diff options
4 files changed, 589 insertions, 10 deletions
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt index f3ab0e33d026..f4d7a8ec5484 100644 --- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt @@ -21,6 +21,7 @@ import android.content.pm.PackageManager import android.content.pm.PermissionGroupInfo import android.content.pm.PermissionInfo import android.content.pm.SigningDetails +import android.health.connect.HealthPermissions import android.os.Build import android.permission.flags.Flags import android.util.Slog @@ -701,6 +702,7 @@ class AppIdPermissionPolicy : SchemePolicy() { private fun MutateStateScope.revokePermissionsOnPackageUpdate(appId: Int) { revokeStorageAndMediaPermissionsOnPackageUpdate(appId) + revokeHeartRatePermissionsOnPackageUpdate(appId) } private fun MutateStateScope.revokeStorageAndMediaPermissionsOnPackageUpdate(appId: Int) { @@ -751,23 +753,154 @@ class AppIdPermissionPolicy : SchemePolicy() { // SYSTEM_FIXED. Otherwise the user cannot grant back the permission. if ( permissionName in STORAGE_AND_MEDIA_PERMISSIONS && - oldFlags.hasBits(PermissionFlags.RUNTIME_GRANTED) && - !oldFlags.hasAnyBit(SYSTEM_OR_POLICY_FIXED_MASK) + oldFlags.hasBits(PermissionFlags.RUNTIME_GRANTED) ) { - Slog.v( - LOG_TAG, - "Revoking storage permission: $permissionName for appId: " + - " $appId and user: $userId", + revokeRuntimePermission(appId, userId, permissionName) + } + } + } + } + } + + /** + * If the app is updated, the legacy BODY_SENSOR and READ_HEART_RATE permissions may go out of + * sync (for example, when the app eventually requests the implicit new permission). If this + * occurs, revoke both permissions to force a re-prompt. + */ + private fun MutateStateScope.revokeHeartRatePermissionsOnPackageUpdate(appId: Int) { + val targetSdkVersion = getAppIdTargetSdkVersion(appId, null) + // Apps targeting BAKLAVA and above shouldn't be using BODY_SENSORS. + if (targetSdkVersion >= Build.VERSION_CODES.BAKLAVA) { + return + } + + val isBodySensorsRequested = + anyPackageInAppId(appId, newState) { + Manifest.permission.BODY_SENSORS in it.androidPackage!!.requestedPermissions + } + val isReadHeartRateRequested = + anyPackageInAppId(appId, newState) { + HealthPermissions.READ_HEART_RATE in it.androidPackage!!.requestedPermissions + } + val isBodySensorsBackgroundRequested = + anyPackageInAppId(appId, newState) { + Manifest.permission.BODY_SENSORS_BACKGROUND in + it.androidPackage!!.requestedPermissions + } + val isReadHealthDataInBackgroundRequested = + anyPackageInAppId(appId, newState) { + HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND in + it.androidPackage!!.requestedPermissions + } + + // Walk the list of user IDs and revoke states as needed. + newState.userStates.forEachIndexed { _, userId, _ -> + // First sync BODY_SENSORS and READ_HEART_RATE, if required. + var isBodySensorsGranted = + isRuntimePermissionGranted(appId, userId, Manifest.permission.BODY_SENSORS) + if (isBodySensorsRequested && isReadHeartRateRequested) { + val isReadHeartRateGranted = + isRuntimePermissionGranted(appId, userId, HealthPermissions.READ_HEART_RATE) + if (isBodySensorsGranted != isReadHeartRateGranted) { + if (isBodySensorsGranted) { + if ( + revokeRuntimePermission(appId, userId, Manifest.permission.BODY_SENSORS) + ) { + isBodySensorsGranted = false + } + } + if (isReadHeartRateGranted) { + revokeRuntimePermission(appId, userId, HealthPermissions.READ_HEART_RATE) + } + } + } + + // Then check to ensure we haven't put the background/foreground permissions out of + // sync. + var isBodySensorsBackgroundGranted = + isRuntimePermissionGranted( + appId, + userId, + Manifest.permission.BODY_SENSORS_BACKGROUND, + ) + if (isBodySensorsBackgroundGranted && !isBodySensorsGranted) { + if ( + revokeRuntimePermission( + appId, + userId, + Manifest.permission.BODY_SENSORS_BACKGROUND, + ) + ) { + isBodySensorsBackgroundGranted = false + } + } + + // Finally sync BODY_SENSORS_BACKGROUND and READ_HEALTH_DATA_IN_BACKGROUND, if required. + if (isBodySensorsBackgroundRequested && isReadHealthDataInBackgroundRequested) { + val isReadHealthDataInBackgroundGranted = + isRuntimePermissionGranted( + appId, + userId, + HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND, + ) + if (isBodySensorsBackgroundGranted != isReadHealthDataInBackgroundGranted) { + if (isBodySensorsBackgroundGranted) { + revokeRuntimePermission( + appId, + userId, + Manifest.permission.BODY_SENSORS_BACKGROUND, + ) + } + if (isReadHealthDataInBackgroundGranted) { + revokeRuntimePermission( + appId, + userId, + HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND, ) - val newFlags = - oldFlags andInv (PermissionFlags.RUNTIME_GRANTED or USER_SETTABLE_MASK) - setPermissionFlags(appId, userId, permissionName, newFlags) } } } } } + private fun GetStateScope.isRuntimePermissionGranted( + appId: Int, + userId: Int, + permissionName: String, + ): Boolean { + val flags = getPermissionFlags(appId, userId, permissionName) + return PermissionFlags.isAppOpGranted(flags) + } + + fun MutateStateScope.revokeRuntimePermission( + appId: Int, + userId: Int, + permissionName: String, + ): Boolean { + Slog.v( + LOG_TAG, + "Revoking runtime permission for appId: $appId, " + + "permission: $permissionName, userId: $userId", + ) + var flags = getPermissionFlags(appId, userId, permissionName) + if (flags.hasAnyBit(SYSTEM_OR_POLICY_FIXED_MASK)) { + Slog.v( + LOG_TAG, + "Not allowed to revoke $permissionName for appId: $appId, userId: $userId", + ) + return false + } + + flags = + flags andInv + (PermissionFlags.RUNTIME_GRANTED or + USER_SETTABLE_MASK or + PermissionFlags.PREGRANT or + PermissionFlags.ROLE) + setPermissionFlags(appId, userId, permissionName, flags) + return true + } + private fun MutateStateScope.evaluatePermissionStateForAllPackages( permissionName: String, installedPackageState: PackageState?, diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt index bd63918e751b..e3e965de4559 100644 --- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt +++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt @@ -441,7 +441,7 @@ class AppIdPermissionUpgrade(private val policy: AppIdPermissionPolicy) { return false } - val newFlags = + flags = flags andInv (PermissionFlags.RUNTIME_GRANTED or MASK_USER_SETTABLE or diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt index bf9033981442..c0f0369d4774 100644 --- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt +++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionStatesTest.kt @@ -29,6 +29,7 @@ import com.android.server.pm.pkg.PackageState import com.android.server.testutils.mock import com.android.server.testutils.whenever import com.google.common.truth.Truth.assertWithMessage +import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -537,6 +538,442 @@ class AppIdPermissionPolicyPermissionStatesTest : BasePermissionPolicyTest() { .isEqualTo(expectedNewFlags) } + /** Setup: BODY_SENSORS: granted, READ_HEART_RATE: not granted Result: BODY_SENSORS: revoked */ + @Test + fun testEvaluatePermissionState_bodySensorReadHrOutOfSync_revokesGrantedBodySensor() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = PermissionFlags.RUNTIME_GRANTED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS, + requestedPermissions = setOf(PERMISSION_BODY_SENSORS, PERMISSION_READ_HEART_RATE), + ) {} + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " permission that was granted while read hr was not, the actual permission" + + " flags $actualFlags should match the expected flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS: not granted, READ_HEART_RATE: granted Result: READ_HEART_RATE: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorReadHrOutOfSync_revokesGrantedReadHr() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = 0 + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS, + requestedPermissions = setOf(PERMISSION_BODY_SENSORS, PERMISSION_READ_HEART_RATE), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEART_RATE, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_READ_HEART_RATE) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " permission that was not granted while read hr was, the actual permission" + + "flags $actualFlags should match the expected flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS: granted, READ_HEART_RATE: not granted Result: nothing revoked since the + * targetSdk is Baklava + */ + @Test + fun testEvaluatePermissionState_bodySensorReadHrOutOfSync_baklavaTargetSdk_nothingRevoked() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = PermissionFlags.RUNTIME_GRANTED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS, + installedPackageTargetSdkVersion = Build.VERSION_CODES.BAKLAVA, + requestedPermissions = setOf(PERMISSION_BODY_SENSORS, PERMISSION_READ_HEART_RATE), + ) {} + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS) + val expectedNewFlags = oldFlags + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " permission that was granted while read hr was not targeting Baklava," + + " the actual permission flags $actualFlags should match the expected" + + " flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS_BACKGROUND: granted, BODY_SENSORS: not granted Result: + * BODY_SENSORS_BACKGROUND: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorBackgroundGrantMismatch_revokesBackground() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = 0 + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS, + requestedPermissions = + setOf(PERMISSION_BODY_SENSORS, PERMISSION_BODY_SENSORS_BACKGROUND), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " permission that was not granted while body sensors background was," + + " the actual permission flags $actualFlags should match the expected" + + " flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS_BACKGROUND: granted, BODY_SENSORS: not requested Result: + * BODY_SENSORS_BACKGROUND: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorBackgroundMissingForeground_baklavaTargetSdk_revokesBackground() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = PermissionFlags.RUNTIME_GRANTED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS_BACKGROUND, + requestedPermissions = setOf(PERMISSION_BODY_SENSORS_BACKGROUND), + ) {} + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that has runtime body sensors background" + + " permission granted but is not requesting the body sensors foreground" + + " permission, the actual permission flags $actualFlags should match the" + + " expected flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS_BACKGROUND: granted, BODY_SENSORS: granted, READ_HEART_RATE: not granted + * Result: BODY_SENSORS_BACKGROUND: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorHeartRateOutOfSync_revokesGrantedBodySensorBackground() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = PermissionFlags.RUNTIME_GRANTED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS, + installedPackageTargetSdkVersion = Build.VERSION_CODES.BAKLAVA, + requestedPermissions = + setOf(PERMISSION_BODY_SENSORS, PERMISSION_READ_HEART_RATE, PERMISSION_BODY_SENSORS), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " permission that was granted while read hr was not targeting Baklava," + + " the actual permission flags $actualFlags should match the expected" + + " flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS_BACKGROUND: granted, READ_HEALTH_DATA_IN_BACKGROUND: not granted Result: + * BODY_SENSORS_BACKGROUND: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorReadHealthBackgroundOutOfSync_revokesGrantedBodySensorBackground() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = 0 + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS_BACKGROUND, + requestedPermissions = + setOf(PERMISSION_BODY_SENSORS_BACKGROUND, PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val actualFlags = + getPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + ) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " background permission that was not granted while read health data in" + + " background was, the actual permission flags $actualFlags should match" + + " the expected flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Setup: BODY_SENSORS_BACKGROUND: not granted, READ_HEALTH_DATA_IN_BACKGROUND: granted Result: + * READ_HEALTH_DATA_IN_BACKGROUND: revoked + */ + @Test + fun testEvaluatePermissionState_bodySensorReadHealthBackgroundOutOfSync_revokesGrantedReadHealthBackground() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = PermissionFlags.RUNTIME_GRANTED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_BODY_SENSORS_BACKGROUND, + requestedPermissions = + setOf(PERMISSION_BODY_SENSORS_BACKGROUND, PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND), + ) {} + + val actualFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that requests a runtime body sensors" + + " background permission that was granted while read health data in" + + " background was not, the actual permission flags $actualFlags should match" + + " the expected flags $expectedNewFlags" + ) + .that(actualFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * The sequence of events here is: + * + * Starting: + * - READ_HR=not granted + * - BODY_SENSORS=granted + * - BODY_SENSORS_BACKGROUND=granted, + * - READ_HEALTH_DATA_IN_BACKGROUND=granted + * + * Actions: + * - BODY_SENSORS->revoked (due to READ_HR mismatch) + * - BODY_SENSORS_BACKGROUND->revoked (due to new BODY_SENSORS mismatch) + * - READ_HEALTH_DATA_IN_BACKGROUND->revoked (due to new BODY_SENSORS_BACKGROUND mismatch) + * + * End result: All permissions revoked. + */ + @Test + fun testEvaluatePermissionState_healthPermissionsSync_revocationChain() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = 0 + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_READ_HEART_RATE, + requestedPermissions = + setOf( + PERMISSION_READ_HEART_RATE, + PERMISSION_BODY_SENSORS, + PERMISSION_BODY_SENSORS_BACKGROUND, + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + ), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS, + PermissionFlags.RUNTIME_GRANTED, + ) + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val bodySensorsFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS) + val bodySensorsBackgroundFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val readHealthDataInBackgroundFlags = + getPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + ) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + " the actual permission flags for body sensors $bodySensorsFlags should" + + " match the expected flags $expectedNewFlags" + ) + .that(bodySensorsFlags) + .isEqualTo(expectedNewFlags) + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + " the actual permission flags for body sensors background" + + " $bodySensorsBackgroundFlags should match the expected flags" + + " $expectedNewFlags" + ) + .that(bodySensorsBackgroundFlags) + .isEqualTo(expectedNewFlags) + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + " the actual permission flags for read health data in background" + + " $readHealthDataInBackgroundFlags" + + " should match the expected flags $expectedNewFlags" + ) + .that(readHealthDataInBackgroundFlags) + .isEqualTo(expectedNewFlags) + } + + /** + * Similar to test case above but this time the READ_HR permission is going implicitly to + * explicitly granted (which causes it's grant to be revoked). + * + * Starting: + * - READ_HR=imlpicitly granted + * - BODY_SENSORS=granted + * - BODY_SENSORS_BACKGROUND=granted, + * - READ_HEALTH_DATA_IN_BACKGROUND=granted + * + * Actions: + * - READ_HR->revoked (due to implicit permission being explicitly requested) + * - BODY_SENSORS->revoked (due to READ_HR mismatch) + * - BODY_SENSORS_BACKGROUND->revoked (due to new BODY_SENSORS mismatch) + * - READ_HEALTH_DATA_IN_BACKGROUND->revoked (due to new BODY_SENSORS_BACKGROUND mismatch) + * + * End result: All permissions revoked. + */ + @Test + fun testEvaluatePermissionState_implicitHealthPermissionRequested_causesRevocationChain() { + assumeTrue(action != Action.ON_USER_ADDED) + val oldFlags = + PermissionFlags.IMPLICIT or + PermissionFlags.RUNTIME_GRANTED or + PermissionFlags.USER_SET or + PermissionFlags.USER_FIXED + testEvaluatePermissionState( + oldFlags, + PermissionInfo.PROTECTION_DANGEROUS, + permissionName = PERMISSION_READ_HEART_RATE, + requestedPermissions = + setOf( + PERMISSION_READ_HEART_RATE, + PERMISSION_BODY_SENSORS, + PERMISSION_BODY_SENSORS_BACKGROUND, + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + ), + ) { + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS, + PermissionFlags.RUNTIME_GRANTED, + ) + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_BODY_SENSORS_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + setPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + PermissionFlags.RUNTIME_GRANTED, + ) + } + + val bodySensorsFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS) + val bodySensorsBackgroundFlags = + getPermissionFlags(APP_ID_1, getUserIdEvaluated(), PERMISSION_BODY_SENSORS_BACKGROUND) + val readHealthDataInBackgroundFlags = + getPermissionFlags( + APP_ID_1, + getUserIdEvaluated(), + PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND, + ) + val expectedNewFlags = 0 + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + "the actual permission flags for body sensors $bodySensorsFlags should match the" + + "expected flags $expectedNewFlags" + ) + .that(bodySensorsFlags) + .isEqualTo(expectedNewFlags) + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + "the actual permission flags for body sensors background $bodySensorsBackgroundFlags should" + + "match the expected flags $expectedNewFlags" + ) + .that(bodySensorsBackgroundFlags) + .isEqualTo(expectedNewFlags) + assertWithMessage( + "After $action is called for a package that has mismatching health permissions," + + "the actual permission flags for read health data in background $readHealthDataInBackgroundFlags" + + "should match the expected flags $expectedNewFlags" + ) + .that(readHealthDataInBackgroundFlags) + .isEqualTo(expectedNewFlags) + } + @Test fun testEvaluatePermissionState_noLongerImplicitSystemOrPolicyFixedWasGranted_runtimeGranted() { val oldFlags = diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BasePermissionPolicyTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BasePermissionPolicyTest.kt index 207820cc3135..6dfd2611e0af 100644 --- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BasePermissionPolicyTest.kt +++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/BasePermissionPolicyTest.kt @@ -21,6 +21,7 @@ import android.content.pm.PackageManager import android.content.pm.PermissionGroupInfo import android.content.pm.PermissionInfo import android.content.pm.SigningDetails +import android.health.connect.HealthPermissions import android.os.Build import android.os.Bundle import android.util.ArrayMap @@ -390,6 +391,14 @@ abstract class BasePermissionPolicyTest { Manifest.permission.ACCESS_BACKGROUND_LOCATION @JvmStatic protected val PERMISSION_ACCESS_MEDIA_LOCATION = Manifest.permission.ACCESS_MEDIA_LOCATION + @JvmStatic protected val PERMISSION_BODY_SENSORS = Manifest.permission.BODY_SENSORS + @JvmStatic + protected val PERMISSION_BODY_SENSORS_BACKGROUND = + Manifest.permission.BODY_SENSORS_BACKGROUND + @JvmStatic protected val PERMISSION_READ_HEART_RATE = HealthPermissions.READ_HEART_RATE + @JvmStatic + protected val PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND = + HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND @JvmStatic protected val USER_ID_0 = 0 @JvmStatic protected val USER_ID_NEW = 1 |