diff --git a/api/system-current.txt b/api/system-current.txt index f38b02e7a8382..8022ef27cc5a1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -35753,6 +35753,8 @@ package android.provider { method public static boolean putInt(android.content.ContentResolver, java.lang.String, int); method public static boolean putLong(android.content.ContentResolver, java.lang.String, long); method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String); + method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean); + method public static void resetToDefaults(android.content.ContentResolver, java.lang.String); field public static final java.lang.String ADB_ENABLED = "adb_enabled"; field public static final java.lang.String AIRPLANE_MODE_ON = "airplane_mode_on"; field public static final java.lang.String AIRPLANE_MODE_RADIOS = "airplane_mode_radios"; @@ -35826,6 +35828,8 @@ package android.provider { method public static boolean putInt(android.content.ContentResolver, java.lang.String, int); method public static boolean putLong(android.content.ContentResolver, java.lang.String, long); method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String); + method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean); + method public static void resetToDefaults(android.content.ContentResolver, java.lang.String); method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean); field public static final java.lang.String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled"; field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled"; diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 1ba68a64dab42..2590a6beda390 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -221,4 +221,9 @@ public abstract class PackageManagerInternal { public abstract void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj, Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage, int userId); + + /** + * @return The SetupWizard package name. + */ + public abstract String getSetupWizardPackageName(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 37222ade98866..53f0a5ca34be2 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -16,11 +16,17 @@ package android.provider; +import android.Manifest; +import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; +import android.annotation.UserIdInt; import android.app.ActivityThread; import android.app.AppOpsManager; import android.app.Application; @@ -66,6 +72,8 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.widget.ILockSettings; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.HashMap; @@ -347,7 +355,6 @@ public final class Settings { * Input: Nothing. *
* Output: Nothing. - */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_WIFI_SETTINGS = @@ -1211,8 +1218,6 @@ public final class Settings { public static final String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS"; - - /** * Activity Action: Show Default apps settings. *
@@ -1387,6 +1392,21 @@ public final class Settings { */ public static final String CALL_METHOD_USER_KEY = "_user"; + /** + * @hide - Boolean argument extra to the fast-path call()-based requests + */ + public static final String CALL_METHOD_MAKE_DEFAULT_KEY = "_make_default"; + + /** + * @hide - User handle argument extra to the fast-path call()-based requests + */ + public static final String CALL_METHOD_RESET_MODE_KEY = "_reset_mode"; + + /** + * @hide - String argument extra to the fast-path call()-based requests + */ + public static final String CALL_METHOD_TAG_KEY = "_tag"; + /** @hide - Private call() method to write to 'system' table */ public static final String CALL_METHOD_PUT_SYSTEM = "PUT_system"; @@ -1396,6 +1416,12 @@ public final class Settings { /** @hide - Private call() method to write to 'global' table */ public static final String CALL_METHOD_PUT_GLOBAL= "PUT_global"; + /** @hide - Private call() method to reset to defaults the 'global' table */ + public static final String CALL_METHOD_RESET_GLOBAL = "RESET_global"; + + /** @hide - Private call() method to reset to defaults the 'secure' table */ + public static final String CALL_METHOD_RESET_SECURE = "RESET_secure"; + /** * Activity Extra: Limit available options in launched activity based on the given authority. *
@@ -1471,6 +1497,55 @@ public final class Settings { public static final String EXTRA_DO_NOT_DISTURB_MODE_MINUTES = "android.settings.extra.do_not_disturb_mode_minutes"; + /** + * Reset mode: reset to defaults only settings changed by the + * calling package. If there is a default set the setting + * will be set to it, otherwise the setting will be deleted. + * This is the only type of reset available to non-system clients. + * @hide + */ + public static final int RESET_MODE_PACKAGE_DEFAULTS = 1; + + /** + * Reset mode: reset all settings set by untrusted packages, which is + * packages that aren't a part of the system, to the current defaults. + * If there is a default set the setting will be set to it, otherwise + * the setting will be deleted. This mode is only available to the system. + * @hide + */ + public static final int RESET_MODE_UNTRUSTED_DEFAULTS = 2; + + /** + * Reset mode: delete all settings set by untrusted packages, which is + * packages that aren't a part of the system. If a setting is set by an + * untrusted package it will be deleted if its default is not provided + * by the system, otherwise the setting will be set to its default. + * This mode is only available to the system. + * @hide + */ + public static final int RESET_MODE_UNTRUSTED_CHANGES = 3; + + /** + * Reset mode: reset all settings to defaults specified by trusted + * packages, which is packages that are a part of the system, and + * delete all settings set by untrusted packages. If a setting has + * a default set by a system package it will be set to the default, + * otherwise the setting will be deleted. This mode is only available + * to the system. + * @hide + */ + public static final int RESET_MODE_TRUSTED_DEFAULTS = 4; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + RESET_MODE_PACKAGE_DEFAULTS, + RESET_MODE_UNTRUSTED_DEFAULTS, + RESET_MODE_UNTRUSTED_CHANGES, + RESET_MODE_TRUSTED_DEFAULTS + }) + public @interface ResetMode{} + /** * Activity Extra: Number of certificates *
@@ -1574,22 +1649,44 @@ public final class Settings {
}
}
+ private static final class ContentProviderHolder {
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private final Uri mUri;
+ @GuardedBy("mLock")
+ private IContentProvider mContentProvider;
+
+ public ContentProviderHolder(Uri uri) {
+ mUri = uri;
+ }
+
+ public IContentProvider getProvider(ContentResolver contentResolver) {
+ synchronized (mLock) {
+ if (mContentProvider == null) {
+ mContentProvider = contentResolver
+ .acquireProvider(mUri.getAuthority());
+ }
+ return mContentProvider;
+ }
+ }
+ }
+
// Thread-safe.
private static class NameValueCache {
private static final boolean DEBUG = false;
- private final Uri mUri;
-
private static final String[] SELECT_VALUE_PROJECTION = new String[] {
Settings.NameValueTable.VALUE
};
+
private static final String NAME_EQ_PLACEHOLDER = "name=?";
// Must synchronize on 'this' to access mValues and mValuesVersion.
private final HashMap
+ * The method takes an optional tag to associate with the setting
+ * which can be used to clear only settings made by your package and
+ * associated with this tag by passing the tag to {@link
+ * #resetToDefaults(ContentResolver, String)}. Anyone can override
+ * the current tag. Also if another package changes the setting
+ * then the tag will be set to the one specified in the set call
+ * which can be null. Also any of the settings setters that do not
+ * take a tag as an argument effectively clears the tag.
+ *
+ * For example, if you set settings A and B with tags T1 and T2 and
+ * another app changes setting A (potentially to the same value), it
+ * can assign to it a tag T3 (note that now the package that changed
+ * the setting is not yours). Now if you reset your changes for T1 and
+ * T2 only setting B will be reset and A not (as it was changed by
+ * another package) but since A did not change you are in the desired
+ * initial state. Now if the other app changes the value of A (assuming
+ * you registered an observer in the beginning) you would detect that
+ * the setting was changed by another app and handle this appropriately
+ * (ignore, set back to some value, etc).
+ *
+ * Also the method takes an argument whether to make the value the
+ * default for this setting. If the system already specified a default
+ * value, then the one passed in here will not
+ * be set as the default.
+ *
+ * The method takes an optional tag to associate with the setting
+ * which can be used to clear only settings made by your package and
+ * associated with this tag by passing the tag to {@link
+ * #resetToDefaults(ContentResolver, String)}. Anyone can override
+ * the current tag. Also if another package changes the setting
+ * then the tag will be set to the one specified in the set call
+ * which can be null. Also any of the settings setters that do not
+ * take a tag as an argument effectively clears the tag.
+ *
+ * For example, if you set settings A and B with tags T1 and T2 and
+ * another app changes setting A (potentially to the same value), it
+ * can assign to it a tag T3 (note that now the package that changed
+ * the setting is not yours). Now if you reset your changes for T1 and
+ * T2 only setting B will be reset and A not (as it was changed by
+ * another package) but since A did not change you are in the desired
+ * initial state. Now if the other app changes the value of A (assuming
+ * you registered an observer in the beginning) you would detect that
+ * the setting was changed by another app and handle this appropriately
+ * (ignore, set back to some value, etc).
+ *
+ * Also the method takes an argument whether to make the value the
+ * default for this setting. If the system already specified a default
+ * value, then the one passed in here will not
+ * be set as the default.
+ *
* This class is a content provider that publishes the system settings.
@@ -147,6 +151,7 @@ public class SettingsProvider extends ContentProvider {
private static final int MUTATION_OPERATION_INSERT = 1;
private static final int MUTATION_OPERATION_DELETE = 2;
private static final int MUTATION_OPERATION_UPDATE = 3;
+ private static final int MUTATION_OPERATION_RESET = 4;
private static final String[] ALL_COLUMNS = new String[] {
Settings.NameValueTable._ID,
@@ -292,13 +297,17 @@ public class SettingsProvider extends ContentProvider {
case Settings.CALL_METHOD_PUT_GLOBAL: {
String value = getSettingValue(args);
- insertGlobalSetting(name, value, requestingUserId, false);
+ String tag = getSettingTag(args);
+ final boolean makeDefault = getSettingMakeDefault(args);
+ insertGlobalSetting(name, value, tag, makeDefault, requestingUserId, false);
break;
}
case Settings.CALL_METHOD_PUT_SECURE: {
String value = getSettingValue(args);
- insertSecureSetting(name, value, requestingUserId, false);
+ String tag = getSettingTag(args);
+ final boolean makeDefault = getSettingMakeDefault(args);
+ insertSecureSetting(name, value, tag, makeDefault, requestingUserId, false);
break;
}
@@ -308,6 +317,20 @@ public class SettingsProvider extends ContentProvider {
break;
}
+ case Settings.CALL_METHOD_RESET_GLOBAL: {
+ final int mode = getResetModeEnforcingPermission(args);
+ String tag = getSettingTag(args);
+ resetGlobalSetting(requestingUserId, mode, tag);
+ break;
+ }
+
+ case Settings.CALL_METHOD_RESET_SECURE: {
+ final int mode = getResetModeEnforcingPermission(args);
+ String tag = getSettingTag(args);
+ resetSecureSetting(requestingUserId, mode, tag);
+ break;
+ }
+
default: {
Slog.w(LOG_TAG, "call() with invalid method: " + method);
} break;
@@ -399,13 +422,15 @@ public class SettingsProvider extends ContentProvider {
switch (table) {
case TABLE_GLOBAL: {
- if (insertGlobalSetting(name, value, UserHandle.getCallingUserId(), false)) {
+ if (insertGlobalSetting(name, value, null, false,
+ UserHandle.getCallingUserId(), false)) {
return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
}
} break;
case TABLE_SECURE: {
- if (insertSecureSetting(name, value, UserHandle.getCallingUserId(), false)) {
+ if (insertSecureSetting(name, value, null, false,
+ UserHandle.getCallingUserId(), false)) {
return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
}
} break;
@@ -503,12 +528,14 @@ public class SettingsProvider extends ContentProvider {
switch (args.table) {
case TABLE_GLOBAL: {
final int userId = UserHandle.getCallingUserId();
- return updateGlobalSetting(args.name, value, userId, false) ? 1 : 0;
+ return updateGlobalSetting(args.name, value, null, false,
+ userId, false) ? 1 : 0;
}
case TABLE_SECURE: {
final int userId = UserHandle.getCallingUserId();
- return updateSecureSetting(args.name, value, userId, false) ? 1 : 0;
+ return updateSecureSetting(args.name, value, null, false,
+ userId, false) ? 1 : 0;
}
case TABLE_SYSTEM: {
@@ -586,10 +613,9 @@ public class SettingsProvider extends ContentProvider {
SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
if (globalSettings != null) {
dumpSettingsLocked(globalSettings, pw);
+ pw.println();
+ globalSettings.dumpHistoricalOperations(pw);
}
- pw.println();
-
- globalSettings.dumpHistoricalOperations(pw);
}
pw.println("SECURE SETTINGS (user " + userId + ")");
@@ -597,20 +623,18 @@ public class SettingsProvider extends ContentProvider {
SETTINGS_TYPE_SECURE, userId);
if (secureSettings != null) {
dumpSettingsLocked(secureSettings, pw);
+ pw.println();
+ secureSettings.dumpHistoricalOperations(pw);
}
- pw.println();
-
- secureSettings.dumpHistoricalOperations(pw);
pw.println("SYSTEM SETTINGS (user " + userId + ")");
SettingsState systemSettings = mSettingsRegistry.getSettingsLocked(
SETTINGS_TYPE_SYSTEM, userId);
if (systemSettings != null) {
dumpSettingsLocked(systemSettings, pw);
+ pw.println();
+ systemSettings.dumpHistoricalOperations(pw);
}
- pw.println();
-
- systemSettings.dumpHistoricalOperations(pw);
}
private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) {
@@ -624,9 +648,16 @@ public class SettingsProvider extends ContentProvider {
pw.print("_id:"); pw.print(toDumpString(setting.getId()));
pw.print(" name:"); pw.print(toDumpString(name));
if (setting.getPackageName() != null) {
- pw.print(" pkg:"); pw.print(toDumpString(setting.getPackageName()));
+ pw.print(" pkg:"); pw.print(setting.getPackageName());
}
pw.print(" value:"); pw.print(toDumpString(setting.getValue()));
+ if (setting.getDefaultValue() != null) {
+ pw.print(" default:"); pw.print(setting.getDefaultValue());
+ pw.print(" defaultSystemSet:"); pw.print(setting.isDefaultSystemSet());
+ }
+ if (setting.getTag() != null) {
+ pw.print(" tag:"); pw.print(setting.getTag());
+ }
pw.println();
}
}
@@ -691,73 +722,79 @@ public class SettingsProvider extends ContentProvider {
// value with a forced update to ensure that all cross profile dependencies
// are taken into account. Also make sure the settings update to.. the same
// value passes the security checks, so clear binder calling id.
- if (newRestrictions.containsKey(UserManager.DISALLOW_SHARE_LOCATION)
- != prevRestrictions.containsKey(UserManager.DISALLOW_SHARE_LOCATION)) {
+ if (newRestrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION)
+ != prevRestrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION)) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
Setting setting = getSecureSetting(
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, userId);
updateSecureSetting(Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- setting != null ? setting.getValue() : null, userId, true);
+ setting != null ? setting.getValue() : null, null,
+ true, userId, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- if (newRestrictions.containsKey(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
- != prevRestrictions.containsKey(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) {
+ if (newRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
+ != prevRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
Setting setting = getGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS);
+ String value = setting != null ? setting.getValue() : null;
updateGlobalSetting(Settings.Global.INSTALL_NON_MARKET_APPS,
- setting != null ? setting.getValue() : null, userId, true);
+ value, null, true, userId, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- if (newRestrictions.containsKey(UserManager.DISALLOW_DEBUGGING_FEATURES)
- != prevRestrictions.containsKey(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
+ if (newRestrictions.getBoolean(UserManager.DISALLOW_DEBUGGING_FEATURES)
+ != prevRestrictions.getBoolean(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
Setting setting = getGlobalSetting(Settings.Global.ADB_ENABLED);
+ String value = setting != null ? setting.getValue() : null;
updateGlobalSetting(Settings.Global.ADB_ENABLED,
- setting != null ? setting.getValue() : null, userId, true);
+ value, null, true, userId, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- if (newRestrictions.containsKey(UserManager.ENSURE_VERIFY_APPS)
- != prevRestrictions.containsKey(UserManager.ENSURE_VERIFY_APPS)) {
+ if (newRestrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)
+ != prevRestrictions.getBoolean(UserManager.ENSURE_VERIFY_APPS)) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
Setting enable = getGlobalSetting(
Settings.Global.PACKAGE_VERIFIER_ENABLE);
+ String enableValue = enable != null ? enable.getValue() : null;
updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_ENABLE,
- enable != null ? enable.getValue() : null, userId, true);
+ enableValue, null, true, userId, true);
Setting include = getGlobalSetting(
Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB);
+ String includeValue = include != null ? include.getValue() : null;
updateGlobalSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
- include != null ? include.getValue() : null, userId, true);
+ includeValue, null, true, userId, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- if (newRestrictions.containsKey(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
- != prevRestrictions.containsKey(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
+ if (newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
+ != prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
Setting setting = getGlobalSetting(
Settings.Global.PREFERRED_NETWORK_MODE);
+ String value = setting != null ? setting.getValue() : null;
updateGlobalSetting(Settings.Global.PREFERRED_NETWORK_MODE,
- setting != null ? setting.getValue() : null, userId, true);
+ value, null, true, userId, true);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -806,34 +843,49 @@ public class SettingsProvider extends ContentProvider {
}
}
- private boolean updateGlobalSetting(String name, String value, int requestingUserId,
- boolean forceNotify) {
+ private boolean updateGlobalSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
- Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ")");
+ Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ", "
+ + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ + ", " + forceNotify + ")");
}
- return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE,
- forceNotify);
+ return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
+ MUTATION_OPERATION_UPDATE, forceNotify, 0);
}
- private boolean insertGlobalSetting(String name, String value, int requestingUserId,
- boolean forceNotify) {
+ private boolean insertGlobalSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
- Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ")");
+ Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ", "
+ + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ + ", " + forceNotify + ")");
}
- return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT,
- forceNotify);
+ return mutateGlobalSetting(name, value, tag, makeDefault, requestingUserId,
+ MUTATION_OPERATION_INSERT, forceNotify, 0);
}
private boolean deleteGlobalSetting(String name, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
- Slog.v(LOG_TAG, "deleteGlobalSettingLocked(" + name + ")");
+ Slog.v(LOG_TAG, "deleteGlobalSetting(" + name + ", " + requestingUserId
+ + ", " + forceNotify + ")");
}
- return mutateGlobalSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE,
- forceNotify);
+ return mutateGlobalSetting(name, null, null, false, requestingUserId,
+ MUTATION_OPERATION_DELETE, forceNotify, 0);
}
- private boolean mutateGlobalSetting(String name, String value, int requestingUserId,
- int operation, boolean forceNotify) {
+ private void resetGlobalSetting(int requestingUserId, int mode, String tag) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "resetGlobalSetting(" + requestingUserId + ", "
+ + mode + ", " + tag + ")");
+ }
+ mutateGlobalSetting(null, null, tag, false, requestingUserId,
+ MUTATION_OPERATION_RESET, false, mode);
+ }
+
+ private boolean mutateGlobalSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+ int mode) {
// Make sure the caller can change the settings - treated as secure.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -842,7 +894,7 @@ public class SettingsProvider extends ContentProvider {
// If this is a setting that is currently restricted for this user, do not allow
// unrestricting changes.
- if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
+ if (name != null && isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
Binder.getCallingUid())) {
return false;
}
@@ -851,9 +903,9 @@ public class SettingsProvider extends ContentProvider {
synchronized (mLock) {
switch (operation) {
case MUTATION_OPERATION_INSERT: {
- return mSettingsRegistry
- .insertSettingLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM,
- name, value, getCallingPackage(), forceNotify);
+ return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
+ getCallingPackage(), forceNotify);
}
case MUTATION_OPERATION_DELETE: {
@@ -862,10 +914,15 @@ public class SettingsProvider extends ContentProvider {
}
case MUTATION_OPERATION_UPDATE: {
- return mSettingsRegistry
- .updateSettingLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM,
- name, value, getCallingPackage(), forceNotify);
+ return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
+ getCallingPackage(), forceNotify);
}
+
+ case MUTATION_OPERATION_RESET: {
+ mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+ } return true;
}
}
@@ -934,39 +991,53 @@ public class SettingsProvider extends ContentProvider {
}
}
- private boolean insertSecureSetting(String name, String value, int requestingUserId,
- boolean forceNotify) {
+ private boolean insertSecureSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
- + requestingUserId + ")");
+ + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ + ", " + forceNotify + ")");
}
- return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT,
- forceNotify);
+ return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
+ MUTATION_OPERATION_INSERT, forceNotify, 0);
}
private boolean deleteSecureSetting(String name, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
- Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId + ")");
+ Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId
+ + ", " + forceNotify + ")");
}
- return mutateSecureSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE,
- forceNotify);
+ return mutateSecureSetting(name, null, null, false, requestingUserId,
+ MUTATION_OPERATION_DELETE, forceNotify, 0);
}
- private boolean updateSecureSetting(String name, String value, int requestingUserId,
- boolean forceNotify) {
+ private boolean updateSecureSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, boolean forceNotify) {
if (DEBUG) {
Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
- + requestingUserId + ")");
+ + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ + ", " + forceNotify +")");
}
- return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE,
- forceNotify);
+ return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
+ MUTATION_OPERATION_UPDATE, forceNotify, 0);
}
- private boolean mutateSecureSetting(String name, String value, int requestingUserId,
- int operation, boolean forceNotify) {
+ private void resetSecureSetting(int requestingUserId, int mode, String tag) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "resetSecureSetting(" + requestingUserId + ", "
+ + mode + ", " + tag + ")");
+ }
+
+ mutateSecureSetting(null, null, tag, false, requestingUserId,
+ MUTATION_OPERATION_RESET, false, mode);
+ }
+
+ private boolean mutateSecureSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+ int mode) {
// Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -975,7 +1046,7 @@ public class SettingsProvider extends ContentProvider {
// If this is a setting that is currently restricted for this user, do not allow
// unrestricting changes.
- if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
+ if (name != null && isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
Binder.getCallingUid())) {
return false;
}
@@ -990,7 +1061,8 @@ public class SettingsProvider extends ContentProvider {
// Special cases for location providers (sigh).
if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
- return updateLocationProvidersAllowedLocked(value, owningUserId, forceNotify);
+ return updateLocationProvidersAllowedLocked(value, tag, owningUserId, makeDefault,
+ forceNotify);
}
// Mutate the value.
@@ -998,7 +1070,8 @@ public class SettingsProvider extends ContentProvider {
switch (operation) {
case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
- owningUserId, name, value, getCallingPackage(), forceNotify);
+ owningUserId, name, value, tag, makeDefault,
+ getCallingPackage(), forceNotify);
}
case MUTATION_OPERATION_DELETE: {
@@ -1008,8 +1081,14 @@ public class SettingsProvider extends ContentProvider {
case MUTATION_OPERATION_UPDATE: {
return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE,
- owningUserId, name, value, getCallingPackage(), forceNotify);
+ owningUserId, name, value, tag, makeDefault,
+ getCallingPackage(), forceNotify);
}
+
+ case MUTATION_OPERATION_RESET: {
+ mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE,
+ UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+ } return true;
}
}
@@ -1138,7 +1217,7 @@ public class SettingsProvider extends ContentProvider {
case MUTATION_OPERATION_INSERT: {
validateSystemSettingValue(name, value);
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
- owningUserId, name, value, getCallingPackage(), false);
+ owningUserId, name, value, null, false, getCallingPackage(), false);
}
case MUTATION_OPERATION_DELETE: {
@@ -1149,7 +1228,7 @@ public class SettingsProvider extends ContentProvider {
case MUTATION_OPERATION_UPDATE: {
validateSystemSettingValue(name, value);
return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM,
- owningUserId, name, value, getCallingPackage(), false);
+ owningUserId, name, value, null, false, getCallingPackage(), false);
}
}
@@ -1240,7 +1319,8 @@ public class SettingsProvider extends ContentProvider {
case Settings.Secure.ALWAYS_ON_VPN_APP:
case Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN:
// Whitelist system uid (ConnectivityService) and root uid to change always-on vpn
- if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
+ final int appId = UserHandle.getAppId(callingUid);
+ if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
return false;
}
restriction = UserManager.DISALLOW_CONFIG_VPN;
@@ -1294,9 +1374,10 @@ public class SettingsProvider extends ContentProvider {
String name, int userId) {
// System/root/shell can mutate whatever secure settings they want.
final int callingUid = Binder.getCallingUid();
- if (callingUid == android.os.Process.SYSTEM_UID
- || callingUid == Process.SHELL_UID
- || callingUid == Process.ROOT_UID) {
+ final int appId = UserHandle.getAppId(callingUid);
+ if (appId == android.os.Process.SYSTEM_UID
+ || appId == Process.SHELL_UID
+ || appId == Process.ROOT_UID) {
return;
}
@@ -1392,8 +1473,8 @@ public class SettingsProvider extends ContentProvider {
*
* @returns whether the enabled location providers changed.
*/
- private boolean updateLocationProvidersAllowedLocked(String value, int owningUserId,
- boolean forceNotify) {
+ private boolean updateLocationProvidersAllowedLocked(String value, String tag,
+ int owningUserId, boolean makeDefault, boolean forceNotify) {
if (TextUtils.isEmpty(value)) {
return false;
}
@@ -1466,7 +1547,7 @@ public class SettingsProvider extends ContentProvider {
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders,
- getCallingPackage(), forceNotify);
+ tag, makeDefault, getCallingPackage(), forceNotify);
}
private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
@@ -1509,8 +1590,8 @@ public class SettingsProvider extends ContentProvider {
}
Bundle result = new Bundle();
result.putString(Settings.NameValueTable.VALUE,
- setting != null && !setting.isNull() ? setting.getValue() : null);
- mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getkey());
+ !setting.isNull() ? setting.getValue() : null);
+ mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
return result;
}
@@ -1528,6 +1609,51 @@ public class SettingsProvider extends ContentProvider {
return (args != null) ? args.getString(Settings.NameValueTable.VALUE) : null;
}
+ private static String getSettingTag(Bundle args) {
+ return (args != null) ? args.getString(Settings.CALL_METHOD_TAG_KEY) : null;
+ }
+
+ private static boolean getSettingMakeDefault(Bundle args) {
+ return (args != null) && args.getBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY);
+ }
+
+ private static int getResetModeEnforcingPermission(Bundle args) {
+ final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
+ switch (mode) {
+ case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
+ if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
+ throw new SecurityException("Only system, shell/root on a "
+ + "debuggable build can reset to untrusted defaults");
+ }
+ return mode;
+ }
+ case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
+ if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
+ throw new SecurityException("Only system, shell/root on a "
+ + "debuggable build can reset untrusted changes");
+ }
+ return mode;
+ }
+ case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
+ if (!isCallerSystemOrShellOrRootOnDebuggableBuild()) {
+ throw new SecurityException("Only system, shell/root on a "
+ + "debuggable build can reset to trusted defaults");
+ }
+ return mode;
+ }
+ case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
+ return mode;
+ }
+ }
+ throw new IllegalArgumentException("Invalid reset mode: " + mode);
+ }
+
+ private static boolean isCallerSystemOrShellOrRootOnDebuggableBuild() {
+ final int appId = UserHandle.getAppId(Binder.getCallingUid());
+ return appId == SYSTEM_UID || (Build.IS_DEBUGGABLE
+ && (appId == SHELL_UID || appId == ROOT_UID));
+ }
+
private static String getValidTableOrThrow(Uri uri) {
if (uri.getPathSegments().size() > 0) {
String table = uri.getPathSegments().get(0);
@@ -1767,8 +1893,8 @@ public class SettingsProvider extends ContentProvider {
private void ensureSettingsStateLocked(int key) {
if (mSettingsStates.get(key) == null) {
final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
- SettingsState settingsState = new SettingsState(mLock, getSettingsFile(key), key,
- maxBytesPerPackage, mHandlerThread.getLooper());
+ SettingsState settingsState = new SettingsState(getContext(), mLock,
+ getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
mSettingsStates.put(key, settingsState);
}
}
@@ -1815,12 +1941,15 @@ public class SettingsProvider extends ContentProvider {
}
public boolean insertSettingLocked(int type, int userId, String name, String value,
- String packageName, boolean forceNotify) {
+ String tag, boolean makeDefault, String packageName, boolean forceNotify) {
final int key = makeKey(type, userId);
+ boolean success = false;
SettingsState settingsState = peekSettingsStateLocked(key);
- final boolean success = settingsState != null
- && settingsState.insertSettingLocked(name, value, packageName);
+ if (settingsState != null) {
+ success = settingsState.insertSettingLocked(name, value,
+ tag, makeDefault, packageName);
+ }
if (forceNotify || success) {
notifyForSettingsChange(key, name);
@@ -1831,11 +1960,11 @@ public class SettingsProvider extends ContentProvider {
public boolean deleteSettingLocked(int type, int userId, String name, boolean forceNotify) {
final int key = makeKey(type, userId);
+ boolean success = false;
SettingsState settingsState = peekSettingsStateLocked(key);
- if (settingsState == null) {
- return false;
+ if (settingsState != null) {
+ success = settingsState.deleteSettingLocked(name);
}
- final boolean success = settingsState.deleteSettingLocked(name);
if (forceNotify || success) {
notifyForSettingsChange(key, name);
@@ -1854,12 +1983,15 @@ public class SettingsProvider extends ContentProvider {
}
public boolean updateSettingLocked(int type, int userId, String name, String value,
- String packageName, boolean forceNotify) {
+ String tag, boolean makeDefault, String packageName, boolean forceNotify) {
final int key = makeKey(type, userId);
+ boolean success = false;
SettingsState settingsState = peekSettingsStateLocked(key);
- final boolean success = settingsState != null
- && settingsState.updateSettingLocked(name, value, packageName);
+ if (settingsState != null) {
+ success = settingsState.updateSettingLocked(name, value, tag,
+ makeDefault, packageName);
+ }
if (forceNotify || success) {
notifyForSettingsChange(key, name);
@@ -1868,6 +2000,72 @@ public class SettingsProvider extends ContentProvider {
return success;
}
+ public void resetSettingsLocked(int type, int userId, String packageName, int mode,
+ String tag) {
+ final int key = makeKey(type, userId);
+ SettingsState settingsState = peekSettingsStateLocked(key);
+ if (settingsState == null) {
+ return;
+ }
+
+ switch (mode) {
+ case Settings.RESET_MODE_PACKAGE_DEFAULTS: {
+ for (String name : settingsState.getSettingNamesLocked()) {
+ Setting setting = settingsState.getSettingLocked(name);
+ if (packageName.equals(setting.getPackageName())) {
+ if (tag != null && !tag.equals(setting.getTag())) {
+ continue;
+ }
+ if (settingsState.resetSettingLocked(name, packageName)) {
+ notifyForSettingsChange(key, name);
+ }
+ }
+ }
+ } break;
+
+ case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
+ for (String name : settingsState.getSettingNamesLocked()) {
+ Setting setting = settingsState.getSettingLocked(name);
+ if (!SettingsState.isSystemPackage(getContext(),
+ setting.getPackageName())) {
+ if (settingsState.resetSettingLocked(name, packageName)) {
+ notifyForSettingsChange(key, name);
+ }
+ }
+ }
+ } break;
+
+ case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
+ for (String name : settingsState.getSettingNamesLocked()) {
+ Setting setting = settingsState.getSettingLocked(name);
+ if (!SettingsState.isSystemPackage(getContext(),
+ setting.getPackageName())) {
+ if (setting.isDefaultSystemSet()) {
+ if (settingsState.resetSettingLocked(name, packageName)) {
+ notifyForSettingsChange(key, name);
+ }
+ } else if (settingsState.deleteSettingLocked(name)) {
+ notifyForSettingsChange(key, name);
+ }
+ }
+ }
+ } break;
+
+ case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
+ for (String name : settingsState.getSettingNamesLocked()) {
+ Setting setting = settingsState.getSettingLocked(name);
+ if (setting.isDefaultSystemSet()) {
+ if (settingsState.resetSettingLocked(name, packageName)) {
+ notifyForSettingsChange(key, name);
+ }
+ } else if (settingsState.deleteSettingLocked(name)) {
+ notifyForSettingsChange(key, name);
+ }
+ }
+ } break;
+ }
+ }
+
public void onPackageRemovedLocked(String packageName, int userId) {
// Global and secure settings are signature protected. Apps signed
// by the platform certificate are generally not uninstalled and
@@ -2005,7 +2203,7 @@ public class SettingsProvider extends ContentProvider {
while (!cursor.isAfterLast()) {
String name = cursor.getString(nameColumnIdx);
String value = cursor.getString(valueColumnIdx);
- settingsState.insertSettingLocked(name, value,
+ settingsState.insertSettingLocked(name, value, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
cursor.moveToNext();
}
@@ -2037,7 +2235,7 @@ public class SettingsProvider extends ContentProvider {
String androidId = Long.toHexString(new SecureRandom().nextLong());
secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
+ "] for user " + userId);
@@ -2221,7 +2419,8 @@ public class SettingsProvider extends ContentProvider {
String reason = "Settings rebuilt! Current version: "
+ curVersion + " while expected: " + newVersion;
getGlobalSettingsLocked().insertSettingLocked(
- Settings.Global.DATABASE_DOWNGRADE_REASON, reason, "android");
+ Settings.Global.DATABASE_DOWNGRADE_REASON,
+ reason, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
// Set the global settings version if owner.
@@ -2290,11 +2489,11 @@ public class SettingsProvider extends ContentProvider {
if (userId == UserHandle.USER_SYSTEM) {
final SettingsState globalSettings = getGlobalSettingsLocked();
globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
- Integer.toString(Settings.Global.ZEN_MODE_OFF),
- SettingsState.SYSTEM_PACKAGE_NAME);
+ Integer.toString(Settings.Global.ZEN_MODE_OFF), null,
+ true, SettingsState.SYSTEM_PACKAGE_NAME);
globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER,
- Integer.toString(AudioManager.RINGER_MODE_NORMAL),
- SettingsState.SYSTEM_PACKAGE_NAME);
+ Integer.toString(AudioManager.RINGER_MODE_NORMAL), null,
+ true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 119;
}
@@ -2304,7 +2503,7 @@ public class SettingsProvider extends ContentProvider {
SettingsState secureSettings = getSecureSettingsLocked(userId);
secureSettings.insertSettingLocked(Settings.Secure.DOUBLE_TAP_TO_WAKE,
getContext().getResources().getBoolean(
- R.bool.def_double_tap_to_wake) ? "1" : "0",
+ R.bool.def_double_tap_to_wake) ? "1" : "0", null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 120;
@@ -2329,8 +2528,7 @@ public class SettingsProvider extends ContentProvider {
currentSetting.isNull()) {
secureSettings.insertSettingLocked(
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
- defaultComponent,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ defaultComponent, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 122;
}
@@ -2347,7 +2545,7 @@ public class SettingsProvider extends ContentProvider {
Settings.Global.ADD_USERS_WHEN_LOCKED,
getContext().getResources().getBoolean(
R.bool.def_add_users_from_lockscreen) ? "1" : "0",
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
}
currentVersion = 123;
@@ -2358,7 +2556,7 @@ public class SettingsProvider extends ContentProvider {
String defaultDisabledProfiles = (getContext().getResources().getString(
R.string.def_bluetooth_disabled_profiles));
globalSettings.insertSettingLocked(Settings.Global.BLUETOOTH_DISABLED_PROFILES,
- defaultDisabledProfiles, SettingsState.SYSTEM_PACKAGE_NAME);
+ defaultDisabledProfiles, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 124;
}
@@ -2373,7 +2571,7 @@ public class SettingsProvider extends ContentProvider {
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
getContext().getResources().getBoolean(
R.bool.def_show_ime_with_hard_keyboard) ? "1" : "0",
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 125;
}
@@ -2400,7 +2598,7 @@ public class SettingsProvider extends ContentProvider {
}
secureSettings.insertSettingLocked(
Settings.Secure.ENABLED_VR_LISTENERS, b.toString(),
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
}
@@ -2420,7 +2618,7 @@ public class SettingsProvider extends ContentProvider {
final SettingsState secureSettings = getSecureSettingsLocked(userId);
secureSettings.insertSettingLocked(
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- showNotifications.getValue(),
+ showNotifications.getValue(), null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
@@ -2430,7 +2628,7 @@ public class SettingsProvider extends ContentProvider {
final SettingsState secureSettings = getSecureSettingsLocked(userId);
secureSettings.insertSettingLocked(
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- allowPrivate.getValue(),
+ allowPrivate.getValue(), null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
}
@@ -2456,7 +2654,7 @@ public class SettingsProvider extends ContentProvider {
if (policyAccess.isNull()) {
systemSecureSettings.insertSettingLocked(
Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
- defaultPolicyAccess,
+ defaultPolicyAccess, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
} else {
StringBuilder currentSetting =
@@ -2465,7 +2663,7 @@ public class SettingsProvider extends ContentProvider {
currentSetting.append(defaultPolicyAccess);
systemSecureSettings.updateSettingLocked(
Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
- currentSetting.toString(),
+ currentSetting.toString(), null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
}
@@ -2485,7 +2683,7 @@ public class SettingsProvider extends ContentProvider {
Settings.Secure.LONG_PRESS_TIMEOUT,
String.valueOf(getContext().getResources().getInteger(
R.integer.def_long_press_timeout_millis)),
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 130;
}
@@ -2498,9 +2696,9 @@ public class SettingsProvider extends ContentProvider {
if (dozeExplicitlyDisabled) {
secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_PICK_UP,
- "0", SettingsState.SYSTEM_PACKAGE_NAME);
+ "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
- "0", SettingsState.SYSTEM_PACKAGE_NAME);
+ "0", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 131;
}
@@ -2515,7 +2713,7 @@ public class SettingsProvider extends ContentProvider {
Settings.Secure.MULTI_PRESS_TIMEOUT,
String.valueOf(getContext().getResources().getInteger(
R.integer.def_multi_press_timeout_millis)),
- SettingsState.SYSTEM_PACKAGE_NAME);
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 132;
@@ -2527,9 +2725,8 @@ public class SettingsProvider extends ContentProvider {
String defaultSyncParentSounds = (getContext().getResources()
.getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
systemSecureSettings.insertSettingLocked(
- Settings.Secure.SYNC_PARENT_SOUNDS,
- defaultSyncParentSounds,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ Settings.Secure.SYNC_PARENT_SOUNDS, defaultSyncParentSounds,
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 133;
}
@@ -2541,7 +2738,8 @@ public class SettingsProvider extends ContentProvider {
String defaultEndButtonBehavior = Integer.toString(getContext()
.getResources().getInteger(R.integer.def_end_button_behavior));
systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
- defaultEndButtonBehavior, SettingsState.SYSTEM_PACKAGE_NAME);
+ defaultEndButtonBehavior, null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 134;
}
@@ -2565,13 +2763,13 @@ public class SettingsProvider extends ContentProvider {
// A scorer was set so enable recommendations.
globalSettings.insertSettingLocked(
Global.NETWORK_RECOMMENDATIONS_ENABLED,
- "1",
+ "1", null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
// and clear the scorer setting since it's no longer needed.
globalSettings.insertSettingLocked(
Global.NETWORK_SCORER_APP,
- null,
+ null, null, true,
SettingsState.SYSTEM_PACKAGE_NAME);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index cbeb8780be2c3..080805112c650 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -97,6 +97,7 @@ final public class SettingsService extends Binder {
PUT,
DELETE,
LIST,
+ RESET,
}
int mUser = -1; // unspecified
@@ -104,7 +105,10 @@ final public class SettingsService extends Binder {
String mTable = null;
String mKey = null;
String mValue = null;
-
+ String mPackageName = null;
+ String mToken = null;
+ int mResetMode = -1;
+ boolean mMakeDefault;
MyShellCommand(SettingsProvider provider, boolean dumping) {
mProvider = provider;
@@ -142,6 +146,8 @@ final public class SettingsService extends Binder {
mVerb = CommandVerb.DELETE;
} else if ("list".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.LIST;
+ } else if ("reset".equalsIgnoreCase(arg)) {
+ mVerb = CommandVerb.RESET;
} else {
// invalid
perr.println("Invalid command: " + arg);
@@ -159,6 +165,35 @@ final public class SettingsService extends Binder {
valid = true;
break;
}
+ } else if (mVerb == CommandVerb.RESET) {
+ if ("untrusted_defaults".equalsIgnoreCase(arg)) {
+ mResetMode = Settings.RESET_MODE_UNTRUSTED_DEFAULTS;
+ } else if ("untrusted_clear".equalsIgnoreCase(arg)) {
+ mResetMode = Settings.RESET_MODE_UNTRUSTED_CHANGES;
+ } else if ("trusted_defaults".equalsIgnoreCase(arg)) {
+ mResetMode = Settings.RESET_MODE_TRUSTED_DEFAULTS;
+ } else {
+ mPackageName = arg;
+ mResetMode = Settings.RESET_MODE_PACKAGE_DEFAULTS;
+ if (peekNextArg() == null) {
+ valid = true;
+ } else {
+ mToken = getNextArg();
+ if (peekNextArg() == null) {
+ valid = true;
+ } else {
+ perr.println("Too many arguments");
+ return -1;
+ }
+ }
+ break;
+ }
+ if (peekNextArg() == null) {
+ valid = true;
+ } else {
+ perr.println("Too many arguments");
+ return -1;
+ }
} else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
mKey = arg;
if (peekNextArg() == null) {
@@ -171,8 +206,32 @@ final public class SettingsService extends Binder {
} else if (mKey == null) {
mKey = arg;
// keep going; there's another PUT arg
- } else { // PUT, final arg
+ } else if (mValue == null) {
mValue = arg;
+ // keep going; there may be another PUT arg
+ } else if (mToken == null) {
+ mToken = arg;
+ if ("default".equalsIgnoreCase(mToken)) {
+ mToken = null;
+ mMakeDefault = true;
+ if (peekNextArg() == null) {
+ valid = true;
+ } else {
+ perr.println("Too many arguments");
+ return -1;
+ }
+ break;
+ }
+ if (peekNextArg() == null) {
+ valid = true;
+ break;
+ }
+ } else { // PUT, final arg
+ if (!"default".equalsIgnoreCase(arg)) {
+ perr.println("Argument expected to be 'default'");
+ return -1;
+ }
+ mMakeDefault = true;
if (peekNextArg() == null) {
valid = true;
} else {
@@ -214,7 +273,7 @@ final public class SettingsService extends Binder {
pout.println(getForUser(iprovider, mUser, mTable, mKey));
break;
case PUT:
- putForUser(iprovider, mUser, mTable, mKey, mValue);
+ putForUser(iprovider, mUser, mTable, mKey, mValue, mToken, mMakeDefault);
break;
case DELETE:
pout.println("Deleted "
@@ -225,6 +284,9 @@ final public class SettingsService extends Binder {
pout.println(line);
}
break;
+ case RESET:
+ resetForUser(iprovider, mUser, mTable, mToken);
+ break;
default:
perr.println("Unspecified command");
return -1;
@@ -286,11 +348,15 @@ final public class SettingsService extends Binder {
return result;
}
- void putForUser(IContentProvider provider, int userHandle,
- final String table, final String key, final String value) {
+ void putForUser(IContentProvider provider, int userHandle, final String table,
+ final String key, final String value, String token, boolean makeDefault) {
final String callPutCommand;
- if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
- else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
+ if ("system".equals(table)) {
+ callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
+ makeDefault = false;
+ getOutPrintWriter().println("Ignored makeDefault - "
+ + "doesn't apply to system settings");
+ } else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL;
else {
getErrPrintWriter().println("Invalid table; no put performed");
@@ -301,6 +367,10 @@ final public class SettingsService extends Binder {
Bundle arg = new Bundle();
arg.putString(Settings.NameValueTable.VALUE, value);
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+ arg.putString(Settings.CALL_METHOD_TAG_KEY, token);
+ if (makeDefault) {
+ arg.putBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY, true);
+ }
provider.call(resolveCallingPackage(), callPutCommand, key, arg);
} catch (RemoteException e) {
throw new RuntimeException("Failed in IPC", e);
@@ -327,6 +397,29 @@ final public class SettingsService extends Binder {
return num;
}
+ void resetForUser(IContentProvider provider, int userHandle,
+ String table, String token) {
+ final String callResetCommand;
+ if ("secure".equals(table)) callResetCommand = Settings.CALL_METHOD_RESET_SECURE;
+ else if ("global".equals(table)) callResetCommand = Settings.CALL_METHOD_RESET_GLOBAL;
+ else {
+ getErrPrintWriter().println("Invalid table; no reset performed");
+ return;
+ }
+
+ try {
+ Bundle arg = new Bundle();
+ arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+ arg.putInt(Settings.CALL_METHOD_RESET_MODE_KEY, mResetMode);
+ arg.putString(Settings.CALL_METHOD_TAG_KEY, token);
+ String packageName = mPackageName != null ? mPackageName : resolveCallingPackage();
+ arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+ provider.call(packageName, callResetCommand, null, arg);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed in IPC", e);
+ }
+ }
+
public static String resolveCallingPackage() {
switch (Binder.getCallingUid()) {
case Process.ROOT_UID: {
@@ -360,14 +453,18 @@ final public class SettingsService extends Binder {
pw.println(" Print this help text.");
pw.println(" get [--user