Loading services/core/java/com/android/server/wm/DisplayContent.java +4 −3 Original line number Diff line number Diff line Loading @@ -4603,13 +4603,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return super.forAllWindows(callback, traverseTopToBottom); } private boolean skipImeWindowsDuringTraversal(DisplayContent dc) { private static 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(); return dc.mImeLayeringTarget != null && (!dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated() || dc.mImeLayeringTarget.getTask() == null); } /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */ Loading services/core/java/com/android/server/wm/WindowState.java +3 −2 Original line number Diff line number Diff line Loading @@ -4855,8 +4855,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // (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)) { && (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated() || getTask() == null)) { if (mDisplayContent.forAllImeWindows(callback, traverseTopToBottom)) { return true; } } Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +33 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 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; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.Surface.ROTATION_0; Loading Loading @@ -50,6 +51,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; 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.DisplayContent.IME_TARGET_CONTROL; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW; import static com.google.common.truth.Truth.assertThat; Loading @@ -58,6 +60,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; Loading Loading @@ -923,4 +926,34 @@ public class WindowStateTests extends WindowTestsBase { verify(app.getDisplayContent()).updateImeControlTarget(); assertEquals(mAppWindow, mDisplayContent.getImeTarget(IME_TARGET_CONTROL).getWindow()); } @UseTestDisplay(addWindows = { W_ACTIVITY, W_INPUT_METHOD, W_NOTIFICATION_SHADE }) @Test public void testNotificationShadeHasImeInsetsWhenSplitscreenActivated() { WindowState app = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken, "app"); // Simulate entering multi-window mode and verify if the split-screen is activated. app.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, app.getWindowingMode()); assertTrue(mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()); // Simulate notificationShade is shown and being IME layering target. mNotificationShadeWindow.setHasSurface(true); mNotificationShadeWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; assertTrue(mNotificationShadeWindow.canBeImeTarget()); mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindow( mImeWindow, null, null); mDisplayContent.computeImeTarget(true); assertEquals(mNotificationShadeWindow, mDisplayContent.getImeTarget(IME_TARGET_LAYERING)); mDisplayContent.getInsetsStateController().getRawInsetsState() .setSourceVisible(ITYPE_IME, true); // Verify notificationShade can still get IME insets even the split-screen is activated. InsetsState state = mDisplayContent.getInsetsStateController().getInsetsForWindow( mNotificationShadeWindow); assertNotNull(state.peekSource(ITYPE_IME)); assertTrue(state.getSource(ITYPE_IME).isVisible()); } } Loading
services/core/java/com/android/server/wm/DisplayContent.java +4 −3 Original line number Diff line number Diff line Loading @@ -4603,13 +4603,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return super.forAllWindows(callback, traverseTopToBottom); } private boolean skipImeWindowsDuringTraversal(DisplayContent dc) { private static 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(); return dc.mImeLayeringTarget != null && (!dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated() || dc.mImeLayeringTarget.getTask() == null); } /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */ Loading
services/core/java/com/android/server/wm/WindowState.java +3 −2 Original line number Diff line number Diff line Loading @@ -4855,8 +4855,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // (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)) { && (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated() || getTask() == null)) { if (mDisplayContent.forAllImeWindows(callback, traverseTopToBottom)) { return true; } } Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +33 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 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; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.Surface.ROTATION_0; Loading Loading @@ -50,6 +51,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; 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.DisplayContent.IME_TARGET_CONTROL; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW; import static com.google.common.truth.Truth.assertThat; Loading @@ -58,6 +60,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; Loading Loading @@ -923,4 +926,34 @@ public class WindowStateTests extends WindowTestsBase { verify(app.getDisplayContent()).updateImeControlTarget(); assertEquals(mAppWindow, mDisplayContent.getImeTarget(IME_TARGET_CONTROL).getWindow()); } @UseTestDisplay(addWindows = { W_ACTIVITY, W_INPUT_METHOD, W_NOTIFICATION_SHADE }) @Test public void testNotificationShadeHasImeInsetsWhenSplitscreenActivated() { WindowState app = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken, "app"); // Simulate entering multi-window mode and verify if the split-screen is activated. app.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, app.getWindowingMode()); assertTrue(mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()); // Simulate notificationShade is shown and being IME layering target. mNotificationShadeWindow.setHasSurface(true); mNotificationShadeWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; assertTrue(mNotificationShadeWindow.canBeImeTarget()); mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindow( mImeWindow, null, null); mDisplayContent.computeImeTarget(true); assertEquals(mNotificationShadeWindow, mDisplayContent.getImeTarget(IME_TARGET_LAYERING)); mDisplayContent.getInsetsStateController().getRawInsetsState() .setSourceVisible(ITYPE_IME, true); // Verify notificationShade can still get IME insets even the split-screen is activated. InsetsState state = mDisplayContent.getInsetsStateController().getInsetsForWindow( mNotificationShadeWindow); assertNotNull(state.peekSource(ITYPE_IME)); assertTrue(state.getSource(ITYPE_IME).isVisible()); } }