Merge "Show dialog to guide the user to input subtype enabler" into jb-dev
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 4d7fe3d..c3f5e7d 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -571,9 +571,13 @@
         return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY) != 0;
     }
 
-    public Drawable getIcon(KeyboardIconsSet iconSet) {
+    public Drawable getIcon(KeyboardIconsSet iconSet, int alpha) {
         final int iconId = mEnabled ? mIconId : mDisabledIconId;
-        return iconSet.getIconDrawable(iconId);
+        final Drawable icon = iconSet.getIconDrawable(iconId);
+        if (icon != null) {
+            icon.setAlpha(alpha);
+        }
+        return icon;
     }
 
     public Drawable getPreviewIcon(KeyboardIconsSet iconSet) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 9be193b..c0d5b67 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -560,10 +560,7 @@
         }
 
         // Draw key label.
-        final Drawable icon = key.getIcon(mKeyboard.mIconsSet);
-        if (icon != null) {
-            icon.setAlpha(params.mAnimAlpha);
-        }
+        final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha);
         float positionX = centerX;
         if (key.mLabel != null) {
             final String label = key.mLabel;
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 337ae9c..cb37672 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -459,7 +459,8 @@
         mMoreKeysPanelCache.clear();
 
         mSpaceKey = keyboard.getKey(Keyboard.CODE_SPACE);
-        mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon(keyboard.mIconsSet) : null;
+        mSpaceIcon = (mSpaceKey != null)
+                ? mSpaceKey.getIcon(keyboard.mIconsSet, ALPHA_OPAQUE) : null;
         final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
         mSpacebarTextSize = keyHeight * mSpacebarTextRatio;
         if (ProductionFlag.IS_EXPERIMENTAL) {
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index b6a06e1..a3741a2 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -289,8 +289,6 @@
             final int dividerWidth;
             if (parentKey.needsDividersInMoreKeys()) {
                 mDivider = mResources.getDrawable(R.drawable.more_keys_divider);
-                // TODO: Drawable itself should have an alpha value.
-                mDivider.setAlpha(128);
                 dividerWidth = (int)(width * DIVIDER_RATIO);
             } else {
                 mDivider = null;
@@ -333,8 +331,11 @@
             }
 
             @Override
-            public Drawable getIcon(KeyboardIconsSet iconSet) {
-                // KeyboardIconsSet is unused. Use the icon that has been passed to the constructor.
+            public Drawable getIcon(KeyboardIconsSet iconSet, int alpha) {
+                // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
+                // constructor.
+                // TODO: Drawable itself should have an alpha value.
+                mIcon.setAlpha(128);
                 return mIcon;
             }
         }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 37deb0c..f3aa27a 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -70,6 +70,10 @@
         return false;
     }
 
+    public boolean isEmpty() {
+        return mDictionaries.isEmpty();
+    }
+
     @Override
     public void close() {
         for (final Dictionary dict : mDictionaries)
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index f5dc7b3..4cd1b38 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -36,7 +36,7 @@
             DictionaryFactory.class.getPackage().getName();
 
     /**
-     * Initializes a dictionary from a dictionary pack, with explicit flags.
+     * Initializes a main dictionary collection from a dictionary pack, with explicit flags.
      *
      * This searches for a content provider providing a dictionary pack for the specified
      * locale. If none is found, it falls back to the built-in dictionary - if any.
@@ -45,7 +45,7 @@
      * @param useFullEditDistance whether to use the full edit distance in suggestions
      * @return an initialized instance of DictionaryCollection
      */
-    public static DictionaryCollection createDictionaryFromManager(final Context context,
+    public static DictionaryCollection createMainDictionaryFromManager(final Context context,
             final Locale locale, final boolean useFullEditDistance) {
         if (null == locale) {
             Log.e(TAG, "No locale defined for dictionary");
@@ -73,7 +73,7 @@
     }
 
     /**
-     * Initializes a dictionary from a dictionary pack, with default flags.
+     * Initializes a main dictionary collection from a dictionary pack, with default flags.
      *
      * This searches for a content provider providing a dictionary pack for the specified
      * locale. If none is found, it falls back to the built-in dictionary, if any.
@@ -81,9 +81,9 @@
      * @param locale the locale for which to create the dictionary
      * @return an initialized instance of DictionaryCollection
      */
-    public static DictionaryCollection createDictionaryFromManager(final Context context,
+    public static DictionaryCollection createMainDictionaryFromManager(final Context context,
             final Locale locale) {
-        return createDictionaryFromManager(context, locale, false /* useFullEditDistance */);
+        return createMainDictionaryFromManager(context, locale, false /* useFullEditDistance */);
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 845df81..7832cb5 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -43,20 +43,6 @@
     public static final int CORRECTION_FULL = 1;
     public static final int CORRECTION_FULL_BIGRAM = 2;
 
-    /**
-     * Words that appear in both bigram and unigram data gets multiplier ranging from
-     * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the score from
-     * bigram data.
-     */
-    public static final double BIGRAM_MULTIPLIER_MIN = 1.2;
-    public static final double BIGRAM_MULTIPLIER_MAX = 1.5;
-
-    /**
-     * Maximum possible bigram frequency. Will depend on how many bits are being used in data
-     * structure. Maximum bigram frequency will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
-     */
-    public static final int MAXIMUM_BIGRAM_FREQUENCY = 127;
-
     // It seems the following values are only used for logging.
     public static final int DIC_USER_TYPED = 0;
     public static final int DIC_MAIN = 1;
@@ -79,7 +65,7 @@
 
     private static final boolean DBG = LatinImeLogger.sDBG;
 
-    private Dictionary mMainDict;
+    private boolean mHasMainDictionary;
     private Dictionary mContactsDict;
     private WhitelistDictionary mWhiteListDictionary;
     private final HashMap<String, Dictionary> mUnigramDictionaries =
@@ -110,8 +96,12 @@
 
     /* package for test */ Suggest(final Context context, final File dictionary,
             final long startOffset, final long length, final Locale locale) {
-        initSynchronously(context, DictionaryFactory.createDictionaryForTest(context, dictionary,
-                startOffset, length /* useFullEditDistance */, false, locale), locale);
+        final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
+                startOffset, length /* useFullEditDistance */, false, locale);
+        mHasMainDictionary = null != mainDict;
+        addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
+        addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
+        initWhitelistAndAutocorrectAndPool(context, locale);
     }
 
     private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) {
@@ -127,14 +117,6 @@
         initWhitelistAndAutocorrectAndPool(context, locale);
     }
 
-    private void initSynchronously(final Context context, final Dictionary mainDict,
-            final Locale locale) {
-        mMainDict = mainDict;
-        addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
-        addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
-        initWhitelistAndAutocorrectAndPool(context, locale);
-    }
-
     private static void addOrReplaceDictionary(HashMap<String, Dictionary> dictionaries, String key,
             Dictionary dict) {
         final Dictionary oldDict = (dict == null)
@@ -146,13 +128,13 @@
     }
 
     public void resetMainDict(final Context context, final Locale locale) {
-        mMainDict = null;
+        mHasMainDictionary = false;
         new Thread("InitializeBinaryDictionary") {
             @Override
             public void run() {
-                final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
-                        context, locale);
-                mMainDict = newMainDict;
+                final DictionaryCollection newMainDict =
+                        DictionaryFactory.createMainDictionaryFromManager(context, locale);
+                mHasMainDictionary = null != newMainDict && !newMainDict.isEmpty();
                 addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
                 addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
             }
@@ -162,7 +144,7 @@
     // The main dictionary could have been loaded asynchronously.  Don't cache the return value
     // of this method.
     public boolean hasMainDictionary() {
-        return mMainDict != null;
+        return mHasMainDictionary;
     }
 
     public Dictionary getContactsDictionary() {
@@ -376,7 +358,13 @@
         // a boolean flag. Right now this is handled with a slight hack in
         // WhitelistDictionary#shouldForciblyAutoCorrectFrom.
         final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected(
-                getUnigramDictionaries(), consideredWord, wordComposer.isFirstCharCapitalized());
+                getUnigramDictionaries(), consideredWord, wordComposer.isFirstCharCapitalized())
+        // If we don't have a main dictionary, we never want to auto-correct. The reason for this
+        // is, the user may have a contact whose name happens to match a valid word in their
+        // language, and it will unexpectedly auto-correct. For example, if the user types in
+        // English with no dictionary and has a "Will" in their contact list, "will" would
+        // always auto-correct to "Will" which is unwanted. Hence, no main dict => no auto-correct.
+                && mHasMainDictionary;
 
         boolean autoCorrectionAvailable = hasAutoCorrection;
         if (correctionMode == CORRECTION_FULL || correctionMode == CORRECTION_FULL_BIGRAM) {
@@ -476,25 +464,6 @@
                 }
             }
         } else {
-            if (dataType == Dictionary.UNIGRAM) {
-                // Check if the word was already added before (by bigram data)
-                int bigramSuggestion = searchBigramSuggestion(word,offset,length);
-                if(bigramSuggestion >= 0) {
-                    dataTypeForLog = Dictionary.BIGRAM;
-                    // turn freq from bigram into multiplier specified above
-                    double multiplier = (((double) mBigramSuggestions.get(bigramSuggestion).mScore)
-                            / MAXIMUM_BIGRAM_FREQUENCY)
-                            * (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN)
-                            + BIGRAM_MULTIPLIER_MIN;
-                    /* Log.d(TAG,"bigram num: " + bigramSuggestion
-                            + "  wordB: " + mBigramSuggestions.get(bigramSuggestion).toString()
-                            + "  currentScore: " + score + "  bigramScore: "
-                            + mBigramScores[bigramSuggestion]
-                            + "  multiplier: " + multiplier); */
-                    score = (int)Math.round((score * multiplier));
-                }
-            }
-
             // Check the last one's score and bail
             if (suggestions.size() >= prefMaxSuggestions
                     && suggestions.get(prefMaxSuggestions - 1).mScore >= score) return true;
@@ -563,7 +532,7 @@
         for (final Dictionary dictionary : dictionaries) {
             dictionary.close();
         }
-        mMainDict = null;
+        mHasMainDictionary = false;
     }
 
     // TODO: Resolve the inconsistencies between the native auto correction algorithms and
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 6f7f0c3..0c9f9fb 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -398,7 +398,7 @@
                 SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
                 SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT);
         final DictionaryCollection dictionaryCollection =
-                DictionaryFactory.createDictionaryFromManager(this, locale,
+                DictionaryFactory.createMainDictionaryFromManager(this, locale,
                         true /* useFullEditDistance */);
         final String localeStr = locale.toString();
         Dictionary userDictionary = mUserDictionaries.get(localeStr);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index dd83a0c..c6fe43b 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -56,8 +56,6 @@
                 clearKeys();
                 final Resources res = view.getContext().getResources();
                 mDivider = res.getDrawable(R.drawable.more_suggestions_divider);
-                // TODO: Drawable itself should have an alpha value.
-                mDivider.setAlpha(128);
                 mDividerWidth = mDivider.getIntrinsicWidth();
                 final int padding = (int) res.getDimension(
                         R.dimen.more_suggestions_key_horizontal_padding);
@@ -195,7 +193,11 @@
             }
 
             @Override
-            public Drawable getIcon(KeyboardIconsSet iconSet) {
+            public Drawable getIcon(KeyboardIconsSet iconSet, int alpha) {
+                // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
+                // constructor.
+                // TODO: Drawable itself should have an alpha value.
+                mIcon.setAlpha(128);
                 return mIcon;
             }
         }