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

Commit e3729046 authored by Yohei Yukawa's avatar Yohei Yukawa Committed by Android (Google) Code Review
Browse files

Merge "Move mDisplayIdToShowIme to binding controller" into main

parents 0bf86fc2 42dcf977
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SH

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.util.EventLog;
@@ -137,15 +138,17 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
    @GuardedBy("ImfLock.class")
    @Override
    public void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
            @ImeVisibilityStateComputer.VisibilityState int state) {
            @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {
        applyImeVisibility(windowToken, statsToken, state,
                SoftInputShowHideReason.NOT_SET /* ignore reason */);
                SoftInputShowHideReason.NOT_SET /* ignore reason */, userId);
    }

    @GuardedBy("ImfLock.class")
    void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
            @ImeVisibilityStateComputer.VisibilityState int state,
            @SoftInputShowHideReason int reason) {
            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
        final var bindingController = mService.getInputMethodBindingController(userId);
        final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
        switch (state) {
            case STATE_SHOW_IME:
                if (!Flags.refactorInsetsController()) {
@@ -165,8 +168,7 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
                        // NOT_FOCUSABLE, ALT_FOCUSABLE_IM flags set and can the IME target.
                        // Send it to window manager to hide IME from the actual IME control target
                        // of the target display.
                        mWindowManagerInternal.hideIme(windowToken,
                                mService.getDisplayIdToShowImeLocked(), statsToken);
                        mWindowManagerInternal.hideIme(windowToken, displayIdToShowIme, statsToken);
                    } else {
                        ImeTracker.forLogging().onFailed(statsToken,
                                ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
@@ -201,10 +203,10 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
                }
                break;
            case STATE_SHOW_IME_SNAPSHOT:
                showImeScreenshot(windowToken, mService.getDisplayIdToShowImeLocked());
                showImeScreenshot(windowToken, displayIdToShowIme);
                break;
            case STATE_REMOVE_IME_SNAPSHOT:
                removeImeScreenshot(mService.getDisplayIdToShowImeLocked());
                removeImeScreenshot(displayIdToShowIme);
                break;
            default:
                throw new IllegalArgumentException("Invalid IME visibility state: " + state);
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.inputmethod;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.view.inputmethod.ImeTracker;
@@ -63,7 +64,7 @@ interface ImeVisibilityApplier {
     * @param state       The new IME visibility state for the applier to handle
     */
    default void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
            @ImeVisibilityStateComputer.VisibilityState int state) {}
            @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {}

    /**
     * Updates the IME Z-ordering relative to the given window.
+19 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.inputmethod;

import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.INVALID_DISPLAY;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -82,12 +83,15 @@ final class InputMethodBindingController {
    @GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
    @GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
    @GuardedBy("ImfLock.class") @Nullable private IBinder mCurToken;
    @GuardedBy("ImfLock.class") private int mCurTokenDisplayId = Display.INVALID_DISPLAY;
    @GuardedBy("ImfLock.class") private int mCurTokenDisplayId = INVALID_DISPLAY;
    @GuardedBy("ImfLock.class") private int mCurSeq;
    @GuardedBy("ImfLock.class") private boolean mVisibleBound;
    @GuardedBy("ImfLock.class") private boolean mSupportsStylusHw;
    @GuardedBy("ImfLock.class") private boolean mSupportsConnectionlessStylusHw;

    /** The display id for which the latest startInput was called. */
    @GuardedBy("ImfLock.class") private int mDisplayIdToShowIme = INVALID_DISPLAY;

    @Nullable private CountDownLatch mLatchForTesting;

    /**
@@ -455,7 +459,7 @@ final class InputMethodBindingController {
        mWindowManagerInternal.removeWindowToken(mCurToken, true /* removeWindows */,
                false /* animateExit */, mCurTokenDisplayId);
        mCurToken = null;
        mCurTokenDisplayId = Display.INVALID_DISPLAY;
        mCurTokenDisplayId = INVALID_DISPLAY;
    }

    @GuardedBy("ImfLock.class")
@@ -478,16 +482,15 @@ final class InputMethodBindingController {
            mCurId = info.getId();
            mLastBindTime = SystemClock.uptimeMillis();

            final int displayIdToShowIme = mService.getDisplayIdToShowImeLocked();
            mCurToken = new Binder();
            mCurTokenDisplayId = displayIdToShowIme;
            mCurTokenDisplayId = mDisplayIdToShowIme;
            if (DEBUG) {
                Slog.v(TAG, "Adding window token: " + mCurToken + " for display: "
                        + displayIdToShowIme);
                        + mDisplayIdToShowIme);
            }
            mWindowManagerInternal.addWindowToken(mCurToken,
                    WindowManager.LayoutParams.TYPE_INPUT_METHOD,
                    displayIdToShowIme, null /* options */);
                    mDisplayIdToShowIme, null /* options */);
            return new InputBindResult(
                    InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
                    null, null, null, mCurId, mCurSeq, false);
@@ -596,4 +599,14 @@ final class InputMethodBindingController {
            unbindVisibleConnection();
        }
    }

    @GuardedBy("ImfLock.class")
    void setDisplayIdToShowIme(int displayId) {
        mDisplayIdToShowIme = displayId;
    }

    @GuardedBy("ImfLock.class")
    int getDisplayIdToShowIme() {
        return mDisplayIdToShowIme;
    }
}
+12 −19
Original line number Diff line number Diff line
@@ -373,18 +373,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @GuardedBy("ImfLock.class")
    private int mMethodMapUpdateCount = 0;

    /**
     * The display id for which the latest startInput was called.
     */
    @GuardedBy("ImfLock.class")
    int getDisplayIdToShowImeLocked() {
        return mDisplayIdToShowIme;
    }

    @GuardedBy("ImfLock.class")
    @MultiUserUnawareField
    private int mDisplayIdToShowIme = INVALID_DISPLAY;

    @GuardedBy("ImfLock.class")
    @MultiUserUnawareField
    private int mDeviceIdToShowIme = DEVICE_ID_DEFAULT;
@@ -1951,7 +1939,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            final var statsToken = createStatsTokenForFocusedClient(false /* show */,
                    SoftInputShowHideReason.UNBIND_CURRENT_METHOD);
            mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
                    STATE_HIDE_IME);
                    STATE_HIDE_IME, mCurrentUserId);
        }
    }

@@ -2122,7 +2110,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            return InputBindResult.NOT_IME_TARGET_WINDOW;
        }
        final int csDisplayId = cs.mSelfReportedDisplayId;
        mDisplayIdToShowIme = mVisibilityStateComputer.computeImeDisplayId(winState, csDisplayId);
        bindingController.setDisplayIdToShowIme(
                mVisibilityStateComputer.computeImeDisplayId(winState, csDisplayId));

        // Potentially override the selected input method if the new display belongs to a virtual
        // device with a custom IME.
@@ -2193,8 +2182,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        // We expect the caller has already verified that the client is allowed to access this
        // display ID.
        final String curId = bindingController.getCurId();
        final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
        if (curId != null && curId.equals(bindingController.getSelectedMethodId())
                && mDisplayIdToShowIme == getCurTokenDisplayIdLocked()) {
                && displayIdToShowIme == getCurTokenDisplayIdLocked()) {
            if (cs.mCurSession != null) {
                // Fast case: if we are already connected to the input method,
                // then just return it.
@@ -2245,7 +2235,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.

        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
        final int oldDeviceId = mDeviceIdToShowIme;
        mDeviceIdToShowIme = mVdmInternal.getDeviceIdForDisplayId(mDisplayIdToShowIme);
        final var bindingController = getInputMethodBindingController(userId);
        final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
        mDeviceIdToShowIme = mVdmInternal.getDeviceIdForDisplayId(displayIdToShowIme);
        if (mDeviceIdToShowIme == DEVICE_ID_DEFAULT) {
            if (oldDeviceId == DEVICE_ID_DEFAULT) {
                return currentMethodId;
@@ -2279,7 +2271,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        if (DEBUG) {
            Slog.v(TAG, "Switching current input method from " + currentMethodId
                    + " to device-specific one " + deviceMethodId + " because the current display "
                    + mDisplayIdToShowIme + " belongs to device with id " + mDeviceIdToShowIme);
                    + displayIdToShowIme + " belongs to device with id " + mDeviceIdToShowIme);
        }
        return deviceMethodId;
    }
@@ -4653,7 +4645,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                        windowToken);
                mVisibilityApplier.applyImeVisibility(requestToken, statsToken,
                        setVisible ? ImeVisibilityStateComputer.STATE_SHOW_IME
                                : ImeVisibilityStateComputer.STATE_HIDE_IME);
                                : ImeVisibilityStateComputer.STATE_HIDE_IME, mCurrentUserId);
            }
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -5446,7 +5438,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @GuardedBy("ImfLock.class")
    private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
        mDeviceIdToShowIme = DEVICE_ID_DEFAULT;
        mDisplayIdToShowIme = INVALID_DISPLAY;
        final var bindingController = getInputMethodBindingController(mCurrentUserId);
        bindingController.setDisplayIdToShowIme(INVALID_DISPLAY);

        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
        settings.putSelectedDefaultDeviceInputMethod(null);
+20 −10
Original line number Diff line number Diff line
@@ -68,12 +68,15 @@ import org.junit.runner.RunWith;
public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTestBase {
    private DefaultImeVisibilityApplier mVisibilityApplier;

    private int mUserId = 0;

    @Before
    public void setUp() throws RemoteException {
        super.setUp();
        mVisibilityApplier =
                (DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier();
        synchronized (ImfLock.class) {
            mUserId = mInputMethodManagerService.getCurrentImeUserIdLocked();
            mInputMethodManagerService.setAttachedClientForTesting(requireNonNull(
                    mInputMethodManagerService.getClientStateLocked(mMockInputMethodClient)));
        }
@@ -103,7 +106,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
        assertThrows(IllegalArgumentException.class, () -> {
            synchronized (ImfLock.class) {
                mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
                        STATE_INVALID);
                        STATE_INVALID, mUserId);
            }
        });
    }
@@ -112,7 +115,8 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
    public void testApplyImeVisibility_showIme() {
        final var statsToken = ImeTracker.Token.empty();
        synchronized (ImfLock.class) {
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_SHOW_IME);
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_SHOW_IME,
                    mUserId);
        }
        verify(mMockWindowManagerInternal).showImePostLayout(eq(mWindowToken), eq(statsToken));
    }
@@ -121,7 +125,8 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
    public void testApplyImeVisibility_hideIme() {
        final var statsToken = ImeTracker.Token.empty();
        synchronized (ImfLock.class) {
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME);
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
                    mUserId);
        }
        verify(mMockWindowManagerInternal).hideIme(eq(mWindowToken), anyInt() /* displayId */,
                eq(statsToken));
@@ -132,7 +137,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
        mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
        synchronized (ImfLock.class) {
            mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
                    STATE_HIDE_IME_EXPLICIT);
                    STATE_HIDE_IME_EXPLICIT, mUserId);
        }
        verifyHideSoftInput(true, true);
    }
@@ -142,7 +147,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
        mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
        synchronized (ImfLock.class) {
            mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
                    STATE_HIDE_IME_NOT_ALWAYS);
                    STATE_HIDE_IME_NOT_ALWAYS, mUserId);
        }
        verifyHideSoftInput(true, true);
    }
@@ -151,7 +156,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
    public void testApplyImeVisibility_showImeImplicit() throws Exception {
        synchronized (ImfLock.class) {
            mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
                    STATE_SHOW_IME_IMPLICIT);
                    STATE_SHOW_IME_IMPLICIT, mUserId);
        }
        verifyShowSoftInput(true, true, 0 /* showFlags */);
    }
@@ -166,10 +171,13 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe

        final var statsToken = ImeTracker.Token.empty();
        synchronized (ImfLock.class) {
            final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked();
            final var bindingController =
                    mInputMethodManagerService.getInputMethodBindingController(mUserId);
            final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
            // Verify hideIme will apply the expected displayId when the default IME
            // visibility applier app STATE_HIDE_IME.
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME);
            mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
                    mUserId);
            verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
                    eq(mWindowToken), eq(displayIdToShowIme), eq(statsToken));
        }
@@ -204,7 +212,9 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
            // 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 var statsToken = ImeTracker.Token.empty();
            final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked();
            final var bindingController =
                    mInputMethodManagerService.getInputMethodBindingController(mUserId);
            final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
            mInputMethodManagerService.hideCurrentInputLocked(mWindowToken,
                    statsToken, 0 /* flags */, null /* resultReceiver */,
                    HIDE_SWITCH_USER);
@@ -214,7 +224,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe
            // the IME hidden state.
            // The unbind will cancel the previous stats token, and create a new one internally.
            verify(mVisibilityApplier).applyImeVisibility(
                    eq(mWindowToken), any(), eq(STATE_HIDE_IME));
                    eq(mWindowToken), any(), eq(STATE_HIDE_IME), eq(mUserId) /* userId */);
            verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
                    eq(mWindowToken), eq(displayIdToShowIme), and(not(eq(statsToken)), notNull()));
        }