From 78d2e2ddf07414eb342094ad8cf9d830b2220528 Mon Sep 17 00:00:00 2001 From: Phil Weaver Date: Tue, 2 Feb 2016 14:47:44 -0800 Subject: [PATCH] Clean up accessibility gestures. Closing two small holes in the implementation: 1. The gesture was dispatched before the callback was registered. It was possible for gestures that failed quickly to fail to report any status. 2. Gestures could be dispatched before the input filter was installed. Adding a wait to give the filter a chance to install before reporting a failure. Also removing an unused method on the input filter. Change-Id: I77cd80dcd2cec6c72b3761169aba5eaecf62250b (cherry picked from commit 03465fb874ccf35ead2228b66ec03afc31d7694e) --- .../accessibilityservice/AccessibilityService.java | 5 ++-- .../accessibility/AccessibilityInputFilter.java | 4 ---- .../accessibility/AccessibilityManagerService.java | 28 ++++++++++++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index c96cca27be55..4bc6b97c834d 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -624,8 +624,7 @@ public abstract class AccessibilityService extends Service { gesture, 100); try { synchronized (mLock) { - connection.sendMotionEvents(++mGestureStatusCallbackSequence, - new ParceledListSlice<>(events)); + mGestureStatusCallbackSequence++; if (callback != null) { if (mGestureStatusCallbackInfos == null) { mGestureStatusCallbackInfos = new SparseArray<>(); @@ -634,6 +633,8 @@ public abstract class AccessibilityService extends Service { callback, handler); mGestureStatusCallbackInfos.put(mGestureStatusCallbackSequence, callbackInfo); } + connection.sendMotionEvents(mGestureStatusCallbackSequence, + new ParceledListSlice<>(events)); } } catch (RemoteException re) { throw new RuntimeException(re); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index 232c080266c0..3335315f6c01 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -200,10 +200,6 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } } - public MotionEventInjector getMotionEventInjector() { - return mMotionEventInjector; - } - /** * Gets current event stream state associated with an input event. * @return The event stream state that should be used for the event. Null if the event should diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 53504cc2f6c6..c35a73a4c1a1 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -129,6 +129,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000; + // TODO: Restructure service initialization so services aren't connected before all of + // their capabilities are ready. + private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000; + private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; @@ -794,6 +798,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { void setMotionEventInjector(MotionEventInjector motionEventInjector) { synchronized (mLock) { mMotionEventInjector = motionEventInjector; + // We may be waiting on this object being set + mLock.notifyAll(); } } @@ -2655,10 +2661,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { @Override public void sendMotionEvents(int sequence, ParceledListSlice events) { synchronized (mLock) { - if (mSecurityPolicy.canPerformGestures(this) && (mMotionEventInjector != null)) { - mMotionEventInjector.injectEvents((List) events.getList(), - mServiceInterface, sequence); - return; + if (mSecurityPolicy.canPerformGestures(this)) { + final long endMillis = + SystemClock.uptimeMillis() + WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS; + while ((mMotionEventInjector == null) + && (SystemClock.uptimeMillis() < endMillis)) { + try { + mLock.wait(endMillis - SystemClock.uptimeMillis()); + } catch (InterruptedException ie) { + /* ignore */ + } + } + if (mMotionEventInjector != null) { + mMotionEventInjector.injectEvents((List) events.getList(), + mServiceInterface, sequence); + return; + } else { + Slog.e(LOG_TAG, "MotionEventInjector installation timed out"); + } } } try { -- 2.11.0