void cancelAnimation() {
if (DEBUG) Log.d(TAG, "cancelAnimation()");
- if (mCanceled) {
- // We've already canceled the animation
- return;
- }
- mCanceled = true;
- try {
- mRunner.onAnimationCanceled();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to cancel recents animation", e);
+ synchronized (mService.getWindowManagerLock()) {
+ if (mCanceled) {
+ // We've already canceled the animation
+ return;
+ }
+ mCanceled = true;
+ try {
+ mRunner.onAnimationCanceled();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to cancel recents animation", e);
+ }
}
-
// Clean up and return to the previous app
+ // Don't hold the WM lock here as it calls back to AM/RecentsAnimation
mCallbacks.onAnimationFinished(false /* moveHomeToTop */);
}
IRecentsAnimationRunner recentsAnimationRunner,
RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId) {
synchronized (mWindowMap) {
- cancelRecentsAnimation();
mRecentsAnimationController = new RecentsAnimationController(this,
recentsAnimationRunner, callbacks, displayId);
mRecentsAnimationController.initialize();
}
public void cancelRecentsAnimation() {
- synchronized (mWindowMap) {
- if (mRecentsAnimationController != null) {
- // This call will call through to cleanupAnimation() below after the animation is
- // canceled
- mRecentsAnimationController.cancelAnimation();
- }
+ // Note: Do not hold the WM lock, this will lock appropriately in the call which also
+ // calls through to AM/RecentsAnimation.onAnimationFinished()
+ if (mRecentsAnimationController != null) {
+ // This call will call through to cleanupAnimation() below after the animation is
+ // canceled
+ mRecentsAnimationController.cancelAnimation();
}
}