From 570432f700be5880df1a41c74ffbd75ec0d1a8dd Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 9 May 2018 13:45:51 -0700 Subject: [PATCH] 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 --- .../quickstep/RecentsAnimationWrapper.java | 87 ++++++++++--------- .../WindowTransformSwipeHandler.java | 63 +++++++------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java index 730984c934..30b10b0eab 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 @@ public class RecentsAnimationWrapper { * 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 class RecentsAnimationWrapper { 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 @@ public class RecentsAnimationWrapper { 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 @@ public class RecentsAnimationWrapper { 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 2f7aef826d..2eae2aebef 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -491,21 +491,18 @@ public class WindowTransformSwipeHandler { 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 @@ public class WindowTransformSwipeHandler { 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) {