diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index bae2e1ac42aee..7d2b71f7852b9 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY import android.accessibilityservice.AccessibilityTrace; import android.annotation.MainThread; +import android.annotation.NonNull; import android.content.Context; import android.graphics.Region; import android.os.PowerManager; @@ -44,7 +45,10 @@ import com.android.server.accessibility.magnification.WindowMagnificationGesture import com.android.server.accessibility.magnification.WindowMagnificationPromptController; import com.android.server.policy.WindowManagerPolicy; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; +import java.util.StringJoiner; /** * This class is an input filter for implementing accessibility features such @@ -172,9 +176,9 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private int mEnabledFeatures; - private EventStreamState mMouseStreamState; + private final SparseArray mMouseStreamStates = new SparseArray<>(0); - private EventStreamState mTouchScreenStreamState; + private final SparseArray mTouchScreenStreamStates = new SparseArray<>(0); private EventStreamState mKeyboardStreamState; @@ -212,10 +216,17 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo super.onUninstalled(); } - void onDisplayChanged() { + void onDisplayAdded(@NonNull Display display) { if (mInstalled) { - disableFeatures(); - enableFeatures(); + resetStreamStateForDisplay(display.getDisplayId()); + enableFeaturesForDisplay(display); + } + } + + void onDisplayRemoved(int displayId) { + if (mInstalled) { + disableFeaturesForDisplay(displayId); + resetStreamStateForDisplay(displayId); } } @@ -243,16 +254,17 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo return; } - int eventSource = event.getSource(); + final int eventSource = event.getSource(); + final int displayId = event.getDisplayId(); if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) { state.reset(); - clearEventsForAllEventHandlers(eventSource); + clearEventStreamHandler(displayId, eventSource); super.onInputEvent(event, policyFlags); return; } if (state.updateInputSource(event.getSource())) { - clearEventsForAllEventHandlers(eventSource); + clearEventStreamHandler(displayId, eventSource); } if (!state.inputSourceValid()) { @@ -281,35 +293,39 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo */ private EventStreamState getEventStreamState(InputEvent event) { if (event instanceof MotionEvent) { - if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) { - if (mTouchScreenStreamState == null) { - mTouchScreenStreamState = new TouchScreenEventStreamState(); - } - return mTouchScreenStreamState; - } - if (event.isFromSource(InputDevice.SOURCE_MOUSE)) { - if (mMouseStreamState == null) { - mMouseStreamState = new MouseEventStreamState(); - } - return mMouseStreamState; - } + final int displayId = event.getDisplayId(); + + if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) { + EventStreamState touchScreenStreamState = mTouchScreenStreamStates.get(displayId); + if (touchScreenStreamState == null) { + touchScreenStreamState = new TouchScreenEventStreamState(); + mTouchScreenStreamStates.put(displayId, touchScreenStreamState); + } + return touchScreenStreamState; + } + if (event.isFromSource(InputDevice.SOURCE_MOUSE)) { + EventStreamState mouseStreamState = mMouseStreamStates.get(displayId); + if (mouseStreamState == null) { + mouseStreamState = new MouseEventStreamState(); + mMouseStreamStates.put(displayId, mouseStreamState); + } + return mouseStreamState; + } } else if (event instanceof KeyEvent) { - if (event.isFromSource(InputDevice.SOURCE_KEYBOARD)) { - if (mKeyboardStreamState == null) { - mKeyboardStreamState = new KeyboardEventStreamState(); - } - return mKeyboardStreamState; - } + if (event.isFromSource(InputDevice.SOURCE_KEYBOARD)) { + if (mKeyboardStreamState == null) { + mKeyboardStreamState = new KeyboardEventStreamState(); + } + return mKeyboardStreamState; + } } 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 clearEventStreamHandler(int displayId, int eventSource) { + final EventStreamTransformation eventHandler = mEventHandler.get(displayId); + if (eventHandler != null) { + eventHandler.clearEvents(eventSource); } } @@ -425,56 +441,69 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private void enableFeatures() { if (DEBUG) Slog.i(TAG, "enableFeatures()"); - resetStreamState(); + resetAllStreamState(); final ArrayList displaysList = mAms.getValidDisplayList(); - if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) { - mAutoclickController = new AutoclickController( - mContext, mUserId, mAms.getTraceManager()); - addFirstEventHandlerForAllDisplays(displaysList, mAutoclickController); - } - for (int i = displaysList.size() - 1; i >= 0; i--) { - final int displayId = displaysList.get(i).getDisplayId(); - final Context displayContext = mContext.createDisplayContext(displaysList.get(i)); + enableFeaturesForDisplay(displaysList.get(i)); + } + enableDisplayIndependentFeatures(); + } - if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { - TouchExplorer explorer = new TouchExplorer(displayContext, mAms); - if ((mEnabledFeatures & FLAG_SERVICE_HANDLES_DOUBLE_TAP) != 0) { - explorer.setServiceHandlesDoubleTap(true); - } - if ((mEnabledFeatures & FLAG_REQUEST_MULTI_FINGER_GESTURES) != 0) { - explorer.setMultiFingerGesturesEnabled(true); - } - if ((mEnabledFeatures & FLAG_REQUEST_2_FINGER_PASSTHROUGH) != 0) { - explorer.setTwoFingerPassthroughEnabled(true); - } - if ((mEnabledFeatures & FLAG_SEND_MOTION_EVENTS) != 0) { - explorer.setSendMotionEventsEnabled(true); - } - addFirstEventHandler(displayId, explorer); - mTouchExplorer.put(displayId, explorer); - } - - if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 - || ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) - || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0)) { - final MagnificationGestureHandler magnificationGestureHandler = - createMagnificationGestureHandler(displayId, - displayContext); - addFirstEventHandler(displayId, magnificationGestureHandler); - mMagnificationGestureHandler.put(displayId, magnificationGestureHandler); - } - - if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { - MotionEventInjector injector = new MotionEventInjector( - mContext.getMainLooper(), mAms.getTraceManager()); - addFirstEventHandler(displayId, injector); - mMotionEventInjectors.put(displayId, injector); - } + private void enableFeaturesForDisplay(Display display) { + if (DEBUG) { + Slog.i(TAG, "enableFeaturesForDisplay() : display Id = " + display.getDisplayId()); } + final Context displayContext = mContext.createDisplayContext(display); + final int displayId = display.getDisplayId(); + + if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) { + if (mAutoclickController == null) { + mAutoclickController = new AutoclickController( + mContext, mUserId, mAms.getTraceManager()); + } + addFirstEventHandler(displayId, mAutoclickController); + } + + if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { + TouchExplorer explorer = new TouchExplorer(displayContext, mAms); + if ((mEnabledFeatures & FLAG_SERVICE_HANDLES_DOUBLE_TAP) != 0) { + explorer.setServiceHandlesDoubleTap(true); + } + if ((mEnabledFeatures & FLAG_REQUEST_MULTI_FINGER_GESTURES) != 0) { + explorer.setMultiFingerGesturesEnabled(true); + } + if ((mEnabledFeatures & FLAG_REQUEST_2_FINGER_PASSTHROUGH) != 0) { + explorer.setTwoFingerPassthroughEnabled(true); + } + if ((mEnabledFeatures & FLAG_SEND_MOTION_EVENTS) != 0) { + explorer.setSendMotionEventsEnabled(true); + } + addFirstEventHandler(displayId, explorer); + mTouchExplorer.put(displayId, explorer); + } + + if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 + || ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) + || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0)) { + final MagnificationGestureHandler magnificationGestureHandler = + createMagnificationGestureHandler(displayId, + displayContext); + addFirstEventHandler(displayId, magnificationGestureHandler); + mMagnificationGestureHandler.put(displayId, magnificationGestureHandler); + } + + if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { + MotionEventInjector injector = new MotionEventInjector( + mContext.getMainLooper(), mAms.getTraceManager()); + addFirstEventHandler(displayId, injector); + mMotionEventInjectors.put(displayId, injector); + } + } + + private void enableDisplayIndependentFeatures() { if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { mAms.setMotionEventInjectors(mMotionEventInjectors); } @@ -507,55 +536,57 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo 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 displayList, - EventStreamTransformation handler) { - for (int i = 0; i < displayList.size(); i++) { - final int displayId = displayList.get(i).getDisplayId(); - addFirstEventHandler(displayId, handler); + private void disableFeatures() { + final ArrayList displaysList = mAms.getValidDisplayList(); + + for (int i = displaysList.size() - 1; i >= 0; i--) { + disableFeaturesForDisplay(displaysList.get(i).getDisplayId()); + } + mAms.setMotionEventInjectors(null); + disableDisplayIndependentFeatures(); + + resetAllStreamState(); + } + + private void disableFeaturesForDisplay(int displayId) { + if (DEBUG) { + Slog.i(TAG, "disableFeaturesForDisplay() : display Id = " + displayId); + } + + final MotionEventInjector injector = mMotionEventInjectors.get(displayId); + if (injector != null) { + injector.onDestroy(); + mMotionEventInjectors.remove(displayId); + } + + final TouchExplorer explorer = mTouchExplorer.get(displayId); + if (explorer != null) { + explorer.onDestroy(); + mTouchExplorer.remove(displayId); + } + + final MagnificationGestureHandler handler = mMagnificationGestureHandler.get(displayId); + if (handler != null) { + handler.onDestroy(); + mMagnificationGestureHandler.remove(displayId); + } + + final EventStreamTransformation eventStreamTransformation = mEventHandler.get(displayId); + if (eventStreamTransformation != null) { + mEventHandler.remove(displayId); } } - private void disableFeatures() { - for (int i = mMotionEventInjectors.size() - 1; i >= 0; i--) { - final MotionEventInjector injector = mMotionEventInjectors.valueAt(i); - if (injector != null) { - injector.onDestroy(); - } - } - mAms.setMotionEventInjectors(null); - mMotionEventInjectors.clear(); + private void disableDisplayIndependentFeatures() { if (mAutoclickController != null) { mAutoclickController.onDestroy(); mAutoclickController = null; } - for (int i = mTouchExplorer.size() - 1; i >= 0; i--) { - final TouchExplorer explorer = mTouchExplorer.valueAt(i); - if (explorer != null) { - explorer.onDestroy(); - } - } - 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.clear(); - resetStreamState(); } private MagnificationGestureHandler createMagnificationGestureHandler( @@ -584,18 +615,32 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo return magnificationGestureHandler; } - void resetStreamState() { - if (mTouchScreenStreamState != null) { - mTouchScreenStreamState.reset(); - } - if (mMouseStreamState != null) { - mMouseStreamState.reset(); + void resetAllStreamState() { + final ArrayList displaysList = mAms.getValidDisplayList(); + + for (int i = displaysList.size() - 1; i >= 0; i--) { + resetStreamStateForDisplay(displaysList.get(i).getDisplayId()); } + if (mKeyboardStreamState != null) { mKeyboardStreamState.reset(); } } + void resetStreamStateForDisplay(int displayId) { + final EventStreamState touchScreenStreamState = mTouchScreenStreamStates.get(displayId); + if (touchScreenStreamState != null) { + touchScreenStreamState.reset(); + mTouchScreenStreamStates.remove(displayId); + } + + final EventStreamState mouseStreamState = mMouseStreamStates.get(displayId); + if (mouseStreamState != null) { + mouseStreamState.reset(); + mMouseStreamStates.remove(displayId); + } + } + @Override public void onDestroy() { /* ignore */ @@ -846,4 +891,45 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo mTouchExplorer.get(displayId).setTouchExplorationPassthroughRegion(region); } } + + /** + * Dumps all {@link AccessibilityInputFilter}s here. + */ + public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { + if (mEventHandler == null) { + return; + } + pw.append("A11yInputFilter Info : "); + pw.println(); + + final ArrayList displaysList = mAms.getValidDisplayList(); + for (int i = 0; i < displaysList.size(); i++) { + final int displayId = displaysList.get(i).getDisplayId(); + EventStreamTransformation next = mEventHandler.get(displayId); + if (next != null) { + pw.append("Enabled features of Display ["); + pw.append(Integer.toString(displayId)); + pw.append("] = "); + + final StringJoiner joiner = new StringJoiner(",", "[", "]"); + + while (next != null) { + if (next instanceof MagnificationGestureHandler) { + joiner.add("MagnificationGesture"); + } else if (next instanceof KeyboardInterceptor) { + joiner.add("KeyboardInterceptor"); + } else if (next instanceof TouchExplorer) { + joiner.add("TouchExplorer"); + } else if (next instanceof AutoclickController) { + joiner.add("AutoclickController"); + } else if (next instanceof MotionEventInjector) { + joiner.add("MotionEventInjector"); + } + next = next.getNext(); + } + pw.append(joiner.toString()); + } + pw.println(); + } + } } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index ce8943f518ec9..7b2b8e4e50e0e 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -3340,6 +3340,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub pw.println(); } mA11yWindowManager.dump(fd, pw, args); + if (mHasInputFilter && mInputFilter != null) { + mInputFilter.dump(fd, pw, args); + } pw.println("Global client list info:{"); mGlobalClients.dump(pw, " Client list "); pw.println(" Registered clients:{"); @@ -3587,7 +3590,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub synchronized (mLock) { mDisplaysList.add(display); if (mInputFilter != null) { - mInputFilter.onDisplayChanged(); + mInputFilter.onDisplayAdded(display); } AccessibilityUserState userState = getCurrentUserStateLocked(); if (displayId != Display.DEFAULT_DISPLAY) { @@ -3609,7 +3612,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return; } if (mInputFilter != null) { - mInputFilter.onDisplayChanged(); + mInputFilter.onDisplayRemoved(displayId); } AccessibilityUserState userState = getCurrentUserStateLocked(); if (displayId != Display.DEFAULT_DISPLAY) { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java index 80e81d6e7cb96..554f0a4265be0 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java @@ -29,6 +29,7 @@ import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEA import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -176,7 +177,7 @@ public class AccessibilityInputFilterTest { } @Test - public void testEventHandler_shouldChangeAfterOnDisplayChanged() { + public void testEventHandler_shouldIncreaseAndHaveCorrectOrderAfterOnDisplayAdded() { prepareLooper(); // Check if there is only one mEventHandler when there is one default display. @@ -184,13 +185,51 @@ public class AccessibilityInputFilterTest { assertEquals(1, mEventHandler.size()); // Check if it has correct numbers of mEventHandler for corresponding displays. - setDisplayCount(4); - mA11yInputFilter.onDisplayChanged(); - assertEquals(4, mEventHandler.size()); + setDisplayCount(2); + mA11yInputFilter.onDisplayAdded(mDisplayList.get(SECOND_DISPLAY)); + assertEquals(2, mEventHandler.size()); + + EventStreamTransformation next = mEventHandler.get(SECOND_DISPLAY); + assertNotNull(next); + + // Start from index 1 because KeyboardInterceptor only exists in EventHandler for + // DEFAULT_DISPLAY. + for (int i = 1; next != null; i++) { + assertEquals(next.getClass(), mExpectedEventHandlerTypes[i]); + next = next.getNext(); + } + } + + @Test + public void testEventHandler_shouldDecreaseAfterOnDisplayRemoved() { + prepareLooper(); setDisplayCount(2); - mA11yInputFilter.onDisplayChanged(); + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); assertEquals(2, mEventHandler.size()); + + // Check if it has correct numbers of mEventHandler for corresponding displays. + mA11yInputFilter.onDisplayRemoved(SECOND_DISPLAY); + assertEquals(1, mEventHandler.size()); + + EventStreamTransformation eventHandler = mEventHandler.get(SECOND_DISPLAY); + assertNull(eventHandler); + } + + @Test + public void testEventHandler_shouldNoChangedInOtherDisplayAfterOnDisplayRemoved() { + prepareLooper(); + + setDisplayCount(2); + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + EventStreamTransformation eventHandlerBeforeDisplayRemoved = + mEventHandler.get(DEFAULT_DISPLAY); + + mA11yInputFilter.onDisplayRemoved(SECOND_DISPLAY); + EventStreamTransformation eventHandlerAfterDisplayRemoved = + mEventHandler.get(DEFAULT_DISPLAY); + + assertEquals(eventHandlerBeforeDisplayRemoved, eventHandlerAfterDisplayRemoved); } @Test @@ -240,7 +279,7 @@ public class AccessibilityInputFilterTest { } @Test - public void testInputEvent_shouldClearEventsForAllEventHandlers() { + public void testInputEvent_shouldClearEventsForDisplayEventHandlers() { prepareLooper(); mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); @@ -253,12 +292,70 @@ public class AccessibilityInputFilterTest { send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); assertEquals(2, mCaptor1.mEvents.size()); - // InputEvent with different input source should trigger clearEvents() for each - // EventStreamTransformation in EventHandler. + // InputEvent with different input source to the same display should trigger + // clearEvents() for the EventHandler in this display. send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_MOUSE)); assertEquals(1, mCaptor1.mEvents.size()); } + @Test + public void testInputEvent_shouldNotClearEventsForOtherDisplayEventHandlers() { + prepareLooper(); + + setDisplayCount(2); + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + assertEquals(2, mEventHandler.size()); + + mCaptor1 = new EventCaptor(); + mCaptor2 = new EventCaptor(); + mEventHandler.put(DEFAULT_DISPLAY, mCaptor1); + mEventHandler.put(SECOND_DISPLAY, mCaptor2); + + // InputEvent with different displayId should be dispatched to corresponding EventHandler. + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + send(downEvent(SECOND_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + + // InputEvent with different input source should not trigger clearEvents() for + // the EventHandler in the other display. + send(downEvent(SECOND_DISPLAY, InputDevice.SOURCE_MOUSE)); + assertEquals(2, mCaptor1.mEvents.size()); + } + + @Test + public void testInputEvent_shouldNotClearEventsForOtherDisplayAfterOnDisplayAdded() { + prepareLooper(); + + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + mCaptor1 = new EventCaptor(); + mEventHandler.put(DEFAULT_DISPLAY, mCaptor1); + + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + assertEquals(2, mCaptor1.mEvents.size()); + + setDisplayCount(2); + mA11yInputFilter.onDisplayAdded(mDisplayList.get(SECOND_DISPLAY)); + assertEquals(2, mCaptor1.mEvents.size()); + } + + @Test + public void testInputEvent_shouldNotClearEventsForOtherDisplayAfterOnDisplayRemoved() { + prepareLooper(); + + setDisplayCount(2); + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + mCaptor1 = new EventCaptor(); + mEventHandler.put(DEFAULT_DISPLAY, mCaptor1); + + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); + assertEquals(2, mCaptor1.mEvents.size()); + + mA11yInputFilter.onDisplayRemoved(SECOND_DISPLAY); + assertEquals(2, mCaptor1.mEvents.size()); + } + @Test public void testEnabledFeatures_windowMagnificationMode_expectedMagnificationGestureHandler() { prepareLooper();