From 0638a9f91f2539ceed515b679ab3f71e51eb7fee Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Fri, 7 May 2021 13:20:24 +0800 Subject: [PATCH] Fix Keyboard covered input box after leaving split screen When leaving split-screen, task organizer will trigger transaction to reparent task and then invoking updateAboveInsetsState for all windows when updating the IME layering target through the below call path: InsetsStateController.updateAboveInsetsState DisplayContent.setImeLayeringTargetInner DisplayContent.computeImeTarget DisplayContent.updateFocusedWindowLocked .. DisplayContent.layoutAndAssignWindowLayersIfNeeded Task.reparent .. WindowOrganizerController.applyTransaction However, DC#forAllWindows will skip IME windows in WindowState#applyImeWindowsIfNeeded since split-screen mode not yet be changed. that caused the application will get mAboveInsetsState when dispatching to the client because system thought the app window is above IME. Use isSplitScreenModeActivated() to consolide the split-screen check in case misjudge for this issue. Fix: 186746922 Test: atest InsetsStateControllerTest Test: manual as issue steps Change-Id: I47bcb1234a49ea35c5e0d7281973fb3237e420eb --- .../core/java/com/android/server/wm/DisplayContent.java | 6 ++++++ services/core/java/com/android/server/wm/WindowState.java | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a10847876ab6a..e30f274f8438d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2456,6 +2456,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp setWindowingMode(windowingMode); } + /** + * See {@code WindowState#applyImeWindowsIfNeeded} for the details that we won't traverse the + * IME window in some cases. + */ boolean forAllImeWindows(ToBooleanFunction callback, boolean traverseTopToBottom) { return mImeWindowsContainer.forAllWindowForce(callback, traverseTopToBottom); } @@ -4573,6 +4577,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private boolean skipImeWindowsDuringTraversal(DisplayContent dc) { // We skip IME windows so they're processed just above their target, except // in split-screen mode where we process the IME containers above the docked divider. + // Note that this method check should align with {@link + // WindowState#applyImeWindowsIfNeeded} in case of any state mismatch. return dc.getImeTarget(IME_TARGET_LAYERING) != null && !dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated(); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2e8d4cd4e7f8c..11ea2286241e5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4829,7 +4829,10 @@ class WindowState extends WindowContainer implements WindowManagerP // directly above it. The exception is if we are in split screen // in which case we process the IME at the DisplayContent level to // ensure it is above the docked divider. - if (isImeLayeringTarget() && !inSplitScreenWindowingMode()) { + // (i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME + // window will be ignored to traverse when the IME target is still in split-screen mode). + if (isImeLayeringTarget() + && !getDisplayContent().getDefaultTaskDisplayArea().isSplitScreenModeActivated()) { if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) { return true; }