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

Commit f3fd4980 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Unify systemReady() handling for each user in IMMS

With this CL, per-user initialization after systemReady() in IMMS will
be unified between single-user mode and multi-user mode.

Bug: 350386877
Fix: 353751919
Test: atest ConcurrentMultiSessionImeTest
Flag: android.view.inputmethod.concurrent_input_methods
Change-Id: I581fd2057ecf2a3165795d3aff817ee5b367b59e
parent 46d10376
Loading
Loading
Loading
Loading
+21 −75
Original line number Diff line number Diff line
@@ -1060,10 +1060,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            SecureSettingsWrapper.onUserStarting(userId);
            mService.mIoHandler.post(() -> {
                synchronized (ImfLock.class) {
                    if (mService.mConcurrentMultiUserModeEnabled) {
                        if (mService.mCurrentUserId != userId && mService.mSystemReady) {
                            mService.initializeVisibleBackgroundUserLocked(userId);
                        }
                    if (mService.mSystemReady) {
                        mService.onUserReadyLocked(userId);
                    }
                }
            });
@@ -1400,28 +1398,30 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                        UserHandle.ALL, broadcastFilterForAllUsers, null, null,
                        Context.RECEIVER_EXPORTED);

                final String defaultImiId = SecureSettingsWrapper.getString(
                        Settings.Secure.DEFAULT_INPUT_METHOD, null, currentUserId);
                final boolean imeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
                final var settings = InputMethodSettingsRepository.get(currentUserId);
                postInputMethodSettingUpdatedLocked(
                        !imeSelectedOnBoot /* resetDefaultEnabledIme */, currentUserId);
                updateFromSettingsLocked(true, currentUserId);
                InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
                        getPackageManagerForUser(mContext, currentUserId),
                        settings.getEnabledInputMethodList());

                AdditionalSubtypeMapRepository.startWriterThread();

                if (mConcurrentMultiUserModeEnabled) {
                for (int userId : mUserManagerInternal.getUserIds()) {
                        if (userId != mCurrentUserId) {
                            initializeVisibleBackgroundUserLocked(userId);
                    onUserReadyLocked(userId);
                }
            }
        }
    }

    @GuardedBy("ImfLock.class")
    void onUserReadyLocked(@UserIdInt int userId) {
        if (!mUserManagerInternal.isUserRunning(userId)) {
            return;
        }

        final String defaultImiId = SecureSettingsWrapper.getString(
                Settings.Secure.DEFAULT_INPUT_METHOD, null, userId);
        final boolean imeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
        final var settings = InputMethodSettingsRepository.get(userId);
        postInputMethodSettingUpdatedLocked(!imeSelectedOnBoot /* resetDefaultEnabledIme */,
                userId);
        updateFromSettingsLocked(true, userId);
        InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
                getPackageManagerForUser(mContext, userId), settings.getEnabledInputMethodList());
    }

    void registerImeRequestedChangedListener() {
@@ -2840,60 +2840,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        }
    }

    /**
     * This initialization logic is used when and only when {@link #mConcurrentMultiUserModeEnabled}
     * is set to {@code true}.
     *
     * <p>There remain several yet-to-be-implemented features. For the canonical and desired
     * behaviors always refer to single-user code paths such as
     * {@link #updateInputMethodsFromSettingsLocked(boolean, int)}.</p>
     *
     * <p>Here are examples of missing features.</p>
     * <ul>
     *     <li>Profiles are not supported.</li>
     *     <li>
     *         {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED} is not updated.
     *     </li>
     *     <li>{@link InputMethodBindingController#getDeviceIdToShowIme()} is ignored.</li>
     *     <li>and so on.</li>
     * </ul>
     */
    @GuardedBy("ImfLock.class")
    void initializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
        final var settings = InputMethodSettingsRepository.get(userId);

        // Until we figure out what makes most sense, we enable all the pre-installed IMEs in
        // concurrent multi-user IME mode.
        String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
        for (var imi : settings.getMethodList()) {
            if (!imi.isSystem()) {
                continue;
            }
            enabledImeIdsStr = InputMethodUtils.concatEnabledImeIds(enabledImeIdsStr, imi.getId());
        }
        if (!TextUtils.equals(settings.getEnabledInputMethodsStr(), enabledImeIdsStr)) {
            settings.putEnabledInputMethodsStr(enabledImeIdsStr);
        }

        // Also update the currently-selected IME.
        String id = settings.getSelectedInputMethod();
        if (TextUtils.isEmpty(id)) {
            final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
                    settings.getEnabledInputMethodList());
            if (imi != null) {
                id = imi.getId();
                settings.putSelectedInputMethod(id);
            }
        }
        final var userData = getUserData(userId);
        final var bindingController = userData.mBindingController;
        bindingController.setSelectedMethodId(id);

        // Also re-initialize controllers.
        userData.mSwitchingController.resetCircularListLocked(mContext, settings);
        userData.mHardwareKeyboardShortcutController.update(settings);
    }

    @GuardedBy("ImfLock.class")
    void updateInputMethodsFromSettingsLocked(boolean enabledMayChange, @UserIdInt int userId) {
        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);