summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java108
2 files changed, 128 insertions, 9 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
index 739ea0df87ab..cc93d0887d89 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
@@ -248,7 +248,11 @@ public class AutoclickController extends BaseEventStreamTransformation {
private boolean isPaused() {
return Flags.enableAutoclickIndicator() && mAutoclickTypePanel.isPaused()
- && !mAutoclickTypePanel.isHovered();
+ && !isHovered();
+ }
+
+ private boolean isHovered() {
+ return Flags.enableAutoclickIndicator() && mAutoclickTypePanel.isHovered();
}
private void cancelPendingClick() {
@@ -495,6 +499,8 @@ public class AutoclickController extends BaseEventStreamTransformation {
private int mEventPolicyFlags;
/** Current meta state. This value will be used as meta state for click event sequence. */
private int mMetaState;
+ /** Last observed panel hovered state when click was scheduled. */
+ private boolean mHoveredState;
/**
* The current anchor's coordinates. Should be ignored if #mLastMotionEvent is null.
@@ -648,6 +654,7 @@ public class AutoclickController extends BaseEventStreamTransformation {
}
mLastMotionEvent = MotionEvent.obtain(event);
mEventPolicyFlags = policyFlags;
+ mHoveredState = isHovered();
if (useAsAnchor) {
final int pointerIndex = mLastMotionEvent.getActionIndex();
@@ -729,14 +736,18 @@ public class AutoclickController extends BaseEventStreamTransformation {
final long now = SystemClock.uptimeMillis();
- // TODO(b/395094903): 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.
- final int actionButton =
- mActiveClickType == AUTOCLICK_TYPE_RIGHT_CLICK
- ? BUTTON_SECONDARY
- : BUTTON_PRIMARY;
+ int actionButton;
+ 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 {
+ actionButton = mActiveClickType == AUTOCLICK_TYPE_RIGHT_CLICK
+ ? BUTTON_SECONDARY
+ : BUTTON_PRIMARY;
+ }
MotionEvent downEvent =
MotionEvent.obtain(
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
index 69877c372442..ea25e7992dd9 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
@@ -43,6 +43,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.server.accessibility.AccessibilityTraceManager;
+import com.android.server.accessibility.BaseEventStreamTransformation;
import org.junit.After;
import org.junit.Before;
@@ -70,6 +71,19 @@ public class AutoclickControllerTest {
@Mock private WindowManager mMockWindowManager;
private AutoclickController mController;
+ private static class MotionEventCaptor extends BaseEventStreamTransformation {
+ public MotionEvent downEvent;
+
+ @Override
+ public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ downEvent = event;
+ break;
+ }
+ }
+ }
+
@Before
public void setUp() {
mTestableLooper = TestableLooper.get(this);
@@ -713,6 +727,100 @@ public class AutoclickControllerTest {
assertThat(mController.mAutoclickScrollPanel.isVisible()).isFalse();
}
+ @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);
+
+ // Send hover move event.
+ MotionEvent hoverMove = MotionEvent.obtain(
+ /* downTime= */ 0,
+ /* eventTime= */ 100,
+ /* action= */ MotionEvent.ACTION_HOVER_MOVE,
+ /* x= */ 30f,
+ /* y= */ 0f,
+ /* metaState= */ 0);
+ hoverMove.setSource(InputDevice.SOURCE_MOUSE);
+ mController.onMotionEvent(hoverMove, hoverMove, /* policyFlags= */ 0);
+ mTestableLooper.processAllMessages();
+
+ // Verify left click sent.
+ assertThat(motionEventCaptor.downEvent).isNotNull();
+ assertThat(motionEventCaptor.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);
+
+ // Set click type to right click.
+ mController.clickPanelController.handleAutoclickTypeChange(
+ AutoclickTypePanel.AUTOCLICK_TYPE_RIGHT_CLICK);
+
+ // Send hover move event.
+ MotionEvent hoverMove = MotionEvent.obtain(
+ /* downTime= */ 0,
+ /* eventTime= */ 100,
+ /* action= */ MotionEvent.ACTION_HOVER_MOVE,
+ /* x= */ 30f,
+ /* y= */ 0f,
+ /* metaState= */ 0);
+ hoverMove.setSource(InputDevice.SOURCE_MOUSE);
+ mController.onMotionEvent(hoverMove, hoverMove, /* policyFlags= */ 0);
+ mTestableLooper.processAllMessages();
+
+ // Verify right click sent.
+ assertThat(motionEventCaptor.downEvent).isNotNull();
+ assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo(
+ MotionEvent.BUTTON_SECONDARY);
+ }
+
+ @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);
+
+ // Set click type to right click.
+ mController.clickPanelController.handleAutoclickTypeChange(
+ AutoclickTypePanel.AUTOCLICK_TYPE_RIGHT_CLICK);
+ // Set mouse to hover panel.
+ AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class);
+ when(mockAutoclickTypePanel.isHovered()).thenReturn(true);
+ mController.mAutoclickTypePanel = mockAutoclickTypePanel;
+
+ // Send hover move event.
+ MotionEvent hoverMove = MotionEvent.obtain(
+ /* downTime= */ 0,
+ /* eventTime= */ 100,
+ /* action= */ MotionEvent.ACTION_HOVER_MOVE,
+ /* x= */ 30f,
+ /* y= */ 0f,
+ /* metaState= */ 0);
+ hoverMove.setSource(InputDevice.SOURCE_MOUSE);
+ mController.onMotionEvent(hoverMove, hoverMove, /* policyFlags= */ 0);
+ mTestableLooper.processAllMessages();
+
+ // Verify left click is sent due to the mouse hovering the panel.
+ assertThat(motionEventCaptor.downEvent).isNotNull();
+ assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo(
+ MotionEvent.BUTTON_PRIMARY);
+ }
+
private void injectFakeMouseActionHoverMoveEvent() {
MotionEvent event = getFakeMotionHoverMoveEvent();
event.setSource(InputDevice.SOURCE_MOUSE);