Loading services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt +19 −8 Original line number Diff line number Diff line Loading @@ -769,6 +769,7 @@ class AppIdPermissionPolicy : SchemePolicy() { setPermissionFlags(appId, userId, permissionName, newFlags) } else if (permission.isRuntime) { var newFlags = oldFlags and PermissionFlags.MASK_RUNTIME val wasRevoked = newFlags != 0 && !PermissionFlags.isPermissionGranted(newFlags) if (getAppIdTargetSdkVersion(appId, permissionName) < Build.VERSION_CODES.M) { if (permission.isRuntimeOnly) { // Different from the old implementation, which simply skips a runtime-only Loading @@ -778,6 +779,9 @@ class AppIdPermissionPolicy : SchemePolicy() { newFlags = newFlags and PermissionFlags.MASK_EXEMPT } else { newFlags = newFlags or PermissionFlags.LEGACY_GRANTED if (wasRevoked) { newFlags = newFlags or PermissionFlags.APP_OP_REVOKED } // Explicitly check against the old state to determine if this permission is // new. val isNewPermission = Loading Loading @@ -808,16 +812,23 @@ class AppIdPermissionPolicy : SchemePolicy() { (isImplicitPermission && isAnySourcePermissionNonRuntime) if (shouldGrantByImplicit) { newFlags = newFlags or PermissionFlags.IMPLICIT_GRANTED if (wasRevoked) { newFlags = newFlags or PermissionFlags.APP_OP_REVOKED } } else { newFlags = newFlags andInv PermissionFlags.IMPLICIT_GRANTED if ((wasGrantedByLegacy || wasGrantedByImplicit) && newFlags.hasBits(PermissionFlags.APP_OP_REVOKED)) { // The permission was granted from a compatibility grant or an implicit // grant, however this flag might still be set if the user denied this // permission in the settings. Hence upon app upgrade and when this // permission is no longer LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke // the permission, we want to remove this flag so that the app can request // the permission again. newFlags = newFlags andInv ( PermissionFlags.RUNTIME_GRANTED or PermissionFlags.APP_OP_REVOKED ) } if ((wasGrantedByLegacy || wasGrantedByImplicit) && !shouldGrantByImplicit) { // The permission was granted from a compatibility grant or an implicit grant, // however this flag might still be set if the user denied this permission in // the settings. Hence upon app upgrade and when this permission is no longer // LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke the permission, we want to // remove this flag so that the app can request the permission again. newFlags = newFlags andInv PermissionFlags.APP_OP_REVOKED } val hasImplicitFlag = newFlags.hasBits(PermissionFlags.IMPLICIT) if (!isImplicitPermission && hasImplicitFlag) { Loading services/permission/java/com/android/server/permission/access/permission/Permission.kt +1 −3 Original line number Diff line number Diff line Loading @@ -140,9 +140,7 @@ data class Permission( get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED) inline val isHardOrSoftRestricted: Boolean get() = permissionInfo.flags.hasBits( PermissionInfo.FLAG_HARD_RESTRICTED or PermissionInfo.FLAG_SOFT_RESTRICTED ) get() = isHardRestricted || isSoftRestricted inline val isImmutablyRestricted: Boolean get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) Loading services/permission/java/com/android/server/permission/access/permission/PermissionService.kt +15 −9 Original line number Diff line number Diff line Loading @@ -1570,27 +1570,33 @@ class PermissionService( return@forEachIndexed } val wasAllowlisted = oldFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) val isAllowlisted = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) // If the permission is policy fixed as granted but it is no longer // on any of the allowlists we need to clear the policy fixed flag // as allowlisting trumps policy i.e. policy cannot grant a non // grantable permission. if (oldFlags.hasBits(PermissionFlags.POLICY_FIXED)) { if (!isAllowlisted && wasGranted) { if (!isExempt && wasGranted) { mask = mask or PermissionFlags.POLICY_FIXED newFlags = newFlags andInv PermissionFlags.POLICY_FIXED } } // If we are allowlisting an app that does not support runtime permissions // we need to make sure it goes through the permission review UI at launch. if (androidPackage.targetSdkVersion < Build.VERSION_CODES.M && !wasAllowlisted && isAllowlisted) { mask = mask or PermissionFlags.IMPLICIT newFlags = newFlags or PermissionFlags.IMPLICIT val isHardRestricted = permission.isHardRestricted && !isExempt newFlags = if (isHardRestricted) { newFlags or PermissionFlags.RESTRICTION_REVOKED } else { newFlags andInv PermissionFlags.RESTRICTION_REVOKED } val isSoftRestricted = permission.isSoftRestricted && !isExempt newFlags = if (isSoftRestricted) { newFlags or PermissionFlags.SOFT_RESTRICTED } else { newFlags andInv PermissionFlags.SOFT_RESTRICTED } mask = mask or PermissionFlags.RESTRICTION_REVOKED or PermissionFlags.SOFT_RESTRICTED updatePermissionFlags( appId, userId, requestedPermission, mask, newFlags Loading Loading
services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt +19 −8 Original line number Diff line number Diff line Loading @@ -769,6 +769,7 @@ class AppIdPermissionPolicy : SchemePolicy() { setPermissionFlags(appId, userId, permissionName, newFlags) } else if (permission.isRuntime) { var newFlags = oldFlags and PermissionFlags.MASK_RUNTIME val wasRevoked = newFlags != 0 && !PermissionFlags.isPermissionGranted(newFlags) if (getAppIdTargetSdkVersion(appId, permissionName) < Build.VERSION_CODES.M) { if (permission.isRuntimeOnly) { // Different from the old implementation, which simply skips a runtime-only Loading @@ -778,6 +779,9 @@ class AppIdPermissionPolicy : SchemePolicy() { newFlags = newFlags and PermissionFlags.MASK_EXEMPT } else { newFlags = newFlags or PermissionFlags.LEGACY_GRANTED if (wasRevoked) { newFlags = newFlags or PermissionFlags.APP_OP_REVOKED } // Explicitly check against the old state to determine if this permission is // new. val isNewPermission = Loading Loading @@ -808,16 +812,23 @@ class AppIdPermissionPolicy : SchemePolicy() { (isImplicitPermission && isAnySourcePermissionNonRuntime) if (shouldGrantByImplicit) { newFlags = newFlags or PermissionFlags.IMPLICIT_GRANTED if (wasRevoked) { newFlags = newFlags or PermissionFlags.APP_OP_REVOKED } } else { newFlags = newFlags andInv PermissionFlags.IMPLICIT_GRANTED if ((wasGrantedByLegacy || wasGrantedByImplicit) && newFlags.hasBits(PermissionFlags.APP_OP_REVOKED)) { // The permission was granted from a compatibility grant or an implicit // grant, however this flag might still be set if the user denied this // permission in the settings. Hence upon app upgrade and when this // permission is no longer LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke // the permission, we want to remove this flag so that the app can request // the permission again. newFlags = newFlags andInv ( PermissionFlags.RUNTIME_GRANTED or PermissionFlags.APP_OP_REVOKED ) } if ((wasGrantedByLegacy || wasGrantedByImplicit) && !shouldGrantByImplicit) { // The permission was granted from a compatibility grant or an implicit grant, // however this flag might still be set if the user denied this permission in // the settings. Hence upon app upgrade and when this permission is no longer // LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke the permission, we want to // remove this flag so that the app can request the permission again. newFlags = newFlags andInv PermissionFlags.APP_OP_REVOKED } val hasImplicitFlag = newFlags.hasBits(PermissionFlags.IMPLICIT) if (!isImplicitPermission && hasImplicitFlag) { Loading
services/permission/java/com/android/server/permission/access/permission/Permission.kt +1 −3 Original line number Diff line number Diff line Loading @@ -140,9 +140,7 @@ data class Permission( get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED) inline val isHardOrSoftRestricted: Boolean get() = permissionInfo.flags.hasBits( PermissionInfo.FLAG_HARD_RESTRICTED or PermissionInfo.FLAG_SOFT_RESTRICTED ) get() = isHardRestricted || isSoftRestricted inline val isImmutablyRestricted: Boolean get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) Loading
services/permission/java/com/android/server/permission/access/permission/PermissionService.kt +15 −9 Original line number Diff line number Diff line Loading @@ -1570,27 +1570,33 @@ class PermissionService( return@forEachIndexed } val wasAllowlisted = oldFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) val isAllowlisted = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT) // If the permission is policy fixed as granted but it is no longer // on any of the allowlists we need to clear the policy fixed flag // as allowlisting trumps policy i.e. policy cannot grant a non // grantable permission. if (oldFlags.hasBits(PermissionFlags.POLICY_FIXED)) { if (!isAllowlisted && wasGranted) { if (!isExempt && wasGranted) { mask = mask or PermissionFlags.POLICY_FIXED newFlags = newFlags andInv PermissionFlags.POLICY_FIXED } } // If we are allowlisting an app that does not support runtime permissions // we need to make sure it goes through the permission review UI at launch. if (androidPackage.targetSdkVersion < Build.VERSION_CODES.M && !wasAllowlisted && isAllowlisted) { mask = mask or PermissionFlags.IMPLICIT newFlags = newFlags or PermissionFlags.IMPLICIT val isHardRestricted = permission.isHardRestricted && !isExempt newFlags = if (isHardRestricted) { newFlags or PermissionFlags.RESTRICTION_REVOKED } else { newFlags andInv PermissionFlags.RESTRICTION_REVOKED } val isSoftRestricted = permission.isSoftRestricted && !isExempt newFlags = if (isSoftRestricted) { newFlags or PermissionFlags.SOFT_RESTRICTED } else { newFlags andInv PermissionFlags.SOFT_RESTRICTED } mask = mask or PermissionFlags.RESTRICTION_REVOKED or PermissionFlags.SOFT_RESTRICTED updatePermissionFlags( appId, userId, requestedPermission, mask, newFlags Loading