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.os.Build
20 import android.os.UserHandle
21 
22 /**
23  * A lightweight version of the AppPermissionGroup data structure. Represents information about a
24  * package, and all permissions in a particular permission group this package requests.
25  *
26  * @param packageInfo Information about the package
27  * @param permGroupInfo Information about the permission group
28  * @param allPermissions The permissions in the permission group that the package requests
29  * (including restricted ones).
30  * @param hasInstallToRuntimeSplit If this group contains a permission that was previously an
31  * install permission, but is currently a runtime permission
32  * @param specialLocationGrant If this package is the location provider, or the extra location
33  * package, then the grant state of the group is not determined by the grant state of individual
34  * permissions, but by other system properties
35  */
36 data class LightAppPermGroup(
37     val packageInfo: LightPackageInfo,
38     val permGroupInfo: LightPermGroupInfo,
39     val allPermissions: Map<String, LightPermission>,
40     val hasInstallToRuntimeSplit: Boolean,
41     val specialLocationGrant: Boolean?
42 ) {
43     constructor(pI: LightPackageInfo, pGI: LightPermGroupInfo, perms: Map<String, LightPermission>):
44         this(pI, pGI, perms, false, null)
45 
46     /**
47      * All unrestricted permissions. Usually restricted permissions are ignored
48      */
49     val permissions: Map<String, LightPermission> =
50             allPermissions.filter { (_, permission) -> !permission.isRestricted }
51 
52     /**
53      * The package name of this group
54      */
55     val packageName = packageInfo.packageName
56 
57     /**
58      * The permission group name of this group
59      */
60     val permGroupName = permGroupInfo.name
61 
62     /**
63      * The current userHandle of this AppPermGroup.
64      */
65     val userHandle: UserHandle = UserHandle.getUserHandleForUid(packageInfo.uid)
66 
67     /**
68      * The names of all background permissions in the permission group which are requested by the
69      * package.
70      */
71     val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission }
72 
73     /**
74      * All foreground permissions in the permission group which are requested by the package.
75      */
76     val foregroundPermNames get() = permissions.mapNotNull { (name, _) ->
77         if (name !in backgroundPermNames) name else null
78     }
79 
80     val foreground = AppPermSubGroup(permissions.filter { it.key in foregroundPermNames },
81         specialLocationGrant)
82 
83     val background = AppPermSubGroup(permissions.filter { it.key in backgroundPermNames },
84         specialLocationGrant)
85 
86     /**
87      * Whether or not this App Permission Group has a permission which has a background mode
88      */
89     val hasPermWithBackgroundMode = backgroundPermNames.isNotEmpty()
90 
91     /**
92      * Whether or not this App Permission Group requests a background permission
93      */
94     val hasBackgroundGroup = backgroundPermNames.any { permissions.contains(it) }
95 
96     /**
97      * Whether this App Permission Group's background and foreground permissions are fixed by policy
98      */
99     val isPolicyFullyFixed = foreground.isPolicyFixed && (!hasBackgroundGroup ||
100         background.isPolicyFixed)
101 
102     /**
103      * Whether this App Permission Group's background permissions are fixed by the system or policy
104      */
105     val isBackgroundFixed = background.isPolicyFixed || background.isSystemFixed
106 
107     /**
108      * Whether this App Permission Group's foreground permissions are fixed by the system or policy
109      */
110     val isForegroundFixed = foreground.isPolicyFixed || foreground.isSystemFixed
111 
112     /**
113      * Whether or not this group supports runtime permissions
114      */
115     val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M
116 
117     /**
118      * Whether this App Permission Group contains any one-time permission
119      */
120     val isOneTime = permissions.any { it.value.isOneTime }
121 
122     /**
123      * Whether any permissions in this group are granted by default (pregrant)
124      */
125     val isGrantedByDefault = foreground.isGrantedByDefault || background.isGrantedByDefault
126 
127     /**
128      * Whether any permissions in this group are granted by being a role holder
129      */
130     val isGrantedByRole = foreground.isGrantedByRole || background.isGrantedByRole
131 
132     /*
133      * Whether any permissions in this group are user sensitive
134      */
135     val isUserSensitive = permissions.any { it.value.isUserSensitive }
136 
137     /**
138      * A subset of the AppPermssionGroup, representing either the background or foreground permissions
139      * of the full group.
140      *
141      * @param permissions The permissions contained within this subgroup, a subset of those contained
142      * in the full group
143      * @param specialLocationGrant Whether this is a special location package
144      */
145     data class AppPermSubGroup internal constructor(
146         private val permissions: Map<String, LightPermission>,
147         private val specialLocationGrant: Boolean?
148     ) {
149         /**
150          * Whether any of this App Permission SubGroup's permissions are granted
151          */
152         val isGranted = specialLocationGrant ?: permissions.any { it.value.isGrantedIncludingAppOp }
153 
154         /**
155          * Whether any of this App Permission SubGroup's permissions are granted by default
156          */
157         val isGrantedByDefault = permissions.any { it.value.isGrantedByDefault }
158 
159         /**
160          * Whether any of this App Permission Subgroup's foreground permissions are fixed by policy
161          */
162         val isPolicyFixed = permissions.any { it.value.isPolicyFixed }
163 
164         /**
165          * Whether any of this App Permission Subgroup's permissions are fixed by the system
166          */
167         val isSystemFixed = permissions.any { it.value.isSystemFixed }
168 
169         /**
170          * Whether any of this App Permission Subgroup's permissions are fixed by the user
171          */
172         val isUserFixed = permissions.any { it.value.isUserFixed }
173 
174         /**
175          * Whether any of this App Permission Subgroup's permissions are set by the user
176          */
177         val isUserSet = permissions.any { it.value.isUserSet }
178 
179         /**
180          * Whether any of this App Permission Subgroup's permissions are set by the role of this app
181          */
182         val isGrantedByRole = permissions.any { it.value.isGrantedByRole }
183     }
184 }