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