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
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
index 730984c..30b10b0 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -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,17 +53,16 @@
      *                         on the background thread.
      */
     public void finish(boolean toHome, Runnable onFinishComplete) {
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.endSection("RecentsController",
-                        "Finish " + controller + ", toHome=" + toHome);
-                if (controller != null) {
-                    controller.setInputConsumerEnabled(false);
-                    controller.finish(toHome);
-                    if (onFinishComplete != null) {
-                        onFinishComplete.run();
-                    }
-                    controller = null;
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            mController = null;
+            TraceHelper.endSection("RecentsController",
+                    "Finish " + controller + ", toHome=" + toHome);
+            if (controller != null) {
+                controller.setInputConsumerEnabled(false);
+                controller.finish(toHome);
+                if (onFinishComplete != null) {
+                    onFinishComplete.run();
                 }
             }
         });
@@ -67,13 +71,12 @@
     public void enableInputConsumer() {
         mInputConsumerEnabled = true;
         if (mInputConsumerEnabled) {
-            BackgroundExecutor.get().submit(() -> {
-                synchronized (this) {
-                    TraceHelper.partitionSection("RecentsController",
-                            "Enabling consumer on " + controller);
-                    if (controller != null) {
-                        controller.setInputConsumerEnabled(true);
-                    }
+            mExecutorService.submit(() -> {
+                RecentsAnimationControllerCompat controller = mController;
+                TraceHelper.partitionSection("RecentsController",
+                        "Enabling consumer on " + controller);
+                if (controller != null) {
+                    controller.setInputConsumerEnabled(true);
                 }
             });
         }
@@ -84,13 +87,12 @@
             return;
         }
         mBehindSystemBars = behindSystemBars;
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.partitionSection("RecentsController",
-                        "Setting behind system bars on " + controller);
-                if (controller != null) {
-                    controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
-                }
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            TraceHelper.partitionSection("RecentsController",
+                    "Setting behind system bars on " + controller);
+            if (controller != null) {
+                controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
             }
         });
     }
@@ -106,25 +108,28 @@
             return;
         }
         mSplitScreenMinimized = minimized;
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.partitionSection("RecentsController",
-                        "Setting minimize dock on " + controller);
-                if (controller != null) {
-                    controller.setSplitScreenMinimized(minimized);
-                }
+        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");
-                if (controller != null) {
-                    controller.hideCurrentInputMethod();
-                }
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            TraceHelper.partitionSection("RecentsController",
+                    "Hiding currentinput method on " + controller);
+            if (controller != null) {
+                controller.hideCurrentInputMethod();
             }
         });
     }
+
+    public RecentsAnimationControllerCompat getController() {
+        return mController;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 2f7aef8..2eae2ae 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -491,21 +491,18 @@
     private void updateFinalShift() {
         float shift = mCurrentShift.value;
 
-        synchronized (mRecentsAnimationWrapper) {
-            if (mRecentsAnimationWrapper.controller != null) {
-                Interpolator interpolator = mInteractionType == INTERACTION_QUICK_SCRUB
-                        ? ACCEL_2 : LINEAR;
-                float interpolated = interpolator.getInterpolation(shift);
-                mClipAnimationHelper.applyTransform(
-                        mRecentsAnimationWrapper.targetSet, interpolated);
+        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);
 
-                // TODO: This logic is spartanic!
-                boolean passedThreshold = shift > 0.12f;
-                mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
-                if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
-                    mRecentsAnimationWrapper
-                            .setSplitScreenMinimizedForTransaction(passedThreshold);
-                }
+            // TODO: This logic is spartanic!
+            boolean passedThreshold = shift > 0.12f;
+            mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
+            if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
+                mRecentsAnimationWrapper.setSplitScreenMinimizedForTransaction(passedThreshold);
             }
         }
 
@@ -707,27 +704,25 @@
 
     private void switchToScreenshot() {
         boolean finishTransitionPosted = false;
-        synchronized (mRecentsAnimationWrapper) {
-            if (mRecentsAnimationWrapper.controller != null) {
-                // Update the screenshot of the task
-                if (mTaskSnapshot == null) {
-                    mTaskSnapshot = mRecentsAnimationWrapper.controller
-                            .screenshotTask(mRunningTaskId);
-                }
-                TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
-                mRecentsView.setRunningTaskHidden(false);
-                if (taskView != null) {
-                    // Defer finishing the animation until the next launcher frame with the
-                    // new thumbnail
-                    finishTransitionPosted = new WindowCallbacksCompat(taskView) {
+        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+        if (controller != null) {
+            // Update the screenshot of the task
+            if (mTaskSnapshot == null) {
+                mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
+            }
+            TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
+            mRecentsView.setRunningTaskHidden(false);
+            if (taskView != null) {
+                // Defer finishing the animation until the next launcher frame with the
+                // new thumbnail
+                finishTransitionPosted = new WindowCallbacksCompat(taskView) {
 
-                        @Override
-                        public void onPostDraw(Canvas canvas) {
-                            setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
-                            detach();
-                        }
-                    }.attach();
-                }
+                    @Override
+                    public void onPostDraw(Canvas canvas) {
+                        setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+                        detach();
+                    }
+                }.attach();
             }
         }
         if (!finishTransitionPosted) {