diff options
| author | 2023-06-28 11:08:35 +0000 | |
|---|---|---|
| committer | 2023-06-28 11:08:35 +0000 | |
| commit | 38f088a8d968b02db3ec2094b9ca1f99348dd816 (patch) | |
| tree | 895e846860f719528efc560d2318d04676312305 | |
| parent | c71aaf4549edcf98eb4b691a8f39ca285ff93ff6 (diff) | |
| parent | 6aba1a4c82285a2dfc5257ea84619af152493711 (diff) | |
Merge "Fix IME insets not apply hidden when switching focus in diffrent users" into udc-qpr-dev am: ebdd8b4104 am: 6aba1a4c82
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23739364
Change-Id: I0e8fe59f295aabbd19ee849967c44025ff697f8c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 files changed, 50 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 716ecba52d23..1ab83f7c5fe5 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -48,6 +48,7 @@ import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeTargetWindowState; import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeVisibilityResult; +import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME; import static com.android.server.inputmethod.InputMethodBindingController.TIME_TO_RECONNECT; import static com.android.server.inputmethod.InputMethodUtils.isSoftInputModeStateVisibleAllowed; @@ -2367,6 +2368,28 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } + /** + * Called when {@link #resetCurrentMethodAndClientLocked(int)} invoked for clean-up states + * before unbinding the current method. + */ + @GuardedBy("ImfLock.class") + void onUnbindCurrentMethodByReset() { + final ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull( + mCurFocusedWindow); + if (winState != null && !winState.isRequestedImeVisible() + && !mVisibilityStateComputer.isInputShown()) { + // Normally, the focus window will apply the IME visibility state to + // WindowManager when the IME has applied it. But it would be too late when + // switching IMEs in between different users. (Since the focused IME will + // first unbind the service to switch to bind the next user of the IME + // service, that wouldn't make the attached IME token validity check in time) + // As a result, we have to notify WM to apply IME visibility before clearing the + // binding states in the first place. + mVisibilityApplier.applyImeVisibility(mCurFocusedWindow, mCurStatsToken, + STATE_HIDE_IME); + } + } + /** {@code true} when a {@link ClientState} has attached from starting the input connection. */ @GuardedBy("ImfLock.class") boolean hasAttachedClient() { @@ -2838,6 +2861,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason) { setSelectedMethodIdLocked(null); + // Callback before clean-up binding states. + onUnbindCurrentMethodByReset(); mBindingController.unbindCurrentMethod(); unbindCurrentClientLocked(unbindClientReason); } diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java index a6ada4d77253..869497c28def 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java @@ -20,6 +20,7 @@ import static android.inputmethodservice.InputMethodService.IME_ACTIVE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_SOFT_INPUT; +import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_SWITCH_USER; import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_SOFT_INPUT; import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME; import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_EXPLICIT; @@ -43,6 +44,7 @@ import android.view.inputmethod.InputMethodManager; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.internal.inputmethod.InputBindResult; import com.android.internal.inputmethod.StartInputFlags; import com.android.internal.inputmethod.StartInputReason; @@ -165,6 +167,29 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe verify(mMockImeTargetVisibilityPolicy).removeImeScreenshot(eq(Display.DEFAULT_DISPLAY)); } + @Test + public void testApplyImeVisibility_hideImeWhenUnbinding() { + mInputMethodManagerService.setAttachedClientForTesting(null); + startInputOrWindowGainedFocus(mWindowToken, SOFT_INPUT_STATE_ALWAYS_VISIBLE); + ExtendedMockito.spyOn(mVisibilityApplier); + + synchronized (ImfLock.class) { + // Simulate the system hides the IME when switching IME services in different users. + // (e.g. unbinding the IME from the current user to the profile user) + final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked(); + mInputMethodManagerService.hideCurrentInputLocked(mWindowToken, null, 0, null, + HIDE_SWITCH_USER); + mInputMethodManagerService.onUnbindCurrentMethodByReset(); + + // Expects applyImeVisibility() -> hideIme() will be called to notify WM for syncing + // the IME hidden state. + verify(mVisibilityApplier).applyImeVisibility(eq(mWindowToken), any(), + eq(STATE_HIDE_IME)); + verify(mInputMethodManagerService.mWindowManagerInternal).hideIme( + eq(mWindowToken), eq(displayIdToShowIme), eq(null)); + } + } + private InputBindResult startInputOrWindowGainedFocus(IBinder windowToken, int softInputMode) { return mInputMethodManagerService.startInputOrWindowGainedFocus( StartInputReason.WINDOW_FOCUS_GAIN /* startInputReason */, |