Merge changes from topic "overrideable-by-restore"
* changes:
Add Settings.(System/Secure).putStringOverrideableByRestore
Add preserveValueInRestore flag to Setting object
diff --git a/api/system-current.txt b/api/system-current.txt
index d9d9a4d..ef8a604 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -126,6 +126,7 @@
field @Deprecated public static final String MODIFY_NETWORK_ACCOUNTING = "android.permission.MODIFY_NETWORK_ACCOUNTING";
field public static final String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS";
field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE";
+ field public static final String MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE = "android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE";
field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
field public static final String NETWORK_AIRPLANE_MODE = "android.permission.NETWORK_AIRPLANE_MODE";
field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING";
@@ -8169,6 +8170,10 @@
field public static final int VOLUME_HUSH_VIBRATE = 1; // 0x1
}
+ public static final class Settings.System extends android.provider.Settings.NameValueTable {
+ method @RequiresPermission(android.Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE) public static boolean putString(@NonNull android.content.ContentResolver, @NonNull String, @Nullable String, boolean);
+ }
+
public static interface Telephony.CarrierColumns extends android.provider.BaseColumns {
field @NonNull public static final android.net.Uri CONTENT_URI;
field public static final String EXPIRATION_TIME = "expiration_time";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4f84183..96a4a2f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -95,6 +95,7 @@
* The Settings provider contains global system-level device preferences.
*/
public final class Settings {
+ private static final boolean DEFAULT_OVERRIDEABLE_BY_RESTORE = false;
// Intent actions for Settings
@@ -2149,6 +2150,11 @@
*/
public static final String CALL_METHOD_FLAGS_KEY = "_flags";
+ /**
+ * @hide - String argument extra to the fast-path call()-based requests
+ */
+ public static final String CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY = "_overrideable_by_restore";
+
/** @hide - Private call() method to write to 'system' table */
public static final String CALL_METHOD_PUT_SYSTEM = "PUT_system";
@@ -2517,7 +2523,8 @@
}
public boolean putStringForUser(ContentResolver cr, String name, String value,
- String tag, boolean makeDefault, final int userHandle) {
+ String tag, boolean makeDefault, final int userHandle,
+ boolean overrideableByRestore) {
try {
Bundle arg = new Bundle();
arg.putString(Settings.NameValueTable.VALUE, value);
@@ -2528,6 +2535,9 @@
if (makeDefault) {
arg.putBoolean(CALL_METHOD_MAKE_DEFAULT_KEY, true);
}
+ if (overrideableByRestore) {
+ arg.putBoolean(CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY, true);
+ }
IContentProvider cp = mProviderHolder.getProvider(cr);
cp.call(cr.getPackageName(), cr.getFeatureId(),
mProviderHolder.mUri.getAuthority(), mCallSetCommand, name, arg);
@@ -3078,10 +3088,36 @@
return putStringForUser(resolver, name, value, resolver.getUserId());
}
+ /**
+ * Store a name/value pair into the database. Values written by this method will be
+ * overridden if a restore happens in the future.
+ *
+ * @param resolver to access the database with
+ * @param name to store
+ * @param value to associate with the name
+ *
+ * @return true if the value was set, false on database errors
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE)
+ @SystemApi
+ public static boolean putString(@NonNull ContentResolver resolver,
+ @NonNull String name, @Nullable String value, boolean overrideableByRestore) {
+ return putStringForUser(resolver, name, value, resolver.getUserId(),
+ overrideableByRestore);
+ }
+
/** @hide */
@UnsupportedAppUsage
public static boolean putStringForUser(ContentResolver resolver, String name, String value,
int userHandle) {
+ return putStringForUser(resolver, name, value, userHandle,
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
+ }
+
+ private static boolean putStringForUser(ContentResolver resolver, String name, String value,
+ int userHandle, boolean overrideableByRestore) {
if (MOVED_TO_SECURE.contains(name)) {
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
+ " to android.provider.Settings.Secure, value is unchanged.");
@@ -3092,7 +3128,8 @@
+ " to android.provider.Settings.Global, value is unchanged.");
return false;
}
- return sNameValueCache.putStringForUser(resolver, name, value, null, false, userHandle);
+ return sNameValueCache.putStringForUser(resolver, name, value, null, false, userHandle,
+ overrideableByRestore);
}
/**
@@ -3416,7 +3453,7 @@
// need to store the adjusted configuration as the initial settings.
Settings.System.putStringForUser(
cr, SYSTEM_LOCALES, outConfig.getLocales().toLanguageTags(),
- userHandle);
+ userHandle, DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
}
}
@@ -3449,7 +3486,8 @@
int userHandle) {
return Settings.System.putFloatForUser(cr, FONT_SCALE, config.fontScale, userHandle) &&
Settings.System.putStringForUser(
- cr, SYSTEM_LOCALES, config.getLocales().toLanguageTags(), userHandle);
+ cr, SYSTEM_LOCALES, config.getLocales().toLanguageTags(), userHandle,
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/** @hide */
@@ -5251,6 +5289,24 @@
}
/**
+ * Store a name/value pair into the database. Values written by this method will be
+ * overridden if a restore happens in the future.
+ *
+ * @param resolver to access the database with
+ * @param name to store
+ * @param value to associate with the name
+ * @return true if the value was set, false on database errors
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE)
+ public static boolean putString(ContentResolver resolver, String name,
+ String value, boolean overrideableByRestore) {
+ return putStringForUser(resolver, name, value, /* tag */ null, /* makeDefault */ false,
+ resolver.getUserId(), overrideableByRestore);
+ }
+
+ /**
* Store a name/value pair into the database.
* @param resolver to access the database with
* @param name to store
@@ -5265,22 +5321,23 @@
@UnsupportedAppUsage
public static boolean putStringForUser(ContentResolver resolver, String name, String value,
int userHandle) {
- return putStringForUser(resolver, name, value, null, false, userHandle);
+ return putStringForUser(resolver, name, value, null, false, userHandle,
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/** @hide */
@UnsupportedAppUsage
public static boolean putStringForUser(@NonNull ContentResolver resolver,
@NonNull String name, @Nullable String value, @Nullable String tag,
- boolean makeDefault, @UserIdInt int userHandle) {
+ boolean makeDefault, @UserIdInt int userHandle, boolean overrideableByRestore) {
if (MOVED_TO_GLOBAL.contains(name)) {
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure"
+ " to android.provider.Settings.Global");
return Global.putStringForUser(resolver, name, value,
- tag, makeDefault, userHandle);
+ tag, makeDefault, userHandle, DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
return sNameValueCache.putStringForUser(resolver, name, value, tag,
- makeDefault, userHandle);
+ makeDefault, userHandle, overrideableByRestore);
}
/**
@@ -5329,7 +5386,7 @@
@NonNull String name, @Nullable String value, @Nullable String tag,
boolean makeDefault) {
return putStringForUser(resolver, name, value, tag, makeDefault,
- resolver.getUserId());
+ resolver.getUserId(), DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/**
@@ -12940,7 +12997,29 @@
*/
public static boolean putString(ContentResolver resolver,
String name, String value) {
- return putStringForUser(resolver, name, value, null, false, resolver.getUserId());
+ return putStringForUser(resolver, name, value, null, false, resolver.getUserId(),
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
+ }
+
+ /**
+ * Store a name/value pair into the database.
+ *
+ * @param resolver to access the database with
+ * @param name to store
+ * @param value to associate with the name
+ * @param tag to associated with the setting.
+ * @param makeDefault whether to make the value the default one.
+ * @param overrideableByRestore whether restore can override this value
+ * @return true if the value was set, false on database errors
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE)
+ public static boolean putString(@NonNull ContentResolver resolver,
+ @NonNull String name, @Nullable String value, @Nullable String tag,
+ boolean makeDefault, boolean overrideableByRestore) {
+ return putStringForUser(resolver, name, value, tag, makeDefault,
+ resolver.getUserId(), overrideableByRestore);
}
/**
@@ -12989,7 +13068,7 @@
@NonNull String name, @Nullable String value, @Nullable String tag,
boolean makeDefault) {
return putStringForUser(resolver, name, value, tag, makeDefault,
- resolver.getUserId());
+ resolver.getUserId(), DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/**
@@ -13051,13 +13130,14 @@
@UnsupportedAppUsage
public static boolean putStringForUser(ContentResolver resolver,
String name, String value, int userHandle) {
- return putStringForUser(resolver, name, value, null, false, userHandle);
+ return putStringForUser(resolver, name, value, null, false, userHandle,
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/** @hide */
public static boolean putStringForUser(@NonNull ContentResolver resolver,
@NonNull String name, @Nullable String value, @Nullable String tag,
- boolean makeDefault, @UserIdInt int userHandle) {
+ boolean makeDefault, @UserIdInt int userHandle, boolean overrideableByRestore) {
if (LOCAL_LOGV) {
Log.v(TAG, "Global.putString(name=" + name + ", value=" + value
+ " for " + userHandle);
@@ -13067,10 +13147,10 @@
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Global"
+ " to android.provider.Settings.Secure, value is unchanged.");
return Secure.putStringForUser(resolver, name, value, tag,
- makeDefault, userHandle);
+ makeDefault, userHandle, overrideableByRestore);
}
return sNameValueCache.putStringForUser(resolver, name, value, tag,
- makeDefault, userHandle);
+ makeDefault, userHandle, overrideableByRestore);
}
/**
@@ -13937,7 +14017,8 @@
static boolean putString(@NonNull ContentResolver resolver, @NonNull String namespace,
@NonNull String name, @Nullable String value, boolean makeDefault) {
return sNameValueCache.putStringForUser(resolver, createCompositeName(namespace, name),
- value, null, makeDefault, resolver.getUserId());
+ value, null, makeDefault, resolver.getUserId(),
+ DEFAULT_OVERRIDEABLE_BY_RESTORE);
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2665e8a..0bc16a3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3980,6 +3980,13 @@
<permission android:name="android.permission.BACKUP"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows an application to make modifications to device settings such that these
+ modifications will be overridden by settings restore..
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE"
+ android:protectionLevel="signature|setup" />
+
<!-- @SystemApi Allows application to manage
{@link android.security.keystore.recovery.RecoveryController}.
<p>Not for use by third-party applications.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 4443524..c913999 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -367,7 +367,9 @@
String value = getSettingValue(args);
String tag = getSettingTag(args);
final boolean makeDefault = getSettingMakeDefault(args);
- insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false);
+ final boolean overrideableByRestore = getSettingOverrideableByRestore(args);
+ insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false,
+ overrideableByRestore);
break;
}
@@ -375,13 +377,16 @@
String value = getSettingValue(args);
String tag = getSettingTag(args);
final boolean makeDefault = getSettingMakeDefault(args);
- insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false);
+ final boolean overrideableByRestore = getSettingOverrideableByRestore(args);
+ insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false,
+ overrideableByRestore);
break;
}
case Settings.CALL_METHOD_PUT_SYSTEM: {
String value = getSettingValue(args);
- insertSystemSetting(name, value, requestingUserId);
+ boolean overrideableByRestore = getSettingOverrideableByRestore(args);
+ insertSystemSetting(name, value, requestingUserId, overrideableByRestore);
break;
}
@@ -576,20 +581,23 @@
switch (table) {
case TABLE_GLOBAL: {
if (insertGlobalSetting(name, value, null, false,
- UserHandle.getCallingUserId(), false)) {
+ UserHandle.getCallingUserId(), false,
+ /* overrideableByRestore */ false)) {
return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
}
} break;
case TABLE_SECURE: {
if (insertSecureSetting(name, value, null, false,
- UserHandle.getCallingUserId(), false)) {
+ UserHandle.getCallingUserId(), false,
+ /* overrideableByRestore */ false)) {
return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
}
} break;
case TABLE_SYSTEM: {
- if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
+ if (insertSystemSetting(name, value, UserHandle.getCallingUserId(),
+ /* overridableByRestore */ false)) {
return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
}
} break;
@@ -1075,7 +1083,8 @@
case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
- resolveCallingPackage(), false, null);
+ resolveCallingPackage(), false, null,
+ /* overrideableByRestore */ false);
}
case MUTATION_OPERATION_DELETE: {
@@ -1179,14 +1188,15 @@
}
private boolean insertGlobalSetting(String name, String value, String tag,
- boolean makeDefault, int requestingUserId, boolean forceNotify) {
+ boolean makeDefault, int requestingUserId, boolean forceNotify,
+ boolean overrideableByRestore) {
if (DEBUG) {
Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ", "
+ ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ ", " + forceNotify + ")");
}
return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
- MUTATION_OPERATION_INSERT, forceNotify, 0);
+ MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore);
}
private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) {
@@ -1221,6 +1231,15 @@
private boolean mutateGlobalSetting(String name, String value, String tag,
boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
int mode) {
+ // overrideableByRestore = false as by default settings values shouldn't be overrideable by
+ // restore.
+ return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId, operation,
+ forceNotify, mode, /* overrideableByRestore */ false);
+ }
+
+ private boolean mutateGlobalSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+ int mode, boolean overrideableByRestore) {
// Make sure the caller can change the settings - treated as secure.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -1239,7 +1258,8 @@
case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
- getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
+ getCallingPackage(), forceNotify,
+ CRITICAL_GLOBAL_SETTINGS, overrideableByRestore);
}
case MUTATION_OPERATION_DELETE: {
@@ -1475,7 +1495,7 @@
) {
@Override
public boolean update(String value, boolean setDefault, String packageName,
- String tag, boolean forceNonSystemPackage) {
+ String tag, boolean forceNonSystemPackage, boolean overrideableByRestore) {
Slog.wtf(LOG_TAG, "update shouldn't be called on this instance.");
return false;
}
@@ -1484,14 +1504,15 @@
}
private boolean insertSecureSetting(String name, String value, String tag,
- boolean makeDefault, int requestingUserId, boolean forceNotify) {
+ boolean makeDefault, int requestingUserId, boolean forceNotify,
+ boolean overrideableByRestore) {
if (DEBUG) {
Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
+ ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ ", " + forceNotify + ")");
}
return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
- MUTATION_OPERATION_INSERT, forceNotify, 0);
+ MUTATION_OPERATION_INSERT, forceNotify, 0, overrideableByRestore);
}
private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) {
@@ -1529,6 +1550,15 @@
private boolean mutateSecureSetting(String name, String value, String tag,
boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
int mode) {
+ // overrideableByRestore = false as by default settings values shouldn't be overrideable by
+ // restore.
+ return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId, operation,
+ forceNotify, mode, /* overrideableByRestore */ false);
+ }
+
+ private boolean mutateSecureSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+ int mode, boolean overrideableByRestore) {
// Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -1561,7 +1591,8 @@
case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
owningUserId, name, value, tag, makeDefault,
- getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
+ getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS,
+ overrideableByRestore);
}
case MUTATION_OPERATION_DELETE: {
@@ -1637,13 +1668,15 @@
}
}
- private boolean insertSystemSetting(String name, String value, int requestingUserId) {
+ private boolean insertSystemSetting(String name, String value, int requestingUserId,
+ boolean overrideableByRestore) {
if (DEBUG) {
Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
+ requestingUserId + ")");
}
- return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
+ return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT,
+ overrideableByRestore);
}
private boolean deleteSystemSetting(String name, int requestingUserId) {
@@ -1663,8 +1696,15 @@
return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
}
- private boolean mutateSystemSetting(String name, String value, int runAsUserId,
- int operation) {
+ private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) {
+ // overrideableByRestore = false as by default settings values shouldn't be overrideable by
+ // restore.
+ return mutateSystemSetting(name, value, runAsUserId, operation,
+ /* overrideableByRestore */ false);
+ }
+
+ private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation,
+ boolean overrideableByRestore) {
if (!hasWriteSecureSettingsPermission()) {
// If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this
// operation is allowed for the calling package through appops.
@@ -1714,7 +1754,7 @@
validateSystemSettingValue(name, value);
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
owningUserId, name, value, null, false, getCallingPackage(),
- false, null);
+ false, null, overrideableByRestore);
}
case MUTATION_OPERATION_DELETE: {
@@ -2051,7 +2091,8 @@
}
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders, tag,
- makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
+ makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS,
+ /* overrideableByRestore */ false);
}
private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
@@ -2145,6 +2186,10 @@
return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY);
}
+ private static boolean getSettingOverrideableByRestore(Bundle args) {
+ return (args != null) && args.getBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY);
+ }
+
private static int getResetModeEnforcingPermission(Bundle args) {
final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
switch (mode) {
@@ -2642,21 +2687,21 @@
public boolean insertSettingLocked(int type, int userId, String name, String value,
String tag, boolean makeDefault, String packageName, boolean forceNotify,
- Set<String> criticalSettings) {
+ Set<String> criticalSettings, boolean overrideableByRestore) {
return insertSettingLocked(type, userId, name, value, tag, makeDefault, false,
- packageName, forceNotify, criticalSettings);
+ packageName, forceNotify, criticalSettings, overrideableByRestore);
}
public boolean insertSettingLocked(int type, int userId, String name, String value,
String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName,
- boolean forceNotify, Set<String> criticalSettings) {
+ boolean forceNotify, Set<String> criticalSettings, boolean overrideableByRestore) {
final int key = makeKey(type, userId);
boolean success = false;
SettingsState settingsState = peekSettingsStateLocked(key);
if (settingsState != null) {
success = settingsState.insertSettingLocked(name, value,
- tag, makeDefault, forceNonSystemPackage, packageName);
+ tag, makeDefault, forceNonSystemPackage, packageName, overrideableByRestore);
}
if (success && criticalSettings != null && criticalSettings.contains(name)) {
@@ -3391,6 +3436,10 @@
* for this user from the old to the new version. When you add a new
* upgrade step you *must* update SETTINGS_VERSION.
*
+ * All settings modifications should be made through
+ * {@link SettingsState#insertSettingOverrideableByRestoreLocked(String, String, String,
+ * boolean, String)} so that restore can override those values if needed.
+ *
* This is an example of moving a setting from secure to global.
*
* // v119: Example settings changes.
@@ -3436,7 +3485,8 @@
// v120: Add double tap to wake setting.
if (currentVersion == 119) {
SettingsState secureSettings = getSecureSettingsLocked(userId);
- secureSettings.insertSettingLocked(Settings.Secure.DOUBLE_TAP_TO_WAKE,
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.DOUBLE_TAP_TO_WAKE,
getContext().getResources().getBoolean(
R.bool.def_double_tap_to_wake) ? "1" : "0", null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -3461,7 +3511,7 @@
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
if (defaultComponent != null && !defaultComponent.isEmpty() &&
currentSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -3476,7 +3526,7 @@
Setting currentSetting = globalSettings.getSettingLocked(
Settings.Global.ADD_USERS_WHEN_LOCKED);
if (currentSetting.isNull()) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.ADD_USERS_WHEN_LOCKED,
getContext().getResources().getBoolean(
R.bool.def_add_users_from_lockscreen) ? "1" : "0",
@@ -3490,8 +3540,9 @@
final SettingsState globalSettings = getGlobalSettingsLocked();
String defaultDisabledProfiles = (getContext().getResources().getString(
R.string.def_bluetooth_disabled_profiles));
- globalSettings.insertSettingLocked(Settings.Global.BLUETOOTH_DISABLED_PROFILES,
- defaultDisabledProfiles, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ globalSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Global.BLUETOOTH_DISABLED_PROFILES, defaultDisabledProfiles,
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 124;
}
@@ -3502,7 +3553,7 @@
Setting currentSetting = secureSettings.getSettingLocked(
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
if (currentSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
getContext().getResources().getBoolean(
R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0",
@@ -3531,7 +3582,7 @@
b.append(c.flattenToString());
start = false;
}
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.ENABLED_VR_LISTENERS, b.toString(),
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -3551,7 +3602,7 @@
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
if (!showNotifications.isNull()) {
final SettingsState secureSettings = getSecureSettingsLocked(userId);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
showNotifications.getValue(), null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -3561,7 +3612,7 @@
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
if (!allowPrivate.isNull()) {
final SettingsState secureSettings = getSecureSettingsLocked(userId);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
allowPrivate.getValue(), null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -3588,7 +3639,7 @@
final String oldValue = systemSecureSettings.getSettingLocked(
Settings.Secure.LONG_PRESS_TIMEOUT).getValue();
if (TextUtils.equals("500", oldValue)) {
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.LONG_PRESS_TIMEOUT,
String.valueOf(getContext().getResources().getInteger(
R.integer.def_long_press_timeout_millis)),
@@ -3604,10 +3655,12 @@
getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue());
if (dozeExplicitlyDisabled) {
- secureSettings.insertSettingLocked(Settings.Secure.DOZE_PICK_UP_GESTURE,
- "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- secureSettings.insertSettingLocked(Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
- "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.DOZE_PICK_UP_GESTURE, "0", null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, "0", null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 131;
}
@@ -3618,7 +3671,7 @@
final String oldValue = systemSecureSettings.getSettingLocked(
Settings.Secure.MULTI_PRESS_TIMEOUT).getValue();
if (TextUtils.equals(null, oldValue)) {
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.MULTI_PRESS_TIMEOUT,
String.valueOf(getContext().getResources().getInteger(
R.integer.def_multi_press_timeout_millis)),
@@ -3633,7 +3686,7 @@
final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
String defaultSyncParentSounds = (getContext().getResources()
.getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds,
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 133;
@@ -3646,9 +3699,9 @@
.isNull()) {
String defaultEndButtonBehavior = Integer.toString(getContext()
.getResources().getInteger(R.integer.def_end_button_behavior));
- systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
- defaultEndButtonBehavior, null, true,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ systemSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.System.END_BUTTON_BEHAVIOR, defaultEndButtonBehavior, null,
+ true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 134;
}
@@ -3706,8 +3759,8 @@
if (ssaid.isNull() || ssaid.getValue() == null) {
// Android Id doesn't exist for this package so create it.
- ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
- info.packageName);
+ ssaidSettings.insertSettingOverrideableByRestoreLocked(uid,
+ legacySsaid, null, true, info.packageName);
if (DEBUG) {
Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
}
@@ -3727,13 +3780,14 @@
&& secureSetting.getSettingLocked(
Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) {
- secureSetting.insertSettingLocked(Settings.Secure.INSTALL_NON_MARKET_APPS,
- "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ secureSetting.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.INSTALL_NON_MARKET_APPS, "1", null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
// For managed profiles with profile owners, DevicePolicyManagerService
// may want to set the user restriction in this case
- secureSetting.insertSettingLocked(
- Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null, true,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ secureSetting.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null,
+ true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 138;
}
@@ -3774,7 +3828,7 @@
Setting currentSetting = globalSettings.getSettingLocked(
Settings.Global.WIFI_WAKEUP_ENABLED);
if (currentSetting.isNull()) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.WIFI_WAKEUP_ENABLED,
getContext().getResources().getBoolean(
R.bool.def_wifi_wakeup_enabled) ? "1" : "0",
@@ -3796,8 +3850,9 @@
if (defaultValue != null) {
Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service "
+ "for user " + userId);
- secureSettings.insertSettingLocked(Settings.Secure.AUTOFILL_SERVICE,
- defaultValue, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ secureSettings.insertSettingOverrideableByRestoreLocked(
+ Settings.Secure.AUTOFILL_SERVICE, defaultValue, null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
}
}
@@ -3848,7 +3903,7 @@
final Setting currentSetting = globalSettings.getSettingLocked(
Global.DEFAULT_RESTRICT_BACKGROUND_DATA);
if (currentSetting.isNull()) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.DEFAULT_RESTRICT_BACKGROUND_DATA,
getContext().getResources().getBoolean(
R.bool.def_restrict_background_data) ? "1" : "0",
@@ -3867,7 +3922,7 @@
final String defaultValue = getContext().getResources().getString(
R.string.def_backup_manager_constants);
if (!TextUtils.isEmpty(defaultValue)) {
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.BACKUP_MANAGER_CONSTANTS, defaultValue, null,
true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -3881,7 +3936,7 @@
final Setting currentSetting = globalSettings.getSettingLocked(
Settings.Global.MOBILE_DATA_ALWAYS_ON);
if (currentSetting.isNull()) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.MOBILE_DATA_ALWAYS_ON,
getContext().getResources().getBoolean(
R.bool.def_mobile_data_always_on) ? "1" : "0",
@@ -3917,7 +3972,7 @@
if (showNotificationBadges.isNull()) {
final boolean defaultValue = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_notificationBadging);
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Secure.NOTIFICATION_BADGING,
defaultValue ? "1" : "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
@@ -3934,7 +3989,7 @@
final String defaultValue = getContext().getResources().getString(
R.string.def_backup_local_transport_parameters);
if (!TextUtils.isEmpty(defaultValue)) {
- systemSecureSettings.insertSettingLocked(
+ systemSecureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS, defaultValue,
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -3957,7 +4012,7 @@
if (currentSetting.isNull()) {
String defaultZenDuration = Integer.toString(getContext()
.getResources().getInteger(R.integer.def_zen_duration));
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.ZEN_DURATION, defaultZenDuration,
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -3973,7 +4028,7 @@
final String defaultValue = getContext().getResources().getString(
R.string.def_backup_agent_timeout_parameters);
if (!TextUtils.isEmpty(defaultValue)) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS, defaultValue,
null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4002,7 +4057,7 @@
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
// The default value is "1", check if user has turned it off.
if ("0".equals(showNotifications.getValue())) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, "0",
null /* tag */, false /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4023,7 +4078,7 @@
String oldValue = globalSettings.getSettingLocked(
Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY).getValue();
if (TextUtils.equals(null, oldValue)) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
Integer.toString(getContext().getResources().getInteger(
R.integer.def_max_sound_trigger_detection_service_ops_per_day)),
@@ -4033,7 +4088,7 @@
oldValue = globalSettings.getSettingLocked(
Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT).getValue();
if (TextUtils.equals(null, oldValue)) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT,
Integer.toString(getContext().getResources().getInteger(
R.integer.def_sound_trigger_detection_service_op_timeout)),
@@ -4048,7 +4103,7 @@
final Setting currentSetting = secureSettings.getSettingLocked(
Secure.VOLUME_HUSH_GESTURE);
if (currentSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.VOLUME_HUSH_GESTURE,
Integer.toString(Secure.VOLUME_HUSH_VIBRATE),
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4069,7 +4124,7 @@
final Setting currentSetting = settings.getSettingLocked(
Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY);
if (currentSetting.isDefaultFromSystem()) {
- settings.insertSettingLocked(
+ settings.insertSettingOverrideableByRestoreLocked(
Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
Integer.toString(getContext().getResources().getInteger(
R.integer
@@ -4098,7 +4153,7 @@
Setting currentHushUsedSetting = secureSettings.getSettingLocked(
Secure.HUSH_GESTURE_USED);
if (currentHushUsedSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.HUSH_GESTURE_USED, "0", null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4106,7 +4161,7 @@
Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked(
Secure.MANUAL_RINGER_TOGGLE_COUNT);
if (currentRingerToggleCountSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4125,7 +4180,7 @@
final Setting currentSetting = systemSettings.getSettingLocked(
Settings.System.VIBRATE_WHEN_RINGING);
if (currentSetting.isNull()) {
- systemSettings.insertSettingLocked(
+ systemSettings.insertSettingOverrideableByRestoreLocked(
Settings.System.VIBRATE_WHEN_RINGING,
getContext().getResources().getBoolean(
R.bool.def_vibrate_when_ringing) ? "1" : "0",
@@ -4149,18 +4204,18 @@
// ZEN_DURATION
if (!globalZenDuration.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false,
SettingsState.SYSTEM_PACKAGE_NAME);
// set global zen duration setting to null since it's deprecated
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.ZEN_DURATION, null, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
} else if (secureZenDuration.isNull()) {
String defaultZenDuration = Integer.toString(getContext()
.getResources().getInteger(R.integer.def_zen_duration));
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.ZEN_DURATION, defaultZenDuration, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4169,7 +4224,7 @@
final Setting currentShowZenSettingSuggestion = secureSettings.getSettingLocked(
Secure.SHOW_ZEN_SETTINGS_SUGGESTION);
if (currentShowZenSettingSuggestion.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4178,7 +4233,7 @@
final Setting currentUpdatedSetting = secureSettings.getSettingLocked(
Secure.ZEN_SETTINGS_UPDATED);
if (currentUpdatedSetting.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.ZEN_SETTINGS_UPDATED, "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4187,7 +4242,7 @@
final Setting currentSettingSuggestionViewed = secureSettings.getSettingLocked(
Secure.ZEN_SETTINGS_SUGGESTION_VIEWED);
if (currentSettingSuggestionViewed.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4210,20 +4265,20 @@
if (!globalChargingSoundEnabled.isNull()) {
if (secureChargingSoundsEnabled.isNull()) {
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.CHARGING_SOUNDS_ENABLED,
globalChargingSoundEnabled.getValue(), null, false,
SettingsState.SYSTEM_PACKAGE_NAME);
}
// set global charging_sounds_enabled setting to null since it's deprecated
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.CHARGING_SOUNDS_ENABLED, null, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
} else if (secureChargingSoundsEnabled.isNull()) {
String defChargingSoundsEnabled = getContext().getResources()
.getBoolean(R.bool.def_charging_sounds_enabled) ? "1" : "0";
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.CHARGING_SOUNDS_ENABLED, defChargingSoundsEnabled, null,
true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4235,7 +4290,7 @@
if (secureChargingVibrationEnabled.isNull()) {
String defChargingVibrationEnabled = getContext().getResources()
.getBoolean(R.bool.def_charging_vibration_enabled) ? "1" : "0";
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.CHARGING_VIBRATION_ENABLED, defChargingVibrationEnabled,
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4255,7 +4310,7 @@
currentSetting.getValue());
if ((currentSettingIntegerValue
& (1 << AudioManager.STREAM_VOICE_CALL)) == 0) {
- systemSettings.insertSettingLocked(
+ systemSettings.insertSettingOverrideableByRestoreLocked(
Settings.System.MUTE_STREAMS_AFFECTED,
Integer.toString(
currentSettingIntegerValue
@@ -4296,7 +4351,7 @@
? Secure.LOCATION_MODE_ON
: Secure.LOCATION_MODE_OFF;
}
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.LOCATION_MODE, Integer.toString(defLocationMode),
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4318,7 +4373,7 @@
Setting currentRampingRingerSetting = globalSettings.getSettingLocked(
Settings.Global.APPLY_RAMPING_RINGER);
if (currentRampingRingerSetting.isNull()) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Settings.Global.APPLY_RAMPING_RINGER,
getContext().getResources().getBoolean(
R.bool.def_apply_ramping_ringer) ? "1" : "0", null,
@@ -4344,7 +4399,7 @@
if (!notificationVibrationIntensity.isNull()
&& ringVibrationIntensity.isNull()) {
- systemSettings.insertSettingLocked(
+ systemSettings.insertSettingOverrideableByRestoreLocked(
Settings.System.RING_VIBRATION_INTENSITY,
notificationVibrationIntensity.getValue(),
null , true, SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4388,7 +4443,7 @@
if (awareEnabled.isNull()) {
final boolean defAwareEnabled = getContext().getResources().getBoolean(
R.bool.def_aware_enabled);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.AWARE_ENABLED, defAwareEnabled ? "1" : "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4408,7 +4463,7 @@
if (skipGesture.isNull()) {
final boolean defSkipGesture = getContext().getResources().getBoolean(
R.bool.def_skip_gesture);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.SKIP_GESTURE, defSkipGesture ? "1" : "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4419,7 +4474,7 @@
if (silenceGesture.isNull()) {
final boolean defSilenceGesture = getContext().getResources().getBoolean(
R.bool.def_silence_gesture);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.SILENCE_GESTURE, defSilenceGesture ? "1" : "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4447,7 +4502,7 @@
if (awareLockEnabled.isNull()) {
final boolean defAwareLockEnabled = getContext().getResources().getBoolean(
R.bool.def_aware_lock_enabled);
- secureSettings.insertSettingLocked(
+ secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.AWARE_LOCK_ENABLED, defAwareLockEnabled ? "1" : "0",
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -4467,7 +4522,7 @@
currentSetting.getValue());
if ((currentSettingIntegerValue
& (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) {
- systemSettings.insertSettingLocked(
+ systemSettings.insertSettingOverrideableByRestoreLocked(
Settings.System.MUTE_STREAMS_AFFECTED,
Integer.toString(
currentSettingIntegerValue
@@ -4513,13 +4568,13 @@
if (oldValueWireless == null
|| TextUtils.equals(oldValueWireless, defaultValueWired)) {
if (!TextUtils.isEmpty(defaultValueWireless)) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWireless,
null /* tag */, true /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
} else if (!TextUtils.isEmpty(defaultValueWired)) {
// if the wireless sound is empty, use the wired charging sound
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.WIRELESS_CHARGING_STARTED_SOUND, defaultValueWired,
null /* tag */, true /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4528,7 +4583,7 @@
// wired charging sound
if (oldValueWired == null && !TextUtils.isEmpty(defaultValueWired)) {
- globalSettings.insertSettingLocked(
+ globalSettings.insertSettingOverrideableByRestoreLocked(
Global.CHARGING_STARTED_SOUND, defaultValueWired,
null /* tag */, true /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4540,8 +4595,8 @@
// Version 184: Reset the default for Global Settings: NOTIFICATION_BUBBLES
// This is originally set in version 182, however, the default value changed
// so this step is to ensure the value is updated to the correct default.
- getGlobalSettingsLocked().insertSettingLocked(Global.NOTIFICATION_BUBBLES,
- getContext().getResources().getBoolean(
+ getGlobalSettingsLocked().insertSettingOverrideableByRestoreLocked(
+ Global.NOTIFICATION_BUBBLES, getContext().getResources().getBoolean(
R.bool.def_notification_bubbles) ? "1" : "0", null /* tag */,
true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME);
@@ -4617,7 +4672,7 @@
final boolean systemSet = SettingsState.isSystemPackage(getContext(),
setting.getPackageName(), callingUid, userId);
if (systemSet) {
- settings.insertSettingLocked(name, setting.getValue(),
+ settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(),
setting.getTag(), true, setting.getPackageName());
} else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
// We had a bug where changes by non-system packages were marked
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 5b1b530..db18213 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -117,6 +117,8 @@
private static final String ATTR_NAMESPACE = "namespace";
private static final String ATTR_BANNED_HASH = "bannedHash";
+ private static final String ATTR_PRESERVE_IN_RESTORE = "preserve_in_restore";
+
/**
* Non-binary value will be written in this attributes.
*/
@@ -388,15 +390,25 @@
// The settings provider must hold its lock when calling here.
@GuardedBy("mLock")
- public boolean insertSettingLocked(String name, String value, String tag,
+ public boolean insertSettingOverrideableByRestoreLocked(String name, String value, String tag,
boolean makeDefault, String packageName) {
- return insertSettingLocked(name, value, tag, makeDefault, false, packageName);
+ return insertSettingLocked(name, value, tag, makeDefault, false, packageName,
+ /* overrideableByRestore */ true);
}
// The settings provider must hold its lock when calling here.
@GuardedBy("mLock")
public boolean insertSettingLocked(String name, String value, String tag,
- boolean makeDefault, boolean forceNonSystemPackage, String packageName) {
+ boolean makeDefault, String packageName) {
+ return insertSettingLocked(name, value, tag, makeDefault, false, packageName,
+ /* overrideableByRestore */ false);
+ }
+
+ // The settings provider must hold its lock when calling here.
+ @GuardedBy("mLock")
+ public boolean insertSettingLocked(String name, String value, String tag,
+ boolean makeDefault, boolean forceNonSystemPackage, String packageName,
+ boolean overrideableByRestore) {
if (TextUtils.isEmpty(name)) {
return false;
}
@@ -407,7 +419,8 @@
Setting newState;
if (oldState != null) {
- if (!oldState.update(value, makeDefault, packageName, tag, forceNonSystemPackage)) {
+ if (!oldState.update(value, makeDefault, packageName, tag, forceNonSystemPackage,
+ overrideableByRestore)) {
return false;
}
newState = oldState;
@@ -495,7 +508,8 @@
changedKeys.add(key); // key was added
} else if (state.value != value) {
oldValue = state.value;
- state.update(value, false, packageName, null, true);
+ state.update(value, false, packageName, null, true,
+ /* overrideableByRestore */ false);
changedKeys.add(key); // key was updated
} else {
// this key/value already exists, no change and no logging necessary
@@ -797,7 +811,8 @@
writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(),
setting.getValue(), setting.getDefaultValue(), setting.getPackageName(),
- setting.getTag(), setting.isDefaultFromSystem());
+ setting.getTag(), setting.isDefaultFromSystem(),
+ setting.isValuePreservedInRestore());
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[PERSISTED]" + setting.getName() + "="
@@ -886,7 +901,8 @@
static void writeSingleSetting(int version, XmlSerializer serializer, String id,
String name, String value, String defaultValue, String packageName,
- String tag, boolean defaultSysSet) throws IOException {
+ String tag, boolean defaultSysSet, boolean isValuePreservedInRestore)
+ throws IOException {
if (id == null || isBinary(id) || name == null || isBinary(name)
|| packageName == null || isBinary(packageName)) {
// This shouldn't happen.
@@ -905,6 +921,9 @@
setValueAttribute(ATTR_TAG, ATTR_TAG_BASE64,
version, serializer, tag);
}
+ if (isValuePreservedInRestore) {
+ serializer.attribute(null, ATTR_PRESERVE_IN_RESTORE, Boolean.toString(true));
+ }
serializer.endTag(null, TAG_SETTING);
}
@@ -1041,6 +1060,10 @@
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
String defaultValue = getValueAttribute(parser, ATTR_DEFAULT_VALUE,
ATTR_DEFAULT_VALUE_BASE64);
+ String isPreservedInRestoreString = parser.getAttributeValue(null,
+ ATTR_PRESERVE_IN_RESTORE);
+ boolean isPreservedInRestore = isPreservedInRestoreString != null
+ && Boolean.parseBoolean(isPreservedInRestoreString);
String tag = null;
boolean fromSystem = false;
if (defaultValue != null) {
@@ -1049,7 +1072,7 @@
tag = getValueAttribute(parser, ATTR_TAG, ATTR_TAG_BASE64);
}
mSettings.put(name, new Setting(name, value, defaultValue, packageName, tag,
- fromSystem, id));
+ fromSystem, id, isPreservedInRestore));
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[RESTORED] " + name + "=" + value);
@@ -1133,6 +1156,8 @@
private String tag;
// Whether the default is set by the system
private boolean defaultFromSystem;
+ // Whether the value of this setting will be preserved when restore happens.
+ private boolean isValuePreservedInRestore;
public Setting(Setting other) {
name = other.name;
@@ -1142,25 +1167,38 @@
id = other.id;
defaultFromSystem = other.defaultFromSystem;
tag = other.tag;
+ isValuePreservedInRestore = other.isValuePreservedInRestore;
}
public Setting(String name, String value, boolean makeDefault, String packageName,
String tag) {
this.name = name;
- update(value, makeDefault, packageName, tag, false);
+ // overrideableByRestore = true as the first initialization isn't considered a
+ // modification.
+ update(value, makeDefault, packageName, tag, false,
+ /* overrideableByRestore */ true);
}
public Setting(String name, String value, String defaultValue,
String packageName, String tag, boolean fromSystem, String id) {
+ this(name, value, defaultValue, packageName, tag, fromSystem, id,
+ /* isOverrideableByRestore */ false);
+ }
+
+ Setting(String name, String value, String defaultValue,
+ String packageName, String tag, boolean fromSystem, String id,
+ boolean isValuePreservedInRestore) {
mNextId = Math.max(mNextId, Long.parseLong(id) + 1);
if (NULL_VALUE.equals(value)) {
value = null;
}
- init(name, value, tag, defaultValue, packageName, fromSystem, id);
+ init(name, value, tag, defaultValue, packageName, fromSystem, id,
+ isValuePreservedInRestore);
}
private void init(String name, String value, String tag, String defaultValue,
- String packageName, boolean fromSystem, String id) {
+ String packageName, boolean fromSystem, String id,
+ boolean isValuePreservedInRestore) {
this.name = name;
this.value = value;
this.tag = tag;
@@ -1168,6 +1206,7 @@
this.packageName = packageName;
this.id = id;
this.defaultFromSystem = fromSystem;
+ this.isValuePreservedInRestore = isValuePreservedInRestore;
}
public String getName() {
@@ -1198,6 +1237,10 @@
return defaultFromSystem;
}
+ public boolean isValuePreservedInRestore() {
+ return isValuePreservedInRestore;
+ }
+
public String getId() {
return id;
}
@@ -1208,7 +1251,9 @@
/** @return whether the value changed */
public boolean reset() {
- return update(this.defaultValue, false, packageName, null, true);
+ // overrideableByRestore = true as resetting to default value isn't considered a
+ // modification.
+ return update(this.defaultValue, false, packageName, null, true, true);
}
public boolean isTransient() {
@@ -1220,7 +1265,7 @@
}
public boolean update(String value, boolean setDefault, String packageName, String tag,
- boolean forceNonSystemPackage) {
+ boolean forceNonSystemPackage, boolean overrideableByRestore) {
if (NULL_VALUE.equals(value)) {
value = null;
}
@@ -1253,17 +1298,22 @@
}
}
+ // isValuePreservedInRestore shouldn't change back to false if it has been set to true.
+ boolean isPreserved = this.isValuePreservedInRestore || !overrideableByRestore;
+
// Is something gonna change?
if (Objects.equals(value, this.value)
&& Objects.equals(defaultValue, this.defaultValue)
&& Objects.equals(packageName, this.packageName)
&& Objects.equals(tag, this.tag)
- && defaultFromSystem == this.defaultFromSystem) {
+ && defaultFromSystem == this.defaultFromSystem
+ && isPreserved == this.isValuePreservedInRestore) {
return false;
}
init(name, value, tag, defaultValue, packageName, defaultFromSystem,
- String.valueOf(mNextId++));
+ String.valueOf(mNextId++), isPreserved);
+
return true;
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 3f68554..b855d87 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -46,6 +46,18 @@
"\uD800ab\uDC00 " + // broken surrogate pairs
"日本語";
+ private static final String TEST_PACKAGE = "package";
+ private static final String SETTING_NAME = "test_setting";
+
+ private final Object mLock = new Object();
+
+ private File mSettingsFile;
+
+ @Override
+ protected void setUp() {
+ mSettingsFile = new File(getContext().getCacheDir(), "setting.xml");
+ mSettingsFile.delete();
+ }
public void testIsBinary() {
assertFalse(SettingsState.isBinary(" abc 日本語"));
@@ -99,10 +111,10 @@
checkWriteSingleSetting(serializer, CRAZY_STRING, null);
SettingsState.writeSingleSetting(
SettingsState.SETTINGS_VERSION_NEW_ENCODING,
- serializer, null, "k", "v", null, "package", null, false);
+ serializer, null, "k", "v", null, "package", null, false, false);
SettingsState.writeSingleSetting(
SettingsState.SETTINGS_VERSION_NEW_ENCODING,
- serializer, "1", "k", "v", null, null, null, false);
+ serializer, "1", "k", "v", null, null, null, false, false);
}
private void checkWriteSingleSetting(XmlSerializer serializer, String key, String value)
@@ -115,7 +127,7 @@
// Make sure the XML serializer won't crash.
SettingsState.writeSingleSetting(
SettingsState.SETTINGS_VERSION_NEW_ENCODING,
- serializer, "1", key, value, null, "package", null, false);
+ serializer, "1", key, value, null, "package", null, false, false);
}
/**
@@ -182,4 +194,57 @@
assertEquals("p2", s.getPackageName());
}
}
+
+ public void testInitializeSetting_preserveFlagNotSet() {
+ SettingsState settingsWriter = getSettingStateObject();
+ settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
+ settingsWriter.persistSyncLocked();
+
+ SettingsState settingsReader = getSettingStateObject();
+ assertFalse(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+ }
+
+ public void testModifySetting_preserveFlagSet() {
+ SettingsState settingsWriter = getSettingStateObject();
+ settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
+ settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, TEST_PACKAGE);
+ settingsWriter.persistSyncLocked();
+
+ SettingsState settingsReader = getSettingStateObject();
+ assertTrue(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+ }
+
+ public void testModifySettingOverrideableByRestore_preserveFlagNotSet() {
+ SettingsState settingsWriter = getSettingStateObject();
+ settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
+ settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, false, TEST_PACKAGE,
+ /* overrideableByRestore */ true);
+ settingsWriter.persistSyncLocked();
+
+ SettingsState settingsReader = getSettingStateObject();
+ assertFalse(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+ }
+
+ public void testModifySettingOverrideableByRestore_preserveFlagAlreadySet_flagValueUnchanged() {
+ SettingsState settingsWriter = getSettingStateObject();
+ // Init the setting.
+ settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
+ // This modification will set isValuePreservedInRestore = true.
+ settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
+ // This modification shouldn't change the value of isValuePreservedInRestore since it's
+ // already been set to true.
+ settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, false, TEST_PACKAGE,
+ /* overrideableByRestore */ true);
+ settingsWriter.persistSyncLocked();
+
+ SettingsState settingsReader = getSettingStateObject();
+ assertTrue(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+ }
+
+ private SettingsState getSettingStateObject() {
+ SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
+ settingsState.setVersionLocked(SettingsState.SETTINGS_VERSION_NEW_ENCODING);
+ return settingsState;
+ }
}