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