Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6aba1a4c authored by Ming-Shin Lu's avatar Ming-Shin Lu Committed by Automerger Merge Worker
Browse files

Merge "Fix IME insets not apply hidden when switching focus in diffrent users"...

Merge "Fix IME insets not apply hidden when switching focus in diffrent users" into udc-qpr-dev am: ebdd8b41

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23739364



Change-Id: I0fe771b4800e53c8219771b68f66a0a75d8f7545
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents be1f8016 ebdd8b41
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -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);
    }
+25 −0
Original line number Diff line number Diff line
@@ -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 */,