Merge "Do not call out of the settings provider with a lock held" into mnc-dev

This commit is contained in:
Svetoslav
2015-05-21 00:35:12 +00:00
committed by Android (Google) Code Review

View File

@@ -201,14 +201,14 @@ public class SettingsProvider extends ContentProvider {
@GuardedBy("mLock") @GuardedBy("mLock")
private SettingsRegistry mSettingsRegistry; private SettingsRegistry mSettingsRegistry;
@GuardedBy("mLock") // We have to call in the user manager with no lock held,
private UserManager mUserManager; private volatile UserManager mUserManager;
@GuardedBy("mLock") // We have to call in the app ops manager with no lock held,
private AppOpsManager mAppOpsManager; private volatile AppOpsManager mAppOpsManager;
@GuardedBy("mLock") // We have to call in the package manager with no lock held,
private PackageManager mPackageManager; private volatile PackageManager mPackageManager;
@Override @Override
public boolean onCreate() { public boolean onCreate() {
@@ -224,44 +224,46 @@ public class SettingsProvider extends ContentProvider {
@Override @Override
public Bundle call(String method, String name, Bundle args) { public Bundle call(String method, String name, Bundle args) {
synchronized (mLock) { final int requestingUserId = getRequestingUserId(args);
final int requestingUserId = getRequestingUserId(args); switch (method) {
switch (method) { case Settings.CALL_METHOD_GET_GLOBAL: {
case Settings.CALL_METHOD_GET_GLOBAL: { Setting setting = getGlobalSetting(name);
Setting setting = getGlobalSettingLocked(name); return packageValueForCallResult(setting);
return packageValueForCallResult(setting);
}
case Settings.CALL_METHOD_GET_SECURE: {
Setting setting = getSecureSettingLocked(name, requestingUserId);
return packageValueForCallResult(setting);
}
case Settings.CALL_METHOD_GET_SYSTEM: {
Setting setting = getSystemSettingLocked(name, requestingUserId);
return packageValueForCallResult(setting);
}
case Settings.CALL_METHOD_PUT_GLOBAL: {
String value = getSettingValue(args);
insertGlobalSettingLocked(name, value, requestingUserId);
} break;
case Settings.CALL_METHOD_PUT_SECURE: {
String value = getSettingValue(args);
insertSecureSettingLocked(name, value, requestingUserId);
} break;
case Settings.CALL_METHOD_PUT_SYSTEM: {
String value = getSettingValue(args);
insertSystemSettingLocked(name, value, requestingUserId);
} break;
default: {
Slog.w(LOG_TAG, "call() with invalid method: " + method);
} break;
} }
case Settings.CALL_METHOD_GET_SECURE: {
Setting setting = getSecureSetting(name, requestingUserId);
return packageValueForCallResult(setting);
}
case Settings.CALL_METHOD_GET_SYSTEM: {
Setting setting = getSystemSetting(name, requestingUserId);
return packageValueForCallResult(setting);
}
case Settings.CALL_METHOD_PUT_GLOBAL: {
String value = getSettingValue(args);
insertGlobalSetting(name, value, requestingUserId);
break;
}
case Settings.CALL_METHOD_PUT_SECURE: {
String value = getSettingValue(args);
insertSecureSetting(name, value, requestingUserId);
break;
}
case Settings.CALL_METHOD_PUT_SYSTEM: {
String value = getSettingValue(args);
insertSystemSetting(name, value, requestingUserId);
break;
}
default: {
Slog.w(LOG_TAG, "call() with invalid method: " + method);
} break;
} }
return null; return null;
} }
@@ -271,7 +273,7 @@ public class SettingsProvider extends ContentProvider {
if (TextUtils.isEmpty(args.name)) { if (TextUtils.isEmpty(args.name)) {
return "vnd.android.cursor.dir/" + args.table; return "vnd.android.cursor.dir/" + args.table;
} else { } else {
return "vnd.android.cursor.item/" + args.table; return "vnd.android.cursor.item/" + args.table;
} }
} }
@@ -290,40 +292,38 @@ public class SettingsProvider extends ContentProvider {
return new MatrixCursor(normalizedProjection, 0); return new MatrixCursor(normalizedProjection, 0);
} }
synchronized (mLock) { switch (args.table) {
switch (args.table) { case TABLE_GLOBAL: {
case TABLE_GLOBAL: { if (args.name != null) {
if (args.name != null) { Setting setting = getGlobalSetting(args.name);
Setting setting = getGlobalSettingLocked(args.name); return packageSettingForQuery(setting, normalizedProjection);
return packageSettingForQuery(setting, normalizedProjection); } else {
} else { return getAllGlobalSettings(projection);
return getAllGlobalSettingsLocked(projection);
}
} }
}
case TABLE_SECURE: { case TABLE_SECURE: {
final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId();
if (args.name != null) { if (args.name != null) {
Setting setting = getSecureSettingLocked(args.name, userId); Setting setting = getSecureSetting(args.name, userId);
return packageSettingForQuery(setting, normalizedProjection); return packageSettingForQuery(setting, normalizedProjection);
} else { } else {
return getAllSecureSettingsLocked(userId, projection); return getAllSecureSettings(userId, projection);
}
} }
}
case TABLE_SYSTEM: { case TABLE_SYSTEM: {
final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId();
if (args.name != null) { if (args.name != null) {
Setting setting = getSystemSettingLocked(args.name, userId); Setting setting = getSystemSetting(args.name, userId);
return packageSettingForQuery(setting, normalizedProjection); return packageSettingForQuery(setting, normalizedProjection);
} else { } else {
return getAllSystemSettingsLocked(userId, projection); return getAllSystemSettings(userId, projection);
}
} }
}
default: { default: {
throw new IllegalArgumentException("Invalid Uri path:" + uri); throw new IllegalArgumentException("Invalid Uri path:" + uri);
}
} }
} }
} }
@@ -348,29 +348,27 @@ public class SettingsProvider extends ContentProvider {
String value = values.getAsString(Settings.Secure.VALUE); String value = values.getAsString(Settings.Secure.VALUE);
synchronized (mLock) { switch (table) {
switch (table) { case TABLE_GLOBAL: {
case TABLE_GLOBAL: { if (insertGlobalSetting(name, value, UserHandle.getCallingUserId())) {
if (insertGlobalSettingLocked(name, value, UserHandle.getCallingUserId())) { return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
return Uri.withAppendedPath(Settings.Global.CONTENT_URI, name);
}
} break;
case TABLE_SECURE: {
if (insertSecureSettingLocked(name, value, UserHandle.getCallingUserId())) {
return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
}
} break;
case TABLE_SYSTEM: {
if (insertSystemSettingLocked(name, value, UserHandle.getCallingUserId())) {
return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
}
} break;
default: {
throw new IllegalArgumentException("Bad Uri path:" + uri);
} }
} break;
case TABLE_SECURE: {
if (insertSecureSetting(name, value, UserHandle.getCallingUserId())) {
return Uri.withAppendedPath(Settings.Secure.CONTENT_URI, name);
}
} break;
case TABLE_SYSTEM: {
if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) {
return Uri.withAppendedPath(Settings.System.CONTENT_URI, name);
}
} break;
default: {
throw new IllegalArgumentException("Bad Uri path:" + uri);
} }
} }
@@ -412,26 +410,25 @@ public class SettingsProvider extends ContentProvider {
return 0; return 0;
} }
synchronized (mLock) {
switch (args.table) {
case TABLE_GLOBAL: {
final int userId = UserHandle.getCallingUserId();
return deleteGlobalSettingLocked(args.name, userId) ? 1 : 0;
}
case TABLE_SECURE: { switch (args.table) {
final int userId = UserHandle.getCallingUserId(); case TABLE_GLOBAL: {
return deleteSecureSettingLocked(args.name, userId) ? 1 : 0; final int userId = UserHandle.getCallingUserId();
} return deleteGlobalSetting(args.name, userId) ? 1 : 0;
}
case TABLE_SYSTEM: { case TABLE_SECURE: {
final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId();
return deleteSystemSettingLocked(args.name, userId) ? 1 : 0; return deleteSecureSetting(args.name, userId) ? 1 : 0;
} }
default: { case TABLE_SYSTEM: {
throw new IllegalArgumentException("Bad Uri path:" + uri); final int userId = UserHandle.getCallingUserId();
} return deleteSystemSetting(args.name, userId) ? 1 : 0;
}
default: {
throw new IllegalArgumentException("Bad Uri path:" + uri);
} }
} }
} }
@@ -454,26 +451,24 @@ public class SettingsProvider extends ContentProvider {
return 0; return 0;
} }
synchronized (mLock) { switch (args.table) {
switch (args.table) { case TABLE_GLOBAL: {
case TABLE_GLOBAL: { final int userId = UserHandle.getCallingUserId();
final int userId = UserHandle.getCallingUserId(); return updateGlobalSetting(args.name, value, userId) ? 1 : 0;
return updateGlobalSettingLocked(args.name, value, userId) ? 1 : 0; }
}
case TABLE_SECURE: { case TABLE_SECURE: {
final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId();
return updateSecureSettingLocked(args.name, value, userId) ? 1 : 0; return updateSecureSetting(args.name, value, userId) ? 1 : 0;
} }
case TABLE_SYSTEM: { case TABLE_SYSTEM: {
final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId();
return updateSystemSettingLocked(args.name, value, userId) ? 1 : 0; return updateSystemSetting(args.name, value, userId) ? 1 : 0;
} }
default: { default: {
throw new IllegalArgumentException("Invalid Uri path:" + uri); throw new IllegalArgumentException("Invalid Uri path:" + uri);
}
} }
} }
} }
@@ -504,18 +499,18 @@ public class SettingsProvider extends ContentProvider {
private void dumpForUser(int userId, PrintWriter pw) { private void dumpForUser(int userId, PrintWriter pw) {
if (userId == UserHandle.USER_OWNER) { if (userId == UserHandle.USER_OWNER) {
pw.println("GLOBAL SETTINGS (user " + userId + ")"); pw.println("GLOBAL SETTINGS (user " + userId + ")");
Cursor globalCursor = getAllGlobalSettingsLocked(ALL_COLUMNS); Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS);
dumpSettings(globalCursor, pw); dumpSettings(globalCursor, pw);
pw.println(); pw.println();
} }
pw.println("SECURE SETTINGS (user " + userId + ")"); pw.println("SECURE SETTINGS (user " + userId + ")");
Cursor secureCursor = getAllSecureSettingsLocked(userId, ALL_COLUMNS); Cursor secureCursor = getAllSecureSettings(userId, ALL_COLUMNS);
dumpSettings(secureCursor, pw); dumpSettings(secureCursor, pw);
pw.println(); pw.println();
pw.println("SYSTEM SETTINGS (user " + userId + ")"); pw.println("SYSTEM SETTINGS (user " + userId + ")");
Cursor systemCursor = getAllSystemSettingsLocked(userId, ALL_COLUMNS); Cursor systemCursor = getAllSystemSettings(userId, ALL_COLUMNS);
dumpSettings(systemCursor, pw); dumpSettings(systemCursor, pw);
pw.println(); pw.println();
} }
@@ -575,64 +570,68 @@ public class SettingsProvider extends ContentProvider {
UserHandle.ALL, true); UserHandle.ALL, true);
} }
private Cursor getAllGlobalSettingsLocked(String[] projection) { private Cursor getAllGlobalSettings(String[] projection) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getAllGlobalSettingsLocked()"); Slog.v(LOG_TAG, "getAllGlobalSettings()");
} }
// Get the settings. synchronized (mLock) {
SettingsState settingsState = mSettingsRegistry.getSettingsLocked( // Get the settings.
SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER); SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
List<String> names = settingsState.getSettingNamesLocked(); List<String> names = settingsState.getSettingNamesLocked();
final int nameCount = names.size(); final int nameCount = names.size();
String[] normalizedProjection = normalizeProjection(projection); String[] normalizedProjection = normalizeProjection(projection);
MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
// Anyone can get the global settings, so no security checks. // Anyone can get the global settings, so no security checks.
for (int i = 0; i < nameCount; i++) { for (int i = 0; i < nameCount; i++) {
String name = names.get(i); String name = names.get(i);
Setting setting = settingsState.getSettingLocked(name); Setting setting = settingsState.getSettingLocked(name);
appendSettingToCursor(result, setting); appendSettingToCursor(result, setting);
}
return result;
} }
return result;
} }
private Setting getGlobalSettingLocked(String name) { private Setting getGlobalSetting(String name) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")"); Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
} }
// Get the value. // Get the value.
return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, synchronized (mLock) {
UserHandle.USER_OWNER, name); return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
} UserHandle.USER_OWNER, name);
private boolean updateGlobalSettingLocked(String name, String value, int requestingUserId) {
if (DEBUG) {
Slog.v(LOG_TAG, "updateGlobalSettingLocked(" + name + ", " + value + ")");
} }
return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
} }
private boolean insertGlobalSettingLocked(String name, String value, int requestingUserId) { private boolean updateGlobalSetting(String name, String value, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "insertGlobalSettingLocked(" + name + ", " + value + ")"); Slog.v(LOG_TAG, "updateGlobalSetting(" + name + ", " + value + ")");
} }
return mutateGlobalSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
} }
private boolean deleteGlobalSettingLocked(String name, int requestingUserId) { private boolean insertGlobalSetting(String name, String value, int requestingUserId) {
if (DEBUG) {
Slog.v(LOG_TAG, "insertGlobalSetting(" + name + ", " + value + ")");
}
return mutateGlobalSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
}
private boolean deleteGlobalSetting(String name, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "deleteGlobalSettingLocked(" + name + ")"); Slog.v(LOG_TAG, "deleteGlobalSettingLocked(" + name + ")");
} }
return mutateGlobalSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); return mutateGlobalSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
} }
private boolean mutateGlobalSettingLocked(String name, String value, int requestingUserId, private boolean mutateGlobalSetting(String name, String value, int requestingUserId,
int operation) { int operation) {
// Make sure the caller can change the settings - treated as secure. // Make sure the caller can change the settings - treated as secure.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -651,28 +650,32 @@ public class SettingsProvider extends ContentProvider {
} }
// Perform the mutation. // Perform the mutation.
switch (operation) { synchronized (mLock) {
case MUTATION_OPERATION_INSERT: { switch (operation) {
return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, case MUTATION_OPERATION_INSERT: {
UserHandle.USER_OWNER, name, value, getCallingPackage()); return mSettingsRegistry
} .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
UserHandle.USER_OWNER, name, value, getCallingPackage());
}
case MUTATION_OPERATION_DELETE: { case MUTATION_OPERATION_DELETE: {
return mSettingsRegistry.deleteSettingLocked( return mSettingsRegistry.deleteSettingLocked(
SettingsRegistry.SETTINGS_TYPE_GLOBAL, SettingsRegistry.SETTINGS_TYPE_GLOBAL,
UserHandle.USER_OWNER, name); UserHandle.USER_OWNER, name);
} }
case MUTATION_OPERATION_UPDATE: { case MUTATION_OPERATION_UPDATE: {
return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL, return mSettingsRegistry
UserHandle.USER_OWNER, name, value, getCallingPackage()); .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
UserHandle.USER_OWNER, name, value, getCallingPackage());
}
} }
} }
return false; return false;
} }
private Cursor getAllSecureSettingsLocked(int userId, String[] projection) { private Cursor getAllSecureSettings(int userId, String[] projection) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")"); Slog.v(LOG_TAG, "getAllSecureSettings(" + userId + ")");
} }
@@ -680,34 +683,36 @@ public class SettingsProvider extends ContentProvider {
// Resolve the userId on whose behalf the call is made. // Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId); final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
List<String> names = mSettingsRegistry.getSettingsNamesLocked( synchronized (mLock) {
SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId); List<String> names = mSettingsRegistry.getSettingsNamesLocked(
SettingsRegistry.SETTINGS_TYPE_SECURE, callingUserId);
final int nameCount = names.size(); final int nameCount = names.size();
String[] normalizedProjection = normalizeProjection(projection); String[] normalizedProjection = normalizeProjection(projection);
MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
for (int i = 0; i < nameCount; i++) { for (int i = 0; i < nameCount; i++) {
String name = names.get(i); String name = names.get(i);
// Determine the owning user as some profile settings are cloned from the parent.
final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId,
name);
// Determine the owning user as some profile settings are cloned from the parent. // Special case for location (sigh).
final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name); if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
return null;
}
// Special case for location (sigh). Setting setting = mSettingsRegistry.getSettingLocked(
if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) { SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name);
return null; appendSettingToCursor(result, setting);
} }
Setting setting = mSettingsRegistry.getSettingLocked( return result;
SettingsRegistry.SETTINGS_TYPE_SECURE, owningUserId, name);
appendSettingToCursor(result, setting);
} }
return result;
} }
private Setting getSecureSettingLocked(String name, int requestingUserId) { private Setting getSecureSetting(String name, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")"); Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
} }
@@ -724,37 +729,39 @@ public class SettingsProvider extends ContentProvider {
} }
// Get the value. // Get the value.
return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, synchronized (mLock) {
owningUserId, name); return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
owningUserId, name);
}
} }
private boolean insertSecureSettingLocked(String name, String value, int requestingUserId) { private boolean insertSecureSetting(String name, String value, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "insertSecureSettingLocked(" + name + ", " + value + ", " Slog.v(LOG_TAG, "insertSecureSetting(" + name + ", " + value + ", "
+ requestingUserId + ")"); + requestingUserId + ")");
} }
return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
} }
private boolean deleteSecureSettingLocked(String name, int requestingUserId) { private boolean deleteSecureSetting(String name, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "deleteSecureSettingLocked(" + name + ", " + requestingUserId + ")"); Slog.v(LOG_TAG, "deleteSecureSetting(" + name + ", " + requestingUserId + ")");
} }
return mutateSecureSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); return mutateSecureSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
} }
private boolean updateSecureSettingLocked(String name, String value, int requestingUserId) { private boolean updateSecureSetting(String name, String value, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "updateSecureSettingLocked(" + name + ", " + value + ", " Slog.v(LOG_TAG, "updateSecureSetting(" + name + ", " + value + ", "
+ requestingUserId + ")"); + requestingUserId + ")");
} }
return mutateSecureSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); return mutateSecureSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
} }
private boolean mutateSecureSettingLocked(String name, String value, int requestingUserId, private boolean mutateSecureSetting(String name, String value, int requestingUserId,
int operation) { int operation) {
// Make sure the caller can change the settings. // Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
@@ -786,58 +793,65 @@ public class SettingsProvider extends ContentProvider {
} }
// Mutate the value. // Mutate the value.
switch(operation) { synchronized (mLock) {
case MUTATION_OPERATION_INSERT: { switch (operation) {
return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, case MUTATION_OPERATION_INSERT: {
owningUserId, name, value, getCallingPackage()); return mSettingsRegistry
} .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
owningUserId, name, value, getCallingPackage());
}
case MUTATION_OPERATION_DELETE: { case MUTATION_OPERATION_DELETE: {
return mSettingsRegistry.deleteSettingLocked( return mSettingsRegistry.deleteSettingLocked(
SettingsRegistry.SETTINGS_TYPE_SECURE, SettingsRegistry.SETTINGS_TYPE_SECURE,
owningUserId, name); owningUserId, name);
} }
case MUTATION_OPERATION_UPDATE: { case MUTATION_OPERATION_UPDATE: {
return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE, return mSettingsRegistry
owningUserId, name, value, getCallingPackage()); .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SECURE,
owningUserId, name, value, getCallingPackage());
}
} }
} }
return false; return false;
} }
private Cursor getAllSystemSettingsLocked(int userId, String[] projection) { private Cursor getAllSystemSettings(int userId, String[] projection) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getAllSecureSystemLocked(" + userId + ")"); Slog.v(LOG_TAG, "getAllSecureSystem(" + userId + ")");
} }
// Resolve the userId on whose behalf the call is made. // Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId); final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(userId);
List<String> names = mSettingsRegistry.getSettingsNamesLocked( synchronized (mLock) {
SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId); List<String> names = mSettingsRegistry.getSettingsNamesLocked(
SettingsRegistry.SETTINGS_TYPE_SYSTEM, callingUserId);
final int nameCount = names.size(); final int nameCount = names.size();
String[] normalizedProjection = normalizeProjection(projection); String[] normalizedProjection = normalizeProjection(projection);
MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount); MatrixCursor result = new MatrixCursor(normalizedProjection, nameCount);
for (int i = 0; i < nameCount; i++) { for (int i = 0; i < nameCount; i++) {
String name = names.get(i); String name = names.get(i);
// Determine the owning user as some profile settings are cloned from the parent. // Determine the owning user as some profile settings are cloned from the parent.
final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId,
name);
Setting setting = mSettingsRegistry.getSettingLocked( Setting setting = mSettingsRegistry.getSettingLocked(
SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name); SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name);
appendSettingToCursor(result, setting); appendSettingToCursor(result, setting);
}
return result;
} }
return result;
} }
private Setting getSystemSettingLocked(String name, int requestingUserId) { private Setting getSystemSetting(String name, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")"); Slog.v(LOG_TAG, "getSystemSetting(" + name + ", " + requestingUserId + ")");
} }
@@ -849,37 +863,39 @@ public class SettingsProvider extends ContentProvider {
final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name); final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
// Get the value. // Get the value.
return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, synchronized (mLock) {
owningUserId, name); return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name);
}
} }
private boolean insertSystemSettingLocked(String name, String value, int requestingUserId) { private boolean insertSystemSetting(String name, String value, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "insertSystemSettingLocked(" + name + ", " + value + ", " Slog.v(LOG_TAG, "insertSystemSetting(" + name + ", " + value + ", "
+ requestingUserId + ")"); + requestingUserId + ")");
} }
return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_INSERT); return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT);
} }
private boolean deleteSystemSettingLocked(String name, int requestingUserId) { private boolean deleteSystemSetting(String name, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "deleteSystemSettingLocked(" + name + ", " + requestingUserId + ")"); Slog.v(LOG_TAG, "deleteSystemSetting(" + name + ", " + requestingUserId + ")");
} }
return mutateSystemSettingLocked(name, null, requestingUserId, MUTATION_OPERATION_DELETE); return mutateSystemSetting(name, null, requestingUserId, MUTATION_OPERATION_DELETE);
} }
private boolean updateSystemSettingLocked(String name, String value, int requestingUserId) { private boolean updateSystemSetting(String name, String value, int requestingUserId) {
if (DEBUG) { if (DEBUG) {
Slog.v(LOG_TAG, "updateSystemSettingLocked(" + name + ", " + value + ", " Slog.v(LOG_TAG, "updateSystemSetting(" + name + ", " + value + ", "
+ requestingUserId + ")"); + requestingUserId + ")");
} }
return mutateSystemSettingLocked(name, value, requestingUserId, MUTATION_OPERATION_UPDATE); return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_UPDATE);
} }
private boolean mutateSystemSettingLocked(String name, String value, int runAsUserId, private boolean mutateSystemSetting(String name, String value, int runAsUserId,
int operation) { int operation) {
// Make sure the caller can change the settings. // Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SETTINGS);
@@ -904,27 +920,31 @@ public class SettingsProvider extends ContentProvider {
} }
// Mutate the value. // Mutate the value.
switch (operation) { synchronized (mLock) {
case MUTATION_OPERATION_INSERT: { switch (operation) {
validateSystemSettingValue(name, value); case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, validateSystemSettingValue(name, value);
owningUserId, name, value, getCallingPackage()); return mSettingsRegistry
.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name, value, getCallingPackage());
}
case MUTATION_OPERATION_DELETE: {
return mSettingsRegistry.deleteSettingLocked(
SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name);
}
case MUTATION_OPERATION_UPDATE: {
validateSystemSettingValue(name, value);
return mSettingsRegistry
.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name, value, getCallingPackage());
}
} }
case MUTATION_OPERATION_DELETE: { return false;
return mSettingsRegistry.deleteSettingLocked(
SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name);
}
case MUTATION_OPERATION_UPDATE: {
validateSystemSettingValue(name, value);
return mSettingsRegistry.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM,
owningUserId, name, value, getCallingPackage());
}
} }
return false;
} }
private void validateSystemSettingValue(String name, String value) { private void validateSystemSettingValue(String name, String value) {
@@ -1043,6 +1063,7 @@ public class SettingsProvider extends ContentProvider {
// user info is a cached instance, so just look up instead of cache. // user info is a cached instance, so just look up instead of cache.
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
// Just a lookup and not reentrant, so holding a lock is fine.
UserInfo userInfo = mUserManager.getProfileParent(userId); UserInfo userInfo = mUserManager.getProfileParent(userId);
return (userInfo != null) ? userInfo.id : userId; return (userInfo != null) ? userInfo.id : userId;
} finally { } finally {
@@ -1088,7 +1109,7 @@ public class SettingsProvider extends ContentProvider {
// skip prefix // skip prefix
value = value.substring(1); value = value.substring(1);
Setting settingValue = getSecureSettingLocked( Setting settingValue = getSecureSetting(
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId); Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
String oldProviders = (settingValue != null) ? settingValue.getValue() : ""; String oldProviders = (settingValue != null) ? settingValue.getValue() : "";