Allow system to disable behavior of pausing animators for bg apps am: 161732cf18

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

Change-Id: Iab25efc6926ec409ac93769c2d76c88cf8b5bcb6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Chet Haase
2022-06-07 19:57:50 +00:00
committed by Automerger Merge Worker
3 changed files with 43 additions and 5 deletions

View File

@@ -98,6 +98,7 @@ package android.animation {
public abstract class Animator implements java.lang.Cloneable {
method public static long getBackgroundPauseDelay();
method public static void setAnimatorPausingEnabled(boolean);
method public static void setBackgroundPauseDelay(long);
}

View File

@@ -53,6 +53,9 @@ public class AnimationHandler {
new ArrayList<>();
private AnimationFrameCallbackProvider mProvider;
// Static flag which allows the pausing behavior to be globally disabled/enabled.
private static boolean sAnimatorPausingEnabled = true;
/**
* This paused list is used to store animators forcibly paused when the activity
* went into the background (to avoid unnecessary background processing work).
@@ -93,6 +96,15 @@ public class AnimationHandler {
return sAnimatorHandler.get();
}
/**
* Disable the default behavior of pausing infinite animators when
* apps go into the background.
*
* @param enable Enable (default behavior) or disable background pausing behavior.
*/
public static void setAnimatorPausingEnabled(boolean enable) {
sAnimatorPausingEnabled = enable;
}
/**
* This is called when a window goes away. We should remove
@@ -136,16 +148,19 @@ public class AnimationHandler {
} else {
mAnimatorRequestors.remove(requestor);
}
if (!sAnimatorPausingEnabled) {
// Resume any animators that have been paused in the meantime, otherwise noop
// Leave logic above so that if pausing gets re-enabled, the state of the requestors
// list is valid
resumeAnimators();
return;
}
boolean isEmpty = mAnimatorRequestors.isEmpty();
if (wasEmpty != isEmpty) {
// only paused/resume animators if there was a visibility change
if (!isEmpty) {
// If any requestors are enabled, resume currently paused animators
Choreographer.getInstance().removeFrameCallback(mPauser);
for (int i = mPausedAnimators.size() - 1; i >= 0; --i) {
mPausedAnimators.get(i).resume();
}
mPausedAnimators.clear();
resumeAnimators();
} else {
// Wait before pausing to avoid thrashing animator state for temporary backgrounding
Choreographer.getInstance().postFrameCallbackDelayed(mPauser,
@@ -160,6 +175,14 @@ public class AnimationHandler {
}
}
private void resumeAnimators() {
Choreographer.getInstance().removeFrameCallback(mPauser);
for (int i = mPausedAnimators.size() - 1; i >= 0; --i) {
mPausedAnimators.get(i).resume();
}
mPausedAnimators.clear();
}
private Choreographer.FrameCallback mPauser = frameTimeNanos -> {
if (mAnimatorRequestors.size() > 0) {
// something enabled animators since this callback was scheduled - bail

View File

@@ -92,6 +92,20 @@ public abstract class Animator implements Cloneable {
return sBackgroundPauseDelay;
}
/**
* Sets the behavior of animator pausing when apps go into the background.
* This is exposed as a test API for verification, but is intended for use by internal/
* platform code, potentially for use by a system property that could disable it
* system wide.
*
* @param enable Enable (default behavior) or disable background pausing behavior.
* @hide
*/
@TestApi
public static void setAnimatorPausingEnabled(boolean enable) {
AnimationHandler.setAnimatorPausingEnabled(enable);
}
/**
* Starts this animation. If the animation has a nonzero startDelay, the animation will start
* running after that delay elapses. A non-delayed animation will have its initial