Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68cf2cd9 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Check all regexp patterns in ResourceUtils.getDeviceOverrideValue"

parents e168a3c2 4c75ea85
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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>
+58 −23
Original line number Diff line number Diff line
@@ -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);
+47 −37
Original line number Diff line number Diff line
@@ -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));
    }
}