Merge "Prevent animation update callbacks after it has finished" into tm-qpr-dev am: 5252db7ba5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20276150

Change-Id: I2909146ae80e84c594bc53bd9c603731a2dde15b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jorge Gil
2022-10-25 18:02:31 +00:00
committed by Automerger Merge Worker

View File

@@ -619,12 +619,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// Animation length is already expected to be scaled. // Animation length is already expected to be scaled.
va.overrideDurationScale(1.0f); va.overrideDurationScale(1.0f);
va.setDuration(anim.computeDurationHint()); va.setDuration(anim.computeDurationHint());
va.addUpdateListener(animation -> { final ValueAnimator.AnimatorUpdateListener updateListener = animation -> {
final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime());
applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix, applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix,
position, cornerRadius, clipRect); position, cornerRadius, clipRect);
}); };
va.addUpdateListener(updateListener);
final Runnable finisher = () -> { final Runnable finisher = () -> {
applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix, applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix,
@@ -637,20 +638,30 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}); });
}; };
va.addListener(new AnimatorListenerAdapter() { va.addListener(new AnimatorListenerAdapter() {
// It is possible for the end/cancel to be called more than once, which may cause
// issues if the animating surface has already been released. Track the finished
// state here to skip duplicate callbacks. See b/252872225.
private boolean mFinished = false; private boolean mFinished = false;
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (mFinished) return; onFinish();
mFinished = true;
finisher.run();
} }
@Override @Override
public void onAnimationCancel(Animator animation) { public void onAnimationCancel(Animator animation) {
onFinish();
}
private void onFinish() {
if (mFinished) return; if (mFinished) return;
mFinished = true; mFinished = true;
finisher.run(); finisher.run();
// The update listener can continue to be called after the animation has ended if
// end() is called manually again before the finisher removes the animation.
// Remove it manually here to prevent animating a released surface.
// See b/252872225.
va.removeUpdateListener(updateListener);
} }
}); });
animations.add(va); animations.add(va);