Always use PermMgrSrv APIs to change permission
So that the appropriate callbacks are called when a permission is changed. Test: cleared package state and saw PermissionPolicyService being run Bug: 132704705 Change-Id: Iea53b463fcc7d73dde89efbe91a7c5fa8b65bd7b
This commit is contained in:
@@ -111,9 +111,6 @@ import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFile
|
|||||||
import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
|
import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
|
||||||
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
|
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
|
||||||
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
|
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
|
||||||
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
|
|
||||||
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
|
|
||||||
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
@@ -294,6 +291,7 @@ import com.android.internal.util.ConcurrentUtils;
|
|||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.internal.util.FastXmlSerializer;
|
import com.android.internal.util.FastXmlSerializer;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
import com.android.internal.util.IntPair;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.server.AttributeCache;
|
import com.android.server.AttributeCache;
|
||||||
import com.android.server.DeviceIdleController;
|
import com.android.server.DeviceIdleController;
|
||||||
@@ -19801,6 +19799,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String packageName = ps.pkg.packageName;
|
||||||
|
|
||||||
// These are flags that can change base on user actions.
|
// These are flags that can change base on user actions.
|
||||||
final int userSettableMask = FLAG_PERMISSION_USER_SET
|
final int userSettableMask = FLAG_PERMISSION_USER_SET
|
||||||
| FLAG_PERMISSION_USER_FIXED
|
| FLAG_PERMISSION_USER_FIXED
|
||||||
@@ -19810,8 +19810,59 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
|
final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
|
||||||
| FLAG_PERMISSION_POLICY_FIXED;
|
| FLAG_PERMISSION_POLICY_FIXED;
|
||||||
|
|
||||||
boolean writeInstallPermissions = false;
|
// Delay and combine non-async permission callbacks
|
||||||
boolean writeRuntimePermissions = false;
|
final boolean[] permissionRemoved = new boolean[1];
|
||||||
|
final ArraySet<Long> revokedPermissions = new ArraySet<>();
|
||||||
|
final SparseBooleanArray updatedUsers = new SparseBooleanArray();
|
||||||
|
|
||||||
|
PermissionCallback delayingPermCallback = new PermissionCallback() {
|
||||||
|
public void onGidsChanged(int appId, int userId) {
|
||||||
|
mPermissionCallback.onGidsChanged(appId, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPermissionChanged() {
|
||||||
|
mPermissionCallback.onPermissionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPermissionGranted(int uid, int userId) {
|
||||||
|
mPermissionCallback.onPermissionGranted(uid, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onInstallPermissionGranted() {
|
||||||
|
mPermissionCallback.onInstallPermissionGranted();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPermissionRevoked(int uid, int userId) {
|
||||||
|
revokedPermissions.add(IntPair.of(uid, userId));
|
||||||
|
|
||||||
|
updatedUsers.put(userId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onInstallPermissionRevoked() {
|
||||||
|
mPermissionCallback.onInstallPermissionRevoked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
|
||||||
|
for (int userId : updatedUserIds) {
|
||||||
|
if (sync) {
|
||||||
|
updatedUsers.put(userId, true);
|
||||||
|
} else {
|
||||||
|
// Don't override sync=true by sync=false
|
||||||
|
if (!updatedUsers.get(userId)) {
|
||||||
|
updatedUsers.put(userId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPermissionRemoved() {
|
||||||
|
permissionRemoved[0] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onInstallPermissionUpdated() {
|
||||||
|
mPermissionCallback.onInstallPermissionUpdated();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
final int permissionCount = ps.pkg.requestedPermissions.size();
|
final int permissionCount = ps.pkg.requestedPermissions.size();
|
||||||
for (int i = 0; i < permissionCount; i++) {
|
for (int i = 0; i < permissionCount; i++) {
|
||||||
@@ -19843,26 +19894,20 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
final int oldFlags = mPermissionManager.getPermissionFlags(permName, packageName,
|
||||||
|
Process.SYSTEM_UID, userId);
|
||||||
final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
|
|
||||||
|
|
||||||
// Always clear the user settable flags.
|
// Always clear the user settable flags.
|
||||||
final boolean hasInstallState =
|
|
||||||
permissionsState.getInstallPermissionState(permName) != null;
|
|
||||||
// If permission review is enabled and this is a legacy app, mark the
|
// If permission review is enabled and this is a legacy app, mark the
|
||||||
// permission as requiring a review as this is the initial state.
|
// permission as requiring a review as this is the initial state.
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
|
if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
|
||||||
flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
|
flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
|
||||||
}
|
}
|
||||||
if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
|
|
||||||
if (hasInstallState) {
|
mPermissionManager.updatePermissionFlags(permName, packageName,
|
||||||
writeInstallPermissions = true;
|
userSettableMask, flags, Process.SYSTEM_UID, userId, false,
|
||||||
} else {
|
delayingPermCallback);
|
||||||
writeRuntimePermissions = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Below is only runtime permission handling.
|
// Below is only runtime permission handling.
|
||||||
if (!bp.isRuntime()) {
|
if (!bp.isRuntime()) {
|
||||||
@@ -19876,35 +19921,42 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
// If this permission was granted by default, make sure it is.
|
// If this permission was granted by default, make sure it is.
|
||||||
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
|
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
|
||||||
if (permissionsState.grantRuntimePermission(bp, userId)
|
mPermissionManager.grantRuntimePermission(permName, packageName, false,
|
||||||
!= PERMISSION_OPERATION_FAILURE) {
|
Process.SYSTEM_UID, userId, delayingPermCallback);
|
||||||
writeRuntimePermissions = true;
|
|
||||||
}
|
|
||||||
// If permission review is enabled the permissions for a legacy apps
|
// If permission review is enabled the permissions for a legacy apps
|
||||||
// are represented as constantly granted runtime ones, so don't revoke.
|
// are represented as constantly granted runtime ones, so don't revoke.
|
||||||
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
|
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
|
||||||
// Otherwise, reset the permission.
|
// Otherwise, reset the permission.
|
||||||
final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
|
mPermissionManager.revokeRuntimePermission(permName, packageName, false, userId,
|
||||||
switch (revokeResult) {
|
delayingPermCallback);
|
||||||
case PERMISSION_OPERATION_SUCCESS:
|
|
||||||
case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
|
|
||||||
writeRuntimePermissions = true;
|
|
||||||
final int appId = ps.appId;
|
|
||||||
mHandler.post(
|
|
||||||
() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronously write as we are taking permissions away.
|
// Execute delayed callbacks
|
||||||
if (writeRuntimePermissions) {
|
if (permissionRemoved[0]) {
|
||||||
mSettings.writeRuntimePermissionsForUserLPr(userId, true);
|
mPermissionCallback.onPermissionRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronously write as we are taking permissions away.
|
// Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
|
||||||
if (writeInstallPermissions) {
|
// kill uid while holding mPackages-lock
|
||||||
mSettings.writeLPr();
|
if (!revokedPermissions.isEmpty()) {
|
||||||
|
int numRevokedPermissions = revokedPermissions.size();
|
||||||
|
for (int i = 0; i < numRevokedPermissions; i++) {
|
||||||
|
int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
|
||||||
|
int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
|
||||||
|
|
||||||
|
mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
|
||||||
|
|
||||||
|
// Kill app later as we are holding mPackages
|
||||||
|
mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
|
||||||
|
KILL_APP_REASON_PERMISSIONS_REVOKED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int numUpdatedUsers = updatedUsers.size();
|
||||||
|
for (int i = 0; i < numUpdatedUsers; i++) {
|
||||||
|
mSettings.writeRuntimePermissionsForUserLPr(updatedUsers.keyAt(i),
|
||||||
|
updatedUsers.valueAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user