Merge "Refactor StringUtils.findPrefixedString to findValueOfKey"
diff --git a/java/res/values/keyboard-heights.xml b/java/res/values/keyboard-heights.xml
index 418d3e5..1c0277c 100644
--- a/java/res/values/keyboard-heights.xml
+++ b/java/res/values/keyboard-heights.xml
@@ -19,20 +19,20 @@
 -->
 
 <resources>
-    <!-- Build.HARDWARE,keyboard_height_in_dp -->
+    <!-- Build condition,keyboard_height_in_dp -->
     <string-array name="keyboard_heights" translatable="false">
     <!-- Preferable keyboard height in absolute scale: 1.285in -->
         <!-- Droid -->
-        <item>sholes,227.0167</item>
+        <item>HARDWARE=sholes,227.0167</item>
         <!-- Nexus One -->
-        <item>mahimahi,217.5932</item>
+        <item>HARDWARE=mahimahi,217.5932</item>
         <!-- Nexus S -->
-        <item>herring,200.8554</item>
+        <item>HARDWARE=herring,200.8554</item>
         <!-- Galaxy Nexus -->
-        <item>tuna,202.5869</item>
+        <item>HARDWARE=tuna,202.5869</item>
     <!-- Preferable keyboard height in absolute scale: 48.0mm -->
         <!-- Xoom -->
-        <item>stingray,283.1337</item>
+        <item>HARDWARE=stingray,283.1337</item>
     <!-- Default value for unknown device: empty string -->
         <item>DEFAULT,</item>
     </string-array>
diff --git a/java/res/values/keypress-vibration-durations.xml b/java/res/values/keypress-vibration-durations.xml
index 10400be..45c51e7 100644
--- a/java/res/values/keypress-vibration-durations.xml
+++ b/java/res/values/keypress-vibration-durations.xml
@@ -18,16 +18,16 @@
 */
 -->
 <resources>
-    <!-- Build.HARDWARE,duration_in_milliseconds -->
+    <!-- Build condition,duration_in_milliseconds -->
     <string-array name="keypress_vibration_durations" translatable="false">
         <!-- Nexus S -->
-        <item>herring,5</item>
+        <item>HARDWARE=herring,5</item>
         <!-- Galaxy Nexus -->
-        <item>tuna,5</item>
+        <item>HARDWARE=tuna,5</item>
         <!-- Nexus 4 -->
-        <item>mako,5</item>
+        <item>HARDWARE=mako,5</item>
         <!-- Nexus 10 -->
-        <item>manta,16</item>
+        <item>HARDWARE=manta,16</item>
         <!-- Default value for unknown device -->
         <item>DEFAULT,20</item>
     </string-array>
diff --git a/java/res/values/keypress-volumes.xml b/java/res/values/keypress-volumes.xml
index 047fe0c..7061f13 100644
--- a/java/res/values/keypress-volumes.xml
+++ b/java/res/values/keypress-volumes.xml
@@ -18,14 +18,14 @@
 */
 -->
 <resources>
+    <!-- Build condition,volume -->
     <string-array name="keypress_volumes" translatable="false">
-        <!-- Build.HARDWARE,volume -->
-        <item>herring,0.5f</item>
-        <item>tuna,0.5f</item>
-        <item>stingray,0.4f</item>
-        <item>grouper,0.3f</item>
-        <item>mako,0.3f</item>
-        <item>manta,0.2f</item>
+        <item>HARDWARE=herring,0.5f</item>
+        <item>HARDWARE=tuna,0.5f</item>
+        <item>HARDWARE=stingray,0.4f</item>
+        <item>HARDWARE=grouper,0.3f</item>
+        <item>HARDWARE=mako,0.3f</item>
+        <item>HARDWARE=manta,0.2f</item>
         <!-- Default value for unknown device -->
         <item>DEFAULT,0.2f</item>
     </string-array>
diff --git a/java/res/values/phantom-sudden-move-event-device-list.xml b/java/res/values/phantom-sudden-move-event-device-list.xml
index 22f5102..d0895b1 100644
--- a/java/res/values/phantom-sudden-move-event-device-list.xml
+++ b/java/res/values/phantom-sudden-move-event-device-list.xml
@@ -19,10 +19,10 @@
 -->
 <resources>
     <string-array name="phantom_sudden_move_event_device_list" translatable="false">
-        <!-- "Build.HARDWARE,true" that needs "phantom sudden move event" hack.
+        <!-- "Build condition,true" that needs "phantom sudden move event" hack.
              See {@link com.android.inputmethod.keyboard.PointerTracker}. -->
         <!-- Xoom -->
-        <item>stingray,true</item>
+        <item>HARDWARE=stingray,true</item>
         <!-- Default value for unknown device -->
         <item>DEFAULT,false</item>
     </string-array>
diff --git a/java/res/values/sudden-jumping-touch-event-device-list.xml b/java/res/values/sudden-jumping-touch-event-device-list.xml
index 3fdc0c7..73e30c1 100644
--- a/java/res/values/sudden-jumping-touch-event-device-list.xml
+++ b/java/res/values/sudden-jumping-touch-event-device-list.xml
@@ -19,12 +19,12 @@
 -->
 <resources>
     <string-array name="sudden_jumping_touch_event_device_list" translatable="false">
-        <!-- "Build.HARDWARE,true" that needs "sudden jump touch event" hack.
+        <!-- "Build condition,true" that needs "sudden jump touch event" hack.
              See {@link com.android.inputmethod.keyboard.SuddenJumpingTouchEventHandler}. -->
         <!-- Nexus One -->
-        <item>mahimahi,true</item>
+        <item>HARDWARE=mahimahi,true</item>
         <!-- Droid -->
-        <item>sholes,true</item>
+        <item>HARDWARE=sholes,true</item>
         <!-- Default value for unknown device -->
         <item>DEFAULT,false</item>
     </string-array>
diff --git a/java/src/com/android/inputmethod/latin/ResourceUtils.java b/java/src/com/android/inputmethod/latin/ResourceUtils.java
index b74b979..f0bfe75 100644
--- a/java/src/com/android/inputmethod/latin/ResourceUtils.java
+++ b/java/src/com/android/inputmethod/latin/ResourceUtils.java
@@ -35,8 +35,7 @@
         // This utility class is not publicly instantiable.
     }
 
-    private static final String DEFAULT_PREFIX = "DEFAULT,";
-    private static final String HARDWARE_PREFIX = Build.HARDWARE + ",";
+    private static final String DEFAULT_KEY = "DEFAULT";
     private static final HashMap<String, String> sDeviceOverrideValueMap =
             CollectionUtils.newHashMap();
 
@@ -48,28 +47,29 @@
         }
 
         final String[] overrideArray = res.getStringArray(overrideResId);
-        final String overrideValue = StringUtils.findPrefixedString(HARDWARE_PREFIX, overrideArray);
+        final String hardwareKey = "HARDWARE=" + Build.HARDWARE;
+        final String overrideValue = StringUtils.findValueOfKey(hardwareKey, overrideArray);
         // The overrideValue might be an empty string.
         if (overrideValue != null) {
             if (DEBUG) {
                 Log.d(TAG, "Find override value:"
                         + " resource="+ res.getResourceEntryName(overrideResId)
-                        + " Build.HARDWARE=" + Build.HARDWARE + " override=" + overrideValue);
+                        + " " + hardwareKey + " override=" + overrideValue);
             }
             sDeviceOverrideValueMap.put(key, overrideValue);
             return overrideValue;
         }
 
-        final String defaultValue = StringUtils.findPrefixedString(DEFAULT_PREFIX, overrideArray);
+        final String defaultValue = StringUtils.findValueOfKey(DEFAULT_KEY, overrideArray);
         // The defaultValue might be an empty string.
         if (defaultValue == null) {
             Log.w(TAG, "Couldn't find override value nor default value:"
                     + " resource="+ res.getResourceEntryName(overrideResId)
-                    + " Build.HARDWARE=" + Build.HARDWARE);
+                    + " " + hardwareKey);
         } else if (DEBUG) {
             Log.d(TAG, "Found default value:"
                 + " resource="+ res.getResourceEntryName(overrideResId)
-                + " Build.HARDWARE=" + Build.HARDWARE + " default=" + defaultValue);
+                + " " + hardwareKey + " " + DEFAULT_KEY + "=" + defaultValue);
         }
         sDeviceOverrideValueMap.put(key, defaultValue);
         return defaultValue;
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index d5ee58a..5ff101f 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -65,17 +65,24 @@
     }
 
     /**
-     * Find a string that start with specified prefix from an array.
+     * Find a value that has a specified key from an array of key-comma-value.
      *
-     * @param prefix a prefix string to find.
-     * @param array an string array to be searched.
-     * @return the rest part of the string that starts with the prefix.
+     * @param key a key string to find.
+     * @param array an array of key-comma-value string to be searched.
+     * @return the value part of the first string that has a specified key.
      * Returns null if it couldn't be found.
      */
-    public static String findPrefixedString(final String prefix, final String[] array) {
+    public static String findValueOfKey(final String key, final String[] array) {
+        if (array == null) {
+            return null;
+        }
         for (final String element : array) {
-            if (element.startsWith(prefix)) {
-                return element.substring(prefix.length());
+            final int posComma = element.indexOf(',');
+            if (posComma < 0) {
+                throw new RuntimeException("Element has no comma: " + element);
+            }
+            if (element.substring(0, posComma).equals(key)) {
+                return element.substring(posComma + 1);
             }
         }
         return null;
diff --git a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
index 1e3cc8a..b6a17a3 100644
--- a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
@@ -237,4 +237,63 @@
         // code for now True is acceptable.
         assertTrue(StringUtils.lastPartLooksLikeURL(".abc/def"));
     }
+
+    public void testFindValueOfKey() {
+        final String nullKey = null;
+        final String emptyKey = "";
+
+        final String[] nullArray = null;
+        assertNull(StringUtils.findValueOfKey("anyKey", nullArray));
+        assertNull(StringUtils.findValueOfKey(emptyKey, nullArray));
+        assertNull(StringUtils.findValueOfKey(nullKey, nullArray));
+
+        final String[] emptyArray = {};
+        assertNull(StringUtils.findValueOfKey("anyKey", emptyArray));
+        assertNull(StringUtils.findValueOfKey(emptyKey, emptyArray));
+        assertNull(StringUtils.findValueOfKey(nullKey, emptyArray));
+
+        final String[] array = {
+            "DEFAULT,defaultValue",
+            "HARDWARE=grouper,0.3",
+            "HARDWARE=mako,0.4",
+            "HARDWARE=manta,0.2"
+        };
+        assertEquals(StringUtils.findValueOfKey("HARDWARE=grouper", array), "0.3");
+        assertEquals(StringUtils.findValueOfKey("HARDWARE=mako", array), "0.4");
+        assertEquals(StringUtils.findValueOfKey("HARDWARE=manta", array), "0.2");
+        assertEquals(StringUtils.findValueOfKey("DEFAULT", array), "defaultValue");
+
+        assertNull(StringUtils.findValueOfKey("hardware=grouper", array));
+        assertNull(StringUtils.findValueOfKey("HARDWARE=MAKO", array));
+        assertNull(StringUtils.findValueOfKey("HARDWARE=mantaray", array));
+        assertNull(StringUtils.findValueOfKey(emptyKey, array));
+        assertNull(StringUtils.findValueOfKey(nullKey, array));
+
+        final String[] containsNullKey = {
+            "DEFAULT,defaultValue",
+            ",emptyValue"
+        };
+        assertEquals(StringUtils.findValueOfKey(emptyKey, containsNullKey), "emptyValue");
+
+        final String[] containsMultipleSameKeys = {
+            "key1,value1",
+            "key2,value2",
+            "key3,value3",
+            "key2,value4"
+        };
+        assertEquals(StringUtils.findValueOfKey("key2", containsMultipleSameKeys), "value2");
+
+        final String[] containNoCommaElement = {
+            "key1,value1",
+            "key2-and-value2",
+            "key3,value3"
+        };
+        assertEquals(StringUtils.findValueOfKey("key1", containNoCommaElement), "value1");
+        try {
+            final String valueOfKey3 = StringUtils.findValueOfKey("key3", containNoCommaElement);
+            fail("finding valueOfKey3=" + valueOfKey3 + " must fail");
+        } catch (final RuntimeException e) {
+            assertEquals(e.getMessage(), "Element has no comma: key2-and-value2");
+        }
+    }
 }