summaryrefslogtreecommitdiff
path: root/services/permission/java
diff options
context:
space:
mode:
author Hai Zhang <zhanghai@google.com> 2022-12-14 22:49:47 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-14 22:49:47 +0000
commit53fe6bdb82e52a1b4edb5b6d6afb6ae43821d649 (patch)
tree1b90910fcd4e12d377bf421fbe430d77c80e87b0 /services/permission/java
parentd741b93f4b0b6a6fdb951e911ea79a3beec509c0 (diff)
parent9043314199eb7cadc1e34981f4da3629ec1b7984 (diff)
Merge "Add new permission flags implementation."
Diffstat (limited to 'services/permission/java')
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt466
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionService.kt14
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt19
3 files changed, 481 insertions, 18 deletions
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
index 1b055202af7c..6b2b1856f7fe 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
@@ -16,18 +16,468 @@
package com.android.server.permission.access.permission
+import android.app.AppOpsManager
+import android.app.admin.DevicePolicyManager
+import android.content.pm.PackageManager
+import android.os.Build
+import android.permission.PermissionManager
+import com.android.server.permission.access.util.andInv
+import com.android.server.permission.access.util.hasAnyBit
+import com.android.server.permission.access.util.hasBits
+
+/**
+ * A set of internal permission flags that's better than the set of `FLAG_PERMISSION_*` constants on
+ * [PackageManager].
+ *
+ * The old binary permission state is now tracked by multiple `*_GRANTED` and `*_REVOKED` flags, so
+ * that:
+ *
+ * - With [INSTALL_GRANTED] and [INSTALL_REVOKED], we can now get rid of the old per-package
+ * `areInstallPermissionsFixed` attribute and correctly track it per-permission, finally fixing
+ * edge cases during module rollbacks.
+ *
+ * - With [LEGACY_GRANTED] and [IMPLICIT_GRANTED], we can now ensure that legacy permissions and
+ * implicit permissions split from non-runtime permissions are never revoked, without checking
+ * split permissions and package state everywhere slowly and in slightly different ways.
+ *
+ * - With [RESTRICTION_REVOKED], we can now get rid of the error-prone logic about revoking and
+ * potentially re-granting permissions upon restriction state changes.
+ *
+ * Permission grants due to protection level are now tracked by [PROTECTION_GRANTED], and permission
+ * grants due to [PackageManager.grantRuntimePermission] are now tracked by [RUNTIME_GRANTED].
+ *
+ * The [PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED] and
+ * [PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED] flags are now unified into [IMPLICIT], and
+ * they can be differentiated by the presence of [LEGACY_GRANTED].
+ *
+ * The rest of the permission flags have a 1:1 mapping to the old `FLAG_PERMISSION_*` constants, and
+ * don't have any effect on the binary permission state.
+ */
object PermissionFlags {
+ /**
+ * Permission flag for a normal permission that is granted at package installation.
+ */
const val INSTALL_GRANTED = 1 shl 0
+
+ /**
+ * Permission flag for a normal permission that is revoked at package installation.
+ *
+ * Normally packages that have already been installed cannot be granted new normal permissions
+ * until its next installation (update), so this flag helps track that the normal permission was
+ * revoked upon its most recent installation.
+ */
const val INSTALL_REVOKED = 1 shl 1
+
+ /**
+ * Permission flag for a signature or internal permission that is granted based on the
+ * permission's protection level, including its protection and protection flags.
+ *
+ * For example, this flag may be set when the permission is a signature permission and the
+ * package is having a compatible signing certificate with the package defining the permission,
+ * or when the permission is a privileged permission and the package is a privileged app with
+ * its permission in the
+ * [privileged permission allowlist](https://source.android.com/docs/core/permissions/perms-allowlist).
+ */
const val PROTECTION_GRANTED = 1 shl 2
- const val ROLE_GRANTED = 1 shl 3
- // For permissions that are granted in other ways,
- // ex: via an API or implicit permissions that inherit from granted install permissions
- const val OTHER_GRANTED = 1 shl 4
- // For the permissions that are implicit for the package
- const val IMPLICIT = 1 shl 5
+ /**
+ * Permission flag for a role or runtime permission that is or was granted by a role.
+ *
+ * @see PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE
+ */
+ const val ROLE = 1 shl 3
+
+ /**
+ * Permission flag for a development, role or runtime permission that is granted via
+ * [PackageManager.grantRuntimePermission].
+ */
+ const val RUNTIME_GRANTED = 1 shl 4
+
+ /**
+ * Permission flag for a runtime permission whose state is set by the user.
+ *
+ * For example, this flag may be set when the permission is allowed by the user in the
+ * request permission dialog, or managed in the permission settings.
+ *
+ * @see PackageManager.FLAG_PERMISSION_USER_SET
+ */
+ const val USER_SET = 1 shl 5
+
+ /**
+ * Permission flag for a runtime permission whose state is (revoked and) fixed by the user.
+ *
+ * For example, this flag may be set when the permission is denied twice by the user in the
+ * request permission dialog.
+ *
+ * @see PackageManager.FLAG_PERMISSION_USER_FIXED
+ */
+ const val USER_FIXED = 1 shl 6
+
+ /**
+ * Permission flag for a runtime permission whose state is set and fixed by the device policy
+ * via [DevicePolicyManager.setPermissionGrantState].
+ *
+ * @see PackageManager.FLAG_PERMISSION_POLICY_FIXED
+ */
+ const val POLICY_FIXED = 1 shl 7
+
+ /**
+ * Permission flag for a runtime permission that is (pregranted and) fixed by the system.
+ *
+ * For example, this flag may be set in
+ * [com.android.server.pm.permission.DefaultPermissionGrantPolicy].
+ *
+ * @see PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+ */
+ const val SYSTEM_FIXED = 1 shl 8
+
+ /**
+ * Permission flag for a runtime permission that is or was pregranted by the system.
+ *
+ * For example, this flag may be set in
+ * [com.android.server.pm.permission.DefaultPermissionGrantPolicy].
+ *
+ * @see PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+ */
+ const val PREGRANT = 1 shl 9
+
+ /**
+ * Permission flag for a runtime permission that is granted because the package targets a legacy
+ * SDK version before [Build.VERSION_CODES.M] and doesn't support runtime permissions.
+ *
+ * As long as this flag is set, the permission should always be considered granted, although
+ * [APP_OP_REVOKED] may cause the app op for the runtime permission to be revoked. Once the
+ * package targets a higher SDK version so that it started supporting runtime permissions, this
+ * flag should be removed and the remaining flags should take effect.
+ *
+ * @see PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+ * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+ */
+ const val LEGACY_GRANTED = 1 shl 10
+
+ /**
+ * Permission flag for a runtime permission that is granted because the package targets a lower
+ * SDK version and the permission is implicit to it as a
+ * [split permission][PermissionManager.SplitPermissionInfo] from other non-runtime permissions.
+ *
+ * As long as this flag is set, the permission should always be considered granted, although
+ * [APP_OP_REVOKED] may cause the app op for the runtime permission to be revoked. Once the
+ * package targets a higher SDK version so that the permission is no longer implicit to it, this
+ * flag should be removed and the remaining flags should take effect.
+ *
+ * @see PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
+ * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+ */
+ const val IMPLICIT_GRANTED = 1 shl 11
+
+ /**
+ * Permission flag for a runtime permission that is granted because the package targets a legacy
+ * SDK version before [Build.VERSION_CODES.M] and doesn't support runtime permissions, so that
+ * it needs to be reviewed by the user; or granted because the package targets a lower SDK
+ * version and the permission is implicit to it as a
+ * [split permission][PermissionManager.SplitPermissionInfo] from other non-runtime permissions,
+ * so that it needs to be revoked when it's no longer implicit.
+ *
+ * @see PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+ * @see PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
+ */
+ const val IMPLICIT = 1 shl 12
+
+ /**
+ * Permission flag for a runtime permission that is user-sensitive when it's granted.
+ *
+ * This flag is informational and managed by PermissionController.
+ *
+ * @see PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED
+ */
+ const val USER_SENSITIVE_WHEN_GRANTED = 1 shl 13
+
+ /**
+ * Permission flag for a runtime permission that is user-sensitive when it's revoked.
+ *
+ * This flag is informational and managed by PermissionController.
+ *
+ * @see PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED
+ */
+ const val USER_SENSITIVE_WHEN_REVOKED = 1 shl 14
+
+ /**
+ * Permission flag for a restricted runtime permission that is exempt by the package's
+ * installer.
+ *
+ * For example, this flag may be set when the installer applied the exemption as part of the
+ * [session parameters](https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(java.util.Set%3Cjava.lang.String%3E)).
+ *
+ * The permission will be restricted when none of the exempt flags is set.
+ *
+ * @see PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
+ */
+ const val INSTALLER_EXEMPT = 1 shl 15
+
+ /**
+ * Permission flag for a restricted runtime permission that is exempt by the system.
+ *
+ * For example, this flag may be set when the package is a system app.
+ *
+ * The permission will be restricted when none of the exempt flags is set.
+ *
+ * @see PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+ */
+ const val SYSTEM_EXEMPT = 1 shl 16
+
+ /**
+ * Permission flag for a restricted runtime permission that is exempt due to system upgrade.
+ *
+ * For example, this flag may be set when the package was installed before the system was
+ * upgraded to [Build.VERSION_CODES.Q], when restricted permissions were introduced.
+ *
+ * The permission will be restricted when none of the exempt flags is set.
+ *
+ * @see PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
+ */
+ const val UPGRADE_EXEMPT = 1 shl 17
+
+ /**
+ * Permission flag for a restricted runtime permission that is revoked due to being hard
+ * restricted.
+ *
+ * @see PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION
+ */
+ const val RESTRICTION_REVOKED = 1 shl 18
+
+ /**
+ * Permission flag for a restricted runtime permission that is soft restricted.
+ *
+ * @see PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION
+ */
+ const val SOFT_RESTRICTED = 1 shl 19
+
+ /**
+ * Permission flag for a runtime permission whose app op is revoked.
+ *
+ * For example, this flag may be set when the runtime permission is legacy or implicit but still
+ * "revoked" by the user in permission settings, or when the app op mode for the runtime
+ * permission is set to revoked via [AppOpsManager.setUidMode].
+ *
+ * @see PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+ */
+ const val APP_OP_REVOKED = 1 shl 20
+
+ /**
+ * Permission flag for a runtime permission that is granted as one-time.
+ *
+ * For example, this flag may be set when the user selected "Only this time" in the request
+ * permission dialog.
+ *
+ * This flag, along with other user decisions when it is set, should never be persisted, and
+ * should be removed once the permission is revoked.
+ *
+ * @see PackageManager.FLAG_PERMISSION_ONE_TIME
+ */
+ const val ONE_TIME = 1 shl 21
+
+ /**
+ * Permission flag for a runtime permission that was revoked due to app hibernation.
+ *
+ * This flag is informational and added by PermissionController, and should be removed once the
+ * permission is granted again.
+ *
+ * @see PackageManager.FLAG_PERMISSION_AUTO_REVOKED
+ */
+ const val HIBERNATION = 1 shl 22
+
+ /**
+ * Permission flag for a runtime permission that is selected by the user.
+ *
+ * For example, this flag may be set when one of the coarse/fine location accuracies is
+ * selected by the user.
+ *
+ * This flag is informational and managed by PermissionController.
+ *
+ * @see PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY
+ */
+ const val USER_SELECTED = 1 shl 23
+
+ /**
+ * Mask for all permission flags.
+ */
const val MASK_ALL = 0.inv()
- const val MASK_GRANTED = INSTALL_GRANTED or PROTECTION_GRANTED or OTHER_GRANTED or ROLE_GRANTED
- const val MASK_RUNTIME = OTHER_GRANTED or IMPLICIT
+
+ /**
+ * Mask for all permission flags that may be applied to a runtime permission.
+ */
+ const val MASK_RUNTIME = ROLE or RUNTIME_GRANTED or USER_SET or USER_FIXED or POLICY_FIXED or
+ SYSTEM_FIXED or PREGRANT or LEGACY_GRANTED or IMPLICIT_GRANTED or IMPLICIT or
+ USER_SENSITIVE_WHEN_GRANTED or USER_SENSITIVE_WHEN_REVOKED or INSTALLER_EXEMPT or
+ SYSTEM_EXEMPT or UPGRADE_EXEMPT or RESTRICTION_REVOKED or SOFT_RESTRICTED or
+ APP_OP_REVOKED or ONE_TIME or HIBERNATION or USER_SELECTED
+
+ /**
+ * Mask for all API permission flags about permission restriction.
+ */
+ private const val API_MASK_RESTRICTION =
+ PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT or
+ PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT or
+ PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT or
+ PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION
+
+ /**
+ * Mask for all permission flags about permission restriction.
+ */
+ private const val MASK_RESTRICTION = INSTALLER_EXEMPT or SYSTEM_EXEMPT or
+ UPGRADE_EXEMPT or RESTRICTION_REVOKED or SOFT_RESTRICTED
+
+ fun isPermissionGranted(policyFlags: Int): Boolean {
+ if (policyFlags.hasBits(INSTALL_GRANTED)) {
+ return true
+ }
+ if (policyFlags.hasBits(INSTALL_REVOKED)) {
+ return false
+ }
+ if (policyFlags.hasBits(PROTECTION_GRANTED)) {
+ return true
+ }
+ if (policyFlags.hasBits(LEGACY_GRANTED) || policyFlags.hasBits(IMPLICIT_GRANTED)) {
+ return true
+ }
+ if (policyFlags.hasBits(RESTRICTION_REVOKED)) {
+ return false
+ }
+ return policyFlags.hasBits(RUNTIME_GRANTED)
+ }
+
+ fun isAppOpGranted(policyFlags: Int): Boolean =
+ isPermissionGranted(policyFlags) && !policyFlags.hasBits(APP_OP_REVOKED)
+
+ fun isReviewRequired(policyFlags: Int): Boolean =
+ policyFlags.hasBits(LEGACY_GRANTED) && policyFlags.hasBits(IMPLICIT)
+
+ fun toApiFlags(policyFlags: Int): Int {
+ var apiFlags = 0
+ if (policyFlags.hasBits(USER_SET)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SET
+ }
+ if (policyFlags.hasBits(USER_FIXED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_FIXED
+ }
+ if (policyFlags.hasBits(POLICY_FIXED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_POLICY_FIXED
+ }
+ if (policyFlags.hasBits(SYSTEM_FIXED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+ }
+ if (policyFlags.hasBits(PREGRANT)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT
+ }
+ if (policyFlags.hasBits(IMPLICIT)) {
+ apiFlags = apiFlags or if (policyFlags.hasBits(LEGACY_GRANTED)) {
+ PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+ } else {
+ PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
+ }
+ }
+ if (policyFlags.hasBits(USER_SENSITIVE_WHEN_GRANTED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED
+ }
+ if (policyFlags.hasBits(USER_SENSITIVE_WHEN_REVOKED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED
+ }
+ if (policyFlags.hasBits(INSTALLER_EXEMPT)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
+ }
+ if (policyFlags.hasBits(SYSTEM_EXEMPT)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+ }
+ if (policyFlags.hasBits(UPGRADE_EXEMPT)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
+ }
+ if (policyFlags.hasBits(RESTRICTION_REVOKED) || policyFlags.hasBits(SOFT_RESTRICTED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION
+ }
+ if (policyFlags.hasBits(ROLE)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE
+ }
+ if (policyFlags.hasBits(APP_OP_REVOKED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+ }
+ if (policyFlags.hasBits(ONE_TIME)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_ONE_TIME
+ }
+ if (policyFlags.hasBits(HIBERNATION)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_AUTO_REVOKED
+ }
+ if (policyFlags.hasBits(USER_SELECTED)) {
+ apiFlags = apiFlags or PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY
+ }
+ return apiFlags
+ }
+
+ fun setRuntimePermissionGranted(policyFlags: Int, isGranted: Boolean): Int =
+ if (isGranted) policyFlags or RUNTIME_GRANTED else policyFlags andInv RUNTIME_GRANTED
+
+ fun updatePolicyFlags(policyFlags: Int, apiFlagMask: Int, apiFlagValues: Int): Int {
+ check(!apiFlagMask.hasAnyBit(API_MASK_RESTRICTION)) {
+ "Permission flags about permission restriction can only be directly mutated by the" +
+ " policy"
+ }
+ val oldApiFlags = toApiFlags(policyFlags)
+ val newApiFlags = (oldApiFlags andInv apiFlagMask) or (apiFlagValues and apiFlagMask)
+ return toPolicyFlags(policyFlags, newApiFlags)
+ }
+
+ private fun toPolicyFlags(oldPolicyFlags: Int, apiFlags: Int): Int {
+ var policyFlags = 0
+ policyFlags = policyFlags or (oldPolicyFlags and INSTALL_GRANTED)
+ policyFlags = policyFlags or (oldPolicyFlags and INSTALL_REVOKED)
+ policyFlags = policyFlags or (oldPolicyFlags and PROTECTION_GRANTED)
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) {
+ policyFlags = policyFlags or ROLE
+ }
+ policyFlags = policyFlags or (oldPolicyFlags and RUNTIME_GRANTED)
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SET)) {
+ policyFlags = policyFlags or USER_SET
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_FIXED)) {
+ policyFlags = policyFlags or USER_FIXED
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_POLICY_FIXED)) {
+ policyFlags = policyFlags or POLICY_FIXED
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) {
+ policyFlags = policyFlags or SYSTEM_FIXED
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT)) {
+ policyFlags = policyFlags or PREGRANT
+ }
+ policyFlags = policyFlags or (oldPolicyFlags and LEGACY_GRANTED)
+ policyFlags = policyFlags or (oldPolicyFlags and IMPLICIT_GRANTED)
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) ||
+ apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED)) {
+ policyFlags = policyFlags or IMPLICIT
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)) {
+ policyFlags = policyFlags or USER_SENSITIVE_WHEN_GRANTED
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED)) {
+ policyFlags = policyFlags or USER_SENSITIVE_WHEN_REVOKED
+ }
+ // FLAG_PERMISSION_APPLY_RESTRICTION can be either REVOKED_BY_RESTRICTION when the
+ // permission is hard restricted, or SOFT_RESTRICTED when the permission is soft restricted.
+ // However since we should never allow indirect mutation of restriction state, we can just
+ // get the flags about restriction from the old policy flags.
+ policyFlags = policyFlags or (oldPolicyFlags and MASK_RESTRICTION)
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_REVOKED_COMPAT)) {
+ policyFlags = policyFlags or APP_OP_REVOKED
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_ONE_TIME)) {
+ policyFlags = policyFlags or ONE_TIME
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_AUTO_REVOKED)) {
+ policyFlags = policyFlags or HIBERNATION
+ }
+ if (apiFlags.hasBits(PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY)) {
+ policyFlags = policyFlags or USER_SELECTED
+ }
+ return policyFlags
+ }
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index f04734caedba..82017362da29 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -232,7 +232,12 @@ class PermissionService(
}
override fun getPermissionFlags(packageName: String, permissionName: String, userId: Int): Int {
- TODO("Not yet implemented")
+ // TODO: Implement permission checks.
+ val appId = 0
+ val flags = service.getState {
+ with(policy) { getPermissionFlags(appId, userId, permissionName) }
+ }
+ return PermissionFlags.toApiFlags(flags)
}
override fun isPermissionRevokedByPolicy(
@@ -244,7 +249,12 @@ class PermissionService(
}
override fun isPermissionsReviewRequired(packageName: String, userId: Int): Boolean {
- TODO("Not yet implemented")
+ val packageState = packageManagerLocal.withUnfilteredSnapshot()
+ .use { it.packageStates[packageName] } ?: return false
+ val permissionFlags = service.getState {
+ with(policy) { getUidPermissionFlags(packageState.appId, userId) }
+ } ?: return false
+ return permissionFlags.anyIndexed { _, _, flags -> PermissionFlags.isReviewRequired(flags) }
}
override fun shouldShowRequestPermissionRationale(
diff --git a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
index a17a31797270..b2f52cc814cb 100644
--- a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
@@ -37,7 +37,6 @@ import com.android.server.permission.access.SystemState
import com.android.server.permission.access.UidUri
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.util.andInv
-import com.android.server.permission.access.util.hasAnyBit
import com.android.server.permission.access.util.hasBits
import com.android.server.pm.KnownPackages
import com.android.server.pm.parsing.PackageInfoUtils
@@ -474,10 +473,10 @@ class UidPermissionPolicy : SchemePolicy() {
// should only affect the other static flags, but not dynamic flags like development or
// role. This may be useful in the case of an updated system app.
if (permission.isDevelopment) {
- newFlags = newFlags or (oldFlags and PermissionFlags.OTHER_GRANTED)
+ newFlags = newFlags or (oldFlags and PermissionFlags.RUNTIME_GRANTED)
}
if (permission.isRole) {
- newFlags = newFlags or (oldFlags and PermissionFlags.ROLE_GRANTED)
+ newFlags = newFlags or (oldFlags and PermissionFlags.ROLE)
}
setPermissionFlags(appId, userId, permissionName, newFlags)
} else if (permission.isRuntime) {
@@ -519,8 +518,8 @@ class UidPermissionPolicy : SchemePolicy() {
"Unknown source permission $sourcePermissionName in split permissions"
}
val sourceFlags = getPermissionFlags(appId, userId, sourcePermissionName)
- val isSourceGranted = sourceFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
- val isNewGranted = newFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
+ val isSourceGranted = PermissionFlags.isPermissionGranted(sourceFlags)
+ val isNewGranted = PermissionFlags.isPermissionGranted(newFlags)
val isGrantingNewFromRevoke = isSourceGranted && !isNewGranted
if (isSourceGranted == isNewGranted || isGrantingNewFromRevoke) {
if (isGrantingNewFromRevoke) {
@@ -528,7 +527,7 @@ class UidPermissionPolicy : SchemePolicy() {
}
newFlags = newFlags or (sourceFlags and PermissionFlags.MASK_RUNTIME)
if (!sourcePermission.isRuntime && isSourceGranted) {
- newFlags = newFlags or PermissionFlags.OTHER_GRANTED
+ newFlags = newFlags or PermissionFlags.IMPLICIT_GRANTED
}
}
}
@@ -836,6 +835,9 @@ class UidPermissionPolicy : SchemePolicy() {
fun GetStateScope.getPermission(permissionName: String): Permission? =
state.systemState.permissions[permissionName]
+ fun GetStateScope.getUidPermissionFlags(appId: Int, userId: Int): IndexedMap<String, Int>? =
+ state.userStates[userId]?.uidPermissionFlags?.get(appId)
+
fun GetStateScope.getPermissionFlags(
appId: Int,
userId: Int,
@@ -854,7 +856,8 @@ class UidPermissionPolicy : SchemePolicy() {
appId: Int,
userId: Int,
permissionName: String
- ): Int = state.userStates[userId].uidPermissionFlags[appId].getWithDefault(permissionName, 0)
+ ): Int =
+ state.userStates[userId]?.uidPermissionFlags?.get(appId).getWithDefault(permissionName, 0)
fun MutateStateScope.setPermissionFlags(
appId: Int,
@@ -875,7 +878,7 @@ class UidPermissionPolicy : SchemePolicy() {
val uidPermissionFlags = userState.uidPermissionFlags
var permissionFlags = uidPermissionFlags[appId]
val oldFlags = permissionFlags.getWithDefault(permissionName, 0)
- val newFlags = (oldFlags andInv flagMask) or flagValues
+ val newFlags = (oldFlags andInv flagMask) or (flagValues and flagMask)
if (oldFlags == newFlags) {
return false
}