diff options
| author | 2020-01-16 18:33:48 +0000 | |
|---|---|---|
| committer | 2020-01-16 18:33:48 +0000 | |
| commit | 9e99080cd30d5c6cfa48354f73c0ff062a4ad5b8 (patch) | |
| tree | d7d9ed2e5ebba58b58a3e589e78bd282807abb53 | |
| parent | 8474b608a77560ecc68dac83f0e7dc3d6ba4d821 (diff) | |
| parent | 018f5534fa78ac1e297ae4b38c4e9a06e94c78ee (diff) | |
Merge changes from topic "overrideable-by-restore"
* changes:
Add Settings.(System/Secure).putStringOverrideableByRestore
Add preserveValueInRestore flag to Setting object
6 files changed, 389 insertions, 126 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index d9d9a4d1377f..ef8a6041b414 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -126,6 +126,7 @@ package android { 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 @@ package android.provider { 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 4f84183209aa..96a4a2f96931 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -95,6 +95,7 @@ import java.util.Set; * 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 final class Settings { */ 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 final class Settings { } 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 @@ public final class Settings { 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 @@ public final class Settings { 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 @@ public final class Settings { + " 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 @@ public final class Settings { // 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 @@ public final class Settings { 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 @@ public final class Settings { } /** + * 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 @@ public final class Settings { @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 @@ public final class Settings { @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 final class Settings { */ 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 @@ public final class Settings { @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 @@ public final class Settings { @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 @@ public final class Settings { 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 @@ public final class Settings { 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 2665e8a8dd8b..0bc16a3ca817 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 4443524d2098..c913999ecb7c 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { } 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { ) { @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 @@ public class SettingsProvider extends ContentProvider { } 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { } } - 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { } 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 @@ public class SettingsProvider extends ContentProvider { 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 class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { * 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 @@ public class SettingsProvider extends ContentProvider { // 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { .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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { && 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { // 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { ? 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { 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 @@ public class SettingsProvider extends ContentProvider { // 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 @@ public class SettingsProvider extends ContentProvider { // 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 @@ public class SettingsProvider extends ContentProvider { 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 5b1b5305865e..db18213a3599 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 @@ final class SettingsState { 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 @@ final class SettingsState { // The settings provider must hold its lock when calling here. @GuardedBy("mLock") + public boolean insertSettingOverrideableByRestoreLocked(String name, String value, String tag, + boolean makeDefault, String 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, String packageName) { - return insertSettingLocked(name, value, tag, makeDefault, false, 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 makeDefault, boolean forceNonSystemPackage, String packageName, + boolean overrideableByRestore) { if (TextUtils.isEmpty(name)) { return false; } @@ -407,7 +419,8 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { 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 @@ final class SettingsState { this.packageName = packageName; this.id = id; this.defaultFromSystem = fromSystem; + this.isValuePreservedInRestore = isValuePreservedInRestore; } public String getName() { @@ -1198,6 +1237,10 @@ final class SettingsState { return defaultFromSystem; } + public boolean isValuePreservedInRestore() { + return isValuePreservedInRestore; + } + public String getId() { return id; } @@ -1208,7 +1251,9 @@ final class SettingsState { /** @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 @@ final class SettingsState { } 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 @@ final class SettingsState { } } + // 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 3f68554ffe87..b855d87fc214 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 @@ public class SettingsStateTest extends AndroidTestCase { "\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 @@ public class SettingsStateTest extends AndroidTestCase { 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 @@ public class SettingsStateTest extends AndroidTestCase { // 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 @@ public class SettingsStateTest extends AndroidTestCase { 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; + } } |