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 import com.android.permissioncontroller.permission.utils.Utils 24 25 /** 26 * A lightweight version of the AppPermissionGroup data structure. Represents information about a 27 * package, and all permissions in a particular permission group this package requests. 28 * 29 * @param packageInfo Information about the package 30 * @param permGroupInfo Information about the permission group 31 * @param allPermissions The permissions in the permission group that the package requests 32 * (including restricted ones). 33 * @param hasInstallToRuntimeSplit If this group contains a permission that was previously an 34 * install permission, but is currently a runtime permission 35 * @param specialLocationGrant If this package is the location provider, or the extra location 36 * package, then the grant state of the group is not determined by the grant state of individual 37 * permissions, but by other system properties 38 * @param specialFixedStorageGrant If this package holds the SYSTEM_GALLERY role, and has the 39 * WRITE_MEDIA_IMAGES app op granted, then we should show the grant state of the storage 40 * permissions as system fixed and granted. 41 * 42 */ 43 data class LightAppPermGroup( 44 val packageInfo: LightPackageInfo, 45 val permGroupInfo: LightPermGroupInfo, 46 val allPermissions: Map<String, LightPermission>, 47 val hasInstallToRuntimeSplit: Boolean, 48 val specialLocationGrant: Boolean?, 49 val specialFixedStorageGrant: Boolean, 50 ) { 51 constructor( 52 pI: LightPackageInfo, 53 pGI: LightPermGroupInfo, 54 perms: Map<String, LightPermission> 55 ) : this(pI, pGI, perms, false, null, false) 56 57 /** All unrestricted permissions. Usually restricted permissions are ignored */ 58 val permissions: Map<String, LightPermission> = 59 allPermissions.filter { (_, permission) -> !permission.isRestricted } 60 61 /** The package name of this group */ 62 val packageName = packageInfo.packageName 63 64 /** The permission group name of this group */ 65 val permGroupName = permGroupInfo.name 66 67 /** The current userHandle of this AppPermGroup. */ 68 val userHandle: UserHandle = UserHandle.getUserHandleForUid(packageInfo.uid) 69 70 /** The device ID of this group, inferred from LightPackageInfo */ 71 val deviceId = packageInfo.deviceId 72 73 /** 74 * The names of all background permissions in the permission group which are requested by the 75 * package. 76 */ 77 val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission } 78 79 /** All foreground permissions in the permission group which are requested by the package. */ 80 val foregroundPermNames 81 get() = 82 permissions.mapNotNull { (name, _) -> if (name !in backgroundPermNames) name else null } 83 84 val isPlatformPermissionGroup = permGroupInfo.packageName == Utils.OS_PKG 85 86 val foreground = 87 AppPermSubGroup( 88 permissions.filter { it.key in foregroundPermNames }, 89 packageInfo, 90 isPlatformPermissionGroup, 91 specialLocationGrant, 92 specialFixedStorageGrant 93 ) 94 95 val background = 96 AppPermSubGroup( 97 permissions.filter { it.key in backgroundPermNames }, 98 packageInfo, 99 isPlatformPermissionGroup, 100 specialLocationGrant, 101 specialFixedStorageGrant 102 ) 103 104 /** Whether or not this App Permission Group has a permission which has a background mode */ 105 val hasPermWithBackgroundMode = backgroundPermNames.isNotEmpty() 106 107 /** Whether or not this App Permission Group requests a background permission */ 108 val hasBackgroundGroup = backgroundPermNames.any { permissions.contains(it) } 109 110 /** 111 * Whether this App Permission Group's background and foreground permissions are fixed by policy 112 */ 113 val isPolicyFullyFixed = 114 foreground.isPolicyFixed && (!hasBackgroundGroup || background.isPolicyFixed) 115 116 /** 117 * Whether this App Permission Group's background permissions are fixed by the system or policy 118 */ 119 val isBackgroundFixed = background.isPolicyFixed || background.isSystemFixed 120 121 /** 122 * Whether this App Permission Group's foreground permissions are fixed by the system or policy 123 */ 124 val isForegroundFixed = foreground.isPolicyFixed || foreground.isSystemFixed 125 126 /** Whether or not this group supports runtime permissions */ 127 val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M 128 129 /** 130 * Whether this App Permission Group is one-time. 2 cases: 131 * 1. If the perm group is not LOCATION, check if any of the permissions is one-time and none of 132 * the granted permissions are not one-time. 133 * 2. If the perm group is LOCATION, check if ACCESS_COARSE_LOCATION is one-time. 134 */ 135 val isOneTime = 136 (permGroupName != Manifest.permission_group.LOCATION && 137 permissions.any { it.value.isOneTime } && 138 permissions.none { !it.value.isOneTime && it.value.isGranted }) || 139 (permGroupName == Manifest.permission_group.LOCATION && 140 permissions[ACCESS_COARSE_LOCATION]?.isOneTime == true) 141 142 /** Whether any permissions in this group are granted by default (pregrant) */ 143 val isGrantedByDefault = foreground.isGrantedByDefault || background.isGrantedByDefault 144 145 /** Whether any permissions in this group are granted by being a role holder */ 146 val isGrantedByRole = foreground.isGrantedByRole || background.isGrantedByRole 147 148 /** Whether any of the permission (foreground/background) is fixed by the system */ 149 val isSystemFixed = foreground.isSystemFixed || background.isSystemFixed 150 151 /** Whether any of the permission (foreground/background) in this group requires a review */ 152 val isReviewRequired = foreground.isReviewRequired || background.isReviewRequired 153 154 /** Whether any of the permission (foreground/background) is granted in this permission group */ 155 var isGranted = foreground.isGranted || background.isGranted 156 157 /** Whether any permissions in this group are user sensitive */ 158 val isUserSensitive = permissions.any { it.value.isUserSensitive } 159 160 /** Whether any permissions in this group are revoke-when-requested */ 161 val isRevokeWhenRequested = permissions.any { it.value.isRevokeWhenRequested } 162 163 /** Whether any of this App Permission Groups permissions are fixed by the user */ 164 val isUserFixed = foreground.isUserFixed || background.isUserFixed 165 166 /** Whether any of this App Permission Group's permissions are set by the user */ 167 val isUserSet = foreground.isUserSet || background.isUserSet 168 169 /** 170 * A subset of the AppPermissionGroup, representing either the background or foreground 171 * permissions of the full group. 172 * 173 * @param permissions The permissions contained within this subgroup, a subset of those 174 * contained in the full group 175 * @param isPlatformPermissionGroup Whether this is a platform permission group 176 * @param specialLocationGrant Whether this is a special location package 177 * @param specialFixedStorageGrant Whether this is a special storage grant 178 */ 179 data class AppPermSubGroup 180 internal constructor( 181 private val permissions: Map<String, LightPermission>, 182 private val packageInfo: LightPackageInfo, 183 private val isPlatformPermissionGroup: Boolean, 184 private val specialLocationGrant: Boolean?, 185 private val specialFixedStorageGrant: Boolean 186 ) { 187 /** Whether any of this App Permission SubGroup's permissions are granted */ 188 val isGranted = 189 specialLocationGrant 190 ?: specialFixedStorageGrant || permissions.any { 191 val mayGrantByPlatformOrSystem = 192 !isPlatformPermissionGroup || it.value.isPlatformOrSystem 193 it.value.isGranted && mayGrantByPlatformOrSystem 194 } 195 196 /** 197 * Whether this App Permission SubGroup should be treated as granted. This means either: 198 * 1) At least one permission was granted excluding auto-granted permissions (i.e., granted 199 * during install time with flag RevokeWhenRequested.) Or, 200 * 2) All permissions were auto-granted (all permissions are all granted and all 201 * RevokeWhenRequested.) 202 */ 203 val allowFullGroupGrant = 204 specialLocationGrant 205 ?: (permissions.any { 206 val mayGrantByPlatformOrSystem = 207 !isPlatformPermissionGroup || it.value.isPlatformOrSystem 208 it.value.allowFullGroupGrant && mayGrantByPlatformOrSystem 209 } || permissions.all { it.value.isGranted && it.value.isRevokeWhenRequested }) 210 211 /** Whether any of this App Permission SubGroup's permissions are granted by default */ 212 val isGrantedByDefault = permissions.any { it.value.isGrantedByDefault } 213 214 /** 215 * Whether at least one of this App Permission SubGroup's permissions is one-time and none 216 * of the granted permissions are not one-time. 217 */ 218 val isOneTime = 219 permissions.any { it.value.isOneTime } && 220 permissions.none { it.value.isGranted && !it.value.isOneTime } 221 222 /** 223 * Whether any of this App Permission Subgroup's foreground permissions are fixed by policy 224 */ 225 val isPolicyFixed = permissions.any { it.value.isPolicyFixed } 226 227 /** Whether any of this App Permission Subgroup's permissions are fixed by the system */ 228 val isSystemFixed = permissions.any { it.value.isSystemFixed } || specialFixedStorageGrant 229 230 /** Whether any of this App Permission Subgroup's permissions are fixed by the user */ 231 val isUserFixed = permissions.any { it.value.isUserFixed } 232 233 /** Whether any of this App Permission Subgroup's permissions are set by the user */ 234 val isUserSet = permissions.any { it.value.isUserSet } 235 236 /** whether review is required or not for the permission group */ 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 /** Whether or not any permissions in this App Permission Subgroup can be granted */ 249 val isGrantable = 250 (!packageInfo.isInstantApp || hasInstantPerm) && 251 (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntimePerm) 252 } 253 } 254