Don't use RichInputMethodManager in setup wizard

In setup wizard, InputMethodManager may not be able to be aware that
this IME is installed, especially just after the IME is installed via
GooglePlay app and hit the open button on the app to launch the setup
wizard.

Bug: 9299618
Change-Id: I00c8544178b41074253d49ae9481996ec56593d2
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 0dd302a..94513e6 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -54,13 +54,6 @@
         return sInstance;
     }
 
-    // Caveat: This may cause IPC
-    public static boolean isInputMethodManagerValidForUserOfThisProcess(final Context context) {
-        // Basically called to check whether this IME has been triggered by the current user or not
-        return !((InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE)).
-                getInputMethodList().isEmpty();
-    }
-
     public static void init(final Context context) {
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         sInstance.initInternal(context, prefs);
diff --git a/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java b/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
index 604ebee..63d2fec 100644
--- a/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
+++ b/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
@@ -25,9 +25,9 @@
 import android.os.Process;
 import android.preference.PreferenceManager;
 import android.util.Log;
+import android.view.inputmethod.InputMethodManager;
 
 import com.android.inputmethod.compat.IntentCompatUtils;
-import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.Settings;
 
 /**
@@ -65,17 +65,16 @@
         }
 
         // The process that hosts this broadcast receiver is invoked and remains alive even after
-        // 1) the package has been re-installed, 2) the device has been booted,
-        // 3) a multiuser has been created.
+        // 1) the package has been re-installed, 2) the device has just booted,
+        // 3) a new user has been created.
         // There is no good reason to keep the process alive if this IME isn't a current IME.
-        final boolean isCurrentImeOfCurrentUser;
-        if (RichInputMethodManager.isInputMethodManagerValidForUserOfThisProcess(context)) {
-            RichInputMethodManager.init(context);
-            isCurrentImeOfCurrentUser = SetupActivity.isThisImeCurrent(context);
-        } else {
-            isCurrentImeOfCurrentUser = false;
-        }
-
+        final InputMethodManager imm =
+                (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        // Called to check whether this IME has been triggered by the current user or not
+        final boolean isInputMethodManagerValidForUserOfThisProcess =
+                !imm.getInputMethodList().isEmpty();
+        final boolean isCurrentImeOfCurrentUser = isInputMethodManagerValidForUserOfThisProcess
+                && SetupActivity.isThisImeCurrent(context, imm);
         if (!isCurrentImeOfCurrentUser) {
             final int myPid = Process.myPid();
             Log.i(TAG, "Killing my process: pid=" + myPid);
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index 8a2de88..a68f98f 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -24,8 +24,6 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 
-import com.android.inputmethod.latin.RichInputMethodManager;
-
 public final class SetupActivity extends Activity {
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
@@ -40,17 +38,24 @@
         }
     }
 
+    /*
+     * We may not be able to get our own {@link InputMethodInfo} just after this IME is installed
+     * because {@link InputMethodManagerService} may not be aware of this IME yet.
+     * Note: {@link RichInputMethodManager} has similar methods. Here in setup wizard, we can't
+     * use it for the reason above.
+     */
+
     /**
      * Check if the IME specified by the context is enabled.
-     * Note that {@link RichInputMethodManager} must have been initialized before calling this
-     * method.
+     * CAVEAT: This may cause a round trip IPC.
      *
      * @param context package context of the IME to be checked.
+     * @param imm the {@link InputMethodManager}.
      * @return true if this IME is enabled.
      */
-    public static boolean isThisImeEnabled(final Context context) {
+    /* package */ static boolean isThisImeEnabled(final Context context,
+            final InputMethodManager imm) {
         final String packageName = context.getPackageName();
-        final InputMethodManager imm = RichInputMethodManager.getInstance().getInputMethodManager();
         for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) {
             if (packageName.equals(imi.getPackageName())) {
                 return true;
@@ -61,17 +66,36 @@
 
     /**
      * Check if the IME specified by the context is the current IME.
-     * Note that {@link RichInputMethodManager} must have been initialized before calling this
-     * method.
+     * CAVEAT: This may cause a round trip IPC.
      *
      * @param context package context of the IME to be checked.
+     * @param imm the {@link InputMethodManager}.
      * @return true if this IME is the current IME.
      */
-    public static boolean isThisImeCurrent(final Context context) {
-        final InputMethodInfo myImi =
-                RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
+    /* package */ static boolean isThisImeCurrent(final Context context,
+            final InputMethodManager imm) {
+        final InputMethodInfo imi = getInputMethodInfoOf(context.getPackageName(), imm);
         final String currentImeId = Settings.Secure.getString(
                 context.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
-        return myImi.getId().equals(currentImeId);
+        return imi != null && imi.getId().equals(currentImeId);
+    }
+
+    /**
+     * Get {@link InputMethodInfo} of the IME specified by the package name.
+     * CAVEAT: This may cause a round trip IPC.
+     *
+     * @param packageName package name of the IME.
+     * @param imm the {@link InputMethodManager}.
+     * @return the {@link InputMethodInfo} of the IME specified by the <code>packageName</code>,
+     * or null if not found.
+     */
+    /* package */ static InputMethodInfo getInputMethodInfoOf(final String packageName,
+            final InputMethodManager imm) {
+        for (final InputMethodInfo imi : imm.getInputMethodList()) {
+            if (packageName.equals(imi.getPackageName())) {
+                return imi;
+            }
+        }
+        return null;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index 78a6478..13fa9d9 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.view.View;
 import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.VideoView;
@@ -36,7 +37,6 @@
 import com.android.inputmethod.compat.ViewCompatUtils;
 import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.SettingsActivity;
 import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
 
@@ -48,6 +48,8 @@
 
     private static final boolean ENABLE_WELCOME_VIDEO = true;
 
+    private InputMethodManager mImm;
+
     private View mSetupWizard;
     private View mWelcomeScreen;
     private View mSetupScreen;
@@ -69,15 +71,19 @@
     private static final int STEP_LAUNCHING_IME_SETTINGS = 4;
     private static final int STEP_BACK_FROM_IME_SETTINGS = 5;
 
-    final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
+    private SettingsPoolingHandler mHandler;
 
-    static final class SettingsPoolingHandler
+    private static final class SettingsPoolingHandler
             extends StaticInnerHandlerWrapper<SetupWizardActivity> {
         private static final int MSG_POLLING_IME_SETTINGS = 0;
         private static final long IME_SETTINGS_POLLING_INTERVAL = 200;
 
-        public SettingsPoolingHandler(final SetupWizardActivity outerInstance) {
+        private final InputMethodManager mImmInHandler;
+
+        public SettingsPoolingHandler(final SetupWizardActivity outerInstance,
+                final InputMethodManager imm) {
             super(outerInstance);
+            mImmInHandler = imm;
         }
 
         @Override
@@ -88,7 +94,7 @@
             }
             switch (msg.what) {
             case MSG_POLLING_IME_SETTINGS:
-                if (SetupActivity.isThisImeEnabled(setupWizardActivity)) {
+                if (SetupActivity.isThisImeEnabled(setupWizardActivity, mImmInHandler)) {
                     setupWizardActivity.invokeSetupWizardOfThisIme();
                     return;
                 }
@@ -112,11 +118,12 @@
         setTheme(android.R.style.Theme_Translucent_NoTitleBar);
         super.onCreate(savedInstanceState);
 
+        mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
+        mHandler = new SettingsPoolingHandler(this, mImm);
+
         setContentView(R.layout.setup_wizard);
         mSetupWizard = findViewById(R.id.setup_wizard);
 
-        RichInputMethodManager.init(this);
-
         if (savedInstanceState == null) {
             mStepNumber = determineSetupStepNumberFromLauncher();
         } else {
@@ -143,11 +150,12 @@
                 R.string.setup_step1_title, R.string.setup_step1_instruction,
                 R.string.setup_step1_finished_instruction, R.drawable.ic_setup_step1,
                 R.string.setup_step1_action);
+        final SettingsPoolingHandler handler = mHandler;
         step1.setAction(new Runnable() {
             @Override
             public void run() {
                 invokeLanguageAndInputSettings();
-                mHandler.startPollingImeSettings();
+                handler.startPollingImeSettings();
             }
         });
         mSetupStepGroup.addStep(step1);
@@ -265,14 +273,15 @@
 
     void invokeInputMethodPicker() {
         // Invoke input method picker.
-        RichInputMethodManager.getInstance().getInputMethodManager()
-                .showInputMethodPicker();
+        mImm.showInputMethodPicker();
         mNeedsToAdjustStepNumberToSystemState = true;
     }
 
     void invokeSubtypeEnablerOfThisIme() {
-        final InputMethodInfo imi =
-                RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
+        final InputMethodInfo imi = SetupActivity.getInputMethodInfoOf(getPackageName(), mImm);
+        if (imi == null) {
+            return;
+        }
         final Intent intent = new Intent();
         intent.setAction(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
@@ -293,10 +302,10 @@
 
     private int determineSetupStepNumber() {
         mHandler.cancelPollingImeSettings();
-        if (!SetupActivity.isThisImeEnabled(this)) {
+        if (!SetupActivity.isThisImeEnabled(this, mImm)) {
             return STEP_1;
         }
-        if (!SetupActivity.isThisImeCurrent(this)) {
+        if (!SetupActivity.isThisImeCurrent(this, mImm)) {
             return STEP_2;
         }
         return STEP_3;