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