Merge "Reset the features in A11yInputFilter per display" into sc-v2-dev

This commit is contained in:
Jacky Kao
2021-07-06 04:58:27 +00:00
committed by Android (Google) Code Review
3 changed files with 315 additions and 129 deletions

View File

@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
import android.accessibilityservice.AccessibilityTrace; import android.accessibilityservice.AccessibilityTrace;
import android.annotation.MainThread; import android.annotation.MainThread;
import android.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.graphics.Region; import android.graphics.Region;
import android.os.PowerManager; 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.accessibility.magnification.WindowMagnificationPromptController;
import com.android.server.policy.WindowManagerPolicy; import com.android.server.policy.WindowManagerPolicy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.StringJoiner;
/** /**
* This class is an input filter for implementing accessibility features such * 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 int mEnabledFeatures;
private EventStreamState mMouseStreamState; private final SparseArray<EventStreamState> mMouseStreamStates = new SparseArray<>(0);
private EventStreamState mTouchScreenStreamState; private final SparseArray<EventStreamState> mTouchScreenStreamStates = new SparseArray<>(0);
private EventStreamState mKeyboardStreamState; private EventStreamState mKeyboardStreamState;
@@ -212,10 +216,17 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
super.onUninstalled(); super.onUninstalled();
} }
void onDisplayChanged() { void onDisplayAdded(@NonNull Display display) {
if (mInstalled) { if (mInstalled) {
disableFeatures(); resetStreamStateForDisplay(display.getDisplayId());
enableFeatures(); enableFeaturesForDisplay(display);
}
}
void onDisplayRemoved(int displayId) {
if (mInstalled) {
disableFeaturesForDisplay(displayId);
resetStreamStateForDisplay(displayId);
} }
} }
@@ -243,16 +254,17 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
return; return;
} }
int eventSource = event.getSource(); final int eventSource = event.getSource();
final int displayId = event.getDisplayId();
if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) { if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
state.reset(); state.reset();
clearEventsForAllEventHandlers(eventSource); clearEventStreamHandler(displayId, eventSource);
super.onInputEvent(event, policyFlags); super.onInputEvent(event, policyFlags);
return; return;
} }
if (state.updateInputSource(event.getSource())) { if (state.updateInputSource(event.getSource())) {
clearEventsForAllEventHandlers(eventSource); clearEventStreamHandler(displayId, eventSource);
} }
if (!state.inputSourceValid()) { if (!state.inputSourceValid()) {
@@ -281,35 +293,39 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
*/ */
private EventStreamState getEventStreamState(InputEvent event) { private EventStreamState getEventStreamState(InputEvent event) {
if (event instanceof MotionEvent) { if (event instanceof MotionEvent) {
if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) { final int displayId = event.getDisplayId();
if (mTouchScreenStreamState == null) {
mTouchScreenStreamState = new TouchScreenEventStreamState(); if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) {
} EventStreamState touchScreenStreamState = mTouchScreenStreamStates.get(displayId);
return mTouchScreenStreamState; if (touchScreenStreamState == null) {
} touchScreenStreamState = new TouchScreenEventStreamState();
if (event.isFromSource(InputDevice.SOURCE_MOUSE)) { mTouchScreenStreamStates.put(displayId, touchScreenStreamState);
if (mMouseStreamState == null) { }
mMouseStreamState = new MouseEventStreamState(); return touchScreenStreamState;
} }
return mMouseStreamState; 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) { } else if (event instanceof KeyEvent) {
if (event.isFromSource(InputDevice.SOURCE_KEYBOARD)) { if (event.isFromSource(InputDevice.SOURCE_KEYBOARD)) {
if (mKeyboardStreamState == null) { if (mKeyboardStreamState == null) {
mKeyboardStreamState = new KeyboardEventStreamState(); mKeyboardStreamState = new KeyboardEventStreamState();
} }
return mKeyboardStreamState; return mKeyboardStreamState;
} }
} }
return null; return null;
} }
private void clearEventsForAllEventHandlers(int eventSource) { private void clearEventStreamHandler(int displayId, int eventSource) {
for (int i = 0; i < mEventHandler.size(); i++) { final EventStreamTransformation eventHandler = mEventHandler.get(displayId);
final EventStreamTransformation eventHandler = mEventHandler.valueAt(i); if (eventHandler != null) {
if (eventHandler != null) { eventHandler.clearEvents(eventSource);
eventHandler.clearEvents(eventSource);
}
} }
} }
@@ -425,56 +441,69 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
private void enableFeatures() { private void enableFeatures() {
if (DEBUG) Slog.i(TAG, "enableFeatures()"); if (DEBUG) Slog.i(TAG, "enableFeatures()");
resetStreamState(); resetAllStreamState();
final ArrayList<Display> displaysList = mAms.getValidDisplayList(); final ArrayList<Display> 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--) { for (int i = displaysList.size() - 1; i >= 0; i--) {
final int displayId = displaysList.get(i).getDisplayId(); enableFeaturesForDisplay(displaysList.get(i));
final Context displayContext = mContext.createDisplayContext(displaysList.get(i)); }
enableDisplayIndependentFeatures();
}
if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { private void enableFeaturesForDisplay(Display display) {
TouchExplorer explorer = new TouchExplorer(displayContext, mAms); if (DEBUG) {
if ((mEnabledFeatures & FLAG_SERVICE_HANDLES_DOUBLE_TAP) != 0) { Slog.i(TAG, "enableFeaturesForDisplay() : display Id = " + display.getDisplayId());
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);
}
} }
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) { if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
mAms.setMotionEventInjectors(mMotionEventInjectors); mAms.setMotionEventInjectors(mMotionEventInjectors);
} }
@@ -507,55 +536,57 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
mEventHandler.put(displayId, eventHandler); mEventHandler.put(displayId, eventHandler);
} }
/** private void disableFeatures() {
* Adds an event handler to the event handler chain for all displays. The handler is added at final ArrayList<Display> displaysList = mAms.getValidDisplayList();
* the beginning of the chain.
* for (int i = displaysList.size() - 1; i >= 0; i--) {
* @param displayList The list of displays disableFeaturesForDisplay(displaysList.get(i).getDisplayId());
* @param handler The handler to be added to the event handlers list. }
*/ mAms.setMotionEventInjectors(null);
private void addFirstEventHandlerForAllDisplays(ArrayList<Display> displayList, disableDisplayIndependentFeatures();
EventStreamTransformation handler) {
for (int i = 0; i < displayList.size(); i++) { resetAllStreamState();
final int displayId = displayList.get(i).getDisplayId(); }
addFirstEventHandler(displayId, handler);
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() { private void disableDisplayIndependentFeatures() {
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();
if (mAutoclickController != null) { if (mAutoclickController != null) {
mAutoclickController.onDestroy(); mAutoclickController.onDestroy();
mAutoclickController = null; 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) { if (mKeyboardInterceptor != null) {
mKeyboardInterceptor.onDestroy(); mKeyboardInterceptor.onDestroy();
mKeyboardInterceptor = null; mKeyboardInterceptor = null;
} }
mEventHandler.clear();
resetStreamState();
} }
private MagnificationGestureHandler createMagnificationGestureHandler( private MagnificationGestureHandler createMagnificationGestureHandler(
@@ -584,18 +615,32 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
return magnificationGestureHandler; return magnificationGestureHandler;
} }
void resetStreamState() { void resetAllStreamState() {
if (mTouchScreenStreamState != null) { final ArrayList<Display> displaysList = mAms.getValidDisplayList();
mTouchScreenStreamState.reset();
} for (int i = displaysList.size() - 1; i >= 0; i--) {
if (mMouseStreamState != null) { resetStreamStateForDisplay(displaysList.get(i).getDisplayId());
mMouseStreamState.reset();
} }
if (mKeyboardStreamState != null) { if (mKeyboardStreamState != null) {
mKeyboardStreamState.reset(); 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 @Override
public void onDestroy() { public void onDestroy() {
/* ignore */ /* ignore */
@@ -846,4 +891,45 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
mTouchExplorer.get(displayId).setTouchExplorationPassthroughRegion(region); 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<Display> 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();
}
}
} }

View File

@@ -3338,6 +3338,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
pw.println(); pw.println();
} }
mA11yWindowManager.dump(fd, pw, args); mA11yWindowManager.dump(fd, pw, args);
if (mHasInputFilter && mInputFilter != null) {
mInputFilter.dump(fd, pw, args);
}
pw.println("Global client list info:{"); pw.println("Global client list info:{");
mGlobalClients.dump(pw, " Client list "); mGlobalClients.dump(pw, " Client list ");
pw.println(" Registered clients:{"); pw.println(" Registered clients:{");
@@ -3585,7 +3588,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
synchronized (mLock) { synchronized (mLock) {
mDisplaysList.add(display); mDisplaysList.add(display);
if (mInputFilter != null) { if (mInputFilter != null) {
mInputFilter.onDisplayChanged(); mInputFilter.onDisplayAdded(display);
} }
AccessibilityUserState userState = getCurrentUserStateLocked(); AccessibilityUserState userState = getCurrentUserStateLocked();
if (displayId != Display.DEFAULT_DISPLAY) { if (displayId != Display.DEFAULT_DISPLAY) {
@@ -3607,7 +3610,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return; return;
} }
if (mInputFilter != null) { if (mInputFilter != null) {
mInputFilter.onDisplayChanged(); mInputFilter.onDisplayRemoved(displayId);
} }
AccessibilityUserState userState = getCurrentUserStateLocked(); AccessibilityUserState userState = getCurrentUserStateLocked();
if (displayId != Display.DEFAULT_DISPLAY) { if (displayId != Display.DEFAULT_DISPLAY) {

View File

@@ -29,6 +29,7 @@ import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEA
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -176,7 +177,7 @@ public class AccessibilityInputFilterTest {
} }
@Test @Test
public void testEventHandler_shouldChangeAfterOnDisplayChanged() { public void testEventHandler_shouldIncreaseAndHaveCorrectOrderAfterOnDisplayAdded() {
prepareLooper(); prepareLooper();
// Check if there is only one mEventHandler when there is one default display. // Check if there is only one mEventHandler when there is one default display.
@@ -184,13 +185,51 @@ public class AccessibilityInputFilterTest {
assertEquals(1, mEventHandler.size()); assertEquals(1, mEventHandler.size());
// Check if it has correct numbers of mEventHandler for corresponding displays. // Check if it has correct numbers of mEventHandler for corresponding displays.
setDisplayCount(4); setDisplayCount(2);
mA11yInputFilter.onDisplayChanged(); mA11yInputFilter.onDisplayAdded(mDisplayList.get(SECOND_DISPLAY));
assertEquals(4, mEventHandler.size()); 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); setDisplayCount(2);
mA11yInputFilter.onDisplayChanged(); mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures);
assertEquals(2, mEventHandler.size()); 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 @Test
@@ -240,7 +279,7 @@ public class AccessibilityInputFilterTest {
} }
@Test @Test
public void testInputEvent_shouldClearEventsForAllEventHandlers() { public void testInputEvent_shouldClearEventsForDisplayEventHandlers() {
prepareLooper(); prepareLooper();
mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures);
@@ -253,12 +292,70 @@ public class AccessibilityInputFilterTest {
send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN)); send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_TOUCHSCREEN));
assertEquals(2, mCaptor1.mEvents.size()); assertEquals(2, mCaptor1.mEvents.size());
// InputEvent with different input source should trigger clearEvents() for each // InputEvent with different input source to the same display should trigger
// EventStreamTransformation in EventHandler. // clearEvents() for the EventHandler in this display.
send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_MOUSE)); send(downEvent(DEFAULT_DISPLAY, InputDevice.SOURCE_MOUSE));
assertEquals(1, mCaptor1.mEvents.size()); 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 @Test
public void testEnabledFeatures_windowMagnificationMode_expectedMagnificationGestureHandler() { public void testEnabledFeatures_windowMagnificationMode_expectedMagnificationGestureHandler() {
prepareLooper(); prepareLooper();