Treat additional inputmethod subtypes per user

Bug: 6931482
Change-Id: I4f7c7e69a80534da3a48ac508ff7a9e7511f33ce
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6952d72..0f2bb20 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -171,8 +171,8 @@
     final SettingsObserver mSettingsObserver;
     final IWindowManager mIWindowManager;
     final HandlerCaller mCaller;
-    private final InputMethodFileManager mFileManager;
-    private final InputMethodAndSubtypeListManager mImListManager;
+    private InputMethodFileManager mFileManager;
+    private InputMethodAndSubtypeListManager mImListManager;
     private final HardKeyboardListener mHardKeyboardListener;
     private final WindowManagerService mWindowManagerService;
 
@@ -625,11 +625,6 @@
 
         mShowOngoingImeSwitcherForPhones = false;
 
-        synchronized (mMethodMap) {
-            mFileManager = new InputMethodFileManager(mMethodMap);
-        }
-        mImListManager = new InputMethodAndSubtypeListManager(context, this);
-
         final IntentFilter broadcastFilter = new IntentFilter();
         broadcastFilter.addAction(Intent.ACTION_SCREEN_ON);
         broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -643,7 +638,9 @@
                     new IUserSwitchObserver.Stub() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
-                            switchUser(newUserId);
+                            synchronized(mMethodMap) {
+                                switchUserLocked(newUserId);
+                            }
                             if (reply != null) {
                                 try {
                                     reply.sendResult(null);
@@ -665,6 +662,8 @@
         // mSettings should be created before buildInputMethodListLocked
         mSettings = new InputMethodSettings(
                 mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+        mFileManager = new InputMethodFileManager(mMethodMap, userId);
+        mImListManager = new InputMethodAndSubtypeListManager(context, this);
 
         // Just checking if defaultImiId is empty or not
         final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -736,6 +735,8 @@
             if (DEBUG) {
                 Slog.i(TAG, "Locale has been changed to " + newLocale);
             }
+            // InputMethodAndSubtypeListManager should be reset when the locale is changed.
+            mImListManager = new InputMethodAndSubtypeListManager(mContext, this);
             buildInputMethodListLocked(mMethodList, mMethodMap);
             if (!updateOnlyWhenLocaleChanged) {
                 final String selectedImiId = mSettings.getSelectedInputMethod();
@@ -761,8 +762,10 @@
         resetAllInternalStateLocked(true);
     }
 
-    private void switchUser(int newUserId) {
+    private void switchUserLocked(int newUserId) {
         mSettings.setCurrentUserId(newUserId);
+        // InputMethodFileManager should be reset when the user is changed
+        mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
         resetAllInternalStateLocked(false);
     }
 
@@ -3816,6 +3819,7 @@
         }
     }
 
+    // TODO: Cache the state for each user and reset when the cached user is removed.
     private static class InputMethodFileManager {
         private static final String SYSTEM_PATH = "system";
         private static final String INPUT_METHOD_PATH = "inputmethod";
@@ -3834,12 +3838,14 @@
         private final HashMap<String, InputMethodInfo> mMethodMap;
         private final HashMap<String, List<InputMethodSubtype>> mAdditionalSubtypesMap =
                 new HashMap<String, List<InputMethodSubtype>>();
-        public InputMethodFileManager(HashMap<String, InputMethodInfo> methodMap) {
+        public InputMethodFileManager(HashMap<String, InputMethodInfo> methodMap, int userId) {
             if (methodMap == null) {
                 throw new NullPointerException("methodMap is null");
             }
             mMethodMap = methodMap;
-            final File systemDir = new File(Environment.getDataDirectory(), SYSTEM_PATH);
+            final File systemDir = userId == UserHandle.USER_OWNER
+                    ? new File(Environment.getDataDirectory(), SYSTEM_PATH)
+                    : Environment.getUserSystemDirectory(userId);
             final File inputMethodDir = new File(systemDir, INPUT_METHOD_PATH);
             if (!inputMethodDir.mkdirs()) {
                 Slog.w(TAG, "Couldn't create dir.: " + inputMethodDir.getAbsolutePath());