Add a new config table to the settings provider for remotely configured parameters. This includes the minimum number of changes necessary to make the table work, but no API surface yet.
Test: local tests
bug: 113100523
Change-Id: I47f89f5e6657a2a347e62cb40924bba4547f7dd9
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 63978ba..256ebbb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -180,6 +180,7 @@
public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM;
public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE;
public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID;
+ public static final int SETTINGS_TYPE_CONFIG = SettingsState.SETTINGS_TYPE_CONFIG;
private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
Settings.NameValueTable.VALUE, null);
@@ -189,6 +190,13 @@
private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
+ /**
+ * TODO(b/113100523): Move this to DeviceConfig.java when it is added, and expose it as a System
+ * API.
+ */
+ private static final Uri CONFIG_CONTENT_URI =
+ Uri.parse("content://" + Settings.AUTHORITY + "/config");
+
static {
for (String name : Resources.getSystem().getStringArray(
com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
@@ -380,6 +388,11 @@
public Bundle call(String method, String name, Bundle args) {
final int requestingUserId = getRequestingUserId(args);
switch (method) {
+ case Settings.CALL_METHOD_GET_CONFIG: {
+ Setting setting = getConfigSetting(name);
+ return packageValueForCallResult(setting, isTrackingGeneration(args));
+ }
+
case Settings.CALL_METHOD_GET_GLOBAL: {
Setting setting = getGlobalSetting(name);
return packageValueForCallResult(setting, isTrackingGeneration(args));
@@ -396,6 +409,14 @@
return packageValueForCallResult(setting, isTrackingGeneration(args));
}
+ case Settings.CALL_METHOD_PUT_CONFIG: {
+ String value = getSettingValue(args);
+ String tag = getSettingTag(args);
+ final boolean makeDefault = getSettingMakeDefault(args);
+ insertConfigSetting(name, value, tag, makeDefault, requestingUserId, false);
+ break;
+ }
+
case Settings.CALL_METHOD_PUT_GLOBAL: {
String value = getSettingValue(args);
String tag = getSettingTag(args);
@@ -418,6 +439,13 @@
break;
}
+ case Settings.CALL_METHOD_RESET_CONFIG: {
+ final int mode = getResetModeEnforcingPermission(args);
+ String tag = getSettingTag(args);
+ resetConfigSetting(requestingUserId, mode, tag);
+ break;
+ }
+
case Settings.CALL_METHOD_RESET_GLOBAL: {
final int mode = getResetModeEnforcingPermission(args);
String tag = getSettingTag(args);
@@ -725,6 +753,15 @@
@GuardedBy("mLock")
private void dumpForUserLocked(int userId, PrintWriter pw) {
if (userId == UserHandle.USER_SYSTEM) {
+ pw.println("CONFIG SETTINGS (user " + userId + ")");
+ SettingsState configSettings = mSettingsRegistry.getSettingsLocked(
+ SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
+ if (configSettings != null) {
+ dumpSettingsLocked(configSettings, pw);
+ pw.println();
+ configSettings.dumpHistoricalOperations(pw);
+ }
+
pw.println("GLOBAL SETTINGS (user " + userId + ")");
SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
@@ -935,6 +972,69 @@
});
}
+ private Setting getConfigSetting(String name) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "getConfigSetting(" + name + ")");
+ }
+
+ // TODO(b/117663715): Ensure the caller can access the setting.
+ // enforceSettingReadable(name, SETTINGS_TYPE_CONFIG, UserHandle.getCallingUserId());
+
+ // Get the value.
+ synchronized (mLock) {
+ return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_CONFIG,
+ UserHandle.USER_SYSTEM, name);
+ }
+ }
+
+ private boolean insertConfigSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, boolean forceNotify) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value + ", "
+ + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+ + ", " + forceNotify + ")");
+ }
+ return mutateConfigSetting(name, value, tag, makeDefault, requestingUserId,
+ MUTATION_OPERATION_INSERT, forceNotify, 0);
+ }
+
+ private void resetConfigSetting(int requestingUserId, int mode, String tag) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "resetConfigSetting(" + requestingUserId + ", "
+ + mode + ", " + tag + ")");
+ }
+ mutateConfigSetting(null, null, tag, false, requestingUserId,
+ MUTATION_OPERATION_RESET, false, mode);
+ }
+
+ private boolean mutateConfigSetting(String name, String value, String tag,
+ boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+ int mode) {
+ // TODO(b/117663715): check the new permission when it's added.
+ // enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
+
+ // Resolve the userId on whose behalf the call is made.
+ final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
+
+ // Perform the mutation.
+ synchronized (mLock) {
+ switch (operation) {
+ case MUTATION_OPERATION_INSERT: {
+ return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
+ UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
+ getCallingPackage(), forceNotify, null);
+ }
+
+ case MUTATION_OPERATION_RESET: {
+ mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
+ UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+ } return true;
+ }
+ }
+
+ return false;
+ }
+
private Cursor getAllGlobalSettings(String[] projection) {
if (DEBUG) {
Slog.v(LOG_TAG, "getAllGlobalSettings()");
@@ -2128,6 +2228,7 @@
private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
+ private static final String SETTINGS_FILE_CONFIG = "settings_config.xml";
private static final String SSAID_USER_KEY = "userkey";
@@ -2299,6 +2400,13 @@
// Migrate the setting for this user if needed.
migrateLegacySettingsForUserIfNeededLocked(userId);
+ // Ensure config settings loaded if owner.
+ if (userId == UserHandle.USER_SYSTEM) {
+ final int configKey
+ = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
+ ensureSettingsStateLocked(configKey);
+ }
+
// Ensure global settings loaded if owner.
if (userId == UserHandle.USER_SYSTEM) {
final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
@@ -2849,6 +2957,10 @@
}
}
+ private boolean isConfigSettingsKey(int key) {
+ return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG;
+ }
+
private boolean isGlobalSettingsKey(int key) {
return getTypeFromKey(key) == SETTINGS_TYPE_GLOBAL;
}
@@ -2866,7 +2978,11 @@
}
private File getSettingsFile(int key) {
- if (isGlobalSettingsKey(key)) {
+ if (isConfigSettingsKey(key)) {
+ final int userId = getUserIdFromKey(key);
+ return new File(Environment.getUserSystemDirectory(userId),
+ SETTINGS_FILE_CONFIG);
+ } else if (isGlobalSettingsKey(key)) {
final int userId = getUserIdFromKey(key);
return new File(Environment.getUserSystemDirectory(userId),
SETTINGS_FILE_GLOBAL);
@@ -2888,7 +3004,10 @@
}
private Uri getNotificationUriFor(int key, String name) {
- if (isGlobalSettingsKey(key)) {
+ if (isConfigSettingsKey(key)) {
+ return (name != null) ? Uri.withAppendedPath(CONFIG_CONTENT_URI, name)
+ : CONFIG_CONTENT_URI;
+ } else if (isGlobalSettingsKey(key)) {
return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name)
: Settings.Global.CONTENT_URI;
} else if (isSecureSettingsKey(key)) {
@@ -2904,6 +3023,7 @@
private int getMaxBytesPerPackageForType(int type) {
switch (type) {
+ case SETTINGS_TYPE_CONFIG:
case SETTINGS_TYPE_GLOBAL:
case SETTINGS_TYPE_SECURE:
case SETTINGS_TYPE_SSAID: {