DO NOT MERGE Update permissions flags for all users before attempting to
restore permissions. bug: 140274903 Test: cts-tradefed run cts-dev -m CtsPermissionTestCases -t android.permission.cts.SplitPermissionTest on both user 0 and user 10. Also (running on u10): $ adb install out/.../CtsAppThatRequestsLocationPermission29.apk $ adb shell pm grant --user 10 android.permission.cts.appthatrequestpermission android.permission.ACCESS_COARSE_LOCATION $ adb install out/.../CtsAppThatRequestsLocationPermission28.apk $ adb shell dumpsys package android.permission.cts.appthatrequestpermission Verify that ACCESS_BACKGROUND_LOCATION is granted to user 10 Change-Id: I3cd4365ca5abce292a190ca7abca4e4e8fbf61c4
This commit is contained in:
@@ -2022,16 +2022,6 @@ public class PermissionManagerService {
|
|||||||
return whitelistedPermissions;
|
return whitelistedPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
|
|
||||||
@NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
|
|
||||||
@PackageManager.PermissionWhitelistFlags int whitelistFlags,
|
|
||||||
@NonNull PermissionCallback callback) {
|
|
||||||
for (int userId : userIds) {
|
|
||||||
setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
|
|
||||||
callingUid, whitelistFlags, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
|
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
|
||||||
String[] grantedPermissions, int callingUid, PermissionCallback callback) {
|
String[] grantedPermissions, int callingUid, PermissionCallback callback) {
|
||||||
PackageSetting ps = (PackageSetting) pkg.mExtras;
|
PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||||
@@ -2312,109 +2302,122 @@ public class PermissionManagerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
|
private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
|
||||||
@UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
|
@NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
|
||||||
@PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
|
@PackageManager.PermissionWhitelistFlags int whitelistFlags,
|
||||||
|
@NonNull PermissionCallback callback) {
|
||||||
|
|
||||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||||
if (ps == null) {
|
if (ps == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
final PermissionsState permissionsState = ps.getPermissionsState();
|
||||||
|
SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
|
||||||
ArraySet<String> oldGrantedRestrictedPermissions = null;
|
|
||||||
boolean updatePermissions = false;
|
boolean updatePermissions = false;
|
||||||
|
|
||||||
final int permissionCount = pkg.requestedPermissions.size();
|
final int permissionCount = pkg.requestedPermissions.size();
|
||||||
for (int i = 0; i < permissionCount; i++) {
|
for (int userId : userIds) {
|
||||||
final String permissionName = pkg.requestedPermissions.get(i);
|
for (int i = 0; i < permissionCount; i++) {
|
||||||
|
final String permissionName = pkg.requestedPermissions.get(i);
|
||||||
|
|
||||||
final BasePermission bp = mSettings.getPermissionLocked(permissionName);
|
final BasePermission bp = mSettings.getPermissionLocked(permissionName);
|
||||||
if (bp == null) {
|
if (bp == null) {
|
||||||
Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
|
Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!bp.isHardOrSoftRestricted()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permissionsState.hasPermission(permissionName, userId)) {
|
|
||||||
if (oldGrantedRestrictedPermissions == null) {
|
|
||||||
oldGrantedRestrictedPermissions = new ArraySet<>();
|
|
||||||
}
|
}
|
||||||
oldGrantedRestrictedPermissions.add(permissionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
|
if (!bp.isHardOrSoftRestricted()) {
|
||||||
|
continue;
|
||||||
int newFlags = oldFlags;
|
|
||||||
int mask = 0;
|
|
||||||
int whitelistFlagsCopy = whitelistFlags;
|
|
||||||
while (whitelistFlagsCopy != 0) {
|
|
||||||
final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
|
|
||||||
whitelistFlagsCopy &= ~flag;
|
|
||||||
switch (flag) {
|
|
||||||
case FLAG_PERMISSION_WHITELIST_SYSTEM: {
|
|
||||||
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
|
||||||
if (permissions != null && permissions.contains(permissionName)) {
|
|
||||||
newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
|
||||||
} else {
|
|
||||||
newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case FLAG_PERMISSION_WHITELIST_UPGRADE: {
|
|
||||||
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
|
||||||
if (permissions != null && permissions.contains(permissionName)) {
|
|
||||||
newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
|
||||||
} else {
|
|
||||||
newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case FLAG_PERMISSION_WHITELIST_INSTALLER: {
|
|
||||||
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
|
||||||
if (permissions != null && permissions.contains(permissionName)) {
|
|
||||||
newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
|
||||||
} else {
|
|
||||||
newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (oldFlags == newFlags) {
|
if (permissionsState.hasPermission(permissionName, userId)) {
|
||||||
continue;
|
if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
|
||||||
}
|
oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
|
||||||
|
}
|
||||||
updatePermissions = true;
|
oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
|
||||||
|
|
||||||
final boolean wasWhitelisted = (oldFlags
|
|
||||||
& (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
|
|
||||||
final boolean isWhitelisted = (newFlags
|
|
||||||
& (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
|
|
||||||
|
|
||||||
// If the permission is policy fixed as granted but it is no longer
|
|
||||||
// on any of the whitelists we need to clear the policy fixed flag
|
|
||||||
// as whitelisting trumps policy i.e. policy cannot grant a non
|
|
||||||
// grantable permission.
|
|
||||||
if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
|
|
||||||
final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
|
|
||||||
if (!isWhitelisted && isGranted) {
|
|
||||||
mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
|
||||||
newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If we are whitelisting an app that does not support runtime permissions
|
final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
|
||||||
// we need to make sure it goes through the permission review UI at launch.
|
|
||||||
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
|
|
||||||
&& !wasWhitelisted && isWhitelisted) {
|
|
||||||
mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
|
||||||
newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
|
int newFlags = oldFlags;
|
||||||
callingUid, userId, false, null /*callback*/);
|
int mask = 0;
|
||||||
|
int whitelistFlagsCopy = whitelistFlags;
|
||||||
|
while (whitelistFlagsCopy != 0) {
|
||||||
|
final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
|
||||||
|
whitelistFlagsCopy &= ~flag;
|
||||||
|
switch (flag) {
|
||||||
|
case FLAG_PERMISSION_WHITELIST_SYSTEM: {
|
||||||
|
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||||
|
if (permissions != null && permissions.contains(permissionName)) {
|
||||||
|
newFlags |=
|
||||||
|
PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||||
|
} else {
|
||||||
|
newFlags &=
|
||||||
|
~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FLAG_PERMISSION_WHITELIST_UPGRADE: {
|
||||||
|
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||||
|
if (permissions != null && permissions.contains(permissionName)) {
|
||||||
|
newFlags |=
|
||||||
|
PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||||
|
} else {
|
||||||
|
newFlags &=
|
||||||
|
~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FLAG_PERMISSION_WHITELIST_INSTALLER: {
|
||||||
|
mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||||
|
if (permissions != null && permissions.contains(permissionName)) {
|
||||||
|
newFlags |=
|
||||||
|
PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||||
|
} else {
|
||||||
|
newFlags &= ~PackageManager
|
||||||
|
.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldFlags == newFlags) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePermissions = true;
|
||||||
|
|
||||||
|
final boolean wasWhitelisted = (oldFlags
|
||||||
|
& (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
|
||||||
|
final boolean isWhitelisted = (newFlags
|
||||||
|
& (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
|
||||||
|
|
||||||
|
// If the permission is policy fixed as granted but it is no longer
|
||||||
|
// on any of the whitelists we need to clear the policy fixed flag
|
||||||
|
// as whitelisting trumps policy i.e. policy cannot grant a non
|
||||||
|
// grantable permission.
|
||||||
|
if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
|
||||||
|
final boolean isGranted = permissionsState.hasPermission(permissionName,
|
||||||
|
userId);
|
||||||
|
if (!isWhitelisted && isGranted) {
|
||||||
|
mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
||||||
|
newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are whitelisting an app that does not support runtime permissions
|
||||||
|
// we need to make sure it goes through the permission review UI at launch.
|
||||||
|
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
|
||||||
|
&& !wasWhitelisted && isWhitelisted) {
|
||||||
|
mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||||
|
newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
|
||||||
|
callingUid, userId, false, null /*callback*/);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updatePermissions) {
|
if (updatePermissions) {
|
||||||
@@ -2422,7 +2425,12 @@ public class PermissionManagerService {
|
|||||||
restorePermissionState(pkg, false, pkg.packageName, callback);
|
restorePermissionState(pkg, false, pkg.packageName, callback);
|
||||||
|
|
||||||
// If this resulted in losing a permission we need to kill the app.
|
// If this resulted in losing a permission we need to kill the app.
|
||||||
if (oldGrantedRestrictedPermissions != null) {
|
int oldGrantedRestrictedPermissionsByUserCount =
|
||||||
|
oldGrantedRestrictedPermissionsByUser.size();
|
||||||
|
for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
|
||||||
|
final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
|
||||||
|
final ArraySet<String> oldGrantedRestrictedPermissions =
|
||||||
|
oldGrantedRestrictedPermissionsByUser.valueAt(j);
|
||||||
final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
|
final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
|
||||||
for (int i = 0; i < oldGrantedCount; i++) {
|
for (int i = 0; i < oldGrantedCount; i++) {
|
||||||
final String permission = oldGrantedRestrictedPermissions.valueAt(i);
|
final String permission = oldGrantedRestrictedPermissions.valueAt(i);
|
||||||
|
|||||||
Reference in New Issue
Block a user