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