Merge "Fix SubtypeSwitcher initialization path" into jb-mr1-dev
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 70e38fd..039c77b 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -35,6 +35,7 @@
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.latin.CollectionUtils;
 
 /**
  * Exposes a virtual view sub-tree for {@link KeyboardView} and generates
@@ -55,7 +56,7 @@
     private final AccessibilityUtils mAccessibilityUtils;
 
     /** A map of integer IDs to {@link Key}s. */
-    private final SparseArray<Key> mVirtualViewIdToKey = new SparseArray<Key>();
+    private final SparseArray<Key> mVirtualViewIdToKey = CollectionUtils.newSparseArray();
 
     /** Temporary rect used to calculate in-screen bounds. */
     private final Rect mTempBoundsInScreen = new Rect();
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index a5429e9..e37868b 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -135,7 +135,7 @@
     public final Key[] mAltCodeKeysWhileTyping;
     public final KeyboardIconsSet mIconsSet;
 
-    private final SparseArray<Key> mKeyCache = new SparseArray<Key>();
+    private final SparseArray<Key> mKeyCache = CollectionUtils.newSparseArray();
 
     private final ProximityInfo mProximityInfo;
     private final boolean mProximityCharsCorrectionEnabled;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index 0cb8d86..76ac3de 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -117,7 +117,7 @@
         int mWidth;
         // Sparse array of KeyboardLayoutSet element parameters indexed by element's id.
         final SparseArray<ElementParams> mKeyboardLayoutSetElementIdToParamsMap =
-                new SparseArray<ElementParams>();
+                CollectionUtils.newSparseArray();
 
         static class ElementParams {
             int mKeyboardXmlId;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index c8f30e2..0a70605 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -107,6 +107,7 @@
 
     // Key preview
     private final int mKeyPreviewLayoutId;
+    private final SparseArray<TextView> mKeyPreviewTexts = CollectionUtils.newSparseArray();
     protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
     private boolean mShowKeyPreviewPopup = true;
     private int mDelayAfterPreview;
@@ -130,9 +131,9 @@
     private final Paint mPaint = new Paint();
     private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
     // This sparse array caches key label text height in pixel indexed by key label text size.
-    private static final SparseArray<Float> sTextHeightCache = new SparseArray<Float>();
+    private static final SparseArray<Float> sTextHeightCache = CollectionUtils.newSparseArray();
     // This sparse array caches key label text width in pixel indexed by key label text size.
-    private static final SparseArray<Float> sTextWidthCache = new SparseArray<Float>();
+    private static final SparseArray<Float> sTextWidthCache = CollectionUtils.newSparseArray();
     private static final char[] KEY_LABEL_REFERENCE_CHAR = { 'M' };
     private static final char[] KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR = { '8' };
 
@@ -152,7 +153,10 @@
             final PointerTracker tracker = (PointerTracker) msg.obj;
             switch (msg.what) {
             case MSG_DISMISS_KEY_PREVIEW:
-                tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
+                final TextView previewText = keyboardView.mKeyPreviewTexts.get(tracker.mPointerId);
+                if (previewText != null) {
+                    previewText.setVisibility(INVISIBLE);
+                }
                 break;
             }
         }
@@ -165,7 +169,7 @@
             removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
         }
 
-        public void cancelAllDismissKeyPreviews() {
+        private void cancelAllDismissKeyPreviews() {
             removeMessages(MSG_DISMISS_KEY_PREVIEW);
         }
 
@@ -907,15 +911,30 @@
         }
     }
 
-    // Called by {@link PointerTracker} constructor to create a TextView.
-    @Override
-    public TextView inflateKeyPreviewText() {
+    private TextView getKeyPreviewText(final int pointerId) {
+        TextView previewText = mKeyPreviewTexts.get(pointerId);
+        if (previewText != null) {
+            return previewText;
+        }
         final Context context = getContext();
         if (mKeyPreviewLayoutId != 0) {
-            return (TextView)LayoutInflater.from(context).inflate(mKeyPreviewLayoutId, null);
+            previewText = (TextView)LayoutInflater.from(context).inflate(mKeyPreviewLayoutId, null);
         } else {
-            return new TextView(context);
+            previewText = new TextView(context);
         }
+        mKeyPreviewTexts.put(pointerId, previewText);
+        return previewText;
+    }
+
+    private void dismissAllKeyPreviews() {
+        final int pointerCount = mKeyPreviewTexts.size();
+        for (int id = 0; id < pointerCount; id++) {
+            final TextView previewText = mKeyPreviewTexts.get(id);
+            if (previewText != null) {
+                previewText.setVisibility(INVISIBLE);
+            }
+        }
+        PointerTracker.setReleasedKeyGraphicsToAllKeys();
     }
 
     @Override
@@ -971,7 +990,7 @@
     public void showKeyPreview(PointerTracker tracker) {
         if (!mShowKeyPreviewPopup) return;
 
-        final TextView previewText = tracker.getKeyPreviewText();
+        final TextView previewText = getKeyPreviewText(tracker.mPointerId);
         // If the key preview has no parent view yet, add it to the ViewGroup which can place
         // key preview absolutely in SoftInputWindow.
         if (previewText.getParent() == null) {
@@ -1082,7 +1101,7 @@
     }
 
     public void closing() {
-        PointerTracker.dismissAllKeyPreviews();
+        dismissAllKeyPreviews();
         cancelAllMessages();
 
         mInvalidateAllKeys = true;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 9d95320..d9a7cb4 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -21,8 +21,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.MotionEvent;
-import android.view.View;
-import android.widget.TextView;
 
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.keyboard.internal.GestureStroke;
@@ -79,7 +77,6 @@
 
     public interface DrawingProxy extends MoreKeysPanel.Controller {
         public void invalidateKey(Key key);
-        public TextView inflateKeyPreviewText();
         public void showKeyPreview(PointerTracker tracker);
         public void dismissKeyPreview(PointerTracker tracker);
         public void showGestureTrail(PointerTracker tracker);
@@ -140,7 +137,6 @@
 
     private Keyboard mKeyboard;
     private int mKeyQuarterWidthSquared;
-    private final TextView mKeyPreviewText;
 
     private boolean mIsAlphabetKeyboard;
     private boolean mIsPossibleGesture = false;
@@ -261,11 +257,10 @@
         updateGestureHandlingMode();
     }
 
-    public static void dismissAllKeyPreviews() {
+    public static void setReleasedKeyGraphicsToAllKeys() {
         final int trackersSize = sTrackers.size();
         for (int i = 0; i < trackersSize; ++i) {
             final PointerTracker tracker = sTrackers.get(i);
-            tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
             tracker.setReleasedKeyGraphics(tracker.mCurrentKey);
         }
     }
@@ -312,11 +307,6 @@
         mListener = handler.getKeyboardActionListener();
         mDrawingProxy = handler.getDrawingProxy();
         mTimerProxy = handler.getTimerProxy();
-        mKeyPreviewText = mDrawingProxy.inflateKeyPreviewText();
-    }
-
-    public TextView getKeyPreviewText() {
-        return mKeyPreviewText;
     }
 
     // Returns true if keyboard has been changed by this callback.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 16fd715..e40cf45 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -91,7 +91,7 @@
 
     private class DeclaredKeyStyle extends KeyStyle {
         private final String mParentStyleName;
-        private final SparseArray<Object> mStyleAttributes = new SparseArray<Object>();
+        private final SparseArray<Object> mStyleAttributes = CollectionUtils.newSparseArray();
 
         public DeclaredKeyStyle(String parentStyleName) {
             mParentStyleName = parentStyleName;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
index 59a92d6..3f33aee 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
@@ -28,6 +28,7 @@
 import android.widget.RelativeLayout;
 
 import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
 
@@ -47,7 +48,7 @@
     private int mXOrigin;
     private int mYOrigin;
 
-    private final SparseArray<PointerTracker> mPointers = new SparseArray<PointerTracker>();
+    private final SparseArray<PointerTracker> mPointers = CollectionUtils.newSparseArray();
 
     private String mGestureFloatingPreviewText;
     private int mLastPointerX;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index c04a99b..8909526 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -63,7 +63,7 @@
     private final boolean mUseFullEditDistance;
 
     private final SparseArray<DicTraverseSession> mDicTraverseSessions =
-            new SparseArray<DicTraverseSession>();
+            CollectionUtils.newSparseArray();
 
     // TODO: There should be a way to remove used DicTraverseSession objects from
     // {@code mDicTraverseSessions}.
diff --git a/java/src/com/android/inputmethod/latin/CollectionUtils.java b/java/src/com/android/inputmethod/latin/CollectionUtils.java
index 789b79a..baa2ee1 100644
--- a/java/src/com/android/inputmethod/latin/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/CollectionUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import android.util.SparseArray;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -86,4 +88,8 @@
     public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(final E[] array) {
         return new CopyOnWriteArrayList<E>(array);
     }
+
+    public static <E> SparseArray<E> newSparseArray() {
+        return new SparseArray<E>();
+    }
 }