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