diff options
author | 2025-03-22 01:21:22 -0700 | |
---|---|---|
committer | 2025-04-17 20:18:50 -0700 | |
commit | af23e219388afe04eaf7e2eb8cc3d675e15922ab (patch) | |
tree | 7d91ec3176e0e67dff2d420f4a4fbe335ef0a957 | |
parent | 4341e620bf1c066c40e4633acc65f1e897af48a0 (diff) |
Only update remote target, if visibility is different from input target
When syncing the visibility of the imeInputTarget to the (RemoteInsets)ControlTarget, without having an actual change, the upcoming call to updateClientVisibility will be ignored and we don't invoke the IMMS listener.
Therefore, we should only sync the visibility when it's different between imeInputTarget and controlTarget - otherwise we can directly invoke the listener.
Fix: 402547338
Fix: 405296840
Flag: android.view.inputmethod.refactor_insets_controller
Test: atest ImeInsetsSourceProviderTest#testUpdateControlForTarget_remoteInsetsControlTargetUnchanged
Test: manual: open view where controlTarget=RemoteInsetsControlTarget; Open another fullscreen app and request IME; close new window to return to RICT
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:43624020c81c27f67beb882d4cabb6ea041a6c89)
Merged-In: I96ffe688ae5eb32e325f3f7c9c62b392f7287100
Change-Id: I96ffe688ae5eb32e325f3f7c9c62b392f7287100
-rw-r--r-- | services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java | 9 | ||||
-rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java | 40 |
2 files changed, 45 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index f2bc909bd64b..c87c2501d3b1 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -326,9 +326,12 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { // IME input target to update IME request state. For example, switch from a task // with showing IME to a split-screen task without showing IME. InputTarget imeInputTarget = mDisplayContent.getImeInputTarget(); - if (imeInputTarget != target && imeInputTarget != null) { - // The controlTarget should be updated with the visibility of the - // current IME input target. + if (imeInputTarget != target && imeInputTarget != null + && imeInputTarget.isRequestedVisible(WindowInsets.Type.ime()) + != target.isRequestedVisible(WindowInsets.Type.ime())) { + // Only update the controlTarget, if it has a different requested visibility + // than the imeInputTarget. Otherwise, updateClientVisibility won't invoke + // the listener, as nothing changed. reportImeInputTargetStateToControlTarget(imeInputTarget, target, statsToken); } else { 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 aa794b2d071d..bc172c120283 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java @@ -25,6 +25,7 @@ import static com.android.server.wm.WindowStateAnimator.NO_SURFACE; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.never; @@ -245,13 +246,50 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { assertTrue(inputTarget.isRequestedVisible(WindowInsets.Type.ime())); assertFalse(controlTarget.isRequestedVisible(WindowInsets.Type.ime())); - mImeProvider.updateControlForTarget(controlTarget, true /* force */, null /* statsToken */); + mImeProvider.updateControlForTarget(controlTarget, true /* force */, + ImeTracker.Token.empty()); verify(displayWindowInsetsController, times(1)).setImeInputTargetRequestedVisibility( eq(true), any()); } @Test @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) + public void testUpdateControlForTarget_remoteInsetsControlTargetUnchanged() + throws RemoteException { + final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build(); + mImeProvider.setWindowContainer(ime, null, null); + final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build(); + final var displayWindowInsetsController = spy(createDisplayWindowInsetsController()); + mDisplayContent.setRemoteInsetsController(displayWindowInsetsController); + final var controlTarget = mDisplayContent.mRemoteInsetsControlTarget; + mDisplayContent.setImeInputTarget(inputTarget); + mDisplayContent.setImeControlTarget(controlTarget); + + // Test for visible + inputTarget.setRequestedVisibleTypes(WindowInsets.Type.ime()); + controlTarget.updateRequestedVisibleTypes(WindowInsets.Type.ime(), WindowInsets.Type.ime()); + clearInvocations(mDisplayContent); + assertTrue(inputTarget.isRequestedVisible(WindowInsets.Type.ime())); + assertTrue((controlTarget.isRequestedVisible(WindowInsets.Type.ime()))); + mImeProvider.updateControlForTarget(controlTarget, true /* force */, + ImeTracker.Token.empty()); + verify(displayWindowInsetsController, never()).setImeInputTargetRequestedVisibility( + anyBoolean(), any()); + + // Test for not visible + inputTarget.setRequestedVisibleTypes(0); + controlTarget.updateRequestedVisibleTypes(0 /* visibleTypes */, WindowInsets.Type.ime()); + clearInvocations(mDisplayContent); + assertFalse(inputTarget.isRequestedVisible(WindowInsets.Type.ime())); + assertFalse((controlTarget.isRequestedVisible(WindowInsets.Type.ime()))); + mImeProvider.updateControlForTarget(controlTarget, true /* force */, + ImeTracker.Token.empty()); + verify(displayWindowInsetsController, never()).setImeInputTargetRequestedVisibility( + anyBoolean(), any()); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) public void testOnPostLayout_resetServerVisibilityWhenImeIsNotDrawn() { final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build(); final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build(); |