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 17package com.android.internal.telephony; 18 19import static org.junit.Assert.fail; 20import static org.mockito.Matchers.anyBoolean; 21import static org.mockito.Matchers.anyLong; 22import static org.mockito.Matchers.nullable; 23import static org.mockito.Mockito.anyInt; 24import static org.mockito.Mockito.doAnswer; 25import static org.mockito.Mockito.doReturn; 26import static org.mockito.Mockito.eq; 27 28import android.app.ActivityManager; 29import android.app.IActivityManager; 30import android.content.ContentResolver; 31import android.content.Context; 32import android.content.IIntentSender; 33import android.content.Intent; 34import android.content.SharedPreferences; 35import android.content.pm.PackageInfo; 36import android.content.pm.PackageManager; 37import android.database.Cursor; 38import android.os.Bundle; 39import android.os.Handler; 40import android.os.IBinder; 41import android.os.IDeviceIdleController; 42import android.os.Looper; 43import android.os.RegistrantList; 44import android.os.ServiceManager; 45import android.provider.BlockedNumberContract; 46import android.provider.Settings; 47import android.telephony.ServiceState; 48import android.telephony.SubscriptionManager; 49import android.telephony.TelephonyManager; 50import android.telephony.euicc.EuiccManager; 51import android.telephony.ims.ImsCallProfile; 52import android.test.mock.MockContentProvider; 53import android.test.mock.MockContentResolver; 54import android.util.Log; 55import android.util.Singleton; 56 57import com.android.ims.ImsCall; 58import com.android.ims.ImsEcbm; 59import com.android.ims.ImsManager; 60import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 61import com.android.internal.telephony.cdma.EriManager; 62import com.android.internal.telephony.dataconnection.DcTracker; 63import com.android.internal.telephony.imsphone.ImsExternalCallTracker; 64import com.android.internal.telephony.imsphone.ImsPhone; 65import com.android.internal.telephony.imsphone.ImsPhoneCallTracker; 66import com.android.internal.telephony.test.SimulatedCommands; 67import com.android.internal.telephony.test.SimulatedCommandsVerifier; 68import com.android.internal.telephony.uicc.IccCardStatus; 69import com.android.internal.telephony.uicc.IccRecords; 70import com.android.internal.telephony.uicc.IsimUiccRecords; 71import com.android.internal.telephony.uicc.RuimRecords; 72import com.android.internal.telephony.uicc.SIMRecords; 73import com.android.internal.telephony.uicc.UiccCard; 74import com.android.internal.telephony.uicc.UiccCardApplication; 75import com.android.internal.telephony.uicc.UiccController; 76import com.android.internal.telephony.uicc.UiccProfile; 77 78import org.mockito.Mock; 79import org.mockito.MockitoAnnotations; 80import org.mockito.invocation.InvocationOnMock; 81import org.mockito.stubbing.Answer; 82 83import java.lang.reflect.Field; 84import java.lang.reflect.InvocationTargetException; 85import java.lang.reflect.Method; 86import java.util.HashMap; 87import java.util.HashSet; 88import java.util.Iterator; 89import java.util.LinkedList; 90import java.util.Set; 91import java.util.concurrent.CountDownLatch; 92import java.util.concurrent.TimeUnit; 93 94public abstract class TelephonyTest { 95 protected static String TAG; 96 97 private static final int MAX_INIT_WAIT_MS = 30000; // 30 seconds 98 99 @Mock 100 protected GsmCdmaPhone mPhone; 101 @Mock 102 protected ImsPhone mImsPhone; 103 @Mock 104 protected ServiceStateTracker mSST; 105 @Mock 106 protected GsmCdmaCallTracker mCT; 107 @Mock 108 protected ImsPhoneCallTracker mImsCT; 109 @Mock 110 protected UiccController mUiccController; 111 @Mock 112 protected UiccProfile mUiccProfile; 113 @Mock 114 protected CallManager mCallManager; 115 @Mock 116 protected PhoneNotifier mNotifier; 117 @Mock 118 protected TelephonyComponentFactory mTelephonyComponentFactory; 119 @Mock 120 protected CdmaSubscriptionSourceManager mCdmaSSM; 121 @Mock 122 protected RegistrantList mRegistrantList; 123 @Mock 124 protected IccPhoneBookInterfaceManager mIccPhoneBookIntManager; 125 @Mock 126 protected ImsManager mImsManager; 127 @Mock 128 protected DcTracker mDcTracker; 129 @Mock 130 protected GsmCdmaCall mGsmCdmaCall; 131 @Mock 132 protected ImsCall mImsCall; 133 @Mock 134 protected ImsEcbm mImsEcbm; 135 @Mock 136 protected SubscriptionController mSubscriptionController; 137 @Mock 138 protected ServiceState mServiceState; 139 @Mock 140 protected SimulatedCommandsVerifier mSimulatedCommandsVerifier; 141 @Mock 142 protected IDeviceIdleController mIDeviceIdleController; 143 @Mock 144 protected InboundSmsHandler mInboundSmsHandler; 145 @Mock 146 protected WspTypeDecoder mWspTypeDecoder; 147 @Mock 148 protected UiccCardApplication mUiccCardApplication3gpp; 149 @Mock 150 protected UiccCardApplication mUiccCardApplication3gpp2; 151 @Mock 152 protected UiccCardApplication mUiccCardApplicationIms; 153 @Mock 154 protected SIMRecords mSimRecords; 155 @Mock 156 protected RuimRecords mRuimRecords; 157 @Mock 158 protected IsimUiccRecords mIsimUiccRecords; 159 @Mock 160 protected ProxyController mProxyController; 161 @Mock 162 protected Singleton<IActivityManager> mIActivityManagerSingleton; 163 @Mock 164 protected IActivityManager mIActivityManager; 165 @Mock 166 protected InboundSmsTracker mInboundSmsTracker; 167 @Mock 168 protected IIntentSender mIIntentSender; 169 @Mock 170 protected IBinder mIBinder; 171 @Mock 172 protected SmsStorageMonitor mSmsStorageMonitor; 173 @Mock 174 protected SmsUsageMonitor mSmsUsageMonitor; 175 @Mock 176 protected PackageInfo mPackageInfo; 177 @Mock 178 protected EriManager mEriManager; 179 @Mock 180 protected IBinder mConnMetLoggerBinder; 181 @Mock 182 protected CarrierSignalAgent mCarrierSignalAgent; 183 @Mock 184 protected CarrierActionAgent mCarrierActionAgent; 185 @Mock 186 protected ImsExternalCallTracker mImsExternalCallTracker; 187 @Mock 188 protected AppSmsManager mAppSmsManager; 189 @Mock 190 protected DeviceStateMonitor mDeviceStateMonitor; 191 @Mock 192 protected IntentBroadcaster mIntentBroadcaster; 193 @Mock 194 protected NitzStateMachine mNitzStateMachine; 195 @Mock 196 protected RadioConfig mMockRadioConfig; 197 @Mock 198 protected SubscriptionInfoUpdater mSubInfoRecordUpdater; 199 @Mock 200 protected LocaleTracker mLocaleTracker; 201 202 protected ImsCallProfile mImsCallProfile; 203 protected TelephonyManager mTelephonyManager; 204 protected SubscriptionManager mSubscriptionManager; 205 protected EuiccManager mEuiccManager; 206 protected PackageManager mPackageManager; 207 protected SimulatedCommands mSimulatedCommands; 208 protected ContextFixture mContextFixture; 209 protected Context mContext; 210 protected FakeBlockedNumberContentProvider mFakeBlockedNumberContentProvider; 211 private Object mLock = new Object(); 212 private boolean mReady; 213 protected HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>(); 214 private Phone[] mPhones; 215 216 217 protected HashMap<Integer, ImsManager> mImsManagerInstances = new HashMap<>(); 218 private HashMap<InstanceKey, Object> mOldInstances = new HashMap<InstanceKey, Object>(); 219 220 private LinkedList<InstanceKey> mInstanceKeys = new LinkedList<InstanceKey>(); 221 222 private class InstanceKey { 223 public final Class mClass; 224 public final String mInstName; 225 public final Object mObj; 226 InstanceKey(final Class c, final String instName, final Object obj) { 227 mClass = c; 228 mInstName = instName; 229 mObj = obj; 230 } 231 232 @Override 233 public int hashCode() { 234 return (mClass.getName().hashCode() * 31 + mInstName.hashCode()) * 31; 235 } 236 237 @Override 238 public boolean equals(Object obj) { 239 if (obj == null || obj.getClass() != getClass()) { 240 return false; 241 } 242 243 InstanceKey other = (InstanceKey) obj; 244 return (other.mClass == mClass && other.mInstName.equals(mInstName) 245 && other.mObj == mObj); 246 } 247 } 248 249 protected void waitUntilReady() { 250 synchronized (mLock) { 251 try { 252 mLock.wait(MAX_INIT_WAIT_MS); 253 } catch (InterruptedException ie) { 254 } 255 256 if (!mReady) { 257 fail("Telephony tests failed to initialize"); 258 } 259 } 260 } 261 262 protected void setReady(boolean ready) { 263 synchronized (mLock) { 264 mReady = ready; 265 mLock.notifyAll(); 266 } 267 } 268 269 protected synchronized void replaceInstance(final Class c, final String instanceName, 270 final Object obj, final Object newValue) 271 throws Exception { 272 Field field = c.getDeclaredField(instanceName); 273 field.setAccessible(true); 274 275 InstanceKey key = new InstanceKey(c, instanceName, obj); 276 if (!mOldInstances.containsKey(key)) { 277 mOldInstances.put(key, field.get(obj)); 278 mInstanceKeys.add(key); 279 } 280 field.set(obj, newValue); 281 } 282 283 protected synchronized void restoreInstance(final Class c, final String instanceName, 284 final Object obj) throws Exception { 285 InstanceKey key = new InstanceKey(c, instanceName, obj); 286 if (mOldInstances.containsKey(key)) { 287 Field field = c.getDeclaredField(instanceName); 288 field.setAccessible(true); 289 field.set(obj, mOldInstances.get(key)); 290 mOldInstances.remove(key); 291 mInstanceKeys.remove(key); 292 } 293 } 294 295 protected synchronized void restoreInstances() throws Exception { 296 Iterator<InstanceKey> it = mInstanceKeys.descendingIterator(); 297 298 while (it.hasNext()) { 299 InstanceKey key = it.next(); 300 Field field = key.mClass.getDeclaredField(key.mInstName); 301 field.setAccessible(true); 302 field.set(key.mObj, mOldInstances.get(key)); 303 } 304 305 mInstanceKeys.clear(); 306 mOldInstances.clear(); 307 } 308 309 protected void setUp(String tag) throws Exception { 310 TAG = tag; 311 MockitoAnnotations.initMocks(this); 312 313 mPhones = new Phone[] {mPhone}; 314 mImsCallProfile = new ImsCallProfile(); 315 mSimulatedCommands = new SimulatedCommands(); 316 mContextFixture = new ContextFixture(); 317 mContext = mContextFixture.getTestDouble(); 318 mFakeBlockedNumberContentProvider = new FakeBlockedNumberContentProvider(); 319 ((MockContentResolver)mContext.getContentResolver()).addProvider( 320 BlockedNumberContract.AUTHORITY, mFakeBlockedNumberContentProvider); 321 mPhone.mCi = mSimulatedCommands; 322 mCT.mCi = mSimulatedCommands; 323 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 324 mSubscriptionManager = (SubscriptionManager) mContext.getSystemService( 325 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 326 mEuiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE); 327 mPackageManager = mContext.getPackageManager(); 328 329 //mTelephonyComponentFactory 330 doReturn(mSST).when(mTelephonyComponentFactory) 331 .makeServiceStateTracker(nullable(GsmCdmaPhone.class), 332 nullable(CommandsInterface.class)); 333 doReturn(mUiccProfile).when(mTelephonyComponentFactory) 334 .makeUiccProfile(nullable(Context.class), nullable(CommandsInterface.class), 335 nullable(IccCardStatus.class), anyInt(), nullable(UiccCard.class), 336 nullable(Object.class)); 337 doReturn(mCT).when(mTelephonyComponentFactory) 338 .makeGsmCdmaCallTracker(nullable(GsmCdmaPhone.class)); 339 doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory) 340 .makeIccPhoneBookInterfaceManager(nullable(Phone.class)); 341 doReturn(mDcTracker).when(mTelephonyComponentFactory) 342 .makeDcTracker(nullable(Phone.class)); 343 doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory) 344 .makeWspTypeDecoder(nullable(byte[].class)); 345 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 346 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(), 347 anyBoolean(), nullable(String.class), nullable(String.class), 348 nullable(String.class)); 349 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 350 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(), 351 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 352 anyInt(), anyBoolean(), nullable(String.class)); 353 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 354 .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean()); 355 doReturn(mImsCT).when(mTelephonyComponentFactory) 356 .makeImsPhoneCallTracker(nullable(ImsPhone.class)); 357 doReturn(mCdmaSSM).when(mTelephonyComponentFactory) 358 .getCdmaSubscriptionSourceManagerInstance(nullable(Context.class), 359 nullable(CommandsInterface.class), nullable(Handler.class), 360 anyInt(), nullable(Object.class)); 361 doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory) 362 .getIDeviceIdleController(); 363 doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory) 364 .makeImsExternalCallTracker(nullable(ImsPhone.class)); 365 doReturn(mAppSmsManager).when(mTelephonyComponentFactory) 366 .makeAppSmsManager(nullable(Context.class)); 367 doReturn(mCarrierSignalAgent).when(mTelephonyComponentFactory) 368 .makeCarrierSignalAgent(nullable(Phone.class)); 369 doReturn(mCarrierActionAgent).when(mTelephonyComponentFactory) 370 .makeCarrierActionAgent(nullable(Phone.class)); 371 doReturn(mDeviceStateMonitor).when(mTelephonyComponentFactory) 372 .makeDeviceStateMonitor(nullable(Phone.class)); 373 doReturn(mNitzStateMachine).when(mTelephonyComponentFactory) 374 .makeNitzStateMachine(nullable(GsmCdmaPhone.class)); 375 doReturn(mLocaleTracker).when(mTelephonyComponentFactory) 376 .makeLocaleTracker(nullable(Phone.class), nullable(Looper.class)); 377 378 //mPhone 379 doReturn(mContext).when(mPhone).getContext(); 380 doReturn(mContext).when(mImsPhone).getContext(); 381 doReturn(true).when(mPhone).getUnitTestMode(); 382 doReturn(mUiccProfile).when(mPhone).getIccCard(); 383 doReturn(mServiceState).when(mPhone).getServiceState(); 384 doReturn(mServiceState).when(mImsPhone).getServiceState(); 385 doReturn(mPhone).when(mImsPhone).getDefaultPhone(); 386 doReturn(true).when(mPhone).isPhoneTypeGsm(); 387 doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType(); 388 doReturn(mCT).when(mPhone).getCallTracker(); 389 doReturn(mSST).when(mPhone).getServiceStateTracker(); 390 doReturn(mCarrierSignalAgent).when(mPhone).getCarrierSignalAgent(); 391 doReturn(mCarrierActionAgent).when(mPhone).getCarrierActionAgent(); 392 doReturn(mAppSmsManager).when(mPhone).getAppSmsManager(); 393 mPhone.mEriManager = mEriManager; 394 395 //mUiccController 396 doReturn(mUiccCardApplication3gpp).when(mUiccController).getUiccCardApplication(anyInt(), 397 eq(UiccController.APP_FAM_3GPP)); 398 doReturn(mUiccCardApplication3gpp2).when(mUiccController).getUiccCardApplication(anyInt(), 399 eq(UiccController.APP_FAM_3GPP2)); 400 doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(), 401 eq(UiccController.APP_FAM_IMS)); 402 403 doAnswer(new Answer<IccRecords>() { 404 public IccRecords answer(InvocationOnMock invocation) { 405 switch ((Integer) invocation.getArguments()[1]) { 406 case UiccController.APP_FAM_3GPP: 407 return mSimRecords; 408 case UiccController.APP_FAM_3GPP2: 409 return mRuimRecords; 410 case UiccController.APP_FAM_IMS: 411 return mIsimUiccRecords; 412 default: 413 logd("Unrecognized family " + invocation.getArguments()[1]); 414 return null; 415 } 416 } 417 }).when(mUiccController).getIccRecords(anyInt(), anyInt()); 418 419 //UiccCardApplication 420 doReturn(mSimRecords).when(mUiccCardApplication3gpp).getIccRecords(); 421 doReturn(mRuimRecords).when(mUiccCardApplication3gpp2).getIccRecords(); 422 doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords(); 423 424 //mUiccProfile 425 doReturn(mSimRecords).when(mUiccProfile).getIccRecords(); 426 doAnswer(new Answer<IccRecords>() { 427 public IccRecords answer(InvocationOnMock invocation) { 428 return (mPhone.isPhoneTypeGsm()) ? mSimRecords : mRuimRecords; 429 } 430 }).when(mUiccProfile).getIccRecords(); 431 432 //mUiccProfile 433 doReturn(mUiccCardApplication3gpp).when(mUiccProfile).getApplication( 434 eq(UiccController.APP_FAM_3GPP)); 435 doReturn(mUiccCardApplication3gpp2).when(mUiccProfile).getApplication( 436 eq(UiccController.APP_FAM_3GPP2)); 437 doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplication( 438 eq(UiccController.APP_FAM_IMS)); 439 440 //SMS 441 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 442 doReturn(true).when(mSmsUsageMonitor).check(nullable(String.class), anyInt()); 443 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 444 doReturn(true).when(mTelephonyManager).getSmsSendCapableForPhone( 445 anyInt(), anyBoolean()); 446 447 //Misc 448 doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState). 449 getRilDataRadioTechnology(); 450 doReturn(mPhone).when(mCT).getPhone(); 451 mImsManagerInstances.put(mPhone.getPhoneId(), mImsManager); 452 doReturn(mImsEcbm).when(mImsManager).getEcbmInterface(); 453 doReturn(mPhone).when(mInboundSmsHandler).getPhone(); 454 doReturn(mImsCallProfile).when(mImsCall).getCallProfile(); 455 doReturn(mIBinder).when(mIIntentSender).asBinder(); 456 doReturn(mIIntentSender).when(mIActivityManager).getIntentSender(anyInt(), 457 nullable(String.class), nullable(IBinder.class), nullable(String.class), anyInt(), 458 nullable(Intent[].class), nullable(String[].class), anyInt(), 459 nullable(Bundle.class), anyInt()); 460 mSST.mSS = mServiceState; 461 mServiceManagerMockedServices.put("connectivity_metrics_logger", mConnMetLoggerBinder); 462 463 //SIM 464 doReturn(1).when(mTelephonyManager).getSimCount(); 465 doReturn(1).when(mTelephonyManager).getPhoneCount(); 466 467 //Data 468 //Initial state is: userData enabled, provisioned. 469 ContentResolver resolver = mContext.getContentResolver(); 470 Settings.Global.putInt(resolver, Settings.Global.MOBILE_DATA, 1); 471 Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1); 472 Settings.Global.putInt(resolver, 473 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1); 474 475 //Use reflection to mock singletons 476 replaceInstance(CallManager.class, "INSTANCE", null, mCallManager); 477 replaceInstance(TelephonyComponentFactory.class, "sInstance", null, 478 mTelephonyComponentFactory); 479 replaceInstance(UiccController.class, "mInstance", null, mUiccController); 480 replaceInstance(CdmaSubscriptionSourceManager.class, "sInstance", null, mCdmaSSM); 481 replaceInstance(ImsManager.class, "sImsManagerInstances", null, mImsManagerInstances); 482 replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController); 483 replaceInstance(ProxyController.class, "sProxyController", null, mProxyController); 484 replaceInstance(ActivityManager.class, "IActivityManagerSingleton", null, 485 mIActivityManagerSingleton); 486 replaceInstance(CdmaSubscriptionSourceManager.class, 487 "mCdmaSubscriptionSourceChangedRegistrants", mCdmaSSM, mRegistrantList); 488 replaceInstance(SimulatedCommandsVerifier.class, "sInstance", null, 489 mSimulatedCommandsVerifier); 490 replaceInstance(Singleton.class, "mInstance", mIActivityManagerSingleton, 491 mIActivityManager); 492 replaceInstance(ServiceManager.class, "sCache", null, mServiceManagerMockedServices); 493 replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster); 494 replaceInstance(TelephonyManager.class, "sInstance", null, 495 mContext.getSystemService(Context.TELEPHONY_SERVICE)); 496 replaceInstance(PhoneFactory.class, "sMadeDefaults", null, true); 497 replaceInstance(PhoneFactory.class, "sPhone", null, mPhone); 498 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 499 replaceInstance(PhoneFactory.class, "sSubInfoRecordUpdater", null, mSubInfoRecordUpdater); 500 replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig); 501 502 setReady(false); 503 } 504 505 protected void tearDown() throws Exception { 506 507 mSimulatedCommands.dispose(); 508 509 SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0); 510 sharedPreferences.edit().clear().commit(); 511 512 restoreInstances(); 513 } 514 515 protected static void logd(String s) { 516 Log.d(TAG, s); 517 } 518 519 public static class FakeBlockedNumberContentProvider extends MockContentProvider { 520 public Set<String> mBlockedNumbers = new HashSet<>(); 521 public int mNumEmergencyContactNotifications = 0; 522 523 @Override 524 public Bundle call(String method, String arg, Bundle extras) { 525 switch (method) { 526 case BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER: 527 Bundle bundle = new Bundle(); 528 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, 529 mBlockedNumbers.contains(arg)); 530 return bundle; 531 case BlockedNumberContract.SystemContract.METHOD_NOTIFY_EMERGENCY_CONTACT: 532 mNumEmergencyContactNotifications++; 533 return new Bundle(); 534 default: 535 fail("Method not expected: " + method); 536 } 537 return null; 538 } 539 } 540 541 protected void setupMockPackagePermissionChecks() throws Exception { 542 doReturn(new String[]{TAG}).when(mPackageManager).getPackagesForUid(anyInt()); 543 doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(eq(TAG), anyInt()); 544 doReturn(mPackageInfo).when(mPackageManager).getPackageInfoAsUser( 545 eq(TAG), anyInt(), anyInt()); 546 } 547 548 protected final void waitForHandlerAction(Handler h, long timeoutMillis) { 549 final CountDownLatch lock = new CountDownLatch(1); 550 h.post(lock::countDown); 551 while (lock.getCount() > 0) { 552 try { 553 lock.await(timeoutMillis, TimeUnit.MILLISECONDS); 554 } catch (InterruptedException e) { 555 // do nothing 556 } 557 } 558 } 559 560 protected final void waitForHandlerActionDelayed(Handler h, long timeoutMillis, long delayMs) { 561 final CountDownLatch lock = new CountDownLatch(1); 562 h.postDelayed(lock::countDown, delayMs); 563 while (lock.getCount() > 0) { 564 try { 565 lock.await(timeoutMillis, TimeUnit.MILLISECONDS); 566 } catch (InterruptedException e) { 567 // do nothing 568 } 569 } 570 } 571 572 public static Object invokeMethod( 573 Object instance, String methodName, Class<?>[] parameterClasses, Object[] parameters) { 574 try { 575 Method method = instance.getClass().getDeclaredMethod(methodName, parameterClasses); 576 method.setAccessible(true); 577 return method.invoke(instance, parameters); 578 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 579 fail(instance.getClass() + " " + methodName + " " + e.getClass().getName()); 580 } 581 return null; 582 } 583} 584