Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11f489aa authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Fix activity leak bug" into tm-qpr-dev am: 020d3fa7" into tm-qpr-dev-plus-aosp

parents 250413b0 359453d8
Loading
Loading
Loading
Loading
+39 −20
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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,19 +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
        requestAnimatorsEnabled(false, requestor);
        mAnimatorRequestors.remove(requestor);
        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);
        }
    }

@@ -173,10 +163,36 @@ public class AnimationHandler {
    private void requestAnimatorsEnabledImpl(boolean enable, Object requestor) {
        boolean wasEmpty = mAnimatorRequestors.isEmpty();
        setAnimatorPausingEnabled(isPauseBgAnimationsEnabledInSystemProperties());
        synchronized (mAnimatorRequestors) {
            // Only store WeakRef objects to avoid leaks
            if (enable) {
            mAnimatorRequestors.add(requestor);
                // 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 {
            mAnimatorRequestors.remove(requestor);
                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
            }
        }
        if (!sAnimatorPausingEnabled) {
            // Resume any animators that have been paused in the meantime, otherwise noop
@@ -198,9 +214,12 @@ public class AnimationHandler {
            }
        }
        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());
            }
        }
    }
+11 −2
Original line number Diff line number Diff line
@@ -1411,7 +1411,11 @@ public final class ViewRootImpl implements ViewParent,
                mFirstPostImeInputStage = earlyPostImeStage;
                mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;

                if (!mRemoved || !mAppVisible) {
                    AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
                } else if (LOCAL_LOGV) {
                    Log.v(mTag, "setView() enabling visibility when removed");
                }
            }
        }
    }
@@ -1749,7 +1753,12 @@ public final class ViewRootImpl implements ViewParent,
            if (!mAppVisible) {
                WindowManagerGlobal.trimForeground();
            }
            // 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");
            }
        }
    }