Merge "Import translations. DO NOT MERGE"
diff --git a/java/res/values/keypress-vibration-durations.xml b/java/res/values/keypress-vibration-durations.xml
index 0474b1c..e8d9225 100644
--- a/java/res/values/keypress-vibration-durations.xml
+++ b/java/res/values/keypress-vibration-durations.xml
@@ -51,7 +51,7 @@
         <!-- HTC One X -->
         <item>MODEL=HTC One X:MANUFACTURER=HTC,20</item>
         <!-- HTC One -->
-        <item>MODEL=HTC One:MANUFACTURER=HTC,15</item>
+        <item>MODEL=HTC One( special edition)?:MANUFACTURER=HTC,15</item>
         <!-- Motorola Razor M -->
         <item>MODEL=XT907:MANUFACTURER=motorola,30</item>
         <!-- Sony Xperia Z -->
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 1511dbc..dac1213 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -36,8 +36,6 @@
  * Various helper functions for the state database
  */
 public class MetadataDbHelper extends SQLiteOpenHelper {
-
-    @SuppressWarnings("unused")
     private static final String TAG = MetadataDbHelper.class.getSimpleName();
 
     // This was the initial release version of the database. It should never be
@@ -437,37 +435,37 @@
      */
     public static ContentValues completeWithDefaultValues(final ContentValues result)
             throws BadFormatException {
-        if (!result.containsKey(WORDLISTID_COLUMN) || !result.containsKey(LOCALE_COLUMN)) {
+        if (null == result.get(WORDLISTID_COLUMN) || null == result.get(LOCALE_COLUMN)) {
             throw new BadFormatException();
         }
         // 0 for the pending id, because there is none
-        if (!result.containsKey(PENDINGID_COLUMN)) result.put(PENDINGID_COLUMN, 0);
+        if (null == result.get(PENDINGID_COLUMN)) result.put(PENDINGID_COLUMN, 0);
         // This is a binary blob of a dictionary
-        if (!result.containsKey(TYPE_COLUMN)) result.put(TYPE_COLUMN, TYPE_BULK);
+        if (null == result.get(TYPE_COLUMN)) result.put(TYPE_COLUMN, TYPE_BULK);
         // This word list is unknown, but it's present, else we wouldn't be here, so INSTALLED
-        if (!result.containsKey(STATUS_COLUMN)) result.put(STATUS_COLUMN, STATUS_INSTALLED);
+        if (null == result.get(STATUS_COLUMN)) result.put(STATUS_COLUMN, STATUS_INSTALLED);
         // No description unless specified, because we can't guess it
-        if (!result.containsKey(DESCRIPTION_COLUMN)) result.put(DESCRIPTION_COLUMN, "");
+        if (null == result.get(DESCRIPTION_COLUMN)) result.put(DESCRIPTION_COLUMN, "");
         // File name - this is an asset, so it works as an already deleted file.
         //     hence, we need to supply a non-existent file name. Anything will
         //     do as long as it returns false when tested with File#exist(), and
         //     the empty string does not, so it's set to "_".
-        if (!result.containsKey(LOCAL_FILENAME_COLUMN)) result.put(LOCAL_FILENAME_COLUMN, "_");
+        if (null == result.get(LOCAL_FILENAME_COLUMN)) result.put(LOCAL_FILENAME_COLUMN, "_");
         // No remote file name : this can't be downloaded. Unless specified.
-        if (!result.containsKey(REMOTE_FILENAME_COLUMN)) result.put(REMOTE_FILENAME_COLUMN, "");
+        if (null == result.get(REMOTE_FILENAME_COLUMN)) result.put(REMOTE_FILENAME_COLUMN, "");
         // 0 for the update date : 1970/1/1. Unless specified.
-        if (!result.containsKey(DATE_COLUMN)) result.put(DATE_COLUMN, 0);
+        if (null == result.get(DATE_COLUMN)) result.put(DATE_COLUMN, 0);
         // Checksum unknown unless specified
-        if (!result.containsKey(CHECKSUM_COLUMN)) result.put(CHECKSUM_COLUMN, "");
+        if (null == result.get(CHECKSUM_COLUMN)) result.put(CHECKSUM_COLUMN, "");
         // No filesize unless specified
-        if (!result.containsKey(FILESIZE_COLUMN)) result.put(FILESIZE_COLUMN, 0);
+        if (null == result.get(FILESIZE_COLUMN)) result.put(FILESIZE_COLUMN, 0);
         // Smallest possible version unless specified
-        if (!result.containsKey(VERSION_COLUMN)) result.put(VERSION_COLUMN, 1);
+        if (null == result.get(VERSION_COLUMN)) result.put(VERSION_COLUMN, 1);
         // Assume current format unless specified
-        if (!result.containsKey(FORMATVERSION_COLUMN))
+        if (null == result.get(FORMATVERSION_COLUMN))
             result.put(FORMATVERSION_COLUMN, UpdateHandler.MAXIMUM_SUPPORTED_FORMAT_VERSION);
         // No flags unless specified
-        if (!result.containsKey(FLAGS_COLUMN)) result.put(FLAGS_COLUMN, 0);
+        if (null == result.get(FLAGS_COLUMN)) result.put(FLAGS_COLUMN, 0);
         return result;
     }
 
diff --git a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java
index df7bad8..9d47849 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java
@@ -30,6 +30,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.Locale;
 
 /**
@@ -301,12 +302,14 @@
 
     private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList,
             final DictionaryInfo newElement) {
-        for (final DictionaryInfo info : dictList) {
-            if (info.mLocale.equals(newElement.mLocale)) {
-                if (newElement.mVersion <= info.mVersion) {
+        final Iterator<DictionaryInfo> iter = dictList.iterator();
+        while (iter.hasNext()) {
+            final DictionaryInfo thisDictInfo = iter.next();
+            if (thisDictInfo.mLocale.equals(newElement.mLocale)) {
+                if (newElement.mVersion <= thisDictInfo.mVersion) {
                     return;
                 }
-                dictList.remove(info);
+                iter.remove();
             }
         }
         dictList.add(newElement);
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/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 9fefb58..a6149c6 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -21,6 +21,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
 import android.preference.PreferenceManager;
+import android.util.Log;
 
 import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
 
@@ -28,6 +29,7 @@
 import java.util.Locale;
 
 public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
+    private static final String TAG = Settings.class.getSimpleName();
     // In the same order as xml/prefs.xml
     public static final String PREF_GENERAL_SETTINGS = "general_settings";
     public static final String PREF_AUTO_CAP = "auto_cap";
@@ -114,6 +116,12 @@
 
     @Override
     public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+        if (mSettingsValues == null) {
+            // TODO: Introduce a static function to register this class and ensure that
+            // loadSettings must be called before "onSharedPreferenceChanged" is called.
+            Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
+            return;
+        }
         loadSettings(mCurrentLocale, mSettingsValues.mInputAttributes);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 7225cd6..8365cce 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -32,6 +32,7 @@
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
+import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
 import java.util.TreeSet;
@@ -45,6 +46,7 @@
 
 public final class SettingsFragment extends InputMethodSettingsFragment
         implements SharedPreferences.OnSharedPreferenceChangeListener {
+    private static final String TAG = SettingsFragment.class.getSimpleName();
     private static final boolean DBG_USE_INTERNAL_USER_DICTIONARY_SETTINGS = false;
 
     private ListPreference mVoicePreference;
@@ -246,7 +248,14 @@
 
     @Override
     public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
-        (new BackupManager(getActivity())).dataChanged();
+        final Activity activity = getActivity();
+        if (activity == null) {
+            // TODO: Introduce a static function to register this class and ensure that
+            // onCreate must be called before "onSharedPreferenceChanged" is called.
+            Log.w(TAG, "onSharedPreferenceChanged called before activity starts.");
+            return;
+        }
+        (new BackupManager(activity)).dataChanged();
         final Resources res = getResources();
         if (key.equals(Settings.PREF_POPUP_ON)) {
             setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 282b579..1eca68a 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -43,20 +43,23 @@
     private static final String TAG = SubtypeSwitcher.class.getSimpleName();
 
     private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
+
     private /* final */ RichInputMethodManager mRichImm;
     private /* final */ Resources mResources;
     private /* final */ ConnectivityManager mConnectivityManager;
 
-    /*-----------------------------------------------------------*/
-    // Variants which should be changed only by reload functions.
-    private NeedsToDisplayLanguage mNeedsToDisplayLanguage = new NeedsToDisplayLanguage();
+    private final NeedsToDisplayLanguage mNeedsToDisplayLanguage = new NeedsToDisplayLanguage();
     private InputMethodInfo mShortcutInputMethodInfo;
     private InputMethodSubtype mShortcutSubtype;
     private InputMethodSubtype mNoLanguageSubtype;
-    /*-----------------------------------------------------------*/
-
     private boolean mIsNetworkConnected;
 
+    // Dummy no language QWERTY subtype. See {@link R.xml.method}.
+    private static final InputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE = new InputMethodSubtype(
+            R.string.subtype_no_language_qwerty, R.drawable.ic_subtype_keyboard, "zz", "keyboard",
+            "KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable",
+            false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
+
     static final class NeedsToDisplayLanguage {
         private int mEnabledSubtypeCount;
         private boolean mIsSystemLanguageSameAsInputLanguage;
@@ -96,11 +99,6 @@
         mRichImm = RichInputMethodManager.getInstance();
         mConnectivityManager = (ConnectivityManager) context.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
-        mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY);
-        if (mNoLanguageSubtype == null) {
-            throw new RuntimeException("Can't find no lanugage with QWERTY subtype");
-        }
 
         final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
         mIsNetworkConnected = (info != null && info.isConnected());
@@ -255,10 +253,20 @@
     }
 
     public InputMethodSubtype getCurrentSubtype() {
-        return mRichImm.getCurrentInputMethodSubtype(mNoLanguageSubtype);
+        return mRichImm.getCurrentInputMethodSubtype(getNoLanguageSubtype());
     }
 
     public InputMethodSubtype getNoLanguageSubtype() {
-        return mNoLanguageSubtype;
+        if (mNoLanguageSubtype == null) {
+            mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                    SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY);
+        }
+        if (mNoLanguageSubtype != null) {
+            return mNoLanguageSubtype;
+        }
+        Log.w(TAG, "Can't find no lanugage with QWERTY subtype");
+        Log.w(TAG, "No input method subtype found; return dummy subtype: "
+                + DUMMY_NO_LANGUAGE_SUBTYPE);
+        return DUMMY_NO_LANGUAGE_SUBTYPE;
     }
 }
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;