Merge "Fix IME insets not apply hidden when switching focus in diffrent users" into udc-qpr-dev am: ebdd8b4104
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23739364 Change-Id: I0fe771b4800e53c8219771b68f66a0a75d8f7545 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */,
|
||||
|
||||
Reference in New Issue
Block a user