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
This commit is contained in:
Nader Jawad
2021-06-01 16:17:25 -07:00
parent 21eeb8c976
commit 7d0ed97427

View File

@@ -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 <code>deltaDistance</code>.
*/
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;