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