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

Commit 702050b6 authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "Preventing release animation targets due to unsynchronize." into main

parents 0e6f9586 d0e3c362
Loading
Loading
Loading
Loading
+49 −17
Original line number Diff line number Diff line
@@ -106,11 +106,12 @@ public class BackAnimationRunner {

    private Runnable mFinishedCallback;
    private RemoteAnimationTarget[] mApps;
    private IRemoteAnimationFinishedCallback mRemoteCallback;
    private RemoteAnimationFinishedStub mRemoteCallback;

    private static class RemoteAnimationFinishedStub extends IRemoteAnimationFinishedCallback.Stub {
        //the binder callback should not hold strong reference to it to avoid memory leak.
        private WeakReference<BackAnimationRunner> mRunnerRef;
        private final WeakReference<BackAnimationRunner> mRunnerRef;
        private boolean mAbandoned;

        private RemoteAnimationFinishedStub(BackAnimationRunner runner) {
            mRunnerRef = new WeakReference<>(runner);
@@ -118,23 +119,29 @@ public class BackAnimationRunner {

        @Override
        public void onAnimationFinished() {
            BackAnimationRunner runner = mRunnerRef.get();
            synchronized (this) {
                if (mAbandoned) {
                    return;
                }
            }
            final BackAnimationRunner runner = mRunnerRef.get();
            if (runner == null) {
                return;
            }
            if (runner.shouldMonitorCUJ(runner.mApps)) {
                InteractionJankMonitor.getInstance().end(runner.mCujType);
            runner.onAnimationFinish(this);
        }

            runner.mFinishedCallback.run();
            for (int i = runner.mApps.length - 1; i >= 0; --i) {
                 SurfaceControl sc = runner.mApps[i].leash;
                 if (sc != null && sc.isValid()) {
                     sc.release();
        void abandon() {
            synchronized (this) {
                mAbandoned = true;
                final BackAnimationRunner runner = mRunnerRef.get();
                if (runner == null) {
                    return;
                }
                if (runner.shouldMonitorCUJ(runner.mApps)) {
                    InteractionJankMonitor.getInstance().end(runner.mCujType);
                }
            }
            runner.mApps = null;
            runner.mFinishedCallback = null;
        }
    }

@@ -144,13 +151,16 @@ public class BackAnimationRunner {
     */
    void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
            RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
        InteractionJankMonitor interactionJankMonitor = InteractionJankMonitor.getInstance();
        if (mRemoteCallback != null) {
            mRemoteCallback.abandon();
            mRemoteCallback = null;
        }
        mRemoteCallback = new RemoteAnimationFinishedStub(this);
        mFinishedCallback = finishedCallback;
        mApps = apps;
        if (mRemoteCallback == null) mRemoteCallback = new RemoteAnimationFinishedStub(this);
        mWaitingAnimation = false;
        if (shouldMonitorCUJ(apps)) {
            interactionJankMonitor.begin(
            InteractionJankMonitor.getInstance().begin(
                    apps[0].leash, mContext, mHandler, mCujType);
        }
        try {
@@ -161,6 +171,28 @@ public class BackAnimationRunner {
        }
    }

    void onAnimationFinish(RemoteAnimationFinishedStub finished) {
        mHandler.post(() -> {
            if (mRemoteCallback != null && finished != mRemoteCallback) {
                return;
            }
            if (shouldMonitorCUJ(mApps)) {
                InteractionJankMonitor.getInstance().end(mCujType);
            }

            mFinishedCallback.run();
            for (int i = mApps.length - 1; i >= 0; --i) {
                final SurfaceControl sc = mApps[i].leash;
                if (sc != null && sc.isValid()) {
                    sc.release();
                }
            }
            mApps = null;
            mFinishedCallback = null;
            mRemoteCallback = null;
        });
    }

    @VisibleForTesting
    boolean shouldMonitorCUJ(RemoteAnimationTarget[] apps) {
        return apps.length > 0 && mCujType != NO_CUJ;