diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 9aa07f7ed8b31..bcfa18b1a2e84 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -4289,7 +4289,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp setImeInputTarget(target); mInsetsStateController.updateAboveInsetsState(mInsetsStateController .getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME)); - updateImeControlTarget(); + // Force updating the IME parent when the IME control target has been updated to the + // remote target but updateImeParent not happen because ImeLayeringTarget and + // ImeInputTarget are different. Then later updateImeParent would be ignored when there + // is no new IME control target to change the IME parent. + final boolean forceUpdateImeParent = mImeControlTarget == mRemoteInsetsControlTarget + && (mInputMethodSurfaceParent != null + && !mInputMethodSurfaceParent.isSameSurface( + mImeWindowsContainer.getParent().mSurfaceControl)); + updateImeControlTarget(forceUpdateImeParent); } // Unfreeze IME insets after the new target updated, in case updateAboveInsetsState may // deliver unrelated IME insets change to the non-IME requester. diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 2e19c09568c14..89dfffb532ea1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1203,6 +1203,31 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.computeImeParent()); } + @Test + public void testComputeImeParent_remoteControlTarget() throws Exception { + final DisplayContent dc = mDisplayContent; + WindowState app1 = createWindow(null, TYPE_BASE_APPLICATION, "app1"); + WindowState app2 = createWindow(null, TYPE_BASE_APPLICATION, "app2"); + + dc.setImeLayeringTarget(app1); + dc.setImeInputTarget(app2); + dc.setRemoteInsetsController(createDisplayWindowInsetsController()); + dc.getImeTarget(IME_TARGET_LAYERING).getWindow().setWindowingMode( + WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); + dc.getImeInputTarget().getWindowState().setWindowingMode( + WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); + + // Expect ImeParent is null since ImeLayeringTarget and ImeInputTarget are different. + assertNull(dc.computeImeParent()); + + // ImeLayeringTarget and ImeInputTarget are updated to the same. + dc.setImeInputTarget(app1); + assertEquals(dc.getImeTarget(IME_TARGET_LAYERING), dc.getImeInputTarget()); + + // The ImeParent should be the display. + assertEquals(dc.getImeContainer().getParent().getSurfaceControl(), dc.computeImeParent()); + } + @Test public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception { final DisplayContent dc = createNewDisplay();