diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 9853d1304b142..358e93d89f64d 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -82,6 +82,7 @@ abstract class InsetsSourceProvider { private boolean mIsLeashReadyForDispatching; private final Rect mSourceFrame = new Rect(); private final Rect mLastSourceFrame = new Rect(); + private @NonNull Insets mInsetsHint = Insets.NONE; private final Consumer mSetLeashPositionConsumer = t -> { if (mControl != null) { @@ -298,6 +299,7 @@ abstract class InsetsSourceProvider { if (!insetsHint.equals(mControl.getInsetsHint())) { changed = true; mControl.setInsetsHint(insetsHint); + mInsetsHint = insetsHint; } mLastSourceFrame.set(mSource.getFrame()); } @@ -433,8 +435,8 @@ abstract class InsetsSourceProvider { final SurfaceControl leash = mAdapter.mCapturedLeash; mControlTarget = target; updateVisibility(); - mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition, - mSource.calculateInsets(mWindowContainer.getBounds(), true /* ignoreVisibility */)); + mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition, mInsetsHint); + ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource Control %s for target %s", mControl, mControlTarget); } diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index 6d022262b7200..ffa21fadff6b9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -449,6 +449,36 @@ public class InsetsStateControllerTest extends WindowTestsBase { assertNotNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR)); } + @UseTestDisplay(addWindows = W_INPUT_METHOD) + @Test + public void testGetInsetsHintForNewControl() { + final WindowState app1 = createTestWindow("app1"); + final WindowState app2 = createTestWindow("app2"); + + makeWindowVisible(mImeWindow); + final InsetsSourceProvider imeInsetsProvider = getController().getSourceProvider(ITYPE_IME); + imeInsetsProvider.setWindowContainer(mImeWindow, null, null); + imeInsetsProvider.updateSourceFrame(mImeWindow.getFrame()); + + imeInsetsProvider.updateControlForTarget(app1, false); + imeInsetsProvider.onPostLayout(); + final InsetsSourceControl control1 = imeInsetsProvider.getControl(app1); + assertNotNull(control1); + assertEquals(imeInsetsProvider.getSource().getFrame().height(), + control1.getInsetsHint().bottom); + + // Simulate the IME control target updated from app1 to app2 when IME insets was invisible. + imeInsetsProvider.setServerVisible(false); + imeInsetsProvider.updateControlForTarget(app2, false); + + // Verify insetsHint of the new control is same as last IME source frame after the layout. + imeInsetsProvider.onPostLayout(); + final InsetsSourceControl control2 = imeInsetsProvider.getControl(app2); + assertNotNull(control2); + assertEquals(imeInsetsProvider.getSource().getFrame().height(), + control2.getInsetsHint().bottom); + } + private WindowState createTestWindow(String name) { final WindowState win = createWindow(null, TYPE_APPLICATION, name); win.setHasSurface(true);