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

Commit 2bd3a022 authored by Tracy Zhou's avatar Tracy Zhou
Browse files

Properly clean up screenshot of recents animation upon cancelation

Bug: 122593881
Test: Manual
Change-Id: Ia9ce1ede08309a0898c622bcd07a9e076443d98a
parent 0c3692d5
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -173,6 +173,12 @@ public class RecentsAnimationWrapper {
        return true;
    }

    public void setCancelWithDeferredScreenshot(boolean deferredWithScreenshot) {
        if (targetSet != null) {
            targetSet.controller.setCancelWithDeferredScreenshot(deferredWithScreenshot);
        }
    }

    public SwipeAnimationTargetSet getController() {
        return targetSet;
    }
+1 −0
Original line number Diff line number Diff line
@@ -1170,6 +1170,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
            mLauncherTransitionController = null;
        }
        mActivityControlHelper.onSwipeUpComplete(mActivity);
        mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true);

        // Animate the first icon.
        mRecentsView.animateUpRunningTaskIconScale();
+14 −1
Original line number Diff line number Diff line
@@ -38,9 +38,16 @@ import androidx.annotation.UiThread;
 */
public class RecentsAnimationListenerSet implements RecentsAnimationListener {

    // The actual app surface is replaced by a screenshot upon recents animation cancelation when
    // deferredWithScreenshot is true. Launcher takes the responsibility to clean up this screenshot
    // after app transition is finished. This delay is introduced to cover the app transition
    // period of time.
    private final int TRANSITION_DELAY = 100;

    private final Set<SwipeAnimationListener> mListeners = new ArraySet<>();
    private final boolean mShouldMinimizeSplitScreen;
    private final Consumer<SwipeAnimationTargetSet> mOnFinishListener;
    private RecentsAnimationControllerCompat mController;

    public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen,
            Consumer<SwipeAnimationTargetSet> onFinishListener) {
@@ -64,6 +71,7 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
    public final void onAnimationStart(RecentsAnimationControllerCompat controller,
            RemoteAnimationTargetCompat[] targets, Rect homeContentInsets,
            Rect minimizedHomeBounds) {
        mController = controller;
        SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, targets,
                homeContentInsets, minimizedHomeBounds, mShouldMinimizeSplitScreen,
                mOnFinishListener);
@@ -75,12 +83,17 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
    }

    @Override
    public final void onAnimationCanceled() {
    public final void onAnimationCanceled(boolean deferredWithScreenshot) {
        Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
            for (SwipeAnimationListener listener : getListeners()) {
                listener.onRecentsAnimationCanceled();
            }
        });
        // TODO: handle the transition better instead of simply using a transition delay.
        if (deferredWithScreenshot) {
            MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
                    TRANSITION_DELAY);
        }
    }

    private SwipeAnimationListener[] getListeners() {
+1 −6
Original line number Diff line number Diff line
@@ -95,13 +95,8 @@ public class LauncherRecentsView extends RecentsView<Launcher> {

    @Override
    public void startHome() {
        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
            takeScreenshotAndFinishRecentsAnimation(true,
                    () -> mActivity.getStateManager().goToState(NORMAL));
        } else {
        mActivity.getStateManager().goToState(NORMAL);
    }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+0 −48
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ import com.android.quickstep.RecentsModel.TaskThumbnailChangeListener;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.util.TaskViewDrawable;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -103,7 +102,6 @@ import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowCallbacksCompat;

import java.util.ArrayList;
import java.util.function.Consumer;
@@ -1577,50 +1575,4 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl

        mRecentsAnimationWrapper.finish(toRecents, onFinishComplete);
    }

    public void takeScreenshotAndFinishRecentsAnimation(boolean toRecents,
            Runnable onFinishComplete) {
        if (mRecentsAnimationWrapper == null || getRunningTaskView() == null) {
            if (onFinishComplete != null) {
                onFinishComplete.run();
            }
            return;
        }

        SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
        if (controller != null) {
            // Update the screenshot of the task
            ThumbnailData taskSnapshot = controller.screenshotTask(mRunningTaskId);
            TaskView taskView = updateThumbnail(mRunningTaskId, taskSnapshot);
            if (taskView != null) {
                taskView.setShowScreenshot(true);
                // Defer finishing the animation until the next launcher frame with the
                // new thumbnail
                new WindowCallbacksCompat(taskView) {

                    // The number of frames to defer until we actually finish the animation
                    private int mDeferFrameCount = 2;

                    @Override
                    public void onPostDraw(Canvas canvas) {
                        if (mDeferFrameCount > 0) {
                            mDeferFrameCount--;
                            // Workaround, detach and reattach to invalidate the root node for
                            // another draw
                            detach();
                            attach();
                            taskView.invalidate();
                            return;
                        }

                        detach();
                        mRecentsAnimationWrapper.finish(toRecents, () -> {
                            onFinishComplete.run();
                            mRunningTaskId = -1;
                        });
                    }
                }.attach();
            }
        }
    }
}
Loading