OSDN Git Service

Fix flashing dialogs when IME enters/exits.
authorFilip Gruszczynski <gruszczy@google.com>
Tue, 5 Jan 2016 19:29:21 +0000 (11:29 -0800)
committerFilip Gruszczynski <gruszczy@google.com>
Tue, 5 Jan 2016 21:35:12 +0000 (13:35 -0800)
The flashing is caused by changing the shown frame of the window
prematurely, before the animation kicks in. After the animation kicks
in, the shown frame goes back to the original position and then animates
to the final position.

We need the shown calculation to happen during layout for resizing and
the layout might be triggered at any time before the animation is run.
In order to avoid flashing, we don't calculate shown frame for windows
that are animating during the layout and let the animation position the
shown frame correctly later.

Includes also logging for inset setting, which triggers layout run.

Bug: 26323134
Change-Id: Ibe1efae798415d3564c659aa94c2b94af92c743a

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

index f7b81cb..d722ec7 100644 (file)
@@ -224,11 +224,14 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM;
+
     static final int LAYOUT_REPEAT_THRESHOLD = 4;
 
     static final boolean PROFILE_ORIENTATION = false;
@@ -2428,13 +2431,17 @@ public class WindowManagerService extends IWindowManager.Stub
         }
     }
 
-    void setInsetsWindow(Session session, IWindow client,
-            int touchableInsets, Rect contentInsets,
+    void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,
             Rect visibleInsets, Region touchableRegion) {
         long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
                 WindowState w = windowForClientLocked(session, client, false);
+                if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w
+                        + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets
+                        + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets
+                        + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion
+                        + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets);
                 if (w != null) {
                     w.mGivenInsetsPending = false;
                     w.mGivenContentInsets.set(contentInsets);
index 6ebda07..feeab27 100644 (file)
@@ -739,13 +739,15 @@ class WindowSurfacePlacer {
                             }
                         }
                     }
-                    /*
-                     * Updates the shown frame before we set up the surface. This is needed because
-                     * the resizing could change the top-left position (in addition to size) of the
-                     * window. setSurfaceBoundariesLocked uses mShownPosition to position the
-                      * surface.
-                     */
-                    winAnimator.computeShownFrameLocked();
+                    if (!winAnimator.isAnimating()) {
+                        // Updates the shown frame before we set up the surface. This is needed
+                        // because the resizing could change the top-left position (in addition to
+                        // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
+                        // position the surface. We only apply it to windows that aren't animating,
+                        // because we depend on the animation to calculate the correct shown frame
+                        // on the next animation step.
+                        winAnimator.computeShownFrameLocked();
+                    }
                     winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
                 }