Merge "Some cleanup and reinforcement"
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index b21f300..2006a5c 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -50,23 +50,15 @@
     // to auto-correct, so we set this to the highest frequency that won't, i.e. 14.
     private static final int USER_DICT_SHORTCUT_FREQUENCY = 14;
 
-    // TODO: use Words.SHORTCUT when we target JellyBean or above
-    final static String SHORTCUT = "shortcut";
-    private static final String[] PROJECTION_QUERY;
-    static {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            PROJECTION_QUERY = new String[] {
-                Words.WORD,
-                SHORTCUT,
-                Words.FREQUENCY,
-            };
-        } else {
-            PROJECTION_QUERY = new String[] {
-                Words.WORD,
-                Words.FREQUENCY,
-            };
-        }
-    }
+    private static final String[] PROJECTION_QUERY_WITH_SHORTCUT = new String[] {
+        Words.WORD,
+        Words.SHORTCUT,
+        Words.FREQUENCY,
+    };
+    private static final String[] PROJECTION_QUERY_WITHOUT_SHORTCUT = new String[] {
+        Words.WORD,
+        Words.FREQUENCY,
+    };
 
     private static final String NAME = "userunigram";
 
@@ -179,10 +171,29 @@
         } else {
             requestArguments = localeElements;
         }
+        final String requestString = request.toString();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+            try {
+                addWordsFromProjectionLocked(PROJECTION_QUERY_WITH_SHORTCUT, requestString,
+                        requestArguments);
+            } catch (IllegalArgumentException e) {
+                // This may happen on some non-compliant devices where the declared API is JB+ but
+                // the SHORTCUT column is not present for some reason.
+                addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString,
+                        requestArguments);
+            }
+        } else {
+            addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString,
+                    requestArguments);
+        }
+    }
+
+    private void addWordsFromProjectionLocked(final String[] query, String request,
+            final String[] requestArguments) throws IllegalArgumentException {
         Cursor cursor = null;
         try {
             cursor = mContext.getContentResolver().query(
-                Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+                    Words.CONTENT_URI, query, request, requestArguments, null);
             addWordsLocked(cursor);
         } catch (final SQLiteException e) {
             Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
@@ -239,7 +250,7 @@
         if (cursor == null) return;
         if (cursor.moveToFirst()) {
             final int indexWord = cursor.getColumnIndex(Words.WORD);
-            final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(SHORTCUT) : 0;
+            final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(Words.SHORTCUT) : 0;
             final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY);
             while (!cursor.isAfterLast()) {
                 final String word = cursor.getString(indexWord);