From e4abc512aa6474f0106f407f7b399832da34483f Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Wed, 9 May 2012 11:02:38 -0700 Subject: [PATCH] Remove activation gestures form reported and add a touch explore requesting flag. 1. Delegating activation gestures has several issues that we should decide how to handle if possible before allowing an accessibility service to take over them: A) It is needed that every view than can be clicked or long pressed on reacts to such as a response to calling performClick and performLongPress which is not necessary true since the view may watch the touch events and do its own click long click detection. As a result it may be possible that there are view a user cannot interact with in touch exploration mode but can if not in that mode. B) Clicking or long pressing on a different location in a view may yield different results, for example NumberPicker. Ideally such views have to implement AccessibilityNodeProvide which provider handles correctly the request for click long press on virtual nodes. Some apps however just fire different hover accessibility events when the user is over a specific semantic portion of the view but do not provide virtual nodes. Hence, a user will not be able to interact with such semantic regions but the system can achieve that by sending the click/long click at the precise location in the view that was last touch explored. 2. Adding a flag on accessibility service info to request explore by touch mode. There is no need to put the device in this mode if node of the currently enabled accessibility services supports it. Now the problem is inverted and the service has to explicitly state its capability. 3. Fixing a bug where includeImportantViews was ignored for automation services. Change-Id: I3b29a19f24ab5e26ee29f974bbac2197614c9e2a --- api/current.txt | 9 ++-- .../AccessibilityService.java | 27 +++--------- .../AccessibilityServiceInfo.java | 42 +++++++++---------- .../UiTestAutomationBridge.java | 2 +- core/res/res/values/attrs.xml | 6 +-- core/res/res/values/public.xml | 1 - .../AccessibilityManagerService.java | 17 ++++---- 7 files changed, 40 insertions(+), 64 deletions(-) diff --git a/api/current.txt b/api/current.txt index a8bf9492c70e5..3dd1fc220b23c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -315,7 +315,6 @@ package android { field public static final int cacheColorHint = 16843009; // 0x1010101 field public static final int calendarViewShown = 16843596; // 0x101034c field public static final int calendarViewStyle = 16843613; // 0x101035d - field public static final int canHandleGestures = 16843691; // 0x10103ab field public static final int canRetrieveWindowContent = 16843653; // 0x1010385 field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230 field public static final deprecated int capitalize = 16843113; // 0x1010169 @@ -754,7 +753,7 @@ package android { field public static final int pathPrefix = 16842795; // 0x101002b field public static final int permission = 16842758; // 0x1010006 field public static final int permissionGroup = 16842762; // 0x101000a - field public static final int permissionGroupFlags = 16843692; // 0x10103ac + field public static final int permissionGroupFlags = 16843691; // 0x10103ab field public static final int persistent = 16842765; // 0x101000d field public static final int persistentDrawingCache = 16842990; // 0x10100ee field public static final deprecated int phoneNumber = 16843111; // 0x1010167 @@ -2017,7 +2016,6 @@ package android.accessibilityservice { method protected void onServiceConnected(); method public final boolean performGlobalAction(int); method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo); - field public static final int GESTURE_DOUBLE_TAP = 17; // 0x11 field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2 field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10 @@ -2034,7 +2032,6 @@ package android.accessibilityservice { field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7 field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe - field public static final int GESTURE_TAP_AND_HOLD = 18; // 0x12 field public static final int GLOBAL_ACTION_BACK = 1; // 0x1 field public static final int GLOBAL_ACTION_HOME = 2; // 0x2 field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4 @@ -2048,7 +2045,6 @@ package android.accessibilityservice { method public int describeContents(); method public static java.lang.String feedbackTypeToString(int); method public static java.lang.String flagToString(int); - method public boolean getCanHandleGestures(); method public boolean getCanRetrieveWindowContent(); method public deprecated java.lang.String getDescription(); method public java.lang.String getId(); @@ -2064,7 +2060,8 @@ package android.accessibilityservice { field public static final int FEEDBACK_HAPTIC = 2; // 0x2 field public static final int FEEDBACK_SPOKEN = 1; // 0x1 field public static final int FEEDBACK_VISUAL = 8; // 0x8 - field public static final int INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2 + field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2 + field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4 field public int eventTypes; field public int feedbackType; field public int flags; diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index c559e540f8536..850fe4879917b 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -283,16 +283,6 @@ public abstract class AccessibilityService extends Service { */ public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; - /** - * The user has performed a double tap gesture on the touch screen. - */ - public static final int GESTURE_DOUBLE_TAP = 17; - - /** - * The user has performed a tap and hold gesture on the touch screen. - */ - public static final int GESTURE_TAP_AND_HOLD = 18; - /** * The {@link Intent} that must be declared as handled by the service. */ @@ -377,14 +367,12 @@ public abstract class AccessibilityService extends Service { /** * Called by the system when the user performs a specific gesture on the - * touch screen. If the gesture is not handled in this callback the system - * may provide default handing. Therefore, one should return true from this - * function if overriding of default behavior is desired. + * touch screen. * - * Note: To receive gestures an accessibility service - * must declare that it can handle such by specifying the - * <{@link android.R.styleable#AccessibilityService_canHandleGestures - * canHandleGestures}> attribute. + * Note: To receive gestures an accessibility service must + * request that the device is in touch exploration mode by setting the + * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} + * flag. * * @param gestureId The unique id of the performed gesture. * @@ -406,13 +394,8 @@ public abstract class AccessibilityService extends Service { * @see #GESTURE_SWIPE_RIGHT_AND_UP * @see #GESTURE_SWIPE_RIGHT_AND_LEFT * @see #GESTURE_SWIPE_RIGHT_AND_DOWN - * @see #GESTURE_CLOCKWISE_CIRCLE - * @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE - * @see #GESTURE_DOUBLE_TAP - * @see #GESTURE_TAP_AND_HOLD */ protected boolean onGesture(int gestureId) { - // TODO: Describe the default gesture processing in the javaDoc once it is finalized. return false; } diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 7e6786b16a12e..10ea0fe4da942 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -131,7 +131,19 @@ public class AccessibilityServiceInfo implements Parcelable { * elements. *

*/ - public static final int INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002; + public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002; + + /** + * This flag requests that the system gets into touch exploration mode. + * In this mode a single finger moving on the screen behaves as a mouse + * pointer hovering over the user interface. The system will also detect + * certain gestures performed on the touch screen and notify this service. + * The system will enable touch exploration mode if there is at least one + * accessibility service that has this flag set. Hence, clearing this + * flag does not guarantee that the device will not be in touch exploration + * mode since there may be another enabled service that requested it. + */ + public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004; /** * The event types an {@link AccessibilityService} is interested in. @@ -198,7 +210,8 @@ public class AccessibilityServiceInfo implements Parcelable { * Can be dynamically set at runtime. *

* @see #DEFAULT - * @see #INCLUDE_NOT_IMPORTANT_VIEWS + * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS + * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE */ public int flags; @@ -223,11 +236,6 @@ public class AccessibilityServiceInfo implements Parcelable { */ private boolean mCanRetrieveWindowContent; - /** - * Flag whether this accessibility service can handle gestures. - */ - private boolean mCanHandleGestures; - /** * Resource id of the description of the accessibility service. */ @@ -308,8 +316,6 @@ public class AccessibilityServiceInfo implements Parcelable { mCanRetrieveWindowContent = asAttributes.getBoolean( com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent, false); - mCanHandleGestures = asAttributes.getBoolean( - com.android.internal.R.styleable.AccessibilityService_canHandleGestures, false); TypedValue peekedValue = asAttributes.peekValue( com.android.internal.R.styleable.AccessibilityService_description); if (peekedValue != null) { @@ -391,18 +397,6 @@ public class AccessibilityServiceInfo implements Parcelable { return mCanRetrieveWindowContent; } - /** - * Whether this service can handle gestures. - *

- * Statically set from - * {@link AccessibilityService#SERVICE_META_DATA meta-data}. - *

- * @return True if the service can handle gestures. - */ - public boolean getCanHandleGestures() { - return mCanHandleGestures; - } - /** * Gets the non-localized description of the accessibility service. *

@@ -614,8 +608,10 @@ public class AccessibilityServiceInfo implements Parcelable { switch (flag) { case DEFAULT: return "DEFAULT"; - case INCLUDE_NOT_IMPORTANT_VIEWS: - return "REGARD_VIEWS_NOT_IMPORTANT_FOR_ACCESSIBILITY"; + case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS: + return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS"; + case FLAG_REQUEST_TOUCH_EXPLORATION_MODE: + return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE"; default: return null; } diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java index 30be374372d51..6837386e3af6d 100644 --- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java +++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java @@ -189,7 +189,7 @@ public class UiTestAutomationBridge { final AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; - info.flags |= AccessibilityServiceInfo.INCLUDE_NOT_IMPORTANT_VIEWS; + info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; try { manager.registerUiTestAutomationService(mListener, info); diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 484de0df3c48e..ad1dff5764e82 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2461,8 +2461,10 @@ - + + + @@ -2470,8 +2472,6 @@ - - diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 98c19cf0ff4e4..d3f27e1a41ff3 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3600,7 +3600,6 @@ - diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 1cb2092300471..df7bbf2815f6a 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -17,7 +17,7 @@ package com.android.server.accessibility; import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT; -import static android.accessibilityservice.AccessibilityServiceInfo.INCLUDE_NOT_IMPORTANT_VIEWS; +import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; import android.Manifest; import android.accessibilityservice.AccessibilityService; @@ -531,12 +531,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // last record in the enabled services setting. Ideally, // the user should make the call which service handles // gestures. However, only one service should handle - // gestrues to avoid user frustration when different - // bahiour is observed from different combinations of + // gestures to avoid user frustration when different + // behavior is observed from different combinations of // enabled accessibility services. for (int i = mServices.size() - 1; i >= 0; i--) { Service service = mServices.get(i); - if (service.mCanHandleGestures && service.mIsDefault == isDefault) { + if (service.mReqeustTouchExplorationMode && service.mIsDefault == isDefault) { mGestureHandler.scheduleHandleGesture(gestureId, service.mServiceInterface); return true; } @@ -1225,7 +1225,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub boolean mCanRetrieveScreenContent; - boolean mCanHandleGestures; + boolean mReqeustTouchExplorationMode; boolean mIsAutomation; @@ -1243,7 +1243,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mIsAutomation = isAutomation; if (!isAutomation) { mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent(); - mCanHandleGestures = accessibilityServiceInfo.getCanHandleGestures(); + mReqeustTouchExplorationMode = + (accessibilityServiceInfo.flags + & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; mIntent = new Intent().setComponent(mComponentName); mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.accessibility_binding_label); @@ -1251,7 +1253,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0)); } else { mCanRetrieveScreenContent = true; - mCanHandleGestures = true; } setDynamicallyConfigurableProperties(accessibilityServiceInfo); } @@ -1272,7 +1273,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // >= Build.VERSION_CODES.JELLY_BEAN) { > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { mIncludeNotImportantViews = - (info.flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0; + (info.flags & FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0; } synchronized (mLock) {