Loading services/accessibility/java/com/android/server/accessibility/AutoclickController.java +65 −15 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. * Loading Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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, Loading @@ -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); } } } } Loading Loading @@ -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; Loading Loading @@ -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; } /** Loading Loading
services/accessibility/java/com/android/server/accessibility/AutoclickController.java +65 −15 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. * Loading Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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, Loading @@ -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); } } } } Loading Loading @@ -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; Loading Loading @@ -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; } /** Loading