From 7d0ed9742784a9253cf10a9e7505bcaec283f55d Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Tue, 1 Jun 2021 16:17:25 -0700 Subject: [PATCH] Updated EdgeEffect to respect accessibility settings Modified EdgeEffect to be disabled if the global ValueAnimator#areAnimatorsEnabled flag is false Fixes: 189870180 Test: Added CTS test Change-Id: I7adb00342f6f89655719d6c5b64316fc58589e0a --- core/java/android/widget/EdgeEffect.java | 56 +++++++++++++++++++----- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index 207385d12d908..f2827f3fec73e 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -16,6 +16,7 @@ package android.widget; +import android.animation.ValueAnimator; import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; @@ -75,6 +76,11 @@ public class EdgeEffect { */ public static final BlendMode DEFAULT_BLEND_MODE = BlendMode.SRC_ATOP; + /** + * Completely disable edge effect + */ + private static final int TYPE_NONE = -1; + /** * Use a color edge glow for the edge effect. */ @@ -114,7 +120,7 @@ public class EdgeEffect { private static final float ON_ABSORB_VELOCITY_ADJUSTMENT = 13f; /** @hide */ - @IntDef({TYPE_GLOW, TYPE_STRETCH}) + @IntDef({TYPE_NONE, TYPE_GLOW, TYPE_STRETCH}) @Retention(RetentionPolicy.SOURCE) public @interface EdgeEffectType { } @@ -195,6 +201,12 @@ public class EdgeEffect { private float mBaseGlowScale; private float mDisplacement = 0.5f; private float mTargetDisplacement = 0.5f; + + /** + * Current edge effect type, consumers should always query + * {@link #getCurrentEdgeEffectBehavior()} instead of this parameter + * directly in case animations have been disabled (ex. for accessibility reasons) + */ private @EdgeEffectType int mEdgeEffectType = TYPE_GLOW; private Matrix mTmpMatrix = null; private float[] mTmpPoints = null; @@ -227,6 +239,15 @@ public class EdgeEffect { mPaint.setBlendMode(DEFAULT_BLEND_MODE); } + @EdgeEffectType + private int getCurrentEdgeEffectBehavior() { + if (!ValueAnimator.areAnimatorsEnabled()) { + return TYPE_NONE; + } else { + return mEdgeEffectType; + } + } + /** * Set the size of this edge effect in pixels. * @@ -302,14 +323,19 @@ public class EdgeEffect { * Values may be from 0-1. */ public void onPull(float deltaDistance, float displacement) { + int edgeEffectBehavior = getCurrentEdgeEffectBehavior(); + if (edgeEffectBehavior == TYPE_NONE) { + finish(); + return; + } final long now = AnimationUtils.currentAnimationTimeMillis(); mTargetDisplacement = displacement; if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration - && mEdgeEffectType == TYPE_GLOW) { + && edgeEffectBehavior == TYPE_GLOW) { return; } if (mState != STATE_PULL) { - if (mEdgeEffectType == TYPE_STRETCH) { + if (edgeEffectBehavior == TYPE_STRETCH) { // Restore the mPullDistance to the fraction it is currently showing -- we want // to "catch" the current stretch value. mPullDistance = mDistance; @@ -342,7 +368,7 @@ public class EdgeEffect { mGlowAlphaFinish = mGlowAlpha; mGlowScaleYFinish = mGlowScaleY; - if (mEdgeEffectType == TYPE_STRETCH && mDistance == 0) { + if (edgeEffectBehavior == TYPE_STRETCH && mDistance == 0) { mState = STATE_IDLE; } } @@ -377,13 +403,17 @@ public class EdgeEffect { * 0 and deltaDistance. */ public float onPullDistance(float deltaDistance, float displacement) { + int edgeEffectBehavior = getCurrentEdgeEffectBehavior(); + if (edgeEffectBehavior == TYPE_NONE) { + return 0f; + } float finalDistance = Math.max(0f, deltaDistance + mDistance); float delta = finalDistance - mDistance; if (delta == 0f && mDistance == 0f) { return 0f; // No pull, don't do anything. } - if (mState != STATE_PULL && mState != STATE_PULL_DECAY && mEdgeEffectType == TYPE_GLOW) { + if (mState != STATE_PULL && mState != STATE_PULL_DECAY && edgeEffectBehavior == TYPE_GLOW) { // Catch the edge glow in the middle of an animation. mPullDistance = mDistance; mState = STATE_PULL; @@ -442,11 +472,12 @@ public class EdgeEffect { * @param velocity Velocity at impact in pixels per second. */ public void onAbsorb(int velocity) { - if (mEdgeEffectType == TYPE_STRETCH) { + int edgeEffectBehavior = getCurrentEdgeEffectBehavior(); + if (edgeEffectBehavior == TYPE_STRETCH) { mState = STATE_RECEDE; mVelocity = velocity * ON_ABSORB_VELOCITY_ADJUSTMENT; mStartTime = AnimationUtils.currentAnimationTimeMillis(); - } else { + } else if (edgeEffectBehavior == TYPE_GLOW) { mState = STATE_ABSORB; mVelocity = 0; velocity = Math.min(Math.max(MIN_VELOCITY, Math.abs(velocity)), MAX_VELOCITY); @@ -470,6 +501,8 @@ public class EdgeEffect { mGlowAlphaStart, Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA)); mTargetDisplacement = 0.5f; + } else { + finish(); } } @@ -532,7 +565,8 @@ public class EdgeEffect { * animation */ public boolean draw(Canvas canvas) { - if (mEdgeEffectType == TYPE_GLOW) { + int edgeEffectBehavior = getCurrentEdgeEffectBehavior(); + if (edgeEffectBehavior == TYPE_GLOW) { update(); final int count = canvas.save(); @@ -549,7 +583,7 @@ public class EdgeEffect { mPaint.setAlpha((int) (0xff * mGlowAlpha)); canvas.drawCircle(centerX, centerY, mRadius, mPaint); canvas.restoreToCount(count); - } else if (canvas instanceof RecordingCanvas) { + } else if (edgeEffectBehavior == TYPE_STRETCH && canvas instanceof RecordingCanvas) { if (mState == STATE_RECEDE) { updateSpring(); } @@ -604,8 +638,8 @@ public class EdgeEffect { ); } } else { - // This is TYPE_STRETCH and drawing into a Canvas that isn't a Recording Canvas, - // so no effect can be shown. Just end the effect. + // Animations have been disabled or this is TYPE_STRETCH and drawing into a Canvas + // that isn't a Recording Canvas, so no effect can be shown. Just end the effect. mState = STATE_IDLE; mDistance = 0; mVelocity = 0;