diff options
| author | 2025-01-06 12:22:45 -0800 | |
|---|---|---|
| committer | 2025-01-06 12:22:45 -0800 | |
| commit | 47e00ff8e80b5670cf9517e8d2fe63fb97076b6f (patch) | |
| tree | d75344fa3f66cc94c552a4f1755c0db43fcc8907 | |
| parent | 89d87b4ae461f05b4000fed493c338e26c8e8bff (diff) | |
| parent | 714ddbd9a8c264b7f1604c93c2b39efe1677370a (diff) | |
Merge "a11y: Add animation effect to the autoclick indicator" into main
| -rw-r--r-- | services/accessibility/java/com/android/server/accessibility/AutoclickController.java | 8 | ||||
| -rw-r--r-- | services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java | 44 |
2 files changed, 49 insertions, 3 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/AutoclickController.java index a69ececd5373..e3d7062ddb4e 100644 --- a/services/accessibility/java/com/android/server/accessibility/AutoclickController.java +++ b/services/accessibility/java/com/android/server/accessibility/AutoclickController.java @@ -18,6 +18,8 @@ package com.android.server.accessibility; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; +import static com.android.server.accessibility.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME; + import android.accessibilityservice.AccessibilityTrace; import android.annotation.NonNull; import android.content.ContentResolver; @@ -286,8 +288,6 @@ public class AutoclickController extends BaseEventStreamTransformation { } public void update() { - // TODO(b/383901288): update delay time once determined by UX. - long SHOW_INDICATOR_DELAY_TIME = 150; long scheduledShowIndicatorTime = SystemClock.uptimeMillis() + SHOW_INDICATOR_DELAY_TIME; // If there already is a scheduled show indicator at time before the updated time, just @@ -432,6 +432,10 @@ public class AutoclickController extends BaseEventStreamTransformation { */ public void updateDelay(int delay) { mDelay = delay; + + if (Flags.enableAutoclickIndicator() && mAutoclickIndicatorView != null) { + mAutoclickIndicatorView.setAnimationDuration(delay - SHOW_INDICATOR_DELAY_TIME); + } } /** diff --git a/services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java b/services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java index 54c31e5bca79..816d8e456a9a 100644 --- a/services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java +++ b/services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java @@ -16,25 +16,43 @@ package com.android.server.accessibility; +import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.RectF; import android.util.DisplayMetrics; import android.view.View; +import android.view.accessibility.AccessibilityManager; +import android.view.animation.LinearInterpolator; // A visual indicator for the autoclick feature. public class AutoclickIndicatorView extends View { private static final String TAG = AutoclickIndicatorView.class.getSimpleName(); + // TODO(b/383901288): update delay time once determined by UX. + static final int SHOW_INDICATOR_DELAY_TIME = 150; + + static final int MINIMAL_ANIMATION_DURATION = 50; + // TODO(b/383901288): allow users to customize the indicator area. static final float RADIUS = 50; private final Paint mPaint; + private final ValueAnimator mAnimator; + + private final RectF mRingRect; + // x and y coordinates of the visual indicator. private float mX; private float mY; + // Current sweep angle of the animated ring. + private float mSweepAngle; + + private int mAnimationDuration = AccessibilityManager.AUTOCLICK_DELAY_DEFAULT; + // Status of whether the visual indicator should display or not. private boolean showIndicator = false; @@ -46,6 +64,18 @@ public class AutoclickIndicatorView extends View { mPaint.setARGB(255, 52, 103, 235); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); + + mAnimator = ValueAnimator.ofFloat(0, 360); + mAnimator.setDuration(mAnimationDuration); + mAnimator.setInterpolator(new LinearInterpolator()); + mAnimator.addUpdateListener( + animation -> { + mSweepAngle = (float) animation.getAnimatedValue(); + // Redraw the view with the updated angle. + invalidate(); + }); + + mRingRect = new RectF(); } @Override @@ -53,7 +83,12 @@ public class AutoclickIndicatorView extends View { super.onDraw(canvas); if (showIndicator) { - canvas.drawCircle(mX, mY, RADIUS, mPaint); + mRingRect.set( + /* left= */ mX - RADIUS, + /* top= */ mY - RADIUS, + /* right= */ mX + RADIUS, + /* bottom= */ mY + RADIUS); + canvas.drawArc(mRingRect, /* startAngle= */ -90, mSweepAngle, false, mPaint); } } @@ -75,10 +110,17 @@ public class AutoclickIndicatorView extends View { public void redrawIndicator() { showIndicator = true; invalidate(); + mAnimator.start(); } public void clearIndicator() { showIndicator = false; + mAnimator.cancel(); invalidate(); } + + public void setAnimationDuration(int duration) { + mAnimationDuration = Math.max(duration, MINIMAL_ANIMATION_DURATION); + mAnimator.setDuration(mAnimationDuration); + } } |