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.junit.Assert.fail; 20 import static org.mockito.Matchers.anyBoolean; 21 import static org.mockito.Matchers.anyLong; 22 import static org.mockito.Matchers.anyString; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.anyInt; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.eq; 28 29 import android.app.ActivityManagerNative; 30 import android.app.IActivityManager; 31 import android.content.Context; 32 import android.content.IIntentSender; 33 import android.content.Intent; 34 import android.content.SharedPreferences; 35 import android.content.pm.PackageInfo; 36 import android.content.pm.PackageManager; 37 import android.database.Cursor; 38 import android.os.Bundle; 39 import android.os.Handler; 40 import android.os.IBinder; 41 import android.os.IDeviceIdleController; 42 import android.os.RegistrantList; 43 import android.os.ServiceManager; 44 import android.provider.BlockedNumberContract; 45 import android.telephony.ServiceState; 46 import android.telephony.TelephonyManager; 47 import android.telephony.SubscriptionManager; 48 import android.test.mock.MockContentProvider; 49 import android.test.mock.MockContentResolver; 50 import android.util.Log; 51 import android.util.Singleton; 52 import android.util.SparseArray; 53 54 import com.android.ims.ImsCall; 55 import com.android.ims.ImsCallProfile; 56 import com.android.ims.ImsEcbm; 57 import com.android.ims.ImsManager; 58 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 59 import com.android.internal.telephony.cdma.EriManager; 60 import com.android.internal.telephony.dataconnection.DcTracker; 61 import com.android.internal.telephony.imsphone.ImsExternalCallTracker; 62 import com.android.internal.telephony.imsphone.ImsPhone; 63 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker; 64 import com.android.internal.telephony.mocks.TelephonyRegistryMock; 65 import com.android.internal.telephony.test.SimulatedCommands; 66 import com.android.internal.telephony.test.SimulatedCommandsVerifier; 67 import com.android.internal.telephony.uicc.IccCardProxy; 68 import com.android.internal.telephony.uicc.IccRecords; 69 import com.android.internal.telephony.uicc.IsimUiccRecords; 70 import com.android.internal.telephony.uicc.RuimRecords; 71 import com.android.internal.telephony.uicc.SIMRecords; 72 import com.android.internal.telephony.uicc.UiccCardApplication; 73 import com.android.internal.telephony.uicc.UiccController; 74 75 import org.mockito.Mock; 76 import org.mockito.MockitoAnnotations; 77 import org.mockito.invocation.InvocationOnMock; 78 import org.mockito.stubbing.Answer; 79 80 import java.lang.reflect.Field; 81 import java.util.HashMap; 82 import java.util.HashSet; 83 import java.util.Iterator; 84 import java.util.LinkedList; 85 import java.util.Set; 86 87 public abstract class TelephonyTest { 88 protected static String TAG; 89 90 @Mock 91 protected GsmCdmaPhone mPhone; 92 @Mock 93 protected ImsPhone mImsPhone; 94 @Mock 95 protected ServiceStateTracker mSST; 96 @Mock 97 protected GsmCdmaCallTracker mCT; 98 @Mock 99 protected ImsPhoneCallTracker mImsCT; 100 @Mock 101 protected UiccController mUiccController; 102 @Mock 103 protected IccCardProxy mIccCardProxy; 104 @Mock 105 protected CallManager mCallManager; 106 @Mock 107 protected PhoneNotifier mNotifier; 108 @Mock 109 protected TelephonyComponentFactory mTelephonyComponentFactory; 110 @Mock 111 protected CdmaSubscriptionSourceManager mCdmaSSM; 112 @Mock 113 protected RegistrantList mRegistrantList; 114 @Mock 115 protected IccPhoneBookInterfaceManager mIccPhoneBookIntManager; 116 @Mock 117 protected ImsManager mImsManager; 118 @Mock 119 protected DcTracker mDcTracker; 120 @Mock 121 protected GsmCdmaCall mGsmCdmaCall; 122 @Mock 123 protected ImsCall mImsCall; 124 @Mock 125 protected ImsCallProfile mImsCallProfile; 126 @Mock 127 protected ImsEcbm mImsEcbm; 128 @Mock 129 protected SubscriptionController mSubscriptionController; 130 @Mock 131 protected ServiceState mServiceState; 132 @Mock 133 protected SimulatedCommandsVerifier mSimulatedCommandsVerifier; 134 @Mock 135 protected IDeviceIdleController mIDeviceIdleController; 136 @Mock 137 protected InboundSmsHandler mInboundSmsHandler; 138 @Mock 139 protected WspTypeDecoder mWspTypeDecoder; 140 @Mock 141 protected UiccCardApplication mUiccCardApplication3gpp; 142 @Mock 143 protected UiccCardApplication mUiccCardApplication3gpp2; 144 @Mock 145 protected UiccCardApplication mUiccCardApplicationIms; 146 @Mock 147 protected SIMRecords mSimRecords; 148 @Mock 149 protected RuimRecords mRuimRecords; 150 @Mock 151 protected IsimUiccRecords mIsimUiccRecords; 152 @Mock 153 protected ProxyController mProxyController; 154 @Mock 155 protected Singleton<IActivityManager> mIActivityManagerSingleton; 156 @Mock 157 protected IActivityManager mIActivityManager; 158 @Mock 159 protected InboundSmsTracker mInboundSmsTracker; 160 @Mock 161 protected IIntentSender mIIntentSender; 162 @Mock 163 protected IBinder mIBinder; 164 @Mock 165 protected SmsStorageMonitor mSmsStorageMonitor; 166 @Mock 167 protected SmsUsageMonitor mSmsUsageMonitor; 168 @Mock 169 protected PackageInfo mPackageInfo; 170 @Mock 171 protected EriManager mEriManager; 172 @Mock 173 protected IBinder mConnMetLoggerBinder; 174 @Mock 175 protected CarrierSignalAgent mCarrierSignalAgent; 176 @Mock 177 protected ImsExternalCallTracker mImsExternalCallTracker; 178 179 protected TelephonyManager mTelephonyManager; 180 protected SubscriptionManager mSubscriptionManager; 181 protected PackageManager mPackageManager; 182 protected SimulatedCommands mSimulatedCommands; 183 protected ContextFixture mContextFixture; 184 protected Context mContext; 185 protected FakeBlockedNumberContentProvider mFakeBlockedNumberContentProvider; 186 private Object mLock = new Object(); 187 private boolean mReady; 188 protected HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>(); 189 190 191 protected HashMap<Integer, ImsManager> mImsManagerInstances = new HashMap<>(); 192 private HashMap<InstanceKey, Object> mOldInstances = new HashMap<InstanceKey, Object>(); 193 194 private LinkedList<InstanceKey> mInstanceKeys = new LinkedList<InstanceKey>(); 195 196 private class InstanceKey { 197 public final Class mClass; 198 public final String mInstName; 199 public final Object mObj; 200 InstanceKey(final Class c, final String instName, final Object obj) { 201 mClass = c; 202 mInstName = instName; 203 mObj = obj; 204 } 205 206 @Override 207 public int hashCode() { 208 return (mClass.getName().hashCode() * 31 + mInstName.hashCode()) * 31; 209 } 210 211 @Override 212 public boolean equals(Object obj) { 213 if (obj == null || obj.getClass() != getClass()) { 214 return false; 215 } 216 217 InstanceKey other = (InstanceKey) obj; 218 return (other.mClass == mClass && other.mInstName.equals(mInstName) 219 && other.mObj == mObj); 220 } 221 } 222 223 protected void waitUntilReady() { 224 while (true) { 225 synchronized (mLock) { 226 if (mReady) { 227 break; 228 } 229 } 230 } 231 } 232 233 protected void setReady(boolean ready) { 234 synchronized (mLock) { 235 mReady = ready; 236 } 237 } 238 239 protected synchronized void replaceInstance(final Class c, final String instanceName, 240 final Object obj, final Object newValue) 241 throws Exception { 242 Field field = c.getDeclaredField(instanceName); 243 field.setAccessible(true); 244 245 InstanceKey key = new InstanceKey(c, instanceName, obj); 246 if (!mOldInstances.containsKey(key)) { 247 mOldInstances.put(key, field.get(obj)); 248 mInstanceKeys.add(key); 249 } 250 field.set(obj, newValue); 251 } 252 253 protected synchronized void restoreInstance(final Class c, final String instanceName, 254 final Object obj) throws Exception { 255 InstanceKey key = new InstanceKey(c, instanceName, obj); 256 if (mOldInstances.containsKey(key)) { 257 Field field = c.getDeclaredField(instanceName); 258 field.setAccessible(true); 259 field.set(obj, mOldInstances.get(key)); 260 mOldInstances.remove(key); 261 mInstanceKeys.remove(key); 262 } 263 } 264 265 protected synchronized void restoreInstances() throws Exception { 266 Iterator<InstanceKey> it = mInstanceKeys.descendingIterator(); 267 268 while (it.hasNext()) { 269 InstanceKey key = it.next(); 270 Field field = key.mClass.getDeclaredField(key.mInstName); 271 field.setAccessible(true); 272 field.set(key.mObj, mOldInstances.get(key)); 273 } 274 275 mInstanceKeys.clear(); 276 mOldInstances.clear(); 277 } 278 279 protected void setUp(String tag) throws Exception { 280 TAG = tag; 281 MockitoAnnotations.initMocks(this); 282 283 //Use reflection to mock singletons 284 replaceInstance(CallManager.class, "INSTANCE", null, mCallManager); 285 replaceInstance(TelephonyComponentFactory.class, "sInstance", null, 286 mTelephonyComponentFactory); 287 replaceInstance(UiccController.class, "mInstance", null, mUiccController); 288 replaceInstance(CdmaSubscriptionSourceManager.class, "sInstance", null, mCdmaSSM); 289 replaceInstance(ImsManager.class, "sImsManagerInstances", null, mImsManagerInstances); 290 replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController); 291 replaceInstance(ProxyController.class, "sProxyController", null, mProxyController); 292 replaceInstance(ActivityManagerNative.class, "gDefault", null, mIActivityManagerSingleton); 293 replaceInstance(CdmaSubscriptionSourceManager.class, 294 "mCdmaSubscriptionSourceChangedRegistrants", mCdmaSSM, mRegistrantList); 295 replaceInstance(SimulatedCommandsVerifier.class, "sInstance", null, 296 mSimulatedCommandsVerifier); 297 replaceInstance(Singleton.class, "mInstance", mIActivityManagerSingleton, 298 mIActivityManager); 299 replaceInstance(ServiceManager.class, "sCache", null, mServiceManagerMockedServices); 300 301 mSimulatedCommands = new SimulatedCommands(); 302 mContextFixture = new ContextFixture(); 303 mContext = mContextFixture.getTestDouble(); 304 mFakeBlockedNumberContentProvider = new FakeBlockedNumberContentProvider(); 305 ((MockContentResolver)mContext.getContentResolver()).addProvider( 306 BlockedNumberContract.AUTHORITY, mFakeBlockedNumberContentProvider); 307 mPhone.mCi = mSimulatedCommands; 308 mCT.mCi = mSimulatedCommands; 309 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 310 mSubscriptionManager = (SubscriptionManager) mContext.getSystemService( 311 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 312 mPackageManager = mContext.getPackageManager(); 313 314 replaceInstance(TelephonyManager.class, "sInstance", null, 315 mContext.getSystemService(Context.TELEPHONY_SERVICE)); 316 317 //mTelephonyComponentFactory 318 doReturn(mSST).when(mTelephonyComponentFactory) 319 .makeServiceStateTracker(any(GsmCdmaPhone.class), any(CommandsInterface.class)); 320 doReturn(mIccCardProxy).when(mTelephonyComponentFactory) 321 .makeIccCardProxy(any(Context.class), any(CommandsInterface.class), anyInt()); 322 doReturn(mCT).when(mTelephonyComponentFactory) 323 .makeGsmCdmaCallTracker(any(GsmCdmaPhone.class)); 324 doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory) 325 .makeIccPhoneBookInterfaceManager(any(Phone.class)); 326 doReturn(mDcTracker).when(mTelephonyComponentFactory) 327 .makeDcTracker(any(Phone.class)); 328 doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory) 329 .makeWspTypeDecoder(any(byte[].class)); 330 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 331 .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), 332 anyBoolean(), anyString(), anyString()); 333 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 334 .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), 335 anyString(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyString()); 336 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 337 .makeInboundSmsTracker(any(Cursor.class), anyBoolean()); 338 doReturn(mImsCT).when(mTelephonyComponentFactory) 339 .makeImsPhoneCallTracker(any(ImsPhone.class)); 340 doReturn(mCdmaSSM).when(mTelephonyComponentFactory) 341 .getCdmaSubscriptionSourceManagerInstance(any(Context.class), 342 any(CommandsInterface.class), any(Handler.class), 343 anyInt(), any(Object.class)); 344 doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory) 345 .getIDeviceIdleController(); 346 doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory). 347 makeImsExternalCallTracker(any(ImsPhone.class)); 348 349 //mPhone 350 doReturn(mContext).when(mPhone).getContext(); 351 doReturn(mContext).when(mImsPhone).getContext(); 352 doReturn(true).when(mPhone).getUnitTestMode(); 353 doReturn(mIccCardProxy).when(mPhone).getIccCard(); 354 doReturn(mServiceState).when(mPhone).getServiceState(); 355 doReturn(mServiceState).when(mImsPhone).getServiceState(); 356 doReturn(mPhone).when(mImsPhone).getDefaultPhone(); 357 doReturn(true).when(mPhone).isPhoneTypeGsm(); 358 doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType(); 359 doReturn(mCT).when(mPhone).getCallTracker(); 360 doReturn(mSST).when(mPhone).getServiceStateTracker(); 361 doReturn(mCarrierSignalAgent).when(mPhone).getCarrierSignalAgent(); 362 mPhone.mEriManager = mEriManager; 363 364 //mUiccController 365 doReturn(mUiccCardApplication3gpp).when(mUiccController).getUiccCardApplication(anyInt(), 366 eq(UiccController.APP_FAM_3GPP)); 367 doReturn(mUiccCardApplication3gpp2).when(mUiccController).getUiccCardApplication(anyInt(), 368 eq(UiccController.APP_FAM_3GPP2)); 369 doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(), 370 eq(UiccController.APP_FAM_IMS)); 371 372 doAnswer(new Answer<IccRecords>() { 373 public IccRecords answer(InvocationOnMock invocation) { 374 switch ((Integer) invocation.getArguments()[1]) { 375 case UiccController.APP_FAM_3GPP: 376 return mSimRecords; 377 case UiccController.APP_FAM_3GPP2: 378 return mRuimRecords; 379 case UiccController.APP_FAM_IMS: 380 return mIsimUiccRecords; 381 default: 382 logd("Unrecognized family " + invocation.getArguments()[1]); 383 return null; 384 } 385 } 386 }).when(mUiccController).getIccRecords(anyInt(), anyInt()); 387 388 //UiccCardApplication 389 doReturn(mSimRecords).when(mUiccCardApplication3gpp).getIccRecords(); 390 doReturn(mRuimRecords).when(mUiccCardApplication3gpp2).getIccRecords(); 391 doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords(); 392 393 //mIccCardProxy 394 doReturn(mSimRecords).when(mIccCardProxy).getIccRecords(); 395 doAnswer(new Answer<IccRecords>() { 396 public IccRecords answer(InvocationOnMock invocation) { 397 return (mPhone.isPhoneTypeGsm()) ? mSimRecords : mRuimRecords; 398 } 399 }).when(mIccCardProxy).getIccRecords(); 400 401 //SMS 402 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 403 doReturn(true).when(mSmsUsageMonitor).check(anyString(), anyInt()); 404 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 405 doReturn(true).when(mTelephonyManager).getSmsSendCapableForPhone( 406 anyInt(), anyBoolean()); 407 408 //Misc 409 doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState). 410 getRilDataRadioTechnology(); 411 doReturn(mPhone).when(mCT).getPhone(); 412 mImsManagerInstances.put(mPhone.getPhoneId(), null); 413 doReturn(mImsEcbm).when(mImsManager).getEcbmInterface(anyInt()); 414 doReturn(mPhone).when(mInboundSmsHandler).getPhone(); 415 doReturn(mImsCallProfile).when(mImsCall).getCallProfile(); 416 doReturn(mIBinder).when(mIIntentSender).asBinder(); 417 doReturn(mIIntentSender).when(mIActivityManager).getIntentSender(anyInt(), 418 anyString(), any(IBinder.class), anyString(), anyInt(), any(Intent[].class), 419 any(String[].class), anyInt(), any(Bundle.class), anyInt()); 420 mSST.mSS = mServiceState; 421 mServiceManagerMockedServices.put("connectivity_metrics_logger", mConnMetLoggerBinder); 422 423 setReady(false); 424 } 425 426 protected void tearDown() throws Exception { 427 428 SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0); 429 sharedPreferences.edit().clear().commit(); 430 431 restoreInstances(); 432 } 433 434 protected static void logd(String s) { 435 Log.d(TAG, s); 436 } 437 438 public static class FakeBlockedNumberContentProvider extends MockContentProvider { 439 public Set<String> mBlockedNumbers = new HashSet<>(); 440 public int mNumEmergencyContactNotifications = 0; 441 442 @Override 443 public Bundle call(String method, String arg, Bundle extras) { 444 switch (method) { 445 case BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER: 446 Bundle bundle = new Bundle(); 447 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, 448 mBlockedNumbers.contains(arg)); 449 return bundle; 450 case BlockedNumberContract.SystemContract.METHOD_NOTIFY_EMERGENCY_CONTACT: 451 mNumEmergencyContactNotifications++; 452 return new Bundle(); 453 default: 454 fail("Method not expected: " + method); 455 } 456 return null; 457 } 458 } 459 460 protected void setupMockPackagePermissionChecks() throws Exception { 461 doReturn(new String[]{TAG}).when(mPackageManager).getPackagesForUid(anyInt()); 462 doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(eq(TAG), anyInt()); 463 } 464 } 465