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 com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
     20 import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
     21 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
     22 
     23 import static org.junit.Assert.assertEquals;
     24 import static org.junit.Assert.assertFalse;
     25 import static org.junit.Assert.assertTrue;
     26 import static org.junit.Assert.fail;
     27 import static org.mockito.Matchers.anyLong;
     28 import static org.mockito.Matchers.nullable;
     29 import static org.mockito.Mockito.anyBoolean;
     30 import static org.mockito.Mockito.anyInt;
     31 import static org.mockito.Mockito.atLeast;
     32 import static org.mockito.Mockito.doReturn;
     33 import static org.mockito.Mockito.eq;
     34 import static org.mockito.Mockito.mock;
     35 import static org.mockito.Mockito.spy;
     36 import static org.mockito.Mockito.times;
     37 import static org.mockito.Mockito.verify;
     38 
     39 import android.app.Activity;
     40 import android.app.IApplicationThread;
     41 import android.content.IIntentReceiver;
     42 import android.content.Intent;
     43 import android.content.SharedPreferences;
     44 import android.os.AsyncResult;
     45 import android.os.Bundle;
     46 import android.os.Handler;
     47 import android.os.HandlerThread;
     48 import android.os.Message;
     49 import android.os.Process;
     50 import android.os.WorkSource;
     51 import android.preference.PreferenceManager;
     52 import android.support.test.filters.FlakyTest;
     53 import android.telephony.CarrierConfigManager;
     54 import android.telephony.CellLocation;
     55 import android.telephony.ServiceState;
     56 import android.telephony.SubscriptionManager;
     57 import android.telephony.cdma.CdmaCellLocation;
     58 import android.telephony.gsm.GsmCellLocation;
     59 import android.test.suitebuilder.annotation.SmallTest;
     60 
     61 import com.android.internal.telephony.test.SimulatedCommands;
     62 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
     63 import com.android.internal.telephony.uicc.IccException;
     64 import com.android.internal.telephony.uicc.IccRecords;
     65 import com.android.internal.telephony.uicc.UiccController;
     66 import com.android.internal.telephony.uicc.UiccProfile;
     67 import com.android.internal.telephony.uicc.UiccSlot;
     68 
     69 import org.junit.After;
     70 import org.junit.Before;
     71 import org.junit.Ignore;
     72 import org.junit.Test;
     73 import org.mockito.ArgumentCaptor;
     74 import org.mockito.Mock;
     75 import org.mockito.Mockito;
     76 
     77 import java.util.List;
     78 
     79 public class GsmCdmaPhoneTest extends TelephonyTest {
     80     @Mock
     81     private Handler mTestHandler;
     82 
     83     //mPhoneUnderTest
     84     private GsmCdmaPhone mPhoneUT;
     85     private GsmCdmaPhoneTestHandler mGsmCdmaPhoneTestHandler;
     86 
     87     private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 1;
     88     private static final int EVENT_EMERGENCY_CALL_TOGGLE = 2;
     89     private static final int EVENT_SET_ICC_LOCK_ENABLED = 3;
     90 
     91     private class GsmCdmaPhoneTestHandler extends HandlerThread {
     92 
     93         private GsmCdmaPhoneTestHandler(String name) {
     94             super(name);
     95         }
     96 
     97         @Override
     98         public void onLooperPrepared() {
     99             mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
    100                     PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory);
    101             setReady(true);
    102         }
    103     }
    104 
    105     private void switchToGsm() {
    106         mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_GSM);
    107         mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED,
    108                 new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
    109         //wait for voice RAT to be updated
    110         waitForMs(50);
    111         assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
    112     }
    113 
    114     private void switchToCdma() {
    115         mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_IS95A);
    116         mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED,
    117                 new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_IS95A}, null)));
    118         //wait for voice RAT to be updated
    119         waitForMs(100);
    120         assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType());
    121     }
    122 
    123     @Before
    124     public void setUp() throws Exception {
    125         super.setUp(getClass().getSimpleName());
    126 
    127         doReturn(false).when(mSST).isDeviceShuttingDown();
    128 
    129         mGsmCdmaPhoneTestHandler = new GsmCdmaPhoneTestHandler(TAG);
    130         mGsmCdmaPhoneTestHandler.start();
    131         waitUntilReady();
    132         ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
    133         verify(mUiccController).registerForIccChanged(eq(mPhoneUT), integerArgumentCaptor.capture(),
    134                 nullable(Object.class));
    135         Message msg = Message.obtain();
    136         msg.what = integerArgumentCaptor.getValue();
    137         mPhoneUT.sendMessage(msg);
    138         waitForMs(50);
    139     }
    140 
    141     @After
    142     public void tearDown() throws Exception {
    143         mPhoneUT.removeCallbacksAndMessages(null);
    144         mPhoneUT = null;
    145         mGsmCdmaPhoneTestHandler.quit();
    146         super.tearDown();
    147     }
    148 
    149     @Test
    150     @SmallTest
    151     public void testPhoneTypeSwitch() {
    152         assertTrue(mPhoneUT.isPhoneTypeGsm());
    153         switchToCdma();
    154         assertTrue(mPhoneUT.isPhoneTypeCdmaLte());
    155     }
    156 
    157     @Test
    158     @SmallTest
    159     public void testHandleActionCarrierConfigChanged() {
    160         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
    161         mContext.sendBroadcast(intent);
    162         waitForMs(50);
    163         verify(mSST, times(1)).pollState();
    164 
    165         // set voice radio tech in RIL to 1xRTT. ACTION_CARRIER_CONFIG_CHANGED should trigger a
    166         // query and change phone type
    167         mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT);
    168         assertTrue(mPhoneUT.isPhoneTypeGsm());
    169         mContext.sendBroadcast(intent);
    170         waitForMs(50);
    171         assertTrue(mPhoneUT.isPhoneTypeCdmaLte());
    172         verify(mSST, times(2)).pollState();
    173     }
    174 
    175     @Test
    176     @SmallTest
    177     public void testGetServiceState() {
    178         ServiceState serviceState = new ServiceState();
    179         mSST.mSS = serviceState;
    180         assertEquals(serviceState, mPhoneUT.getServiceState());
    181     }
    182 
    183     @Test
    184     @SmallTest
    185     public void testGetSubscriberIdForGsmPhone() {
    186         final String subscriberId = "123456789";
    187         IccRecords iccRecords = Mockito.mock(IccRecords.class);
    188         doReturn(subscriberId).when(iccRecords).getIMSI();
    189         doReturn(iccRecords).when(mUiccController)
    190                 .getIccRecords(anyInt() /* phoneId */, eq(UiccController.APP_FAM_3GPP));
    191 
    192         // Ensure the phone type is GSM
    193         GsmCdmaPhone spyPhone = spy(mPhoneUT);
    194         doReturn(false).when(spyPhone).isPhoneTypeCdma();
    195         doReturn(false).when(spyPhone).isPhoneTypeCdmaLte();
    196         doReturn(true).when(spyPhone).isPhoneTypeGsm();
    197 
    198         assertEquals(subscriberId, spyPhone.getSubscriberId());
    199     }
    200 
    201     @Test
    202     @SmallTest
    203     public void testGetSubscriberIdForCdmaLtePhone() {
    204         final String subscriberId = "abcdefghijk";
    205         IccRecords iccRecords = Mockito.mock(IccRecords.class);
    206         doReturn(subscriberId).when(iccRecords).getIMSI();
    207         doReturn(iccRecords).when(mUiccController)
    208                 .getIccRecords(anyInt() /* phoneId */, eq(UiccController.APP_FAM_3GPP));
    209 
    210         // Ensure the phone type is CdmaLte
    211         GsmCdmaPhone spyPhone = spy(mPhoneUT);
    212         doReturn(false).when(spyPhone).isPhoneTypeCdma();
    213         doReturn(true).when(spyPhone).isPhoneTypeCdmaLte();
    214         doReturn(false).when(spyPhone).isPhoneTypeGsm();
    215 
    216         assertEquals(subscriberId, spyPhone.getSubscriberId());
    217     }
    218 
    219     @Test
    220     @SmallTest
    221     public void testGetSubscriberIdForCdmaPhone() {
    222         final String subscriberId = "987654321";
    223         doReturn(subscriberId).when(mSST).getImsi();
    224 
    225         // Ensure the phone type is GSM
    226         GsmCdmaPhone spyPhone = spy(mPhoneUT);
    227         doReturn(true).when(spyPhone).isPhoneTypeCdma();
    228         doReturn(false).when(spyPhone).isPhoneTypeCdmaLte();
    229         doReturn(false).when(spyPhone).isPhoneTypeGsm();
    230 
    231         assertEquals(subscriberId, spyPhone.getSubscriberId());
    232     }
    233 
    234     @Test
    235     @SmallTest
    236     public void testGetCellLocation() {
    237         // GSM
    238         CellLocation cellLocation = new GsmCellLocation();
    239         WorkSource workSource = new WorkSource(Process.myUid(),
    240             mContext.getPackageName());
    241         doReturn(cellLocation).when(mSST).getCellLocation(workSource);
    242         assertEquals(cellLocation, mPhoneUT.getCellLocation(workSource));
    243 
    244         // Switch to CDMA
    245         switchToCdma();
    246 
    247         CdmaCellLocation cdmaCellLocation = new CdmaCellLocation();
    248         cdmaCellLocation.setCellLocationData(0, 0, 0, 0, 0);
    249         mSST.mCellLoc = cdmaCellLocation;
    250 
    251         /*
    252         LOCATION_MODE is a special case in SettingsProvider. Adding the special handling in mock
    253         content provider is probably not worth the effort; it will also tightly couple tests with
    254         SettingsProvider implementation.
    255         // LOCATION_MODE_ON
    256         Settings.Secure.putInt(mContext.getContentResolver(),
    257                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
    258         waitForMs(50);
    259         CdmaCellLocation actualCellLocation = (CdmaCellLocation) mPhoneUT.getCellLocation();
    260         assertEquals(0, actualCellLocation.getBaseStationLatitude());
    261         assertEquals(0, actualCellLocation.getBaseStationLongitude());
    262 
    263         // LOCATION_MODE_OFF
    264         Settings.Secure.putInt(TestApplication.getAppContext().getContentResolver(),
    265                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
    266         waitForMs(50);
    267         */
    268 
    269         CdmaCellLocation actualCellLocation =
    270                 (CdmaCellLocation) mPhoneUT.getCellLocation(workSource);
    271         assertEquals(CdmaCellLocation.INVALID_LAT_LONG,
    272                 actualCellLocation.getBaseStationLatitude());
    273         assertEquals(CdmaCellLocation.INVALID_LAT_LONG,
    274                 actualCellLocation.getBaseStationLongitude());
    275     }
    276 
    277     @Test
    278     @SmallTest
    279     public void testGetPhoneType() {
    280         assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
    281 
    282         // Switch to CDMA
    283         switchToCdma();
    284 
    285         assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType());
    286     }
    287 
    288     @Test
    289     @SmallTest
    290     public void testGetDataConnectionState() {
    291         // There are several cases possible. Testing few of them for now.
    292         // 1. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn != APN_TYPE_EMERGENCY
    293         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST).getCurrentDataConnectionState();
    294         assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
    295                 PhoneConstants.APN_TYPE_ALL));
    296 
    297         // 2. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, apn
    298         // not connected
    299         doReturn(DctConstants.State.IDLE).when(mDcTracker).getState(
    300                 PhoneConstants.APN_TYPE_EMERGENCY);
    301         assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
    302                 PhoneConstants.APN_TYPE_EMERGENCY));
    303 
    304         // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
    305         // APN is connected, callTracker state = idle
    306         doReturn(DctConstants.State.CONNECTED).when(mDcTracker).getState(
    307                 PhoneConstants.APN_TYPE_EMERGENCY);
    308         mCT.mState = PhoneConstants.State.IDLE;
    309         assertEquals(PhoneConstants.DataState.CONNECTED, mPhoneUT.getDataConnectionState(
    310                 PhoneConstants.APN_TYPE_EMERGENCY));
    311 
    312         // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
    313         // APN enabled and CONNECTED, callTracker state != idle, !isConcurrentVoiceAndDataAllowed
    314         mCT.mState = PhoneConstants.State.RINGING;
    315         doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
    316         assertEquals(PhoneConstants.DataState.SUSPENDED, mPhoneUT.getDataConnectionState(
    317                 PhoneConstants.APN_TYPE_EMERGENCY));
    318     }
    319 
    320     @Test
    321     @SmallTest
    322     public void testHandleInCallMmiCommands() {
    323         try {
    324             // Switch to CDMA
    325             switchToCdma();
    326 
    327             assertFalse(mPhoneUT.handleInCallMmiCommands("0"));
    328 
    329             // Switch to GSM
    330             switchToGsm();
    331 
    332             mCT.mForegroundCall = mGsmCdmaCall;
    333             mCT.mBackgroundCall = mGsmCdmaCall;
    334             mCT.mRingingCall = mGsmCdmaCall;
    335             doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
    336 
    337             // !isInCall
    338             assertFalse(mPhoneUT.handleInCallMmiCommands("0"));
    339 
    340             // isInCall
    341             doReturn(GsmCdmaCall.State.ACTIVE).when(mGsmCdmaCall).getState();
    342             assertTrue(mPhoneUT.handleInCallMmiCommands("0"));
    343 
    344             // empty dialString
    345             assertFalse(mPhoneUT.handleInCallMmiCommands(""));
    346             assertFalse(mPhoneUT.handleInCallMmiCommands(null));
    347 
    348         } catch (Exception e) {
    349             fail(e.toString());
    350         }
    351     }
    352 
    353     @Test
    354     @SmallTest
    355     public void testDial() {
    356         try {
    357             mSST.mSS = mServiceState;
    358             doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
    359 
    360             mCT.mForegroundCall = mGsmCdmaCall;
    361             mCT.mBackgroundCall = mGsmCdmaCall;
    362             mCT.mRingingCall = mGsmCdmaCall;
    363             doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
    364 
    365             Connection connection = mPhoneUT.dial("1234567890",
    366                     new PhoneInternalInterface.DialArgs.Builder().build());
    367             verify(mCT).dial("1234567890", null, null);
    368         } catch (CallStateException e) {
    369             fail();
    370         }
    371     }
    372 
    373     @Test
    374     @SmallTest
    375     public void testHandlePinMmi() {
    376         assertFalse(mPhoneUT.handlePinMmi("1234567890"));
    377     }
    378 
    379     @Test
    380     @SmallTest
    381     public void testSendBurstDtmf() {
    382         //Should do nothing for GSM
    383         mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
    384         verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
    385                 anyInt(), nullable(Message.class));
    386 
    387         switchToCdma();
    388         //invalid character
    389         mPhoneUT.sendBurstDtmf("12345a67890", 0, 0, null);
    390         verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
    391                 anyInt(), nullable(Message.class));
    392 
    393         //state IDLE
    394         mCT.mState = PhoneConstants.State.IDLE;
    395         mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
    396         verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
    397                 anyInt(), nullable(Message.class));
    398 
    399         //state RINGING
    400         mCT.mState = PhoneConstants.State.RINGING;
    401         mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
    402         verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(),
    403                 anyInt(), nullable(Message.class));
    404 
    405         mCT.mState = PhoneConstants.State.OFFHOOK;
    406         mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null);
    407         verify(mSimulatedCommandsVerifier).sendBurstDtmf("1234567890", 0, 0, null);
    408     }
    409 
    410     @Test
    411     @SmallTest
    412     public void testVoiceMailNumberGsm() {
    413         String voiceMailNumber = "1234567890";
    414         // first test for GSM
    415         assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType());
    416 
    417         // no resource or sharedPreference set -- should be null
    418         assertEquals(null, mPhoneUT.getVoiceMailNumber());
    419 
    420         // voicemail number from config
    421         mContextFixture.getCarrierConfigBundle().
    422                 putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber);
    423         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    424 
    425         // voicemail number from config for roaming network
    426         String voiceMailNumberForRoaming = "1234567892";
    427         mContextFixture.getCarrierConfigBundle()
    428                 .putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_STRING,
    429                         voiceMailNumberForRoaming);
    430         //Verify voicemail number for home
    431         doReturn(false).when(mSST.mSS).getRoaming();
    432         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    433         //Move to roaming condition, verify voicemail number for roaming
    434         doReturn(true).when(mSST.mSS).getRoaming();
    435         assertEquals(voiceMailNumberForRoaming, mPhoneUT.getVoiceMailNumber());
    436         //Move to home condition, verify voicemail number for home
    437         doReturn(false).when(mSST.mSS).getRoaming();
    438         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    439 
    440         // voicemail number that is explicitly set
    441         voiceMailNumber = "1234567891";
    442         mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
    443         verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
    444                 nullable(Message.class));
    445 
    446         doReturn(voiceMailNumber).when(mSimRecords).getVoiceMailNumber();
    447         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    448     }
    449 
    450     @Test
    451     @SmallTest
    452     public void testVoiceMailNumberCdma() {
    453         switchToCdma();
    454         String voiceMailNumber = "1234567890";
    455 
    456         // no resource or sharedPreference set -- should be *86
    457         assertEquals("*86", mPhoneUT.getVoiceMailNumber());
    458 
    459         // config_telephony_use_own_number_for_voicemail
    460         mContextFixture.getCarrierConfigBundle()
    461                 .putBoolean(CarrierConfigManager
    462                                 .KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL, true);
    463         doReturn(voiceMailNumber).when(mSST).getMdnNumber();
    464         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    465 
    466         // voicemail number from config
    467         voiceMailNumber = "1234567891";
    468         mContextFixture.getCarrierConfigBundle().
    469                 putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber);
    470         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    471 
    472         // voicemail number from config for roaming network
    473         String voiceMailNumberForRoaming = "1234567892";
    474         mContextFixture.getCarrierConfigBundle()
    475                 .putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_ROAMING_STRING,
    476                         voiceMailNumberForRoaming);
    477         //Verify voicemail number for home
    478         doReturn(false).when(mSST.mSS).getRoaming();
    479         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    480         //Move to roaming condition, verify voicemail number for roaming
    481         doReturn(true).when(mSST.mSS).getRoaming();
    482         assertEquals(voiceMailNumberForRoaming, mPhoneUT.getVoiceMailNumber());
    483         //Move to home condition, verify voicemail number for home
    484         doReturn(false).when(mSST.mSS).getRoaming();
    485         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    486 
    487         // voicemail number from sharedPreference
    488         mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
    489         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
    490         verify(mRuimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
    491                 messageArgumentCaptor.capture());
    492 
    493         Message msg = messageArgumentCaptor.getValue();
    494         AsyncResult.forMessage(msg).exception =
    495                 new IccException("setVoiceMailNumber not implemented");
    496         msg.sendToTarget();
    497         waitForMs(50);
    498 
    499         assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber());
    500     }
    501 
    502     @FlakyTest
    503     @Test
    504     @Ignore
    505     public void testVoiceMailCount() {
    506         // initial value
    507         assertEquals(0, mPhoneUT.getVoiceMessageCount());
    508 
    509         // old sharedPreference set (testing upgrade from M to N scenario)
    510         SharedPreferences sharedPreferences =
    511                 PreferenceManager.getDefaultSharedPreferences(mContext);
    512         SharedPreferences.Editor editor = sharedPreferences.edit();
    513         String imsi = "1234567890";
    514         editor.putString("vm_id_key", imsi);
    515         editor.putInt("vm_count_key", 5);
    516         editor.apply();
    517         doReturn(imsi).when(mSimRecords).getIMSI();
    518 
    519         // updateVoiceMail should read old shared pref and delete it and new sharedPref should be
    520         // updated now
    521         doReturn(-1).when(mSimRecords).getVoiceMessageCount();
    522         mPhoneUT.updateVoiceMail();
    523         assertEquals(5, mPhoneUT.getVoiceMessageCount());
    524         assertEquals(null, sharedPreferences.getString("vm_id_key", null));
    525         assertEquals(5, sharedPreferences.getInt("vm_count_key" + mPhoneUT.getSubId(), 0));
    526 
    527         // sim records return count as 0, that overrides shared preference
    528         doReturn(0).when(mSimRecords).getVoiceMessageCount();
    529         mPhoneUT.updateVoiceMail();
    530         assertEquals(0, mPhoneUT.getVoiceMessageCount());
    531 
    532         // sim records return count as -1
    533         doReturn(-1).when(mSimRecords).getVoiceMessageCount();
    534         mPhoneUT.updateVoiceMail();
    535         assertEquals(-1, mPhoneUT.getVoiceMessageCount());
    536 
    537         // sim records return count as -1 and sharedPreference says 0
    538         mPhoneUT.setVoiceMessageCount(0);
    539         mPhoneUT.updateVoiceMail();
    540         assertEquals(-1, mPhoneUT.getVoiceMessageCount());
    541 
    542         // sim records return count as -1 and sharedPreference says 2
    543         mPhoneUT.setVoiceMessageCount(2);
    544         mPhoneUT.updateVoiceMail();
    545         assertEquals(2, mPhoneUT.getVoiceMessageCount());
    546 
    547         // sim records return count as 0 and sharedPreference says 2
    548         doReturn(0).when(mSimRecords).getVoiceMessageCount();
    549         mPhoneUT.setVoiceMessageCount(2);
    550         mPhoneUT.updateVoiceMail();
    551         assertEquals(0, mPhoneUT.getVoiceMessageCount());
    552     }
    553 
    554     @Test
    555     @SmallTest
    556     public void testGetCallForwardingOption() {
    557         // invalid reason (-1)
    558         mPhoneUT.getCallForwardingOption(-1, null);
    559         verify(mSimulatedCommandsVerifier, times(0)).queryCallForwardStatus(
    560                 anyInt(), anyInt(), nullable(String.class), nullable(Message.class));
    561 
    562         // valid reason
    563         String imsi = "1234567890";
    564         doReturn(imsi).when(mSimRecords).getIMSI();
    565         mPhoneUT.getCallForwardingOption(CF_REASON_UNCONDITIONAL, null);
    566         verify(mSimulatedCommandsVerifier).queryCallForwardStatus(
    567                 eq(CF_REASON_UNCONDITIONAL), eq(CommandsInterface.SERVICE_CLASS_VOICE),
    568                 nullable(String.class), nullable(Message.class));
    569         waitForMs(50);
    570         verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(),
    571                 nullable(String.class));
    572 
    573         // should have updated shared preferences
    574         SharedPreferences sharedPreferences = PreferenceManager.
    575                 getDefaultSharedPreferences(mContext);
    576         assertEquals(IccRecords.CALL_FORWARDING_STATUS_DISABLED,
    577                 sharedPreferences.getInt(Phone.CF_STATUS + mPhoneUT.getSubId(),
    578                         IccRecords.CALL_FORWARDING_STATUS_ENABLED));
    579 
    580         // clean up
    581         SharedPreferences.Editor editor = sharedPreferences.edit();
    582         editor.remove(Phone.CF_STATUS + mPhoneUT.getSubId());
    583         editor.apply();
    584     }
    585 
    586     @Test
    587     @SmallTest
    588     public void testSetCallForwardingOption() {
    589         String cfNumber = "1234567890";
    590 
    591         // invalid action
    592         mPhoneUT.setCallForwardingOption(-1, CF_REASON_UNCONDITIONAL,
    593                 cfNumber, 0, null);
    594         verify(mSimulatedCommandsVerifier, times(0)).setCallForward(anyInt(), anyInt(), anyInt(),
    595                 nullable(String.class), anyInt(), nullable(Message.class));
    596 
    597         // valid action
    598         mPhoneUT.setCallForwardingOption(CF_ACTION_ENABLE, CF_REASON_UNCONDITIONAL, cfNumber, 0,
    599                 null);
    600         verify(mSimulatedCommandsVerifier).setCallForward(eq(CF_ACTION_ENABLE),
    601                 eq(CF_REASON_UNCONDITIONAL), anyInt(), eq(cfNumber), eq(0),
    602                 nullable(Message.class));
    603         waitForMs(50);
    604         verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(), eq(cfNumber));
    605     }
    606 
    607     /**
    608      * GsmCdmaPhone handles a lot of messages. This function verifies behavior for messages that are
    609      * received when obj is created and that are received on phone type switch
    610      */
    611     @FlakyTest
    612     @Ignore
    613     @Test
    614     @SmallTest
    615     public void testHandleInitialMessages() {
    616         // EVENT_RADIO_AVAILABLE
    617         verify(mSimulatedCommandsVerifier).getBasebandVersion(nullable(Message.class));
    618         verify(mSimulatedCommandsVerifier).getDeviceIdentity(nullable(Message.class));
    619         verify(mSimulatedCommandsVerifier).getRadioCapability(nullable(Message.class));
    620         // once as part of constructor, and once on radio available
    621         verify(mSimulatedCommandsVerifier, times(2)).startLceService(anyInt(), anyBoolean(),
    622                 nullable(Message.class));
    623 
    624         // EVENT_RADIO_ON
    625         verify(mSimulatedCommandsVerifier).getVoiceRadioTechnology(nullable(Message.class));
    626         verify(mSimulatedCommandsVerifier).setPreferredNetworkType(
    627                 eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class));
    628 
    629         // verify responses for above requests:
    630         // baseband version
    631         verify(mTelephonyManager).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
    632                 nullable(String.class));
    633         // IMEI
    634         assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
    635         // IMEISV
    636         assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
    637         // radio capability
    638         verify(mSimulatedCommandsVerifier).getNetworkSelectionMode(nullable(Message.class));
    639 
    640         switchToCdma(); // this leads to eventRadioAvailable handling on cdma
    641 
    642         // EVENT_RADIO_AVAILABLE
    643         verify(mSimulatedCommandsVerifier, times(2)).getBasebandVersion(nullable(Message.class));
    644         verify(mSimulatedCommandsVerifier, times(2)).getDeviceIdentity(nullable(Message.class));
    645         verify(mSimulatedCommandsVerifier, times(3)).startLceService(anyInt(), anyBoolean(),
    646                 nullable(Message.class));
    647 
    648         // EVENT_RADIO_ON
    649         verify(mSimulatedCommandsVerifier, times(2)).getVoiceRadioTechnology(
    650                 nullable(Message.class));
    651         // once on radio on, and once on get baseband version
    652         verify(mSimulatedCommandsVerifier, times(3)).setPreferredNetworkType(
    653                 eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class));
    654 
    655         // verify responses for above requests:
    656         // baseband version
    657         verify(mTelephonyManager, times(2)).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
    658                 nullable(String.class));
    659         // device identity
    660         assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
    661         assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
    662         assertEquals(SimulatedCommands.FAKE_ESN, mPhoneUT.getEsn());
    663         assertEquals(SimulatedCommands.FAKE_MEID, mPhoneUT.getMeid());
    664     }
    665 
    666     @Test
    667     @SmallTest
    668     public void testEmergencyCallbackMessages() {
    669         verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
    670                 nullable(Object.class));
    671         verify(mSimulatedCommandsVerifier).registerForExitEmergencyCallbackMode(eq(mPhoneUT),
    672                 anyInt(), nullable(Object.class));
    673 
    674         // verify handling of emergency callback mode
    675         mSimulatedCommands.notifyEmergencyCallbackMode();
    676         waitForMs(50);
    677 
    678         // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
    679         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
    680         try {
    681             verify(mIActivityManager, atLeast(1)).broadcastIntent(eq((IApplicationThread) null),
    682                     intentArgumentCaptor.capture(),
    683                     eq((String) null),
    684                     eq((IIntentReceiver) null),
    685                     eq(Activity.RESULT_OK),
    686                     eq((String) null),
    687                     eq((Bundle) null),
    688                     eq((String[]) null),
    689                     anyInt(),
    690                     eq((Bundle) null),
    691                     eq(false),
    692                     eq(true),
    693                     anyInt());
    694         } catch(Exception e) {
    695             fail("Unexpected exception: " + e.getStackTrace());
    696         }
    697 
    698         Intent intent = intentArgumentCaptor.getValue();
    699         assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
    700         assertEquals(true, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false));
    701         assertEquals(true, mPhoneUT.isInEcm());
    702 
    703         // verify that wakeLock is acquired in ECM
    704         assertEquals(true, mPhoneUT.getWakeLock().isHeld());
    705 
    706         mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
    707         mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
    708 
    709         // verify handling of emergency callback mode exit
    710         mSimulatedCommands.notifyExitEmergencyCallbackMode();
    711         waitForMs(50);
    712 
    713         // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
    714         try {
    715             verify(mIActivityManager, atLeast(2)).broadcastIntent(eq((IApplicationThread) null),
    716                     intentArgumentCaptor.capture(),
    717                     eq((String) null),
    718                     eq((IIntentReceiver) null),
    719                     eq(Activity.RESULT_OK),
    720                     eq((String) null),
    721                     eq((Bundle) null),
    722                     eq((String[]) null),
    723                     anyInt(),
    724                     eq((Bundle) null),
    725                     eq(false),
    726                     eq(true),
    727                     anyInt());
    728         } catch(Exception e) {
    729             fail("Unexpected exception: " + e.getStackTrace());
    730         }
    731 
    732         intent = intentArgumentCaptor.getValue();
    733         assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
    734         assertEquals(false, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, true));
    735         assertEquals(false, mPhoneUT.isInEcm());
    736 
    737         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
    738 
    739         // verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
    740         verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
    741                 anyLong());
    742         List<Message> msgList = messageArgumentCaptor.getAllValues();
    743         assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
    744         assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
    745 
    746         // verify setInternalDataEnabled
    747         verify(mDcTracker).setInternalDataEnabled(true);
    748 
    749         // verify wakeLock released
    750         assertEquals(false, mPhoneUT.getWakeLock().isHeld());
    751     }
    752 
    753     @Test
    754     @SmallTest
    755     public void testModemResetInEmergencyCallbackMessages() {
    756         verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
    757                 nullable(Object.class));
    758         verify(mSimulatedCommandsVerifier).registerForModemReset(eq(mPhoneUT),
    759                 anyInt(), nullable(Object.class));
    760 
    761         switchToCdma();
    762         // verify handling of emergency callback mode
    763         mSimulatedCommands.notifyEmergencyCallbackMode();
    764         waitForMs(50);
    765 
    766         // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
    767         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
    768         try {
    769             verify(mIActivityManager, atLeast(1)).broadcastIntent(eq((IApplicationThread) null),
    770                     intentArgumentCaptor.capture(),
    771                     eq((String) null),
    772                     eq((IIntentReceiver) null),
    773                     eq(Activity.RESULT_OK),
    774                     eq((String) null),
    775                     eq((Bundle) null),
    776                     eq((String[]) null),
    777                     anyInt(),
    778                     eq((Bundle) null),
    779                     eq(false),
    780                     eq(true),
    781                     anyInt());
    782         } catch (Exception e) {
    783             fail("Unexpected exception: " + e.getStackTrace());
    784         }
    785 
    786         Intent intent = intentArgumentCaptor.getValue();
    787         assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
    788         assertEquals(true, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false));
    789         assertEquals(true, mPhoneUT.isInEcm());
    790 
    791         // verify that wakeLock is acquired in ECM
    792         assertEquals(true, mPhoneUT.getWakeLock().isHeld());
    793 
    794         mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
    795         mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
    796 
    797         // verify handling of emergency callback mode exit when modem resets
    798         mSimulatedCommands.notifyModemReset();
    799         waitForMs(50);
    800 
    801         // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
    802         try {
    803             verify(mIActivityManager, atLeast(2)).broadcastIntent(eq((IApplicationThread) null),
    804                     intentArgumentCaptor.capture(),
    805                     eq((String) null),
    806                     eq((IIntentReceiver) null),
    807                     eq(Activity.RESULT_OK),
    808                     eq((String) null),
    809                     eq((Bundle) null),
    810                     eq((String[]) null),
    811                     anyInt(),
    812                     eq((Bundle) null),
    813                     eq(false),
    814                     eq(true),
    815                     anyInt());
    816         } catch (Exception e) {
    817             fail("Unexpected exception: " + e.getStackTrace());
    818         }
    819 
    820         intent = intentArgumentCaptor.getValue();
    821         assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
    822         assertEquals(false, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, true));
    823         assertEquals(false, mPhoneUT.isInEcm());
    824 
    825         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
    826 
    827         // verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
    828         verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
    829                 anyLong());
    830         List<Message> msgList = messageArgumentCaptor.getAllValues();
    831         assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
    832         assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
    833 
    834         // verify setInternalDataEnabled
    835         verify(mDcTracker).setInternalDataEnabled(true);
    836 
    837         // verify wakeLock released
    838         assertEquals(false, mPhoneUT.getWakeLock().isHeld());
    839     }
    840 
    841     @Test
    842     @SmallTest
    843     public void testCallForwardingIndicator() {
    844         doReturn(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN).when(mSimRecords).
    845                 getVoiceCallForwardingFlag();
    846 
    847         // invalid subId
    848         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionController).
    849                 getSubIdUsingPhoneId(anyInt());
    850         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
    851 
    852         // valid subId, sharedPreference not present
    853         int subId1 = 0;
    854         int subId2 = 1;
    855         doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
    856         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
    857 
    858         // old sharedPreference present
    859         String imsi = "1234";
    860         doReturn(imsi).when(mSimRecords).getIMSI();
    861         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    862         SharedPreferences.Editor editor = sp.edit();
    863         editor.putString(Phone.CF_ID, imsi);
    864         editor.putInt(Phone.CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_ENABLED);
    865         editor.apply();
    866         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
    867 
    868         // old sharedPreference should be removed now
    869         assertEquals(null, sp.getString(Phone.CF_ID, null));
    870         assertEquals(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN,
    871                 sp.getInt(Phone.CF_ID, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN));
    872 
    873         // now verify value from new sharedPreference
    874         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
    875 
    876         // check for another subId
    877         doReturn(subId2).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
    878         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
    879 
    880         // set value for the new subId in sharedPreference
    881         editor.putInt(Phone.CF_STATUS + subId2, IccRecords.CALL_FORWARDING_STATUS_ENABLED);
    882         editor.apply();
    883         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
    884 
    885         // switching back to previous subId, stored value should still be available
    886         doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
    887         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
    888 
    889         // cleanup
    890         editor.remove(Phone.CF_STATUS + subId1);
    891         editor.remove(Phone.CF_STATUS + subId2);
    892         editor.apply();
    893     }
    894 
    895     @Test
    896     @SmallTest
    897     public void testEriLoading() {
    898         mPhoneUT.mEriManager = mEriManager;
    899         mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_CARRIER_CONFIG_CHANGED,
    900                 null));
    901         waitForMs(100);
    902         verify(mEriManager, times(1)).loadEriFile();
    903     }
    904 
    905     @Test
    906     @SmallTest
    907     public void testGetIccCardUnknownAndAbsent() {
    908         // If UiccSlot.isStateUnknown is true, we should return a dummy IccCard with the state
    909         // set to UNKNOWN
    910         doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
    911         UiccSlot mockSlot = mock(UiccSlot.class);
    912         doReturn(mockSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
    913         doReturn(true).when(mockSlot).isStateUnknown();
    914 
    915         IccCard iccCard = mPhoneUT.getIccCard();
    916         assertEquals(IccCardConstants.State.UNKNOWN, iccCard.getState());
    917 
    918         // if isStateUnknown is false, we should return a dummy IccCard with the state set to
    919         // ABSENT
    920         doReturn(false).when(mockSlot).isStateUnknown();
    921         iccCard = mPhoneUT.getIccCard();
    922         assertEquals(IccCardConstants.State.ABSENT, iccCard.getState());
    923     }
    924 
    925     @Test
    926     @SmallTest
    927     public void testGetEmptyIccCard() {
    928         doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
    929 
    930         IccCard iccCard = mPhoneUT.getIccCard();
    931 
    932         // The iccCard should be a dummy object, not null.
    933         assertTrue(!(iccCard instanceof UiccProfile));
    934 
    935         assertTrue(iccCard != null);
    936         assertEquals(IccCardConstants.State.UNKNOWN, iccCard.getState());
    937         assertEquals(null, iccCard.getIccRecords());
    938         assertEquals(false, iccCard.getIccLockEnabled());
    939         assertEquals(false, iccCard.getIccFdnEnabled());
    940         assertEquals(false, iccCard.isApplicationOnIcc(
    941                 IccCardApplicationStatus.AppType.APPTYPE_SIM));
    942         assertEquals(false, iccCard.hasIccCard());
    943         assertEquals(false, iccCard.getIccPin2Blocked());
    944         assertEquals(false, iccCard.getIccPuk2Blocked());
    945 
    946         Message onComplete = mTestHandler.obtainMessage(EVENT_SET_ICC_LOCK_ENABLED);
    947         iccCard.setIccLockEnabled(true, "password", onComplete);
    948 
    949         waitForMs(100);
    950 
    951         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
    952         // Verify that message is sent back with exception.
    953         verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
    954                 anyLong());
    955         Message message = messageArgumentCaptor.getAllValues().get(0);
    956         AsyncResult ret = (AsyncResult) message.obj;
    957         assertEquals(EVENT_SET_ICC_LOCK_ENABLED, message.what);
    958         assertTrue(ret.exception != null);
    959     }
    960 }
    961