Merge "Step 22-A implement session" into jb-mr1-dev
diff --git a/dictionaries/en_whitelist.xml b/dictionaries/en_whitelist.xml
new file mode 100644
index 0000000..f112077
--- /dev/null
+++ b/dictionaries/en_whitelist.xml
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<shortcuts>
+ <entry shortcut="ill">
+  <target replacement="I\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="acomodate">
+  <target replacement="accommodate" priority="whitelist" />
+ </entry>
+ <entry shortcut="aint">
+  <target replacement="ain\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="alot">
+  <target replacement="a lot" priority="whitelist" />
+ </entry>
+ <entry shortcut="andteh">
+  <target replacement="and the" priority="whitelist" />
+ </entry>
+ <entry shortcut="arent">
+  <target replacement="aren\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="bern">
+  <target replacement="been" priority="whitelist" />
+ </entry>
+ <entry shortcut="bot">
+  <target replacement="not" priority="whitelist" />
+ </entry>
+ <entry shortcut="bur">
+  <target replacement="but" priority="whitelist" />
+ </entry>
+ <entry shortcut="cam">
+  <target replacement="can" priority="whitelist" />
+ </entry>
+ <entry shortcut="cant">
+  <target replacement="can\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="dame">
+  <target replacement="same" priority="whitelist" />
+ </entry>
+ <entry shortcut="didint">
+  <target replacement="didn\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="dormer">
+  <target replacement="former" priority="whitelist" />
+ </entry>
+ <entry shortcut="dud">
+  <target replacement="did" priority="whitelist" />
+ </entry>
+ <entry shortcut="fay">
+  <target replacement="day" priority="whitelist" />
+ </entry>
+ <entry shortcut="fife">
+  <target replacement="five" priority="whitelist" />
+ </entry>
+ <entry shortcut="foo">
+  <target replacement="for" priority="whitelist" />
+ </entry>
+ <entry shortcut="fora">
+  <target replacement="for a" priority="whitelist" />
+ </entry>
+ <entry shortcut="galled">
+  <target replacement="called" priority="whitelist" />
+ </entry>
+ <entry shortcut="goo">
+  <target replacement="too" priority="whitelist" />
+ </entry>
+ <entry shortcut="hed">
+  <target replacement="he\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="hel">
+  <target replacement="he\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="heres">
+  <target replacement="here\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="hew">
+  <target replacement="new" priority="whitelist" />
+ </entry>
+ <entry shortcut="hoe">
+  <target replacement="how" priority="whitelist" />
+ </entry>
+ <entry shortcut="hoes">
+  <target replacement="how\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="howd">
+  <target replacement="how\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="howll">
+  <target replacement="how\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="hows">
+  <target replacement="how\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="howve">
+  <target replacement="how\'ve" priority="whitelist" />
+ </entry>
+ <entry shortcut="hum">
+  <target replacement="him" priority="whitelist" />
+ </entry>
+ <entry shortcut="i">
+  <target replacement="I" priority="whitelist" />
+ </entry>
+ <entry shortcut="ifs">
+  <target replacement="its" priority="whitelist" />
+ </entry>
+ <entry shortcut="il">
+  <target replacement="I\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="im">
+  <target replacement="I\'m" priority="whitelist" />
+ </entry>
+ <entry shortcut="inteh">
+  <target replacement="in the" priority="whitelist" />
+ </entry>
+ <entry shortcut="itd">
+  <target replacement="it\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="itsa">
+  <target replacement="it\'s a" priority="whitelist" />
+ </entry>
+ <entry shortcut="lets">
+  <target replacement="let\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="maam">
+  <target replacement="ma\'am" priority="whitelist" />
+ </entry>
+ <entry shortcut="manu">
+  <target replacement="many" priority="whitelist" />
+ </entry>
+ <entry shortcut="mare">
+  <target replacement="made" priority="whitelist" />
+ </entry>
+ <entry shortcut="mew">
+  <target replacement="new" priority="whitelist" />
+ </entry>
+ <entry shortcut="mire">
+  <target replacement="more" priority="whitelist" />
+ </entry>
+ <entry shortcut="moat">
+  <target replacement="most" priority="whitelist" />
+ </entry>
+ <entry shortcut="mot">
+  <target replacement="not" priority="whitelist" />
+ </entry>
+ <entry shortcut="mote">
+  <target replacement="note" priority="whitelist" />
+ </entry>
+ <entry shortcut="motes">
+  <target replacement="notes" priority="whitelist" />
+ </entry>
+ <entry shortcut="mow">
+  <target replacement="now" priority="whitelist" />
+ </entry>
+ <entry shortcut="namer">
+  <target replacement="named" priority="whitelist" />
+ </entry>
+ <entry shortcut="nave">
+  <target replacement="have" priority="whitelist" />
+ </entry>
+ <entry shortcut="nee">
+  <target replacement="new" priority="whitelist" />
+ </entry>
+ <entry shortcut="nigh">
+  <target replacement="high" priority="whitelist" />
+ </entry>
+ <entry shortcut="nit">
+  <target replacement="not" priority="whitelist" />
+ </entry>
+ <entry shortcut="oft">
+  <target replacement="off" priority="whitelist" />
+ </entry>
+ <entry shortcut="os">
+  <target replacement="is" priority="whitelist" />
+ </entry>
+ <entry shortcut="pater">
+  <target replacement="later" priority="whitelist" />
+ </entry>
+ <entry shortcut="rook">
+  <target replacement="took" priority="whitelist" />
+ </entry>
+ <entry shortcut="shel">
+  <target replacement="she\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="shouldent">
+  <target replacement="shouldn\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="sill">
+  <target replacement="will" priority="whitelist" />
+ </entry>
+ <entry shortcut="sown">
+  <target replacement="down" priority="whitelist" />
+ </entry>
+ <entry shortcut="thatd">
+  <target replacement="that\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="tine">
+  <target replacement="time" priority="whitelist" />
+ </entry>
+ <entry shortcut="thong">
+  <target replacement="thing" priority="whitelist" />
+ </entry>
+ <entry shortcut="tome">
+  <target replacement="time" priority="whitelist" />
+ </entry>
+ <entry shortcut="uf">
+  <target replacement="if" priority="whitelist" />
+ </entry>
+ <entry shortcut="un">
+  <target replacement="in" priority="whitelist" />
+ </entry>
+ <entry shortcut="UnitedStates">
+  <target replacement="United States" priority="whitelist" />
+ </entry>
+ <entry shortcut="unitedstates">
+  <target replacement="United States" priority="whitelist" />
+ </entry>
+ <entry shortcut="visavis">
+  <target replacement="vis-a-vis" priority="whitelist" />
+ </entry>
+ <entry shortcut="wierd">
+  <target replacement="weird" priority="whitelist" />
+ </entry>
+ <entry shortcut="wel">
+  <target replacement="we\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="wer">
+  <target replacement="we\'re" priority="whitelist" />
+ </entry>
+ <entry shortcut="whatd">
+  <target replacement="what\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="whatm">
+  <target replacement="what\'m" priority="whitelist" />
+ </entry>
+ <entry shortcut="whatre">
+  <target replacement="what\'re" priority="whitelist" />
+ </entry>
+ <entry shortcut="whats">
+  <target replacement="what\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="whens">
+  <target replacement="when\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="whered">
+  <target replacement="where\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="wherell">
+  <target replacement="where\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="wheres">
+  <target replacement="where\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="wholl">
+  <target replacement="who\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="whove">
+  <target replacement="who\'ve" priority="whitelist" />
+ </entry>
+ <entry shortcut="whyd">
+  <target replacement="why\'d" priority="whitelist" />
+ </entry>
+ <entry shortcut="whyll">
+  <target replacement="why\'ll" priority="whitelist" />
+ </entry>
+ <entry shortcut="whys">
+  <target replacement="why\'s" priority="whitelist" />
+ </entry>
+ <entry shortcut="whyve">
+  <target replacement="why\'ve" priority="whitelist" />
+ </entry>
+ <entry shortcut="wont">
+  <target replacement="won\'t" priority="whitelist" />
+ </entry>
+ <entry shortcut="yall">
+  <target replacement="y\'all" priority="whitelist" />
+ </entry>
+ <entry shortcut="youd">
+  <target replacement="you\'d" priority="whitelist" />
+ </entry>
+</shortcuts>
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 4088f3e..9590290 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -835,20 +835,6 @@
         return false;
     }
 
-    @Override
-    public void draw(Canvas c) {
-        Utils.GCUtils.getInstance().reset();
-        boolean tryGC = true;
-        for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
-            try {
-                super.draw(c);
-                tryGC = false;
-            } catch (OutOfMemoryError e) {
-                tryGC = Utils.GCUtils.getInstance().tryGCOrWait(TAG, e);
-            }
-        }
-    }
-
     /**
      * Receives hover events from the input framework.
      *
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 7ba565c..0967644 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -144,9 +144,10 @@
                 ++len;
             }
             if (len > 0) {
+                final int score = SuggestedWordInfo.KIND_WHITELIST == mOutputTypes[j]
+                        ? SuggestedWordInfo.MAX_SCORE : mOutputScores[j];
                 suggestions.add(new SuggestedWordInfo(
-                        new String(mOutputChars, start, len),
-                        mOutputScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType));
+                        new String(mOutputChars, start, len), score, mOutputTypes[j], mDictType));
             }
         }
         return suggestions;
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index b6b0210..9f7ab53 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -63,8 +63,8 @@
 
 // TODO: This needs to take a const unsigned short* and not tinker with its contents
 static inline void addWord(
-        unsigned short *word, int length, int frequency, WordsPriorityQueue *queue) {
-    queue->push(frequency, word, length);
+        unsigned short *word, int length, int frequency, WordsPriorityQueue *queue, int type) {
+    queue->push(frequency, word, length, type);
 }
 
 // Return the replacement code point for a digraph, or 0 if none.
@@ -213,8 +213,8 @@
         AKLOGI("Max normalized score = %f", ns);
     }
     const int suggestedWordsCount =
-            queuePool.getMasterQueue()->outputSuggestions(
-                    masterCorrection.getPrimaryInputWord(), codesSize, frequencies, outWords);
+            queuePool.getMasterQueue()->outputSuggestions(masterCorrection.getPrimaryInputWord(),
+                    codesSize, frequencies, outWords, outputTypes);
 
     if (DEBUG_DICT) {
         float ns = queuePool.getMasterQueue()->getHighestNormalizedScore(
@@ -391,7 +391,8 @@
         const int finalProbability =
                 correction->getFinalProbability(probability, &wordPointer, &wordLength);
         if (finalProbability != NOT_A_PROBABILITY) {
-            addWord(wordPointer, wordLength, finalProbability, masterQueue);
+            addWord(wordPointer, wordLength, finalProbability, masterQueue,
+                    Dictionary::KIND_CORRECTION);
 
             const int shortcutProbability = finalProbability > 0 ? finalProbability - 1 : 0;
             // Please note that the shortcut candidates will be added to the master queue only.
@@ -409,7 +410,7 @@
                 const int shortcutTargetStringLength = iterator.getNextShortcutTarget(
                         MAX_WORD_LENGTH_INTERNAL, shortcutTarget);
                 addWord(shortcutTarget, shortcutTargetStringLength, shortcutProbability,
-                        masterQueue);
+                        masterQueue, Dictionary::KIND_CORRECTION);
             }
         }
     }
@@ -424,7 +425,7 @@
         }
         const int finalProbability = correction->getFinalProbabilityForSubQueue(
                 probability, &wordPointer, &wordLength, inputIndex);
-        addWord(wordPointer, wordLength, finalProbability, subQueue);
+        addWord(wordPointer, wordLength, finalProbability, subQueue, Dictionary::KIND_CORRECTION);
     }
 }
 
@@ -572,7 +573,8 @@
             AKLOGI("Split two words: freq = %d, length = %d, %d, isSpace ? %d", pairFreq,
                     inputLength, tempOutputWordLength, isSpaceProximity);
         }
-        addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue());
+        addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue(),
+                Dictionary::KIND_CORRECTION);
     }
     return FLAG_MULTIPLE_SUGGEST_CONTINUE;
 }
diff --git a/native/jni/src/words_priority_queue.h b/native/jni/src/words_priority_queue.h
index c0dedb5..8a6da1c 100644
--- a/native/jni/src/words_priority_queue.h
+++ b/native/jni/src/words_priority_queue.h
@@ -33,12 +33,14 @@
         unsigned short mWord[MAX_WORD_LENGTH_INTERNAL];
         int mWordLength;
         bool mUsed;
+        int mType;
 
-        void setParams(int score, unsigned short *word, int wordLength) {
+        void setParams(int score, unsigned short *word, int wordLength, int type) {
             mScore = score;
             mWordLength = wordLength;
             memcpy(mWord, word, sizeof(unsigned short) * wordLength);
             mUsed = true;
+            mType = type;
         }
     };
 
@@ -56,7 +58,7 @@
         delete[] mSuggestedWords;
     }
 
-    void push(int score, unsigned short *word, int wordLength) {
+    void push(int score, unsigned short *word, int wordLength, int type) {
         SuggestedWord *sw = 0;
         if (mSuggestions.size() >= MAX_WORDS) {
             sw = mSuggestions.top();
@@ -69,9 +71,9 @@
             }
         }
         if (sw == 0) {
-            sw = getFreeSuggestedWord(score, word, wordLength);
+            sw = getFreeSuggestedWord(score, word, wordLength, type);
         } else {
-            sw->setParams(score, word, wordLength);
+            sw->setParams(score, word, wordLength, type);
         }
         if (sw == 0) {
             AKLOGE("SuggestedWord is accidentally null.");
@@ -94,7 +96,7 @@
     }
 
     int outputSuggestions(const unsigned short *before, const int beforeLength,
-            int *frequencies, unsigned short *outputChars) {
+            int *frequencies, unsigned short *outputChars, int* outputTypes) {
         mHighestSuggestedWord = 0;
         const unsigned int size = min(
               MAX_WORDS, static_cast<unsigned int>(mSuggestions.size()));
@@ -140,6 +142,7 @@
             const unsigned int wordLength = sw->mWordLength;
             char *targetAdr = (char*) outputChars + i * MAX_WORD_LENGTH * sizeof(short);
             frequencies[i] = sw->mScore;
+            outputTypes[i] = sw->mType;
             memcpy(targetAdr, sw->mWord, (wordLength) * sizeof(short));
             if (wordLength < MAX_WORD_LENGTH) {
                 ((unsigned short*) targetAdr)[wordLength] = 0;
@@ -191,10 +194,10 @@
     };
 
     SuggestedWord *getFreeSuggestedWord(int score, unsigned short *word,
-            int wordLength) {
+            int wordLength, int type) {
         for (unsigned int i = 0; i < MAX_WORD_LENGTH; ++i) {
             if (!mSuggestedWords[i].mUsed) {
-                mSuggestedWords[i].setParams(score, word, wordLength);
+                mSuggestedWords[i].setParams(score, word, wordLength, type);
                 return &mSuggestedWords[i];
             }
         }
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
index 9ab56d7..9ce8c49 100644
--- a/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
@@ -90,6 +90,10 @@
 
         public FusionDictionary getFinalDictionary() {
             final FusionDictionary dict = mDictionary;
+            for (final String shortcutOnly : mShortcutsMap.keySet()) {
+                if (dict.hasWord(shortcutOnly)) continue;
+                dict.add(shortcutOnly, 0, mShortcutsMap.get(shortcutOnly));
+            }
             mDictionary = null;
             mShortcutsMap.clear();
             mWord = "";