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.Context 28 import android.content.pm.ApplicationInfo 29 import android.content.pm.PackageManager 30 import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED 31 import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME 32 import android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 33 import android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT 34 import android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 35 import android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED 36 import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET 37 import android.content.pm.PackageManager.PERMISSION_DENIED 38 import android.content.pm.PackageManager.PERMISSION_GRANTED 39 import android.content.pm.PermissionInfo 40 import android.content.pm.PermissionInfo.PROTECTION_FLAG_INSTANT 41 import android.content.pm.PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY 42 import android.os.Build 43 import android.os.UserHandle 44 import android.permission.PermissionManager 45 import androidx.test.ext.junit.runners.AndroidJUnit4 46 import com.android.modules.utils.build.SdkLevel 47 import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup 48 import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo 49 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo 50 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo 51 import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission 52 import com.android.permissioncontroller.permission.utils.ContextCompat 53 import com.android.permissioncontroller.permission.utils.KotlinUtils 54 import com.google.common.truth.Truth.assertThat 55 import com.google.common.truth.Truth.assertWithMessage 56 import org.junit.Assume.assumeNotNull 57 import org.junit.Assume.assumeTrue 58 import org.junit.BeforeClass 59 import org.junit.Test 60 import org.junit.runner.RunWith 61 import org.mockito.ArgumentMatchers.anyInt 62 import org.mockito.ArgumentMatchers.anyString 63 import org.mockito.ArgumentMatchers.eq 64 import org.mockito.ArgumentMatchers.nullable 65 import org.mockito.Mock 66 import org.mockito.Mockito.mock 67 import org.mockito.Mockito.never 68 import org.mockito.Mockito.verify 69 import org.mockito.Mockito.`when` 70 71 private const val PERMISSION_CONTROLLER_CHANGED_FLAG_MASK = 72 FLAG_PERMISSION_USER_SET or 73 FLAG_PERMISSION_USER_FIXED or 74 FLAG_PERMISSION_ONE_TIME or 75 FLAG_PERMISSION_REVOKED_COMPAT or 76 FLAG_PERMISSION_ONE_TIME or 77 FLAG_PERMISSION_REVIEW_REQUIRED or 78 FLAG_PERMISSION_AUTO_REVOKED 79 80 /** 81 * A suite of unit tests to test the granting and revoking of permissions. Note- does not currently 82 * test the Location Access Check. 83 */ 84 @RunWith(AndroidJUnit4::class) 85 class GrantRevokeTests { 86 87 companion object { 88 private const val PERM_GROUP_NAME = Manifest.permission_group.LOCATION 89 private const val FG_PERM_NAME = Manifest.permission.ACCESS_COARSE_LOCATION 90 private const val FG_PERM_2_NAME = Manifest.permission.ACCESS_FINE_LOCATION 91 private const val FG_PERM_NAME_NO_APP_OP = "android.permission.permWithNoAppOp" 92 private const val BG_PERM_NAME = Manifest.permission.ACCESS_BACKGROUND_LOCATION 93 private const val TEST_PACKAGE_NAME = "android.permission.cts.testapp" 94 private const val TEST_UID = 1 95 private val TEST_USER = UserHandle.getUserHandleForUid(TEST_UID) 96 private const val NO_FLAGS = 0 97 private val FG_PERM_NAMES = listOf(FG_PERM_NAME, FG_PERM_2_NAME, FG_PERM_NAME_NO_APP_OP) 98 private val OP_NAME = permissionToOp(FG_PERM_NAME)!! 99 private val OP_2_NAME = permissionToOp(FG_PERM_2_NAME)!! 100 101 @BeforeClass 102 @JvmStatic checkAppOpsNotNullAndDistinctnull103 fun checkAppOpsNotNullAndDistinct() { 104 assumeNotNull(OP_NAME, OP_2_NAME) 105 assumeTrue(OP_NAME != OP_2_NAME) 106 } 107 } 108 109 @Mock val app: Application = mock(Application::class.java) 110 111 @Mock val context: Context = mock(Context::class.java) 112 113 /** 114 * Create a mock Application object, with a mock packageManager, AppOpsManager, and 115 * ActivityManager. 116 * 117 * @return The mocked Application object 118 */ resetMockAppStatenull119 private fun resetMockAppState() { 120 `when`(app.packageManager).thenReturn(mock(PackageManager::class.java)) 121 122 val aom: AppOpsManager = mock(AppOpsManager::class.java) 123 124 if (SdkLevel.isAtLeastU()) { 125 `when`(context.deviceId).thenReturn(ContextCompat.DEVICE_ID_DEFAULT) 126 } 127 `when`(context.packageManager).thenReturn(mock(PackageManager::class.java)) 128 `when`(context.getSystemService(PermissionManager::class.java)) 129 .thenReturn(mock(PermissionManager::class.java)) 130 // Return an invalid app op state, so setOpMode will always attempt to change the op state 131 `when`(aom.unsafeCheckOpRaw(anyString(), anyInt(), nullable(String::class.java))) 132 .thenReturn(-1) 133 `when`(app.getSystemService(AppOpsManager::class.java)).thenReturn(aom) 134 135 `when`(app.getSystemService(ActivityManager::class.java)) 136 .thenReturn(mock(ActivityManager::class.java)) 137 138 `when`(app.getSystemService(PermissionManager::class.java)) 139 .thenReturn(mock(PermissionManager::class.java)) 140 `when`(app.applicationContext).thenReturn(context) 141 } 142 143 /** 144 * Create a LightPackageInfo object with a particular set of properties 145 * 146 * @param perms The (name -> permissionInfo) of the permissions requested by the app 147 * @param isPreMApp Whether this app targets pre-M 148 * @param isInstantApp {@code true} iff this is an instant app 149 */ createMockPackagenull150 private fun createMockPackage( 151 perms: Map<String, Boolean>, 152 isPreMApp: Boolean = false, 153 isInstantApp: Boolean = false 154 ): LightPackageInfo { 155 val permNames = mutableListOf<String>() 156 val permFlags = mutableListOf<Int>() 157 for ((permName, isGranted) in perms) { 158 permNames.add(permName) 159 permFlags.add( 160 if (isGranted) { 161 PERMISSION_GRANTED 162 } else { 163 PERMISSION_DENIED 164 } 165 ) 166 } 167 168 return LightPackageInfo( 169 TEST_PACKAGE_NAME, 170 listOf(), 171 permNames, 172 permFlags, 173 TEST_UID, 174 if (isPreMApp) { 175 Build.VERSION_CODES.LOLLIPOP 176 } else { 177 Build.VERSION_CODES.R 178 }, 179 isInstantApp, 180 isInstantApp, 181 0, 182 0L, 183 0L, 184 false, 185 emptyMap(), 186 ContextCompat.DEVICE_ID_DEFAULT 187 ) 188 } 189 190 /** 191 * Create a LightPermission object with a particular set of properties 192 * 193 * @param pkg Package requesting the permission 194 * @param permName The name of the permission 195 * @param granted Whether the permission is granted (should be false if the permission is compat 196 * revoked) 197 * @param backgroundPerm The name of this permission's background permission, if there is one 198 * @param foregroundPerms The names of this permission's foreground permissions, if there are 199 * any 200 * @param flags The system permission flags of this permission 201 * @param permInfoProtectionFlags The flags that the PermissionInfo object has (accessed by 202 * PermissionInfo.getProtectionFlags) 203 */ createMockPermnull204 private fun createMockPerm( 205 pkgInfo: LightPackageInfo, 206 permName: String, 207 backgroundPerm: String? = null, 208 foregroundPerms: List<String>? = null, 209 flags: Int = NO_FLAGS, 210 permInfoProtectionFlags: Int = 0 211 ): LightPermission { 212 val permInfo = 213 LightPermInfo( 214 permName, 215 TEST_PACKAGE_NAME, 216 PERM_GROUP_NAME, 217 backgroundPerm, 218 PermissionInfo.PROTECTION_DANGEROUS, 219 permInfoProtectionFlags, 220 0, 221 pkgInfo.appFlags and ApplicationInfo.FLAG_SYSTEM != 0 222 ) 223 return LightPermission( 224 pkgInfo, 225 permInfo, 226 pkgInfo.requestedPermissionsFlags[pkgInfo.requestedPermissions.indexOf(permName)] == 227 PERMISSION_GRANTED, 228 flags, 229 foregroundPerms 230 ) 231 } 232 233 /** 234 * Create a LightAppPermGroup with a particular set of properties. 235 * 236 * @param pkg Package requesting the permission 237 * @param perms The map of perm name to LightPermission (should be created with @createMockPerm) 238 */ createMockGroupnull239 private fun createMockGroup( 240 pkgInfo: LightPackageInfo, 241 perms: Map<String, LightPermission> = emptyMap() 242 ): LightAppPermGroup { 243 val pGi = LightPermGroupInfo(PERM_GROUP_NAME, TEST_PACKAGE_NAME, 0, 0, 0, false) 244 return LightAppPermGroup(pkgInfo, pGi, perms, false, false, false) 245 } 246 247 /** 248 * Create a list of strings which usefully states which flags are set in a group of flags. Only 249 * checks for flags relevant to granting and revoking (so, for instance, policy fixed is not 250 * checked). 251 * 252 * @param flags The flags to check 253 * @return a list of strings, representing which flags have been set 254 */ flagsToStringnull255 private fun flagsToString(flags: Int): List<String> { 256 val flagStrings = mutableListOf<String>() 257 if (flags and FLAG_PERMISSION_USER_SET != 0) { 258 flagStrings.add("USER_SET") 259 } 260 if (flags and FLAG_PERMISSION_USER_FIXED != 0) { 261 flagStrings.add("USER_FIXED") 262 } 263 if (flags and FLAG_PERMISSION_SYSTEM_FIXED != 0) { 264 flagStrings.add("SYSTEM_FIXED") 265 } 266 if (flags and FLAG_PERMISSION_REVOKED_COMPAT != 0) { 267 flagStrings.add("REVOKED_COMPAT") 268 } 269 if (flags and FLAG_PERMISSION_REVIEW_REQUIRED != 0) { 270 flagStrings.add("REVIEW_REQUIRED") 271 } 272 if (flags and FLAG_PERMISSION_ONE_TIME != 0) { 273 flagStrings.add("ONE_TIME") 274 } 275 return flagStrings 276 } 277 278 /** 279 * Assert that the permissions of the given group match the expected state 280 * 281 * @param groupToCheck The LightAppPermGroup whose permissions we are checking 282 * @param expectedState A map <permission name, grant state and permission flags pair> 283 */ assertGroupPermStatenull284 private fun assertGroupPermState( 285 groupToCheck: LightAppPermGroup, 286 expectedState: Map<String, Pair<Boolean, Int>> 287 ) { 288 val perms = groupToCheck.permissions 289 290 assertThat(perms.keys).isEqualTo(expectedState.keys) 291 292 for ((permName, state) in expectedState) { 293 val granted = state.first 294 val flags = state.second 295 296 assertWithMessage("permission $permName grant state incorrect") 297 .that(perms[permName]?.isGranted) 298 .isEqualTo(granted) 299 300 val actualFlags = perms[permName]!!.flags 301 assertWithMessage( 302 "permission $permName flags incorrect, expected" + 303 "${flagsToString(flags)}; got ${flagsToString(actualFlags)}" 304 ) 305 .that(perms[permName]?.flags) 306 .isEqualTo(flags) 307 } 308 } 309 310 /** 311 * Verify that permission state was propagated to the system. Verify that grant or revoke were 312 * called, if applicable, or verify they weren't. Verify that we have set flags correctly, if 313 * applicable, or verify flags were not set. 314 * 315 * @param permName The name of the permission to verify 316 * @param expectPermChange Whether or not a permission grant or revoke was expected. If false, 317 * verify neither grant nor revoke were called 318 * @param expectPermGranted If a permission change was expected, verify that the permission was 319 * set to granted (if true) or revoked (if false) 320 * @param expectedFlags The flags that the system should have set the permission to have 321 * @param originalFlags The flags the permission originally had. Used to ensure the correct flag 322 * mask was used 323 */ verifyPermissionStatenull324 private fun verifyPermissionState( 325 permName: String, 326 expectPermChange: Boolean, 327 expectPermGranted: Boolean = true, 328 expectedFlags: Int = NO_FLAGS, 329 originalFlags: Int = NO_FLAGS 330 ) { 331 val pm = context.packageManager 332 if (expectPermChange) { 333 if (expectPermGranted) { 334 verify(pm).grantRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 335 } else { 336 verify(pm).revokeRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 337 } 338 } else { 339 verify(pm, never()).grantRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 340 verify(pm, never()).revokeRuntimePermission(TEST_PACKAGE_NAME, permName, TEST_USER) 341 } 342 343 if (expectedFlags != originalFlags) { 344 verify(pm) 345 .updatePermissionFlags( 346 permName, 347 TEST_PACKAGE_NAME, 348 PERMISSION_CONTROLLER_CHANGED_FLAG_MASK, 349 expectedFlags, 350 TEST_USER 351 ) 352 } else { 353 verify(pm, never()) 354 .updatePermissionFlags( 355 eq(permName), 356 eq(TEST_PACKAGE_NAME), 357 anyInt(), 358 anyInt(), 359 eq(TEST_USER) 360 ) 361 } 362 } 363 364 /** 365 * Verify that app op state was propagated to the system. Verify that setUidMode was called, if 366 * applicable, or verify it wasn't. 367 * 368 * @param appOpName The name of the app op to check 369 * @param expectAppOpSet Whether an app op change was expected. If false, verify setUidMode was 370 * not called 371 * @param expectedMode If a change was expected, the mode the app op should be set to 372 */ verifyAppOpStatenull373 private fun verifyAppOpState( 374 appOpName: String, 375 expectAppOpSet: Boolean, 376 expectedMode: Int = MODE_IGNORED 377 ) { 378 val aom = app.getSystemService(AppOpsManager::class.java) 379 if (expectAppOpSet) { 380 verify(aom).setUidMode(appOpName, TEST_UID, expectedMode) 381 } else { 382 verify(aom, never()).setUidMode(eq(appOpName), eq(TEST_UID), anyInt()) 383 } 384 } 385 386 /** 387 * Verify that the test app either was or was not killed. 388 * 389 * @param shouldBeKilled Whether or not the app should have been killed 390 */ verifyAppKillStatenull391 private fun verifyAppKillState(shouldBeKilled: Boolean) { 392 val am = app.getSystemService(ActivityManager::class.java) 393 if (shouldBeKilled) { 394 verify(am).killUid(eq(TEST_UID), anyString()) 395 } else { 396 verify(am, never()).killUid(eq(TEST_UID), anyString()) 397 } 398 } 399 400 /** 401 * Test the granting of a single foreground permission. The permission and its app op should be 402 * granted. 403 */ 404 @Test grantOnePermTestnull405 fun grantOnePermTest() { 406 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 407 val perms = mutableMapOf<String, LightPermission>() 408 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 409 val group = createMockGroup(pkg, perms) 410 resetMockAppState() 411 412 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 413 414 val newFlags = FLAG_PERMISSION_USER_SET 415 verifyPermissionState( 416 permName = FG_PERM_NAME, 417 expectPermChange = true, 418 expectPermGranted = true, 419 expectedFlags = newFlags 420 ) 421 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 422 verifyAppKillState(shouldBeKilled = false) 423 424 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 425 assertGroupPermState(newGroup, expectedState) 426 } 427 428 /** 429 * Test the granting of two foreground permissions, one with a background permission. The 430 * permissions and app ops should be granted, and the permissions marked user set. The second 431 * app op should be set to foreground mode. 432 */ 433 @Test grantTwoPermTestnull434 fun grantTwoPermTest() { 435 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, FG_PERM_2_NAME to false)) 436 val perms = mutableMapOf<String, LightPermission>() 437 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 438 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, BG_PERM_NAME) 439 val group = createMockGroup(pkg, perms) 440 resetMockAppState() 441 442 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 443 444 val newFlags = FLAG_PERMISSION_USER_SET 445 verifyPermissionState( 446 permName = FG_PERM_NAME, 447 expectPermChange = true, 448 expectPermGranted = true, 449 expectedFlags = newFlags 450 ) 451 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 452 verifyPermissionState( 453 permName = FG_PERM_2_NAME, 454 expectPermChange = true, 455 expectPermGranted = true, 456 expectedFlags = newFlags 457 ) 458 verifyAppOpState( 459 appOpName = OP_2_NAME, 460 expectAppOpSet = true, 461 expectedMode = MODE_FOREGROUND 462 ) 463 verifyAppKillState(shouldBeKilled = false) 464 465 val expectedState = 466 mutableMapOf(FG_PERM_NAME to (true to newFlags), FG_PERM_2_NAME to (true to newFlags)) 467 assertGroupPermState(newGroup, expectedState) 468 } 469 470 /** 471 * Test the granting of a permission with no app op. No app ops should change, but the 472 * permission should be granted 473 */ 474 @Test grantNoAppOpPermnull475 fun grantNoAppOpPerm() { 476 val pkg = createMockPackage(mapOf(FG_PERM_NAME_NO_APP_OP to false)) 477 val perms = mutableMapOf<String, LightPermission>() 478 perms[FG_PERM_NAME_NO_APP_OP] = createMockPerm(pkg, FG_PERM_NAME_NO_APP_OP) 479 val group = createMockGroup(pkg, perms) 480 resetMockAppState() 481 482 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 483 484 val newFlags = FLAG_PERMISSION_USER_SET 485 verifyPermissionState( 486 permName = FG_PERM_NAME_NO_APP_OP, 487 expectPermChange = true, 488 expectPermGranted = true, 489 expectedFlags = newFlags 490 ) 491 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 492 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 493 verifyAppKillState(shouldBeKilled = false) 494 495 val expectedState = mutableMapOf(FG_PERM_NAME_NO_APP_OP to (true to newFlags)) 496 assertGroupPermState(newGroup, expectedState) 497 } 498 499 /** 500 * Test that granting a background permission grants the background permission, and allows the 501 * app ops of its foreground permissions, but does not grant the foreground permission itself. 502 */ 503 @Test grantBgPermTestnull504 fun grantBgPermTest() { 505 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to false)) 506 val perms = mutableMapOf<String, LightPermission>() 507 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 508 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 509 val group = createMockGroup(pkg, perms) 510 resetMockAppState() 511 512 val newGroup = KotlinUtils.grantBackgroundRuntimePermissions(app, group) 513 514 val newFlags = FLAG_PERMISSION_USER_SET 515 verifyPermissionState( 516 permName = BG_PERM_NAME, 517 expectPermChange = true, 518 expectPermGranted = true, 519 expectedFlags = newFlags 520 ) 521 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 522 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 523 verifyAppKillState(shouldBeKilled = false) 524 525 val expectedState = 526 mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), BG_PERM_NAME to (true to newFlags)) 527 assertGroupPermState(newGroup, expectedState) 528 } 529 530 /** 531 * Test granting a foreground permission, then a background. After the foreground permission is 532 * granted, the app op should be in foreground mode. After the background permission, it should 533 * be fully allowed. 534 */ 535 @Test grantBgAndFgPermTestnull536 fun grantBgAndFgPermTest() { 537 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 538 val perms = mutableMapOf<String, LightPermission>() 539 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 540 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 541 val group = createMockGroup(pkg, perms) 542 resetMockAppState() 543 544 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 545 546 val newFlags = FLAG_PERMISSION_USER_SET 547 verifyPermissionState( 548 permName = FG_PERM_NAME, 549 expectPermChange = true, 550 expectPermGranted = true, 551 expectedFlags = newFlags 552 ) 553 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false) 554 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 555 verifyAppKillState(shouldBeKilled = false) 556 557 val expectedState = 558 mutableMapOf(FG_PERM_NAME to (true to newFlags), BG_PERM_NAME to (false to NO_FLAGS)) 559 assertGroupPermState(newGroup, expectedState) 560 561 resetMockAppState() 562 val newGroup2 = KotlinUtils.grantBackgroundRuntimePermissions(app, newGroup) 563 564 verifyPermissionState( 565 permName = BG_PERM_NAME, 566 expectPermChange = true, 567 expectPermGranted = true, 568 expectedFlags = newFlags 569 ) 570 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 571 verifyAppKillState(shouldBeKilled = false) 572 573 val expectedState2 = 574 mutableMapOf(FG_PERM_NAME to (true to newFlags), BG_PERM_NAME to (true to newFlags)) 575 assertGroupPermState(newGroup2, expectedState2) 576 } 577 578 /** 579 * Test the granting of a permission which has been auto-revoked along with others in the group. 580 * Granting one permission should also clear the [FLAG_PERMISSION_AUTO_REVOKED] flag on others 581 * in the group. 582 */ 583 @Test grantAutoRevokedPermInGroupTestnull584 fun grantAutoRevokedPermInGroupTest() { 585 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 586 val perms = mutableMapOf<String, LightPermission>() 587 val origBgFlags = FLAG_PERMISSION_AUTO_REVOKED 588 perms[FG_PERM_NAME] = 589 createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME, null, FLAG_PERMISSION_AUTO_REVOKED) 590 perms[BG_PERM_NAME] = 591 createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME), origBgFlags) 592 val group = createMockGroup(pkg, perms) 593 resetMockAppState() 594 595 KotlinUtils.grantForegroundRuntimePermissions(app, group) 596 597 val newFlags = FLAG_PERMISSION_USER_SET 598 verifyPermissionState( 599 permName = FG_PERM_NAME, 600 expectPermChange = true, 601 expectPermGranted = true, 602 expectedFlags = newFlags 603 ) 604 verifyPermissionState( 605 permName = BG_PERM_NAME, 606 expectPermChange = false, 607 expectedFlags = NO_FLAGS, 608 originalFlags = origBgFlags 609 ) 610 } 611 612 /** 613 * Test granting a group with a foreground permission that is system fixed, and another that 614 * isn't. The system fixed permission should not change. 615 */ 616 @Test grantSystemFixedTestnull617 fun grantSystemFixedTest() { 618 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, FG_PERM_2_NAME to false)) 619 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 620 val perms = mutableMapOf<String, LightPermission>() 621 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 622 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, flags = permFlags) 623 val group = createMockGroup(pkg, perms) 624 resetMockAppState() 625 626 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 627 628 val newFlags = FLAG_PERMISSION_USER_SET 629 verifyPermissionState( 630 permName = FG_PERM_NAME, 631 expectPermChange = true, 632 expectPermGranted = true, 633 expectedFlags = newFlags 634 ) 635 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 636 verifyPermissionState( 637 permName = FG_PERM_2_NAME, 638 expectPermChange = false, 639 expectedFlags = permFlags, 640 originalFlags = permFlags 641 ) 642 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 643 verifyAppKillState(shouldBeKilled = false) 644 645 val expectedState = 646 mutableMapOf(FG_PERM_NAME to (true to newFlags), FG_PERM_2_NAME to (false to permFlags)) 647 assertGroupPermState(newGroup, expectedState) 648 } 649 650 /** 651 * Test granting a group with a background permission that is system fixed, and a background 652 * permission that isn't. The system fixed permission should not change. 653 */ 654 @Test grantBgSystemFixedTestnull655 fun grantBgSystemFixedTest() { 656 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false, BG_PERM_NAME to false)) 657 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 658 val perms = mutableMapOf<String, LightPermission>() 659 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 660 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, FG_PERM_NAMES, permFlags) 661 val group = createMockGroup(pkg, perms) 662 resetMockAppState() 663 664 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 665 666 val newFlags = FLAG_PERMISSION_USER_SET 667 verifyPermissionState( 668 permName = FG_PERM_NAME, 669 expectPermChange = true, 670 expectPermGranted = true, 671 expectedFlags = newFlags 672 ) 673 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 674 verifyAppKillState(shouldBeKilled = false) 675 676 var expectedState = 677 mutableMapOf(FG_PERM_NAME to (true to newFlags), BG_PERM_NAME to (false to permFlags)) 678 assertGroupPermState(newGroup, expectedState) 679 680 resetMockAppState() 681 val newGroup2 = KotlinUtils.grantBackgroundRuntimePermissions(app, newGroup) 682 683 verifyPermissionState( 684 permName = BG_PERM_NAME, 685 expectPermChange = false, 686 expectedFlags = permFlags, 687 originalFlags = permFlags 688 ) 689 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 690 verifyAppKillState(shouldBeKilled = false) 691 692 expectedState = 693 mutableMapOf(FG_PERM_NAME to (true to newFlags), BG_PERM_NAME to (false to permFlags)) 694 assertGroupPermState(newGroup2, expectedState) 695 } 696 697 /** 698 * Test granting a one time granted permission. The permission should still be granted, but no 699 * longer be one time. 700 */ 701 @Test grantOneTimeTestnull702 fun grantOneTimeTest() { 703 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 704 val oldFlags = FLAG_PERMISSION_ONE_TIME 705 val perms = mutableMapOf<String, LightPermission>() 706 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 707 val group = createMockGroup(pkg, perms) 708 resetMockAppState() 709 710 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 711 712 val newFlags = FLAG_PERMISSION_USER_SET 713 verifyPermissionState( 714 permName = FG_PERM_NAME, 715 expectPermChange = false, 716 expectedFlags = newFlags, 717 originalFlags = oldFlags 718 ) 719 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 720 verifyAppKillState(shouldBeKilled = false) 721 722 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 723 assertGroupPermState(newGroup, expectedState) 724 } 725 726 /** 727 * Test granting a compat revoked (permission granted, app op denied) permission. The app op 728 * should be allowed, as should the permission. The app should also be killed. 729 */ 730 @Test grantPreMAppTestnull731 fun grantPreMAppTest() { 732 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isPreMApp = true) 733 val oldFlags = FLAG_PERMISSION_REVOKED_COMPAT 734 val perms = mutableMapOf<String, LightPermission>() 735 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 736 val group = createMockGroup(pkg, perms) 737 resetMockAppState() 738 739 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 740 val newFlags = FLAG_PERMISSION_USER_SET 741 verifyPermissionState( 742 permName = FG_PERM_NAME, 743 expectPermChange = false, 744 expectedFlags = newFlags, 745 originalFlags = oldFlags 746 ) 747 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 748 verifyAppKillState(shouldBeKilled = true) 749 750 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 751 assertGroupPermState(newGroup, expectedState) 752 } 753 754 /** 755 * Test the granting of a single foreground permission for a Pre M app. Nothing should change, 756 * and the app should not be killed 757 */ 758 @Test grantAlreadyGrantedPreMTestnull759 fun grantAlreadyGrantedPreMTest() { 760 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 761 val perms = mutableMapOf<String, LightPermission>() 762 val flags = FLAG_PERMISSION_USER_SET 763 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = flags) 764 val group = createMockGroup(pkg, perms) 765 resetMockAppState() 766 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 767 768 verifyPermissionState( 769 permName = FG_PERM_NAME, 770 expectPermChange = false, 771 expectedFlags = flags, 772 originalFlags = flags 773 ) 774 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 775 verifyAppKillState(shouldBeKilled = false) 776 777 val expectedState = mutableMapOf(FG_PERM_NAME to (true to flags)) 778 assertGroupPermState(newGroup, expectedState) 779 } 780 781 /** Test that an instant app cannot have regular (non-instant) permission granted. */ 782 @Test cantGrantInstantAppStandardPermTestnull783 fun cantGrantInstantAppStandardPermTest() { 784 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isInstantApp = true) 785 val perms = mutableMapOf<String, LightPermission>() 786 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 787 val group = createMockGroup(pkg, perms) 788 resetMockAppState() 789 790 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 791 792 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 793 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 794 verifyAppKillState(shouldBeKilled = false) 795 796 val expectedState = mutableMapOf(FG_PERM_NAME to (false to NO_FLAGS)) 797 assertGroupPermState(newGroup, expectedState) 798 } 799 800 /** 801 * Test that a pre-M app (pre runtime permissions) can't have a runtime only permission granted. 802 */ 803 @Test cantGrantPreRuntimeAppWithRuntimeOnlyPermTestnull804 fun cantGrantPreRuntimeAppWithRuntimeOnlyPermTest() { 805 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isPreMApp = true) 806 val perms = mutableMapOf<String, LightPermission>() 807 perms[FG_PERM_NAME] = 808 createMockPerm( 809 pkg, 810 FG_PERM_NAME, 811 permInfoProtectionFlags = PROTECTION_FLAG_RUNTIME_ONLY 812 ) 813 val group = createMockGroup(pkg, perms) 814 resetMockAppState() 815 816 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 817 818 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 819 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 820 verifyAppKillState(shouldBeKilled = false) 821 822 val expectedState = mutableMapOf(FG_PERM_NAME to (false to NO_FLAGS)) 823 assertGroupPermState(newGroup, expectedState) 824 } 825 826 /** Test that an instant package can have an instant permission granted. */ 827 @Test grantInstantAppInstantPermTestnull828 fun grantInstantAppInstantPermTest() { 829 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false), isInstantApp = true) 830 val perms = mutableMapOf<String, LightPermission>() 831 perms[FG_PERM_NAME] = 832 createMockPerm(pkg, FG_PERM_NAME, permInfoProtectionFlags = PROTECTION_FLAG_INSTANT) 833 val group = createMockGroup(pkg, perms) 834 resetMockAppState() 835 836 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 837 838 val newFlags = FLAG_PERMISSION_USER_SET 839 verifyPermissionState( 840 permName = FG_PERM_NAME, 841 expectPermChange = true, 842 expectPermGranted = true, 843 expectedFlags = newFlags 844 ) 845 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_ALLOWED) 846 verifyAppKillState(shouldBeKilled = false) 847 848 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 849 assertGroupPermState(newGroup, expectedState) 850 } 851 852 /** Test that granting a permission clears the user fixed and review required flags. */ 853 @Test grantClearsUserFixedAndReviewRequirednull854 fun grantClearsUserFixedAndReviewRequired() { 855 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 856 val oldFlags = FLAG_PERMISSION_USER_FIXED or FLAG_PERMISSION_REVIEW_REQUIRED 857 val perms = mutableMapOf<String, LightPermission>() 858 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 859 val group = createMockGroup(pkg, perms) 860 resetMockAppState() 861 val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) 862 863 val newFlags = FLAG_PERMISSION_USER_SET 864 verifyPermissionState( 865 permName = FG_PERM_NAME, 866 expectPermChange = false, 867 expectedFlags = newFlags, 868 originalFlags = oldFlags 869 ) 870 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 871 verifyAppKillState(shouldBeKilled = false) 872 873 val expectedState = mutableMapOf(FG_PERM_NAME to (true to newFlags)) 874 assertGroupPermState(newGroup, expectedState) 875 } 876 877 /** Test revoking one foreground permission. The permission and app op should be revoked. */ 878 @Test revokeOnePermTestnull879 fun revokeOnePermTest() { 880 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 881 val perms = mutableMapOf<String, LightPermission>() 882 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 883 val group = createMockGroup(pkg, perms) 884 resetMockAppState() 885 886 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 887 888 val newFlags = FLAG_PERMISSION_USER_SET 889 verifyPermissionState( 890 permName = FG_PERM_NAME, 891 expectPermChange = true, 892 expectPermGranted = false, 893 expectedFlags = newFlags 894 ) 895 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 896 verifyAppKillState(shouldBeKilled = false) 897 898 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 899 assertGroupPermState(newGroup, expectedState) 900 } 901 902 /** Test revoking two foreground permissions. Both permissions and app ops should be revoked. */ 903 @Test revokeTwoPermTestnull904 fun revokeTwoPermTest() { 905 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, FG_PERM_2_NAME to true)) 906 val perms = mutableMapOf<String, LightPermission>() 907 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 908 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME) 909 val group = createMockGroup(pkg, perms) 910 resetMockAppState() 911 912 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 913 914 val newFlags = FLAG_PERMISSION_USER_SET 915 verifyPermissionState( 916 permName = FG_PERM_NAME, 917 expectPermChange = true, 918 expectPermGranted = false, 919 expectedFlags = newFlags 920 ) 921 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 922 verifyPermissionState( 923 permName = FG_PERM_2_NAME, 924 expectPermChange = true, 925 expectPermGranted = false, 926 expectedFlags = newFlags 927 ) 928 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 929 verifyAppKillState(shouldBeKilled = false) 930 931 val expectedState = 932 mutableMapOf(FG_PERM_NAME to (false to newFlags), FG_PERM_2_NAME to (false to newFlags)) 933 assertGroupPermState(newGroup, expectedState) 934 } 935 936 /** 937 * Test the revoking of a permission with no app op. No app ops should change, but the 938 * permission should be revoked. 939 */ 940 @Test revokeNoAppOpPermnull941 fun revokeNoAppOpPerm() { 942 val pkg = createMockPackage(mapOf(FG_PERM_NAME_NO_APP_OP to true)) 943 val perms = mutableMapOf<String, LightPermission>() 944 perms[FG_PERM_NAME_NO_APP_OP] = createMockPerm(pkg, FG_PERM_NAME_NO_APP_OP) 945 val group = createMockGroup(pkg, perms) 946 resetMockAppState() 947 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 948 949 val newFlags = FLAG_PERMISSION_USER_SET 950 verifyPermissionState( 951 permName = FG_PERM_NAME_NO_APP_OP, 952 expectPermChange = true, 953 expectPermGranted = false, 954 expectedFlags = newFlags 955 ) 956 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 957 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 958 verifyAppKillState(shouldBeKilled = false) 959 960 val expectedState = mutableMapOf(FG_PERM_NAME_NO_APP_OP to (false to newFlags)) 961 assertGroupPermState(newGroup, expectedState) 962 } 963 964 /** 965 * Test that revoking a background permission revokes the permission, and sets the app ops of 966 * its foreground permissions to foreground only, and does not revoke the foreground permission. 967 */ 968 @Test revokeBgPermTestnull969 fun revokeBgPermTest() { 970 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 971 val perms = mutableMapOf<String, LightPermission>() 972 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 973 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 974 val group = createMockGroup(pkg, perms) 975 resetMockAppState() 976 977 val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group) 978 979 val newFlags = FLAG_PERMISSION_USER_SET 980 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 981 verifyPermissionState( 982 permName = BG_PERM_NAME, 983 expectPermChange = true, 984 expectPermGranted = false, 985 expectedFlags = newFlags 986 ) 987 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 988 verifyAppKillState(shouldBeKilled = false) 989 990 val expectedState = 991 mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), BG_PERM_NAME to (false to newFlags)) 992 assertGroupPermState(newGroup, expectedState) 993 } 994 995 /** 996 * Test granting a foreground permission, then a background. After the foreground permission is 997 * granted, the app op should be in foreground mode. After the background permission, it should 998 * be fully allowed. 999 */ 1000 @Test revokeBgAndFgPermTestnull1001 fun revokeBgAndFgPermTest() { 1002 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 1003 val perms = mutableMapOf<String, LightPermission>() 1004 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 1005 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, listOf(FG_PERM_NAME)) 1006 val group = createMockGroup(pkg, perms) 1007 resetMockAppState() 1008 1009 val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, true) 1010 1011 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED 1012 verifyPermissionState( 1013 permName = BG_PERM_NAME, 1014 expectPermChange = true, 1015 expectPermGranted = false, 1016 expectedFlags = newFlags 1017 ) 1018 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_FOREGROUND) 1019 verifyAppKillState(shouldBeKilled = false) 1020 val expectedState = 1021 mutableMapOf(FG_PERM_NAME to (true to NO_FLAGS), BG_PERM_NAME to (false to newFlags)) 1022 assertGroupPermState(newGroup, expectedState) 1023 1024 resetMockAppState() 1025 val newGroup2 = KotlinUtils.revokeForegroundRuntimePermissions(app, newGroup, true) 1026 1027 verifyPermissionState( 1028 permName = FG_PERM_NAME, 1029 expectPermChange = true, 1030 expectPermGranted = false, 1031 expectedFlags = newFlags 1032 ) 1033 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1034 verifyAppKillState(shouldBeKilled = false) 1035 1036 val expectedState2 = 1037 mutableMapOf(FG_PERM_NAME to (false to newFlags), BG_PERM_NAME to (false to newFlags)) 1038 assertGroupPermState(newGroup2, expectedState2) 1039 } 1040 1041 /** 1042 * Test revoking a group with a foreground permission that is system fixed, and another that 1043 * isn't. The system fixed permission should not change. 1044 */ 1045 @Test revokeSystemFixedTestnull1046 fun revokeSystemFixedTest() { 1047 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, FG_PERM_2_NAME to true)) 1048 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 1049 val perms = mutableMapOf<String, LightPermission>() 1050 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 1051 perms[FG_PERM_2_NAME] = createMockPerm(pkg, FG_PERM_2_NAME, flags = permFlags) 1052 val group = createMockGroup(pkg, perms) 1053 resetMockAppState() 1054 1055 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1056 1057 val newFlags = FLAG_PERMISSION_USER_SET 1058 verifyPermissionState( 1059 permName = FG_PERM_NAME, 1060 expectPermChange = true, 1061 expectPermGranted = false, 1062 expectedFlags = newFlags 1063 ) 1064 verifyPermissionState(permName = FG_PERM_2_NAME, expectPermChange = false) 1065 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1066 verifyAppOpState(appOpName = OP_2_NAME, expectAppOpSet = false) 1067 verifyAppKillState(shouldBeKilled = false) 1068 1069 val expectedState = 1070 mutableMapOf(FG_PERM_NAME to (false to newFlags), FG_PERM_2_NAME to (true to permFlags)) 1071 assertGroupPermState(newGroup, expectedState) 1072 } 1073 1074 /** 1075 * Test revoking a group with a background permission that is system fixed, and a background 1076 * permission that isn't. The system fixed permission should not change. 1077 */ 1078 @Test revokeBgSystemFixedTestnull1079 fun revokeBgSystemFixedTest() { 1080 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true, BG_PERM_NAME to true)) 1081 val permFlags = FLAG_PERMISSION_SYSTEM_FIXED 1082 val perms = mutableMapOf<String, LightPermission>() 1083 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, BG_PERM_NAME) 1084 perms[BG_PERM_NAME] = createMockPerm(pkg, BG_PERM_NAME, null, FG_PERM_NAMES, permFlags) 1085 val group = createMockGroup(pkg, perms) 1086 resetMockAppState() 1087 1088 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1089 1090 val newFlags = FLAG_PERMISSION_USER_SET 1091 verifyPermissionState( 1092 permName = FG_PERM_NAME, 1093 expectPermChange = true, 1094 expectPermGranted = false, 1095 expectedFlags = newFlags 1096 ) 1097 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1098 verifyAppKillState(shouldBeKilled = false) 1099 1100 var expectedState = 1101 mutableMapOf(FG_PERM_NAME to (false to newFlags), BG_PERM_NAME to (true to permFlags)) 1102 assertGroupPermState(newGroup, expectedState) 1103 1104 resetMockAppState() 1105 val newGroup2 = KotlinUtils.revokeBackgroundRuntimePermissions(app, newGroup) 1106 1107 verifyPermissionState(permName = BG_PERM_NAME, expectPermChange = false) 1108 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 1109 verifyAppKillState(shouldBeKilled = false) 1110 1111 expectedState = 1112 mutableMapOf(FG_PERM_NAME to (false to newFlags), BG_PERM_NAME to (true to permFlags)) 1113 assertGroupPermState(newGroup2, expectedState) 1114 } 1115 1116 /** 1117 * Test revoking a one time granted permission. The permission should be revoked, but no longer 1118 * be one time. 1119 */ 1120 @Test revokeOneTimeTestnull1121 fun revokeOneTimeTest() { 1122 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 1123 val oldFlags = FLAG_PERMISSION_ONE_TIME 1124 val perms = mutableMapOf<String, LightPermission>() 1125 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = oldFlags) 1126 val group = createMockGroup(pkg, perms) 1127 resetMockAppState() 1128 1129 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1130 1131 val newFlags = FLAG_PERMISSION_USER_SET 1132 verifyPermissionState( 1133 permName = FG_PERM_NAME, 1134 expectPermChange = true, 1135 expectPermGranted = false, 1136 expectedFlags = newFlags, 1137 originalFlags = oldFlags 1138 ) 1139 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1140 verifyAppKillState(shouldBeKilled = false) 1141 1142 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1143 assertGroupPermState(newGroup, expectedState) 1144 } 1145 1146 /** 1147 * Test compat revoking (permission granted, app op denied) permission. The app op should be 1148 * revoked, while the permission remains granted. The app should also be killed. 1149 */ 1150 @Test revokePreMAppTestnull1151 fun revokePreMAppTest() { 1152 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true), isPreMApp = true) 1153 val perms = mutableMapOf<String, LightPermission>() 1154 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 1155 val group = createMockGroup(pkg, perms) 1156 resetMockAppState() 1157 1158 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1159 1160 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_REVOKED_COMPAT 1161 verifyPermissionState( 1162 permName = FG_PERM_NAME, 1163 expectPermChange = false, 1164 expectedFlags = newFlags 1165 ) 1166 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1167 verifyAppKillState(shouldBeKilled = true) 1168 1169 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1170 assertGroupPermState(newGroup, expectedState) 1171 } 1172 1173 /** 1174 * Test the revoking of a single foreground permission for a Pre M app. Nothing should change, 1175 * and the app should not be killed 1176 */ 1177 @Test revokeAlreadyRevokedPreMTestnull1178 fun revokeAlreadyRevokedPreMTest() { 1179 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 1180 val perms = mutableMapOf<String, LightPermission>() 1181 val flags = FLAG_PERMISSION_USER_SET 1182 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, flags = flags) 1183 val group = createMockGroup(pkg, perms) 1184 resetMockAppState() 1185 1186 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1187 1188 verifyPermissionState(permName = FG_PERM_NAME, expectPermChange = false) 1189 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 1190 verifyAppKillState(shouldBeKilled = false) 1191 1192 val expectedState = mutableMapOf(FG_PERM_NAME to (false to flags)) 1193 assertGroupPermState(newGroup, expectedState) 1194 } 1195 1196 /** 1197 * Test revoking a standard permission for an instant app, to show that instant app status does 1198 * not affect the revoking of a permission. 1199 */ 1200 @Test revokeInstantAppTestnull1201 fun revokeInstantAppTest() { 1202 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true), isInstantApp = true) 1203 val perms = mutableMapOf<String, LightPermission>() 1204 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME) 1205 val group = createMockGroup(pkg, perms) 1206 resetMockAppState() 1207 1208 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, true) 1209 1210 val newFlags = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED 1211 verifyPermissionState( 1212 permName = FG_PERM_NAME, 1213 expectPermChange = true, 1214 expectPermGranted = false, 1215 expectedFlags = newFlags 1216 ) 1217 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1218 verifyAppKillState(shouldBeKilled = false) 1219 1220 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1221 assertGroupPermState(newGroup, expectedState) 1222 } 1223 1224 /** 1225 * Revoke a permission that was user fixed, and set it to no longer be user fixed. The 1226 * permission and its app op should be revoked, and the permission should no longer be user 1227 * fixed. 1228 */ 1229 @Test revokeUserFixedPermTestnull1230 fun revokeUserFixedPermTest() { 1231 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 1232 val perms = mutableMapOf<String, LightPermission>() 1233 val oldFlags = FLAG_PERMISSION_USER_FIXED 1234 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1235 val group = createMockGroup(pkg, perms) 1236 resetMockAppState() 1237 1238 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1239 1240 val newFlags = FLAG_PERMISSION_USER_SET 1241 verifyPermissionState( 1242 permName = FG_PERM_NAME, 1243 expectPermChange = true, 1244 expectPermGranted = false, 1245 expectedFlags = newFlags, 1246 originalFlags = oldFlags 1247 ) 1248 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1249 verifyAppKillState(shouldBeKilled = false) 1250 1251 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1252 assertGroupPermState(newGroup, expectedState) 1253 } 1254 1255 /** 1256 * Revoke a permission that was not user fixed, and set it to be user fixed. The permission and 1257 * its app op should be revoked, and the permission should be user fixed. 1258 */ 1259 @Test revokeAndSetUserFixedPermTestnull1260 fun revokeAndSetUserFixedPermTest() { 1261 val pkg = createMockPackage(mapOf(FG_PERM_NAME to true)) 1262 val perms = mutableMapOf<String, LightPermission>() 1263 val oldFlags = FLAG_PERMISSION_USER_SET 1264 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1265 val group = createMockGroup(pkg, perms) 1266 resetMockAppState() 1267 1268 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, true) 1269 1270 val newFlags = oldFlags or FLAG_PERMISSION_USER_FIXED 1271 verifyPermissionState( 1272 permName = FG_PERM_NAME, 1273 expectPermChange = true, 1274 expectPermGranted = false, 1275 expectedFlags = newFlags, 1276 originalFlags = oldFlags 1277 ) 1278 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = true, expectedMode = MODE_IGNORED) 1279 verifyAppKillState(shouldBeKilled = false) 1280 1281 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1282 assertGroupPermState(newGroup, expectedState) 1283 } 1284 1285 /** 1286 * Test revoking an already revoked permission, while changing its user fixed state from true to 1287 * false. The user fixed should update, but the state should stay the same otherwise. 1288 */ 1289 @Test changeUserFixedTestnull1290 fun changeUserFixedTest() { 1291 val pkg = createMockPackage(mapOf(FG_PERM_NAME to false)) 1292 val perms = mutableMapOf<String, LightPermission>() 1293 val oldFlags = FLAG_PERMISSION_USER_FIXED 1294 perms[FG_PERM_NAME] = createMockPerm(pkg, FG_PERM_NAME, null, null, oldFlags) 1295 val group = createMockGroup(pkg, perms) 1296 resetMockAppState() 1297 1298 val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group) 1299 1300 val newFlags = FLAG_PERMISSION_USER_SET 1301 verifyPermissionState( 1302 permName = FG_PERM_NAME, 1303 expectPermChange = false, 1304 expectedFlags = newFlags, 1305 originalFlags = oldFlags 1306 ) 1307 verifyAppOpState(appOpName = OP_NAME, expectAppOpSet = false) 1308 verifyAppKillState(shouldBeKilled = false) 1309 1310 val expectedState = mutableMapOf(FG_PERM_NAME to (false to newFlags)) 1311 assertGroupPermState(newGroup, expectedState) 1312 } 1313 } 1314