diff options
author | Svetoslav <svetoslavganov@google.com> | 2013-04-12 05:45:43 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-12 05:45:43 +0000 |
commit | 14c8c741f79983578a8e9c5124d142c6d85ab91b (patch) | |
tree | acd87b490df1cbe29c55a6130fb5d471ff41aeac /core/java/android | |
parent | 35182905df4d1adb973621af61c831439f0b929b (diff) | |
parent | c4fccd183f1bb47a027bb303af5e65bec2f68b1b (diff) | |
download | frameworks_base-14c8c741f79983578a8e9c5124d142c6d85ab91b.zip frameworks_base-14c8c741f79983578a8e9c5124d142c6d85ab91b.tar.gz frameworks_base-14c8c741f79983578a8e9c5124d142c6d85ab91b.tar.bz2 |
Merge "Adding APIs for an accessibility service to intercept key events." into jb-mr2-dev
Diffstat (limited to 'core/java/android')
4 files changed, 85 insertions, 129 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 811b92a..31de98d 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -24,6 +24,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; +import android.view.KeyEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityNodeInfo; @@ -348,6 +349,7 @@ public abstract class AccessibilityService extends Service { public void onServiceConnected(); public void onSetConnectionId(int connectionId); public boolean onGesture(int gestureId); + public boolean onKeyEvent(KeyEvent event); } private int mConnectionId; @@ -413,6 +415,32 @@ public abstract class AccessibilityService extends Service { } /** + * Callback that allows an accessibility service to observe the key events + * before they are passed to the rest of the system. This means that the events + * are first delivered here before they are passed to the device policy, the + * input method, or applications. + * <p> + * <strong>Note:</strong> It is important that key events are handled in such + * a way that the event stream that would be passed to the rest of the system + * is well-formed. For example, handling the down event but not the up event + * and vice versa would generate an inconsistent event stream. + * </p> + * <p> + * <strong>Note:</strong> The key events delivered in this method are copies + * and modifying them will have no effect on the events that will be passed + * to the system. This method is intended to perform purely filtering + * functionality. + * <p> + * + * @param event The event to be processed. + * @return If true then the event will be consumed and not delivered to + * applications, otherwise it will be delivered as usual. + */ + protected boolean onKeyEvent(KeyEvent event) { + return false; + } + + /** * Gets the root node in the currently active window if this service * can retrieve window content. * @@ -535,6 +563,11 @@ public abstract class AccessibilityService extends Service { public boolean onGesture(int gestureId) { return AccessibilityService.this.onGesture(gestureId); } + + @Override + public boolean onKeyEvent(KeyEvent event) { + return AccessibilityService.this.onKeyEvent(event); + } }); } @@ -554,11 +587,14 @@ public abstract class AccessibilityService extends Service { private static final int DO_ON_ACCESSIBILITY_EVENT = 30; private static final int DO_ON_GESTURE = 40; private static final int DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE = 50; + private static final int DO_ON_KEY_EVENT = 60; private final HandlerCaller mCaller; private final Callbacks mCallback; + private int mConnectionId; + public IAccessibilityServiceClientWrapper(Context context, Looper looper, Callbacks callback) { mCallback = callback; @@ -591,41 +627,65 @@ public abstract class AccessibilityService extends Service { mCaller.sendMessage(message); } + @Override + public void onKeyEvent(KeyEvent event, int sequence) { + Message message = mCaller.obtainMessageIO(DO_ON_KEY_EVENT, sequence, event); + mCaller.sendMessage(message); + } + public void executeMessage(Message message) { switch (message.what) { - case DO_ON_ACCESSIBILITY_EVENT : + case DO_ON_ACCESSIBILITY_EVENT: { AccessibilityEvent event = (AccessibilityEvent) message.obj; if (event != null) { AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event); mCallback.onAccessibilityEvent(event); event.recycle(); } - return; - case DO_ON_INTERRUPT : + } return; + case DO_ON_INTERRUPT: { mCallback.onInterrupt(); - return; - case DO_SET_SET_CONNECTION : - final int connectionId = message.arg1; + } return; + case DO_SET_SET_CONNECTION: { + mConnectionId = message.arg1; IAccessibilityServiceConnection connection = (IAccessibilityServiceConnection) message.obj; if (connection != null) { - AccessibilityInteractionClient.getInstance().addConnection(connectionId, + AccessibilityInteractionClient.getInstance().addConnection(mConnectionId, connection); - mCallback.onSetConnectionId(connectionId); + mCallback.onSetConnectionId(mConnectionId); mCallback.onServiceConnected(); } else { - AccessibilityInteractionClient.getInstance().removeConnection(connectionId); + AccessibilityInteractionClient.getInstance().removeConnection(mConnectionId); AccessibilityInteractionClient.getInstance().clearCache(); mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID); } - return; - case DO_ON_GESTURE : + } return; + case DO_ON_GESTURE: { final int gestureId = message.arg1; mCallback.onGesture(gestureId); - return; - case DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: + } return; + case DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: { AccessibilityInteractionClient.getInstance().clearCache(); - return; + } return; + case DO_ON_KEY_EVENT: { + KeyEvent event = (KeyEvent) message.obj; + try { + IAccessibilityServiceConnection connection = AccessibilityInteractionClient + .getInstance().getConnection(mConnectionId); + if (connection != null) { + final boolean result = mCallback.onKeyEvent(event); + final int sequence = message.arg1; + try { + connection.setOnKeyEventResult(result, sequence); + } catch (RemoteException re) { + /* ignore */ + } + } + } finally { + event.recycle(); + } + } return; default : Log.w(LOG_TAG, "Unknown message type " + message.what); } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl index 5d684e3..c5e3d43a 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl @@ -18,6 +18,7 @@ package android.accessibilityservice; import android.accessibilityservice.IAccessibilityServiceConnection; import android.view.accessibility.AccessibilityEvent; +import android.view.KeyEvent; /** * Top-level interface to an accessibility service component. @@ -35,4 +36,6 @@ import android.view.accessibility.AccessibilityEvent; void onGesture(int gesture); void clearAccessibilityNodeInfoCache(); + + void onKeyEvent(in KeyEvent event, int sequence); } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 7a29f35..3df06b5 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -31,144 +31,31 @@ interface IAccessibilityServiceConnection { void setServiceInfo(in AccessibilityServiceInfo info); - /** - * Finds an {@link android.view.accessibility.AccessibilityNodeInfo} by accessibility id. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} - * to start from the root. - * @param interactionId The id of the interaction for matching with the callback result. - * @param callback Callback which to receive the result. - * @param flags Additional flags. - * @param threadId The id of the calling thread. - * @return Whether the call succeeded. - */ boolean findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId, long accessibilityNodeId, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, long threadId); - /** - * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by View text. - * The match is case insensitive containment. The search is performed in the window - * whose id is specified and starts from the node whose accessibility id is specified. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} - * to start from the root. - * @param text The searched text. - * @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 call succeeded. - */ boolean findAccessibilityNodeInfosByText(int accessibilityWindowId, long accessibilityNodeId, String text, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); - /** - * Finds an {@link android.view.accessibility.AccessibilityNodeInfo} by View id. The search - * is performed in the window whose id is specified and starts from the node whose - * accessibility id is specified. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} - * to start from the root. - * @param viewId The fully qualified resource name of the view id to find. - * @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 call succeeded. - */ boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId, long accessibilityNodeId, String viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); - /** - * Finds the {@link android.view.accessibility.AccessibilityNodeInfo} that has the specified - * focus type. The search is performed in the window whose id is specified and starts from - * the node whose accessibility id is specified. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} - * to start from the root. - * @param focusType The type of focus to find. - * @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 call succeeded. - */ boolean findFocus(int accessibilityWindowId, long accessibilityNodeId, int focusType, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); - /** - * Finds an {@link android.view.accessibility.AccessibilityNodeInfo} to take accessibility - * focus in the given direction. The search is performed in the window whose id is - * specified and starts from the node whose accessibility id is specified. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} - * to start from the root. - * @param direction The direction in which to search for focusable. - * @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 call succeeded. - */ boolean focusSearch(int accessibilityWindowId, long accessibilityNodeId, int direction, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); - /** - * Performs an accessibility action on an - * {@link android.view.accessibility.AccessibilityNodeInfo}. - * - * @param accessibilityWindowId A unique window id. Use - * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} - * to query the currently active window. - * @param accessibilityNodeId A unique view id or virtual descendant id from - * where to start the search. Use - * {@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, in Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); - /** - * @return The associated accessibility service info. - */ AccessibilityServiceInfo getServiceInfo(); - /** - * Performs a global action, such as going home, going back, etc. - * - * @param action The action to perform. - * @return Whether the action was performed. - */ boolean performGlobalAction(int action); + + oneway void setOnKeyEventResult(boolean handled, int sequence); } diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 7d02342..d9799b6 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -31,6 +31,7 @@ import android.os.SystemClock; import android.util.Log; import android.view.Display; import android.view.InputEvent; +import android.view.KeyEvent; import android.view.Surface; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; @@ -693,6 +694,11 @@ public final class UiAutomation { listener.onAccessibilityEvent(AccessibilityEvent.obtain(event)); } } + + @Override + public boolean onKeyEvent(KeyEvent event) { + return false; + } }); } } |