Fix replacing window timeouts
Do not post app token with the timeout message, instead put the token
in a list and post empty message only.
bug: 28744782
Change-Id: If809d8ee16bcc31067f25ae5696b62d09ea4b864
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a234241..e490a40 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 @@
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 196b38a..8706682 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -415,6 +415,12 @@
final ArrayList<AppWindowToken> 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<AppWindowToken> mReplacingWindowTimeouts = new ArrayList<>();
+
+ /**
* The input consumer added to the window manager which consumes input events to windows below
* it.
*/
@@ -8497,9 +8503,12 @@
}
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: {
@@ -10757,16 +10766,22 @@
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) {