diff options
Diffstat (limited to 'core/java/android')
7 files changed, 121 insertions, 115 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 4e340c0..c858e3c 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -19,22 +19,17 @@ package android.accessibilityservice; import android.app.Service; import android.content.Context; import android.content.Intent; -import android.content.res.Configuration; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; -import android.util.LocaleUtil; import android.util.Log; -import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.os.HandlerCaller; -import java.util.Locale; - /** * An accessibility service runs in the background and receives callbacks by the system * when {@link AccessibilityEvent}s are fired. Such events denote some state transition @@ -299,6 +294,16 @@ public abstract class AccessibilityService extends Service { public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; /** + * The user has performed a two finger tap gesture on the touch screen. + */ + public static final int GESTURE_TWO_FINGER_TAP = 19; + + /** + * The user has performed a two finger long press gesture on the touch screen. + */ + public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20; + + /** * The {@link Intent} that must be declared as handled by the service. */ public static final String SERVICE_INTERFACE = @@ -342,8 +347,6 @@ public abstract class AccessibilityService extends Service { */ public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; - private static final int UNDEFINED = -1; - private static final String LOG_TAG = "AccessibilityService"; interface Callbacks { @@ -351,15 +354,13 @@ public abstract class AccessibilityService extends Service { public void onInterrupt(); public void onServiceConnected(); public void onSetConnectionId(int connectionId); - public void onGesture(int gestureId); + public boolean onGesture(int gestureId); } private int mConnectionId; private AccessibilityServiceInfo mInfo; - private int mLayoutDirection; - /** * Callback for {@link android.view.accessibility.AccessibilityEvent}s. * @@ -386,95 +387,43 @@ public abstract class AccessibilityService extends Service { /** * Called by the system when the user performs a specific gesture on the - * touch screen. + * 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. + * + * <strong>Note:</strong> To receive gestures an accessibility service + * must declare that it can handle such by specifying the + * <code><{@link android.R.styleable#AccessibilityService_canHandleGestures + * canHandleGestures}></code> attribute. * * @param gestureId The unique id of the performed gesture. * + * @return Whether the gesture was handled. + * * @see #GESTURE_SWIPE_UP - * @see #GESTURE_SWIPE_DOWN - * @see #GESTURE_SWIPE_LEFT - * @see #GESTURE_SWIPE_RIGHT + * @see #GESTURE_SWIPE_UP_AND_LEFT * @see #GESTURE_SWIPE_UP_AND_DOWN + * @see #GESTURE_SWIPE_UP_AND_RIGHT + * @see #GESTURE_SWIPE_DOWN + * @see #GESTURE_SWIPE_DOWN_AND_LEFT * @see #GESTURE_SWIPE_DOWN_AND_UP + * @see #GESTURE_SWIPE_DOWN_AND_RIGHT + * @see #GESTURE_SWIPE_LEFT + * @see #GESTURE_SWIPE_LEFT_AND_UP * @see #GESTURE_SWIPE_LEFT_AND_RIGHT + * @see #GESTURE_SWIPE_LEFT_AND_DOWN + * @see #GESTURE_SWIPE_RIGHT + * @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_TWO_FINGER_TAP + * @see #GESTURE_TWO_FINGER_LONG_PRESS */ - protected void onGesture(int gestureId) { + protected boolean onGesture(int gestureId) { // TODO: Describe the default gesture processing in the javaDoc once it is finalized. - - // Global actions. - switch (gestureId) { - case GESTURE_SWIPE_DOWN_AND_LEFT: { - performGlobalAction(GLOBAL_ACTION_BACK); - } return; - case GESTURE_SWIPE_DOWN_AND_RIGHT: { - performGlobalAction(GLOBAL_ACTION_HOME); - } return; - case GESTURE_SWIPE_UP_AND_LEFT: { - performGlobalAction(GLOBAL_ACTION_RECENTS); - } return; - case GESTURE_SWIPE_UP_AND_RIGHT: { - performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS); - } return; - } - - // Cache the id to avoid locking - final int connectionId = mConnectionId; - if (connectionId == UNDEFINED) { - throw new IllegalStateException("AccessibilityService not connected." - + " Did you receive a call of onServiceConnected()?"); - } - AccessibilityNodeInfo root = getRootInActiveWindow(); - if (root == null) { - return; - } - - AccessibilityNodeInfo current = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); - if (current == null) { - current = root; - } - - // Local actions. - AccessibilityNodeInfo next = null; - switch (gestureId) { - case GESTURE_SWIPE_UP: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT); - } break; - case GESTURE_SWIPE_DOWN: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN); - } break; - case GESTURE_SWIPE_LEFT: { - if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD); - } else { // LAYOUT_DIRECTION_RTL - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD); - } - } break; - case GESTURE_SWIPE_RIGHT: { - if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD); - } else { // LAYOUT_DIRECTION_RTL - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD); - } - } break; - case GESTURE_SWIPE_UP_AND_DOWN: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_UP); - } break; - case GESTURE_SWIPE_DOWN_AND_UP: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_DOWN); - } break; - case GESTURE_SWIPE_LEFT_AND_RIGHT: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_LEFT); - } break; - case GESTURE_SWIPE_RIGHT_AND_LEFT: { - next = current.focusSearch(View.ACCESSIBILITY_FOCUS_RIGHT); - } break; - } - if (next != null && !next.equals(current)) { - next.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); - } + return false; } /** @@ -484,10 +433,7 @@ public abstract class AccessibilityService extends Service { * @return The root node if this service can retrieve window content. */ public AccessibilityNodeInfo getRootInActiveWindow() { - return AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByAccessibilityId(mConnectionId, - AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, - AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS); + return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId); } /** @@ -509,7 +455,7 @@ public abstract class AccessibilityService extends Service { AccessibilityInteractionClient.getInstance().getConnection(mConnectionId); if (connection != null) { try { - return connection.perfromGlobalAction(action); + return connection.performGlobalAction(action); } catch (RemoteException re) { Log.w(LOG_TAG, "Error while calling performGlobalAction", re); } @@ -572,18 +518,6 @@ public abstract class AccessibilityService extends Service { } } - @Override - public void onCreate() { - Locale locale = getResources().getConfiguration().locale; - mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale); - } - - @Override - public void onConfigurationChanged(Configuration configuration) { - super.onConfigurationChanged(configuration); - mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(configuration.locale); - } - /** * Implement to return the implementation of the internal accessibility * service interface. @@ -612,8 +546,8 @@ public abstract class AccessibilityService extends Service { } @Override - public void onGesture(int gestureId) { - AccessibilityService.this.onGesture(gestureId); + public boolean onGesture(int gestureId) { + return AccessibilityService.this.onGesture(gestureId); } }); } @@ -658,8 +592,10 @@ public abstract class AccessibilityService extends Service { mCaller.sendMessage(message); } - public void onGesture(int gestureId) { - Message message = mCaller.obtainMessageI(DO_ON_GESTURE, gestureId); + public void onGesture(int gestureId, IAccessibilityServiceClientCallback callback, + int interactionId) { + Message message = mCaller.obtainMessageIIO(DO_ON_GESTURE, gestureId, interactionId, + callback); mCaller.sendMessage(message); } @@ -692,7 +628,15 @@ public abstract class AccessibilityService extends Service { return; case DO_ON_GESTURE : final int gestureId = message.arg1; - mCallback.onGesture(gestureId); + final int interactionId = message.arg2; + IAccessibilityServiceClientCallback callback = + (IAccessibilityServiceClientCallback) message.obj; + final boolean handled = mCallback.onGesture(gestureId); + try { + callback.setGestureResult(gestureId, handled, interactionId); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling back with the gesture resut.", re); + } return; default : Log.w(LOG_TAG, "Unknown message type " + message.what); diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index e77ed9a..7e6786b 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -224,6 +224,11 @@ 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. */ private int mDescriptionResId; @@ -303,6 +308,8 @@ 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) { @@ -378,13 +385,25 @@ public class AccessibilityServiceInfo implements Parcelable { * <strong>Statically set from * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> * </p> - * @return True window content can be retrieved. + * @return True if window content can be retrieved. */ public boolean getCanRetrieveWindowContent() { return mCanRetrieveWindowContent; } /** + * Whether this service can handle gestures. + * <p> + * <strong>Statically set from + * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> + * </p> + * @return True if the service can handle gestures. + */ + public boolean getCanHandleGestures() { + return mCanHandleGestures; + } + + /** * Gets the non-localized description of the accessibility service. * <p> * <strong>Statically set from diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl index 588728c..0257aa4 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl @@ -16,6 +16,7 @@ package android.accessibilityservice; +import android.accessibilityservice.IAccessibilityServiceClientCallback; import android.accessibilityservice.IAccessibilityServiceConnection; import android.view.accessibility.AccessibilityEvent; @@ -32,5 +33,5 @@ import android.view.accessibility.AccessibilityEvent; void onInterrupt(); - void onGesture(int gestureId); + void onGesture(int gesture, in IAccessibilityServiceClientCallback callback, int interactionId); } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl new file mode 100644 index 0000000..9061398 --- /dev/null +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl @@ -0,0 +1,30 @@ +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.accessibilityservice; + +import android.accessibilityservice.IAccessibilityServiceConnection; +import android.view.accessibility.AccessibilityEvent; + +/** + * Callback for IAccessibilityServiceClient. + * + * @hide + */ + oneway interface IAccessibilityServiceClientCallback { + + void setGestureResult(int gestureId, boolean handled, int interactionId); +} diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 1bd5387..6e85665 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -167,5 +167,5 @@ interface IAccessibilityServiceConnection { * @param action The action to perform. * @return Whether the action was performed. */ - boolean perfromGlobalAction(int action); + boolean performGlobalAction(int action); } diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java index c840bd6..1697df0 100644 --- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java +++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java @@ -177,8 +177,8 @@ public class UiTestAutomationBridge { } @Override - public void onGesture(int gestureId) { - /* do nothing */ + public boolean onGesture(int gestureId) { + return false; } }); diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 35f0d9d..f73faf3 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -84,7 +84,7 @@ public final class AccessibilityInteractionClient private final Object mInstanceLock = new Object(); - private int mInteractionId = -1; + private volatile int mInteractionId = -1; private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult; @@ -150,6 +150,18 @@ public final class AccessibilityInteractionClient } /** + * Gets the root {@link AccessibilityNodeInfo} in the currently active window. + * + * @param connectionId The id of a connection for interacting with the system. + * @return The root {@link AccessibilityNodeInfo} if found, null otherwise. + */ + public AccessibilityNodeInfo getRootInActiveWindow(int connectionId) { + return findAccessibilityNodeInfoByAccessibilityId(connectionId, + AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, + AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS); + } + + /** * Finds an {@link AccessibilityNodeInfo} by accessibility id. * * @param connectionId The id of a connection for interacting with the system. |
