diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 2159cf43d6d6d..9abb64f15e996 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7112,24 +7112,8 @@ public final class Settings { */ public static final String TTS_DEFAULT_LOCALE = "tts_default_locale"; - private static final Validator TTS_DEFAULT_LOCALE_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null || value.length() == 0) { - return false; - } - String[] ttsLocales = value.split(","); - boolean valid = true; - for (String ttsLocale : ttsLocales) { - String[] parts = ttsLocale.split(":"); - valid |= ((parts.length == 2) - && (parts[0].length() > 0) - && ANY_STRING_VALIDATOR.validate(parts[0]) - && LOCALE_VALIDATOR.validate(parts[1])); - } - return valid; - } - }; + private static final Validator TTS_DEFAULT_LOCALE_VALIDATOR = + new SettingsValidators.TTSListValidator(); /** * Space delimited list of plugin packages that are enabled. @@ -8649,25 +8633,13 @@ public final class Settings { /** * Holds comma separated list of ordering of QS tiles. + * * @hide */ public static final String QS_TILES = "sysui_qs_tiles"; - private static final Validator QS_TILES_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null) { - return false; - } - String[] tiles = value.split(","); - boolean valid = true; - for (String tile : tiles) { - // tile can be any non-empty string as specified by OEM - valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); - } - return valid; - } - }; + private static final Validator QS_TILES_VALIDATOR = + new SettingsValidators.TileListValidator(); /** * Specifies whether the web action API is enabled. @@ -8733,21 +8705,8 @@ public final class Settings { */ public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles"; - private static final Validator QS_AUTO_ADDED_TILES_VALIDATOR = new Validator() { - @Override - public boolean validate(@Nullable String value) { - if (value == null) { - return false; - } - String[] tiles = value.split(","); - boolean valid = true; - for (String tile : tiles) { - // tile can be any non-empty string as specified by OEM - valid |= ((tile.length() > 0) && ANY_STRING_VALIDATOR.validate(tile)); - } - return valid; - } - }; + private static final Validator QS_AUTO_ADDED_TILES_VALIDATOR = + new SettingsValidators.TileListValidator(); /** * Whether the Lockdown button should be shown in the power menu. diff --git a/core/java/android/provider/SettingsValidators.java b/core/java/android/provider/SettingsValidators.java index 405121378d1f1..e4cf9fd6aaee4 100644 --- a/core/java/android/provider/SettingsValidators.java +++ b/core/java/android/provider/SettingsValidators.java @@ -283,4 +283,50 @@ public class SettingsValidators { return true; } } + + private abstract static class ListValidator implements Validator { + public boolean validate(@Nullable String value) { + if (!isEntryValid(value)) { + return false; + } + String[] items = value.split(","); + for (String item : items) { + if (!isItemValid(item)) { + return false; + } + } + return true; + } + + protected abstract boolean isEntryValid(String entry); + + protected abstract boolean isItemValid(String item); + } + + /** Ensure a restored value is a string in the format the text-to-speech system handles */ + public static final class TTSListValidator extends ListValidator { + protected boolean isEntryValid(String entry) { + return entry != null && entry.length() > 0; + } + + protected boolean isItemValid(String item) { + String[] parts = item.split(":"); + // Replaces any old language separator (-) with the new one (_) + return ((parts.length == 2) + && (parts[0].length() > 0) + && ANY_STRING_VALIDATOR.validate(parts[0]) + && LOCALE_VALIDATOR.validate(parts[1].replace('-', '_'))); + } + } + + /** Ensure a restored value is suitable to be used as a tile name */ + public static final class TileListValidator extends ListValidator { + protected boolean isEntryValid(String entry) { + return entry != null; + } + + protected boolean isItemValid(String item) { + return item.length() > 0 && ANY_STRING_VALIDATOR.validate(item); + } + } } diff --git a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java index 8081e9e6c67bd..eea8c83e036ba 100644 --- a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java +++ b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java @@ -254,6 +254,55 @@ public class SettingsValidatorsTest { failIfOffendersPresent(offenders, "Settings.System"); } + @Test + public void testTTSListValidator_withValidInput_returnsTrue() { + Validator v = new SettingsValidators.TTSListValidator(); + + assertTrue(v.validate("com.foo.ttsengine:en-US,com.bar.ttsengine:es_ES")); + } + + @Test + public void testTTSListValidator_withInvalidInput_returnsFalse() { + Validator v = new SettingsValidators.TTSListValidator(); + + assertFalse(v.validate("com.foo.ttsengine:eng-USA,INVALID")); + } + + @Test + public void testTTSListValidator_withEmptyInput_returnsFalse() { + Validator v = new SettingsValidators.TTSListValidator(); + + assertFalse(v.validate("")); + } + + @Test + public void testTTSListValidator_withNullInput_returnsFalse() { + Validator v = new SettingsValidators.TTSListValidator(); + + assertFalse(v.validate(null)); + } + + @Test + public void testTileListValidator_withValidInput_returnsTrue() { + Validator v = new SettingsValidators.TileListValidator(); + + assertTrue(v.validate("1,2,3,4")); + } + + @Test + public void testTileListValidator_withMissingValue_returnsFalse() { + Validator v = new SettingsValidators.TileListValidator(); + + assertFalse(v.validate("1,,3")); + } + + @Test + public void testTileListValidator_withNullInput_returnsFalse() { + Validator v = new SettingsValidators.TileListValidator(); + + assertFalse(v.validate(null)); + } + @Test public void ensureAllBackedUpGlobalSettingsHaveValidators() { String offenders = getOffenders(concat(Settings.Global.SETTINGS_TO_BACKUP,