Add restore of Settings keys to
SettingsBackupAgent.RESTORE_FROM_HIGHER_SDK_INT_SUPPORTED_KEYS
Now that we have validators in place for all settings that are
backed up.
Also, add a setting to override restoreAnyVersion, which can be
modified by Phenotype.
Bug: 64988620
Bug: 72162887
Test: manual (P->P - master without changes to master with changes)
Test: manual (Q->P = API29 -> API28)
Test: a lot of other scenarios covered by our end-to-end tests
Test: a GTS test with both settings that don't have validators
and have values that wouldn't pass validation will be added
in vendor/xts
Change-Id: Ifaf94306984b5204c79648d48fd4056ad403196e
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b2cc18b..347e563 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11175,6 +11175,15 @@
"location_global_kill_switch";
/**
+ * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
+ * and restoring to lower version of platform API will be skipped.
+ *
+ * @hide
+ */
+ public static final String OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION =
+ "override_settings_provider_restore_any_version";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ec3a6ce..406f6d7 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -426,7 +426,8 @@
Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_CONFIG_ETAG,
Settings.Global.ZEN_MODE_RINGER_LEVEL,
- Settings.Global.ZRAM_ENABLED);
+ Settings.Global.ZRAM_ENABLED,
+ Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION);
private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS =
newHashSet(
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index c7ba4d6..dd89df1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -35,6 +35,7 @@
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.provider.Settings;
+import android.provider.SettingsValidators.Validator;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.BackupUtils;
@@ -155,6 +156,9 @@
new ArraySet<String>(Arrays.asList(new String[] {
KEY_NETWORK_POLICIES,
KEY_WIFI_NEW_CONFIG,
+ KEY_SYSTEM,
+ KEY_SECURE,
+ KEY_GLOBAL,
}));
private SettingsHelper mSettingsHelper;
@@ -223,6 +227,15 @@
Log.d(TAG, "onRestore(): appVersionCode: " + appVersionCode
+ "; Build.VERSION.SDK_INT: " + Build.VERSION.SDK_INT);
}
+
+ boolean overrideRestoreAnyVersion = Settings.Global.getInt(getContentResolver(),
+ Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION, 0) == 1;
+ if ((appVersionCode > Build.VERSION.SDK_INT) && overrideRestoreAnyVersion) {
+ Log.w(TAG, "Ignoring restore from API" + appVersionCode + " to API"
+ + Build.VERSION.SDK_INT + " due to settings flag override.");
+ return;
+ }
+
// versionCode of com.android.providers.settings corresponds to SDK_INT
mRestoredFromSdkInt = appVersionCode;
@@ -571,15 +584,19 @@
// Figure out the white list and redirects to the global table. We restore anything
// in either the backup whitelist or the legacy-restore whitelist for this table.
final String[] whitelist;
+ Map<String, Validator> validators = null;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
whitelist = concat(Settings.Secure.SETTINGS_TO_BACKUP,
Settings.Secure.LEGACY_RESTORE_SETTINGS);
+ validators = Settings.Secure.VALIDATORS;
} else if (contentUri.equals(Settings.System.CONTENT_URI)) {
whitelist = concat(Settings.System.SETTINGS_TO_BACKUP,
Settings.System.LEGACY_RESTORE_SETTINGS);
+ validators = Settings.System.VALIDATORS;
} else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
whitelist = concat(Settings.Global.SETTINGS_TO_BACKUP,
Settings.Global.LEGACY_RESTORE_SETTINGS);
+ validators = Settings.Global.VALIDATORS;
} else {
throw new IllegalArgumentException("Unknown URI: " + contentUri);
}
@@ -627,6 +644,13 @@
continue;
}
+ // only restore the settings that have valid values
+ if (!isValidSettingValue(key, value, validators)) {
+ Log.w(TAG, "Attempted restore of " + key + " setting, but its value didn't pass"
+ + " validation, value: " + value);
+ continue;
+ }
+
final Uri destination = (movedToGlobal != null && movedToGlobal.contains(key))
? Settings.Global.CONTENT_URI
: contentUri;
@@ -639,6 +663,15 @@
}
}
+ private boolean isValidSettingValue(String key, String value,
+ Map<String, Validator> validators) {
+ if (key == null || validators == null) {
+ return false;
+ }
+ Validator validator = validators.get(key);
+ return (validator != null) && validator.validate(value);
+ }
+
private final String[] concat(String[] first, @Nullable String[] second) {
if (second == null || second.length == 0) {
return first;