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 }