summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Philip P. Moltmann <moltmann@google.com> 2019-06-13 15:49:08 -0700
committer Philip P. Moltmann <moltmann@google.com> 2019-06-19 09:41:17 -0700
commitcf5e437b6c1f23bbf3c65252fd9a30061bdd957c (patch)
treef17c642996fa39c1aeee775d236efeea8c2037e8
parent61a878126c66a144ef98f2cf5bfa155e1f1481c6 (diff)
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
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java126
1 files changed, 89 insertions, 37 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5f4d11360160..d2031b6c7e9c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -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.logCriticalInfo;
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.annotation.IntDef;
@@ -294,6 +291,7 @@ import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.IntPair;
import com.android.internal.util.Preconditions;
import com.android.server.AttributeCache;
import com.android.server.DeviceIdleController;
@@ -19801,6 +19799,8 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
+ final String packageName = ps.pkg.packageName;
+
// These are flags that can change base on user actions.
final int userSettableMask = FLAG_PERMISSION_USER_SET
| FLAG_PERMISSION_USER_FIXED
@@ -19810,8 +19810,59 @@ public class PackageManagerService extends IPackageManager.Stub
final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
| FLAG_PERMISSION_POLICY_FIXED;
- boolean writeInstallPermissions = false;
- boolean writeRuntimePermissions = false;
+ // Delay and combine non-async permission callbacks
+ 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();
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 = permissionsState.getPermissionFlags(permName, userId);
+ final int oldFlags = mPermissionManager.getPermissionFlags(permName, packageName,
+ Process.SYSTEM_UID, userId);
// 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
// permission as requiring a review as this is the initial state.
int flags = 0;
if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
}
- if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
- if (hasInstallState) {
- writeInstallPermissions = true;
- } else {
- writeRuntimePermissions = true;
- }
- }
+
+ mPermissionManager.updatePermissionFlags(permName, packageName,
+ userSettableMask, flags, Process.SYSTEM_UID, userId, false,
+ delayingPermCallback);
// Below is only runtime permission handling.
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 ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
- if (permissionsState.grantRuntimePermission(bp, userId)
- != PERMISSION_OPERATION_FAILURE) {
- writeRuntimePermissions = true;
- }
+ mPermissionManager.grantRuntimePermission(permName, packageName, false,
+ Process.SYSTEM_UID, userId, delayingPermCallback);
// If permission review is enabled the permissions for a legacy apps
// are represented as constantly granted runtime ones, so don't revoke.
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
// Otherwise, reset the permission.
- final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
- switch (revokeResult) {
- 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;
- }
+ mPermissionManager.revokeRuntimePermission(permName, packageName, false, userId,
+ delayingPermCallback);
}
}
- // Synchronously write as we are taking permissions away.
- if (writeRuntimePermissions) {
- mSettings.writeRuntimePermissionsForUserLPr(userId, true);
+ // Execute delayed callbacks
+ if (permissionRemoved[0]) {
+ mPermissionCallback.onPermissionRemoved();
}
- // Synchronously write as we are taking permissions away.
- if (writeInstallPermissions) {
- mSettings.writeLPr();
+ // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
+ // kill uid while holding mPackages-lock
+ 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));
}
}