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