diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index a23424175300a..e490a40306449 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -582,10 +582,7 @@ class AppWindowToken extends WindowToken { w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow; // if we got a replacement window, reset the timeout to give drawing more time - service.mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT); - service.mH.sendMessageDelayed( - service.mH.obtainMessage(H.WINDOW_REPLACEMENT_TIMEOUT, this), - WINDOW_REPLACEMENT_TIMEOUT_DURATION); + service.scheduleReplacingWindowTimeouts(this); } } allAppWindows.add(w); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8b1d2a0d632ce..defd513703a4c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -414,6 +414,12 @@ public class WindowManagerService extends IWindowManager.Stub */ final ArrayList mFinishedStarting = new ArrayList<>(); + /** + * List of app window tokens that are waiting for replacing windows. If the + * replacement doesn't come in time the stale windows needs to be disposed of. + */ + final ArrayList mReplacingWindowTimeouts = new ArrayList<>(); + /** * The input consumer added to the window manager which consumes input events to windows below * it. @@ -8497,9 +8503,12 @@ public class WindowManagerService extends IWindowManager.Stub } break; case WINDOW_REPLACEMENT_TIMEOUT: { - final AppWindowToken token = (AppWindowToken) msg.obj; synchronized (mWindowMap) { - token.clearTimedoutReplacesLocked(); + for (int i = mReplacingWindowTimeouts.size() - 1; i >= 0; i--) { + final AppWindowToken token = mReplacingWindowTimeouts.get(i); + token.clearTimedoutReplacesLocked(); + } + mReplacingWindowTimeouts.clear(); } } case NOTIFY_APP_TRANSITION_STARTING: { @@ -10769,16 +10778,22 @@ public class WindowManagerService extends IWindowManager.Stub return; } if (replacing) { - mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT); - mH.sendMessageDelayed( - mH.obtainMessage(H.WINDOW_REPLACEMENT_TIMEOUT, appWindowToken), - WINDOW_REPLACEMENT_TIMEOUT_DURATION); + scheduleReplacingWindowTimeouts(appWindowToken); } else { appWindowToken.resetReplacingWindows(); } } } + void scheduleReplacingWindowTimeouts(AppWindowToken appWindowToken) { + if (!mReplacingWindowTimeouts.contains(appWindowToken)) { + mReplacingWindowTimeouts.add(appWindowToken); + } + mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT); + mH.sendEmptyMessageDelayed( + H.WINDOW_REPLACEMENT_TIMEOUT, WINDOW_REPLACEMENT_TIMEOUT_DURATION); + } + @Override public int getDockedStackSide() { synchronized (mWindowMap) {