1 /*
2  * Copyright (C) 2010 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 package com.android.providers.contacts;
17 
18 import android.content.Context;
19 import android.content.Intent;
20 import android.content.pm.ApplicationInfo;
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.content.pm.ProviderInfo;
24 import android.content.pm.ResolveInfo;
25 import android.content.res.Resources;
26 import android.os.Binder;
27 import android.os.UserHandle;
28 import android.test.mock.MockPackageManager;
29 
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 
34 /**
35  * Mock {@link PackageManager} that knows about a specific set of packages
36  * to help test security models. Because {@link Binder#getCallingUid()}
37  * can't be mocked, you'll have to find your mock-UID manually using your
38  * {@link Context#getPackageName()}.
39  */
40 public class ContactsMockPackageManager extends MockPackageManager {
41 
42     private final Context mRealContext;
43 
44     private final HashMap<Integer, String> mForward = new HashMap<Integer, String>();
45     private final HashMap<String, Integer> mReverse = new HashMap<String, Integer>();
46     private List<PackageInfo> mPackages;
47 
ContactsMockPackageManager(Context realContext)48     public ContactsMockPackageManager(Context realContext) {
49         mRealContext = realContext;
50     }
51 
52     /**
53      * Add a UID-to-package mapping, which is then stored internally.
54      */
addPackage(int packageUid, String packageName)55     public void addPackage(int packageUid, String packageName) {
56         mForward.put(packageUid, packageName);
57         mReverse.put(packageName, packageUid);
58     }
59 
removePackage(int packageUid)60     public void removePackage(int packageUid) {
61         final String packageName = mForward.remove(packageUid);
62         if (packageName != null) {
63             mReverse.remove(packageName);
64         }
65     }
66 
67     @Override
getNameForUid(int uid)68     public String getNameForUid(int uid) {
69         return "name-for-uid";
70     }
71 
72     @Override
getPackagesForUid(int uid)73     public String[] getPackagesForUid(int uid) {
74         final String packageName = mForward.get(uid);
75         if (packageName != null) {
76             return new String[] {packageName};
77         } else if (mPackages != null) {
78             return new String[] { mPackages.get(0).packageName };
79         } else {
80             return new String[] {};
81         }
82     }
83 
84     @Override
getApplicationInfo(String packageName, int flags)85     public ApplicationInfo getApplicationInfo(String packageName, int flags)
86             throws NameNotFoundException {
87         ApplicationInfo info = new ApplicationInfo();
88         Integer uid = mReverse.get(packageName);
89         if (uid == null) {
90             throw new NameNotFoundException();
91         }
92         info.uid = (uid != null) ? uid : -1;
93         info.flags = ApplicationInfo.FLAG_INSTALLED;
94         return info;
95     }
96 
setInstalledPackages(List<PackageInfo> packages)97     public void setInstalledPackages(List<PackageInfo> packages) {
98         this.mPackages = packages;
99     }
100 
101     @Override
getInstalledPackages(int flags)102     public List<PackageInfo> getInstalledPackages(int flags) {
103         return mPackages;
104     }
105 
106     @Override
getPackageInfo(String packageName, int flags)107     public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
108         for (PackageInfo info : mPackages) {
109             if (info.packageName.equals(packageName)) {
110                 return info;
111             }
112         }
113         throw new NameNotFoundException();
114     }
115 
116     @Override
queryBroadcastReceivers(Intent intent, int flags)117     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
118         return new ArrayList<ResolveInfo>();
119     }
120 
121     @Override
getResourcesForApplication(String appPackageName)122     public Resources getResourcesForApplication(String appPackageName) {
123         if (mRealContext.getPackageName().equals(appPackageName)) {
124             return mRealContext.getResources();
125         }
126         return new ContactsMockResources();
127     }
128 
129     @Override
queryContentProviders(String processName, int uid, int flags, String metaDataKey)130     public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags,
131             String metaDataKey) {
132         final List<ProviderInfo> ret = new ArrayList<>();
133         final List<PackageInfo> packages = getInstalledPackages(flags);
134         if (packages == null) {
135             return ret;
136         }
137         for (PackageInfo pkg : packages) {
138             if (pkg.providers == null) {
139                 continue;
140             }
141             for (ProviderInfo proi : pkg.providers) {
142                 if (metaDataKey == null) {
143                     ret.add(proi);
144                 } else {
145                     if (proi.metaData != null && proi.metaData.containsKey(metaDataKey)) {
146                         ret.add(proi);
147                     }
148                 }
149             }
150         }
151         return ret;
152     }
153 
154     @Override
queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags, UserHandle user)155     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags,
156             UserHandle user) {
157         return new ArrayList<>();
158     }
159 
160     @Override
getPackageUid(String packageName, int flags)161     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
162         return 123;
163     }
164 
165     @Override
isPackageStopped(String packageName)166     public boolean isPackageStopped(String packageName) throws NameNotFoundException {
167         PackageInfo packageInfo = getPackageInfo(packageName, 0);
168         return packageInfo.applicationInfo != null
169                 && ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0);
170     }
171 }
172