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