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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user