Loading core/java/android/view/accessibility/AccessibilityManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -1166,9 +1166,10 @@ public final class AccessibilityManager { /** * Notifies that the accessibility button in the system's navigation area has been clicked * * @param displayId The logical display id. * @hide */ public void notifyAccessibilityButtonClicked() { public void notifyAccessibilityButtonClicked(int displayId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); Loading @@ -1177,7 +1178,7 @@ public final class AccessibilityManager { } } try { service.notifyAccessibilityButtonClicked(); service.notifyAccessibilityButtonClicked(displayId); } catch (RemoteException re) { Log.e(LOG_TAG, "Error while dispatching accessibility button click", re); } Loading core/java/android/view/accessibility/IAccessibilityManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ interface IAccessibilityManager { IBinder getWindowToken(int windowId, int userId); void notifyAccessibilityButtonClicked(); void notifyAccessibilityButtonClicked(int displayId); void notifyAccessibilityButtonVisibilityChanged(boolean available); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +3 −1 Original line number Diff line number Diff line Loading @@ -802,7 +802,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } private void onAccessibilityClick(View v) { mAccessibilityManager.notifyAccessibilityButtonClicked(); final Display display = v.getDisplay(); mAccessibilityManager.notifyAccessibilityButtonClicked( display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY); } private boolean onAccessibilityLongClick(View v) { Loading services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +163 −84 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ package com.android.server.accessibility; import android.content.Context; import android.os.Handler; import android.os.PowerManager; import android.util.DebugUtils; import android.util.ExceptionUtils; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.Display; import android.view.InputDevice; import android.view.InputEvent; import android.view.InputFilter; Loading @@ -31,10 +29,11 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.accessibility.AccessibilityEvent; import com.android.internal.util.BitUtils; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; import java.util.ArrayList; /** * This class is an input filter for implementing accessibility features such * as display magnification and explore by touch. Loading Loading @@ -108,23 +107,24 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private final AccessibilityManagerService mAms; private boolean mInstalled; private int mUserId; private int mEnabledFeatures; private final SparseArray<EventStreamTransformation> mEventHandler; private TouchExplorer mTouchExplorer; private final SparseArray<TouchExplorer> mTouchExplorer = new SparseArray<>(0); private MagnificationGestureHandler mMagnificationGestureHandler; private final SparseArray<MagnificationGestureHandler> mMagnificationGestureHandler = new SparseArray<>(0); private MotionEventInjector mMotionEventInjector; private final SparseArray<MotionEventInjector> mMotionEventInjector = new SparseArray<>(0); private AutoclickController mAutoclickController; private KeyboardInterceptor mKeyboardInterceptor; private EventStreamTransformation mEventHandler; private boolean mInstalled; private int mUserId; private int mEnabledFeatures; private EventStreamState mMouseStreamState; Loading @@ -133,10 +133,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private EventStreamState mKeyboardStreamState; AccessibilityInputFilter(Context context, AccessibilityManagerService service) { this(context, service, new SparseArray<>(0)); } AccessibilityInputFilter(Context context, AccessibilityManagerService service, SparseArray<EventStreamTransformation> eventHandler) { super(context.getMainLooper()); mContext = context; mAms = service; mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mEventHandler = eventHandler; } @Override Loading @@ -160,6 +166,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo super.onUninstalled(); } void onDisplayChanged() { if (mInstalled) { disableFeatures(); enableFeatures(); } } @Override public void onInputEvent(InputEvent event, int policyFlags) { if (DEBUG) { Loading @@ -167,8 +180,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo + Integer.toHexString(policyFlags)); } if (mEventHandler == null) { if (DEBUG) Slog.d(TAG, "mEventHandler == null for event " + event); if (mEventHandler.size() == 0) { if (DEBUG) Slog.d(TAG, "No mEventHandler for event " + event); super.onInputEvent(event, policyFlags); return; } Loading @@ -182,16 +195,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo int eventSource = event.getSource(); if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) { state.reset(); mEventHandler.clearEvents(eventSource); clearEventsForAllEventHandlers(eventSource); super.onInputEvent(event, policyFlags); return; } if (state.updateDeviceId(event.getDeviceId())) { mEventHandler.clearEvents(eventSource); if (state.updateInputSource(event.getSource())) { clearEventsForAllEventHandlers(eventSource); } if (!state.deviceIdValid()) { if (!state.inputSourceValid()) { super.onInputEvent(event, policyFlags); return; } Loading Loading @@ -240,6 +253,15 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo return null; } private void clearEventsForAllEventHandlers(int eventSource) { for (int i = 0; i < mEventHandler.size(); i++) { final EventStreamTransformation eventHandler = mEventHandler.valueAt(i); if (eventHandler != null) { eventHandler.clearEvents(eventSource); } } } private void processMotionEvent(EventStreamState state, MotionEvent event, int policyFlags) { if (!state.shouldProcessScroll() && event.getActionMasked() == MotionEvent.ACTION_SCROLL) { super.onInputEvent(event, policyFlags); Loading @@ -258,7 +280,10 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo super.onInputEvent(event, policyFlags); return; } mEventHandler.onKeyEvent(event, policyFlags); // Since the display id of KeyEvent always would be -1 and there is only one // KeyboardInterceptor for all display, pass KeyEvent to the mEventHandler of // DEFAULT_DISPLAY to handle. mEventHandler.get(Display.DEFAULT_DISPLAY).onKeyEvent(event, policyFlags); } private void handleMotionEvent(MotionEvent event, int policyFlags) { Loading @@ -267,10 +292,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } mPm.userActivity(event.getEventTime(), false); MotionEvent transformedEvent = MotionEvent.obtain(event); mEventHandler.onMotionEvent(transformedEvent, event, policyFlags); final int displayId = event.getDisplayId(); mEventHandler.get(isDisplayIdValid(displayId) ? displayId : Display.DEFAULT_DISPLAY) .onMotionEvent(transformedEvent, event, policyFlags); transformedEvent.recycle(); } private boolean isDisplayIdValid(int displayId) { return mEventHandler.get(displayId) != null; } @Override public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent, int policyFlags) { Loading Loading @@ -323,14 +354,20 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } void notifyAccessibilityEvent(AccessibilityEvent event) { if (mEventHandler != null) { mEventHandler.onAccessibilityEvent(event); for (int i = 0; i < mEventHandler.size(); i++) { final EventStreamTransformation eventHandler = mEventHandler.valueAt(i); if (eventHandler != null) { eventHandler.onAccessibilityEvent(event); } } } void notifyAccessibilityButtonClicked() { if (mMagnificationGestureHandler != null) { mMagnificationGestureHandler.notifyShortcutTriggered(); void notifyAccessibilityButtonClicked(int displayId) { if (mMagnificationGestureHandler.size() != 0) { final MagnificationGestureHandler handler = mMagnificationGestureHandler.get(displayId); if (handler != null) { handler.notifyShortcutTriggered(); } } } Loading @@ -339,14 +376,20 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo resetStreamState(); final ArrayList<Display> displaysList = mAms.getValidDisplayList(); if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) { mAutoclickController = new AutoclickController(mContext, mUserId); addFirstEventHandler(mAutoclickController); addFirstEventHandlerForAllDisplays(displaysList, mAutoclickController); } for (int i = displaysList.size() - 1; i >= 0; i--) { final int displayId = displaysList.get(i).getDisplayId(); if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { mTouchExplorer = new TouchExplorer(mContext, mAms); addFirstEventHandler(mTouchExplorer); TouchExplorer explorer = new TouchExplorer(mContext, mAms); addFirstEventHandler(displayId, explorer); mTouchExplorer.put(displayId, explorer); } if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 Loading @@ -356,64 +399,101 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0; final boolean triggerable = (mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0; mMagnificationGestureHandler = new MagnificationGestureHandler( mContext, mAms.getMagnificationController(), MagnificationGestureHandler magnificationGestureHandler = new MagnificationGestureHandler(mContext, mAms.getMagnificationController(), detectControlGestures, triggerable); addFirstEventHandler(mMagnificationGestureHandler); addFirstEventHandler(displayId, magnificationGestureHandler); mMagnificationGestureHandler.put(displayId, magnificationGestureHandler); } if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper()); addFirstEventHandler(mMotionEventInjector); mAms.setMotionEventInjector(mMotionEventInjector); MotionEventInjector injector = new MotionEventInjector( mContext.getMainLooper()); addFirstEventHandler(displayId, injector); // TODO: Need to set MotionEventInjector per display. mAms.setMotionEventInjector(injector); mMotionEventInjector.put(displayId, injector); } } if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) { mKeyboardInterceptor = new KeyboardInterceptor(mAms, LocalServices.getService(WindowManagerPolicy.class)); addFirstEventHandler(mKeyboardInterceptor); // Since the display id of KeyEvent always would be -1 and it would be dispatched to // the display with input focus directly, we only need one KeyboardInterceptor for // default display. addFirstEventHandler(Display.DEFAULT_DISPLAY, mKeyboardInterceptor); } } /** * Adds an event handler to the event handler chain. The handler is added at the beginning of * the chain. * Adds an event handler to the event handler chain for giving display. The handler is added at * the beginning of the chain. * * @param displayId The logical display id. * @param handler The handler to be added to the event handlers list. */ private void addFirstEventHandler(EventStreamTransformation handler) { if (mEventHandler != null) { handler.setNext(mEventHandler); private void addFirstEventHandler(int displayId, EventStreamTransformation handler) { EventStreamTransformation eventHandler = mEventHandler.get(displayId); if (eventHandler != null) { handler.setNext(eventHandler); } else { handler.setNext(this); } mEventHandler = handler; eventHandler = handler; mEventHandler.put(displayId, eventHandler); } /** * Adds an event handler to the event handler chain for all displays. The handler is added at * the beginning of the chain. * * @param displayList The list of displays * @param handler The handler to be added to the event handlers list. */ private void addFirstEventHandlerForAllDisplays(ArrayList<Display> displayList, EventStreamTransformation handler) { for (int i = 0; i < displayList.size(); i++) { final int displayId = displayList.get(i).getDisplayId(); addFirstEventHandler(displayId, handler); } } private void disableFeatures() { if (mMotionEventInjector != null) { for (int i = mMotionEventInjector.size() - 1; i >= 0; i--) { final MotionEventInjector injector = mMotionEventInjector.valueAt(i); // TODO: Need to set MotionEventInjector per display. mAms.setMotionEventInjector(null); mMotionEventInjector.onDestroy(); mMotionEventInjector = null; if (injector != null) { injector.onDestroy(); } } mMotionEventInjector.clear(); if (mAutoclickController != null) { mAutoclickController.onDestroy(); mAutoclickController = null; } if (mTouchExplorer != null) { mTouchExplorer.onDestroy(); mTouchExplorer = null; for (int i = mTouchExplorer.size() - 1; i >= 0; i--) { final TouchExplorer explorer = mTouchExplorer.valueAt(i); if (explorer != null) { explorer.onDestroy(); } } if (mMagnificationGestureHandler != null) { mMagnificationGestureHandler.onDestroy(); mMagnificationGestureHandler = null; mTouchExplorer.clear(); for (int i = mMagnificationGestureHandler.size() - 1; i >= 0; i--) { final MagnificationGestureHandler handler = mMagnificationGestureHandler.valueAt(i); if (handler != null) { handler.onDestroy(); } } mMagnificationGestureHandler.clear(); if (mKeyboardInterceptor != null) { mKeyboardInterceptor.onDestroy(); mKeyboardInterceptor = null; } mEventHandler = null; mEventHandler.clear(); resetStreamState(); } Loading Loading @@ -441,41 +521,41 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo * whose events should not be handled by a11y event stream transformations. */ private static class EventStreamState { private int mDeviceId; private int mSource; EventStreamState() { mDeviceId = -1; mSource = -1; } /** * Updates the ID of the device associated with the state. If the ID changes, resets * internal state. * Updates the input source of the device associated with the state. If the source changes, * resets internal state. * * @param deviceId Updated input device ID. * @return Whether the device ID has changed. * @param source Updated input source. * @return Whether the input source has changed. */ public boolean updateDeviceId(int deviceId) { if (mDeviceId == deviceId) { public boolean updateInputSource(int source) { if (mSource == source) { return false; } // Reset clears internal state, so make sure it's called before |mDeviceId| is updated. // Reset clears internal state, so make sure it's called before |mSource| is updated. reset(); mDeviceId = deviceId; mSource = source; return true; } /** * @return Whether device ID is valid. * @return Whether input source is valid. */ public boolean deviceIdValid() { return mDeviceId >= 0; public boolean inputSourceValid() { return mSource >= 0; } /** * Resets the event stream state. */ public void reset() { mDeviceId = -1; mSource = -1; } /** Loading Loading @@ -592,20 +672,19 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo /* * Key events from different devices may be interleaved. For example, the volume up and * down keys can come from different device IDs. * down keys can come from different input sources. */ @Override public boolean updateDeviceId(int deviceId) { public boolean updateInputSource(int deviceId) { return false; } // We manage all device ids simultaneously; there is no concept of validity. // We manage all input source simultaneously; there is no concept of validity. @Override public boolean deviceIdValid() { public boolean inputSourceValid() { return true; } @Override final public boolean shouldProcessKeyEvent(KeyEvent event) { // For each keyboard device, wait for a down event from a device to start processing Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +121 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/view/accessibility/AccessibilityManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -1166,9 +1166,10 @@ public final class AccessibilityManager { /** * Notifies that the accessibility button in the system's navigation area has been clicked * * @param displayId The logical display id. * @hide */ public void notifyAccessibilityButtonClicked() { public void notifyAccessibilityButtonClicked(int displayId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); Loading @@ -1177,7 +1178,7 @@ public final class AccessibilityManager { } } try { service.notifyAccessibilityButtonClicked(); service.notifyAccessibilityButtonClicked(displayId); } catch (RemoteException re) { Log.e(LOG_TAG, "Error while dispatching accessibility button click", re); } Loading
core/java/android/view/accessibility/IAccessibilityManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ interface IAccessibilityManager { IBinder getWindowToken(int windowId, int userId); void notifyAccessibilityButtonClicked(); void notifyAccessibilityButtonClicked(int displayId); void notifyAccessibilityButtonVisibilityChanged(boolean available); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +3 −1 Original line number Diff line number Diff line Loading @@ -802,7 +802,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } private void onAccessibilityClick(View v) { mAccessibilityManager.notifyAccessibilityButtonClicked(); final Display display = v.getDisplay(); mAccessibilityManager.notifyAccessibilityButtonClicked( display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY); } private boolean onAccessibilityLongClick(View v) { Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +163 −84 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ package com.android.server.accessibility; import android.content.Context; import android.os.Handler; import android.os.PowerManager; import android.util.DebugUtils; import android.util.ExceptionUtils; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.Display; import android.view.InputDevice; import android.view.InputEvent; import android.view.InputFilter; Loading @@ -31,10 +29,11 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.accessibility.AccessibilityEvent; import com.android.internal.util.BitUtils; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; import java.util.ArrayList; /** * This class is an input filter for implementing accessibility features such * as display magnification and explore by touch. Loading Loading @@ -108,23 +107,24 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private final AccessibilityManagerService mAms; private boolean mInstalled; private int mUserId; private int mEnabledFeatures; private final SparseArray<EventStreamTransformation> mEventHandler; private TouchExplorer mTouchExplorer; private final SparseArray<TouchExplorer> mTouchExplorer = new SparseArray<>(0); private MagnificationGestureHandler mMagnificationGestureHandler; private final SparseArray<MagnificationGestureHandler> mMagnificationGestureHandler = new SparseArray<>(0); private MotionEventInjector mMotionEventInjector; private final SparseArray<MotionEventInjector> mMotionEventInjector = new SparseArray<>(0); private AutoclickController mAutoclickController; private KeyboardInterceptor mKeyboardInterceptor; private EventStreamTransformation mEventHandler; private boolean mInstalled; private int mUserId; private int mEnabledFeatures; private EventStreamState mMouseStreamState; Loading @@ -133,10 +133,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private EventStreamState mKeyboardStreamState; AccessibilityInputFilter(Context context, AccessibilityManagerService service) { this(context, service, new SparseArray<>(0)); } AccessibilityInputFilter(Context context, AccessibilityManagerService service, SparseArray<EventStreamTransformation> eventHandler) { super(context.getMainLooper()); mContext = context; mAms = service; mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mEventHandler = eventHandler; } @Override Loading @@ -160,6 +166,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo super.onUninstalled(); } void onDisplayChanged() { if (mInstalled) { disableFeatures(); enableFeatures(); } } @Override public void onInputEvent(InputEvent event, int policyFlags) { if (DEBUG) { Loading @@ -167,8 +180,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo + Integer.toHexString(policyFlags)); } if (mEventHandler == null) { if (DEBUG) Slog.d(TAG, "mEventHandler == null for event " + event); if (mEventHandler.size() == 0) { if (DEBUG) Slog.d(TAG, "No mEventHandler for event " + event); super.onInputEvent(event, policyFlags); return; } Loading @@ -182,16 +195,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo int eventSource = event.getSource(); if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) { state.reset(); mEventHandler.clearEvents(eventSource); clearEventsForAllEventHandlers(eventSource); super.onInputEvent(event, policyFlags); return; } if (state.updateDeviceId(event.getDeviceId())) { mEventHandler.clearEvents(eventSource); if (state.updateInputSource(event.getSource())) { clearEventsForAllEventHandlers(eventSource); } if (!state.deviceIdValid()) { if (!state.inputSourceValid()) { super.onInputEvent(event, policyFlags); return; } Loading Loading @@ -240,6 +253,15 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo return null; } private void clearEventsForAllEventHandlers(int eventSource) { for (int i = 0; i < mEventHandler.size(); i++) { final EventStreamTransformation eventHandler = mEventHandler.valueAt(i); if (eventHandler != null) { eventHandler.clearEvents(eventSource); } } } private void processMotionEvent(EventStreamState state, MotionEvent event, int policyFlags) { if (!state.shouldProcessScroll() && event.getActionMasked() == MotionEvent.ACTION_SCROLL) { super.onInputEvent(event, policyFlags); Loading @@ -258,7 +280,10 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo super.onInputEvent(event, policyFlags); return; } mEventHandler.onKeyEvent(event, policyFlags); // Since the display id of KeyEvent always would be -1 and there is only one // KeyboardInterceptor for all display, pass KeyEvent to the mEventHandler of // DEFAULT_DISPLAY to handle. mEventHandler.get(Display.DEFAULT_DISPLAY).onKeyEvent(event, policyFlags); } private void handleMotionEvent(MotionEvent event, int policyFlags) { Loading @@ -267,10 +292,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } mPm.userActivity(event.getEventTime(), false); MotionEvent transformedEvent = MotionEvent.obtain(event); mEventHandler.onMotionEvent(transformedEvent, event, policyFlags); final int displayId = event.getDisplayId(); mEventHandler.get(isDisplayIdValid(displayId) ? displayId : Display.DEFAULT_DISPLAY) .onMotionEvent(transformedEvent, event, policyFlags); transformedEvent.recycle(); } private boolean isDisplayIdValid(int displayId) { return mEventHandler.get(displayId) != null; } @Override public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent, int policyFlags) { Loading Loading @@ -323,14 +354,20 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } void notifyAccessibilityEvent(AccessibilityEvent event) { if (mEventHandler != null) { mEventHandler.onAccessibilityEvent(event); for (int i = 0; i < mEventHandler.size(); i++) { final EventStreamTransformation eventHandler = mEventHandler.valueAt(i); if (eventHandler != null) { eventHandler.onAccessibilityEvent(event); } } } void notifyAccessibilityButtonClicked() { if (mMagnificationGestureHandler != null) { mMagnificationGestureHandler.notifyShortcutTriggered(); void notifyAccessibilityButtonClicked(int displayId) { if (mMagnificationGestureHandler.size() != 0) { final MagnificationGestureHandler handler = mMagnificationGestureHandler.get(displayId); if (handler != null) { handler.notifyShortcutTriggered(); } } } Loading @@ -339,14 +376,20 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo resetStreamState(); final ArrayList<Display> displaysList = mAms.getValidDisplayList(); if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) { mAutoclickController = new AutoclickController(mContext, mUserId); addFirstEventHandler(mAutoclickController); addFirstEventHandlerForAllDisplays(displaysList, mAutoclickController); } for (int i = displaysList.size() - 1; i >= 0; i--) { final int displayId = displaysList.get(i).getDisplayId(); if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { mTouchExplorer = new TouchExplorer(mContext, mAms); addFirstEventHandler(mTouchExplorer); TouchExplorer explorer = new TouchExplorer(mContext, mAms); addFirstEventHandler(displayId, explorer); mTouchExplorer.put(displayId, explorer); } if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 Loading @@ -356,64 +399,101 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0; final boolean triggerable = (mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0; mMagnificationGestureHandler = new MagnificationGestureHandler( mContext, mAms.getMagnificationController(), MagnificationGestureHandler magnificationGestureHandler = new MagnificationGestureHandler(mContext, mAms.getMagnificationController(), detectControlGestures, triggerable); addFirstEventHandler(mMagnificationGestureHandler); addFirstEventHandler(displayId, magnificationGestureHandler); mMagnificationGestureHandler.put(displayId, magnificationGestureHandler); } if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper()); addFirstEventHandler(mMotionEventInjector); mAms.setMotionEventInjector(mMotionEventInjector); MotionEventInjector injector = new MotionEventInjector( mContext.getMainLooper()); addFirstEventHandler(displayId, injector); // TODO: Need to set MotionEventInjector per display. mAms.setMotionEventInjector(injector); mMotionEventInjector.put(displayId, injector); } } if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) { mKeyboardInterceptor = new KeyboardInterceptor(mAms, LocalServices.getService(WindowManagerPolicy.class)); addFirstEventHandler(mKeyboardInterceptor); // Since the display id of KeyEvent always would be -1 and it would be dispatched to // the display with input focus directly, we only need one KeyboardInterceptor for // default display. addFirstEventHandler(Display.DEFAULT_DISPLAY, mKeyboardInterceptor); } } /** * Adds an event handler to the event handler chain. The handler is added at the beginning of * the chain. * Adds an event handler to the event handler chain for giving display. The handler is added at * the beginning of the chain. * * @param displayId The logical display id. * @param handler The handler to be added to the event handlers list. */ private void addFirstEventHandler(EventStreamTransformation handler) { if (mEventHandler != null) { handler.setNext(mEventHandler); private void addFirstEventHandler(int displayId, EventStreamTransformation handler) { EventStreamTransformation eventHandler = mEventHandler.get(displayId); if (eventHandler != null) { handler.setNext(eventHandler); } else { handler.setNext(this); } mEventHandler = handler; eventHandler = handler; mEventHandler.put(displayId, eventHandler); } /** * Adds an event handler to the event handler chain for all displays. The handler is added at * the beginning of the chain. * * @param displayList The list of displays * @param handler The handler to be added to the event handlers list. */ private void addFirstEventHandlerForAllDisplays(ArrayList<Display> displayList, EventStreamTransformation handler) { for (int i = 0; i < displayList.size(); i++) { final int displayId = displayList.get(i).getDisplayId(); addFirstEventHandler(displayId, handler); } } private void disableFeatures() { if (mMotionEventInjector != null) { for (int i = mMotionEventInjector.size() - 1; i >= 0; i--) { final MotionEventInjector injector = mMotionEventInjector.valueAt(i); // TODO: Need to set MotionEventInjector per display. mAms.setMotionEventInjector(null); mMotionEventInjector.onDestroy(); mMotionEventInjector = null; if (injector != null) { injector.onDestroy(); } } mMotionEventInjector.clear(); if (mAutoclickController != null) { mAutoclickController.onDestroy(); mAutoclickController = null; } if (mTouchExplorer != null) { mTouchExplorer.onDestroy(); mTouchExplorer = null; for (int i = mTouchExplorer.size() - 1; i >= 0; i--) { final TouchExplorer explorer = mTouchExplorer.valueAt(i); if (explorer != null) { explorer.onDestroy(); } } if (mMagnificationGestureHandler != null) { mMagnificationGestureHandler.onDestroy(); mMagnificationGestureHandler = null; mTouchExplorer.clear(); for (int i = mMagnificationGestureHandler.size() - 1; i >= 0; i--) { final MagnificationGestureHandler handler = mMagnificationGestureHandler.valueAt(i); if (handler != null) { handler.onDestroy(); } } mMagnificationGestureHandler.clear(); if (mKeyboardInterceptor != null) { mKeyboardInterceptor.onDestroy(); mKeyboardInterceptor = null; } mEventHandler = null; mEventHandler.clear(); resetStreamState(); } Loading Loading @@ -441,41 +521,41 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo * whose events should not be handled by a11y event stream transformations. */ private static class EventStreamState { private int mDeviceId; private int mSource; EventStreamState() { mDeviceId = -1; mSource = -1; } /** * Updates the ID of the device associated with the state. If the ID changes, resets * internal state. * Updates the input source of the device associated with the state. If the source changes, * resets internal state. * * @param deviceId Updated input device ID. * @return Whether the device ID has changed. * @param source Updated input source. * @return Whether the input source has changed. */ public boolean updateDeviceId(int deviceId) { if (mDeviceId == deviceId) { public boolean updateInputSource(int source) { if (mSource == source) { return false; } // Reset clears internal state, so make sure it's called before |mDeviceId| is updated. // Reset clears internal state, so make sure it's called before |mSource| is updated. reset(); mDeviceId = deviceId; mSource = source; return true; } /** * @return Whether device ID is valid. * @return Whether input source is valid. */ public boolean deviceIdValid() { return mDeviceId >= 0; public boolean inputSourceValid() { return mSource >= 0; } /** * Resets the event stream state. */ public void reset() { mDeviceId = -1; mSource = -1; } /** Loading Loading @@ -592,20 +672,19 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo /* * Key events from different devices may be interleaved. For example, the volume up and * down keys can come from different device IDs. * down keys can come from different input sources. */ @Override public boolean updateDeviceId(int deviceId) { public boolean updateInputSource(int deviceId) { return false; } // We manage all device ids simultaneously; there is no concept of validity. // We manage all input source simultaneously; there is no concept of validity. @Override public boolean deviceIdValid() { public boolean inputSourceValid() { return true; } @Override final public boolean shouldProcessKeyEvent(KeyEvent event) { // For each keyboard device, wait for a down event from a device to start processing Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +121 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes