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