Check all regexp patterns in ResourceUtils.getDeviceOverrideValue
This change also fixes a regexp error of Galaxy S III. Change-Id: I42a4780bbfd2b083f4e27e61ec513aa875907344main
parent
a2d8d30f8e
commit
4c75ea858a
|
@ -37,7 +37,7 @@
|
|||
<item>MODEL=(SAMSUNG-)?GT-I(930[05][NT]?|9308):MANUFACTURER=samsung,8</item>
|
||||
<item>MODEL=(SAMSUNG-)?SGH-(T999[V]?|I747[M]?|N064|N035):MANUFACTURER=samsung,8</item>
|
||||
<item>MODEL=(SAMSUNG-)?SCH-(J021|R530|I535|I939):MANUFACTURER=samsung,8</item>
|
||||
<item>MODEL=(SAMSUNG-)?(SCL21|SC-06D|SC-03E]):MANUFACTURER=samsung,8</item>
|
||||
<item>MODEL=(SAMSUNG-)?(SCL21|SC-06D|SC-03E):MANUFACTURER=samsung,8</item>
|
||||
<item>MODEL=(SAMSUNG-)?(SHV-210[KLS]?|SPH-L710):MANUFACTURER=samsung,8</item>
|
||||
<!-- LG Optimus G -->
|
||||
<item>MODEL=LG-E97[013]|LS970|L-01E:MANUFACTURER=LGE,15</item>
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public final class ResourceUtils {
|
||||
private static final String TAG = ResourceUtils.class.getSimpleName();
|
||||
|
@ -83,7 +84,9 @@ public final class ResourceUtils {
|
|||
return overrideValue;
|
||||
}
|
||||
|
||||
final String defaultValue = findDefaultConstant(overrideArray);
|
||||
String defaultValue = null;
|
||||
try {
|
||||
defaultValue = findDefaultConstant(overrideArray);
|
||||
// The defaultValue might be an empty string.
|
||||
if (defaultValue == null) {
|
||||
Log.w(TAG, "Couldn't find override value nor default value:"
|
||||
|
@ -95,10 +98,25 @@ public final class ResourceUtils {
|
|||
+ " build=" + sBuildKeyValuesDebugString
|
||||
+ " default=" + defaultValue);
|
||||
}
|
||||
} catch (final DeviceOverridePatternSyntaxError e) {
|
||||
Log.w(TAG, "Syntax error, ignored", e);
|
||||
}
|
||||
sDeviceOverrideValueMap.put(key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class DeviceOverridePatternSyntaxError extends Exception {
|
||||
public DeviceOverridePatternSyntaxError(final String message, final String expression) {
|
||||
this(message, expression, null);
|
||||
}
|
||||
|
||||
public DeviceOverridePatternSyntaxError(final String message, final String expression,
|
||||
final Throwable throwable) {
|
||||
super(message + ": " + expression, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the condition that fulfills specified key value pairs from an array of
|
||||
* "condition,constant", and return the corresponding string constant. A condition is
|
||||
|
@ -123,10 +141,12 @@ public final class ResourceUtils {
|
|||
if (conditionConstantArray == null || keyValuePairs == null) {
|
||||
return null;
|
||||
}
|
||||
String foundValue = null;
|
||||
for (final String conditionConstant : conditionConstantArray) {
|
||||
final int posComma = conditionConstant.indexOf(',');
|
||||
if (posComma < 0) {
|
||||
throw new RuntimeException("Array element has no comma: " + conditionConstant);
|
||||
Log.w(TAG, "Array element has no comma: " + conditionConstant);
|
||||
continue;
|
||||
}
|
||||
final String condition = conditionConstant.substring(0, posComma);
|
||||
if (condition.isEmpty()) {
|
||||
|
@ -134,44 +154,59 @@ public final class ResourceUtils {
|
|||
// {@link #findConstantForDefault(String[])}.
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (fulfillsCondition(keyValuePairs, condition)) {
|
||||
return conditionConstant.substring(posComma + 1);
|
||||
// Take first match
|
||||
if (foundValue == null) {
|
||||
foundValue = conditionConstant.substring(posComma + 1);
|
||||
}
|
||||
// And continue walking through all conditions.
|
||||
}
|
||||
} catch (final DeviceOverridePatternSyntaxError e) {
|
||||
Log.w(TAG, "Syntax error, ignored", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return foundValue;
|
||||
}
|
||||
|
||||
private static boolean fulfillsCondition(final HashMap<String,String> keyValuePairs,
|
||||
final String condition) {
|
||||
final String condition) throws DeviceOverridePatternSyntaxError {
|
||||
final String[] patterns = condition.split(":");
|
||||
// Check all patterns in a condition are true
|
||||
boolean matchedAll = true;
|
||||
for (final String pattern : patterns) {
|
||||
final int posEqual = pattern.indexOf('=');
|
||||
if (posEqual < 0) {
|
||||
throw new RuntimeException("Pattern has no '=': " + condition);
|
||||
throw new DeviceOverridePatternSyntaxError("Pattern has no '='", condition);
|
||||
}
|
||||
final String key = pattern.substring(0, posEqual);
|
||||
final String value = keyValuePairs.get(key);
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Found unknown key: " + condition);
|
||||
throw new DeviceOverridePatternSyntaxError("Unknown key", condition);
|
||||
}
|
||||
final String patternRegexpValue = pattern.substring(posEqual + 1);
|
||||
try {
|
||||
if (!value.matches(patternRegexpValue)) {
|
||||
return false;
|
||||
matchedAll = false;
|
||||
// And continue walking through all patterns.
|
||||
}
|
||||
} catch (final PatternSyntaxException e) {
|
||||
throw new DeviceOverridePatternSyntaxError("Syntax error", condition, e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return matchedAll;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
static String findDefaultConstant(final String[] conditionConstantArray) {
|
||||
static String findDefaultConstant(final String[] conditionConstantArray)
|
||||
throws DeviceOverridePatternSyntaxError {
|
||||
if (conditionConstantArray == null) {
|
||||
return null;
|
||||
}
|
||||
for (final String condition : conditionConstantArray) {
|
||||
final int posComma = condition.indexOf(',');
|
||||
if (posComma < 0) {
|
||||
throw new RuntimeException("Array element has no comma: " + condition);
|
||||
throw new DeviceOverridePatternSyntaxError("Array element has no comma", condition);
|
||||
}
|
||||
if (posComma == 0) { // condition is empty.
|
||||
return condition.substring(posComma + 1);
|
||||
|
|
|
@ -19,17 +19,15 @@ package com.android.inputmethod.latin;
|
|||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.inputmethod.latin.ResourceUtils.DeviceOverridePatternSyntaxError;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@SmallTest
|
||||
public class ResourceUtilsTests extends AndroidTestCase {
|
||||
public void testFindDefaultConstant() {
|
||||
final String[] nullArray = null;
|
||||
assertNull(ResourceUtils.findDefaultConstant(nullArray));
|
||||
|
||||
final String[] emptyArray = {};
|
||||
assertNull(ResourceUtils.findDefaultConstant(emptyArray));
|
||||
|
||||
final String[] array = {
|
||||
"HARDWARE=grouper,0.3",
|
||||
"HARDWARE=mako,0.4",
|
||||
|
@ -37,7 +35,25 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
"HARDWARE=manta,0.2",
|
||||
",defaultValue2",
|
||||
};
|
||||
|
||||
try {
|
||||
assertNull(ResourceUtils.findDefaultConstant(nullArray));
|
||||
assertNull(ResourceUtils.findDefaultConstant(emptyArray));
|
||||
assertEquals(ResourceUtils.findDefaultConstant(array), "defaultValue1");
|
||||
} catch (final DeviceOverridePatternSyntaxError e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
final String[] errorArray = {
|
||||
"HARDWARE=grouper,0.3",
|
||||
"no_comma"
|
||||
};
|
||||
try {
|
||||
final String defaultValue = ResourceUtils.findDefaultConstant(errorArray);
|
||||
fail("exception should be thrown: defaultValue=" + defaultValue);
|
||||
} catch (final DeviceOverridePatternSyntaxError e) {
|
||||
assertEquals("Array element has no comma: no_comma", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testFindConstantForKeyValuePairsSimple() {
|
||||
|
@ -67,33 +83,23 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
|
||||
final HashMap<String,String> keyValues = CollectionUtils.newHashMap();
|
||||
keyValues.put(HARDWARE_KEY, "grouper");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.3");
|
||||
assertEquals("0.3", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "mako");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.4");
|
||||
assertEquals("0.4", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "manta");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.2");
|
||||
assertEquals("0.2", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
|
||||
try {
|
||||
keyValues.clear();
|
||||
keyValues.put("hardware", "grouper");
|
||||
final String constant = ResourceUtils.findConstantForKeyValuePairs(keyValues, array);
|
||||
fail("condition without HARDWARE must fail: constant=" + constant);
|
||||
} catch (final RuntimeException e) {
|
||||
assertEquals(e.getMessage(), "Found unknown key: HARDWARE=grouper");
|
||||
}
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
|
||||
keyValues.clear();
|
||||
keyValues.put(HARDWARE_KEY, "MAKO");
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "mantaray");
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
|
||||
try {
|
||||
final String constant = ResourceUtils.findConstantForKeyValuePairs(
|
||||
emptyKeyValue, array);
|
||||
fail("emptyCondition shouldn't match: constant=" + constant);
|
||||
} catch (final RuntimeException e) {
|
||||
assertEquals(e.getMessage(), "Found unknown key: HARDWARE=grouper");
|
||||
}
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(emptyKeyValue, array));
|
||||
}
|
||||
|
||||
public void testFindConstantForKeyValuePairsCombined() {
|
||||
|
@ -102,6 +108,8 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
final String MANUFACTURER_KEY = "MANUFACTURER";
|
||||
final String[] array = {
|
||||
",defaultValue",
|
||||
"no_comma",
|
||||
"error_pattern,0.1",
|
||||
"HARDWARE=grouper:MANUFACTURER=asus,0.3",
|
||||
"HARDWARE=mako:MODEL=Nexus 4,0.4",
|
||||
"HARDWARE=manta:MODEL=Nexus 10:MANUFACTURER=samsung,0.2"
|
||||
|
@ -117,25 +125,25 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
keyValues.put(HARDWARE_KEY, "grouper");
|
||||
keyValues.put(MODEL_KEY, "Nexus 7");
|
||||
keyValues.put(MANUFACTURER_KEY, "asus");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.3");
|
||||
assertEquals("0.3", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, failArray));
|
||||
|
||||
keyValues.clear();
|
||||
keyValues.put(HARDWARE_KEY, "mako");
|
||||
keyValues.put(MODEL_KEY, "Nexus 4");
|
||||
keyValues.put(MANUFACTURER_KEY, "LGE");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.4");
|
||||
assertEquals("0.4", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, failArray));
|
||||
|
||||
keyValues.clear();
|
||||
keyValues.put(HARDWARE_KEY, "manta");
|
||||
keyValues.put(MODEL_KEY, "Nexus 10");
|
||||
keyValues.put(MANUFACTURER_KEY, "samsung");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.2");
|
||||
assertEquals("0.2", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, failArray));
|
||||
keyValues.put(HARDWARE_KEY, "mantaray");
|
||||
assertNull(ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, failArray), "0.2");
|
||||
assertEquals("0.2", ResourceUtils.findConstantForKeyValuePairs(keyValues, failArray));
|
||||
}
|
||||
|
||||
public void testFindConstantForKeyValuePairsRegexp() {
|
||||
|
@ -144,6 +152,8 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
final String MANUFACTURER_KEY = "MANUFACTURER";
|
||||
final String[] array = {
|
||||
",defaultValue",
|
||||
"no_comma",
|
||||
"HARDWARE=error_regexp:MANUFACTURER=error[regexp,0.1",
|
||||
"HARDWARE=grouper|tilapia:MANUFACTURER=asus,0.3",
|
||||
"HARDWARE=[mM][aA][kK][oO]:MODEL=Nexus 4,0.4",
|
||||
"HARDWARE=manta.*:MODEL=Nexus 10:MANUFACTURER=samsung,0.2"
|
||||
|
@ -153,24 +163,24 @@ public class ResourceUtilsTests extends AndroidTestCase {
|
|||
keyValues.put(HARDWARE_KEY, "grouper");
|
||||
keyValues.put(MODEL_KEY, "Nexus 7");
|
||||
keyValues.put(MANUFACTURER_KEY, "asus");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.3");
|
||||
assertEquals("0.3", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "tilapia");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.3");
|
||||
assertEquals("0.3", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
|
||||
keyValues.clear();
|
||||
keyValues.put(HARDWARE_KEY, "mako");
|
||||
keyValues.put(MODEL_KEY, "Nexus 4");
|
||||
keyValues.put(MANUFACTURER_KEY, "LGE");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.4");
|
||||
assertEquals("0.4", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "MAKO");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.4");
|
||||
assertEquals("0.4", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
|
||||
keyValues.clear();
|
||||
keyValues.put(HARDWARE_KEY, "manta");
|
||||
keyValues.put(MODEL_KEY, "Nexus 10");
|
||||
keyValues.put(MANUFACTURER_KEY, "samsung");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.2");
|
||||
assertEquals("0.2", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
keyValues.put(HARDWARE_KEY, "mantaray");
|
||||
assertEquals(ResourceUtils.findConstantForKeyValuePairs(keyValues, array), "0.2");
|
||||
assertEquals("0.2", ResourceUtils.findConstantForKeyValuePairs(keyValues, array));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue