Merge "Fix lock contention while swiping up" into ub-launcher3-edmonton
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) {