1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.permissioncontroller.tests.mocking.permission.utils 18 19 import android.Manifest 20 import android.app.ActivityManager 21 import android.app.AppOpsManager 22 import android.app.AppOpsManager.MODE_ALLOWED 23 import android.app.AppOpsManager.MODE_FOREGROUND 24 import android.app.AppOpsManager.MODE_IGNORED 25 import android.app.AppOpsManager.permissionToOp 26 import android.app.Application 27 import android.content.pm.PackageManager 28 import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED 29 import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME 30 import android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 31 import android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 32 import android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 33 import android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED 34 import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET 35 import android.content.pm.PackageManager.PERMISSION_DENIED 36 import android.content.pm.PackageManager.PERMISSION_GRANTED 37 import android.content.pm.PermissionInfo 38 import android.content.pm.PermissionInfo.PROTECTION_FLAG_INSTANT 39 import android.content.pm.PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY 40 import android.os.Build 41 import android.os.UserHandle 42 import android.permission.PermissionManager 43 import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup 44 import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo 45 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo 46 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo 47 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission 48 import com.android.permissioncontroller.permission.utils.KotlinUtils 49 import com.google.common.truth.Truth.assertThat 50 import com.google.common.truth.Truth.assertWithMessage 51 import org.junit.Assume.assumeNotNull 52 import org.junit.Assume.assumeTrue 53 import org.junit.BeforeClass 54 import org.junit.Test 55 import org.junit.runner.RunWith 56 import org.mockito.ArgumentMatchers.anyInt 57 import org.mockito.ArgumentMatchers.anyString 58 import org.mockito.ArgumentMatchers.eq 59 import org.mockito.ArgumentMatchers.nullable 60 import org.mockito.Mock 61 import org.mockito.Mockito.`when` 62 import org.mockito.Mockito.mock 63 import org.mockito.Mockito.never 64 import org.mockito.Mockito.verify 65 66 import androidx.test.ext.junit.runners.AndroidJUnit4 67 68 private const val PERMISSION_CONTROLLER_CHANGED_FLAG_MASK = FLAG_PERMISSION_USER_SET or 69 FLAG_PERMISSION_USER_FIXED or 70 FLAG_PERMISSION_ONE_TIME or 71 FLAG_PERMISSION_REVOKED_COMPAT or 72 FLAG_PERMISSION_ONE_TIME or 73 FLAG_PERMISSION_REVIEW_REQUIRED or 74 FLAG_PERMISSION_AUTO_REVOKED 75 76 /** 77 * A suite of unit tests to test the granting and revoking of permissions. Note- does not currently 78 * test the Location Access Check. 79 */ 80 @RunWith(AndroidJUnit4::class) 81 class GrantRevokeTests { 82 83 companion object { 84 private const val PERM_GROUP_NAME = Manifest.permission_group.LOCATION 85 private const val FG_PERM_NAME = Manifest.permission.ACCESS_COARSE_LOCATION 86 private const val FG_PERM_2_NAME = Manifest.permission.ACCESS_FINE_LOCATION 87 private const val FG_PERM_NAME_NO_APP_OP = "android.permission.permWithNoAppOp" 88 private const val BG_PERM_NAME = Manifest.permission.ACCESS_BACKGROUND_LOCATION 89 private const val TEST_PACKAGE_NAME = "android.permission.cts.testapp" 90 private const val TEST_UID = 1 91 private val TEST_USER = UserHandle.getUserHandleForUid(TEST_UID) 92 private const val NO_FLAGS = 0 93 private val FG_PERM_NAMES = listOf(FG_PERM_NAME, FG_PERM_2_NAME, FG_PERM_NAME_NO_APP_OP) 94 private val OP_NAME = permissionToOp(FG_PERM_NAME)!! 95 private val OP_2_NAME = permissionToOp(FG_PERM_2_NAME)!! 96 97 @BeforeClass 98 @JvmStatic checkAppOpsNotNullAndDistinctnull99 fun checkAppOpsNotNullAndDistinct() { 100 assumeNotNull(OP_NAME, OP_2_NAME) 101 assumeTrue(OP_NAME != OP_2_NAME) 102 } 103 } 104 105 @Mock 106 val app: Application = mock(Application::class.java) 107 108 /** 109 * Create a mock Application object, with a mock packageManager, AppOpsManager, and 110 * ActivityManager. 111 * 112 * @return The mocked Application object 113 */ resetMockAppStatenull114 private fun resetMockAppState() { 115 `when`(app.packageManager).thenReturn(mock(PackageManager::class.java)) 116 117 val aom: AppOpsManager = mock(AppOpsManager::class.java) 118 // Return an invalid app op state, so setOpMode will always attempt to change the op state 119 `when`(aom.unsafeCheckOpRaw(anyString(), anyInt(), nullable(String::class.java))) 120 .thenReturn(-1) 121 `when`(app.getSystemService(AppOpsManager::class.java)).thenReturn(aom) 122 123 `when`(app.getSystemService(ActivityManager::class.java)).thenReturn( 124 mock(ActivityManager::class.java)) 125 126 `when`(app.getSystemService(PermissionManager::class.java)).thenReturn( 127 mock(PermissionManager::class.java)) 128 } 129 130 /** 131 * Create a LightPackageInfo object with a particular set of properties 132 * 133 * @param perms The (name -> permissionInfo) of the permissions requested by the app 134 * @param isPreMApp Whether this app targets pre-M 135 * @param isInstantApp {@code true} iff this is an instant app 136 */ createMockPackagenull137 private fun createMockPackage( 138 perms: Map<String, Boolean>, 139 isPreMApp: Boolean = false, 140 isInstantApp: Boolean = false 141 ): LightPackageInfo { 142 val permNames = mutableListOf<String>() 143 val permFlags = mutableListOf<Int>() 144 for ((permName, isGranted) in perms) { 145 permNames.add(permName) 146 permFlags.add(if (isGranted) { 147 PERMISSION_GRANTED 148 } else { 149 PERMISSION_DENIED 150 }) 151 } 152 153 return LightPackageInfo(TEST_PACKAGE_NAME, listOf(), permNames, permFlags, TEST_UID, 154 if (isPreMApp) { 155 Build.VERSION_CODES.LOLLIPOP 156 } else { 157 Build.VERSION_CODES.R 158 }, isInstantApp, isInstantApp, 0, 0L) 159 } 160 161 /** 162 * Create a LightPermission object with a particular set of properties 163 * 164 * @param pkg Package requesting the permission 165 * @param permName The name of the permission 166 * @param granted Whether the permission is granted (should be false if the permission is compat 167 * revoked) 168 * @param backgroundPerm The name of this permission's background permission, if there is one 169 * @param foregroundPerms The names of this permission's foreground permissions, if there are 170 * any 171 * @param flags The system permission flags of this permission 172 * @param permInfoProtectionFlags The flags that the PermissionInfo object has (accessed by 173 * PermissionInfo.getProtectionFlags) 174 */ createMockPermnull175 private fun createMockPerm( 176 pkgInfo: LightPackageInfo, 177 permName: String, 178 backgroundPerm: String? = null, 179 foregroundPerms: List<String>? = null, 180 flags: Int = NO_FLAGS, 181 permInfoProtectionFlags: Int = 0 182 ): LightPermission { 183 val permInfo = LightPermInfo(permName, TEST_PACKAGE_NAME, PERM_GROUP_NAME, backgroundPerm, 184 PermissionInfo.PROTECTION_DANGEROUS, permInfoProtectionFlags, 0) 185 return LightPermission(pkgInfo, permInfo, 186 pkgInfo.requestedPermissionsFlags[pkgInfo.requestedPermissions.indexOf(permName)] 187 == PERMISSION_GRANTED, flags, foregroundPerms) 188 } 189 190 /** 191 * Create a LightAppPermGroup with a particular set of properties. 192 * 193 * @param pkg Package requesting the permission 194 * @param perms The map of perm name to LightPermission (should be created with @createMockPerm) 195 */ createMockGroupnull196 private fun createMockGroup( 197 pkgInfo: LightPackageInfo, 198 perms: Map<String, LightPermission> = emptyMap() 199 ): LightAppPermGroup { 200 val pGi = LightPermGroupInfo(PERM_GROUP_NAME, TEST_PACKAGE_NAME, 0, 0, 0, false) 201 return LightAppPermGroup(pkgInfo, pGi, perms, false, false) 202 } 203 204 /** 205 * Create a list of strings which usefully states which flags are set in a group of flags. 206 * Only checks for flags relevant to granting and revoking (so, for instance, policy fixed is 207 * not checked). 208 * 209 * @param flags The flags to check 210 * 211 * @return a list of strings, representing which flags have been set 212 */ flagsToStringnull213 private fun flagsToString(flags: Int): List<String> { 214 val flagStrings = mutableListOf<String>() 215 if (flags and FLAG_PERMISSION_USER_SET != 0) { 216 flagStrings.add("USER_SET") 217 } 218 if (flags and FLAG_PERMISSION_USER_FIXED != 0) { 219 flagStrings.add("USER_FIXED") 220 } 221 if (flags and FLAG_PERMISSION_SYSTEM_FIXED != 0) { 222 flagStrings.add("SYSTEM_FIXED") 223 } 224 if (flags and FLAG_PERMISSION_REVOKED_COMPAT != 0) { 225 flagStrings.add("REVOKED_COMPAT") 226 } 227 if (flags and FLAG_PERMISSION_REVIEW_REQUIRED != 0) { 228 flagStrings.add("REVIEW_REQUIRED") 229 } 230 if (flags and FLAG_PERMISSION_ONE_TIME != 0) { 231 flagStrings.add("ONE_TIME") 232 } 233 return flagStrings 234 } 235 236 /** 237 * Assert that the permissions of the given group match the expected state 238 * 239 * @param groupToCheck The LightAppPermGroup whose permissions we are checking 240 * @param expectedState A map <permission name, grant state and permission flags pair> 241 */ assertGroupPermStatenull242 private fun assertGroupPermState( 243 groupToCheck: LightAppPermGroup, 244 expectedState: Map<String, Pair<Boolean, Int>> 245 ) { 246 val perms = groupToCheck.permissions 247 248 assertThat(perms.keys).isEqualTo(expectedState.keys) 249 250 for ((permName, state) in expectedState) { 251 val granted = state.first 252 val flags = state.second 253 254 assertWithMessage("permission $permName grant state incorrect") 255 .that(perms[permName]?.isGrantedIncludingAppOp).isEqualTo(granted) 256 257 val actualFlags = perms[permName]!!.flags 258 assertWithMessage("permission $permName flags incorrect, expected" + 259 "${flagsToString(flags)}; got ${flagsToString(actualFlags)}") 260 .that(perms[permName]?.flags).isEqualTo(flags) 261 } 262 } 263 264 /** 265 * Verify that permission state was propagated to the system. Verify that grant or revoke 266 * were called, if applicable, or verify they weren't. Verify that we have set flags 267 * correctly, if applicable, or verify flags were not set. 268 * 269 * @param permName The name of the permission to verify 270 * @param expectPermChange Whether or not a permission grant or revoke was expected. If false, 271 * verify neither grant nor revoke were called 272 * @param expectPermGranted If a permission change was expected, verify that the permission 273 * was set to granted (if true) or revoked (if false) 274 * @param expectedFlags The flags that the system should have set the permission to have 275 * @param originalFlags The flags the permission originally had. Used to ensure the correct 276 * flag mask was used 277 */ verifyPermissionStatenull278 private fun verifyPermissionState( 279 permName: String, 280 expectPermChange: Boolean, 281 expectPermGranted: Boolean = true, 282 expectedFlags: Int = NO_FLAGS, 283 originalFlags: Int = NO_FLAGS 284 ) { 285 val pm = app.packageManager 286 if (expectPermChange) { 287 if (expectPermGranted) { 288 verify(pm).grantRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 289 } else { 290 verify(pm).revokeRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 291 } 292 } else { 293 verify(pm, never()).grantRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 294 verify(pm, never()).revokeRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 295 } 296 297 if (expectedFlags != originalFlags) { 298 verify(pm).updatePermissionFlags(permName, TEST_PACKAGE_NAME, 299 PERMISSION_CONTROLLER_CHANGED_FLAG_MASK, expectedFlags, TEST_USER) 300 } else { 301 verify(pm, never()).updatePermissionFlags(eq(permName), eq(TEST_PACKAGE_NAME), anyInt(), 302 anyInt(), eq(TEST_USER)) 303 } 304 } 305 306 /** 307 * Verify that app op state was propagated to the system. Verify that setUidMode was called, if 308 * applicable, or verify it wasn't. 309 * 310 * @param appOpName The name of the app op to check 311 * @param expectAppOpSet Whether an app op change was expected. If false, verify setUidMode was 312 * not called 313 * @param expectedMode If a change was expected, the mode the app op should be set to 314 */ verifyAppOpStatenull315 private fun verifyAppOpState( 316 appOpName: String, 317 expectAppOpSet: Boolean, 318 expectedMode: Int = MODE_IGNORED 319 ) { 320 val aom = app.getSystemService(AppOpsManager::class.java) 321 if (expectAppOpSet) { 322 verify(aom).setUidMode(appOpName, TEST_UID, expectedMode) 323 } else { 324 verify(aom, never()).setUidMode(eq(appOpName), eq(TEST_UID), anyInt()) 325 } 326 } 327 328 /** 329 * Verify that the test app either was or was not killed. 330 * 331 * @param shouldBeKilled Whether or not the app should have been killed 332 */ verifyAppKillStatenull333 private fun verifyAppKillState(shouldBeKilled: Boolean) { 334 val am = app.getSystemService(ActivityManager::class.java) 335 if (shouldBeKilled) { 336 verify(am).killUid(eq(TEST_UID), anyString()) 337 } else { 338 verify(am, never()).killUid(eq(TEST_UID), anyString()) 339 } 340 } 341 342 /** 343 * Test the granting of a single foreground permission. The permission and its app op should be 344 * granted. 345 */ 346 @Test grantOnePermTestnull347 fun grantOnePermTest() { 348 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 349 val perms = mutableMapOf<String, LightPermission>() 350 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 351 val group = createMockGroup(pkg, perms) 352 resetMockAppState() 353 354 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 355 356 val newFlags = FLAG_PERMISSION_USER_SET 357 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 358 expectPermGranted = true, expectedFlags = newFlags) 359 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 360 verifyAppKillState(shouldBeKilled = false) 361 362 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 363 assertGroupPermState(newGroup, expectedState) 364 } 365 366 /** 367 * Test the granting of two foreground permissions, one with a background permission. The 368 * permissions and app ops should be granted, and the permissions marked user set. The second 369 * app op should be set to foreground mode. 370 */ 371 @Test grantTwoPermTestnull372 fun grantTwoPermTest() { 373 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, FG_PERM_2_NAME to false)) 374 val perms = mutableMapOf<String, LightPermission>() 375 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 376 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, BG_PERM_NAME) 377 val group = createMockGroup(pkg, perms) 378 resetMockAppState() 379 380 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 381 382 val newFlags = FLAG_PERMISSION_USER_SET 383 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 384 expectPermGranted = true, expectedFlags = newFlags) 385 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 386 verifyPermissionState(permName = FG_PERM_2_NAME, expectPermChange = true, 387 expectPermGranted = true, expectedFlags = newFlags) 388 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = true, 389 expectedMode = MODE_FOREGROUND) 390 verifyAppKillState(shouldBeKilled = false) 391 392 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags), 393 FG_PERM_2_NAME to (true to newFlags)) 394 assertGroupPermState(newGroup, expectedState) 395 } 396 397 /** 398 * Test the granting of a permission with no app op. No app ops should change, but the 399 * permission should be granted 400 */ 401 @Test grantNoAppOpPermnull402 fun grantNoAppOpPerm() { 403 val pkg = createMockPackage(mapOf(FG_PERM_NAME_NO_APP_OP to false)) 404 val perms = mutableMapOf<String, LightPermission>() 405 perms[FG_PERM_NAME_NO_APP_OP] = createMockPerm(pkg, FG_PERM_NAME_NO_APP_OP) 406 val group = createMockGroup(pkg, perms) 407 resetMockAppState() 408 409 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 410 411 val newFlags = FLAG_PERMISSION_USER_SET 412 verifyPermissionState(permName = FG_PERM_NAME_NO_APP_OP, expectPermChange = true, 413 expectPermGranted = true, expectedFlags = newFlags) 414 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 415 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 416 verifyAppKillState(shouldBeKilled = false) 417 418 val expectedState = mutableMapOf(FG_PERM_NAME_NO_APP_OP to (true to newFlags)) 419 assertGroupPermState(newGroup, expectedState) 420 } 421 422 /** 423 * Test that granting a background permission grants the background permission, and allows the 424 * app ops of its foreground permissions, but does not grant the foreground permission itself. 425 */ 426 @Test grantBgPermTestnull427 fun grantBgPermTest() { 428 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to false)) 429 val perms = mutableMapOf<String, LightPermission>() 430 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 431 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 432 val group = createMockGroup(pkg, perms) 433 resetMockAppState() 434 435 val newGroup = KotlinUtils.grantBackgroundRuntimePermissions(app, group) 436 437 val newFlags = FLAG_PERMISSION_USER_SET 438 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = true, 439 expectPermGranted = true, expectedFlags = newFlags) 440 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 441 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 442 verifyAppKillState(shouldBeKilled = false) 443 444 val expectedState = mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), 445 BG_PERM_NAME to (true to newFlags)) 446 assertGroupPermState(newGroup, expectedState) 447 } 448 449 /** 450 * Test granting a foreground permission, then a background. After the foreground permission is 451 * granted, the app op should be in foreground mode. After the background permission, it should 452 * be fully allowed. 453 */ 454 @Test grantBgAndFgPermTestnull455 fun grantBgAndFgPermTest() { 456 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 457 val perms = mutableMapOf<String, LightPermission>() 458 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 459 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 460 val group = createMockGroup(pkg, perms) 461 resetMockAppState() 462 463 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 464 465 val newFlags = FLAG_PERMISSION_USER_SET 466 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 467 expectPermGranted = true, expectedFlags = newFlags) 468 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false) 469 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 470 verifyAppKillState(shouldBeKilled = false) 471 472 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags), 473 BG_PERM_NAME to (false to NO_FLAGS)) 474 assertGroupPermState(newGroup, expectedState) 475 476 resetMockAppState() 477 val newGroup2 = KotlinUtils.grantBackgroundRuntimePermissions(app, newGroup) 478 479 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = true, 480 expectPermGranted = true, expectedFlags = newFlags) 481 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 482 verifyAppKillState(shouldBeKilled = false) 483 484 val expectedState2 = mutableMapOf(FG_PERM_NAME to (true to newFlags), 485 BG_PERM_NAME to (true to newFlags)) 486 assertGroupPermState(newGroup2, expectedState2) 487 } 488 489 /** 490 * Test the granting of a permission which has been auto-revoked along with others in the group. 491 * Granting one permission should also clear the [FLAG_PERMISSION_AUTO_REVOKED] flag on others 492 * in the group. 493 */ 494 @Test grantAutoRevokedPermInGroupTestnull495 fun grantAutoRevokedPermInGroupTest() { 496 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 497 val perms = mutableMapOf<String, LightPermission>() 498 val origBgFlags = FLAG_PERMISSION_AUTO_REVOKED 499 perms[FG_PERM_NAME] = createMockPerm( 500 pkg, FG_PERM_NAME, BG_PERM_NAME, null, FLAG_PERMISSION_AUTO_REVOKED) 501 perms[BG_PERM_NAME] = createMockPerm( 502 pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME), origBgFlags) 503 val group = createMockGroup(pkg, perms) 504 resetMockAppState() 505 506 KotlinUtils.grantForegroundRuntimePermissions(app, group) 507 508 val newFlags = FLAG_PERMISSION_USER_SET 509 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 510 expectPermGranted = true, expectedFlags = newFlags) 511 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false, 512 expectedFlags = NO_FLAGS, originalFlags = origBgFlags) 513 } 514 515 /** 516 * Test granting a group with a foreground permission that is system fixed, and another that 517 * isn't. The system fixed permission should not change. 518 */ 519 @Test grantSystemFixedTestnull520 fun grantSystemFixedTest() { 521 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, FG_PERM_2_NAME to false)) 522 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 523 val perms = mutableMapOf<String, LightPermission>() 524 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 525 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, flags = permFlags) 526 val group = createMockGroup(pkg, perms) 527 resetMockAppState() 528 529 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 530 531 val newFlags = FLAG_PERMISSION_USER_SET 532 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 533 expectPermGranted = true, expectedFlags = newFlags) 534 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 535 verifyPermissionState(permName = FG_PERM_2_NAME, expectPermChange = false, 536 expectedFlags = permFlags, originalFlags = permFlags) 537 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 538 verifyAppKillState(shouldBeKilled = false) 539 540 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags), 541 FG_PERM_2_NAME to (false to permFlags)) 542 assertGroupPermState(newGroup, expectedState) 543 } 544 545 /** 546 * Test granting a group with a background permission that is system fixed, and a background 547 * permission that isn't. The system fixed permission should not change. 548 */ 549 @Test grantBgSystemFixedTestnull550 fun grantBgSystemFixedTest() { 551 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 552 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 553 val perms = mutableMapOf<String, LightPermission>() 554 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 555 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, FG_PERM_NAMES, permFlags) 556 val group = createMockGroup(pkg, perms) 557 resetMockAppState() 558 559 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 560 561 val newFlags = FLAG_PERMISSION_USER_SET 562 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 563 expectPermGranted = true, expectedFlags = newFlags) 564 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 565 verifyAppKillState(shouldBeKilled = false) 566 567 var expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags), 568 BG_PERM_NAME to (false to permFlags)) 569 assertGroupPermState(newGroup, expectedState) 570 571 resetMockAppState() 572 val newGroup2 = KotlinUtils.grantBackgroundRuntimePermissions(app, newGroup) 573 574 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false, 575 expectedFlags = permFlags, originalFlags = permFlags) 576 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 577 verifyAppKillState(shouldBeKilled = false) 578 579 expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags), 580 BG_PERM_NAME to (false to permFlags)) 581 assertGroupPermState(newGroup2, expectedState) 582 } 583 584 /** 585 * Test granting a one time granted permission. The permission should still be granted, but no 586 * longer be one time. 587 */ 588 @Test grantOneTimeTestnull589 fun grantOneTimeTest() { 590 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 591 val oldFlags = FLAG_PERMISSION_ONE_TIME 592 val perms = mutableMapOf<String, LightPermission>() 593 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 594 val group = createMockGroup(pkg, perms) 595 resetMockAppState() 596 597 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 598 599 val newFlags = FLAG_PERMISSION_USER_SET 600 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 601 expectedFlags = newFlags, originalFlags = oldFlags) 602 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 603 verifyAppKillState(shouldBeKilled = false) 604 605 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 606 assertGroupPermState(newGroup, expectedState) 607 } 608 609 /** 610 * Test granting a compat revoked (permission granted, app op denied) permission. The app op 611 * should be allowed, as should the permission. The app should also be killed. 612 */ 613 @Test grantPreMAppTestnull614 fun grantPreMAppTest() { 615 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isPreMApp = true) 616 val oldFlags = FLAG_PERMISSION_REVOKED_COMPAT 617 val perms = mutableMapOf<String, LightPermission>() 618 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 619 val group = createMockGroup(pkg, perms) 620 resetMockAppState() 621 622 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 623 val newFlags = FLAG_PERMISSION_USER_SET 624 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 625 expectedFlags = newFlags, originalFlags = oldFlags) 626 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 627 verifyAppKillState(shouldBeKilled = true) 628 629 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 630 assertGroupPermState(newGroup, expectedState) 631 } 632 633 /** 634 * Test the granting of a single foreground permission for a Pre M app. Nothing should change, 635 * and the app should not be killed 636 */ 637 @Test grantAlreadyGrantedPreMTestnull638 fun grantAlreadyGrantedPreMTest() { 639 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 640 val perms = mutableMapOf<String, LightPermission>() 641 val flags = FLAG_PERMISSION_USER_SET 642 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = flags) 643 val group = createMockGroup(pkg, perms) 644 resetMockAppState() 645 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 646 647 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 648 expectedFlags = flags, originalFlags = flags) 649 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 650 verifyAppKillState(shouldBeKilled = false) 651 652 val expectedState = mutableMapOf(FG_PERM_NAME to (true to flags)) 653 assertGroupPermState(newGroup, expectedState) 654 } 655 656 /** 657 * Test that an instant app cannot have regular (non-instant) permission granted. 658 */ 659 @Test cantGrantInstantAppStandardPermTestnull660 fun cantGrantInstantAppStandardPermTest() { 661 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isInstantApp = true) 662 val perms = mutableMapOf<String, LightPermission>() 663 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 664 val group = createMockGroup(pkg, perms) 665 resetMockAppState() 666 667 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 668 669 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 670 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 671 verifyAppKillState(shouldBeKilled = false) 672 673 val expectedState = mutableMapOf(FG_PERM_NAME to (false to NO_FLAGS)) 674 assertGroupPermState(newGroup, expectedState) 675 } 676 677 /** 678 * Test that a pre-M app (pre runtime permissions) can't have a runtime only permission granted. 679 */ 680 @Test cantGrantPreRuntimeAppWithRuntimeOnlyPermTestnull681 fun cantGrantPreRuntimeAppWithRuntimeOnlyPermTest() { 682 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isPreMApp = true) 683 val perms = mutableMapOf<String, LightPermission>() 684 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, 685 permInfoProtectionFlags = PROTECTION_FLAG_RUNTIME_ONLY) 686 val group = createMockGroup(pkg, perms) 687 resetMockAppState() 688 689 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 690 691 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 692 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 693 verifyAppKillState(shouldBeKilled = false) 694 695 val expectedState = mutableMapOf(FG_PERM_NAME to (false to NO_FLAGS)) 696 assertGroupPermState(newGroup, expectedState) 697 } 698 699 /** 700 * Test that an instant package can have an instant permission granted. 701 */ 702 @Test grantInstantAppInstantPermTestnull703 fun grantInstantAppInstantPermTest() { 704 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isInstantApp = true) 705 val perms = mutableMapOf<String, LightPermission>() 706 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, 707 permInfoProtectionFlags = PROTECTION_FLAG_INSTANT) 708 val group = createMockGroup(pkg, perms) 709 resetMockAppState() 710 711 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 712 713 val newFlags = FLAG_PERMISSION_USER_SET 714 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 715 expectPermGranted = true, expectedFlags = newFlags) 716 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 717 verifyAppKillState(shouldBeKilled = false) 718 719 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 720 assertGroupPermState(newGroup, expectedState) 721 } 722 723 /** 724 * Test that granting a permission clears the user fixed and review required flags. 725 */ 726 @Test grantClearsUserFixedAndReviewRequirednull727 fun grantClearsUserFixedAndReviewRequired() { 728 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 729 val oldFlags = FLAG_PERMISSION_USER_FIXED or FLAG_PERMISSION_REVIEW_REQUIRED 730 val perms = mutableMapOf<String, LightPermission>() 731 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 732 val group = createMockGroup(pkg, perms) 733 resetMockAppState() 734 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 735 736 val newFlags = FLAG_PERMISSION_USER_SET 737 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 738 expectedFlags = newFlags, originalFlags = oldFlags) 739 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 740 verifyAppKillState(shouldBeKilled = false) 741 742 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 743 assertGroupPermState(newGroup, expectedState) 744 } 745 746 /** 747 * Test revoking one foreground permission. The permission and app op should be revoked. 748 */ 749 @Test revokeOnePermTestnull750 fun revokeOnePermTest() { 751 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 752 val perms = mutableMapOf<String, LightPermission>() 753 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 754 val group = createMockGroup(pkg, perms) 755 resetMockAppState() 756 757 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 758 759 val newFlags = FLAG_PERMISSION_USER_SET 760 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 761 expectPermGranted = false, expectedFlags = newFlags) 762 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 763 verifyAppKillState(shouldBeKilled = false) 764 765 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 766 assertGroupPermState(newGroup, expectedState) 767 } 768 769 /** 770 * Test revoking two foreground permissions. Both permissions and app ops should be revoked. 771 */ 772 @Test revokeTwoPermTestnull773 fun revokeTwoPermTest() { 774 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, FG_PERM_2_NAME to true)) 775 val perms = mutableMapOf<String, LightPermission>() 776 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 777 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME) 778 val group = createMockGroup(pkg, perms) 779 resetMockAppState() 780 781 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 782 783 val newFlags = FLAG_PERMISSION_USER_SET 784 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 785 expectPermGranted = false, expectedFlags = newFlags) 786 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 787 verifyPermissionState(permName = FG_PERM_2_NAME, expectPermChange = true, 788 expectPermGranted = false, expectedFlags = newFlags) 789 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 790 verifyAppKillState(shouldBeKilled = false) 791 792 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags), 793 FG_PERM_2_NAME to (false to newFlags)) 794 assertGroupPermState(newGroup, expectedState) 795 } 796 797 /** 798 * Test the revoking of a permission with no app op. No app ops should change, but the 799 * permission should be revoked. 800 */ 801 @Test revokeNoAppOpPermnull802 fun revokeNoAppOpPerm() { 803 val pkg = createMockPackage(mapOf(FG_PERM_NAME_NO_APP_OP to true)) 804 val perms = mutableMapOf<String, LightPermission>() 805 perms[FG_PERM_NAME_NO_APP_OP] = createMockPerm(pkg, FG_PERM_NAME_NO_APP_OP) 806 val group = createMockGroup(pkg, perms) 807 resetMockAppState() 808 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 809 810 val newFlags = FLAG_PERMISSION_USER_SET 811 verifyPermissionState(permName = FG_PERM_NAME_NO_APP_OP, expectPermChange = true, 812 expectPermGranted = false, expectedFlags = newFlags) 813 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 814 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 815 verifyAppKillState(shouldBeKilled = false) 816 817 val expectedState = mutableMapOf(FG_PERM_NAME_NO_APP_OP to (false to newFlags)) 818 assertGroupPermState(newGroup, expectedState) 819 } 820 821 /** 822 * Test that revoking a background permission revokes the permission, and sets the app ops of 823 * its foreground permissions to foreground only, and does not revoke the foreground permission. 824 */ 825 @Test revokeBgPermTestnull826 fun revokeBgPermTest() { 827 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 828 val perms = mutableMapOf<String, LightPermission>() 829 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 830 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 831 val group = createMockGroup(pkg, perms) 832 resetMockAppState() 833 834 val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group) 835 836 val newFlags = FLAG_PERMISSION_USER_SET 837 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 838 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = true, 839 expectPermGranted = false, expectedFlags = newFlags) 840 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 841 verifyAppKillState(shouldBeKilled = false) 842 843 val expectedState = mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), 844 BG_PERM_NAME to (false to newFlags)) 845 assertGroupPermState(newGroup, expectedState) 846 } 847 848 /** 849 * Test granting a foreground permission, then a background. After the foreground permission is 850 * granted, the app op should be in foreground mode. After the background permission, it should 851 * be fully allowed. 852 */ 853 @Test revokeBgAndFgPermTestnull854 fun revokeBgAndFgPermTest() { 855 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 856 val perms = mutableMapOf<String, LightPermission>() 857 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 858 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 859 val group = createMockGroup(pkg, perms) 860 resetMockAppState() 861 862 val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, true) 863 864 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED 865 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = true, 866 expectPermGranted = false, expectedFlags = newFlags) 867 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 868 verifyAppKillState(shouldBeKilled = false) 869 val expectedState = mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), 870 BG_PERM_NAME to (false to newFlags)) 871 assertGroupPermState(newGroup, expectedState) 872 873 resetMockAppState() 874 val newGroup2 = KotlinUtils.revokeForegroundRuntimePermissions(app, newGroup, true) 875 876 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 877 expectPermGranted = false, expectedFlags = newFlags) 878 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 879 verifyAppKillState(shouldBeKilled = false) 880 881 val expectedState2 = mutableMapOf(FG_PERM_NAME to (false to newFlags), 882 BG_PERM_NAME to (false to newFlags)) 883 assertGroupPermState(newGroup2, expectedState2) 884 } 885 886 /** 887 * Test revoking a group with a foreground permission that is system fixed, and another that 888 * isn't. The system fixed permission should not change. 889 */ 890 @Test revokeSystemFixedTestnull891 fun revokeSystemFixedTest() { 892 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, FG_PERM_2_NAME to true)) 893 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 894 val perms = mutableMapOf<String, LightPermission>() 895 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 896 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, flags = permFlags) 897 val group = createMockGroup(pkg, perms) 898 resetMockAppState() 899 900 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 901 902 val newFlags = FLAG_PERMISSION_USER_SET 903 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 904 expectPermGranted = false, expectedFlags = newFlags) 905 verifyPermissionState(permName = FG_PERM_2_NAME, expectPermChange = false) 906 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 907 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 908 verifyAppKillState(shouldBeKilled = false) 909 910 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags), 911 FG_PERM_2_NAME to (true to permFlags)) 912 assertGroupPermState(newGroup, expectedState) 913 } 914 915 /** 916 * Test revoking a group with a background permission that is system fixed, and a background 917 * permission that isn't. The system fixed permission should not change. 918 */ 919 @Test revokeBgSystemFixedTestnull920 fun revokeBgSystemFixedTest() { 921 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 922 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 923 val perms = mutableMapOf<String, LightPermission>() 924 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 925 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, FG_PERM_NAMES, permFlags) 926 val group = createMockGroup(pkg, perms) 927 resetMockAppState() 928 929 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 930 931 val newFlags = FLAG_PERMISSION_USER_SET 932 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 933 expectPermGranted = false, expectedFlags = newFlags) 934 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 935 verifyAppKillState(shouldBeKilled = false) 936 937 var expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags), 938 BG_PERM_NAME to (true to permFlags)) 939 assertGroupPermState(newGroup, expectedState) 940 941 resetMockAppState() 942 val newGroup2 = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup) 943 944 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false) 945 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 946 verifyAppKillState(shouldBeKilled = false) 947 948 expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags), 949 BG_PERM_NAME to (true to permFlags)) 950 assertGroupPermState(newGroup2, expectedState) 951 } 952 953 /** 954 * Test revoking a one time granted permission. The permission should be revoked, but no 955 * longer be one time. 956 */ 957 @Test revokeOneTimeTestnull958 fun revokeOneTimeTest() { 959 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 960 val oldFlags = FLAG_PERMISSION_ONE_TIME 961 val perms = mutableMapOf<String, LightPermission>() 962 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 963 val group = createMockGroup(pkg, perms) 964 resetMockAppState() 965 966 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 967 968 val newFlags = FLAG_PERMISSION_USER_SET 969 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 970 expectPermGranted = false, expectedFlags = newFlags, originalFlags = oldFlags) 971 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 972 verifyAppKillState(shouldBeKilled = false) 973 974 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 975 assertGroupPermState(newGroup, expectedState) 976 } 977 978 /** 979 * Test compat revoking (permission granted, app op denied) permission. The app op 980 * should be revoked, while the permission remains granted. The app should also be killed. 981 */ 982 @Test revokePreMAppTestnull983 fun revokePreMAppTest() { 984 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true), isPreMApp = true) 985 val perms = mutableMapOf<String, LightPermission>() 986 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 987 val group = createMockGroup(pkg, perms) 988 resetMockAppState() 989 990 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 991 992 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_REVOKED_COMPAT 993 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 994 expectedFlags = newFlags) 995 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 996 verifyAppKillState(shouldBeKilled = true) 997 998 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 999 assertGroupPermState(newGroup, expectedState) 1000 } 1001 1002 /** 1003 * Test the revoking of a single foreground permission for a Pre M app. Nothing should change, 1004 * and the app should not be killed 1005 */ 1006 @Test revokeAlreadyRevokedPreMTestnull1007 fun revokeAlreadyRevokedPreMTest() { 1008 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 1009 val perms = mutableMapOf<String, LightPermission>() 1010 val flags = FLAG_PERMISSION_USER_SET 1011 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = flags) 1012 val group = createMockGroup(pkg, perms) 1013 resetMockAppState() 1014 1015 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1016 1017 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 1018 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 1019 verifyAppKillState(shouldBeKilled = false) 1020 1021 val expectedState = mutableMapOf(FG_PERM_NAME to (false to flags)) 1022 assertGroupPermState(newGroup, expectedState) 1023 } 1024 1025 /** 1026 * Test revoking a standard permission for an instant app, to show that instant app status does 1027 * not affect the revoking of a permission. 1028 */ 1029 @Test revokeInstantAppTestnull1030 fun revokeInstantAppTest() { 1031 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true), isInstantApp = true) 1032 val perms = mutableMapOf<String, LightPermission>() 1033 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 1034 val group = createMockGroup(pkg, perms) 1035 resetMockAppState() 1036 1037 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, true) 1038 1039 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED 1040 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 1041 expectPermGranted = false, expectedFlags = newFlags) 1042 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1043 verifyAppKillState(shouldBeKilled = false) 1044 1045 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1046 assertGroupPermState(newGroup, expectedState) 1047 } 1048 1049 /** 1050 * Revoke a permission that was user fixed, and set it to no longer be user fixed. The 1051 * permission and its app op should be revoked, and the permission should no longer be user 1052 * fixed. 1053 */ 1054 @Test revokeUserFixedPermTestnull1055 fun revokeUserFixedPermTest() { 1056 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 1057 val perms = mutableMapOf<String, LightPermission>() 1058 val oldFlags = FLAG_PERMISSION_USER_FIXED 1059 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1060 val group = createMockGroup(pkg, perms) 1061 resetMockAppState() 1062 1063 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1064 1065 val newFlags = FLAG_PERMISSION_USER_SET 1066 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 1067 expectPermGranted = false, expectedFlags = newFlags, originalFlags = oldFlags) 1068 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1069 verifyAppKillState(shouldBeKilled = false) 1070 1071 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1072 assertGroupPermState(newGroup, expectedState) 1073 } 1074 1075 /** 1076 * Revoke a permission that was not user fixed, and set it to be user fixed. The permission and 1077 * its app op should be revoked, and the permission should be user fixed. 1078 */ 1079 @Test revokeAndSetUserFixedPermTestnull1080 fun revokeAndSetUserFixedPermTest() { 1081 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 1082 val perms = mutableMapOf<String, LightPermission>() 1083 val oldFlags = FLAG_PERMISSION_USER_SET 1084 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1085 val group = createMockGroup(pkg, perms) 1086 resetMockAppState() 1087 1088 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, true) 1089 1090 val newFlags = oldFlags or FLAG_PERMISSION_USER_FIXED 1091 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = true, 1092 expectPermGranted = false, expectedFlags = newFlags, originalFlags = oldFlags) 1093 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1094 verifyAppKillState(shouldBeKilled = false) 1095 1096 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1097 assertGroupPermState(newGroup, expectedState) 1098 } 1099 1100 /** 1101 * Test revoking an already revoked permission, while changing its user fixed state from true 1102 * to false. The user fixed should update, but the state should stay the same otherwise. 1103 */ 1104 @Test changeUserFixedTestnull1105 fun changeUserFixedTest() { 1106 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 1107 val perms = mutableMapOf<String, LightPermission>() 1108 val oldFlags = FLAG_PERMISSION_USER_FIXED 1109 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1110 val group = createMockGroup(pkg, perms) 1111 resetMockAppState() 1112 1113 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1114 1115 val newFlags = FLAG_PERMISSION_USER_SET 1116 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false, 1117 expectedFlags = newFlags, originalFlags = oldFlags) 1118 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 1119 verifyAppKillState(shouldBeKilled = false) 1120 1121 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1122 assertGroupPermState(newGroup, expectedState) 1123 } 1124 } 1125