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 com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; 20import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; 21import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 22 23import static org.junit.Assert.assertEquals; 24import static org.junit.Assert.assertFalse; 25import static org.junit.Assert.assertTrue; 26import static org.junit.Assert.fail; 27import static org.mockito.Matchers.anyLong; 28import static org.mockito.Matchers.nullable; 29import static org.mockito.Mockito.anyBoolean; 30import static org.mockito.Mockito.anyInt; 31import static org.mockito.Mockito.atLeast; 32import static org.mockito.Mockito.doReturn; 33import static org.mockito.Mockito.eq; 34import static org.mockito.Mockito.mock; 35import static org.mockito.Mockito.spy; 36import static org.mockito.Mockito.times; 37import static org.mockito.Mockito.verify; 38 39import android.app.Activity; 40import android.app.IApplicationThread; 41import android.content.IIntentReceiver; 42import android.content.Intent; 43import android.content.SharedPreferences; 44import android.os.AsyncResult; 45import android.os.Bundle; 46import android.os.Handler; 47import android.os.HandlerThread; 48import android.os.Message; 49import android.os.Process; 50import android.os.WorkSource; 51import android.preference.PreferenceManager; 52import android.support.test.filters.FlakyTest; 53import android.telephony.CarrierConfigManager; 54import android.telephony.CellLocation; 55import android.telephony.ServiceState; 56import android.telephony.SubscriptionManager; 57import android.telephony.cdma.CdmaCellLocation; 58import android.telephony.gsm.GsmCellLocation; 59import android.test.suitebuilder.annotation.SmallTest; 60 61import com.android.internal.telephony.test.SimulatedCommands; 62import com.android.internal.telephony.uicc.IccCardApplicationStatus; 63import com.android.internal.telephony.uicc.IccException; 64import com.android.internal.telephony.uicc.IccRecords; 65import com.android.internal.telephony.uicc.UiccController; 66import com.android.internal.telephony.uicc.UiccProfile; 67import com.android.internal.telephony.uicc.UiccSlot; 68 69import org.junit.After; 70import org.junit.Before; 71import org.junit.Ignore; 72import org.junit.Test; 73import org.mockito.ArgumentCaptor; 74import org.mockito.Mock; 75import org.mockito.Mockito; 76 77import java.util.List; 78 79public 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