diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 7bcea36415ccb..a1efd2d09184c 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1638,7 +1638,16 @@ public class DisplayPolicy { */ private void applyKeyguardPolicy(WindowState win, WindowState imeTarget) { if (win.canBeHiddenByKeyguard()) { - if (shouldBeHiddenByKeyguard(win, imeTarget)) { + final boolean shouldBeHiddenByKeyguard = shouldBeHiddenByKeyguard(win, imeTarget); + if (win.mIsImWindow) { + // Notify IME insets provider to freeze the IME insets. In case when turning off + // the screen, the IME insets source window will be hidden because of keyguard + // policy change and affects the system to freeze the last insets state. (And + // unfreeze when the IME is going to show) + mDisplayContent.getInsetsStateController().getImeSourceProvider().setFrozen( + shouldBeHiddenByKeyguard); + } + if (shouldBeHiddenByKeyguard) { win.hide(false /* doAnimation */, true /* requestAnim */); } else { win.show(false /* doAnimation */, true /* requestAnim */); diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 38eca359c2bae..554791a0da918 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -55,6 +55,12 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider private boolean mImeShowing; private final InsetsSource mLastSource = new InsetsSource(ITYPE_IME); + /** @see #setFrozen(boolean) */ + private boolean mFrozen; + + /** @see #setServerVisible(boolean) */ + private boolean mServerVisible; + ImeInsetsSourceProvider(InsetsSource source, InsetsStateController stateController, DisplayContent displayContent) { super(source, stateController, displayContent); @@ -80,6 +86,32 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider return control; } + @Override + void setServerVisible(boolean serverVisible) { + mServerVisible = serverVisible; + if (!mFrozen) { + super.setServerVisible(serverVisible); + } + } + + /** + * Freeze IME insets source state when required. + * + * When setting {@param frozen} as {@code true}, the IME insets provider will freeze the + * current IME insets state and pending the IME insets state update until setting + * {@param frozen} as {@code false}. + */ + void setFrozen(boolean frozen) { + if (mFrozen == frozen) { + return; + } + mFrozen = frozen; + if (!frozen) { + // Unfreeze and process the pending IME insets states. + super.setServerVisible(mServerVisible); + } + } + @Override void updateSourceFrame(Rect frame) { super.updateSourceFrame(frame); diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java index c839d1254397e..eb8b89d593107 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java @@ -85,4 +85,26 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { mImeProvider.setImeShowing(false); assertFalse(mImeProvider.isImeShowing()); } + + @Test + public void testSetFrozen() { + WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime"); + makeWindowVisibleAndDrawn(ime); + mImeProvider.setWindowContainer(ime, null, null); + mImeProvider.setServerVisible(true); + mImeProvider.setClientVisible(true); + mImeProvider.updateVisibility(); + assertTrue(mImeProvider.getSource().isVisible()); + + // Freezing IME states and set the server visible as false. + mImeProvider.setFrozen(true); + mImeProvider.setServerVisible(false); + // Expect the IME insets visible won't be changed. + assertTrue(mImeProvider.getSource().isVisible()); + + // Unfreeze IME states and expect the IME insets became invisible due to pending IME + // visible state updated. + mImeProvider.setFrozen(false); + assertFalse(mImeProvider.getSource().isVisible()); + } }