Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3e760cb authored by Wenyu Zhang's avatar Wenyu Zhang
Browse files

a11y: Plug "ignore minor cursor movement" setting to AutoclickController

Listen to this setting change. Update cursor movement slope accordingly.
When this setting is on, the minimal valid movement that can reset the
scheduler is the cursor area size.

Bug: b/388845718
Test: AutoclickControllerTest
Flag: com.android.server.accessibility.enable_autoclick_indicator
Change-Id: Ide30df27d06b39de852f307b4166a2bc584a4ac7
parent b794c3aa
Loading
Loading
Loading
Loading
+65 −15
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.accessibility;
import static android.view.MotionEvent.BUTTON_PRIMARY;
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.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME;

@@ -41,6 +42,8 @@ import android.view.WindowManager;

import androidx.annotation.VisibleForTesting;

import com.android.internal.accessibility.util.AccessibilityUtils;

/**
 * Implements "Automatically click on mouse stop" feature.
 *
@@ -195,6 +198,11 @@ public class AutoclickController extends BaseEventStreamTransformation {
        private final Uri mAutoclickCursorAreaSizeSettingUri =
                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE);

        /** URI used to identify ignore minor cursor movement setting with content resolver. */
        private final Uri mAutoclickIgnoreMinorCursorMovementSettingUri =
                Settings.Secure.getUriFor(
                        Settings.Secure.ACCESSIBILITY_AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT);

        private ContentResolver mContentResolver;
        private ClickScheduler mClickScheduler;
        private AutoclickIndicatorScheduler mAutoclickIndicatorScheduler;
@@ -251,6 +259,14 @@ public class AutoclickController extends BaseEventStreamTransformation {
                        mUserId);
                // Initialize mAutoclickIndicatorView's initial size.
                onChange(/* selfChange= */ true, mAutoclickCursorAreaSizeSettingUri);

                // Register observer to listen to ignore minor cursor movement setting change.
                mContentResolver.registerContentObserver(
                        mAutoclickIgnoreMinorCursorMovementSettingUri,
                        /* notifyForDescendants= */ false,
                        /* observer= */ this,
                        mUserId);
                onChange(/* selfChange= */ true, mAutoclickIgnoreMinorCursorMovementSettingUri);
            }
        }

@@ -279,8 +295,9 @@ public class AutoclickController extends BaseEventStreamTransformation {
                                mUserId);
                mClickScheduler.updateDelay(delay);
            }
            if (Flags.enableAutoclickIndicator()
                    && mAutoclickCursorAreaSizeSettingUri.equals(uri)) {

            if (Flags.enableAutoclickIndicator()) {
                if (mAutoclickCursorAreaSizeSettingUri.equals(uri)) {
                    int size =
                            Settings.Secure.getIntForUser(
                                    mContentResolver,
@@ -290,6 +307,22 @@ public class AutoclickController extends BaseEventStreamTransformation {
                    if (mAutoclickIndicatorScheduler != null) {
                        mAutoclickIndicatorScheduler.updateCursorAreaSize(size);
                    }
                    mClickScheduler.updateMovementSlope(size);
                }

                if (mAutoclickIgnoreMinorCursorMovementSettingUri.equals(uri)) {
                    boolean ignoreMinorCursorMovement =
                            Settings.Secure.getIntForUser(
                                    mContentResolver,
                                    Settings.Secure
                                            .ACCESSIBILITY_AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT,
                                    AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT_DEFAULT
                                            ? AccessibilityUtils.State.ON
                                            : AccessibilityUtils.State.OFF,
                                    mUserId)
                            == AccessibilityUtils.State.ON;
                    mClickScheduler.setIgnoreMinorCursorMovement(ignoreMinorCursorMovement);
                }
            }
        }
    }
@@ -360,11 +393,16 @@ public class AutoclickController extends BaseEventStreamTransformation {
    @VisibleForTesting
    final class ClickScheduler implements Runnable {
        /**
         * Minimal distance pointer has to move relative to anchor in order for movement not to be
         * discarded as noise. Anchor is the position of the last MOVE event that was not considered
         * noise.
         * Default minimal distance pointer has to move relative to anchor in order for movement not
         * to be discarded as noise. Anchor is the position of the last MOVE event that was not
         * considered noise.
         */
        private static final double MOVEMENT_SLOPE = 20f;
        private static final double DEFAULT_MOVEMENT_SLOPE = 20f;

        private double mMovementSlope = DEFAULT_MOVEMENT_SLOPE;

        /** Whether the minor cursor movement should be ignored. */
        private boolean mIgnoreMinorCursorMovement = AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT_DEFAULT;

        /** Whether there is pending click. */
        private boolean mActive;
@@ -548,7 +586,19 @@ public class AutoclickController extends BaseEventStreamTransformation {
            float deltaX = mAnchorCoords.x - event.getX(pointerIndex);
            float deltaY = mAnchorCoords.y - event.getY(pointerIndex);
            double delta = Math.hypot(deltaX, deltaY);
            return delta > MOVEMENT_SLOPE;
            double slope =
                    ((Flags.enableAutoclickIndicator() && mIgnoreMinorCursorMovement)
                            ? mMovementSlope
                            : DEFAULT_MOVEMENT_SLOPE);
            return delta > slope;
        }

        public void setIgnoreMinorCursorMovement(boolean ignoreMinorCursorMovement) {
            mIgnoreMinorCursorMovement = ignoreMinorCursorMovement;
        }

        private void updateMovementSlope(double slope) {
            mMovementSlope = slope;
        }

        /**