diff options
| author | 2022-12-14 22:49:47 +0000 | |
|---|---|---|
| committer | 2022-12-14 22:49:47 +0000 | |
| commit | 53fe6bdb82e52a1b4edb5b6d6afb6ae43821d649 (patch) | |
| tree | 1b90910fcd4e12d377bf421fbe430d77c80e87b0 /services/permission/java | |
| parent | d741b93f4b0b6a6fdb951e911ea79a3beec509c0 (diff) | |
| parent | 9043314199eb7cadc1e34981f4da3629ec1b7984 (diff) | |
Merge "Add new permission flags implementation."
Diffstat (limited to 'services/permission/java')
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 } |