• 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.
122      * 2. If the perm group is LOCATION, check if ACCESS_COARSE_LOCATION is one-time.
123      */
124     val isOneTime = (permGroupName != Manifest.permission_group.LOCATION &&
125             permissions.any { it.value.isOneTime }) ||
126             (permGroupName == Manifest.permission_group.LOCATION &&
127                     permissions[ACCESS_COARSE_LOCATION]?.isOneTime == true)
128 
129     /**
130      * Whether any permissions in this group are granted by default (pregrant)
131      */
132     val isGrantedByDefault = foreground.isGrantedByDefault || background.isGrantedByDefault
133 
134     /**
135      * Whether any permissions in this group are granted by being a role holder
136      */
137     val isGrantedByRole = foreground.isGrantedByRole || background.isGrantedByRole
138 
139     /**
140      * Whether any permissions in this group are user sensitive
141      */
142     val isUserSensitive = permissions.any { it.value.isUserSensitive }
143 
144     /**
145      * Whether any permissions in this group are revoke-when-requested
146      */
147     val isRevokeWhenRequested = permissions.any { it.value.isRevokeWhenRequested }
148 
149     /**
150      * A subset of the AppPermssionGroup, representing either the background or foreground permissions
151      * of the full group.
152      *
153      * @param permissions The permissions contained within this subgroup, a subset of those contained
154      * in the full group
155      * @param specialLocationGrant Whether this is a special location package
156      */
157     data class AppPermSubGroup internal constructor(
158         private val permissions: Map<String, LightPermission>,
159         private val packageInfo: LightPackageInfo,
160         private val specialLocationGrant: Boolean?
161     ) {
162         /**
163          * Whether any of this App Permission SubGroup's permissions are granted
164          */
165         val isGranted = specialLocationGrant ?: permissions.any { it.value.isGrantedIncludingAppOp }
166 
167         /**
168          * Whether any of this App Permission SubGroup's permissions are granted by default
169          */
170         val isGrantedByDefault = permissions.any { it.value.isGrantedByDefault }
171 
172         /**
173          * Whether any of this App Permission Subgroup's foreground permissions are fixed by policy
174          */
175         val isPolicyFixed = permissions.any { it.value.isPolicyFixed }
176 
177         /**
178          * Whether any of this App Permission Subgroup's permissions are fixed by the system
179          */
180         val isSystemFixed = permissions.any { it.value.isSystemFixed }
181 
182         /**
183          * Whether any of this App Permission Subgroup's permissions are fixed by the user
184          */
185         val isUserFixed = permissions.any { it.value.isUserFixed }
186 
187         /**
188          * Whether any of this App Permission Subgroup's permissions are set by the user
189          */
190         val isUserSet = permissions.any { it.value.isUserSet }
191 
192         /**
193          * Whether any of this App Permission Subgroup's permissions are set by the role of this app
194          */
195         val isGrantedByRole = permissions.any { it.value.isGrantedByRole }
196 
197         private val hasPreRuntimePerm = permissions.any { (_, perm) -> !perm.isRuntimeOnly }
198 
199         private val hasInstantPerm = permissions.any { (_, perm) -> perm.isInstantPerm }
200 
201         /**
202          * Whether or not any permissions in this App Permission Subgroup can be granted
203          */
204         val isGrantable = (!packageInfo.isInstantApp || hasInstantPerm) &&
205                 (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntimePerm)
206     }
207 }