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.app.Application
20 import android.content.pm.ApplicationInfo
21 import android.content.pm.PackageInfo
22 import android.content.pm.PackageManager
23 import android.os.UserHandle
24 import com.android.permissioncontroller.permission.utils.Utils
25 
26 /**
27  * A lighter version of the system's PackageInfo class, containing select information about the
28  * package.
29  *
30  * @param packageName The name of the packages
31  * @param permissions The list of LightPermInfos representing the permissions this package defines
32  * @param requestedPermissions The names of the permissions this package requests
33  * @param requestedPermissionsFlags The grant state of the permissions this package requests
34  * @param uid The UID of this package
35  * @param targetSdkVersion The target SDK of this package
36  * @param isInstantApp Whether or not this package is an instant app
37  * @param enabled Whether or not this package is enabled.
38  */
39 data class LightPackageInfo(
40     val packageName: String,
41     val permissions: List<LightPermInfo>,
42     val requestedPermissions: List<String>,
43     val requestedPermissionsFlags: List<Int>,
44     val uid: Int,
45     val targetSdkVersion: Int,
46     val isInstantApp: Boolean,
47     val enabled: Boolean,
48     val appFlags: Int,
49     val firstInstallTime: Long
50 ) {
51     constructor(pI: PackageInfo) : this(pI.packageName,
52         pI.permissions?.map { perm -> LightPermInfo(perm) } ?: emptyList(),
53         pI.requestedPermissions?.toList() ?: emptyList(),
54         pI.requestedPermissionsFlags?.toList() ?: emptyList(),
55         pI.applicationInfo.uid, pI.applicationInfo.targetSdkVersion,
56         pI.applicationInfo.isInstantApp, pI.applicationInfo.enabled, pI.applicationInfo.flags,
57         pI.firstInstallTime)
58 
59     /**
60      * Permissions which are granted according to the [requestedPermissionsFlags]
61      */
62     val grantedPermissions: List<String> get() {
63         val grantedPermissions = mutableListOf<String>()
64         for (i in 0 until requestedPermissions.size) {
65             if ((requestedPermissionsFlags[i] and PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
66                 grantedPermissions.add(requestedPermissions[i])
67             }
68         }
69         return grantedPermissions
70     }
71 
72     /**
73      * Gets the ApplicationInfo for this package from the system. Can be expensive if called too
74      * often.
75      *
76      * @param app The current application, which will be used to get the ApplicationInfo
77      *
78      * @return The ApplicationInfo corresponding to this package, with this UID, or null, if no
79      * such package exists
80      */
81     fun getApplicationInfo(app: Application): ApplicationInfo? {
82         try {
83             val userContext = Utils.getUserContext(app, UserHandle.getUserHandleForUid(uid))
84             return userContext.packageManager.getApplicationInfo(packageName, 0)
85         } catch (e: PackageManager.NameNotFoundException) {
86         }
87         return null
88     }
89 
90     /**
91      * Gets the PackageInfo for this package from the system. Can be expensive if called too
92      * often.
93      *
94      * @param app The current application, which will be used to get the PackageInfo
95      *
96      * @return The PackageInfo corresponding to this package, with this UID, or null, if no
97      * such package exists
98      */
99     fun toPackageInfo(app: Application): PackageInfo? {
100         try {
101             val userContext = Utils.getUserContext(app, UserHandle.getUserHandleForUid(uid))
102             return userContext.packageManager.getPackageInfo(packageName,
103                 PackageManager.GET_PERMISSIONS)
104         } catch (e: PackageManager.NameNotFoundException) {
105         }
106         return null
107     }
108 }
109