Merge "Show the keyboard earlier when rotating."
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index 85ae500..5c518b8 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -459,6 +459,7 @@
         mEmojiPager.setAdapter(mEmojiPalettesAdapter);
         mEmojiPager.setOnPageChangeListener(this);
         mEmojiPager.setOffscreenPageLimit(0);
+        mEmojiPager.setPersistentDrawingCache(ViewPager.PERSISTENT_NO_CACHE);
         final Resources res = getResources();
         final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res);
         emojiLp.setPagerProperties(mEmojiPager);
@@ -607,7 +608,7 @@
     private static class EmojiPalettesAdapter extends PagerAdapter {
         private final ScrollKeyboardView.OnKeyClickListener mListener;
         private final DynamicGridKeyboard mRecentsKeyboard;
-        private final SparseArray<ScrollKeyboardView> mActiveKeyboardView =
+        private final SparseArray<ScrollKeyboardView> mActiveKeyboardViews =
                 CollectionUtils.newSparseArray();
         private final EmojiCategory mEmojiCategory;
         private int mActivePosition = 0;
@@ -623,7 +624,7 @@
         public void flushPendingRecentKeys() {
             mRecentsKeyboard.flushPendingRecentKeys();
             final KeyboardView recentKeyboardView =
-                    mActiveKeyboardView.get(mEmojiCategory.getRecentTabId());
+                    mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
             if (recentKeyboardView != null) {
                 recentKeyboardView.invalidateAllKeys();
             }
@@ -636,7 +637,7 @@
             }
             mRecentsKeyboard.addKeyFirst(key);
             final KeyboardView recentKeyboardView =
-                    mActiveKeyboardView.get(mEmojiCategory.getRecentTabId());
+                    mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
             if (recentKeyboardView != null) {
                 recentKeyboardView.invalidateAllKeys();
             }
@@ -652,7 +653,7 @@
             if (mActivePosition == position) {
                 return;
             }
-            final ScrollKeyboardView oldKeyboardView = mActiveKeyboardView.get(mActivePosition);
+            final ScrollKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition);
             if (oldKeyboardView != null) {
                 oldKeyboardView.releaseCurrentKey();
                 oldKeyboardView.deallocateMemory();
@@ -662,11 +663,11 @@
 
         @Override
         public Object instantiateItem(final ViewGroup container, final int position) {
-            final ScrollKeyboardView oldKeyboardView = mActiveKeyboardView.get(position);
+            final ScrollKeyboardView oldKeyboardView = mActiveKeyboardViews.get(position);
             if (oldKeyboardView != null) {
                 oldKeyboardView.deallocateMemory();
                 // This may be redundant but wanted to be safer..
-                mActiveKeyboardView.remove(position);
+                mActiveKeyboardViews.remove(position);
             }
             final Keyboard keyboard =
                     mEmojiCategory.getKeyboardFromPagePosition(position);
@@ -681,7 +682,7 @@
                     R.id.emoji_keyboard_scroller);
             keyboardView.setScrollView(scrollView);
             container.addView(view);
-            mActiveKeyboardView.put(position, keyboardView);
+            mActiveKeyboardViews.put(position, keyboardView);
             return view;
         }
 
@@ -693,12 +694,16 @@
         @Override
         public void destroyItem(final ViewGroup container, final int position,
                 final Object object) {
-            final ScrollKeyboardView keyboardView = mActiveKeyboardView.get(position);
+            final ScrollKeyboardView keyboardView = mActiveKeyboardViews.get(position);
             if (keyboardView != null) {
                 keyboardView.deallocateMemory();
-                mActiveKeyboardView.remove(position);
+                mActiveKeyboardViews.remove(position);
             }
-            container.removeView(keyboardView);
+            if (object instanceof View) {
+                container.removeView((View)object);
+            } else {
+                Log.w(TAG, "Warning!!! Emoji palette may be leaking. " + object);
+            }
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index aeb9e67..5578713 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -243,6 +243,8 @@
     }
 
     private void freeOffscreenBuffer() {
+        mOffscreenCanvas.setBitmap(null);
+        mOffscreenCanvas.setMatrix(null);
         if (mOffscreenBuffer != null) {
             mOffscreenBuffer.recycle();
             mOffscreenBuffer = null;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java
index b8ee976..9cf68d4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java
@@ -30,8 +30,9 @@
 import com.android.inputmethod.latin.R;
 
 /**
- * This is an extended {@link KeyboardView} class that hosts a scroll keyboard.
+ * This is an extended {@link KeyboardView} class that hosts a vertical scroll keyboard.
  * Multi-touch unsupported. No {@link PointerTracker}s. No gesture support.
+ * TODO: Vertical scroll capability should be removed from this class because it's no longer used.
  */
 // TODO: Implement key popup preview.
 public final class ScrollKeyboardView extends KeyboardView implements
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
index 3d07c9d..a8ea69f 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
@@ -360,11 +360,11 @@
     } else if (strncmp(query, MAX_UNIGRAM_COUNT_QUERY, maxResultLength) == 0) {
         snprintf(outResult, maxResultLength, "%d",
                 mHeaderPolicy.isDecayingDict() ? ForgettingCurveUtils::MAX_UNIGRAM_COUNT :
-                        DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE);
+                        static_cast<int>(DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE));
     } else if (strncmp(query, MAX_BIGRAM_COUNT_QUERY, maxResultLength) == 0) {
         snprintf(outResult, maxResultLength, "%d",
                 mHeaderPolicy.isDecayingDict() ? ForgettingCurveUtils::MAX_BIGRAM_COUNT :
-                        DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE);
+                        static_cast<int>(DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE));
     } else if (strncmp(query, SET_NEEDS_TO_DECAY_FOR_TESTING_QUERY, maxResultLength) == 0) {
         mNeedsToDecayForTesting = true;
     }
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index bd06e9f..e571bc2 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -183,7 +183,11 @@
                             filename + " does not seem to be a dictionary file"));
                 } else if (CombinedInputOutput.isCombinedDictionary(
                         decodedSpec.mFile.getAbsolutePath())){
-                    if (report) System.out.println("Format : Combined format");
+                    if (report) {
+                        System.out.println("Format : Combined format");
+                        System.out.println("Packaging : " + decodedSpec.describeChain());
+                        System.out.println("Uncompressed size : " + decodedSpec.mFile.length());
+                    }
                     return CombinedInputOutput.readDictionaryCombined(
                             new BufferedInputStream(new FileInputStream(decodedSpec.mFile)));
                 } else {