1 /*
2  * Copyright (C) 2021 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.bedstead.nene.packages;
18 
19 import static android.content.pm.PackageManager.GET_PERMISSIONS;
20 
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.util.Log;
24 
25 import com.android.bedstead.nene.TestApis;
26 import com.android.bedstead.nene.users.UserReference;
27 
28 import java.util.Arrays;
29 import java.util.HashSet;
30 import java.util.Map;
31 import java.util.Set;
32 
33 /**
34  * Resolved information about a package on the device.
35  */
36 public class Package extends PackageReference {
37 
38     private static final String LOG_TAG = "Package";
39     private final PackageManager mPackageManager;
40 
41     static final class MutablePackage {
42         String mPackageName;
43         Map<UserReference, MutableUserPackage> mInstalledOnUsers;
44         Set<String> mInstallPermissions;
45     }
46 
47     static final class MutableUserPackage {
48         Set<String> mGrantedPermissions;
49 
50         @Override
toString()51         public String toString() {
52             return "UserPackage{grantedPermissions=" + mGrantedPermissions + "}";
53         }
54     }
55 
56     private final MutablePackage mMutablePackage;
57     private final Set<String> mRequestedPermissions;
58 
Package(TestApis testApis, MutablePackage mutablePackage)59     Package(TestApis testApis, MutablePackage mutablePackage) {
60         super(testApis, mutablePackage.mPackageName);
61         mMutablePackage = mutablePackage;
62         mRequestedPermissions = new HashSet<>();
63         mPackageManager = testApis.context().instrumentedContext().getPackageManager();
64 
65         try {
66             PackageInfo packageInfo = mPackageManager.getPackageInfo(
67                     mMutablePackage.mPackageName, /* flags= */ GET_PERMISSIONS);
68             if (packageInfo.requestedPermissions != null) {
69                 mRequestedPermissions.addAll(Arrays.asList(packageInfo.requestedPermissions));
70             }
71         } catch (PackageManager.NameNotFoundException e) {
72             // This happens frequently and is not useful to log
73             // TODO(scottjonathan): Figure out why we get this for packages which should exist
74         }
75     }
76 
77     /** Get {@link UserReference}s who have this {@link Package} installed. */
installedOnUsers()78     public Set<UserReference> installedOnUsers() {
79         return mMutablePackage.mInstalledOnUsers.keySet();
80     }
81 
82     /**
83      * Get all permissions granted to this package on the given user.
84      *
85      * <p>This will also include permissions which are granted for all users.
86      */
grantedPermissions(UserReference user)87     public Set<String> grantedPermissions(UserReference user) {
88         MutableUserPackage userPackage = mMutablePackage.mInstalledOnUsers.get(user);
89         if (userPackage == null) {
90             return new HashSet<>();
91         }
92 
93         Set<String> mergedPermissions = new HashSet<>();
94         mergedPermissions.addAll(mMutablePackage.mInstallPermissions);
95         mergedPermissions.addAll(userPackage.mGrantedPermissions);
96 
97         return mergedPermissions;
98     }
99 
100     /**
101      * Get all permissions requested by this package.
102      */
requestedPermissions()103     public Set<String> requestedPermissions() {
104         return mRequestedPermissions;
105     }
106 
107     @Override
toString()108     public String toString() {
109         StringBuilder stringBuilder = new StringBuilder("Package{");
110         stringBuilder.append("packageName=" + mMutablePackage.mPackageName);
111         stringBuilder.append(", installedOnUsers=" + mMutablePackage.mInstalledOnUsers);
112         stringBuilder.append("}");
113         return stringBuilder.toString();
114     }
115 }
116