Merge "Don't call into AM finish-recents-animation while holding onto the WM lock" into pi-dev

This commit is contained in:
Winson Chung
2018-04-24 21:21:26 +00:00
committed by Android (Google) Code Review
4 changed files with 40 additions and 22 deletions

View File

@@ -5306,7 +5306,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final long origId = Binder.clearCallingIdentity();
try {
synchronized (this) {
mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
// Cancel the recents animation synchronously (do not hold the WM lock)
mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
? REORDER_MOVE_TO_ORIGINAL_POSITION
: REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation");
}

View File

@@ -179,8 +179,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
targetActivity.mLaunchTaskBehind = true;
// Fetch all the surface controls and pass them to the client to get the animation
// started
mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION,
// started. Cancel any existing recents animation running synchronously (do not hold the
// WM lock)
mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION,
"startRecentsActivity");
mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
@@ -200,12 +201,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
}
}
@Override
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode) {
private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
synchronized (mService) {
if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
+ mWindowManager.getRecentsAnimationController()
+ " reorderMode=" + reorderMode);
+ mWindowManager.getRecentsAnimationController()
+ " reorderMode=" + reorderMode);
// Cancel the associated assistant data request
if (mAssistDataRequester != null) {
@@ -298,6 +298,16 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
}
}
@Override
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
boolean runSychronously) {
if (runSychronously) {
finishAnimation(reorderMode);
} else {
mService.mHandler.post(() -> finishAnimation(reorderMode));
}
}
/**
* Called only when the animation should be canceled prior to starting.
*/

View File

@@ -83,9 +83,8 @@ public class RecentsAnimationController implements DeathRecipient {
private final RecentsAnimationCallbacks mCallbacks;
private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
private final int mDisplayId;
private final Runnable mFailsafeRunnable = () -> {
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
};
private final Runnable mFailsafeRunnable = () ->
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
// The recents component app token that is shown behind the visibile tasks
private AppWindowToken mTargetAppToken;
@@ -112,7 +111,7 @@ public class RecentsAnimationController implements DeathRecipient {
private boolean mLinkedToDeathOfRunner;
public interface RecentsAnimationCallbacks {
void onAnimationFinished(@ReorderMode int reorderMode);
void onAnimationFinished(@ReorderMode int reorderMode, boolean runSychronously);
}
private final IRecentsAnimationController mController =
@@ -164,7 +163,8 @@ public class RecentsAnimationController implements DeathRecipient {
// prior to calling the callback
mCallbacks.onAnimationFinished(moveHomeToTop
? REORDER_MOVE_TO_TOP
: REORDER_MOVE_TO_ORIGINAL_POSITION);
: REORDER_MOVE_TO_ORIGINAL_POSITION,
true /* runSynchronously */);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -385,7 +385,17 @@ public class RecentsAnimationController implements DeathRecipient {
}
void cancelAnimation(@ReorderMode int reorderMode, String reason) {
if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
cancelAnimation(reorderMode, false /* runSynchronously */, reason);
}
void cancelAnimationSynchronously(@ReorderMode int reorderMode, String reason) {
cancelAnimation(reorderMode, true /* runSynchronously */, reason);
}
private void cancelAnimation(@ReorderMode int reorderMode, boolean runSynchronously,
String reason) {
if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason
+ " runSynchronously=" + runSynchronously);
synchronized (mService.getWindowManagerLock()) {
if (mCanceled) {
// We've already canceled the animation
@@ -401,8 +411,7 @@ public class RecentsAnimationController implements DeathRecipient {
}
// Clean up and return to the previous app
// Don't hold the WM lock here as it calls back to AM/RecentsAnimation
mCallbacks.onAnimationFinished(reorderMode);
mCallbacks.onAnimationFinished(reorderMode, runSynchronously);
}
void cleanupAnimation(@ReorderMode int reorderMode) {

View File

@@ -2732,17 +2732,15 @@ public class WindowManagerService extends IWindowManager.Stub
/**
* Cancels any running recents animation. The caller should NOT hold the WM lock while calling
* this method, as it can call back into AM, and locking will be done in the animation
* controller itself.
* this method, as it will call back into AM and may cause a deadlock. Any locking will be done
* in the animation controller itself.
*/
public void cancelRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode,
String reason) {
// Note: Do not hold the WM lock, this will lock appropriately in the call which also
// calls through to AM/RecentsAnimation.onAnimationFinished()
public void cancelRecentsAnimationSynchronously(
@RecentsAnimationController.ReorderMode int reorderMode, String reason) {
if (mRecentsAnimationController != null) {
// This call will call through to cleanupAnimation() below after the animation is
// canceled
mRecentsAnimationController.cancelAnimation(reorderMode, reason);
mRecentsAnimationController.cancelAnimationSynchronously(reorderMode, reason);
}
}