• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.internal.telephony;
18 
19 import static org.mockito.ArgumentMatchers.anyString;
20 import static org.mockito.ArgumentMatchers.nullable;
21 import static org.mockito.Mockito.any;
22 import static org.mockito.Mockito.anyInt;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.doReturn;
25 import static org.mockito.Mockito.eq;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.ActivityManager;
31 import android.app.AlarmManager;
32 import android.app.AppOpsManager;
33 import android.app.DownloadManager;
34 import android.app.NotificationManager;
35 import android.app.usage.UsageStatsManager;
36 import android.content.BroadcastReceiver;
37 import android.content.ComponentName;
38 import android.content.ContentProvider;
39 import android.content.ContentResolver;
40 import android.content.ContentValues;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.IntentFilter;
44 import android.content.ServiceConnection;
45 import android.content.SharedPreferences;
46 import android.content.pm.ApplicationInfo;
47 import android.content.pm.PackageInfo;
48 import android.content.pm.PackageManager;
49 import android.content.pm.PackageManager.NameNotFoundException;
50 import android.content.pm.ResolveInfo;
51 import android.content.pm.ServiceInfo;
52 import android.content.res.AssetManager;
53 import android.content.res.Configuration;
54 import android.content.res.Resources;
55 import android.database.Cursor;
56 import android.database.MatrixCursor;
57 import android.net.ConnectivityManager;
58 import android.net.Network;
59 import android.net.Uri;
60 import android.net.wifi.WifiManager;
61 import android.os.BatteryManager;
62 import android.os.Bundle;
63 import android.os.Handler;
64 import android.os.IInterface;
65 import android.os.PersistableBundle;
66 import android.os.PowerWhitelistManager;
67 import android.os.SystemConfigManager;
68 import android.os.UserHandle;
69 import android.os.UserManager;
70 import android.preference.PreferenceManager;
71 import android.provider.Settings;
72 import android.provider.Telephony.ServiceStateTable;
73 import android.telecom.TelecomManager;
74 import android.telephony.CarrierConfigManager;
75 import android.telephony.SubscriptionManager;
76 import android.telephony.TelephonyManager;
77 import android.telephony.TelephonyRegistryManager;
78 import android.telephony.euicc.EuiccManager;
79 import android.test.mock.MockContentProvider;
80 import android.test.mock.MockContentResolver;
81 import android.test.mock.MockContext;
82 import android.util.Log;
83 
84 import com.google.common.collect.ArrayListMultimap;
85 import com.google.common.collect.Multimap;
86 
87 import org.mockito.MockitoAnnotations;
88 import org.mockito.invocation.InvocationOnMock;
89 import org.mockito.stubbing.Answer;
90 
91 import java.util.ArrayList;
92 import java.util.Arrays;
93 import java.util.Collection;
94 import java.util.HashMap;
95 import java.util.HashSet;
96 import java.util.List;
97 import java.util.Locale;
98 import java.util.Map;
99 
100 /**
101  * Controls a test {@link Context} as would be provided by the Android framework to an
102  * {@code Activity}, {@code Service} or other system-instantiated component.
103  *
104  * Contains Fake<Component> classes like FakeContext for components that require complex and
105  * reusable stubbing. Others can be mocked using Mockito functions in tests or constructor/public
106  * methods of this class.
107  */
108 public class ContextFixture implements TestFixture<Context> {
109     private static final String TAG = "ContextFixture";
110     public static final String PERMISSION_ENABLE_ALL = "android.permission.STUB_PERMISSION";
111 
112     public class FakeContentProvider extends MockContentProvider {
113         private String[] mColumns = {"name", "value"};
114         private HashMap<String, String> mKeyValuePairs = new HashMap<String, String>();
115         private int mNumKeyValuePairs = 0;
116 
117         @Override
delete(Uri uri, String selection, String[] selectionArgs)118         public int delete(Uri uri, String selection, String[] selectionArgs) {
119             return 0;
120         }
121 
122         @Override
insert(Uri uri, ContentValues values)123         public Uri insert(Uri uri, ContentValues values) {
124             Uri newUri = null;
125             if (values != null) {
126                 mKeyValuePairs.put(values.getAsString("name"), values.getAsString("value"));
127                 mNumKeyValuePairs++;
128                 newUri = Uri.withAppendedPath(uri, "" + mNumKeyValuePairs);
129             }
130             logd("insert called, new mNumKeyValuePairs: " + mNumKeyValuePairs + " uri: " + uri +
131                     " newUri: " + newUri);
132             return newUri;
133         }
134 
135         @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)136         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
137                             String sortOrder) {
138             //assuming query will always be of the form 'name = ?'
139             logd("query called, mNumKeyValuePairs: " + mNumKeyValuePairs + " uri: " + uri);
140             if (mKeyValuePairs.containsKey(selectionArgs[0])) {
141                 MatrixCursor cursor = new MatrixCursor(projection);
142                 cursor.addRow(new String[]{mKeyValuePairs.get(selectionArgs[0])});
143                 return cursor;
144             }
145             return null;
146         }
147 
148         @Override
call(String method, String request, Bundle args)149         public Bundle call(String method, String request, Bundle args) {
150             logd("call called, mNumKeyValuePairs: " + mNumKeyValuePairs + " method: " + method +
151                     " request: " + request);
152             switch(method) {
153                 case Settings.CALL_METHOD_GET_GLOBAL:
154                 case Settings.CALL_METHOD_GET_SECURE:
155                 case Settings.CALL_METHOD_GET_SYSTEM:
156                     if (mKeyValuePairs.containsKey(request)) {
157                         Bundle b = new Bundle(1);
158                         b.putCharSequence("value", mKeyValuePairs.get(request));
159                         logd("returning value pair: " + mKeyValuePairs.get(request) + " for " +
160                                 request);
161                         return b;
162                     }
163                     break;
164                 case Settings.CALL_METHOD_PUT_GLOBAL:
165                 case Settings.CALL_METHOD_PUT_SECURE:
166                 case Settings.CALL_METHOD_PUT_SYSTEM:
167                     logd("adding key-value pair: " + request + "-" + (String)args.get("value"));
168                     mKeyValuePairs.put(request, (String)args.get("value"));
169                     mNumKeyValuePairs++;
170                     break;
171             }
172             return null;
173         }
174     }
175 
176     private final HashMap<String, Object> mSystemServices = new HashMap<String, Object>();
177 
setSystemService(String name, Object service)178     public void setSystemService(String name, Object service) {
179         synchronized (mSystemServices) {
180             mSystemServices.put(name, service);
181         }
182     }
183 
184     public class FakeContext extends MockContext {
185         @Override
getPackageManager()186         public PackageManager getPackageManager() {
187             return mPackageManager;
188         }
189 
190         @Override
bindService( Intent serviceIntent, ServiceConnection connection, int flags)191         public boolean bindService(
192                 Intent serviceIntent,
193                 ServiceConnection connection,
194                 int flags) {
195             if (mServiceByServiceConnection.containsKey(connection)) {
196                 throw new RuntimeException("ServiceConnection already bound: " + connection);
197             }
198             IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
199             if (service == null) {
200                 service = mServiceByPackageName.get(serviceIntent.getPackage());
201             }
202             if (service == null) {
203                 throw new RuntimeException(
204                         String.format("ServiceConnection not found for component: %s, package: %s",
205                                 serviceIntent.getComponent(), serviceIntent.getPackage()));
206             }
207             mServiceByServiceConnection.put(connection, service);
208             connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
209             return true;
210         }
211 
212         @Override
unbindService( ServiceConnection connection)213         public void unbindService(
214                 ServiceConnection connection) {
215             IInterface service = mServiceByServiceConnection.remove(connection);
216             if (service == null) {
217                 throw new RuntimeException("ServiceConnection not found: " + connection);
218             }
219             connection.onServiceDisconnected(mComponentNameByService.get(service));
220         }
221 
222         @Override
getSystemService(String name)223         public Object getSystemService(String name) {
224             synchronized (mSystemServices) {
225                 Object service = mSystemServices.get(name);
226                 if (service != null) return service;
227             }
228             switch (name) {
229                 case Context.TELEPHONY_SERVICE:
230                     return mTelephonyManager;
231                 case Context.ACTIVITY_SERVICE:
232                     return mActivityManager;
233                 case Context.APP_OPS_SERVICE:
234                     return mAppOpsManager;
235                 case Context.NOTIFICATION_SERVICE:
236                     return mNotificationManager;
237                 case Context.USER_SERVICE:
238                     return mUserManager;
239                 case Context.CARRIER_CONFIG_SERVICE:
240                     return mCarrierConfigManager;
241                 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
242                     return mSubscriptionManager;
243                 case Context.WIFI_SERVICE:
244                     return mWifiManager;
245                 case Context.ALARM_SERVICE:
246                     return mAlarmManager;
247                 case Context.CONNECTIVITY_SERVICE:
248                     return mConnectivityManager;
249                 case Context.USAGE_STATS_SERVICE:
250                     return mUsageStatManager;
251                 case Context.BATTERY_SERVICE:
252                     return mBatteryManager;
253                 case Context.EUICC_SERVICE:
254                     return mEuiccManager;
255                 case Context.TELECOM_SERVICE:
256                     return mTelecomManager;
257                 case Context.DOWNLOAD_SERVICE:
258                     return mDownloadManager;
259                 case Context.TELEPHONY_REGISTRY_SERVICE:
260                     return mTelephonyRegistryManager;
261                 case Context.SYSTEM_CONFIG_SERVICE:
262                     return mSystemConfigManager;
263                 case Context.BATTERY_STATS_SERVICE:
264                 case Context.DISPLAY_SERVICE:
265                 case Context.POWER_SERVICE:
266                 case Context.PERMISSION_SERVICE:
267                     // These are final classes so cannot be mocked,
268                     // return real services.
269                     return TestApplication.getAppContext().getSystemService(name);
270                 case Context.POWER_WHITELIST_MANAGER:
271                     return mPowerWhitelistManager;
272                 default:
273                     return null;
274             }
275         }
276 
277         @Override
getSystemServiceName(Class<?> serviceClass)278         public String getSystemServiceName(Class<?> serviceClass) {
279             if (serviceClass == SubscriptionManager.class) {
280                 return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
281             } else if (serviceClass == AppOpsManager.class) {
282                 return Context.APP_OPS_SERVICE;
283             } else if (serviceClass == TelecomManager.class) {
284                 return Context.TELECOM_SERVICE;
285             } else if (serviceClass == UserManager.class) {
286                 return Context.USER_SERVICE;
287             } else if (serviceClass == ConnectivityManager.class) {
288                 return Context.CONNECTIVITY_SERVICE;
289             } else if (serviceClass == PowerWhitelistManager.class) {
290                 return Context.POWER_WHITELIST_MANAGER;
291             } else if (serviceClass == SystemConfigManager.class) {
292                 return Context.SYSTEM_CONFIG_SERVICE;
293             } else if (serviceClass == CarrierConfigManager.class){
294                 return Context.CARRIER_CONFIG_SERVICE;
295             }
296             return super.getSystemServiceName(serviceClass);
297         }
298 
299         @Override
getUserId()300         public int getUserId() {
301             return 0;
302         }
303 
304         @Override
getAssets()305         public AssetManager getAssets() {
306             return mAssetManager;
307         }
308 
309         @Override
getResources()310         public Resources getResources() {
311             return mResources;
312         }
313 
314         @Override
getApplicationInfo()315         public ApplicationInfo getApplicationInfo() {
316             return mApplicationInfo;
317         }
318 
319         @Override
getOpPackageName()320         public String getOpPackageName() {
321             return "com.android.internal.telephony";
322         }
323 
324         @Override
getContentResolver()325         public ContentResolver getContentResolver() {
326             return mContentResolver;
327         }
328 
329         @Override
getTheme()330         public Resources.Theme getTheme() {
331             return null;
332         }
333 
334         @Override
unregisterReceiver(BroadcastReceiver receiver)335         public void unregisterReceiver(BroadcastReceiver receiver) {
336         }
337 
338         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)339         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
340             return registerReceiverFakeImpl(receiver, filter);
341         }
342 
343         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)344         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
345                 String broadcastPermission, Handler scheduler) {
346             return registerReceiverFakeImpl(receiver, filter);
347         }
348 
349         @Override
registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)350         public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
351                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
352             return registerReceiverFakeImpl(receiver, filter);
353         }
354 
355         @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)356         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
357                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
358             return registerReceiverFakeImpl(receiver, filter);
359         }
360 
registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter)361         private Intent registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter) {
362             Intent result = null;
363             synchronized (mBroadcastReceiversByAction) {
364                 for (int i = 0 ; i < filter.countActions() ; i++) {
365                     mBroadcastReceiversByAction.put(filter.getAction(i), receiver);
366                     if (result == null) {
367                         result = mStickyBroadcastByAction.get(filter.getAction(i));
368                     }
369                 }
370             }
371 
372             return result;
373         }
374 
375         @Override
sendBroadcast(Intent intent)376         public void sendBroadcast(Intent intent) {
377             logd("sendBroadcast called for " + intent.getAction());
378             synchronized (mBroadcastReceiversByAction) {
379                 for (BroadcastReceiver broadcastReceiver :
380                         mBroadcastReceiversByAction.get(intent.getAction())) {
381                     broadcastReceiver.onReceive(mContext, intent);
382                 }
383             }
384         }
385 
386         @Override
sendBroadcast(Intent intent, String receiverPermission)387         public void sendBroadcast(Intent intent, String receiverPermission) {
388             logd("sendBroadcast called for " + intent.getAction());
389             sendBroadcast(intent);
390         }
391 
392         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission)393         public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
394             logd("sendOrderedBroadcast called for " + intent.getAction());
395             sendBroadcast(intent);
396         }
397 
398         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)399         public void sendOrderedBroadcast(Intent intent, String receiverPermission,
400                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
401                 String initialData, Bundle initialExtras) {
402             sendOrderedBroadcast(intent, receiverPermission);
403             if (resultReceiver != null) {
404                 synchronized (mOrderedBroadcastReceivers) {
405                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
406                 }
407             }
408         }
409 
410         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)411         public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
412                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
413                 String initialData, Bundle initialExtras) {
414             mLastBroadcastOptions = options;
415             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
416                     initialCode, initialData, initialExtras);
417         }
418 
419         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)420         public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
421                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
422                 String initialData, Bundle initialExtras) {
423             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
424                     initialCode, initialData, initialExtras);
425         }
426 
427         @Override
sendBroadcastAsUser(Intent intent, UserHandle user)428         public void sendBroadcastAsUser(Intent intent, UserHandle user) {
429             sendBroadcast(intent);
430         }
431 
432         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)433         public void sendBroadcastAsUser(Intent intent, UserHandle user,
434                                         String receiverPermission) {
435             sendBroadcast(intent);
436         }
437 
438         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)439         public void sendBroadcastAsUser(Intent intent, UserHandle user,
440                                         String receiverPermission, int appOp) {
441             sendBroadcast(intent);
442         }
443 
444         @Override
createContextAsUser(UserHandle user, int flags)445         public Context createContextAsUser(UserHandle user, int flags) {
446             return this;
447         }
448 
449         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)450         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
451                 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
452                 int initialCode, String initialData, Bundle initialExtras) {
453             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
454             sendBroadcast(intent);
455             if (resultReceiver != null) {
456                 synchronized (mOrderedBroadcastReceivers) {
457                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
458                 }
459             }
460         }
461 
462         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)463         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
464                 String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
465                 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
466             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
467             sendBroadcast(intent);
468             if (resultReceiver != null) {
469                 synchronized (mOrderedBroadcastReceivers) {
470                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
471                 }
472             }
473         }
474 
475         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)476         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
477                 String receiverPermission, int appOp, Bundle options,
478                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
479                 String initialData, Bundle initialExtras) {
480             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
481             mLastBroadcastOptions = options;
482             sendBroadcast(intent);
483             if (resultReceiver != null) {
484                 synchronized (mOrderedBroadcastReceivers) {
485                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
486                 }
487             }
488         }
489 
490         @Override
sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, String initialData, Bundle initialExtras, Bundle options)491         public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
492                 String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
493                 String initialData, Bundle initialExtras, Bundle options) {
494             logd("sendOrderedBroadcast called for " + intent.getAction());
495             mLastBroadcastOptions = options;
496             sendBroadcast(intent);
497             if (resultReceiver != null) {
498                 synchronized (mOrderedBroadcastReceivers) {
499                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
500                 }
501             }
502         }
503 
504         @Override
sendStickyBroadcast(Intent intent)505         public void sendStickyBroadcast(Intent intent) {
506             logd("sendStickyBroadcast called for " + intent.getAction());
507             synchronized (mBroadcastReceiversByAction) {
508                 sendBroadcast(intent);
509                 mStickyBroadcastByAction.put(intent.getAction(), intent);
510             }
511         }
512 
513         @Override
sendStickyBroadcastAsUser(Intent intent, UserHandle ignored)514         public void sendStickyBroadcastAsUser(Intent intent, UserHandle ignored) {
515             logd("sendStickyBroadcastAsUser called for " + intent.getAction());
516             sendStickyBroadcast(intent);
517         }
518 
519         @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)520         public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
521                 throws PackageManager.NameNotFoundException {
522             return this;
523         }
524 
525         @Override
enforceCallingOrSelfPermission(String permission, String message)526         public void enforceCallingOrSelfPermission(String permission, String message) {
527             if (mPermissionTable.contains(permission)
528                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
529                 return;
530             }
531             logd("requested permission: " + permission + " got denied");
532             throw new SecurityException(permission + " denied: " + message);
533         }
534 
535         @Override
enforcePermission(String permission, int pid, int uid, String message)536         public void enforcePermission(String permission, int pid, int uid, String message) {
537             enforceCallingOrSelfPermission(permission, message);
538         }
539 
540         @Override
checkCallingOrSelfPermission(String permission)541         public int checkCallingOrSelfPermission(String permission) {
542             if (mPermissionTable.contains(permission)
543                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
544                 logd("checkCallingOrSelfPermission: " + permission + " return GRANTED");
545                 return PackageManager.PERMISSION_GRANTED;
546             } else {
547                 logd("checkCallingOrSelfPermission: " + permission + " return DENIED");
548                 return PackageManager.PERMISSION_DENIED;
549             }
550         }
551 
552         @Override
checkPermission(String permission, int pid, int uid)553         public int checkPermission(String permission, int pid, int uid) {
554             return checkCallingOrSelfPermission(permission);
555         }
556 
557         @Override
getSharedPreferences(String name, int mode)558         public SharedPreferences getSharedPreferences(String name, int mode) {
559             return mSharedPreferences;
560         }
561 
562         @Override
getPackageName()563         public String getPackageName() {
564             return "com.android.internal.telephony";
565         }
566 
567         @Override
getApplicationContext()568         public Context getApplicationContext() {
569             return null;
570         }
571 
572         @Override
startActivity(Intent intent)573         public void startActivity(Intent intent) {}
574     }
575 
576     private final Multimap<String, ComponentName> mComponentNamesByAction =
577             ArrayListMultimap.create();
578     private final Map<ComponentName, IInterface> mServiceByComponentName =
579             new HashMap<ComponentName, IInterface>();
580     private final Map<String, IInterface> mServiceByPackageName =
581             new HashMap<String, IInterface>();
582     private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
583             new HashMap<ComponentName, ServiceInfo>();
584     private final Map<ComponentName, IntentFilter> mIntentFilterByComponentName = new HashMap<>();
585     private final Map<IInterface, ComponentName> mComponentNameByService =
586             new HashMap<IInterface, ComponentName>();
587     private final Map<ServiceConnection, IInterface> mServiceByServiceConnection =
588             new HashMap<ServiceConnection, IInterface>();
589     private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction =
590             ArrayListMultimap.create();
591     private final HashMap<String, Intent> mStickyBroadcastByAction =
592             new HashMap<String, Intent>();
593     private final Multimap<Intent, BroadcastReceiver> mOrderedBroadcastReceivers =
594             ArrayListMultimap.create();
595     private final HashSet<String> mPermissionTable = new HashSet<>();
596     private final HashSet<String> mSystemFeatures = new HashSet<>();
597     private Bundle mLastBroadcastOptions;
598 
599 
600     // The application context is the most important object this class provides to the system
601     // under test.
602     private final Context mContext = spy(new FakeContext());
603 
604     // We then create a spy on the application context allowing standard Mockito-style
605     // when(...) logic to be used to add specific little responses where needed.
606 
607     private final Resources mResources = mock(Resources.class);
608     private final ApplicationInfo mApplicationInfo = mock(ApplicationInfo.class);
609     private final PackageManager mPackageManager = mock(PackageManager.class);
610     private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
611     private final ActivityManager mActivityManager = mock(ActivityManager.class);
612     private final DownloadManager mDownloadManager = mock(DownloadManager.class);
613     private final AppOpsManager mAppOpsManager = mock(AppOpsManager.class);
614     private final NotificationManager mNotificationManager = mock(NotificationManager.class);
615     private final UserManager mUserManager = mock(UserManager.class);
616     private final CarrierConfigManager mCarrierConfigManager = mock(CarrierConfigManager.class);
617     private final SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
618     private final AlarmManager mAlarmManager = mock(AlarmManager.class);
619     private final AssetManager mAssetManager = new AssetManager();
620     private final ConnectivityManager mConnectivityManager = mock(ConnectivityManager.class);
621     private final UsageStatsManager mUsageStatManager = null;
622     private final WifiManager mWifiManager = mock(WifiManager.class);
623     private final BatteryManager mBatteryManager = mock(BatteryManager.class);
624     private final EuiccManager mEuiccManager = mock(EuiccManager.class);
625     private final TelecomManager mTelecomManager = mock(TelecomManager.class);
626     private final PackageInfo mPackageInfo = mock(PackageInfo.class);
627     private final TelephonyRegistryManager mTelephonyRegistryManager =
628         mock(TelephonyRegistryManager.class);
629     private final SystemConfigManager mSystemConfigManager = mock(SystemConfigManager.class);
630     private final PowerWhitelistManager mPowerWhitelistManager = mock(PowerWhitelistManager.class);
631 
632     private final ContentProvider mContentProvider = spy(new FakeContentProvider());
633 
634     private final Configuration mConfiguration = new Configuration();
635     private final SharedPreferences mSharedPreferences = PreferenceManager
636             .getDefaultSharedPreferences(TestApplication.getAppContext());
637     private final MockContentResolver mContentResolver = new MockContentResolver();
638     private final PersistableBundle mBundle = new PersistableBundle();
639 
ContextFixture()640     public ContextFixture() {
641         MockitoAnnotations.initMocks(this);
642 
643         doAnswer(new Answer<List<ResolveInfo>>() {
644             @Override
645             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
646                 return doQueryIntentServices(
647                         (Intent) invocation.getArguments()[0],
648                         (Integer) invocation.getArguments()[1]);
649             }
650         }).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
651 
652         doAnswer(new Answer<List<ResolveInfo>>() {
653             @Override
654             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
655                 return doQueryIntentServices(
656                         (Intent) invocation.getArguments()[0],
657                         (Integer) invocation.getArguments()[1]);
658             }
659         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), any());
660 
661         try {
662             doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(nullable(String.class),
663                     anyInt());
664         } catch (NameNotFoundException e) {
665         }
666 
667         doAnswer((Answer<Boolean>)
668                 invocation -> mSystemFeatures.contains((String) invocation.getArgument(0)))
669                 .when(mPackageManager).hasSystemFeature(any());
670 
671         try {
672             doReturn(mResources).when(mPackageManager).getResourcesForApplication(anyString());
673         } catch (NameNotFoundException ex) {
674             Log.d(TAG, "NameNotFoundException: " + ex);
675         }
676 
677         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
678         //doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt());
679         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
680 
681         doReturn(mock(Network.class)).when(mConnectivityManager).registerNetworkAgent(
682                 any(), any(), any(), any(), anyInt(), any(), anyInt());
683 
684         doReturn(true).when(mEuiccManager).isEnabled();
685 
686         mConfiguration.locale = Locale.US;
687         doReturn(mConfiguration).when(mResources).getConfiguration();
688 
689         mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider);
690         // Settings caches the provider after first get/set call, this is needed to make sure
691         // Settings is using mContentProvider as the cached provider across all tests.
692         Settings.Global.getInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
693         mContentResolver.addProvider(ServiceStateTable.AUTHORITY, mContentProvider);
694         mPermissionTable.add(PERMISSION_ENABLE_ALL);
695     }
696 
697     @Override
getTestDouble()698     public Context getTestDouble() {
699         return mContext;
700     }
701 
putResource(int id, final String value)702     public void putResource(int id, final String value) {
703         when(mResources.getText(eq(id))).thenReturn(value);
704         when(mResources.getString(eq(id))).thenReturn(value);
705         when(mResources.getString(eq(id), any())).thenAnswer(new Answer<String>() {
706             @Override
707             public String answer(InvocationOnMock invocation) {
708                 Object[] args = invocation.getArguments();
709                 return String.format(value, Arrays.copyOfRange(args, 1, args.length));
710             }
711         });
712     }
713 
putBooleanResource(int id, boolean value)714     public void putBooleanResource(int id, boolean value) {
715         when(mResources.getBoolean(eq(id))).thenReturn(value);
716     }
717 
putStringArrayResource(int id, String[] values)718     public void putStringArrayResource(int id, String[] values) {
719         doReturn(values).when(mResources).getStringArray(eq(id));
720     }
721 
putIntArrayResource(int id, int[] values)722     public void putIntArrayResource(int id, int[] values) {
723         doReturn(values).when(mResources).getIntArray(eq(id));
724     }
725 
putIntResource(int id, int value)726     public void putIntResource(int id, int value) {
727         doReturn(value).when(mResources).getInteger(eq(id));
728     }
729 
getCarrierConfigBundle()730     public PersistableBundle getCarrierConfigBundle() {
731         return mBundle;
732     }
733 
addService(String action, ComponentName name, String packageName, IInterface service, ServiceInfo serviceInfo)734     public void addService(String action, ComponentName name, String packageName,
735                            IInterface service, ServiceInfo serviceInfo) {
736         addService(action, name, packageName, service, serviceInfo, null /* filter */);
737     }
738 
addService(String action, ComponentName name, String packageName, IInterface service, ServiceInfo serviceInfo, IntentFilter filter)739     public void addService(String action, ComponentName name, String packageName,
740             IInterface service, ServiceInfo serviceInfo, IntentFilter filter) {
741         mComponentNamesByAction.put(action, name);
742         mServiceInfoByComponentName.put(name, serviceInfo);
743         mIntentFilterByComponentName.put(name, filter);
744         mServiceByComponentName.put(name, service);
745         mServiceByPackageName.put(packageName, service);
746         mComponentNameByService.put(service, name);
747     }
748 
doQueryIntentServices(Intent intent, int flags)749     private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) {
750         List<ResolveInfo> result = new ArrayList<ResolveInfo>();
751         for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
752             ResolveInfo resolveInfo = new ResolveInfo();
753             resolveInfo.serviceInfo = mServiceInfoByComponentName.get(componentName);
754             resolveInfo.filter = mIntentFilterByComponentName.get(componentName);
755             result.add(resolveInfo);
756         }
757         return result;
758     }
759 
sendBroadcastToOrderedBroadcastReceivers()760     public void sendBroadcastToOrderedBroadcastReceivers() {
761         synchronized (mOrderedBroadcastReceivers) {
762             // having a map separate from mOrderedBroadcastReceivers is helpful here as onReceive()
763             // call within the loop may lead to sendOrderedBroadcast() which can add to
764             // mOrderedBroadcastReceivers
765             Collection<Map.Entry<Intent, BroadcastReceiver>> map =
766                     mOrderedBroadcastReceivers.entries();
767             for (Map.Entry<Intent, BroadcastReceiver> entry : map) {
768                 entry.getValue().onReceive(mContext, entry.getKey());
769                 mOrderedBroadcastReceivers.remove(entry.getKey(), entry.getValue());
770             }
771         }
772     }
773 
addCallingOrSelfPermission(String permission)774     public void addCallingOrSelfPermission(String permission) {
775         synchronized (mPermissionTable) {
776             if (mPermissionTable != null && permission != null) {
777                 mPermissionTable.remove(PERMISSION_ENABLE_ALL);
778                 mPermissionTable.add(permission);
779             }
780         }
781     }
782 
removeCallingOrSelfPermission(String permission)783     public void removeCallingOrSelfPermission(String permission) {
784         synchronized (mPermissionTable) {
785             if (mPermissionTable != null && permission != null) {
786                 mPermissionTable.remove(permission);
787             }
788         }
789     }
790 
addSystemFeature(String feature)791     public void addSystemFeature(String feature) {
792         mSystemFeatures.add(feature);
793     }
794 
getLastBroadcastOptions()795     public Bundle getLastBroadcastOptions() {
796         return mLastBroadcastOptions;
797     }
798 
logd(String s)799     private static void logd(String s) {
800         Log.d(TAG, s);
801     }
802 }
803