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