• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.permissioncontroller.permission.model.livedatatypes
18 
19 import android.Manifest
20 import android.Manifest.permission.ACCESS_COARSE_LOCATION
21 import android.os.Build
22 import android.os.UserHandle
23 
24 /**
25  * A lightweight version of the AppPermissionGroup data structure. Represents information about a
26  * package, and all permissions in a particular permission group this package requests.
27  *
28  * @param packageInfo Information about the package
29  * @param permGroupInfo Information about the permission group
30  * @param allPermissions The permissions in the permission group that the package requests
31  * (including restricted ones).
32  * @param hasInstallToRuntimeSplit If this group contains a permission that was previously an
33  * install permission, but is currently a runtime permission
34  * @param specialLocationGrant If this package is the location provider, or the extra location
35  * package, then the grant state of the group is not determined by the grant state of individual
36  * permissions, but by other system properties
37  */
38 data class LightAppPermGroup(
39     val packageInfo: LightPackageInfo,
40     val permGroupInfo: LightPermGroupInfo,
41     val allPermissions: Map<String, LightPermission>,
42     val hasInstallToRuntimeSplit: Boolean,
43     val specialLocationGrant: Boolean?
44 ) {
45     constructor(
46         pI: LightPackageInfo,
47         pGI: LightPermGroupInfo,
48         perms: Map<String, LightPermission>
49     ) : this(pI, pGI, perms, false, null)
50 
51     /**
52      * All unrestricted permissions. Usually restricted permissions are ignored
53      */
54     val permissions: Map<String, LightPermission> =
55             allPermissions.filter { (_, permission) -> !permission.isRestricted }
56 
57     /**
58      * The package name of this group
59      */
60     val packageName = packageInfo.packageName
61 
62     /**
63      * The permission group name of this group
64      */
65     val permGroupName = permGroupInfo.name
66 
67     /**
68      * The current userHandle of this AppPermGroup.
69      */
70     val userHandle: UserHandle = UserHandle.getUserHandleForUid(packageInfo.uid)
71 
72     /**
73      * The names of all background permissions in the permission group which are requested by the
74      * package.
75      */
76     val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission }
77 
78     /**
79      * All foreground permissions in the permission group which are requested by the package.
80      */
81     val foregroundPermNames get() = permissions.mapNotNull { (name, _) ->
82         if (name !in backgroundPermNames) name else null
83     }
84 
85     val foreground = AppPermSubGroup(permissions.filter { it.key in foregroundPermNames },
86         packageInfo, specialLocationGrant)
87 
88     val background = AppPermSubGroup(permissions.filter { it.key in backgroundPermNames },
89         packageInfo, specialLocationGrant)
90 
91     /**
92      * Whether or not this App Permission Group has a permission which has a background mode
93      */
94     val hasPermWithBackgroundMode = backgroundPermNames.isNotEmpty()
95 
96     /**
97      * Whether or not this App Permission Group requests a background permission
98      */
99     val hasBackgroundGroup = backgroundPermNames.any { permissions.contains(it) }
100 
101     /**
102      * Whether this App Permission Group's background and foreground permissions are fixed by policy
103      */
104     val isPolicyFullyFixed = foreground.isPolicyFixed && (!hasBackgroundGroup ||
105         background.isPolicyFixed)
106 
107     /**
108      * Whether this App Permission Group's background permissions are fixed by the system or policy
109      */
110     val isBackgroundFixed = background.isPolicyFixed || background.isSystemFixed
111 
112     /**
113      * Whether this App Permission Group's foreground permissions are fixed by the system or policy
114      */
115     val isForegroundFixed = foreground.isPolicyFixed || foreground.isSystemFixed
116 
117     /**
118      * Whether or not this group supports runtime permissions
119      */
120     val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M
121 
122     /**
123      * Whether this App Permission Group is one-time. 2 cases:
124      * 1. If the perm group is not LOCATION, check if any of the permissions is one-time and none of
125      * the granted permissions are not one-time.
126      * 2. If the perm group is LOCATION, check if ACCESS_COARSE_LOCATION is one-time.
127      */
128     val isOneTime = (permGroupName != Manifest.permission_group.LOCATION &&
129             permissions.any { it.value.isOneTime } &&
130             permissions.none { !it.value.isOneTime && it.value.isGrantedIncludingAppOp }) ||
131             (permGroupName == Manifest.permission_group.LOCATION &&
132                     permissions[ACCESS_COARSE_LOCATION]?.isOneTime == true)
133 
134     /**
135      * Whether any permissions in this group are granted by default (pregrant)
136      */
137     val isGrantedByDefault = foreground.isGrantedByDefault || background.isGrantedByDefault
138 
139     /**
140      * Whether any permissions in this group are granted by being a role holder
141      */
142     val isGrantedByRole = foreground.isGrantedByRole || background.isGrantedByRole
143 
144     /**
145      * Whether any of the permission (foreground/background) is fixed by the system
146      */
147     val isSystemFixed = foreground.isSystemFixed || background.isSystemFixed
148 
149     /**
150      * Whether any of the permission (foreground/background) in this group requires a review
151      */
152     val isReviewRequired = foreground.isReviewRequired || background.isReviewRequired
153 
154     /**
155      * Whether any of the permission (foreground/background) is granted in this permission group
156      */
157     var isGranted = foreground.isGranted || background.isGranted
158 
159     /**
160      * Whether any permissions in this group are user sensitive
161      */
162     val isUserSensitive = permissions.any { it.value.isUserSensitive }
163 
164     /**
165      * Whether any permissions in this group are revoke-when-requested
166      */
167     val isRevokeWhenRequested = permissions.any { it.value.isRevokeWhenRequested }
168 
169     /**
170      * Whether any of this App Permission Groups permissions are fixed by the user
171      */
172     val isUserFixed = foreground.isUserFixed || background.isUserFixed
173 
174     /**
175      * Whether any of this App Permission Group's permissions are set by the user
176      */
177     val isUserSet = foreground.isUserSet || background.isUserSet
178 
179     /**
180      * A subset of the AppPermissionGroup, representing either the background or foreground permissions
181      * of the full group.
182      *
183      * @param permissions The permissions contained within this subgroup, a subset of those contained
184      * in the full group
185      * @param specialLocationGrant Whether this is a special location package
186      */
187     data class AppPermSubGroup internal constructor(
188         private val permissions: Map<String, LightPermission>,
189         private val packageInfo: LightPackageInfo,
190         private val specialLocationGrant: Boolean?
191     ) {
192         /**
193          * Whether any of this App Permission SubGroup's permissions are granted
194          */
195         val isGranted = specialLocationGrant ?: permissions.any { it.value.isGrantedIncludingAppOp }
196 
197         /**
198          * Whether this App Permission SubGroup should be treated as granted. This means either:
199          * 1) At least one permission was granted excluding auto-granted permissions (i.e., granted
200          * during install time with flag RevokeWhenRequested.) Or,
201          * 2) All permissions were auto-granted (all permissions are all granted and all
202          * RevokeWhenRequested.)
203          */
204         val isGrantedExcludingRWROrAllRWR = specialLocationGrant ?: (permissions
205             .any { it.value.isGrantedIncludingAppOp && !it.value.isRevokeWhenRequested } ||
206             permissions.all { it.value.isGrantedIncludingAppOp && it.value.isRevokeWhenRequested })
207 
208         /**
209          * Whether any of this App Permission SubGroup's permissions are granted by default
210          */
211         val isGrantedByDefault = permissions.any { it.value.isGrantedByDefault }
212 
213         /**
214          * Whether at least one of this App Permission SubGroup's permissions is one-time and
215          * none of the granted permissions are not one-time.
216          */
217         val isOneTime = permissions.any { it.value.isOneTime } &&
218                 permissions.none { it.value.isGrantedIncludingAppOp && !it.value.isOneTime }
219 
220         /**
221          * Whether any of this App Permission Subgroup's foreground permissions are fixed by policy
222          */
223         val isPolicyFixed = permissions.any { it.value.isPolicyFixed }
224 
225         /**
226          * Whether any of this App Permission Subgroup's permissions are fixed by the system
227          */
228         val isSystemFixed = permissions.any { it.value.isSystemFixed }
229 
230         /**
231          * Whether any of this App Permission Subgroup's permissions are fixed by the user
232          */
233         val isUserFixed = permissions.any { it.value.isUserFixed }
234 
235         /**
236          * Whether any of this App Permission Subgroup's permissions are set by the user
237          */
238         val isUserSet = permissions.any { it.value.isUserSet }
239 
240         /**
241          * whether review is required or not for the permission group
242          */
243         val isReviewRequired = permissions.any { it.value.isReviewRequired }
244 
245         /**
246          * Whether any of this App Permission Subgroup's permissions are set by the role of this app
247          */
248         val isGrantedByRole = permissions.any { it.value.isGrantedByRole }
249 
250         private val hasPreRuntimePerm = permissions.any { (_, perm) -> !perm.isRuntimeOnly }
251 
252         private val hasInstantPerm = permissions.any { (_, perm) -> perm.isInstantPerm }
253 
254         /**
255          * Whether or not any permissions in this App Permission Subgroup can be granted
256          */
257         val isGrantable = (!packageInfo.isInstantApp || hasInstantPerm) &&
258                 (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntimePerm)
259     }
260 }