Merge "Make checksum and header checks decoder dependent."
diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
index 5a9258d..011bc59 100644
--- a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
+++ b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin.utils;
 
+import android.view.inputmethod.InputMethodSubtype;
+
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.settings.SettingsValues;
@@ -86,4 +88,8 @@
 
     public static void onInvalidWordIdentification(final String invalidWord) {
     }
+
+    public static void onSubtypeChanged(final InputMethodSubtype oldSubtype,
+            final InputMethodSubtype newSubtype) {
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 22f5f5c..addc8f2 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -173,25 +173,4 @@
     void dumpDictionaryForDebug(final String dictName);
 
     ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts();
-
-    void addOrIncrementTerm(String fileName,
-            String finalWordToBeAdded,
-            NgramContext ngramContext,
-            int increment,
-            int timeStampInSeconds);
-
-    void clearLanguageModel(String filePath);
-
-    /**
-     * Lets callers iterate over a given dynamic language model. Each iterate call
-     * results in ngrams, their counts, their last updated timestamps and an iteration token
-     * that can be used for the next {@link #iterateOverLanguageModel} call.
-     *
-     * Use empty string for starting the iterator from the begining.
-     * Returns empty string if there are no more entries to iterate upon.
-     * TODO: Encapsulate the result arrays into a java class.
-     */
-    String  iterateOverLanguageModel(String filePath, String iterationToken,
-            ArrayList<String> outputNgramEntries, ArrayList<Integer> outputNgramCounts,
-            ArrayList<Integer> outputNgramTimestamps);
 }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index 6bc97ca..1e08854 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+7 * Copyright (C) 2013 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -772,10 +772,12 @@
         }
     }
 
+    @Override
     public void clearUserHistoryDictionary() {
         clearSubDictionary(Dictionary.TYPE_USER_HISTORY);
     }
 
+    @Override
     public void dumpDictionaryForDebug(final String dictName) {
         final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
         for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
@@ -789,6 +791,7 @@
         }
     }
 
+    @Override
     public ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts() {
         final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
         final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
@@ -801,26 +804,4 @@
         }
         return statsOfEnabledSubDicts;
     }
-
-    @Override
-    public void addOrIncrementTerm(String fileName,
-            String word,
-            NgramContext ngramContext,
-            int increment,
-            int timeStampInSeconds) {
-        // Do nothing.
-    }
-
-    @Override
-    public void clearLanguageModel(String filePath) {
-        // Do nothing.
-    }
-
-    @Override
-    public String iterateOverLanguageModel(String filePath, String iterationToken,
-            ArrayList<String> outputNgramEntries, ArrayList<Integer> outputNgramCounts,
-            ArrayList<Integer> outputNgramTimestamps) {
-        // Do nothing.
-        return "";
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
index e9b26c6..b813af4 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
@@ -35,7 +35,7 @@
     private final String mDictionaryNamePrefix;
     private final Object mLock = new Object();
     private final DictionaryFacilitator mDictionaryFacilitator;
-    private boolean mUseContactsDictionary = false;
+    private boolean mUseContactsDictionary;
     private Locale mLocale;
 
     public DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix) {
@@ -71,13 +71,13 @@
                 mDictionaryNamePrefix, null /* listener */);
     }
 
-    public void setUseContactsDictionary(final boolean useContectsDictionary) {
+    public void setUseContactsDictionary(final boolean useContactsDictionary) {
         synchronized (mLock) {
-            if (mUseContactsDictionary == useContectsDictionary) {
+            if (mUseContactsDictionary == useContactsDictionary) {
                 // The value has not been changed.
                 return;
             }
-            mUseContactsDictionary = useContectsDictionary;
+            mUseContactsDictionary = useContactsDictionary;
             resetDictionariesForLocaleLocked();
             waitForLoadingMainDictionary(mDictionaryFacilitator);
         }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e37f20f..550efa5 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -793,6 +793,8 @@
     public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) {
         // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
         // is not guaranteed. It may even be called at the same time on a different thread.
+        InputMethodSubtype oldSubtype = mRichImm.getCurrentSubtype().getRawSubtype();
+        StatsUtils.onSubtypeChanged(oldSubtype, subtype);
         mRichImm.onSubtypeChanged(subtype);
         mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
                 mSettings.getCurrent());
diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
index db5e632..5c3abd2 100644
--- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
@@ -20,6 +20,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.Process;
 import android.util.Log;
@@ -35,6 +36,22 @@
  * package has been replaced by a newer version of the same package. This class also detects
  * {@link Intent#ACTION_BOOT_COMPLETED} and {@link Intent#ACTION_USER_INITIALIZE} broadcast intent.
  *
+ * If this IME has already been installed in the system image and a new version of this IME has
+ * been installed, {@link Intent#ACTION_MY_PACKAGE_REPLACED} is received by this receiver and it
+ * will hide the setup wizard's icon.
+ *
+ * If this IME has already been installed in the data partition and a new version of this IME has
+ * been installed, {@link Intent#ACTION_MY_PACKAGE_REPLACED} is received by this receiver but it
+ * will not hide the setup wizard's icon, and the icon will appear on the launcher.
+ *
+ * If this IME hasn't been installed yet and has been newly installed, no
+ * {@link Intent#ACTION_MY_PACKAGE_REPLACED} will be sent and the setup wizard's icon will appear
+ * on the launcher.
+ *
+ * When the device has been booted, {@link Intent#ACTION_BOOT_COMPLETED} is received by this
+ * receiver and it checks whether the setup wizard's icon should be appeared or not on the launcher
+ * depending on which partition this IME is installed.
+ *
  * When the system locale has been changed, {@link Intent#ACTION_LOCALE_CHANGED} is received by
  * this receiver and the {@link KeyboardLayoutSet}'s cache is cleared.
  */
@@ -52,21 +69,22 @@
             final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
             final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes();
             richImm.setAdditionalInputMethodSubtypes(additionalSubtypes);
-            showAppIcon(context);
+            toggleAppIcon(context);
         } else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
             Log.i(TAG, "Boot has been completed");
-            showAppIcon(context);
+            toggleAppIcon(context);
         } else if (Intent.ACTION_LOCALE_CHANGED.equals(intentAction)) {
             Log.i(TAG, "System locale changed");
             KeyboardLayoutSet.onSystemLocaleChanged();
         }
 
         // 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 just booted,
+        // 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 InputMethodManager imm =
-                (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        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();
@@ -79,12 +97,17 @@
         }
     }
 
-    private static void showAppIcon(final Context context) {
-        final ComponentName setupWizardActivity = new ComponentName(context, SetupActivity.class);
-        final PackageManager pm = context.getPackageManager();
-        pm.setComponentEnabledSetting(
-                setupWizardActivity,
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+    private static void toggleAppIcon(final Context context) {
+        final int appInfoFlags = context.getApplicationInfo().flags;
+        final boolean isSystemApp = (appInfoFlags & ApplicationInfo.FLAG_SYSTEM) > 0;
+        if (Log.isLoggable(TAG, Log.INFO)) {
+            Log.i(TAG, "toggleAppIcon() : FLAG_SYSTEM = " + isSystemApp);
+        }
+        context.getPackageManager().setComponentEnabledSetting(
+                new ComponentName(context, SetupActivity.class),
+                isSystemApp
+                        ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+                        : PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                 PackageManager.DONT_KILL_APP);
     }
 }