Loading services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java +23 −25 Original line number Diff line number Diff line Loading @@ -136,6 +136,10 @@ public class AutoclickController extends BaseEventStreamTransformation { if (clickType != AUTOCLICK_TYPE_SCROLL && mAutoclickScrollPanel != null) { mAutoclickScrollPanel.hide(); } if (clickType != AUTOCLICK_TYPE_DRAG && mDragModeIsDragging) { mClickScheduler.clearDraggingState(); } } @Override Loading Loading @@ -936,6 +940,12 @@ public class AutoclickController extends BaseEventStreamTransformation { return; } // Always triggers left-click when the cursor hovers over the autoclick type panel, to // always allow users to change a different click type. Otherwise, if one chooses the // right-click, this user won't be able to rely on autoclick to select other click // types. int selectedClickType = mHoveredState ? AUTOCLICK_TYPE_LEFT_CLICK : mActiveClickType; // Handle scroll-specific click behavior. if (handleScrollClick()) { return; Loading @@ -959,17 +969,7 @@ public class AutoclickController extends BaseEventStreamTransformation { final long now = SystemClock.uptimeMillis(); int actionButton = BUTTON_PRIMARY; if (mHoveredState) { // Always triggers left-click when the cursor hovers over the autoclick type // panel, to always allow users to change a different click type. Otherwise, if // one chooses the right-click, this user won't be able to rely on autoclick to // select other click types. actionButton = BUTTON_PRIMARY; } else { switch (mActiveClickType) { case AUTOCLICK_TYPE_LEFT_CLICK: actionButton = BUTTON_PRIMARY; break; switch (selectedClickType) { case AUTOCLICK_TYPE_RIGHT_CLICK: actionButton = BUTTON_SECONDARY; break; Loading @@ -989,8 +989,6 @@ public class AutoclickController extends BaseEventStreamTransformation { default: break; } } sendMotionEvent(actionButton, now); } Loading services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java +105 −84 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public class AutoclickControllerTest { @Mock private AccessibilityTraceManager mMockTrace; @Mock private WindowManager mMockWindowManager; private AutoclickController mController; private MotionEventCaptor mMotionEventCaptor; private static class MotionEventCaptor extends BaseEventStreamTransformation { public MotionEvent downEvent; Loading Loading @@ -677,31 +678,21 @@ public class AutoclickControllerTest { @Test public void sendClick_clickType_leftClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 0, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify left click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); } @Test public void sendClick_clickType_rightClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -714,20 +705,15 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify right click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_SECONDARY); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_scroll_showsScrollPanelOnlyOnce() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to scroll. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -743,7 +729,7 @@ public class AutoclickControllerTest { // Verify scroll panel is shown once. verify(mockScrollPanel, times(1)).show(anyFloat(), anyFloat()); assertThat(motionEventCaptor.downEvent).isNull(); assertThat(mMotionEventCaptor.downEvent).isNull(); // Second significant hover move event to trigger another autoclick. injectFakeMouseMoveEvent(/* x= */ 100f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); Loading @@ -751,7 +737,7 @@ public class AutoclickControllerTest { // Verify scroll panel is still only shown once (not called again). verify(mockScrollPanel, times(1)).show(anyFloat(), anyFloat()); assertThat(motionEventCaptor.downEvent).isNull(); assertThat(mMotionEventCaptor.downEvent).isNull(); } @Test Loading @@ -774,12 +760,7 @@ public class AutoclickControllerTest { @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_rightClickType_forceTriggerLeftClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -794,9 +775,60 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify left click is sent due to the mouse hovering the panel. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_dragClickType_forceTriggerLeftClick() { initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( AutoclickTypePanel.AUTOCLICK_TYPE_DRAG); // Set mouse to hover panel. AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class); when(mockAutoclickTypePanel.isHovered()).thenReturn(true); mController.mAutoclickTypePanel = mockAutoclickTypePanel; // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify both the down and up left click events are sent due to the mouse hovering the // panel. assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mController.isDraggingForTesting()).isFalse(); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_scrollClickType_forceTriggerLeftClick() { initializeAutoclick(); // Set click type to scrolling click. mController.clickPanelController.handleAutoclickTypeChange( AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL); // Set mouse to hover panel. AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class); when(mockAutoclickTypePanel.isHovered()).thenReturn(true); mController.mAutoclickTypePanel = mockAutoclickTypePanel; // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify left click is sent and the scroll panel is hidden due to the mouse hovering the // panel. assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(mController.mAutoclickScrollPanel.isVisible()).isFalse(); } @Test Loading Loading @@ -992,12 +1024,7 @@ public class AutoclickControllerTest { @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_doubleclick_triggerClickTwice() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to double click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1010,22 +1037,17 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify left click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(motionEventCaptor.eventCount).isEqualTo( assertThat(mMotionEventCaptor.eventCount).isEqualTo( getNumEventsExpectedFromClick(/* numClicks= */ 2)); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_simulateDragging() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to drag click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1035,55 +1057,50 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify only two motion events were sent. assertThat(motionEventCaptor.eventCount).isEqualTo(2); assertThat(mMotionEventCaptor.eventCount).isEqualTo(2); // Verify both events have the same down time. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.buttonPressEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getDownTime()).isEqualTo( motionEventCaptor.buttonPressEvent.getDownTime()); assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.buttonPressEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getDownTime()).isEqualTo( mMotionEventCaptor.buttonPressEvent.getDownTime()); // Move the mouse again to simulate dragging and verify the new mouse event is // transformed to a MOVE action and its down time matches the drag initiating click's // down time. injectFakeMouseMoveEvent(/* x= */ 40, /* y= */ 0, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); assertThat(motionEventCaptor.eventCount).isEqualTo(3); assertThat(motionEventCaptor.moveEvent).isNotNull(); assertThat(motionEventCaptor.moveEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.eventCount).isEqualTo(3); assertThat(mMotionEventCaptor.moveEvent).isNotNull(); assertThat(mMotionEventCaptor.moveEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); // Move the mouse again further now to simulate ending the drag session. motionEventCaptor.moveEvent = null; motionEventCaptor.eventCount = 0; mMotionEventCaptor.moveEvent = null; mMotionEventCaptor.eventCount = 0; injectFakeMouseMoveEvent(/* x= */ 300, /* y= */ 300, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify the final 3 clicks were sent: the 1 move event + 2 up type events to end the drag. assertThat(motionEventCaptor.eventCount).isEqualTo(3); assertThat(mMotionEventCaptor.eventCount).isEqualTo(3); // Verify each event matches the same down time as the initiating drag click. assertThat(motionEventCaptor.moveEvent).isNotNull(); assertThat(motionEventCaptor.moveEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(motionEventCaptor.buttonReleaseEvent).isNotNull(); assertThat(motionEventCaptor.buttonReleaseEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(motionEventCaptor.upEvent).isNotNull(); assertThat(motionEventCaptor.upEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.moveEvent).isNotNull(); assertThat(mMotionEventCaptor.moveEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.buttonReleaseEvent).isNotNull(); assertThat(mMotionEventCaptor.buttonReleaseEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mMotionEventCaptor.upEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_keyEventCancelsDrag() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to drag click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1104,21 +1121,16 @@ public class AutoclickControllerTest { assertThat(mController.isDraggingForTesting()).isFalse(); // Verify the ACTION_UP was sent for alerting the system that dragging has ended. assertThat(motionEventCaptor.upEvent).isNotNull(); assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.upEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.upEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_clickTypeDoesNotRevertAfterFirstClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set ACCESSIBILITY_AUTOCLICK_REVERT_TO_LEFT_CLICK to true. Settings.Secure.putIntForUser(mTestableContext.getContentResolver(), Loading Loading @@ -1206,4 +1218,13 @@ public class AutoclickControllerTest { private int getNumEventsExpectedFromClick(int numClicks) { return numClicks * 4; } private void initializeAutoclick() { mMotionEventCaptor = new MotionEventCaptor(); mController.setNext(mMotionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); } } Loading
services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java +23 −25 Original line number Diff line number Diff line Loading @@ -136,6 +136,10 @@ public class AutoclickController extends BaseEventStreamTransformation { if (clickType != AUTOCLICK_TYPE_SCROLL && mAutoclickScrollPanel != null) { mAutoclickScrollPanel.hide(); } if (clickType != AUTOCLICK_TYPE_DRAG && mDragModeIsDragging) { mClickScheduler.clearDraggingState(); } } @Override Loading Loading @@ -936,6 +940,12 @@ public class AutoclickController extends BaseEventStreamTransformation { return; } // Always triggers left-click when the cursor hovers over the autoclick type panel, to // always allow users to change a different click type. Otherwise, if one chooses the // right-click, this user won't be able to rely on autoclick to select other click // types. int selectedClickType = mHoveredState ? AUTOCLICK_TYPE_LEFT_CLICK : mActiveClickType; // Handle scroll-specific click behavior. if (handleScrollClick()) { return; Loading @@ -959,17 +969,7 @@ public class AutoclickController extends BaseEventStreamTransformation { final long now = SystemClock.uptimeMillis(); int actionButton = BUTTON_PRIMARY; if (mHoveredState) { // Always triggers left-click when the cursor hovers over the autoclick type // panel, to always allow users to change a different click type. Otherwise, if // one chooses the right-click, this user won't be able to rely on autoclick to // select other click types. actionButton = BUTTON_PRIMARY; } else { switch (mActiveClickType) { case AUTOCLICK_TYPE_LEFT_CLICK: actionButton = BUTTON_PRIMARY; break; switch (selectedClickType) { case AUTOCLICK_TYPE_RIGHT_CLICK: actionButton = BUTTON_SECONDARY; break; Loading @@ -989,8 +989,6 @@ public class AutoclickController extends BaseEventStreamTransformation { default: break; } } sendMotionEvent(actionButton, now); } Loading
services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java +105 −84 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public class AutoclickControllerTest { @Mock private AccessibilityTraceManager mMockTrace; @Mock private WindowManager mMockWindowManager; private AutoclickController mController; private MotionEventCaptor mMotionEventCaptor; private static class MotionEventCaptor extends BaseEventStreamTransformation { public MotionEvent downEvent; Loading Loading @@ -677,31 +678,21 @@ public class AutoclickControllerTest { @Test public void sendClick_clickType_leftClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 0, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify left click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); } @Test public void sendClick_clickType_rightClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -714,20 +705,15 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify right click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_SECONDARY); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_scroll_showsScrollPanelOnlyOnce() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to scroll. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -743,7 +729,7 @@ public class AutoclickControllerTest { // Verify scroll panel is shown once. verify(mockScrollPanel, times(1)).show(anyFloat(), anyFloat()); assertThat(motionEventCaptor.downEvent).isNull(); assertThat(mMotionEventCaptor.downEvent).isNull(); // Second significant hover move event to trigger another autoclick. injectFakeMouseMoveEvent(/* x= */ 100f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); Loading @@ -751,7 +737,7 @@ public class AutoclickControllerTest { // Verify scroll panel is still only shown once (not called again). verify(mockScrollPanel, times(1)).show(anyFloat(), anyFloat()); assertThat(motionEventCaptor.downEvent).isNull(); assertThat(mMotionEventCaptor.downEvent).isNull(); } @Test Loading @@ -774,12 +760,7 @@ public class AutoclickControllerTest { @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_rightClickType_forceTriggerLeftClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -794,9 +775,60 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify left click is sent due to the mouse hovering the panel. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_dragClickType_forceTriggerLeftClick() { initializeAutoclick(); // Set click type to right click. mController.clickPanelController.handleAutoclickTypeChange( AutoclickTypePanel.AUTOCLICK_TYPE_DRAG); // Set mouse to hover panel. AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class); when(mockAutoclickTypePanel.isHovered()).thenReturn(true); mController.mAutoclickTypePanel = mockAutoclickTypePanel; // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify both the down and up left click events are sent due to the mouse hovering the // panel. assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mController.isDraggingForTesting()).isFalse(); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void hoverOnAutoclickPanel_scrollClickType_forceTriggerLeftClick() { initializeAutoclick(); // Set click type to scrolling click. mController.clickPanelController.handleAutoclickTypeChange( AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL); // Set mouse to hover panel. AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class); when(mockAutoclickTypePanel.isHovered()).thenReturn(true); mController.mAutoclickTypePanel = mockAutoclickTypePanel; // Send hover move event. injectFakeMouseMoveEvent(/* x= */ 30f, /* y= */ 100f, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify left click is sent and the scroll panel is hidden due to the mouse hovering the // panel. assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(mController.mAutoclickScrollPanel.isVisible()).isFalse(); } @Test Loading Loading @@ -992,12 +1024,7 @@ public class AutoclickControllerTest { @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_doubleclick_triggerClickTwice() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to double click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1010,22 +1037,17 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify left click sent. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getButtonState()).isEqualTo( MotionEvent.BUTTON_PRIMARY); assertThat(motionEventCaptor.eventCount).isEqualTo( assertThat(mMotionEventCaptor.eventCount).isEqualTo( getNumEventsExpectedFromClick(/* numClicks= */ 2)); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_simulateDragging() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to drag click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1035,55 +1057,50 @@ public class AutoclickControllerTest { mTestableLooper.processAllMessages(); // Verify only two motion events were sent. assertThat(motionEventCaptor.eventCount).isEqualTo(2); assertThat(mMotionEventCaptor.eventCount).isEqualTo(2); // Verify both events have the same down time. assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.buttonPressEvent).isNotNull(); assertThat(motionEventCaptor.downEvent.getDownTime()).isEqualTo( motionEventCaptor.buttonPressEvent.getDownTime()); assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.buttonPressEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent.getDownTime()).isEqualTo( mMotionEventCaptor.buttonPressEvent.getDownTime()); // Move the mouse again to simulate dragging and verify the new mouse event is // transformed to a MOVE action and its down time matches the drag initiating click's // down time. injectFakeMouseMoveEvent(/* x= */ 40, /* y= */ 0, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); assertThat(motionEventCaptor.eventCount).isEqualTo(3); assertThat(motionEventCaptor.moveEvent).isNotNull(); assertThat(motionEventCaptor.moveEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.eventCount).isEqualTo(3); assertThat(mMotionEventCaptor.moveEvent).isNotNull(); assertThat(mMotionEventCaptor.moveEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); // Move the mouse again further now to simulate ending the drag session. motionEventCaptor.moveEvent = null; motionEventCaptor.eventCount = 0; mMotionEventCaptor.moveEvent = null; mMotionEventCaptor.eventCount = 0; injectFakeMouseMoveEvent(/* x= */ 300, /* y= */ 300, MotionEvent.ACTION_HOVER_MOVE); mTestableLooper.processAllMessages(); // Verify the final 3 clicks were sent: the 1 move event + 2 up type events to end the drag. assertThat(motionEventCaptor.eventCount).isEqualTo(3); assertThat(mMotionEventCaptor.eventCount).isEqualTo(3); // Verify each event matches the same down time as the initiating drag click. assertThat(motionEventCaptor.moveEvent).isNotNull(); assertThat(motionEventCaptor.moveEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(motionEventCaptor.buttonReleaseEvent).isNotNull(); assertThat(motionEventCaptor.buttonReleaseEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(motionEventCaptor.upEvent).isNotNull(); assertThat(motionEventCaptor.upEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.moveEvent).isNotNull(); assertThat(mMotionEventCaptor.moveEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.buttonReleaseEvent).isNotNull(); assertThat(mMotionEventCaptor.buttonReleaseEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mMotionEventCaptor.upEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_keyEventCancelsDrag() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set click type to drag click. mController.clickPanelController.handleAutoclickTypeChange( Loading @@ -1104,21 +1121,16 @@ public class AutoclickControllerTest { assertThat(mController.isDraggingForTesting()).isFalse(); // Verify the ACTION_UP was sent for alerting the system that dragging has ended. assertThat(motionEventCaptor.upEvent).isNotNull(); assertThat(motionEventCaptor.downEvent).isNotNull(); assertThat(motionEventCaptor.upEvent.getDownTime()).isEqualTo( motionEventCaptor.downEvent.getDownTime()); assertThat(mMotionEventCaptor.upEvent).isNotNull(); assertThat(mMotionEventCaptor.downEvent).isNotNull(); assertThat(mMotionEventCaptor.upEvent.getDownTime()).isEqualTo( mMotionEventCaptor.downEvent.getDownTime()); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) public void sendClick_clickType_drag_clickTypeDoesNotRevertAfterFirstClick() { MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); mController.setNext(motionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); initializeAutoclick(); // Set ACCESSIBILITY_AUTOCLICK_REVERT_TO_LEFT_CLICK to true. Settings.Secure.putIntForUser(mTestableContext.getContentResolver(), Loading Loading @@ -1206,4 +1218,13 @@ public class AutoclickControllerTest { private int getNumEventsExpectedFromClick(int numClicks) { return numClicks * 4; } private void initializeAutoclick() { mMotionEventCaptor = new MotionEventCaptor(); mController.setNext(mMotionEventCaptor); injectFakeMouseActionHoverMoveEvent(); // Set delay to zero so click is scheduled to run immediately. mController.mClickScheduler.updateDelay(0); } }