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

Commit 45644099 authored by Antonio Kantek's avatar Antonio Kantek Committed by Android (Google) Code Review
Browse files

Merge "Move InputBindingController to UserData" into main

parents f8728f23 d2b417f9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -118,6 +118,14 @@ final class InputMethodBindingController {
        mLatchForTesting = latchForTesting;
    }

    /**
     * Interface used to abstract {@code InputMethodBindingController} instantiation.
     */
    interface Creator {

        InputMethodBindingController create();
    }

    /**
     * Time that we last initiated a bind to the input method, to determine
     * if we should try to disconnect and reconnect to it.
+60 −39
Original line number Diff line number Diff line
@@ -303,8 +303,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @MultiUserUnawareField
    private final InputMethodMenuController mMenuController;
    @MultiUserUnawareField
    @NonNull private final InputMethodBindingController mBindingController;
    @MultiUserUnawareField
    @NonNull private final AutofillSuggestionsController mAutofillController;

    @GuardedBy("ImfLock.class")
@@ -465,12 +463,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    String getSelectedMethodIdLocked() {
        return mBindingController.getSelectedMethodId();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getSelectedMethodId();
    }

    @GuardedBy("ImfLock.class")
    private void setSelectedMethodIdLocked(@Nullable String selectedMethodId) {
        mBindingController.setSelectedMethodId(selectedMethodId);
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        userData.mBindingController.setSelectedMethodId(selectedMethodId);
    }

    /**
@@ -479,8 +479,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private int getSequenceNumberLocked() {
        final UserData monitor = UserData.getOrCreate(mCurrentUserId);
        return monitor.mSequence.getSequenceNumber();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mSequence.getSequenceNumber();
    }

    /**
@@ -550,7 +550,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    private String getCurIdLocked() {
        return mBindingController.getCurId();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getCurId();
    }

    /**
@@ -574,7 +575,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private boolean hasConnectionLocked() {
        return mBindingController.hasMainConnection();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.hasMainConnection();
    }

    /**
@@ -597,7 +599,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    private Intent getCurIntentLocked() {
        return mBindingController.getCurIntent();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getCurIntent();
    }

    /**
@@ -607,7 +610,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    IBinder getCurTokenLocked() {
        return mBindingController.getCurToken();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getCurToken();
    }

    /**
@@ -648,7 +652,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    @Nullable
    IInputMethodInvoker getCurMethodLocked() {
        return mBindingController.getCurMethod();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getCurMethod();
    }

    /**
@@ -656,7 +661,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private int getCurMethodUidLocked() {
        return mBindingController.getCurMethodUid();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getCurMethodUid();
    }

    /**
@@ -665,7 +671,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
     */
    @GuardedBy("ImfLock.class")
    private long getLastBindTimeLocked() {
        return mBindingController.getLastBindTime();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        return userData.mBindingController.getLastBindTime();
    }

    /**
@@ -1379,7 +1386,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked
        InputMethodSettingsRepository.initialize(mHandler, mContext);
        AdditionalSubtypeMapRepository.initialize(mHandler, mContext);
        UserData.initialize(mHandler);

        mCurrentUserId = mActivityManagerInternal.getCurrentUserId();

@@ -1392,19 +1398,17 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                new HardwareKeyboardShortcutController(settings.getMethodMap(),
                        settings.getUserId());
        mMenuController = new InputMethodMenuController(this);
        mBindingController =
                bindingControllerForTesting != null
                        ? bindingControllerForTesting
                        : new InputMethodBindingController(this);
        mAutofillController = new AutofillSuggestionsController(this);

        mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
        mVisibilityApplier = new DefaultImeVisibilityApplier(this);

        mClientController = new ClientController(mPackageManagerInternal);
        synchronized (ImfLock.class) {
            mClientController.addClientControllerCallback(c -> onClientRemoved(c));
            mImeBindingState = ImeBindingState.newEmptyState();
            UserData.initialize(mHandler,
                    /* bindingControllerCreator= */ () -> bindingControllerForTesting != null
                            ? bindingControllerForTesting
                            : new InputMethodBindingController(this));
        }

        mPreventImeStartupUnlessTextEditor = mRes.getBoolean(
@@ -1740,9 +1744,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub

            // Check if selected IME of current user supports handwriting.
            if (userId == mCurrentUserId) {
                return mBindingController.supportsStylusHandwriting()
                final UserData userData = UserData.getOrCreate(userId);
                final InputMethodBindingController bindingController = userData.mBindingController;
                return bindingController.supportsStylusHandwriting()
                        && (!connectionless
                                || mBindingController.supportsConnectionlessStylusHandwriting());
                                || bindingController.supportsConnectionlessStylusHandwriting());
            }
            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
            final InputMethodInfo imi = settings.getMethodMap().get(
@@ -2071,7 +2077,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker();
        final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions =
                createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions);
        if (mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) {
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        if (userData.mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) {
            mHwController.setInkWindowInitializer(new InkWindowInitializer());
        }
        return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
@@ -2186,13 +2193,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        mCurEditorInfo = editorInfo;

        // If configured, we want to avoid starting up the IME if it is not supposed to be showing
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags,
                unverifiedTargetSdkVersion)) {
            if (DEBUG) {
                Slog.d(TAG, "Avoiding IME startup and unbinding current input method.");
            }
            invalidateAutofillSessionLocked();
            mBindingController.unbindCurrentMethod();
            userData.mBindingController.unbindCurrentMethod();
            return InputBindResult.NO_EDITOR;
        }

@@ -2224,9 +2232,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            }
        }

        mBindingController.unbindCurrentMethod();

        return mBindingController.bindCurrentMethod();
        userData.mBindingController.unbindCurrentMethod();
        return userData.mBindingController.bindCurrentMethod();
    }

    /**
@@ -2489,7 +2496,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        setSelectedMethodIdLocked(null);
        // Callback before clean-up binding states.
        onUnbindCurrentMethodByReset();
        mBindingController.unbindCurrentMethod();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        userData.mBindingController.unbindCurrentMethod();
        unbindCurrentClientLocked(unbindClientReason);
    }

@@ -3121,7 +3129,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            @Nullable String delegatorPackageName,
            @NonNull IConnectionlessHandwritingCallback callback) throws RemoteException {
        synchronized (ImfLock.class) {
            if (!mBindingController.supportsConnectionlessStylusHandwriting()) {
            final UserData userData = UserData.getOrCreate(mCurrentUserId);
            if (!userData.mBindingController.supportsConnectionlessStylusHandwriting()) {
                Slog.w(TAG, "Connectionless stylus handwriting mode unsupported by IME.");
                callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED);
                return;
@@ -3187,9 +3196,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                            + " startStylusHandwriting()");
                    return false;
                }
                final UserData userData = UserData.getOrCreate(mCurrentUserId);
                final long ident = Binder.clearCallingIdentity();
                try {
                    if (!mBindingController.supportsStylusHandwriting()) {
                    if (!userData.mBindingController.supportsStylusHandwriting()) {
                        Slog.w(TAG,
                                "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
                        return false;
@@ -3368,7 +3378,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        mVisibilityStateComputer.requestImeVisibility(windowToken, true);

        // Ensure binding the connection when IME is going to show.
        mBindingController.setCurrentMethodVisible();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        userData.mBindingController.setCurrentMethodVisible();
        final IInputMethodInvoker curMethod = getCurMethodLocked();
        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
        if (curMethod != null) {
@@ -3471,7 +3482,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        } else {
            ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
        }
        mBindingController.setCurrentMethodNotVisible();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        userData.mBindingController.setCurrentMethodNotVisible();
        mVisibilityStateComputer.clearImeShowFlags();
        // Cancel existing statsToken for show IME as we got a hide request.
        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
@@ -3753,7 +3765,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                // Note that we can trust client's display ID as long as it matches
                // to the display ID obtained from the window.
                if (cs.mSelfReportedDisplayId != mCurTokenDisplayId) {
                    mBindingController.unbindCurrentMethod();
                    final UserData userData = UserData.getOrCreate(userId);
                    userData.mBindingController.unbindCurrentMethod();
                }
            }
        }
@@ -4209,6 +4222,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        }, mHandler);
    }

    @GuardedBy("ImfLock.class")
    private void addStylusDeviceIdLocked(int deviceId) {
        if (mStylusIds == null) {
            mStylusIds = new IntArray();
@@ -4219,8 +4233,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        mStylusIds.add(deviceId);
        // a new Stylus is detected. If IME supports handwriting, and we don't have
        // handwriting initialized, lets do it now.
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        final InputMethodBindingController bindingController = userData.mBindingController;
        if (!mHwController.getCurrentRequestId().isPresent()
                && mBindingController.supportsStylusHandwriting()) {
                && bindingController.supportsStylusHandwriting()) {
            scheduleResetStylusHandwriting();
        }
    }
@@ -4796,7 +4812,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub

            case MSG_RESET_HANDWRITING: {
                synchronized (ImfLock.class) {
                    if (mBindingController.supportsStylusHandwriting()
                    final UserData userData = UserData.getOrCreate(mCurrentUserId);
                    if (userData.mBindingController.supportsStylusHandwriting()
                            && getCurMethodLocked() != null && hasSupportedStylusLocked()) {
                        Slog.d(TAG, "Initializing Handwriting Spy");
                        mHwController.initializeHandwritingSpy(mCurTokenDisplayId);
@@ -4821,11 +4838,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    if (curMethod == null || mImeBindingState.mFocusedWindow == null) {
                        return true;
                    }
                    final UserData userData = UserData.getOrCreate(mCurrentUserId);
                    final HandwritingModeController.HandwritingSession session =
                            mHwController.startHandwritingSession(
                                    msg.arg1 /*requestId*/,
                                    msg.arg2 /*pid*/,
                                    mBindingController.getCurMethodUid(),
                                    userData.mBindingController.getCurMethodUid(),
                                    mImeBindingState.mFocusedWindow);
                    if (session == null) {
                        Slog.e(TAG,
@@ -5119,7 +5137,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub

    @GuardedBy("ImfLock.class")
    void sendOnNavButtonFlagsChangedLocked() {
        final IInputMethodInvoker curMethod = mBindingController.getCurMethod();
        final UserData userData = UserData.getOrCreate(mCurrentUserId);
        final IInputMethodInvoker curMethod = userData.mBindingController.getCurMethod();
        if (curMethod == null) {
            // No need to send the data if the IME is not yet bound.
            return;
@@ -5876,9 +5895,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            p.println("  mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked());
            p.println("  mFocusedWindowPerceptible=" + mFocusedWindowPerceptible);
            mImeBindingState.dump("  ", p);
            final UserData userData = UserData.getOrCreate(mCurrentUserId);
            p.println("  mCurId=" + getCurIdLocked() + " mHaveConnection=" + hasConnectionLocked()
                    + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound="
                    + mBindingController.isVisibleBound());
                    + userData.mBindingController.isVisibleBound());
            p.println("  mCurToken=" + getCurTokenLocked());
            p.println("  mCurTokenDisplayId=" + mCurTokenDisplayId);
            p.println("  mCurHostInputToken=" + mCurHostInputToken);
@@ -6372,7 +6392,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    if (userId == mCurrentUserId) {
                        hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
                                SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
                        mBindingController.unbindCurrentMethod();
                        final UserData userData = UserData.getOrCreate(mCurrentUserId);
                        userData.mBindingController.unbindCurrentMethod();

                        // Enable default IMEs, disable others
                        var toDisable = settings.getEnabledInputMethodList();
+21 −10
Original line number Diff line number Diff line
@@ -28,8 +28,10 @@ import com.android.server.pm.UserManagerInternal;

final class UserData {

    @NonNull
    private static final SparseArray<UserData> sPerUserMonitor = new SparseArray<>();
    private static SparseArray<UserData> sUserData;

    @GuardedBy("ImfLock.class")
    private static InputMethodBindingController.Creator sBindingControllerCreator;

    @UserIdInt
    final int mUserId;
@@ -37,24 +39,33 @@ final class UserData {
    @GuardedBy("ImfLock.class")
    final Sequence mSequence = new Sequence();

    @NonNull
    final InputMethodBindingController mBindingController;

    /**
     * Not intended to be instantiated.
     */
    private UserData(int userId) {
    private UserData(int userId,
            InputMethodBindingController bindingController) {
        mUserId = userId;
        mBindingController = bindingController;
    }

    @GuardedBy("ImfLock.class")
    static UserData getOrCreate(@UserIdInt int userId) {
        UserData monitor = sPerUserMonitor.get(userId);
        if (monitor == null) {
            monitor = new UserData(userId);
            sPerUserMonitor.put(userId, monitor);
        UserData userData = sUserData.get(userId);
        if (userData == null) {
            userData = new UserData(userId, sBindingControllerCreator.create());
            sUserData.put(userId, userData);
        }
        return monitor;
        return userData;
    }

    static void initialize(Handler handler) {
    @GuardedBy("ImfLock.class")
    static void initialize(Handler handler,
            InputMethodBindingController.Creator bindingControllerCreator) {
        sUserData = new SparseArray<>();
        sBindingControllerCreator = bindingControllerCreator;
        final UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        userManagerInternal.addUserLifecycleListener(
@@ -64,7 +75,7 @@ final class UserData {
                        final int userId = user.id;
                        handler.post(() -> {
                            synchronized (ImfLock.class) {
                                sPerUserMonitor.remove(userId);
                                sUserData.remove(userId);
                            }
                        });
                    }