Fix IME aboves popupwindow when the app is in split-screen

As now the new split-screen system has been migated to wmShell
with using WINDOWING_MODE_MULTI_WINDOW to setup the split task.
so inSplitScreenWindowingMode() will no longer be true since this
method is used for legacy split-screen.

It affects WindowState#needsRelativeLayeringToIme can not
check if the app is in split-screen window and makes system can't
set relative layering to IME for popupWindow to make it above IME.

Note that setting relative layering with IME also benefits for other
non-fullscreen windowing mode like in bubble/freeform mode, the
dropdown menu can above the IME when the parent window is IME
layering target.

Changing to use DC#isImeAttachedToApp() to fix this layering issue.

Fix: 201504527
Test: atest ZOrderingTest#\
 testPopupWindowAndParentIsImeTarget_expectHigherThanIme_inMultiWindow
Test: manual as issue steps
   1) Go to "Create contact" in Phone.
   2) Enter split-screen mode.
   3) Click on a text box of "Create contact".
   4) Click the menu button to show the menu of "Create contact".
   5) Expect the layer of the menu should above the IME surface.

Change-Id: I2f466a2305e56e4fd2a0c509d7c8027104cb51b6
This commit is contained in:
Ming-Shin Lu
2021-10-01 01:43:51 +08:00
parent 3dc9302627
commit d438917585
3 changed files with 33 additions and 7 deletions

View File

@@ -5662,9 +5662,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
boolean needsRelativeLayeringToIme() {
// We only use the relative layering mode in split screen, as part of elevating the IME
// and windows above it's target above the docked divider.
if (!inSplitScreenWindowingMode()) {
// We use the relative layering when IME isn't attached to the app. Such as part of
// elevating the IME and windows above it's target above the docked divider in
// split-screen, or make the popupMenu to be above the IME when the parent window is the
// IME layering target in bubble/freeform mode.
if (mDisplayContent.isImeAttachedToApp()) {
return false;
}

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_IME;
@@ -835,8 +836,7 @@ public class WindowStateTests extends WindowTestsBase {
WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken,
"SameTokenWindow");
mDisplayContent.setImeLayeringTarget(mAppWindow);
sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
assertTrue(sameTokenWindow.needsRelativeLayeringToIme());
sameTokenWindow.removeImmediately();
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
@@ -848,8 +848,7 @@ public class WindowStateTests extends WindowTestsBase {
WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,
mAppWindow.mToken, "SameTokenWindow");
mDisplayContent.setImeLayeringTarget(mAppWindow);
sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
}

View File

@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
@@ -37,6 +38,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.WindowStateAnimator.PRESERVED_SURFACE_LAYER;
import static com.google.common.truth.Truth.assertThat;
@@ -493,4 +495,27 @@ public class ZOrderingTests extends WindowTestsBase {
assertZOrderGreaterThan(mTransaction, mNavBarWindow.mToken.getSurfaceControl(),
mDisplayContent.getImeContainer().getSurfaceControl());
}
@Test
public void testPopupWindowAndParentIsImeTarget_expectHigherThanIme_inMultiWindow() {
// Simulate the app window is in multi windowing mode and being IME target
mAppWindow.getConfiguration().windowConfiguration.setWindowingMode(
WINDOWING_MODE_MULTI_WINDOW);
mDisplayContent.setImeLayeringTarget(mAppWindow);
mDisplayContent.setImeInputTarget(mAppWindow);
// Create a popupWindow
assertWindowHigher(mImeWindow, mAppWindow);
final WindowState popupWindow = createWindow(mAppWindow, TYPE_APPLICATION_PANEL,
mDisplayContent, "PopupWindow");
spyOn(popupWindow);
mDisplayContent.assignChildLayers(mTransaction);
// Verify the surface layer of the popupWindow should higher than IME
verify(popupWindow).needsRelativeLayeringToIme();
assertThat(popupWindow.needsRelativeLayeringToIme()).isTrue();
assertZOrderGreaterThan(mTransaction, popupWindow.getSurfaceControl(),
mDisplayContent.getImeContainer().getSurfaceControl());
}
}