diff options
14 files changed, 236 insertions, 47 deletions
diff --git a/api/current.txt b/api/current.txt index 5c53ab7..217d3e3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23958,7 +23958,7 @@ package android.view { method public void onWindowSystemUiVisibilityChanged(int); method protected void onWindowVisibilityChanged(int); method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean); - method public boolean performAccessibilityAction(int); + method public boolean performAccessibilityAction(int, android.os.Bundle); method public boolean performClick(); method public boolean performHapticFeedback(int); method public boolean performHapticFeedback(int, int); @@ -25027,6 +25027,7 @@ package android.view.accessibility { method public int getChildCount(); method public java.lang.CharSequence getClassName(); method public java.lang.CharSequence getContentDescription(); + method public java.lang.CharSequence[] getGranularities(); method public java.lang.CharSequence getPackageName(); method public android.view.accessibility.AccessibilityNodeInfo getParent(); method public java.lang.CharSequence getText(); @@ -25047,6 +25048,7 @@ package android.view.accessibility { method public static android.view.accessibility.AccessibilityNodeInfo obtain(); method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.accessibility.AccessibilityNodeInfo); method public boolean performAction(int); + method public boolean performAction(int, android.os.Bundle); method public void recycle(); method public void setAccessibilityFocused(boolean); method public void setBoundsInParent(android.graphics.Rect); @@ -25059,6 +25061,7 @@ package android.view.accessibility { method public void setEnabled(boolean); method public void setFocusable(boolean); method public void setFocused(boolean); + method public void setGranularities(java.lang.CharSequence[]); method public void setLongClickable(boolean); method public void setPackageName(java.lang.CharSequence); method public void setParent(android.view.View); @@ -25071,12 +25074,15 @@ package android.view.accessibility { method public void setText(java.lang.CharSequence); method public void writeToParcel(android.os.Parcel, int); field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40 + field public static final java.lang.String ACTION_ARGUMENT_GRANULARITY = "ACTION_ARGUMENT_GRANULARITY"; field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80 field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2 field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8 field public static final int ACTION_CLICK = 16; // 0x10 field public static final int ACTION_FOCUS = 1; // 0x1 field public static final int ACTION_LONG_CLICK = 32; // 0x20 + field public static final int ACTION_NEXT_AT_GRANULARITY = 256; // 0x100 + field public static final int ACTION_PREVIOUS_AT_GRANULARITY = 512; // 0x200 field public static final int ACTION_SELECT = 4; // 0x4 field public static final android.os.Parcelable.Creator CREATOR; field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2 @@ -25089,7 +25095,7 @@ package android.view.accessibility { method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int); method public android.view.accessibility.AccessibilityNodeInfo findAccessibilitiyFocus(int); method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int); - method public boolean performAccessibilityAction(int, int); + method public boolean performAction(int, int, android.os.Bundle); } public class AccessibilityRecord { diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 6e85665..dd50f3c 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -16,6 +16,7 @@ package android.accessibilityservice; +import android.os.Bundle; import android.accessibilityservice.AccessibilityServiceInfo; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; @@ -147,14 +148,15 @@ interface IAccessibilityServiceConnection { * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} * to start from the root. * @param action The action to perform. + * @param arguments Optional action arguments. * @param interactionId The id of the interaction for matching with the callback result. * @param callback Callback which to receive the result. * @param threadId The id of the calling thread. * @return Whether the action was performed. */ boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId, - int action, int interactionId, IAccessibilityInteractionConnectionCallback callback, - long threadId); + int action, in Bundle arguments, int interactionId, + IAccessibilityInteractionConnectionCallback callback, long threadId); /** * @return The associated accessibility service info. diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java index 1697df0..4d4bfeb 100644 --- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java +++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java @@ -19,6 +19,7 @@ package android.accessibilityservice; import android.accessibilityservice.AccessibilityService.Callbacks; import android.accessibilityservice.AccessibilityService.IAccessibilityServiceClientWrapper; import android.content.Context; +import android.os.Bundle; import android.os.HandlerThread; import android.os.Looper; import android.os.RemoteException; @@ -444,10 +445,12 @@ public class UiTestAutomationBridge { * * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id). * @param action The action to perform. + * @param arguments Optional action arguments. * @return Whether the action was performed. */ - public boolean performAccessibilityActionInActiveWindow(long accessibilityNodeId, int action) { - return performAccessibilityAction(ACTIVE_WINDOW_ID, accessibilityNodeId, action); + public boolean performAccessibilityActionInActiveWindow(long accessibilityNodeId, int action, + Bundle arguments) { + return performAccessibilityAction(ACTIVE_WINDOW_ID, accessibilityNodeId, action, arguments); } /** @@ -457,15 +460,16 @@ public class UiTestAutomationBridge { * {@link #ACTIVE_WINDOW_ID} to query the currently active window. * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id). * @param action The action to perform. + * @param arguments Optional action arguments. * @return Whether the action was performed. */ public boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId, - int action) { + int action, Bundle arguments) { // Cache the id to avoid locking final int connectionId = mConnectionId; ensureValidConnection(connectionId); return AccessibilityInteractionClient.getInstance().performAccessibilityAction(connectionId, - accessibilityWindowId, accessibilityNodeId, action); + accessibilityWindowId, accessibilityNodeId, action, arguments); } /** diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index e3f5b96..7d569ad 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -18,6 +18,7 @@ package android.view; import static android.view.accessibility.AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -514,8 +515,9 @@ final class AccessibilityInteractionController { } public void performAccessibilityActionClientThread(long accessibilityNodeId, int action, - int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, - int interogatingPid, long interrogatingTid) { + Bundle arguments, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid, + long interrogatingTid) { Message message = mHandler.obtainMessage(); message.what = PrivateHandler.MSG_PERFORM_ACCESSIBILITY_ACTION; message.arg1 = flags; @@ -525,6 +527,7 @@ final class AccessibilityInteractionController { args.argi2 = action; args.argi3 = interactionId; args.arg1 = callback; + args.arg2 = arguments; message.obj = args; // If the interrogation is performed by the same thread as the main UI // thread in this process, set the message as a static reference so @@ -547,6 +550,7 @@ final class AccessibilityInteractionController { final int interactionId = args.argi3; final IAccessibilityInteractionConnectionCallback callback = (IAccessibilityInteractionConnectionCallback) args.arg1; + Bundle arguments = (Bundle) args.arg2; mPool.release(args); boolean succeeded = false; try { @@ -564,9 +568,10 @@ final class AccessibilityInteractionController { if (target != null && target.isDisplayedOnScreen()) { AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider(); if (provider != null) { - succeeded = provider.performAccessibilityAction(action, virtualDescendantId); + succeeded = provider.performAction(virtualDescendantId, action, + arguments); } else if (virtualDescendantId == View.NO_ID) { - succeeded = target.performAccessibilityAction(action); + succeeded = target.performAccessibilityAction(action, arguments); } } } finally { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index ce02113..e6d7c02 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -39,6 +39,7 @@ import android.graphics.Region; import android.graphics.Shader; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Parcel; @@ -6390,7 +6391,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @param action The action to perform. * @return Whether the action was performed. */ - public boolean performAccessibilityAction(int action) { + public boolean performAccessibilityAction(int action, Bundle args) { switch (action) { case AccessibilityNodeInfo.ACTION_CLICK: { if (isClickable()) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 247f673..aa94765 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -5132,12 +5132,13 @@ public final class ViewRootImpl implements ViewParent, @Override public void performAccessibilityAction(long accessibilityNodeId, int action, - int interactionId, IAccessibilityInteractionConnectionCallback callback, - int flags, int interogatingPid, long interrogatingTid) { + Bundle arguments, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int flags, + int interogatingPid, long interrogatingTid) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() - .performAccessibilityActionClientThread(accessibilityNodeId, action, + .performAccessibilityActionClientThread(accessibilityNodeId, action, arguments, interactionId, callback, flags, interogatingPid, interrogatingTid); } else { // We cannot make the call and notify the caller so it does not wait. diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index f73faf3..24e90fd 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -19,6 +19,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; import android.graphics.Rect; import android.os.Binder; +import android.os.Bundle; import android.os.Message; import android.os.Process; import android.os.RemoteException; @@ -408,17 +409,18 @@ public final class AccessibilityInteractionClient * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} * to start from the root. * @param action The action to perform. + * @param arguments Optional action arguments. * @return Whether the action was performed. */ public boolean performAccessibilityAction(int connectionId, int accessibilityWindowId, - long accessibilityNodeId, int action) { + long accessibilityNodeId, int action, Bundle arguments) { try { IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); final boolean success = connection.performAccessibilityAction( - accessibilityWindowId, accessibilityNodeId, action, interactionId, this, - Thread.currentThread().getId()); + accessibilityWindowId, accessibilityNodeId, action, arguments, + interactionId, this, Thread.currentThread().getId()); if (success) { return getPerformAccessibilityActionResultAndClear(interactionId); } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index c5f2062..7e565fc 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -17,9 +17,9 @@ package android.view.accessibility; import android.graphics.Rect; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.text.TextUtils; import android.util.SparseLongArray; import android.view.View; @@ -122,6 +122,80 @@ public class AccessibilityNodeInfo implements Parcelable { public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080; /** + * Action that requests from the node to go to the next entity in its content + * at a given granularity. For example, move to the next word, link, etc. + * <p> + * <strong>Arguments:</strong> + * <ul> + * <li> + * {@link #ACTION_ARGUMENT_GRANULARITY} + * </li> + * <li> + * </p> + * <p> + * <strong>Example:</strong> + * <code><pre><p> + * // Assume the first granularity was presented to the user and she is + * // making an explicit action to traverse the node at that granularity. + * CharSequence granularity = info.getGranularity(0); + * Bundle arguments = new Bundle(); + * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_GRANULARITY, granularity); + * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY, arguments); + * </code></pre></p> + * </li> + * </ul> + * </p> + * @see #setGranularities(CharSequence[]) + * @see #getGranularities() + */ + public static final int ACTION_NEXT_AT_GRANULARITY = 0x00000100; + + /** + * Action that requests from the node to go to the previous entity in its content + * at a given granularity. For example, move to the next word, link, etc. + * <p> + * <strong>Arguments:</strong> + * <ul> + * <li> + * {@link #ACTION_ARGUMENT_GRANULARITY} + * </li> + * <li> + * </p> + * <p> + * <strong>Example:</strong> + * <code><pre><p> + * // Assume the first granularity was presented to the user and she is + * // making an explicit action to traverse the node at that granularity. + * CharSequence granularity = info.getGranularity(0); + * Bundle arguments = new Bundle(); + * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_GRANULARITY, granularity); + * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY, arguments); + * </code></pre></p> + * </li> + * </ul> + * </p> + * @see #setGranularities(CharSequence[]) + * @see #getGranularities() + */ + public static final int ACTION_PREVIOUS_AT_GRANULARITY = 0x00000200; + + /** + * Argument for which content granularity to be used when traversing the node content. + * <p> + * <strong>Actions:</strong> + * <ul> + * <li> + * {@link #ACTION_PREVIOUS_AT_GRANULARITY} + * </li> + * <li> + * {@link #ACTION_PREVIOUS_AT_GRANULARITY} + * </li> + * </ul> + * </p> + */ + public static final String ACTION_ARGUMENT_GRANULARITY = "ACTION_ARGUMENT_GRANULARITY"; + + /** * The input focus. */ public static final int FOCUS_INPUT = 1; @@ -231,9 +305,11 @@ public class AccessibilityNodeInfo implements Parcelable { private CharSequence mText; private CharSequence mContentDescription; - private SparseLongArray mChildNodeIds = new SparseLongArray(); + private final SparseLongArray mChildNodeIds = new SparseLongArray(); private int mActions; + private CharSequence[] mGranularities; + private int mConnectionId = UNDEFINED; /** @@ -458,6 +534,32 @@ public class AccessibilityNodeInfo implements Parcelable { } /** + * Sets the granularities for traversing the content of this node. + * <p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. + * This class is made immutable before being delivered to an AccessibilityService. + * </p> + * + * @param granularities The granularity names. + * + * @throws IllegalStateException If called from an AccessibilityService. + */ + public void setGranularities(CharSequence[] granularities) { + enforceNotSealed(); + mGranularities = granularities; + } + + /** + * Gets the granularities for traversing the content of this node. + * + * @return The count. + */ + public CharSequence[] getGranularities() { + return mGranularities; + } + + /** * Performs an action on the node. * <p> * <strong>Note:</strong> An action can be performed only if the request is made @@ -475,7 +577,31 @@ public class AccessibilityNodeInfo implements Parcelable { return false; } AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); - return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId, action); + return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId, + action, null); + } + + /** + * Performs an action on the node. + * <p> + * <strong>Note:</strong> An action can be performed only if the request is made + * from an {@link android.accessibilityservice.AccessibilityService}. + * </p> + * + * @param action The action to perform. + * @param arguments A bundle with additional arguments. + * @return True if the action was performed. + * + * @throws IllegalStateException If called outside of an AccessibilityService. + */ + public boolean performAction(int action, Bundle arguments) { + enforceSealed(); + if (!canPerformRequestOverConnection(mSourceNodeId)) { + return false; + } + AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); + return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId, + action, arguments); } /** @@ -1215,6 +1341,8 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeLong(mParentNodeId); parcel.writeInt(mConnectionId); + parcel.writeCharSequenceArray(mGranularities); + SparseLongArray childIds = mChildNodeIds; final int childIdsSize = childIds.size(); parcel.writeInt(childIdsSize); @@ -1236,10 +1364,10 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeInt(mBooleanProperties); - TextUtils.writeToParcel(mPackageName, parcel, flags); - TextUtils.writeToParcel(mClassName, parcel, flags); - TextUtils.writeToParcel(mText, parcel, flags); - TextUtils.writeToParcel(mContentDescription, parcel, flags); + parcel.writeCharSequence(mPackageName); + parcel.writeCharSequence(mClassName); + parcel.writeCharSequence(mText); + parcel.writeCharSequence(mContentDescription); // Since instances of this class are fetched via synchronous i.e. blocking // calls in IPCs we always recycle as soon as the instance is marshaled. @@ -1251,6 +1379,7 @@ public class AccessibilityNodeInfo implements Parcelable { * * @param other The other instance. */ + @SuppressWarnings("unchecked") private void init(AccessibilityNodeInfo other) { mSealed = other.mSealed; mSourceNodeId = other.mSourceNodeId; @@ -1265,7 +1394,11 @@ public class AccessibilityNodeInfo implements Parcelable { mContentDescription = other.mContentDescription; mActions= other.mActions; mBooleanProperties = other.mBooleanProperties; - mChildNodeIds = other.mChildNodeIds.clone(); + mGranularities = other.mGranularities.clone(); + final int otherChildIdCount = other.mChildNodeIds.size(); + for (int i = 0; i < otherChildIdCount; i++) { + mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i)); + } } /** @@ -1280,6 +1413,8 @@ public class AccessibilityNodeInfo implements Parcelable { mParentNodeId = parcel.readLong(); mConnectionId = parcel.readInt(); + mGranularities = parcel.readCharSequenceArray(); + SparseLongArray childIds = mChildNodeIds; final int childrenSize = parcel.readInt(); for (int i = 0; i < childrenSize; i++) { @@ -1301,10 +1436,10 @@ public class AccessibilityNodeInfo implements Parcelable { mBooleanProperties = parcel.readInt(); - mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); - mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); - mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); - mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); + mPackageName = parcel.readCharSequence(); + mClassName = parcel.readCharSequence(); + mText = parcel.readCharSequence(); + mContentDescription = parcel.readCharSequence(); } /** @@ -1316,6 +1451,7 @@ public class AccessibilityNodeInfo implements Parcelable { mParentNodeId = ROOT_NODE_ID; mWindowId = UNDEFINED; mConnectionId = UNDEFINED; + mGranularities = null; mChildNodeIds.clear(); mBoundsInParent.set(0, 0, 0, 0); mBoundsInScreen.set(0, 0, 0, 0); @@ -1394,6 +1530,17 @@ public class AccessibilityNodeInfo implements Parcelable { builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId)); builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId)); builder.append("; mParentNodeId: " + mParentNodeId); + + CharSequence[] granularities = mGranularities; + builder.append("; granularities: ["); + for (int i = 0, count = granularities.length; i < count; i++) { + builder.append(granularities[i]); + if (i < count - 1) { + builder.append(", "); + } + } + builder.append("]"); + SparseLongArray childIds = mChildNodeIds; builder.append("; childAccessibilityIds: ["); for (int i = 0, count = childIds.size(); i < count; i++) { @@ -1401,8 +1548,8 @@ public class AccessibilityNodeInfo implements Parcelable { if (i < count - 1) { builder.append(", "); } - } - builder.append("]"); + } + builder.append("]"); } builder.append("; boundsInParent: " + mBoundsInParent); diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java index 19e35dd..ba6433f 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java +++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java @@ -17,6 +17,7 @@ package android.view.accessibility; import android.accessibilityservice.AccessibilityService; +import android.os.Bundle; import android.view.View; import java.util.List; @@ -47,12 +48,13 @@ import java.util.List; * getAccessibilityNodeProvider( * if (mAccessibilityNodeProvider == null) { * mAccessibilityNodeProvider = new AccessibilityNodeProvider() { - * public boolean performAccessibilityAction(int action, int virtualDescendantId) { + * public boolean performAction(int action, int virtualDescendantId) { * // Implementation. * return false; * } * - * public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text, int virtualDescendantId) { + * public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text, + * int virtualDescendantId) { * // Implementation. * return null; * } @@ -99,15 +101,16 @@ public abstract class AccessibilityNodeProvider { * host View, with the given <code>virtualViewId</code> or the host View itself * if <code>virtualViewId</code> equals to {@link View#NO_ID}. * - * @param action The action to perform. * @param virtualViewId A client defined virtual view id. + * @param action The action to perform. + * @param arguments Optional action arguments. * @return True if the action was performed. * - * @see View#performAccessibilityAction(int) + * @see View#performAccessibilityAction(int, Bundle) * @see #createAccessibilityNodeInfo(int) * @see AccessibilityNodeInfo */ - public boolean performAccessibilityAction(int action, int virtualViewId) { + public boolean performAction(int virtualViewId, int action, Bundle arguments) { return false; } diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl index 8182d29..9d7a928 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl @@ -16,6 +16,7 @@ package android.view.accessibility; +import android.os.Bundle; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; @@ -47,7 +48,7 @@ oneway interface IAccessibilityInteractionConnection { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid); - void performAccessibilityAction(long accessibilityNodeId, int action, int interactionId, - IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, - long interrogatingTid); + void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments, + int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, + int interrogatingPid, long interrogatingTid); } diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 992849d..11d1ed0 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -26,6 +26,7 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.text.InputFilter; import android.text.InputType; import android.text.Spanned; @@ -2068,7 +2069,7 @@ public class NumberPicker extends LinearLayout { } @Override - public boolean performAccessibilityAction(int action, int virtualViewId) { + public boolean performAction(int virtualViewId, int action, Bundle arguments) { switch (virtualViewId) { case VIRTUAL_VIEW_ID_INPUT: { switch (action) { @@ -2086,7 +2087,7 @@ public class NumberPicker extends LinearLayout { } } break; } - return super.performAccessibilityAction(action, virtualViewId); + return super.performAction(virtualViewId, action, arguments); } public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) { diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 3f8036b..a730770 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -865,6 +865,10 @@ <java-symbol type="string" name="yesterday" /> <java-symbol type="string" name="imei" /> <java-symbol type="string" name="meid" /> + <java-symbol type="string" name="granularity_label_character" /> + <java-symbol type="string" name="granularity_label_word" /> + <java-symbol type="string" name="granularity_label_link" /> + <java-symbol type="string" name="granularity_label_line" /> <java-symbol type="plurals" name="abbrev_in_num_days" /> <java-symbol type="plurals" name="abbrev_in_num_hours" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 149a78c..04866b9 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2027,6 +2027,15 @@ <!-- Label for ALT modifier key. Must be short to fit on key! --> <string name="password_keyboard_label_alt_key">ALT</string> + <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by character. Only spoken to the user. [CHAR LIMIT=NONE] --> + <string name="granularity_label_character">character</string> + <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by word. Only spoken to the user. [CHAR LIMIT=NONE] --> + <string name="granularity_label_word">word</string> + <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by link. Only spoken to the user. [CHAR LIMIT=NONE] --> + <string name="granularity_label_link">link</string> + <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by line. Only spoken to the user. [CHAR LIMIT=NONE] --> + <string name="granularity_label_line">line</string> + <!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). --> <string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string> diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 7361062..e9a21c6 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -41,6 +41,7 @@ import android.hardware.input.InputManager; import android.net.Uri; import android.os.Binder; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -1545,7 +1546,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @Override public boolean performAccessibilityAction(int accessibilityWindowId, - long accessibilityNodeId, int action, int interactionId, + long accessibilityNodeId, int action, Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) { final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); IAccessibilityInteractionConnection connection = null; @@ -1566,8 +1567,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int flags = (mIncludeNotImportantViews) ? AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; final int interrogatingPid = Binder.getCallingPid(); - connection.performAccessibilityAction(accessibilityNodeId, action, interactionId, - callback, flags, interrogatingPid, interrogatingTid); + connection.performAccessibilityAction(accessibilityNodeId, action, arguments, + interactionId, callback, flags, interrogatingPid, interrogatingTid); } catch (RemoteException re) { if (DEBUG) { Slog.e(LOG_TAG, "Error calling performAccessibilityAction()"); @@ -1696,7 +1697,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub | AccessibilityNodeInfo.ACTION_SELECT | AccessibilityNodeInfo.ACTION_CLEAR_SELECTION | AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS - | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; + | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS + | AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY + | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_GRANULARITY; private static final int RETRIEVAL_ALLOWING_EVENT_TYPES = AccessibilityEvent.TYPE_VIEW_CLICKED |