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

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

Merge "ImeVisibilityApplier: fix hideIme no-op for Embedded display case."...

Merge "ImeVisibilityApplier: fix hideIme no-op for Embedded display case." into udc-dev am: 263ab0dd

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



Change-Id: Ic995497d72a306d83ace2356c98b06f0bd06410c
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 54099a5e 263ab0dd
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -136,17 +136,16 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
                mWindowManagerInternal.showImePostLayout(windowToken, statsToken);
                break;
            case STATE_HIDE_IME:
                if (mService.mCurFocusedWindowClient != null) {
                if (mService.hasAttachedClient()) {
                    ImeTracker.forLogging().onProgress(statsToken,
                            ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                    // IMMS only knows of focused window, not the actual IME target.
                    // e.g. it isn't aware of any window that has both
                    // NOT_FOCUSABLE, ALT_FOCUSABLE_IM flags set and can the IME target.
                    // Send it to window manager to hide IME from IME target window.
                    // TODO(b/139861270): send to mCurClient.client once IMMS is aware of
                    // actual IME target.
                    // Send it to window manager to hide IME from the actual IME control target
                    // of the target display.
                    mWindowManagerInternal.hideIme(windowToken,
                            mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken);
                            mService.getDisplayIdToShowImeLocked(), statsToken);
                } else {
                    ImeTracker.forLogging().onFailed(statsToken,
                            ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+13 −0
Original line number Diff line number Diff line
@@ -2339,6 +2339,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    /** {@code true} when a {@link ClientState} has attached from starting the input connection. */
    @GuardedBy("ImfLock.class")
    boolean hasAttachedClient() {
        return mCurClient != null;
    }

    @VisibleForTesting
    void setAttachedClientForTesting(@NonNull ClientState cs) {
        synchronized (ImfLock.class) {
            mCurClient = cs;
        }
    }

    @GuardedBy("ImfLock.class")
    void clearInputShownLocked() {
        mVisibilityStateComputer.setInputShown(false);
+2 −2
Original line number Diff line number Diff line
@@ -740,7 +740,7 @@ public abstract class WindowManagerInternal {
    /**
     * Show IME on imeTargetWindow once IME has finished layout.
     *
     * @param imeTargetWindowToken token of the (IME target) window on which IME should be shown.
     * @param imeTargetWindowToken token of the (IME target) window which IME should be shown.
     * @param statsToken the token tracking the current IME show request or {@code null} otherwise.
     */
    public abstract void showImePostLayout(IBinder imeTargetWindowToken,
@@ -749,7 +749,7 @@ public abstract class WindowManagerInternal {
    /**
     * Hide IME using imeTargetWindow when requested.
     *
     * @param imeTargetWindowToken token of the (IME target) window on which IME should be hidden.
     * @param imeTargetWindowToken token of the (IME target) window on which requests hiding IME.
     * @param displayId the id of the display the IME is on.
     * @param statsToken the token tracking the current IME hide request or {@code null} otherwise.
     */
+42 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.inputmethod;

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.SHOW_SOFT_INPUT;
@@ -35,11 +36,16 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.inputmethod.InputMethodManager;

import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -60,8 +66,8 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
        super.setUp();
        mVisibilityApplier =
                (DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier();
        mInputMethodManagerService.mCurFocusedWindowClient = mock(
                InputMethodManagerService.ClientState.class);
        mInputMethodManagerService.setAttachedClientForTesting(
                mock(InputMethodManagerService.ClientState.class));
    }

    @Test
@@ -119,4 +125,38 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
        mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_SHOW_IME_IMPLICIT);
        verifyShowSoftInput(true, true, InputMethodManager.SHOW_IMPLICIT);
    }

    @Test
    public void testApplyImeVisibility_hideImeFromTargetOnSecondaryDisplay() {
        // Init a IME target client on the secondary display to show IME.
        mInputMethodManagerService.addClient(mMockInputMethodClient, mMockRemoteInputConnection,
                10 /* selfReportedDisplayId */);
        mInputMethodManagerService.setAttachedClientForTesting(null);
        startInputOrWindowGainedFocus(mWindowToken, SOFT_INPUT_STATE_ALWAYS_VISIBLE);

        synchronized (ImfLock.class) {
            final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked();
            // Verify hideIme will apply the expected displayId when the default IME
            // visibility applier app STATE_HIDE_IME.
            mVisibilityApplier.applyImeVisibility(mWindowToken, null, 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 */,
                mMockInputMethodClient /* client */,
                windowToken /* windowToken */,
                StartInputFlags.VIEW_HAS_FOCUS | StartInputFlags.IS_TEXT_EDITOR,
                softInputMode /* softInputMode */,
                0 /* windowFlags */,
                mEditorInfo /* editorInfo */,
                mMockRemoteInputConnection /* inputConnection */,
                mMockRemoteAccessibilityInputConnection /* remoteAccessibilityInputConnection */,
                mTargetSdkVersion /* unverifiedTargetSdkVersion */,
                mCallingUserId /* userId */,
                mMockImeOnBackInvokedDispatcher /* imeDispatcher */);
    }
}