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