diff options
Diffstat (limited to 'services/accessibility')
2 files changed, 91 insertions, 34 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 84158cf911ad..0b9c45de6e40 100644 --- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java +++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java @@ -25,6 +25,7 @@ import static android.view.accessibility.AccessibilityManager.AUTOCLICK_REVERT_T import static com.android.server.accessibility.autoclick.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME; import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_DOUBLE_CLICK; +import static com.android.server.accessibility.autoclick.AutoclickScrollPanel.DIRECTION_NONE; 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.AUTOCLICK_TYPE_SCROLL; @@ -97,6 +98,9 @@ public class AutoclickController extends BaseEventStreamTransformation { // Default click type is left-click. private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK; + // Default scroll direction is DIRECTION_NONE. + private @AutoclickScrollPanel.ScrollDirection int mHoveredDirection = DIRECTION_NONE; + @VisibleForTesting final ClickPanelControllerInterface clickPanelController = new ClickPanelControllerInterface() { @@ -131,14 +135,26 @@ public class AutoclickController extends BaseEventStreamTransformation { final AutoclickScrollPanel.ScrollPanelControllerInterface mScrollPanelController = new AutoclickScrollPanel.ScrollPanelControllerInterface() { @Override - public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) { - // TODO(b/388845721): Perform actual scroll. - } + public void onHoverButtonChange( + @AutoclickScrollPanel.ScrollDirection int direction, + boolean hovered) { + // Update the hover direction. + if (hovered) { + mHoveredDirection = direction; + } else if (mHoveredDirection == direction) { + // Safety check: Only clear hover tracking if this is the same button + // we're currently tracking. + mHoveredDirection = AutoclickScrollPanel.DIRECTION_NONE; + } - @Override - public void exitScrollMode() { - if (mAutoclickScrollPanel != null) { - mAutoclickScrollPanel.hide(); + // For exit button, we only trigger hover state changes, the autoclick system + // will handle the countdown. + if (direction == AutoclickScrollPanel.DIRECTION_EXIT) { + return; + } + // For direction buttons, perform scroll action immediately. + if (hovered && direction != AutoclickScrollPanel.DIRECTION_NONE) { + handleScroll(direction); } } }; @@ -285,6 +301,22 @@ public class AutoclickController extends BaseEventStreamTransformation { } } + /** + * Handles scroll operations in the specified direction. + */ + public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) { + // TODO(b/388845721): Perform actual scroll. + } + + /** + * Exits scroll mode and hides the scroll panel UI. + */ + public void exitScrollMode() { + if (mAutoclickScrollPanel != null) { + mAutoclickScrollPanel.hide(); + } + } + @VisibleForTesting void onChangeForTesting(boolean selfChange, Uri uri) { mAutoclickSettingsObserver.onChange(selfChange, uri); @@ -776,6 +808,14 @@ public class AutoclickController extends BaseEventStreamTransformation { return; } + if (mAutoclickScrollPanel != null && mAutoclickScrollPanel.isVisible()) { + // If exit button is hovered, exit scroll mode after countdown and return early. + if (mHoveredDirection == AutoclickScrollPanel.DIRECTION_EXIT) { + exitScrollMode(); + } + return; + } + // Handle scroll type specially, show scroll panel instead of sending click events. if (mActiveClickType == AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL) { if (mAutoclickScrollPanel != null) { diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java index e79be502a6fc..c71443149687 100644 --- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java +++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java @@ -23,6 +23,7 @@ import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.WindowInsets; import android.view.WindowManager; @@ -41,12 +42,16 @@ public class AutoclickScrollPanel { public static final int DIRECTION_DOWN = 1; public static final int DIRECTION_LEFT = 2; public static final int DIRECTION_RIGHT = 3; + public static final int DIRECTION_EXIT = 4; + public static final int DIRECTION_NONE = 5; @IntDef({ DIRECTION_UP, DIRECTION_DOWN, DIRECTION_LEFT, - DIRECTION_RIGHT + DIRECTION_RIGHT, + DIRECTION_EXIT, + DIRECTION_NONE, }) @Retention(RetentionPolicy.SOURCE) public @interface ScrollDirection {} @@ -70,16 +75,12 @@ public class AutoclickScrollPanel { */ public interface ScrollPanelControllerInterface { /** - * Called when a scroll direction is hovered. + * Called when a button hover state changes. * - * @param direction The direction to scroll: one of {@link ScrollDirection} values. + * @param direction The direction associated with the button. + * @param hovered Whether the button is being hovered or not. */ - void handleScroll(@ScrollDirection int direction); - - /** - * Called when the exit button is hovered. - */ - void exitScrollMode(); + void onHoverButtonChange(@ScrollDirection int direction, boolean hovered); } public AutoclickScrollPanel(Context context, WindowManager windowManager, @@ -104,19 +105,12 @@ public class AutoclickScrollPanel { * Sets up hover listeners for scroll panel buttons. */ private void initializeButtonState() { - // Set up hover listeners for direction buttons. - setupHoverListenerForDirectionButton(mUpButton, DIRECTION_UP); - setupHoverListenerForDirectionButton(mLeftButton, DIRECTION_LEFT); - setupHoverListenerForDirectionButton(mRightButton, DIRECTION_RIGHT); - setupHoverListenerForDirectionButton(mDownButton, DIRECTION_DOWN); - - // Set up hover listener for exit button. - mExitButton.setOnHoverListener((v, event) -> { - if (mScrollPanelController != null) { - mScrollPanelController.exitScrollMode(); - } - return true; - }); + // Set up hover listeners for all buttons. + setupHoverListenerForButton(mUpButton, DIRECTION_UP); + setupHoverListenerForButton(mLeftButton, DIRECTION_LEFT); + setupHoverListenerForButton(mRightButton, DIRECTION_RIGHT); + setupHoverListenerForButton(mDownButton, DIRECTION_DOWN); + setupHoverListenerForButton(mExitButton, DIRECTION_EXIT); } /** @@ -142,14 +136,37 @@ public class AutoclickScrollPanel { } /** - * Sets up a hover listener for a direction button. + * Sets up a hover listener for a button. */ - private void setupHoverListenerForDirectionButton(ImageButton button, - @ScrollDirection int direction) { + private void setupHoverListenerForButton(ImageButton button, @ScrollDirection int direction) { button.setOnHoverListener((v, event) -> { - if (mScrollPanelController != null) { - mScrollPanelController.handleScroll(direction); + if (mScrollPanelController == null) { + return true; + } + + boolean hovered; + switch (event.getAction()) { + case MotionEvent.ACTION_HOVER_ENTER: + hovered = true; + break; + case MotionEvent.ACTION_HOVER_MOVE: + // For direction buttons, continuously trigger scroll on hover move. + if (direction != DIRECTION_EXIT) { + hovered = true; + } else { + // Ignore hover move events for exit button. + return true; + } + break; + case MotionEvent.ACTION_HOVER_EXIT: + hovered = false; + break; + default: + return true; } + + // Notify the controller about the hover change. + mScrollPanelController.onHoverButtonChange(direction, hovered); return true; }); } |