summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java40
-rw-r--r--services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java75
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java32
3 files changed, 132 insertions, 15 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 db8441d2424b..5283df5ca7e1 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
@@ -17,11 +17,16 @@
package com.android.server.accessibility.autoclick;
import static android.view.MotionEvent.BUTTON_PRIMARY;
+import static android.view.MotionEvent.BUTTON_SECONDARY;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_DELAY_DEFAULT;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT_DEFAULT;
import static com.android.server.accessibility.autoclick.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_LEFT_CLICK;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_RIGHT_CLICK;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AutoclickType;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.ClickPanelControllerInterface;
import android.accessibilityservice.AccessibilityTrace;
import android.annotation.NonNull;
@@ -84,6 +89,23 @@ public class AutoclickController extends BaseEventStreamTransformation {
@VisibleForTesting AutoclickTypePanel mAutoclickTypePanel;
private WindowManager mWindowManager;
+ // Default click type is left-click.
+ private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK;
+
+ @VisibleForTesting
+ final ClickPanelControllerInterface clickPanelController =
+ new ClickPanelControllerInterface() {
+ @Override
+ public void handleAutoclickTypeChange(@AutoclickType int clickType) {
+ mActiveClickType = clickType;
+ }
+
+ @Override
+ public void toggleAutoclickPause() {
+ // TODO(b/388872274): allows users to pause the autoclick.
+ }
+ };
+
public AutoclickController(Context context, int userId, AccessibilityTraceManager trace) {
mTrace = trace;
mContext = context;
@@ -124,7 +146,8 @@ public class AutoclickController extends BaseEventStreamTransformation {
mAutoclickIndicatorView = new AutoclickIndicatorView(mContext);
mWindowManager = mContext.getSystemService(WindowManager.class);
- mAutoclickTypePanel = new AutoclickTypePanel(mContext, mWindowManager);
+ mAutoclickTypePanel =
+ new AutoclickTypePanel(mContext, mWindowManager, clickPanelController);
mAutoclickTypePanel.show();
mWindowManager.addView(mAutoclickIndicatorView, mAutoclickIndicatorView.getLayoutParams());
@@ -644,6 +667,15 @@ 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;
+
MotionEvent downEvent =
MotionEvent.obtain(
/* downTime= */ now,
@@ -653,7 +685,7 @@ public class AutoclickController extends BaseEventStreamTransformation {
mTempPointerProperties,
mTempPointerCoords,
mMetaState,
- BUTTON_PRIMARY,
+ actionButton,
/* xPrecision= */ 1.0f,
/* yPrecision= */ 1.0f,
mLastMotionEvent.getDeviceId(),
@@ -663,11 +695,11 @@ public class AutoclickController extends BaseEventStreamTransformation {
MotionEvent pressEvent = MotionEvent.obtain(downEvent);
pressEvent.setAction(MotionEvent.ACTION_BUTTON_PRESS);
- pressEvent.setActionButton(BUTTON_PRIMARY);
+ pressEvent.setActionButton(actionButton);
MotionEvent releaseEvent = MotionEvent.obtain(downEvent);
releaseEvent.setAction(MotionEvent.ACTION_BUTTON_RELEASE);
- releaseEvent.setActionButton(BUTTON_PRIMARY);
+ releaseEvent.setActionButton(actionButton);
releaseEvent.setButtonState(0);
MotionEvent upEvent = MotionEvent.obtain(downEvent);
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
index 2ef11f4b78e1..cf928e2f3fa4 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
@@ -18,6 +18,7 @@ package com.android.server.accessibility.autoclick;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import android.annotation.IntDef;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
@@ -39,12 +40,40 @@ public class AutoclickTypePanel {
private final String TAG = AutoclickTypePanel.class.getSimpleName();
+ public static final int AUTOCLICK_TYPE_LEFT_CLICK = 0;
+ public static final int AUTOCLICK_TYPE_RIGHT_CLICK = 1;
+ public static final int AUTOCLICK_TYPE_DOUBLE_CLICK = 2;
+ public static final int AUTOCLICK_TYPE_DRAG = 3;
+ public static final int AUTOCLICK_TYPE_SCROLL = 4;
+
+ // Types of click the AutoclickTypePanel supports.
+ @IntDef({
+ AUTOCLICK_TYPE_LEFT_CLICK,
+ AUTOCLICK_TYPE_RIGHT_CLICK,
+ AUTOCLICK_TYPE_DOUBLE_CLICK,
+ AUTOCLICK_TYPE_DRAG,
+ AUTOCLICK_TYPE_SCROLL,
+ })
+ public @interface AutoclickType {}
+
+ // An interface exposed to {@link AutoclickController) to handle different actions on the panel,
+ // including changing autoclick type, pausing/resuming autoclick.
+ public interface ClickPanelControllerInterface {
+ // Allows users to change a different autoclick type.
+ void handleAutoclickTypeChange(@AutoclickType int clickType);
+
+ // Allows users to pause/resume the autoclick.
+ void toggleAutoclickPause();
+ }
+
private final Context mContext;
private final View mContentView;
private final WindowManager mWindowManager;
+ private final ClickPanelControllerInterface mClickPanelController;
+
// Whether the panel is expanded or not.
private boolean mExpanded = false;
@@ -56,9 +85,13 @@ public class AutoclickTypePanel {
private LinearLayout mSelectedButton;
- public AutoclickTypePanel(Context context, WindowManager windowManager) {
+ public AutoclickTypePanel(
+ Context context,
+ WindowManager windowManager,
+ ClickPanelControllerInterface clickPanelController) {
mContext = context;
mWindowManager = windowManager;
+ mClickPanelController = clickPanelController;
mContentView =
LayoutInflater.from(context)
@@ -76,26 +109,35 @@ public class AutoclickTypePanel {
}
private void initializeButtonState() {
- mLeftClickButton.setOnClickListener(v -> togglePanelExpansion(mLeftClickButton));
- mRightClickButton.setOnClickListener(v -> togglePanelExpansion(mRightClickButton));
- mDoubleClickButton.setOnClickListener(v -> togglePanelExpansion(mDoubleClickButton));
- mScrollButton.setOnClickListener(v -> togglePanelExpansion(mScrollButton));
- mDragButton.setOnClickListener(v -> togglePanelExpansion(mDragButton));
+ mLeftClickButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_LEFT_CLICK));
+ mRightClickButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_RIGHT_CLICK));
+ mDoubleClickButton.setOnClickListener(
+ v -> togglePanelExpansion(AUTOCLICK_TYPE_DOUBLE_CLICK));
+ mScrollButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_SCROLL));
+ mDragButton.setOnClickListener(v -> togglePanelExpansion(AUTOCLICK_TYPE_DRAG));
+
+ // TODO(b/388872274): registers listener for pause button and allows users to pause/resume
+ // the autoclick.
+ // TODO(b/388847771): registers listener for position button and allows users to move the
+ // panel to a different position.
// Initializes panel as collapsed state and only displays the left click button.
hideAllClickTypeButtons();
mLeftClickButton.setVisibility(View.VISIBLE);
- setSelectedButton(/* selectedButton= */ mLeftClickButton);
+ setSelectedClickType(AUTOCLICK_TYPE_LEFT_CLICK);
}
/** Sets the selected button and updates the newly and previously selected button styling. */
- private void setSelectedButton(@NonNull LinearLayout selectedButton) {
+ private void setSelectedClickType(@AutoclickType int clickType) {
+ final LinearLayout selectedButton = getButtonFromClickType(clickType);
+
// Updates the previously selected button styling.
if (mSelectedButton != null) {
toggleSelectedButtonStyle(mSelectedButton, /* isSelected= */ false);
}
mSelectedButton = selectedButton;
+ mClickPanelController.handleAutoclickTypeChange(clickType);
// Updates the newly selected button styling.
toggleSelectedButtonStyle(selectedButton, /* isSelected= */ true);
@@ -130,7 +172,9 @@ public class AutoclickTypePanel {
}
/** Toggles the panel expanded or collapsed state. */
- private void togglePanelExpansion(LinearLayout button) {
+ private void togglePanelExpansion(@AutoclickType int clickType) {
+ final LinearLayout button = getButtonFromClickType(clickType);
+
if (mExpanded) {
// If the panel is already in expanded state, we should collapse it by hiding all
// buttons except the one user selected.
@@ -138,7 +182,7 @@ public class AutoclickTypePanel {
button.setVisibility(View.VISIBLE);
// Sets the newly selected button.
- setSelectedButton(/* selectedButton= */ button);
+ setSelectedClickType(clickType);
} else {
// If the panel is already collapsed, we just need to expand it.
showAllClickTypeButtons();
@@ -166,6 +210,17 @@ public class AutoclickTypePanel {
mScrollButton.setVisibility(View.VISIBLE);
}
+ private LinearLayout getButtonFromClickType(@AutoclickType int clickType) {
+ return switch (clickType) {
+ case AUTOCLICK_TYPE_LEFT_CLICK -> mLeftClickButton;
+ case AUTOCLICK_TYPE_RIGHT_CLICK -> mRightClickButton;
+ case AUTOCLICK_TYPE_DOUBLE_CLICK -> mDoubleClickButton;
+ case AUTOCLICK_TYPE_DRAG -> mDragButton;
+ case AUTOCLICK_TYPE_SCROLL -> mScrollButton;
+ default -> throw new IllegalArgumentException("Unknown clickType " + clickType);
+ };
+ }
+
@VisibleForTesting
boolean getExpansionStateForTesting() {
return mExpanded;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
index 7b8824cb0e3d..00cc7264c1d0 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickTypePanelTest.java
@@ -18,6 +18,11 @@ package com.android.server.accessibility.autoclick;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_LEFT_CLICK;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AutoclickType;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.ClickPanelControllerInterface;
+
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@@ -59,11 +64,25 @@ public class AutoclickTypePanelTest {
private LinearLayout mDragButton;
private LinearLayout mScrollButton;
+ private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK;
+
+ private final ClickPanelControllerInterface clickPanelController =
+ new ClickPanelControllerInterface() {
+ @Override
+ public void handleAutoclickTypeChange(@AutoclickType int clickType) {
+ mActiveClickType = clickType;
+ }
+
+ @Override
+ public void toggleAutoclickPause() {}
+ };
+
@Before
public void setUp() {
mTestableContext.addMockSystemService(Context.WINDOW_SERVICE, mMockWindowManager);
- mAutoclickTypePanel = new AutoclickTypePanel(mTestableContext, mMockWindowManager);
+ mAutoclickTypePanel =
+ new AutoclickTypePanel(mTestableContext, mMockWindowManager, clickPanelController);
View contentView = mAutoclickTypePanel.getContentViewForTesting();
mLeftClickButton = contentView.findViewById(R.id.accessibility_autoclick_left_click_layout);
mRightClickButton =
@@ -136,6 +155,17 @@ public class AutoclickTypePanelTest {
verifyButtonHasSelectedStyle(mScrollButton);
}
+ @Test
+ public void togglePanelExpansion_selectButton_correctActiveClickType() {
+ // By first click, the panel is expanded.
+ mLeftClickButton.callOnClick();
+
+ // Clicks any button in the expanded state to select a type button.
+ mScrollButton.callOnClick();
+
+ assertThat(mActiveClickType).isEqualTo(AUTOCLICK_TYPE_SCROLL);
+ }
+
private void verifyButtonHasSelectedStyle(@NonNull LinearLayout button) {
GradientDrawable gradientDrawable = (GradientDrawable) button.getBackground();
assertThat(gradientDrawable.getColor().getDefaultColor())