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

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

Make IMMS#mSettingsObserver multiuser-aware.

It turns out that IMMS#SettingsObserver has monitored
only main user's the secure settings. As a result, when the
secondary user changes enabled IMEs in the settigs app,
IMMS only updates internal enabled IME lists only when
the user is switched for secondary users.  If a secondary
user enables or disables IMEs at the settings app, such
changes are not correctly notified to IMMS.

This CL addresses above inconsistency by explicitly
specifying the user ID when calling
ContentResolver#registerContentObserver().

This CL also allows dumpsys to contain internal state of
IMMS#mSettingsObserver in case we need to diagnose
problems only with bugreports.

Bug: 19340792
Bug: 19587437
Bug: 21612582
Change-Id: I34b437928c147e9fdbe935f725624cc97c816cb3
parent d724886c
Loading
Loading
Loading
Loading
+36 −5
Original line number Diff line number Diff line
@@ -428,19 +428,39 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
    private final IPackageManager mIPackageManager;

    class SettingsObserver extends ContentObserver {
        int mUserId;
        boolean mRegistered = false;
        String mLastEnabled = "";

        /**
         * <em>This constructor must be called within the lock.</em>
         */
        SettingsObserver(Handler handler) {
            super(handler);
        }

        public void registerContentObserverLocked(int userId) {
            if (mRegistered && mUserId == userId) {
                return;
            }
            ContentResolver resolver = mContext.getContentResolver();
            if (mRegistered) {
                mContext.getContentResolver().unregisterContentObserver(this);
                mRegistered = false;
            }
            if (mUserId != userId) {
                mLastEnabled = "";
                mUserId = userId;
            }
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
                    Settings.Secure.DEFAULT_INPUT_METHOD), false, this, userId);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ENABLED_INPUT_METHODS), false, this);
                    Settings.Secure.ENABLED_INPUT_METHODS), false, this, userId);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this);
                    Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this, userId);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this);
                    Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this, userId);
            mRegistered = true;
        }

        @Override public void onChange(boolean selfChange, Uri uri) {
@@ -460,6 +480,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                }
            }
        }

        @Override
        public String toString() {
            return "SettingsObserver{mUserId=" + mUserId + " mRegistered=" + mRegistered
                    + " mLastEnabled=" + mLastEnabled + "}";
        }
    }

    class ImmsBroadcastReceiver extends android.content.BroadcastReceiver {
@@ -756,6 +782,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        mContext = context;
        mRes = context.getResources();
        mHandler = new Handler(this);
        // Note: SettingsObserver doesn't register observers in its constructor.
        mSettingsObserver = new SettingsObserver(mHandler);
        mIWindowManager = IWindowManager.Stub.asInterface(
                ServiceManager.getService(Context.WINDOW_SERVICE));
        mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@@ -860,8 +888,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            }
        }

        mSettingsObserver = new SettingsObserver(mHandler);
        synchronized (mMethodMap) {
            mSettingsObserver.registerContentObserverLocked(userId);
            updateFromSettingsLocked(true);
        }

@@ -963,6 +991,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
                + " currentUserId=" + mSettings.getCurrentUserId());

        // ContentObserver should be registered again when the user is changed
        mSettingsObserver.registerContentObserverLocked(newUserId);
        mSettings.setCurrentUserId(newUserId);
        updateCurrentProfileIds();
        // InputMethodFileManager should be reset when the user is changed
@@ -3713,6 +3743,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            p.println("  mCurUserActionNotificationSequenceNumber="
                    + mCurUserActionNotificationSequenceNumber);
            p.println("  mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn);
            p.println("  mSettingsObserver=" + mSettingsObserver);
            p.println("  mSwitchingController:");
            mSwitchingController.dump(p);
        }