Let SettingsLib not depend on InputMethodSettings

This is part of an effort to remove dependencies on InputMethodUtils
from Settings and other non-core Framework code.

Currently InputMethodSettingValuesWrapper depends on
InputMethodUtils.InputMethodSettings just to parse
Settings.Secure.ENABLED_INPUT_METHODS to extract enabled IMEs from the
result of InputMethodManager#getInputMethodList(), which can be
rewritten with InputMethodAndSubtypeUtil.

Also, seems that the dependency on
InputMethodUtils.InputMethodSettings confused the author and some
unnecessary synchronization blocks were introduced.

This CL completely removes the dependency on InputMethodSettings as
well as unnecessary synchronization blocks because methods of
InputMethodSettingValuesWrapper are expected to be called only from
the UI thread.

There should be no user-visible behavior change.

Bug: 77730201
Test: Manually verified that IME enabler still works as expected.
Change-Id: I0c52fb31ac2bb976dcd867f72992e260aee255b7
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
index a6c1634..b4280fe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
@@ -105,7 +105,7 @@
     }
 
     // Needs to modify InputMethodManageService if you want to change the format of saved string.
-    private static HashMap<String, HashSet<String>> getEnabledInputMethodsAndSubtypeList(
+    static HashMap<String, HashSet<String>> getEnabledInputMethodsAndSubtypeList(
             ContentResolver resolver) {
         final String enabledInputMethodsStr = Settings.Secure.getString(
                 resolver, Settings.Secure.ENABLED_INPUT_METHODS);
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
index 554fb35..ab017e2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
@@ -16,17 +16,15 @@
 
 package com.android.settingslib.inputmethod;
 
-import android.app.ActivityManager;
+import android.annotation.UiThread;
+import android.content.ContentResolver;
 import android.content.Context;
-import android.os.RemoteException;
 import android.util.Log;
-import android.util.Slog;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.inputmethod.InputMethodUtils;
-import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -35,18 +33,19 @@
 import java.util.Locale;
 
 /**
- * This class is a wrapper for InputMethodSettings. You need to refresh internal states
- * manually on some events when "InputMethodInfo"s and "InputMethodSubtype"s can be
- * changed.
+ * This class is a wrapper for {@link InputMethodManager} and
+ * {@link android.provider.Settings.Secure#ENABLED_INPUT_METHODS}. You need to refresh internal
+ * states manually on some events when "InputMethodInfo"s and "InputMethodSubtype"s can be changed.
+ *
+ * <p>TODO: Consolidate this with {@link InputMethodAndSubtypeUtil}.</p>
  */
-// TODO: Consolidate this with {@link InputMethodAndSubtypeUtil}.
+@UiThread
 public class InputMethodSettingValuesWrapper {
     private static final String TAG = InputMethodSettingValuesWrapper.class.getSimpleName();
 
     private static volatile InputMethodSettingValuesWrapper sInstance;
     private final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
-    private final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<>();
-    private final InputMethodSettings mSettings;
+    private final ContentResolver mContentResolver;
     private final InputMethodManager mImm;
     private final HashSet<InputMethodInfo> mAsciiCapableEnabledImis = new HashSet<>();
 
@@ -61,67 +60,44 @@
         return sInstance;
     }
 
-    private static int getDefaultCurrentUserId() {
-        try {
-            return ActivityManager.getService().getCurrentUser().id;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Couldn't get current user ID; guessing it's 0", e);
-        }
-        return 0;
-    }
-
     // Ensure singleton
     private InputMethodSettingValuesWrapper(Context context) {
-        mSettings = new InputMethodSettings(context.getResources(), context.getContentResolver(),
-                mMethodMap, mMethodList, getDefaultCurrentUserId(), false /* copyOnWrite */);
-        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        mContentResolver = context.getContentResolver();
+        mImm = context.getSystemService(InputMethodManager.class);
         refreshAllInputMethodAndSubtypes();
     }
 
     public void refreshAllInputMethodAndSubtypes() {
-        synchronized (mMethodMap) {
-            mMethodList.clear();
-            mMethodMap.clear();
-            final List<InputMethodInfo> imms = mImm.getInputMethodList();
-            mMethodList.addAll(imms);
-            for (InputMethodInfo imi : imms) {
-                mMethodMap.put(imi.getId(), imi);
-            }
-            updateAsciiCapableEnabledImis();
-        }
+        mMethodList.clear();
+        mMethodList.addAll(mImm.getInputMethodList());
+        updateAsciiCapableEnabledImis();
     }
 
     // TODO: Add a cts to ensure at least one AsciiCapableSubtypeEnabledImis exist
     private void updateAsciiCapableEnabledImis() {
-        synchronized (mMethodMap) {
-            mAsciiCapableEnabledImis.clear();
-            final List<InputMethodInfo> enabledImis = mSettings.getEnabledInputMethodListLocked();
-            for (final InputMethodInfo imi : enabledImis) {
-                final int subtypeCount = imi.getSubtypeCount();
-                for (int i = 0; i < subtypeCount; ++i) {
-                    final InputMethodSubtype subtype = imi.getSubtypeAt(i);
-                    if (InputMethodUtils.SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
-                            && subtype.isAsciiCapable()) {
-                        mAsciiCapableEnabledImis.add(imi);
-                        break;
-                    }
+        mAsciiCapableEnabledImis.clear();
+        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
+        for (final InputMethodInfo imi : enabledImis) {
+            final int subtypeCount = imi.getSubtypeCount();
+            for (int i = 0; i < subtypeCount; ++i) {
+                final InputMethodSubtype subtype = imi.getSubtypeAt(i);
+                if (InputMethodUtils.SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
+                        && subtype.isAsciiCapable()) {
+                    mAsciiCapableEnabledImis.add(imi);
+                    break;
                 }
             }
         }
     }
 
     public List<InputMethodInfo> getInputMethodList() {
-        synchronized (mMethodMap) {
-            return mMethodList;
-        }
+        return new ArrayList<>(mMethodList);
     }
 
     public boolean isAlwaysCheckedIme(InputMethodInfo imi, Context context) {
         final boolean isEnabled = isEnabledImi(imi);
-        synchronized (mMethodMap) {
-            if (mSettings.getEnabledInputMethodListLocked().size() <= 1 && isEnabled) {
-                return true;
-            }
+        if (getEnabledInputMethodList().size() <= 1 && isEnabled) {
+            return true;
         }
 
         final int enabledValidSystemNonAuxAsciiCapableImeCount =
@@ -131,15 +107,11 @@
                 && !(enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabled)
                 && imi.isSystem()
                 && isValidSystemNonAuxAsciiCapableIme(imi, context);
-
     }
 
     private int getEnabledValidSystemNonAuxAsciiCapableImeCount(Context context) {
         int count = 0;
-        final List<InputMethodInfo> enabledImis;
-        synchronized (mMethodMap) {
-            enabledImis = mSettings.getEnabledInputMethodListLocked();
-        }
+        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
         for (final InputMethodInfo imi : enabledImis) {
             if (isValidSystemNonAuxAsciiCapableIme(imi, context)) {
                 ++count;
@@ -152,10 +124,7 @@
     }
 
     public boolean isEnabledImi(InputMethodInfo imi) {
-        final List<InputMethodInfo> enabledImis;
-        synchronized (mMethodMap) {
-            enabledImis = mSettings.getEnabledInputMethodListLocked();
-        }
+        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
         for (final InputMethodInfo tempImi : enabledImis) {
             if (tempImi.getId().equals(imi.getId())) {
                 return true;
@@ -182,4 +151,23 @@
         }
         return mAsciiCapableEnabledImis.contains(imi);
     }
+
+    /**
+     * Returns the list of the enabled {@link InputMethodInfo} determined by
+     * {@link android.provider.Settings.Secure#ENABLED_INPUT_METHODS} rather than just returning
+     * {@link InputMethodManager#getEnabledInputMethodList()}.
+     *
+     * @return the list of the enabled {@link InputMethodInfo}
+     */
+    private ArrayList<InputMethodInfo> getEnabledInputMethodList() {
+        final HashMap<String, HashSet<String>> enabledInputMethodsAndSubtypes =
+                InputMethodAndSubtypeUtil.getEnabledInputMethodsAndSubtypeList(mContentResolver);
+        final ArrayList<InputMethodInfo> result = new ArrayList<>();
+        for (InputMethodInfo imi : mMethodList) {
+            if (enabledInputMethodsAndSubtypes.keySet().contains(imi.getId())) {
+                result.add(imi);
+            }
+        }
+        return result;
+    }
 }