From c46f41c5b5ea5b626ed729030de100223493948d Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Tue, 5 Jan 2016 11:29:21 -0800 Subject: [PATCH] Fix flashing dialogs when IME enters/exits. 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 --- .../android/server/wm/WindowManagerService.java | 11 +++++++++-- .../android/server/wm/WindowSurfacePlacer.java | 16 +++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f7b81cb9634e2..d722ec7a48033 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -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); diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 6ebda0727165b..feeab27e8fae8 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -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); }