Merge "Do not call out of the settings provider with a lock held" into mnc-dev
This commit is contained in:
@@ -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() : "";
|
||||||
|
|||||||
Reference in New Issue
Block a user