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