summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chet Haase <chet@google.com> 2022-12-14 23:50:42 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-14 23:50:42 +0000
commita424fc32ca81c25076b3e2d0738dd21111935abd (patch)
tree86b6c3de3b36faa37155f2d035147a20f49be47d
parent06cbc8c0f5a05f931e450e5c9ed0076381430c72 (diff)
parentb9ed093976c84a6a4a8993fe7029a6c55f9afec9 (diff)
Merge "Revert "DO NOT MERGE Revert "Fix activity leak bug""" into tm-qpr-dev
-rw-r--r--core/java/android/animation/AnimationHandler.java75
-rw-r--r--core/java/android/view/ViewRootImpl.java13
2 files changed, 51 insertions, 37 deletions
diff --git a/core/java/android/animation/AnimationHandler.java b/core/java/android/animation/AnimationHandler.java
index 19606c16cb70..df8a50a1fa5c 100644
--- a/core/java/android/animation/AnimationHandler.java
+++ b/core/java/android/animation/AnimationHandler.java
@@ -19,10 +19,10 @@ package android.animation;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Log;
import android.view.Choreographer;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -40,7 +40,7 @@ import java.util.ArrayList;
public class AnimationHandler {
private static final String TAG = "AnimationHandler";
- private static final boolean LOCAL_LOGV = true;
+ private static final boolean LOCAL_LOGV = false;
/**
* Internal per-thread collections used to avoid set collisions as animations start and end
@@ -78,7 +78,7 @@ public class AnimationHandler {
* store visible (foreground) requestors; if the set size reaches zero, there are no
* objects in the foreground and it is time to pause animators.
*/
- private final ArraySet<Object> mAnimatorRequestors = new ArraySet<>();
+ private final ArrayList<WeakReference<Object>> mAnimatorRequestors = new ArrayList<>();
private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
@Override
@@ -141,24 +141,9 @@ public class AnimationHandler {
* tracking obsolete+enabled requestors.
*/
public static void removeRequestor(Object requestor) {
- getInstance().removeRequestorImpl(requestor);
- }
-
- private void removeRequestorImpl(Object requestor) {
- // Also request disablement, in case that requestor was the sole object keeping
- // animators un-paused
- long startTime = System.nanoTime();
- requestAnimatorsEnabled(false, requestor);
- Log.d(TAG, "removeRequestorImpl called requestAnimatorsEnabled after " +
- (System.nanoTime() - startTime));
- mAnimatorRequestors.remove(requestor);
- Log.d(TAG, "removeRequestorImpl removed requestor after " +
- (System.nanoTime() - startTime));
+ getInstance().requestAnimatorsEnabledImpl(false, requestor);
if (LOCAL_LOGV) {
- Log.v(TAG, "removeRequestorImpl for " + requestor);
- for (int i = 0; i < mAnimatorRequestors.size(); ++i) {
- Log.v(TAG, "animatorRequesters " + i + " = " + mAnimatorRequestors.valueAt(i));
- }
+ Log.v(TAG, "removeRequestor for " + requestor);
}
}
@@ -176,25 +161,44 @@ public class AnimationHandler {
}
private void requestAnimatorsEnabledImpl(boolean enable, Object requestor) {
- long startTime = System.nanoTime();
boolean wasEmpty = mAnimatorRequestors.isEmpty();
setAnimatorPausingEnabled(isPauseBgAnimationsEnabledInSystemProperties());
- Log.d(TAG, "requestAnimatorsEnabledImpl called setAnimatorPausingEnabled after " +
- (System.nanoTime() - startTime));
- if (enable) {
- mAnimatorRequestors.add(requestor);
- } else {
- mAnimatorRequestors.remove(requestor);
+ synchronized (mAnimatorRequestors) {
+ // Only store WeakRef objects to avoid leaks
+ if (enable) {
+ // First, check whether such a reference is already on the list
+ WeakReference<Object> weakRef = null;
+ for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
+ WeakReference<Object> ref = mAnimatorRequestors.get(i);
+ Object referent = ref.get();
+ if (referent == requestor) {
+ weakRef = ref;
+ } else if (referent == null) {
+ // Remove any reference that has been cleared
+ mAnimatorRequestors.remove(i);
+ }
+ }
+ if (weakRef == null) {
+ weakRef = new WeakReference<>(requestor);
+ mAnimatorRequestors.add(weakRef);
+ }
+ } else {
+ for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
+ WeakReference<Object> ref = mAnimatorRequestors.get(i);
+ Object referent = ref.get();
+ if (referent == requestor || referent == null) {
+ // remove requested item or item that has been cleared
+ mAnimatorRequestors.remove(i);
+ }
+ }
+ // If a reference to the requestor wasn't in the list, nothing to remove
+ }
}
- Log.d(TAG, "requestAnimatorsEnabledImpl added/removed after " +
- (System.nanoTime() - startTime));
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();
- Log.d(TAG, "requestAnimatorsEnabledImpl resumed, returning after " +
- (System.nanoTime() - startTime));
return;
}
boolean isEmpty = mAnimatorRequestors.isEmpty();
@@ -209,12 +213,13 @@ public class AnimationHandler {
Animator.getBackgroundPauseDelay());
}
}
- Log.d(TAG, "requestAnimatorsEnabledImpl post was/is check after " +
- (System.nanoTime() - startTime));
if (LOCAL_LOGV) {
- Log.v(TAG, enable ? "enable" : "disable" + " animators for " + requestor);
+ Log.v(TAG, (enable ? "enable" : "disable") + " animators for " + requestor
+ + " with pauseDelay of " + Animator.getBackgroundPauseDelay());
for (int i = 0; i < mAnimatorRequestors.size(); ++i) {
- Log.v(TAG, "animatorRequesters " + i + " = " + mAnimatorRequestors.valueAt(i));
+ Log.v(TAG, "animatorRequestors " + i + " = "
+ + mAnimatorRequestors.get(i) + " with referent "
+ + mAnimatorRequestors.get(i).get());
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c0183ad48139..af070238787f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1417,7 +1417,11 @@ public final class ViewRootImpl implements ViewParent,
mFirstPostImeInputStage = earlyPostImeStage;
mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
- AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ if (!mRemoved || !mAppVisible) {
+ AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ } else if (LOCAL_LOGV) {
+ Log.v(mTag, "setView() enabling visibility when removed");
+ }
}
}
}
@@ -1755,7 +1759,12 @@ public final class ViewRootImpl implements ViewParent,
if (!mAppVisible) {
WindowManagerGlobal.trimForeground();
}
- AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ // Only enable if the window is not already removed (via earlier call to doDie())
+ if (!mRemoved || !mAppVisible) {
+ AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
+ } else if (LOCAL_LOGV) {
+ Log.v(mTag, "handleAppVisibility() enabling visibility when removed");
+ }
}
}