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
bindServiceAsUser( Intent serviceIntent, ServiceConnection connection, int flags, UserHandle user)244         public boolean bindServiceAsUser(
245                 Intent serviceIntent,
246                 ServiceConnection connection,
247                 int flags, UserHandle user) {
248             return bindService(serviceIntent, connection, flags);
249         }
250 
251         @Override
unbindService( ServiceConnection connection)252         public void unbindService(
253                 ServiceConnection connection) {
254             IInterface service = mServiceByServiceConnection.remove(connection);
255             if (service != null) {
256                 connection.onServiceDisconnected(mComponentNameByService.get(service));
257             } else {
258                 logd("unbindService: ServiceConnection not found: " + connection);
259             }
260         }
261 
262         @Override
getSystemService(String name)263         public Object getSystemService(String name) {
264             synchronized (mSystemServices) {
265                 Object service = mSystemServices.get(name);
266                 if (service != null) return service;
267             }
268             switch (name) {
269                 case Context.TELEPHONY_SERVICE:
270                     return mTelephonyManager;
271                 case Context.ACTIVITY_SERVICE:
272                     return mActivityManager;
273                 case Context.APP_OPS_SERVICE:
274                     return mAppOpsManager;
275                 case Context.NOTIFICATION_SERVICE:
276                     return mNotificationManager;
277                 case Context.USER_SERVICE:
278                     return mUserManager;
279                 case Context.CARRIER_CONFIG_SERVICE:
280                     return mCarrierConfigManager;
281                 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
282                     return mSubscriptionManager;
283                 case Context.WIFI_SERVICE:
284                     return mWifiManager;
285                 case Context.ALARM_SERVICE:
286                     return mAlarmManager;
287                 case Context.CONNECTIVITY_SERVICE:
288                     return mConnectivityManager;
289                 case Context.USAGE_STATS_SERVICE:
290                     return mUsageStatManager;
291                 case Context.BATTERY_SERVICE:
292                     return mBatteryManager;
293                 case Context.EUICC_SERVICE:
294                     return mEuiccManager;
295                 case Context.TELECOM_SERVICE:
296                     return mTelecomManager;
297                 case Context.DOWNLOAD_SERVICE:
298                     return mDownloadManager;
299                 case Context.TELEPHONY_REGISTRY_SERVICE:
300                     return mTelephonyRegistryManager;
301                 case Context.SYSTEM_CONFIG_SERVICE:
302                     return mSystemConfigManager;
303                 case Context.KEYGUARD_SERVICE:
304                     return mKeyguardManager;
305                 case Context.VCN_MANAGEMENT_SERVICE:
306                     return mVcnManager;
307                 case Context.BATTERY_STATS_SERVICE:
308                 case Context.DISPLAY_SERVICE:
309                 case Context.POWER_SERVICE:
310                 case Context.PERMISSION_SERVICE:
311                 case Context.LEGACY_PERMISSION_SERVICE:
312                     // These are final classes so cannot be mocked,
313                     // return real services.
314                     return TestApplication.getAppContext().getSystemService(name);
315                 case Context.POWER_WHITELIST_MANAGER:
316                     return mPowerWhitelistManager;
317                 case Context.LOCATION_SERVICE:
318                     return mLocationManager;
319                 case Context.NETWORK_POLICY_SERVICE:
320                     return mNetworkPolicyManager;
321                 case Context.TELEPHONY_IMS_SERVICE:
322                     return mImsManager;
323                 case Context.DEVICE_POLICY_SERVICE:
324                     return mDevicePolicyManager;
325                 case Context.DROPBOX_SERVICE:
326                     return mDropBoxManager;
327                 default:
328                     return null;
329             }
330         }
331 
332         @Override
getSystemServiceName(Class<?> serviceClass)333         public String getSystemServiceName(Class<?> serviceClass) {
334             if (serviceClass == SubscriptionManager.class) {
335                 return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
336             } else if (serviceClass == AppOpsManager.class) {
337                 return Context.APP_OPS_SERVICE;
338             } else if (serviceClass == TelecomManager.class) {
339                 return Context.TELECOM_SERVICE;
340             } else if (serviceClass == UserManager.class) {
341                 return Context.USER_SERVICE;
342             } else if (serviceClass == ConnectivityManager.class) {
343                 return Context.CONNECTIVITY_SERVICE;
344             } else if (serviceClass == PowerWhitelistManager.class) {
345                 return Context.POWER_WHITELIST_MANAGER;
346             } else if (serviceClass == SystemConfigManager.class) {
347                 return Context.SYSTEM_CONFIG_SERVICE;
348             } else if (serviceClass == ActivityManager.class) {
349                 return Context.ACTIVITY_SERVICE;
350             } else if (serviceClass == LocationManager.class) {
351                 return Context.LOCATION_SERVICE;
352             } else if (serviceClass == CarrierConfigManager.class) {
353                 return Context.CARRIER_CONFIG_SERVICE;
354             } else if (serviceClass == TelephonyManager.class) {
355                 return Context.TELEPHONY_SERVICE;
356             } else if (serviceClass == UiModeManager.class) {
357                 return Context.UI_MODE_SERVICE;
358             } else if (serviceClass == KeyguardManager.class) {
359                 return Context.KEYGUARD_SERVICE;
360             } else if (serviceClass == VcnManager.class) {
361                 return Context.VCN_MANAGEMENT_SERVICE;
362             } else if (serviceClass == ImsManager.class) {
363                 return Context.TELEPHONY_IMS_SERVICE;
364             } else if (serviceClass == TelephonyRegistryManager.class) {
365                 return Context.TELEPHONY_REGISTRY_SERVICE;
366             } else if (serviceClass == NetworkPolicyManager.class) {
367                 return Context.NETWORK_POLICY_SERVICE;
368             } else if (serviceClass == PowerManager.class) {
369                 return Context.POWER_SERVICE;
370             } else if (serviceClass == EuiccManager.class) {
371                 return Context.EUICC_SERVICE;
372             } else if (serviceClass == AlarmManager.class) {
373                 return Context.ALARM_SERVICE;
374             } else if (serviceClass == DevicePolicyManager.class) {
375                 return Context.DEVICE_POLICY_SERVICE;
376             } else if (serviceClass == NotificationManager.class) {
377                 return Context.NOTIFICATION_SERVICE;
378             } else if (serviceClass == DropBoxManager.class) {
379                 return Context.DROPBOX_SERVICE;
380             }
381             return super.getSystemServiceName(serviceClass);
382         }
383 
384         @Override
getUserId()385         public int getUserId() {
386             return 0;
387         }
388 
389         @Override
getAssets()390         public AssetManager getAssets() {
391             return mAssetManager;
392         }
393 
394         @Override
getResources()395         public Resources getResources() {
396             return mResources;
397         }
398 
399         @Override
createConfigurationContext(Configuration overrideConfiguration)400         public Context createConfigurationContext(Configuration overrideConfiguration) {
401             return spy(new FakeContext());
402         }
403 
404         @Override
getApplicationInfo()405         public ApplicationInfo getApplicationInfo() {
406             return mApplicationInfo;
407         }
408 
409         @Override
getOpPackageName()410         public String getOpPackageName() {
411             return "com.android.internal.telephony";
412         }
413 
414         @Override
getContentResolver()415         public ContentResolver getContentResolver() {
416             return mContentResolver;
417         }
418 
419         @Override
getTheme()420         public Resources.Theme getTheme() {
421             return null;
422         }
423 
424         @Override
unregisterReceiver(BroadcastReceiver receiver)425         public void unregisterReceiver(BroadcastReceiver receiver) {
426         }
427 
428         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)429         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
430             return registerReceiverFakeImpl(receiver, filter);
431         }
432 
433         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)434         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
435                 String broadcastPermission, Handler scheduler) {
436             return registerReceiverFakeImpl(receiver, filter);
437         }
438 
439         @Override
registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)440         public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
441                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
442             return registerReceiverFakeImpl(receiver, filter);
443         }
444 
445         @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)446         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
447                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
448             return registerReceiverFakeImpl(receiver, filter);
449         }
450 
451         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags)452         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
453             return registerReceiverFakeImpl(receiver, filter);
454         }
455 
456         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags)457         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
458                 String broadcastPermission, Handler scheduler, int flags) {
459             return registerReceiverFakeImpl(receiver, filter);
460         }
461 
registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter)462         private Intent registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter) {
463             Intent result = null;
464             synchronized (mBroadcastReceiversByAction) {
465                 for (int i = 0 ; i < filter.countActions() ; i++) {
466                     mBroadcastReceiversByAction.put(filter.getAction(i), receiver);
467                     if (result == null) {
468                         result = mStickyBroadcastByAction.get(filter.getAction(i));
469                     }
470                 }
471             }
472 
473             return result;
474         }
475 
476         @Override
sendBroadcast(Intent intent)477         public void sendBroadcast(Intent intent) {
478             logd("sendBroadcast called for " + intent.getAction());
479             synchronized (mBroadcastReceiversByAction) {
480                 for (BroadcastReceiver broadcastReceiver :
481                         mBroadcastReceiversByAction.get(intent.getAction())) {
482                     broadcastReceiver.onReceive(mContext, intent);
483                 }
484             }
485         }
486 
487         @Override
sendBroadcast(Intent intent, String receiverPermission)488         public void sendBroadcast(Intent intent, String receiverPermission) {
489             logd("sendBroadcast called for " + intent.getAction());
490             sendBroadcast(intent);
491         }
492 
493         @Override
sendBroadcast(Intent intent, String receiverPermission, Bundle initialExtras)494         public void sendBroadcast(Intent intent, String receiverPermission, Bundle initialExtras) {
495             logd("sendBroadcast called for " + intent.getAction());
496             sendBroadcast(intent);
497         }
498 
499         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission)500         public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
501             logd("sendOrderedBroadcast called for " + intent.getAction());
502             sendBroadcast(intent);
503         }
504 
505         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)506         public void sendOrderedBroadcast(Intent intent, String receiverPermission,
507                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
508                 String initialData, Bundle initialExtras) {
509             sendOrderedBroadcast(intent, receiverPermission);
510             if (resultReceiver != null) {
511                 synchronized (mOrderedBroadcastReceivers) {
512                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
513                 }
514             }
515         }
516 
517         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)518         public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
519                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
520                 String initialData, Bundle initialExtras) {
521             mLastBroadcastOptions = options;
522             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
523                     initialCode, initialData, initialExtras);
524         }
525 
526         @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)527         public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
528                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
529                 String initialData, Bundle initialExtras) {
530             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
531                     initialCode, initialData, initialExtras);
532         }
533 
534         @Override
sendBroadcastAsUser(Intent intent, UserHandle user)535         public void sendBroadcastAsUser(Intent intent, UserHandle user) {
536             sendBroadcast(intent);
537         }
538 
539         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)540         public void sendBroadcastAsUser(Intent intent, UserHandle user,
541                                         String receiverPermission) {
542             sendBroadcast(intent);
543         }
544 
545         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)546         public void sendBroadcastAsUser(Intent intent, UserHandle user,
547                                         String receiverPermission, int appOp) {
548             sendBroadcast(intent);
549         }
550 
551         @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, Bundle options)552         public void sendBroadcastAsUser(Intent intent, UserHandle user,
553                 String receiverPermission, Bundle options) {
554             sendBroadcast(intent);
555         }
556 
557         @Override
sendBroadcastMultiplePermissions(Intent intent, String[] includePermissions, String[] excludePermissions)558         public void sendBroadcastMultiplePermissions(Intent intent,
559                 String[] includePermissions, String[] excludePermissions) {
560             sendBroadcast(intent);
561         }
562 
563         @Override
createContextAsUser(UserHandle user, int flags)564         public Context createContextAsUser(UserHandle user, int flags) {
565             return this;
566         }
567 
568         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)569         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
570                 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
571                 int initialCode, String initialData, Bundle initialExtras) {
572             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
573             sendBroadcast(intent);
574             if (resultReceiver != null) {
575                 synchronized (mOrderedBroadcastReceivers) {
576                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
577                 }
578             }
579         }
580 
581         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)582         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
583                 String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
584                 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
585             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
586             sendBroadcast(intent);
587             if (resultReceiver != null) {
588                 synchronized (mOrderedBroadcastReceivers) {
589                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
590                 }
591             }
592         }
593 
594         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)595         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
596                 String receiverPermission, int appOp, Bundle options,
597                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
598                 String initialData, Bundle initialExtras) {
599             logd("sendOrderedBroadcastAsUser 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
sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, String initialData, Bundle initialExtras, Bundle options)610         public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
611                 String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
612                 String initialData, Bundle initialExtras, Bundle options) {
613             logd("sendOrderedBroadcast called for " + intent.getAction());
614             mLastBroadcastOptions = options;
615             sendBroadcast(intent);
616             if (resultReceiver != null) {
617                 synchronized (mOrderedBroadcastReceivers) {
618                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
619                 }
620             }
621         }
622 
623         @Override
sendStickyBroadcast(Intent intent)624         public void sendStickyBroadcast(Intent intent) {
625             logd("sendStickyBroadcast called for " + intent.getAction());
626             synchronized (mBroadcastReceiversByAction) {
627                 sendBroadcast(intent);
628                 mStickyBroadcastByAction.put(intent.getAction(), intent);
629             }
630         }
631 
632         @Override
sendStickyBroadcastAsUser(Intent intent, UserHandle ignored)633         public void sendStickyBroadcastAsUser(Intent intent, UserHandle ignored) {
634             logd("sendStickyBroadcastAsUser called for " + intent.getAction());
635             sendStickyBroadcast(intent);
636         }
637 
638         @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)639         public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
640                 throws PackageManager.NameNotFoundException {
641             return this;
642         }
643 
644         @Override
enforceCallingOrSelfPermission(String permission, String message)645         public void enforceCallingOrSelfPermission(String permission, String message) {
646             if (mPermissionTable.contains(permission)
647                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
648                 return;
649             }
650             logd("requested permission: " + permission + " got denied");
651             throw new SecurityException(permission + " denied: " + message);
652         }
653 
654         @Override
enforcePermission(String permission, int pid, int uid, String message)655         public void enforcePermission(String permission, int pid, int uid, String message) {
656             enforceCallingOrSelfPermission(permission, message);
657         }
658 
659         @Override
enforceCallingPermission(String permission, String message)660         public void enforceCallingPermission(String permission, String message) {
661             enforceCallingOrSelfPermission(permission, message);
662         }
663 
664         @Override
checkCallingOrSelfPermission(String permission)665         public int checkCallingOrSelfPermission(String permission) {
666             if (mPermissionTable.contains(permission)
667                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
668                 logd("checkCallingOrSelfPermission: " + permission + " return GRANTED");
669                 return PackageManager.PERMISSION_GRANTED;
670             } else {
671                 logd("checkCallingOrSelfPermission: " + permission + " return DENIED");
672                 return PackageManager.PERMISSION_DENIED;
673             }
674         }
675 
676         @Override
checkPermission(String permission, int pid, int uid)677         public int checkPermission(String permission, int pid, int uid) {
678             return checkCallingOrSelfPermission(permission);
679         }
680 
681         @Override
getSharedPreferences(String name, int mode)682         public SharedPreferences getSharedPreferences(String name, int mode) {
683             return mSharedPreferences;
684         }
685 
686         @Override
getPackageName()687         public String getPackageName() {
688             return "com.android.internal.telephony";
689         }
690 
691         @Override
getApplicationContext()692         public Context getApplicationContext() {
693             return null;
694         }
695 
696         @Override
startActivity(Intent intent)697         public void startActivity(Intent intent) {}
698 
699         @Override
startActivityAsUser(Intent intent, UserHandle user)700         public void startActivityAsUser(Intent intent, UserHandle user) {}
701     }
702 
703     private final Multimap<String, ComponentName> mComponentNamesByAction =
704             ArrayListMultimap.create();
705     private final Map<ComponentName, IInterface> mServiceByComponentName =
706             new HashMap<ComponentName, IInterface>();
707     private final Map<String, IInterface> mServiceByPackageName =
708             new HashMap<String, IInterface>();
709     private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
710             new HashMap<ComponentName, ServiceInfo>();
711     private final Map<ComponentName, IntentFilter> mIntentFilterByComponentName = new HashMap<>();
712     private final Map<IInterface, ComponentName> mComponentNameByService =
713             new HashMap<IInterface, ComponentName>();
714     private final Set<String> mMockBindingFailureForPackage = new HashSet();
715     private final Map<ServiceConnection, IInterface> mServiceByServiceConnection =
716             new HashMap<ServiceConnection, IInterface>();
717     private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction =
718             ArrayListMultimap.create();
719     private final HashMap<String, Intent> mStickyBroadcastByAction =
720             new HashMap<String, Intent>();
721     private final Multimap<Intent, BroadcastReceiver> mOrderedBroadcastReceivers =
722             ArrayListMultimap.create();
723     private final HashSet<String> mPermissionTable = new HashSet<>();
724     private final HashSet<String> mSystemFeatures = new HashSet<>();
725     private Bundle mLastBroadcastOptions;
726 
727 
728     // The application context is the most important object this class provides to the system
729     // under test.
730     private final Context mContext = spy(new FakeContext());
731     // We then create a spy on the application context allowing standard Mockito-style
732     // when(...) logic to be used to add specific little responses where needed.
733 
734     private final Resources mResources = mock(Resources.class);
735     private final ApplicationInfo mApplicationInfo = mock(ApplicationInfo.class);
736     private final PackageManager mPackageManager = mock(PackageManager.class);
737     private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
738     private final ActivityManager mActivityManager = mock(ActivityManager.class);
739     private final DownloadManager mDownloadManager = mock(DownloadManager.class);
740     private final AppOpsManager mAppOpsManager = mock(AppOpsManager.class);
741     private final NotificationManager mNotificationManager = mock(NotificationManager.class);
742     private final UserManager mUserManager = mock(UserManager.class);
743     private final CarrierConfigManager mCarrierConfigManager = mock(CarrierConfigManager.class);
744     private final SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
745     private final AlarmManager mAlarmManager = mock(AlarmManager.class);
746     private final AssetManager mAssetManager = new AssetManager();
747     private final ConnectivityManager mConnectivityManager = mock(ConnectivityManager.class);
748     private final UsageStatsManager mUsageStatManager = null;
749     private final WifiManager mWifiManager = mock(WifiManager.class);
750     private final BatteryManager mBatteryManager = mock(BatteryManager.class);
751     private final EuiccManager mEuiccManager = mock(EuiccManager.class);
752     private final TelecomManager mTelecomManager = mock(TelecomManager.class);
753     private final PackageInfo mPackageInfo = mock(PackageInfo.class);
754     private final TelephonyRegistryManager mTelephonyRegistryManager =
755         mock(TelephonyRegistryManager.class);
756     private final SystemConfigManager mSystemConfigManager = mock(SystemConfigManager.class);
757     private final PowerWhitelistManager mPowerWhitelistManager = mock(PowerWhitelistManager.class);
758     private final LocationManager mLocationManager = mock(LocationManager.class);
759     private final KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
760     private final VcnManager mVcnManager = mock(VcnManager.class);
761     private final NetworkPolicyManager mNetworkPolicyManager = mock(NetworkPolicyManager.class);
762     private final ImsManager mImsManager = mock(ImsManager.class);
763     private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
764     private final DropBoxManager mDropBoxManager = mock(DropBoxManager.class);
765     private final Configuration mConfiguration = new Configuration();
766     private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
767     private final SharedPreferences mSharedPreferences = PreferenceManager
768             .getDefaultSharedPreferences(TestApplication.getAppContext());
769     private final MockContentResolver mContentResolver = new MockContentResolver();
770     private final PersistableBundle mBundle = new PersistableBundle();
771     private final Network mNetwork = mock(Network.class);
772     private int mNetworkId = 200;
773 
ContextFixture()774     public ContextFixture() {
775         MockitoAnnotations.initMocks(this);
776 
777         doAnswer(new Answer<List<ResolveInfo>>() {
778             @Override
779             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
780                 return doQueryIntentServices((Intent) invocation.getArguments()[0]);
781             }
782         }).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
783 
784         doAnswer(new Answer<List<ResolveInfo>>() {
785             @Override
786             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
787                 return doQueryIntentServices((Intent) invocation.getArguments()[0]);
788             }
789         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), any());
790 
791         try {
792             doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(nullable(String.class),
793                     anyInt());
794         } catch (NameNotFoundException e) {
795             Log.d(TAG, "NameNotFoundException: e=" + e);
796         }
797 
798         doAnswer((Answer<Boolean>)
799                 invocation -> mSystemFeatures.contains((String) invocation.getArgument(0)))
800                 .when(mPackageManager).hasSystemFeature(any());
801 
802         try {
803             doReturn(mResources).when(mPackageManager).getResourcesForApplication(anyString());
804         } catch (NameNotFoundException ex) {
805             Log.d(TAG, "NameNotFoundException: ex=" + ex);
806         }
807 
808         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
809         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
810         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
811         doAnswer(invocation -> mNetworkId++).when(mNetwork).getNetId();
812         doReturn(mNetwork).when(mConnectivityManager).registerNetworkAgent(
813                 any(), any(), any(), any(), any(), any(), anyInt());
814 
815         doReturn(true).when(mEuiccManager).isEnabled();
816 
817         mConfiguration.locale = Locale.US;
818         doReturn(mConfiguration).when(mResources).getConfiguration();
819 
820         mDisplayMetrics.density = 2.25f;
821         doReturn(mDisplayMetrics).when(mResources).getDisplayMetrics();
822         mPermissionTable.add(PERMISSION_ENABLE_ALL);
823     }
824 
825     @Override
getTestDouble()826     public Context getTestDouble() {
827         return mContext;
828     }
829 
putResource(int id, final String value)830     public void putResource(int id, final String value) {
831         when(mResources.getText(eq(id))).thenReturn(value);
832         when(mResources.getString(eq(id))).thenReturn(value);
833         when(mResources.getString(eq(id), any())).thenAnswer(new Answer<String>() {
834             @Override
835             public String answer(InvocationOnMock invocation) {
836                 Object[] args = invocation.getArguments();
837                 return String.format(value, Arrays.copyOfRange(args, 1, args.length));
838             }
839         });
840     }
841 
putBooleanResource(int id, boolean value)842     public void putBooleanResource(int id, boolean value) {
843         when(mResources.getBoolean(eq(id))).thenReturn(value);
844     }
845 
putStringArrayResource(int id, String[] values)846     public void putStringArrayResource(int id, String[] values) {
847         doReturn(values).when(mResources).getStringArray(eq(id));
848     }
849 
putIntArrayResource(int id, int[] values)850     public void putIntArrayResource(int id, int[] values) {
851         doReturn(values).when(mResources).getIntArray(eq(id));
852     }
853 
putIntResource(int id, int value)854     public void putIntResource(int id, int value) {
855         doReturn(value).when(mResources).getInteger(eq(id));
856     }
857 
getCarrierConfigBundle()858     public PersistableBundle getCarrierConfigBundle() {
859         return mBundle;
860     }
861 
addService(String action, ComponentName name, String packageName, IInterface service, ServiceInfo serviceInfo)862     public void addService(String action, ComponentName name, String packageName,
863                            IInterface service, ServiceInfo serviceInfo) {
864         addService(action, name, packageName, service, serviceInfo, null /* filter */);
865     }
866 
addService(String action, ComponentName name, String packageName, IInterface service, ServiceInfo serviceInfo, IntentFilter filter)867     public void addService(String action, ComponentName name, String packageName,
868             IInterface service, ServiceInfo serviceInfo, IntentFilter filter) {
869         mComponentNamesByAction.put(action, name);
870         mServiceInfoByComponentName.put(name, serviceInfo);
871         mIntentFilterByComponentName.put(name, filter);
872         mServiceByComponentName.put(name, service);
873         mServiceByPackageName.put(packageName, service);
874         mComponentNameByService.put(service, name);
875     }
876 
mockBindingFailureForPackage(String packageName)877     public void mockBindingFailureForPackage(String packageName) {
878         mMockBindingFailureForPackage.add(packageName);
879     }
880 
doQueryIntentServices(Intent intent)881     private List<ResolveInfo> doQueryIntentServices(Intent intent) {
882         List<ResolveInfo> result = new ArrayList<ResolveInfo>();
883         for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
884             ResolveInfo resolveInfo = new ResolveInfo();
885             resolveInfo.serviceInfo = mServiceInfoByComponentName.get(componentName);
886             resolveInfo.filter = mIntentFilterByComponentName.get(componentName);
887             result.add(resolveInfo);
888         }
889         return result;
890     }
891 
sendBroadcastToOrderedBroadcastReceivers()892     public void sendBroadcastToOrderedBroadcastReceivers() {
893         synchronized (mOrderedBroadcastReceivers) {
894             // having a map separate from mOrderedBroadcastReceivers is helpful here as onReceive()
895             // call within the loop may lead to sendOrderedBroadcast() which can add to
896             // mOrderedBroadcastReceivers
897             Collection<Map.Entry<Intent, BroadcastReceiver>> map =
898                     mOrderedBroadcastReceivers.entries();
899             for (Map.Entry<Intent, BroadcastReceiver> entry : map) {
900                 entry.getValue().onReceive(mContext, entry.getKey());
901                 mOrderedBroadcastReceivers.remove(entry.getKey(), entry.getValue());
902             }
903         }
904     }
905 
addCallingOrSelfPermission(String permission)906     public void addCallingOrSelfPermission(String permission) {
907         synchronized (mPermissionTable) {
908             if (mPermissionTable != null && permission != null) {
909                 mPermissionTable.remove(PERMISSION_ENABLE_ALL);
910                 mPermissionTable.add(permission);
911             }
912         }
913     }
914 
addCallingOrSelfPermissionToCurrentPermissions(String permission)915     public void addCallingOrSelfPermissionToCurrentPermissions(String permission) {
916         synchronized (mPermissionTable) {
917             if (mPermissionTable != null && permission != null) {
918                 mPermissionTable.add(permission);
919             }
920         }
921     }
922 
removeCallingOrSelfPermission(String permission)923     public void removeCallingOrSelfPermission(String permission) {
924         synchronized (mPermissionTable) {
925             if (mPermissionTable != null && permission != null) {
926                 mPermissionTable.remove(permission);
927             }
928         }
929     }
930 
addSystemFeature(String feature)931     public void addSystemFeature(String feature) {
932         mSystemFeatures.add(feature);
933     }
934 
getLastBroadcastOptions()935     public Bundle getLastBroadcastOptions() {
936         return mLastBroadcastOptions;
937     }
938 
logd(String s)939     private static void logd(String s) {
940         Log.d(TAG, s);
941     }
942 }
943