Home | History | Annotate | Download | only in telephony
      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