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

Commit f096f3eb authored by Fengjiang Li's avatar Fengjiang Li Committed by Android (Google) Code Review
Browse files

Merge "Fix memory leak of Launcher activityfrom QuickstepTransitionManager and...

Merge "Fix memory leak of Launcher activityfrom QuickstepTransitionManager and LauncherBackAnimationController" into main
parents d48f89be e180de6b
Loading
Loading
Loading
Loading
+22 −20
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.wm.shell.startingsurface.IStartingWindowListener;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@@ -225,7 +226,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
    private final float mClosingWindowTransY;
    private final float mMaxShadowRadius;

    private final StartingWindowListener mStartingWindowListener = new StartingWindowListener();
    private final StartingWindowListener mStartingWindowListener =
            new StartingWindowListener(this);

    private DeviceProfile mDeviceProfile;

@@ -278,7 +280,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                }
            };

            mStartingWindowListener.setTransitionManager(this);
            SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
                    mStartingWindowListener);
        }
@@ -310,8 +311,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
        ItemInfo tag = (ItemInfo) v.getTag();
        if (tag != null && tag.shouldUseBackgroundAnimation()) {
            ContainerAnimationRunner containerAnimationRunner =
                    ContainerAnimationRunner.from(v, mStartingWindowListener, onEndCallback);
            ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(
                            v, mLauncher, mStartingWindowListener, onEndCallback);
            if (containerAnimationRunner != null) {
                mAppLaunchRunner = containerAnimationRunner;
            }
@@ -1152,7 +1153,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
    public void onActivityDestroyed() {
        unregisterRemoteAnimations();
        unregisterRemoteTransitions();
        mStartingWindowListener.setTransitionManager(null);
        SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null);
    }

@@ -1775,8 +1775,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        }

        @Nullable
        private static ContainerAnimationRunner from(
                View v, StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
        private static ContainerAnimationRunner from(View v, Launcher launcher,
                StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
            View viewToUse = findViewWithBackground(v);
            if (viewToUse == null) {
                viewToUse = v;
@@ -1801,8 +1801,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                        }
                    };

            ActivityLaunchAnimator.Callback callback = task -> ColorUtils.setAlphaComponent(
                    startingWindowListener.getBackgroundColor(), 255);
            ActivityLaunchAnimator.Callback callback = task -> {
                final int backgroundColor =
                        startingWindowListener.mBackgroundColor == Color.TRANSPARENT
                                ? launcher.getScrimView().getBackgroundColor()
                                : startingWindowListener.mBackgroundColor;
                return ColorUtils.setAlphaComponent(backgroundColor, 255);
            };

            ActivityLaunchAnimator.Listener listener = new ActivityLaunchAnimator.Listener() {
                @Override
@@ -1912,24 +1917,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        }
    }

    private class StartingWindowListener extends IStartingWindowListener.Stub {
        private QuickstepTransitionManager mTransitionManager;
    private static class StartingWindowListener extends IStartingWindowListener.Stub {
        private final WeakReference<QuickstepTransitionManager> mTransitionManagerRef;
        private int mBackgroundColor;

        public void setTransitionManager(QuickstepTransitionManager transitionManager) {
            mTransitionManager = transitionManager;
        private StartingWindowListener(QuickstepTransitionManager transitionManager) {
            mTransitionManagerRef = new WeakReference<>(transitionManager);
        }

        @Override
        public void onTaskLaunching(int taskId, int supportedType, int color) {
            mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
            mBackgroundColor = color;
            QuickstepTransitionManager transitionManager = mTransitionManagerRef.get();
            if (transitionManager != null) {
                transitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
            }

        public int getBackgroundColor() {
            return mBackgroundColor == Color.TRANSPARENT
                    ? mLauncher.getScrimView().getBackgroundColor()
                    : mBackgroundColor;
            mBackgroundColor = color;
        }
    }

+90 −49
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.systemui.shared.system.QuickStepContract;

import java.lang.ref.WeakReference;

/**
 * Controls the animation of swiping back and returning to launcher.
 *
@@ -105,7 +107,7 @@ public class LauncherBackAnimationController {
    private boolean mAnimatorSetInProgress = false;
    private float mBackProgress = 0;
    private boolean mBackInProgress = false;
    private IOnBackInvokedCallback mBackCallback;
    private OnBackInvokedCallbackStub mBackCallback;
    private IRemoteAnimationFinishedCallback mAnimationFinishedCallback;
    private BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
    private SurfaceControl mScrimLayer;
@@ -137,65 +139,104 @@ public class LauncherBackAnimationController {
     * @param handler Handler to the thread to run the animations on.
     */
    public void registerBackCallbacks(Handler handler) {
        mBackCallback = new IOnBackInvokedCallback.Stub() {
        mBackCallback = new OnBackInvokedCallbackStub(handler, mProgressAnimator, this);
        SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback,
                new RemoteAnimationRunnerStub(this));
    }

    private static class OnBackInvokedCallbackStub extends IOnBackInvokedCallback.Stub {
        private Handler mHandler;
        private BackProgressAnimator mProgressAnimator;
        // LauncherBackAnimationController has strong reference to Launcher activity, the binder
        // callback should not hold strong reference to it to avoid memory leak.
        private WeakReference<LauncherBackAnimationController> mControllerRef;

        private OnBackInvokedCallbackStub(
                Handler handler,
                BackProgressAnimator progressAnimator,
                LauncherBackAnimationController controller) {
            mHandler = handler;
            mProgressAnimator = progressAnimator;
            mControllerRef = new WeakReference<>(controller);
        }

        @Override
        public void onBackCancelled() {
                handler.post(() -> {
            mHandler.post(() -> {
                LauncherBackAnimationController controller = mControllerRef.get();
                if (controller != null) {
                    mProgressAnimator.onBackCancelled(
                            LauncherBackAnimationController.this::resetPositionAnimated);
                            controller::resetPositionAnimated);
                }
            });
        }

        @Override
        public void onBackInvoked() {
                handler.post(() -> {
                    startTransition();
            mHandler.post(() -> {
                LauncherBackAnimationController controller = mControllerRef.get();
                if (controller != null) {
                    controller.startTransition();
                }
                mProgressAnimator.reset();
            });
        }

        @Override
            public void onBackProgressed(BackMotionEvent backEvent) {
                handler.post(() -> {
                    mProgressAnimator.onBackProgressed(backEvent);
        public void onBackProgressed(BackMotionEvent backMotionEvent) {
            mHandler.post(() -> {
                mProgressAnimator.onBackProgressed(backMotionEvent);
            });
        }

        @Override
        public void onBackStarted(BackMotionEvent backEvent) {
                handler.post(() -> {
                    startBack(backEvent);
            mHandler.post(() -> {
                LauncherBackAnimationController controller = mControllerRef.get();
                if (controller != null) {
                    controller.startBack(backEvent);
                    mProgressAnimator.onBackStarted(backEvent, event -> {
                        mBackProgress = event.getProgress();
                        float backProgress = event.getProgress();
                        // TODO: Update once the interpolation curve spec is finalized.
                        mBackProgress =
                                1 - (1 - mBackProgress) * (1 - mBackProgress) * (1
                                        - mBackProgress);
                        updateBackProgress(mBackProgress, event);
                        controller.mBackProgress =
                                1 - (1 - backProgress) * (1 - backProgress) * (1
                                        - backProgress);
                        controller.updateBackProgress(controller.mBackProgress, event);
                    });
                }
            });
        }
        };
    }

    private static class RemoteAnimationRunnerStub extends IRemoteAnimationRunner.Stub {

        // LauncherBackAnimationController has strong reference to Launcher activity, the binder
        // callback should not hold strong reference to it to avoid memory leak.
        private WeakReference<LauncherBackAnimationController> mControllerRef;

        private RemoteAnimationRunnerStub(LauncherBackAnimationController controller) {
            mControllerRef = new WeakReference<>(controller);
        }

        final IRemoteAnimationRunner runner = new IRemoteAnimationRunner.Stub() {
        @Override
        public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
                RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                IRemoteAnimationFinishedCallback finishedCallback) {
            LauncherBackAnimationController controller = mControllerRef.get();
            if (controller == null) {
                return;
            }
            for (final RemoteAnimationTarget target : apps) {
                if (MODE_CLOSING == target.mode) {
                        mBackTarget = target;
                    controller.mBackTarget = target;
                    break;
                }
            }
                mAnimationFinishedCallback = finishedCallback;
            controller.mAnimationFinishedCallback = finishedCallback;
        }

        @Override
        public void onAnimationCancelled() {}
        };

        SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback, runner);
    }

    private void resetPositionAnimated() {