summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ming-Shin Lu <lumark@google.com> 2023-06-28 11:08:35 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-06-28 11:08:35 +0000
commit38f088a8d968b02db3ec2094b9ca1f99348dd816 (patch)
tree895e846860f719528efc560d2318d04676312305
parentc71aaf4549edcf98eb4b691a8f39ca285ff93ff6 (diff)
parent6aba1a4c82285a2dfc5257ea84619af152493711 (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>
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java25
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java25
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 */,