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

Commit 570432f7 authored by Winson Chung's avatar Winson Chung
Browse files

Fix lock contention while swiping up

- Don't lock when making WM calls (only lock when resetting), and use own
  executor since the background executor is fixed to only two threads and
  other things can be running on them already (like task loading).

Bug: 78585335

Change-Id: I73dfc380dd99908cfc30ff7c164a9677a5a126e0
parent 5be40757
Loading
Loading
Loading
Loading
+46 −41
Original line number Diff line number Diff line
@@ -15,27 +15,32 @@
 */
package com.android.quickstep;

import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import java.util.concurrent.ExecutorService;

/**
 * Wrapper around RecentsAnimationController to help with some synchronization
 */
public class RecentsAnimationWrapper {

    public RecentsAnimationControllerCompat controller;
    public RemoteAnimationTargetSet targetSet;

    private RecentsAnimationControllerCompat mController;
    private boolean mInputConsumerEnabled = false;
    private boolean mBehindSystemBars = true;
    private boolean mSplitScreenMinimized = false;

    private final ExecutorService mExecutorService =
            new LooperExecutor(UiThreadHelper.getBackgroundLooper());

    public synchronized void setController(
            RecentsAnimationControllerCompat controller, RemoteAnimationTargetSet targetSet) {
        TraceHelper.partitionSection("RecentsController", "Set controller " + controller);
        this.controller = controller;
        this.mController = controller;
        this.targetSet = targetSet;

        if (mInputConsumerEnabled) {
@@ -48,8 +53,9 @@ public class RecentsAnimationWrapper {
     *                         on the background thread.
     */
    public void finish(boolean toHome, Runnable onFinishComplete) {
        BackgroundExecutor.get().submit(() -> {
            synchronized (this) {
        mExecutorService.submit(() -> {
            RecentsAnimationControllerCompat controller = mController;
            mController = null;
            TraceHelper.endSection("RecentsController",
                    "Finish " + controller + ", toHome=" + toHome);
            if (controller != null) {
@@ -58,8 +64,6 @@ public class RecentsAnimationWrapper {
                if (onFinishComplete != null) {
                    onFinishComplete.run();
                }
                    controller = null;
                }
            }
        });
    }
@@ -67,14 +71,13 @@ public class RecentsAnimationWrapper {
    public void enableInputConsumer() {
        mInputConsumerEnabled = true;
        if (mInputConsumerEnabled) {
            BackgroundExecutor.get().submit(() -> {
                synchronized (this) {
            mExecutorService.submit(() -> {
                RecentsAnimationControllerCompat controller = mController;
                TraceHelper.partitionSection("RecentsController",
                        "Enabling consumer on " + controller);
                if (controller != null) {
                    controller.setInputConsumerEnabled(true);
                }
                }
            });
        }
    }
@@ -84,14 +87,13 @@ public class RecentsAnimationWrapper {
            return;
        }
        mBehindSystemBars = behindSystemBars;
        BackgroundExecutor.get().submit(() -> {
            synchronized (this) {
        mExecutorService.submit(() -> {
            RecentsAnimationControllerCompat controller = mController;
            TraceHelper.partitionSection("RecentsController",
                    "Setting behind system bars on " + controller);
            if (controller != null) {
                controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
            }
            }
        });
    }

@@ -106,25 +108,28 @@ public class RecentsAnimationWrapper {
            return;
        }
        mSplitScreenMinimized = minimized;
        BackgroundExecutor.get().submit(() -> {
            synchronized (this) {
        mExecutorService.submit(() -> {
            RecentsAnimationControllerCompat controller = mController;
            TraceHelper.partitionSection("RecentsController",
                    "Setting minimize dock on " + controller);
            if (controller != null) {
                controller.setSplitScreenMinimized(minimized);
            }
            }
        });
    }

    public void hideCurrentInputMethod() {
        BackgroundExecutor.get().submit(() -> {
            synchronized (this) {
                TraceHelper.partitionSection("RecentsController", "Hiding currentinput method");
        mExecutorService.submit(() -> {
            RecentsAnimationControllerCompat controller = mController;
            TraceHelper.partitionSection("RecentsController",
                    "Hiding currentinput method on " + controller);
            if (controller != null) {
                controller.hideCurrentInputMethod();
            }
            }
        });
    }

    public RecentsAnimationControllerCompat getController() {
        return mController;
    }
}
+31 −36
Original line number Diff line number Diff line
@@ -491,21 +491,18 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
    private void updateFinalShift() {
        float shift = mCurrentShift.value;

        synchronized (mRecentsAnimationWrapper) {
            if (mRecentsAnimationWrapper.controller != null) {
        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
        if (controller != null) {
            Interpolator interpolator = mInteractionType == INTERACTION_QUICK_SCRUB
                    ? ACCEL_2 : LINEAR;
            float interpolated = interpolator.getInterpolation(shift);
                mClipAnimationHelper.applyTransform(
                        mRecentsAnimationWrapper.targetSet, interpolated);
            mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, interpolated);

            // TODO: This logic is spartanic!
            boolean passedThreshold = shift > 0.12f;
            mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
            if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
                    mRecentsAnimationWrapper
                            .setSplitScreenMinimizedForTransaction(passedThreshold);
                }
                mRecentsAnimationWrapper.setSplitScreenMinimizedForTransaction(passedThreshold);
            }
        }

@@ -707,12 +704,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {

    private void switchToScreenshot() {
        boolean finishTransitionPosted = false;
        synchronized (mRecentsAnimationWrapper) {
            if (mRecentsAnimationWrapper.controller != null) {
        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
        if (controller != null) {
            // Update the screenshot of the task
            if (mTaskSnapshot == null) {
                    mTaskSnapshot = mRecentsAnimationWrapper.controller
                            .screenshotTask(mRunningTaskId);
                mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
            }
            TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
            mRecentsView.setRunningTaskHidden(false);
@@ -729,7 +725,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
                }.attach();
            }
        }
        }
        if (!finishTransitionPosted) {
            // If we haven't posted a draw callback, set the state immediately.
            setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);