OSDN Git Service

Fix replacing window timeouts
authorChong Zhang <chz@google.com>
Thu, 12 May 2016 23:00:01 +0000 (16:00 -0700)
committerChong Zhang <chz@google.com>
Thu, 12 May 2016 23:01:53 +0000 (16:01 -0700)
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

services/core/java/com/android/server/wm/AppWindowToken.java
services/core/java/com/android/server/wm/WindowManagerService.java

index a234241..e490a40 100644 (file)
@@ -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);
index 196b38a..8706682 100644 (file)
@@ -415,6 +415,12 @@ public class WindowManagerService extends IWindowManager.Stub
     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 @@ 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: {
@@ -10757,16 +10766,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) {