Merge "Fix: incompatibility of sparse table."
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index a269d49..f4d072d 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -87,6 +87,11 @@
     <!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] -->
     <string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string>
 
+    <!-- Option name for enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=25] -->
+    <string name="use_personalized_dicts">Personalized suggestions</string>
+    <!-- Description for option enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=65] -->
+    <string name="use_personalized_dicts_summary">Learn from your communications and typed data to improve suggestions</string>
+
     <!-- Option name for enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=30] -->
     <string name="use_double_space_period">Double-space period</string>
     <!-- Description for option enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=65] -->
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index bf3b623..4f7c9f0 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -134,6 +134,12 @@
                 android:persistent="true"
                 android:defaultValue="true" />
             <CheckBoxPreference
+                android:key="pref_key_use_personalized_dicts"
+                android:title="@string/use_personalized_dicts"
+                android:summary="@string/use_personalized_dicts_summary"
+                android:persistent="true"
+                android:defaultValue="true" />
+            <CheckBoxPreference
                 android:key="pref_key_use_double_space_period"
                 android:title="@string/use_double_space_period"
                 android:summary="@string/use_double_space_period_summary"
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 1400e05..4b6e12f 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -932,11 +932,7 @@
     @Override
     public void onShowMoreKeysPanel(final MoreKeysPanel panel) {
         locatePreviewPlacerView();
-        // TODO: Remove this check
-        if (panel.isShowingInParent()) {
-            panel.dismissMoreKeysPanel();
-        }
-        mPreviewPlacerView.addView(panel.getContainerView());
+        panel.showInParent(mPreviewPlacerView);
         mMoreKeysPanel = panel;
         dimEntireKeyboard(true /* dimmed */);
     }
@@ -954,7 +950,7 @@
     public void onDismissMoreKeysPanel(final MoreKeysPanel panel) {
         dimEntireKeyboard(false /* dimmed */);
         if (isShowingMoreKeysPanel()) {
-            mPreviewPlacerView.removeView(mMoreKeysPanel.getContainerView());
+            mMoreKeysPanel.removeFromParent();
             mMoreKeysPanel = null;
         }
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index a7c4685..5b13e9a 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
@@ -216,12 +217,26 @@
         return true;
     }
 
-    @Override
-    public View getContainerView() {
+    private View getContainerView() {
         return (View)getParent();
     }
 
     @Override
+    public void showInParent(final ViewGroup parentView) {
+        removeFromParent();
+        parentView.addView(getContainerView());
+    }
+
+    @Override
+    public void removeFromParent() {
+        final View containerView = getContainerView();
+        final ViewGroup currentParent = (ViewGroup)containerView.getParent();
+        if (currentParent != null) {
+            currentParent.removeView(containerView);
+        }
+    }
+
+    @Override
     public boolean isShowingInParent() {
         return (getContainerView().getParent() != null);
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
index 886c628..4a33e65 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.keyboard;
 
 import android.view.View;
+import android.view.ViewGroup;
 
 public interface MoreKeysPanel {
     public interface Controller {
@@ -119,9 +120,16 @@
     public int translateY(int y);
 
     /**
-     * Return the view containing the more keys panel.
+     * Show this {@link MoreKeysPanel} in the parent view.
+     *
+     * @param parentView the {@link ViewGroup} that hosts this {@link MoreKeysPanel}.
      */
-    public View getContainerView();
+    public void showInParent(ViewGroup parentView);
+
+    /**
+     * Remove this {@link MoreKeysPanel} from the parent view.
+     */
+    public void removeFromParent();
 
     /**
      * Return whether the panel is currently being shown.
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8b46655..1f6091e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2565,26 +2565,20 @@
         final SettingsValues currentSettings = mSettings.getCurrent();
         final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues;
 
-        final String previousWord;
-        if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) {
-            previousWord = mWordComposer.getPreviousWord();
-        } else {
-            // Not composing: this is for prediction.
-            // TODO: read the previous word earlier for prediction, like we are doing for
-            // normal suggestions.
-            previousWord = getNthPreviousWordForSuggestion(currentSettings, 1 /* nthPreviousWord*/);
-        }
         if (DEBUG) {
-            // TODO: this is for checking consistency with older versions. Remove this when
-            // we are confident this is stable.
-            // We're checking the previous word in the text field against the memorized previous
-            // word. If we are composing a word we should have the second word before the cursor
-            // memorized, otherwise we should have the first.
-            final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings,
-                    mWordComposer.isComposingWord() ? 2 : 1);
-            if (!TextUtils.equals(previousWord, rereadPrevWord)) {
-                throw new RuntimeException("Unexpected previous word: "
-                        + previousWord + " <> " + rereadPrevWord);
+            if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) {
+                final String previousWord = mWordComposer.getPreviousWord();
+                // TODO: this is for checking consistency with older versions. Remove this when
+                // we are confident this is stable.
+                // We're checking the previous word in the text field against the memorized previous
+                // word. If we are composing a word we should have the second word before the cursor
+                // memorized, otherwise we should have the first.
+                final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings,
+                        mWordComposer.isComposingWord() ? 2 : 1);
+                if (!TextUtils.equals(previousWord, rereadPrevWord)) {
+                    throw new RuntimeException("Unexpected previous word: "
+                            + previousWord + " <> " + rereadPrevWord);
+                }
             }
         }
         suggest.getSuggestedWords(mWordComposer, mWordComposer.getPreviousWord(),
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 714c3a9..94f1458 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -53,6 +53,7 @@
     public static final String PREF_MISC_SETTINGS = "misc_settings";
     public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
     public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
+    public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts";
     public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD =
             "pref_key_use_double_space_period";
     public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE =
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 06406c1..d98e547 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -29,11 +29,9 @@
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodManager;
-import com.android.inputmethod.latin.SubtypeSwitcher;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.InputTypeUtils;
 import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
@@ -71,6 +69,7 @@
     public final boolean mIncludesOtherImesInLanguageSwitchList;
     public final boolean mShowsLanguageSwitchKey;
     public final boolean mUseContactsDict;
+    public final boolean mUsePersonalizedDicts;
     public final boolean mUseDoubleSpacePeriod;
     public final boolean mBlockPotentiallyOffensive;
     // Use bigrams to predict the next word when there is no input for it yet
@@ -148,6 +147,7 @@
                 Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false);
         mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs);
         mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
+        mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
         mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
         mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res);
         mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
@@ -206,6 +206,7 @@
         mIncludesOtherImesInLanguageSwitchList = false;
         mShowsLanguageSwitchKey = true;
         mUseContactsDict = true;
+        mUsePersonalizedDicts = true;
         mUseDoubleSpacePeriod = true;
         mBlockPotentiallyOffensive = true;
         mAutoCorrectEnabled = true;