summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wenyu Zhang <zhangwenyu@google.com> 2025-01-06 12:22:45 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-06 12:22:45 -0800
commit47e00ff8e80b5670cf9517e8d2fe63fb97076b6f (patch)
treed75344fa3f66cc94c552a4f1755c0db43fcc8907
parent89d87b4ae461f05b4000fed493c338e26c8e8bff (diff)
parent714ddbd9a8c264b7f1604c93c2b39efe1677370a (diff)
Merge "a11y: Add animation effect to the autoclick indicator" into main
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AutoclickController.java8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AutoclickIndicatorView.java44
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);
+ }
}