• 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(pI: LightPackageInfo, pGI: LightPermGroupInfo, perms: Map<String, LightPermission>):
46         this(pI, pGI, perms, false, null)
47 
48     /**
49      * All unrestricted permissions. Usually restricted permissions are ignored
50      */
51     val permissions: Map<String, LightPermission> =
52             allPermissions.filter { (_, permission) -> !permission.isRestricted }
53 
54     /**
55      * The package name of this group
56      */
57     val packageName = packageInfo.packageName
58 
59     /**
60      * The permission group name of this group
61      */
62     val permGroupName = permGroupInfo.name
63 
64     /**
65      * The current userHandle of this AppPermGroup.
66      */
67     val userHandle: UserHandle = UserHandle.getUserHandleForUid(packageInfo.uid)
68 
69     /**
70      * The names of all background permissions in the permission group which are requested by the
71      * package.
72      */
73     val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission }
74 
75     /**
76      * All foreground permissions in the permission group which are requested by the package.
77      */
78     val foregroundPermNames get() = permissions.mapNotNull { (name, _) ->
79         if (name !in backgroundPermNames) name else null
80     }
81 
82     val foreground = AppPermSubGroup(permissions.filter { it.key in foregroundPermNames },
83         packageInfo, specialLocationGrant)
84 
85     val background = AppPermSubGroup(permissions.filter { it.key in backgroundPermNames },
86         packageInfo, specialLocationGrant)
87 
88     /**
89      * Whether or not this App Permission Group has a permission which has a background mode
90      */
91     val hasPermWithBackgroundMode = backgroundPermNames.isNotEmpty()
92 
93     /**
94      * Whether or not this App Permission Group requests a background permission
95      */
96     val hasBackgroundGroup = backgroundPermNames.any { permissions.contains(it) }
97 
98     /**
99      * Whether this App Permission Group's background and foreground permissions are fixed by policy
100      */
101     val isPolicyFullyFixed = foreground.isPolicyFixed && (!hasBackgroundGroup ||
102         background.isPolicyFixed)
103 
104     /**
105      * Whether this App Permission Group's background permissions are fixed by the system or policy
106      */
107     val isBackgroundFixed = background.isPolicyFixed || background.isSystemFixed
108 
109     /**
110      * Whether this App Permission Group's foreground permissions are fixed by the system or policy
111      */
112     val isForegroundFixed = foreground.isPolicyFixed || foreground.isSystemFixed
113 
114     /**
115      * Whether or not this group supports runtime permissions
116      */
117     val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M
118 
119     /**
120      * Whether this App Permission Group is one-time. 2 cases:
121      * 1. If the perm group is not LOCATION, check if any of the permissions is one-time and none of
122      * the granted permissions are not one-time.
123      * 2. If the perm group is LOCATION, check if ACCESS_COARSE_LOCATION is one-time.
124      */
125     val isOneTime = (permGroupName != Manifest.permission_group.LOCATION &&
126             permissions.any { it.value.isOneTime } &&
127             permissions.none { !it.value.isOneTime && it.value.isGrantedIncludingAppOp }) ||
128             (permGroupName == Manifest.permission_group.LOCATION &&
129                     permissions[ACCESS_COARSE_LOCATION]?.isOneTime == true)
130 
131     /**
132      * Whether any permissions in this group are granted by default (pregrant)
133      */
134     val isGrantedByDefault = foreground.isGrantedByDefault || background.isGrantedByDefault
135 
136     /**
137      * Whether any permissions in this group are granted by being a role holder
138      */
139     val isGrantedByRole = foreground.isGrantedByRole || background.isGrantedByRole
140 
141     /**
142      * Whether any of the permission (foreground/background) is fixed by the system
143      */
144     val isSystemFixed = foreground.isSystemFixed || background.isSystemFixed
145 
146     /**
147      * Whether any of the permission (foreground/background) in this group requires a review
148      */
149     val isReviewRequired = foreground.isReviewRequired || background.isReviewRequired
150 
151     /**
152      * Whether any of the permission (foreground/background) is granted in this permission group
153      */
154     var isGranted = foreground.isGranted || background.isGranted
155 
156     /**
157      * Whether any permissions in this group are user sensitive
158      */
159     val isUserSensitive = permissions.any { it.value.isUserSensitive }
160 
161     /**
162      * Whether any permissions in this group are revoke-when-requested
163      */
164     val isRevokeWhenRequested = permissions.any { it.value.isRevokeWhenRequested }
165 
166     /**
167      * Whether a runtime permission request dialog must be shown on behalf of the app, rather than
168      * the app requesting explicitly
169      */
170     val isRuntimePermReviewRequired = supportsRuntimePerms &&
171             permissions.any { it.value.isReviewRequired }
172 
173     /**
174      * A subset of the AppPermissionGroup, representing either the background or foreground permissions
175      * of the full group.
176      *
177      * @param permissions The permissions contained within this subgroup, a subset of those contained
178      * in the full group
179      * @param specialLocationGrant Whether this is a special location package
180      */
181     data class AppPermSubGroup internal constructor(
182         private val permissions: Map<String, LightPermission>,
183         private val packageInfo: LightPackageInfo,
184         private val specialLocationGrant: Boolean?
185     ) {
186         /**
187          * Whether any of this App Permission SubGroup's permissions are granted
188          */
189         val isGranted = specialLocationGrant ?: permissions.any { it.value.isGrantedIncludingAppOp }
190 
191         /**
192          * Whether this App Permission SubGroup should be treated as granted. This means either:
193          * 1) At least one permission was granted excluding auto-granted permissions (i.e., granted
194          * during install time with flag RevokeWhenRequested.) Or,
195          * 2) All permissions were auto-granted (all permissions are all granted and all
196          * RevokeWhenRequested.)
197          */
198         val isGrantedExcludingRWROrAllRWR = specialLocationGrant ?: (permissions
199             .any { it.value.isGrantedIncludingAppOp && !it.value.isRevokeWhenRequested } ||
200             permissions.all { it.value.isGrantedIncludingAppOp && it.value.isRevokeWhenRequested })
201 
202         /**
203          * Whether any of this App Permission SubGroup's permissions are granted by default
204          */
205         val isGrantedByDefault = permissions.any { it.value.isGrantedByDefault }
206 
207         /**
208          * Whether at least one of this App Permission SubGroup's permissions is one-time and
209          * none of the granted permissions are not one-time.
210          */
211         val isOneTime = permissions.any { it.value.isOneTime } &&
212                 permissions.none { it.value.isGrantedIncludingAppOp && !it.value.isOneTime }
213 
214         /**
215          * Whether any of this App Permission Subgroup's foreground permissions are fixed by policy
216          */
217         val isPolicyFixed = permissions.any { it.value.isPolicyFixed }
218 
219         /**
220          * Whether any of this App Permission Subgroup's permissions are fixed by the system
221          */
222         val isSystemFixed = permissions.any { it.value.isSystemFixed }
223 
224         /**
225          * Whether any of this App Permission Subgroup's permissions are fixed by the user
226          */
227         val isUserFixed = permissions.any { it.value.isUserFixed }
228 
229         /**
230          * Whether any of this App Permission Subgroup's permissions are set by the user
231          */
232         val isUserSet = permissions.any { it.value.isUserSet }
233 
234         /**
235          * whether review is required or not for the permission group
236          */
237         val isReviewRequired = permissions.any { it.value.isReviewRequired }
238 
239         /**
240          * Whether any of this App Permission Subgroup's permissions are set by the role of this app
241          */
242         val isGrantedByRole = permissions.any { it.value.isGrantedByRole }
243 
244         private val hasPreRuntimePerm = permissions.any { (_, perm) -> !perm.isRuntimeOnly }
245 
246         private val hasInstantPerm = permissions.any { (_, perm) -> perm.isInstantPerm }
247 
248         /**
249          * Whether or not any permissions in this App Permission Subgroup can be granted
250          */
251         val isGrantable = (!packageInfo.isInstantApp || hasInstantPerm) &&
252                 (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntimePerm)
253     }
254 }