• 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 @file:Suppress("DEPRECATION")
17 
18 package com.android.permissioncontroller.permission.model.livedatatypes
19 
20 import android.app.Application
21 import android.content.pm.ApplicationInfo
22 import android.content.pm.Attribution
23 import android.content.pm.PackageInfo
24 import android.content.pm.PackageManager
25 import android.os.UserHandle
26 import android.util.Log
27 import com.android.modules.utils.build.SdkLevel
28 import com.android.permissioncontroller.permission.utils.ContextCompat
29 import com.android.permissioncontroller.permission.utils.Utils
30 
31 /**
32  * A lighter version of the system's PackageInfo class, containing select information about the
33  * package.
34  *
35  * @param packageName The name of the packages
36  * @param permissions The list of LightPermInfos representing the permissions this package defines
37  * @param requestedPermissions The names of the permissions this package requests
38  * @param requestedPermissionsFlags The grant state of the permissions this package requests
39  * @param uid The UID of this package
40  * @param targetSdkVersion The target SDK of this package
41  * @param isInstantApp Whether or not this package is an instant app
42  * @param enabled Whether or not this package is enabled.
43  */
44 data class LightPackageInfo(
45     val packageName: String,
46     val permissions: List<LightPermInfo>,
47     val requestedPermissions: List<String>,
48     var requestedPermissionsFlags: List<Int>,
49     val uid: Int,
50     val targetSdkVersion: Int,
51     val isInstantApp: Boolean,
52     val enabled: Boolean,
53     val appFlags: Int,
54     val firstInstallTime: Long,
55     val lastUpdateTime: Long,
56     val areAttributionsUserVisible: Boolean,
57     val attributionTagsToLabels: Map<String, Int>,
58     var deviceId: Int
59 ) {
60     constructor(
61         pI: PackageInfo
62     ) : this(
63         pI.packageName,
64         pI.permissions?.map { perm ->
65             LightPermInfo(perm, pI.applicationInfo!!.flags and ApplicationInfo.FLAG_SYSTEM != 0)
66         } ?: emptyList(),
67         pI.requestedPermissions?.toList() ?: emptyList(),
68         pI.requestedPermissionsFlags?.toList() ?: emptyList(),
69         pI.applicationInfo!!.uid,
70         pI.applicationInfo!!.targetSdkVersion,
71         pI.applicationInfo!!.isInstantApp,
72         pI.applicationInfo!!.enabled,
73         pI.applicationInfo!!.flags,
74         pI.firstInstallTime,
75         pI.lastUpdateTime,
76         if (SdkLevel.isAtLeastS()) pI.applicationInfo!!.areAttributionsUserVisible() else false,
77         if (SdkLevel.isAtLeastS()) buildAttributionTagsToLabelsMap(pI.attributions) else emptyMap(),
78         ContextCompat.DEVICE_ID_DEFAULT
79     )
80 
81     constructor(
82         pI: PackageInfo,
83         deviceId: Int,
84         requestedPermissionsFlagsForDevice: List<Int>
85     ) : this(pI) {
86         this.deviceId = deviceId
87         this.requestedPermissionsFlags = requestedPermissionsFlagsForDevice
88     }
89 
90     /** Permissions which are granted according to the [requestedPermissionsFlags] */
91     val grantedPermissions: List<String>
92         get() {
93             val grantedPermissions = mutableListOf<String>()
94             for (i in 0 until requestedPermissions.size) {
95                 if (
96                     (requestedPermissionsFlags[i] and PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
97                 ) {
98                     grantedPermissions.add(requestedPermissions[i])
99                 }
100             }
101             return grantedPermissions
102         }
103 
104     /**
105      * Gets the ApplicationInfo for this package from the system. Can be expensive if called too
106      * often.
107      *
108      * @param app The current application, which will be used to get the ApplicationInfo
109      * @return The ApplicationInfo corresponding to this package, with this UID, or null, if no such
110      *   package exists
111      */
112     fun getApplicationInfo(app: Application): ApplicationInfo? {
113         try {
114             val userContext = Utils.getUserContext(app, UserHandle.getUserHandleForUid(uid))
115             return userContext.packageManager.getApplicationInfo(packageName, 0)
116         } catch (e: PackageManager.NameNotFoundException) {}
117         return null
118     }
119 
120     /**
121      * Gets the PackageInfo for this package from the system. Can be expensive if called too often.
122      *
123      * @param app The current application, which will be used to get the PackageInfo
124      * @return The PackageInfo corresponding to this package, with this UID, or null, if no such
125      *   package exists
126      */
127     fun toPackageInfo(app: Application): PackageInfo? {
128         try {
129             val userContext = Utils.getUserContext(app, UserHandle.getUserHandleForUid(uid))
130             return userContext.packageManager.getPackageInfo(
131                 packageName,
132                 PackageManager.GET_PERMISSIONS
133             )
134         } catch (e: PackageManager.NameNotFoundException) {
135             Log.e(
136                 LightPackageInfo::class.java.simpleName,
137                 "Failed to get real package info for $packageName, $uid",
138                 e
139             )
140         }
141         return null
142     }
143 
144     /** Companion object for [LightPackageInfo]. */
145     companion object {
146         /** Creates a mapping of attribution tag to labels from the provided attributions. */
147         fun buildAttributionTagsToLabelsMap(attributions: Array<Attribution>?): Map<String, Int> {
148             val attributionTagToLabel = mutableMapOf<String, Int>()
149             attributions?.forEach { attributionTagToLabel[it.tag] = it.label }
150 
151             return attributionTagToLabel.toMap()
152         }
153     }
154 }
155