diff options
4 files changed, 192 insertions, 17 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3cc5fd788915..3a4a52a021bf 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -16,10 +16,12 @@ package android.provider; +import static android.provider.SettingsValidators.ANY_STRING_VALIDATOR; import static android.provider.SettingsValidators.BOOLEAN_VALIDATOR; import static android.provider.SettingsValidators.COMPONENT_NAME_VALIDATOR; import static android.provider.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR; import static android.provider.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR; +import static android.provider.SettingsValidators.PACKAGE_NAME_VALIDATOR; import static android.provider.SettingsValidators.URI_VALIDATOR; import android.Manifest; @@ -4279,6 +4281,8 @@ public final class Settings { @Deprecated public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead */ @@ -4356,6 +4360,8 @@ public final class Settings { @Deprecated public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; + private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead */ @@ -4385,6 +4391,9 @@ public final class Settings { public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * @deprecated Use * {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} instead @@ -5162,6 +5171,8 @@ public final class Settings { @Deprecated public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; + private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} instead */ @@ -5224,6 +5235,8 @@ public final class Settings { @Deprecated public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON; + private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead */ @@ -5651,6 +5664,8 @@ public final class Settings { @Deprecated public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED; + private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead */ @@ -6118,6 +6133,9 @@ public final class Settings { public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; + private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} * instead. @@ -7843,6 +7861,8 @@ public final class Settings { */ public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled"; + private static final Validator CHARGING_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * Whether we keep the device on while the device is plugged in. * Supported values are: @@ -7887,6 +7907,8 @@ public final class Settings { */ public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; + private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR; + /** * Whether ADB is enabled. */ @@ -7910,6 +7932,8 @@ public final class Settings { */ public static final String BLUETOOTH_ON = "bluetooth_on"; + private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR; + /** * CDMA Cell Broadcast SMS * 0 = CDMA Cell Broadcast SMS disabled @@ -8528,6 +8552,8 @@ public final class Settings { */ public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled"; + private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * If this setting is set (to anything), then all references * to Gmail on the device must change to Google Mail. @@ -8664,6 +8690,9 @@ public final class Settings { public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; + private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR = + BOOLEAN_VALIDATOR; + /** * {@hide} */ @@ -8726,6 +8755,8 @@ public final class Settings { */ public static final String SOFT_AP_TIMEOUT_ENABLED = "soft_ap_timeout_enabled"; + private static final Validator SOFT_AP_TIMEOUT_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * Value to specify if Wi-Fi Wakeup feature is enabled. * @@ -8735,6 +8766,8 @@ public final class Settings { @SystemApi public static final String WIFI_WAKEUP_ENABLED = "wifi_wakeup_enabled"; + private static final Validator WIFI_WAKEUP_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * Value to specify if Wi-Fi Wakeup is available. * @@ -8781,6 +8814,9 @@ public final class Settings { public static final String NETWORK_RECOMMENDATIONS_ENABLED = "network_recommendations_enabled"; + private static final Validator NETWORK_RECOMMENDATIONS_ENABLED_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[] {"-1", "0", "1"}); + /** * Which package name to use for network recommendations. If null, network recommendations * will neither be requested nor accepted. @@ -8804,6 +8840,13 @@ public final class Settings { @TestApi public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package"; + private static final Validator USE_OPEN_WIFI_PACKAGE_VALIDATOR = new Validator() { + @Override + public boolean validate(String value) { + return (value == null) || PACKAGE_NAME_VALIDATOR.validate(value); + } + }; + /** * The number of milliseconds the {@link com.android.server.NetworkScoreService} * will give a recommendation request to complete before returning a default response. @@ -8883,6 +8926,9 @@ public final class Settings { public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED = "wifi_watchdog_poor_network_test_enabled"; + private static final Validator WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED_VALIDATOR = + ANY_STRING_VALIDATOR; + /** * Setting to turn on suspend optimizations at screen off on Wi-Fi. Enabled by default and * needs to be set to 0 to disable it. @@ -9418,11 +9464,16 @@ public final class Settings { * @hide */ public static final String PRIVATE_DNS_MODE = "private_dns_mode"; + + private static final Validator PRIVATE_DNS_MODE_VALIDATOR = ANY_STRING_VALIDATOR; + /** * @hide */ public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier"; + private static final Validator PRIVATE_DNS_SPECIFIER_VALIDATOR = ANY_STRING_VALIDATOR; + /** {@hide} */ public static final String BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_"; @@ -9987,6 +10038,9 @@ public final class Settings { */ public static final String EMERGENCY_TONE = "emergency_tone"; + private static final Validator EMERGENCY_TONE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1", "2"}); + /** * CDMA only settings * Whether the auto retry is enabled. The value is @@ -9995,6 +10049,8 @@ public final class Settings { */ public static final String CALL_AUTO_RETRY = "call_auto_retry"; + private static final Validator CALL_AUTO_RETRY_VALIDATOR = BOOLEAN_VALIDATOR; + /** * A setting that can be read whether the emergency affordance is currently needed. * The value is a boolean (1 or 0). @@ -10064,6 +10120,9 @@ public final class Settings { */ public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level"; + private static final Validator LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 99); + /** * If not 0, the activity manager will aggressively finish activities and * processes as soon as they are no longer needed. If 0, the normal @@ -10079,6 +10138,8 @@ public final class Settings { */ public static final String DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled"; + private static final Validator DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** * The surround sound formats AC3, DTS or IEC61937 are * available for use if they are detected. @@ -10125,6 +10186,9 @@ public final class Settings { */ public static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output"; + private static final Validator ENCODED_SURROUND_OUTPUT_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1", "2"}); + /** * Persisted safe headphone volume management state by AudioService * @hide @@ -10665,6 +10729,41 @@ public final class Settings { }; /** + * All settings in {@link SETTINGS_TO_BACKUP} array *must* have a non-null validator, + * otherwise they won't be restored. + * + * @hide + */ + public static final Map<String, Validator> VALIDATORS = new ArrayMap<>(); + static { + VALIDATORS.put(BUGREPORT_IN_POWER_MENU, BUGREPORT_IN_POWER_MENU_VALIDATOR); + VALIDATORS.put(STAY_ON_WHILE_PLUGGED_IN, STAY_ON_WHILE_PLUGGED_IN_VALIDATOR); + VALIDATORS.put(AUTO_TIME, AUTO_TIME_VALIDATOR); + VALIDATORS.put(AUTO_TIME_ZONE, AUTO_TIME_ZONE_VALIDATOR); + VALIDATORS.put(POWER_SOUNDS_ENABLED, POWER_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(DOCK_SOUNDS_ENABLED, DOCK_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(CHARGING_SOUNDS_ENABLED, CHARGING_SOUNDS_ENABLED_VALIDATOR); + VALIDATORS.put(USB_MASS_STORAGE_ENABLED, USB_MASS_STORAGE_ENABLED_VALIDATOR); + VALIDATORS.put(NETWORK_RECOMMENDATIONS_ENABLED, + NETWORK_RECOMMENDATIONS_ENABLED_VALIDATOR); + VALIDATORS.put(WIFI_WAKEUP_ENABLED, WIFI_WAKEUP_ENABLED_VALIDATOR); + VALIDATORS.put(WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, + WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR); + VALIDATORS.put(USE_OPEN_WIFI_PACKAGE, USE_OPEN_WIFI_PACKAGE_VALIDATOR); + VALIDATORS.put(WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED, + WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED_VALIDATOR); + VALIDATORS.put(EMERGENCY_TONE, EMERGENCY_TONE_VALIDATOR); + VALIDATORS.put(CALL_AUTO_RETRY, CALL_AUTO_RETRY_VALIDATOR); + VALIDATORS.put(DOCK_AUDIO_MEDIA_ENABLED, DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR); + VALIDATORS.put(ENCODED_SURROUND_OUTPUT, ENCODED_SURROUND_OUTPUT_VALIDATOR); + VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); + VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR); + VALIDATORS.put(PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_VALIDATOR); + VALIDATORS.put(PRIVATE_DNS_SPECIFIER, PRIVATE_DNS_SPECIFIER_VALIDATOR); + VALIDATORS.put(SOFT_AP_TIMEOUT_ENABLED, SOFT_AP_TIMEOUT_ENABLED_VALIDATOR); + } + + /** * Global settings that shouldn't be persisted. * * @hide diff --git a/core/java/android/provider/SettingsValidators.java b/core/java/android/provider/SettingsValidators.java index af824526f416..22ef3b6f346f 100644 --- a/core/java/android/provider/SettingsValidators.java +++ b/core/java/android/provider/SettingsValidators.java @@ -32,6 +32,13 @@ public class SettingsValidators { public static final Validator BOOLEAN_VALIDATOR = new DiscreteValueValidator(new String[] {"0", "1"}); + public static final Validator ANY_STRING_VALIDATOR = new Validator() { + @Override + public boolean validate(String value) { + return true; + } + }; + public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() { @Override public boolean validate(String value) { @@ -62,6 +69,38 @@ public class SettingsValidators { } }; + public static final Validator PACKAGE_NAME_VALIDATOR = new Validator() { + @Override + public boolean validate(String value) { + return value != null && isStringPackageName(value); + } + + private boolean isStringPackageName(String value) { + // The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers, + // and underscores ('_'). However, individual package name parts may only + // start with letters. + // (https://developer.android.com/guide/topics/manifest/manifest-element.html#package) + String[] subparts = value.split("."); + boolean isValidPackageName = true; + for (String subpart : subparts) { + isValidPackageName |= isSubpartValidForPackageName(subpart); + if (!isValidPackageName) break; + } + return isValidPackageName; + } + + private boolean isSubpartValidForPackageName(String subpart) { + if (subpart.length() == 0) return false; + boolean isValidSubpart = Character.isLetter(subpart.charAt(0)); + for (int i = 1; i < subpart.length(); i++) { + isValidSubpart |= (Character.isLetterOrDigit(subpart.charAt(i)) + || (subpart.charAt(i) == '_')); + if (!isValidSubpart) break; + } + return isValidSubpart; + } + }; + public static final Validator LENIENT_IP_ADDRESS_VALIDATOR = new Validator() { private static final int MAX_IPV6_LENGTH = 45; diff --git a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java index 6b613dd5a559..00732b09f821 100644 --- a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java +++ b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java @@ -19,12 +19,15 @@ package android.provider; import static org.junit.Assert.fail; import android.platform.test.annotations.Presubmit; +import android.provider.SettingsValidators.Validator; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Map; + /** Tests that ensure all backed up settings have non-null validators. */ @Presubmit @RunWith(AndroidJUnit4.class) @@ -33,18 +36,34 @@ public class SettingsValidatorsTest { @Test public void ensureAllBackedUpSystemSettingsHaveValidators() { + String offenders = getOffenders(Settings.System.SETTINGS_TO_BACKUP, + Settings.System.VALIDATORS); + + failIfOffendersPresent(offenders, "Settings.System"); + } + + @Test + public void ensureAllBackedUpGlobalSettingsHaveValidators() { + String offenders = getOffenders(Settings.Global.SETTINGS_TO_BACKUP, + Settings.Global.VALIDATORS); + + failIfOffendersPresent(offenders, "Settings.Global"); + } + + private void failIfOffendersPresent(String offenders, String settingsType) { + if (offenders.length() > 0) { + fail("All " + settingsType + " settings that are backed up have to have a non-null" + + " validator, but those don't: " + offenders); + } + } + + private String getOffenders(String[] settingsToBackup, Map<String, Validator> validators) { StringBuilder offenders = new StringBuilder(); - for (String setting : Settings.System.SETTINGS_TO_BACKUP) { - if (Settings.System.VALIDATORS.get(setting) == null) { + for (String setting : settingsToBackup) { + if (validators.get(setting) == null) { offenders.append(setting).append(" "); } } - - // if there're any offenders fail the test and report them - String offendersStr = offenders.toString(); - if (offendersStr.length() > 0) { - fail("All Settings.System settings that are backed up have to have a non-null" - + " validator, but those don't: " + offendersStr); - } + return offenders.toString(); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 01e0d52d5126..9ee205f9cde7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -301,6 +301,7 @@ public class SettingsProvider extends ContentProvider { // fail to boot if there're any backed up settings that don't have a non-null validator ensureAllBackedUpSystemSettingsHaveValidators(); + ensureAllBackedUpGlobalSettingsHaveValidators(); synchronized (mLock) { mUserManager = UserManager.get(getContext()); @@ -320,18 +321,35 @@ public class SettingsProvider extends ContentProvider { } private void ensureAllBackedUpSystemSettingsHaveValidators() { + String offenders = getOffenders(Settings.System.SETTINGS_TO_BACKUP, + Settings.System.VALIDATORS); + + failToBootIfOffendersPresent(offenders, "Settings.System"); + } + + private void ensureAllBackedUpGlobalSettingsHaveValidators() { + String offenders = getOffenders(Settings.Global.SETTINGS_TO_BACKUP, + Settings.Global.VALIDATORS); + + failToBootIfOffendersPresent(offenders, "Settings.Global"); + } + + private void failToBootIfOffendersPresent(String offenders, String settingsType) { + if (offenders.length() > 0) { + throw new RuntimeException("All " + settingsType + " settings that are backed up" + + " have to have a non-null validator, but those don't: " + offenders); + } + } + + private String getOffenders(String[] settingsToBackup, Map<String, + SettingsValidators.Validator> validators) { StringBuilder offenders = new StringBuilder(); - for (String setting : Settings.System.SETTINGS_TO_BACKUP) { - if (Settings.System.VALIDATORS.get(setting) == null) { + for (String setting : settingsToBackup) { + if (validators.get(setting) == null) { offenders.append(setting).append(" "); } } - - String offendersStr = offenders.toString(); - if (offendersStr.length() > 0) { - throw new RuntimeException("All Settings.System settings that are backed up must" - + " have a non-null validator, but those don't: " + offendersStr); - } + return offenders.toString(); } @Override |