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.times; 35import static org.mockito.Mockito.verify; 36 37import android.app.Activity; 38import android.app.IApplicationThread; 39import android.content.IIntentReceiver; 40import android.content.Intent; 41import android.content.SharedPreferences; 42import android.os.AsyncResult; 43import android.os.Bundle; 44import android.os.Handler; 45import android.os.HandlerThread; 46import android.os.Message; 47import android.os.Process; 48import android.os.WorkSource; 49import android.preference.PreferenceManager; 50import android.support.test.filters.FlakyTest; 51import android.telephony.CarrierConfigManager; 52import android.telephony.CellLocation; 53import android.telephony.ServiceState; 54import android.telephony.SubscriptionManager; 55import android.telephony.cdma.CdmaCellLocation; 56import android.telephony.gsm.GsmCellLocation; 57import android.test.suitebuilder.annotation.SmallTest; 58 59import com.android.internal.telephony.test.SimulatedCommands; 60import com.android.internal.telephony.uicc.IccException; 61import com.android.internal.telephony.uicc.IccRecords; 62 63import org.junit.After; 64import org.junit.Before; 65import org.junit.Ignore; 66import org.junit.Test; 67import org.mockito.ArgumentCaptor; 68import org.mockito.Mock; 69 70import java.util.List; 71 72public class GsmCdmaPhoneTest extends TelephonyTest { 73 @Mock 74 private Handler mTestHandler; 75 76 //mPhoneUnderTest 77 private GsmCdmaPhone mPhoneUT; 78 private GsmCdmaPhoneTestHandler mGsmCdmaPhoneTestHandler; 79 80 private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 1; 81 private static final int EVENT_EMERGENCY_CALL_TOGGLE = 2; 82 83 private class GsmCdmaPhoneTestHandler extends HandlerThread { 84 85 private GsmCdmaPhoneTestHandler(String name) { 86 super(name); 87 } 88 89 @Override 90 public void onLooperPrepared() { 91 mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0, 92 PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory); 93 setReady(true); 94 } 95 } 96 97 private void switchToGsm() { 98 mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_GSM); 99 mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED, 100 new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null))); 101 //wait for voice RAT to be updated 102 waitForMs(50); 103 assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType()); 104 } 105 106 private void switchToCdma() { 107 mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_IS95A); 108 mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_VOICE_RADIO_TECH_CHANGED, 109 new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_IS95A}, null))); 110 //wait for voice RAT to be updated 111 waitForMs(100); 112 assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType()); 113 } 114 115 @Before 116 public void setUp() throws Exception { 117 super.setUp(getClass().getSimpleName()); 118 119 doReturn(false).when(mSST).isDeviceShuttingDown(); 120 121 mGsmCdmaPhoneTestHandler = new GsmCdmaPhoneTestHandler(TAG); 122 mGsmCdmaPhoneTestHandler.start(); 123 waitUntilReady(); 124 ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class); 125 verify(mUiccController).registerForIccChanged(eq(mPhoneUT), integerArgumentCaptor.capture(), 126 nullable(Object.class)); 127 Message msg = Message.obtain(); 128 msg.what = integerArgumentCaptor.getValue(); 129 mPhoneUT.sendMessage(msg); 130 waitForMs(50); 131 } 132 133 @After 134 public void tearDown() throws Exception { 135 mPhoneUT.removeCallbacksAndMessages(null); 136 mPhoneUT = null; 137 mGsmCdmaPhoneTestHandler.quit(); 138 super.tearDown(); 139 } 140 141 @Test 142 @SmallTest 143 public void testPhoneTypeSwitch() { 144 assertTrue(mPhoneUT.isPhoneTypeGsm()); 145 switchToCdma(); 146 assertTrue(mPhoneUT.isPhoneTypeCdmaLte()); 147 } 148 149 @Test 150 @SmallTest 151 public void testHandleActionCarrierConfigChanged() { 152 // set voice radio tech in RIL to 1xRTT. ACTION_CARRIER_CONFIG_CHANGED should trigger a 153 // query and change phone type 154 mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT); 155 assertTrue(mPhoneUT.isPhoneTypeGsm()); 156 Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 157 mContext.sendBroadcast(intent); 158 waitForMs(50); 159 assertTrue(mPhoneUT.isPhoneTypeCdmaLte()); 160 } 161 162 @Test 163 @SmallTest 164 public void testGetServiceState() { 165 ServiceState serviceState = new ServiceState(); 166 mSST.mSS = serviceState; 167 assertEquals(serviceState, mPhoneUT.getServiceState()); 168 } 169 170 @Test 171 @SmallTest 172 public void testGetCellLocation() { 173 // GSM 174 CellLocation cellLocation = new GsmCellLocation(); 175 WorkSource workSource = new WorkSource(Process.myUid(), 176 mContext.getPackageName()); 177 doReturn(cellLocation).when(mSST).getCellLocation(workSource); 178 assertEquals(cellLocation, mPhoneUT.getCellLocation(workSource)); 179 180 // Switch to CDMA 181 switchToCdma(); 182 183 CdmaCellLocation cdmaCellLocation = new CdmaCellLocation(); 184 cdmaCellLocation.setCellLocationData(0, 0, 0, 0, 0); 185 mSST.mCellLoc = cdmaCellLocation; 186 187 /* 188 LOCATION_MODE is a special case in SettingsProvider. Adding the special handling in mock 189 content provider is probably not worth the effort; it will also tightly couple tests with 190 SettingsProvider implementation. 191 // LOCATION_MODE_ON 192 Settings.Secure.putInt(mContext.getContentResolver(), 193 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); 194 waitForMs(50); 195 CdmaCellLocation actualCellLocation = (CdmaCellLocation) mPhoneUT.getCellLocation(); 196 assertEquals(0, actualCellLocation.getBaseStationLatitude()); 197 assertEquals(0, actualCellLocation.getBaseStationLongitude()); 198 199 // LOCATION_MODE_OFF 200 Settings.Secure.putInt(TestApplication.getAppContext().getContentResolver(), 201 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 202 waitForMs(50); 203 */ 204 205 CdmaCellLocation actualCellLocation = 206 (CdmaCellLocation) mPhoneUT.getCellLocation(workSource); 207 assertEquals(CdmaCellLocation.INVALID_LAT_LONG, 208 actualCellLocation.getBaseStationLatitude()); 209 assertEquals(CdmaCellLocation.INVALID_LAT_LONG, 210 actualCellLocation.getBaseStationLongitude()); 211 } 212 213 @Test 214 @SmallTest 215 public void testGetPhoneType() { 216 assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType()); 217 218 // Switch to CDMA 219 switchToCdma(); 220 221 assertEquals(PhoneConstants.PHONE_TYPE_CDMA, mPhoneUT.getPhoneType()); 222 } 223 224 @Test 225 @SmallTest 226 public void testGetDataConnectionState() { 227 // There are several cases possible. Testing few of them for now. 228 // 1. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn != APN_TYPE_EMERGENCY 229 doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST).getCurrentDataConnectionState(); 230 assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState( 231 PhoneConstants.APN_TYPE_ALL)); 232 233 // 2. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, apn 234 // not connected 235 doReturn(DctConstants.State.IDLE).when(mDcTracker).getState( 236 PhoneConstants.APN_TYPE_EMERGENCY); 237 assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState( 238 PhoneConstants.APN_TYPE_EMERGENCY)); 239 240 // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, 241 // APN is connected, callTracker state = idle 242 doReturn(DctConstants.State.CONNECTED).when(mDcTracker).getState( 243 PhoneConstants.APN_TYPE_EMERGENCY); 244 mCT.mState = PhoneConstants.State.IDLE; 245 assertEquals(PhoneConstants.DataState.CONNECTED, mPhoneUT.getDataConnectionState( 246 PhoneConstants.APN_TYPE_EMERGENCY)); 247 248 // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, 249 // APN enabled and CONNECTED, callTracker state != idle, !isConcurrentVoiceAndDataAllowed 250 mCT.mState = PhoneConstants.State.RINGING; 251 doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed(); 252 assertEquals(PhoneConstants.DataState.SUSPENDED, mPhoneUT.getDataConnectionState( 253 PhoneConstants.APN_TYPE_EMERGENCY)); 254 } 255 256 @Test 257 @SmallTest 258 public void testHandleInCallMmiCommands() { 259 try { 260 // Switch to CDMA 261 switchToCdma(); 262 263 assertFalse(mPhoneUT.handleInCallMmiCommands("0")); 264 265 // Switch to GSM 266 switchToGsm(); 267 268 mCT.mForegroundCall = mGsmCdmaCall; 269 mCT.mBackgroundCall = mGsmCdmaCall; 270 mCT.mRingingCall = mGsmCdmaCall; 271 doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState(); 272 273 // !isInCall 274 assertFalse(mPhoneUT.handleInCallMmiCommands("0")); 275 276 // isInCall 277 doReturn(GsmCdmaCall.State.ACTIVE).when(mGsmCdmaCall).getState(); 278 assertTrue(mPhoneUT.handleInCallMmiCommands("0")); 279 280 // empty dialString 281 assertFalse(mPhoneUT.handleInCallMmiCommands("")); 282 assertFalse(mPhoneUT.handleInCallMmiCommands(null)); 283 284 } catch (Exception e) { 285 fail(e.toString()); 286 } 287 } 288 289 @Test 290 @SmallTest 291 public void testDial() { 292 try { 293 mSST.mSS = mServiceState; 294 doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState(); 295 296 mCT.mForegroundCall = mGsmCdmaCall; 297 mCT.mBackgroundCall = mGsmCdmaCall; 298 mCT.mRingingCall = mGsmCdmaCall; 299 doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState(); 300 301 Connection connection = mPhoneUT.dial("1234567890", 0); 302 verify(mCT).dial("1234567890", null, null); 303 } catch (CallStateException e) { 304 fail(); 305 } 306 } 307 308 @Test 309 @SmallTest 310 public void testHandlePinMmi() { 311 assertFalse(mPhoneUT.handlePinMmi("1234567890")); 312 } 313 314 @Test 315 @SmallTest 316 public void testSendBurstDtmf() { 317 //Should do nothing for GSM 318 mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null); 319 verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(), 320 anyInt(), nullable(Message.class)); 321 322 switchToCdma(); 323 //invalid character 324 mPhoneUT.sendBurstDtmf("12345a67890", 0, 0, null); 325 verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(), 326 anyInt(), nullable(Message.class)); 327 328 //state IDLE 329 mCT.mState = PhoneConstants.State.IDLE; 330 mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null); 331 verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(), 332 anyInt(), nullable(Message.class)); 333 334 //state RINGING 335 mCT.mState = PhoneConstants.State.RINGING; 336 mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null); 337 verify(mSimulatedCommandsVerifier, times(0)).sendBurstDtmf(nullable(String.class), anyInt(), 338 anyInt(), nullable(Message.class)); 339 340 mCT.mState = PhoneConstants.State.OFFHOOK; 341 mPhoneUT.sendBurstDtmf("1234567890", 0, 0, null); 342 verify(mSimulatedCommandsVerifier).sendBurstDtmf("1234567890", 0, 0, null); 343 } 344 345 @Test 346 @SmallTest 347 public void testVoiceMailNumberGsm() { 348 String voiceMailNumber = "1234567890"; 349 // first test for GSM 350 assertEquals(PhoneConstants.PHONE_TYPE_GSM, mPhoneUT.getPhoneType()); 351 352 // no resource or sharedPreference set -- should be null 353 assertEquals(null, mPhoneUT.getVoiceMailNumber()); 354 355 // voicemail number from config 356 mContextFixture.getCarrierConfigBundle(). 357 putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber); 358 assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber()); 359 360 // voicemail number that is explicitly set 361 voiceMailNumber = "1234567891"; 362 mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null); 363 verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber), 364 nullable(Message.class)); 365 366 doReturn(voiceMailNumber).when(mSimRecords).getVoiceMailNumber(); 367 assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber()); 368 } 369 370 @Test 371 @SmallTest 372 public void testVoiceMailNumberCdma() { 373 switchToCdma(); 374 String voiceMailNumber = "1234567890"; 375 376 // no resource or sharedPreference set -- should be *86 377 assertEquals("*86", mPhoneUT.getVoiceMailNumber()); 378 379 // config_telephony_use_own_number_for_voicemail 380 mContextFixture.putBooleanResource( 381 com.android.internal.R.bool.config_telephony_use_own_number_for_voicemail, true); 382 doReturn(voiceMailNumber).when(mSST).getMdnNumber(); 383 assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber()); 384 385 // voicemail number from config 386 voiceMailNumber = "1234567891"; 387 mContextFixture.getCarrierConfigBundle(). 388 putString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING, voiceMailNumber); 389 assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber()); 390 391 // voicemail number from sharedPreference 392 mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null); 393 ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); 394 verify(mRuimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber), 395 messageArgumentCaptor.capture()); 396 397 Message msg = messageArgumentCaptor.getValue(); 398 AsyncResult.forMessage(msg).exception = 399 new IccException("setVoiceMailNumber not implemented"); 400 msg.sendToTarget(); 401 waitForMs(50); 402 403 assertEquals(voiceMailNumber, mPhoneUT.getVoiceMailNumber()); 404 } 405 406 @FlakyTest 407 @Test 408 @Ignore 409 public void testVoiceMailCount() { 410 // initial value 411 assertEquals(0, mPhoneUT.getVoiceMessageCount()); 412 413 // old sharedPreference set (testing upgrade from M to N scenario) 414 SharedPreferences sharedPreferences = 415 PreferenceManager.getDefaultSharedPreferences(mContext); 416 SharedPreferences.Editor editor = sharedPreferences.edit(); 417 String imsi = "1234567890"; 418 editor.putString("vm_id_key", imsi); 419 editor.putInt("vm_count_key", 5); 420 editor.apply(); 421 doReturn(imsi).when(mSimRecords).getIMSI(); 422 423 // updateVoiceMail should read old shared pref and delete it and new sharedPref should be 424 // updated now 425 doReturn(-1).when(mSimRecords).getVoiceMessageCount(); 426 mPhoneUT.updateVoiceMail(); 427 assertEquals(5, mPhoneUT.getVoiceMessageCount()); 428 assertEquals(null, sharedPreferences.getString("vm_id_key", null)); 429 assertEquals(5, sharedPreferences.getInt("vm_count_key" + mPhoneUT.getSubId(), 0)); 430 431 // sim records return count as 0, that overrides shared preference 432 doReturn(0).when(mSimRecords).getVoiceMessageCount(); 433 mPhoneUT.updateVoiceMail(); 434 assertEquals(0, mPhoneUT.getVoiceMessageCount()); 435 436 // sim records return count as -1 437 doReturn(-1).when(mSimRecords).getVoiceMessageCount(); 438 mPhoneUT.updateVoiceMail(); 439 assertEquals(-1, mPhoneUT.getVoiceMessageCount()); 440 441 // sim records return count as -1 and sharedPreference says 0 442 mPhoneUT.setVoiceMessageCount(0); 443 mPhoneUT.updateVoiceMail(); 444 assertEquals(-1, mPhoneUT.getVoiceMessageCount()); 445 446 // sim records return count as -1 and sharedPreference says 2 447 mPhoneUT.setVoiceMessageCount(2); 448 mPhoneUT.updateVoiceMail(); 449 assertEquals(2, mPhoneUT.getVoiceMessageCount()); 450 451 // sim records return count as 0 and sharedPreference says 2 452 doReturn(0).when(mSimRecords).getVoiceMessageCount(); 453 mPhoneUT.setVoiceMessageCount(2); 454 mPhoneUT.updateVoiceMail(); 455 assertEquals(0, mPhoneUT.getVoiceMessageCount()); 456 } 457 458 @Test 459 @SmallTest 460 public void testGetCallForwardingOption() { 461 // invalid reason (-1) 462 mPhoneUT.getCallForwardingOption(-1, null); 463 verify(mSimulatedCommandsVerifier, times(0)).queryCallForwardStatus( 464 anyInt(), anyInt(), nullable(String.class), nullable(Message.class)); 465 466 // valid reason 467 String imsi = "1234567890"; 468 doReturn(imsi).when(mSimRecords).getIMSI(); 469 mPhoneUT.getCallForwardingOption(CF_REASON_UNCONDITIONAL, null); 470 verify(mSimulatedCommandsVerifier).queryCallForwardStatus( 471 eq(CF_REASON_UNCONDITIONAL), anyInt(), nullable(String.class), 472 nullable(Message.class)); 473 waitForMs(50); 474 verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(), 475 nullable(String.class)); 476 477 // should have updated shared preferences 478 SharedPreferences sharedPreferences = PreferenceManager. 479 getDefaultSharedPreferences(mContext); 480 assertEquals(IccRecords.CALL_FORWARDING_STATUS_DISABLED, 481 sharedPreferences.getInt(Phone.CF_STATUS + mPhoneUT.getSubId(), 482 IccRecords.CALL_FORWARDING_STATUS_ENABLED)); 483 484 // clean up 485 SharedPreferences.Editor editor = sharedPreferences.edit(); 486 editor.remove(Phone.CF_STATUS + mPhoneUT.getSubId()); 487 editor.apply(); 488 } 489 490 @Test 491 @SmallTest 492 public void testSetCallForwardingOption() { 493 String cfNumber = "1234567890"; 494 495 // invalid action 496 mPhoneUT.setCallForwardingOption(-1, CF_REASON_UNCONDITIONAL, 497 cfNumber, 0, null); 498 verify(mSimulatedCommandsVerifier, times(0)).setCallForward(anyInt(), anyInt(), anyInt(), 499 nullable(String.class), anyInt(), nullable(Message.class)); 500 501 // valid action 502 mPhoneUT.setCallForwardingOption(CF_ACTION_ENABLE, CF_REASON_UNCONDITIONAL, cfNumber, 0, 503 null); 504 verify(mSimulatedCommandsVerifier).setCallForward(eq(CF_ACTION_ENABLE), 505 eq(CF_REASON_UNCONDITIONAL), anyInt(), eq(cfNumber), eq(0), 506 nullable(Message.class)); 507 waitForMs(50); 508 verify(mSimRecords).setVoiceCallForwardingFlag(anyInt(), anyBoolean(), eq(cfNumber)); 509 } 510 511 /** 512 * GsmCdmaPhone handles a lot of messages. This function verifies behavior for messages that are 513 * received when obj is created and that are received on phone type switch 514 */ 515 @FlakyTest 516 @Test 517 @SmallTest 518 public void testHandleInitialMessages() { 519 // EVENT_RADIO_AVAILABLE 520 verify(mSimulatedCommandsVerifier).getBasebandVersion(nullable(Message.class)); 521 verify(mSimulatedCommandsVerifier).getDeviceIdentity(nullable(Message.class)); 522 verify(mSimulatedCommandsVerifier).getRadioCapability(nullable(Message.class)); 523 // once as part of constructor, and once on radio available 524 verify(mSimulatedCommandsVerifier, times(2)).startLceService(anyInt(), anyBoolean(), 525 nullable(Message.class)); 526 527 // EVENT_RADIO_ON 528 verify(mSimulatedCommandsVerifier).getVoiceRadioTechnology(nullable(Message.class)); 529 verify(mSimulatedCommandsVerifier).setPreferredNetworkType( 530 eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class)); 531 532 // verify responses for above requests: 533 // baseband version 534 verify(mTelephonyManager).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()), 535 nullable(String.class)); 536 // IMEI 537 assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei()); 538 // IMEISV 539 assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn()); 540 // radio capability 541 verify(mSimulatedCommandsVerifier).getNetworkSelectionMode(nullable(Message.class)); 542 543 switchToCdma(); // this leads to eventRadioAvailable handling on cdma 544 545 // EVENT_RADIO_AVAILABLE 546 verify(mSimulatedCommandsVerifier, times(2)).getBasebandVersion(nullable(Message.class)); 547 verify(mSimulatedCommandsVerifier, times(2)).getDeviceIdentity(nullable(Message.class)); 548 verify(mSimulatedCommandsVerifier, times(3)).startLceService(anyInt(), anyBoolean(), 549 nullable(Message.class)); 550 551 // EVENT_RADIO_ON 552 verify(mSimulatedCommandsVerifier, times(2)).getVoiceRadioTechnology( 553 nullable(Message.class)); 554 // once on radio on, and once on get baseband version 555 verify(mSimulatedCommandsVerifier, times(3)).setPreferredNetworkType( 556 eq(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA), nullable(Message.class)); 557 558 // verify responses for above requests: 559 // baseband version 560 verify(mTelephonyManager, times(2)).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()), 561 nullable(String.class)); 562 // device identity 563 assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei()); 564 assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn()); 565 assertEquals(SimulatedCommands.FAKE_ESN, mPhoneUT.getEsn()); 566 assertEquals(SimulatedCommands.FAKE_MEID, mPhoneUT.getMeid()); 567 } 568 569 @Test 570 @SmallTest 571 public void testEmergencyCallbackMessages() { 572 verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(), 573 nullable(Object.class)); 574 verify(mSimulatedCommandsVerifier).registerForExitEmergencyCallbackMode(eq(mPhoneUT), 575 anyInt(), nullable(Object.class)); 576 577 // verify handling of emergency callback mode 578 mSimulatedCommands.notifyEmergencyCallbackMode(); 579 waitForMs(50); 580 581 // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED 582 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 583 try { 584 verify(mIActivityManager, atLeast(1)).broadcastIntent(eq((IApplicationThread)null), 585 intentArgumentCaptor.capture(), 586 eq((String)null), 587 eq((IIntentReceiver)null), 588 eq(Activity.RESULT_OK), 589 eq((String)null), 590 eq((Bundle)null), 591 eq((String[])null), 592 anyInt(), 593 eq((Bundle)null), 594 eq(false), 595 eq(true), 596 anyInt()); 597 } catch(Exception e) { 598 fail("Unexpected exception: " + e.getStackTrace()); 599 } 600 601 Intent intent = intentArgumentCaptor.getValue(); 602 assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction()); 603 assertEquals(true, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false)); 604 605 // verify that wakeLock is acquired in ECM 606 assertEquals(true, mPhoneUT.getWakeLock().isHeld()); 607 608 mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null); 609 mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null); 610 611 // verify handling of emergency callback mode exit 612 mSimulatedCommands.notifyExitEmergencyCallbackMode(); 613 waitForMs(50); 614 615 // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED 616 try { 617 verify(mIActivityManager, atLeast(2)).broadcastIntent(eq((IApplicationThread)null), 618 intentArgumentCaptor.capture(), 619 eq((String)null), 620 eq((IIntentReceiver)null), 621 eq(Activity.RESULT_OK), 622 eq((String)null), 623 eq((Bundle)null), 624 eq((String[])null), 625 anyInt(), 626 eq((Bundle)null), 627 eq(false), 628 eq(true), 629 anyInt()); 630 } catch(Exception e) { 631 fail("Unexpected exception: " + e.getStackTrace()); 632 } 633 634 intent = intentArgumentCaptor.getValue(); 635 assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction()); 636 assertEquals(false, intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, true)); 637 638 ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); 639 640 // verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified 641 verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(), 642 anyLong()); 643 List<Message> msgList = messageArgumentCaptor.getAllValues(); 644 assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what); 645 assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what); 646 647 // verify setInternalDataEnabled 648 verify(mDcTracker).setInternalDataEnabled(true); 649 650 // verify wakeLock released 651 assertEquals(false, mPhoneUT.getWakeLock().isHeld()); 652 } 653 654 @Test 655 @SmallTest 656 public void testCallForwardingIndicator() { 657 doReturn(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN).when(mSimRecords). 658 getVoiceCallForwardingFlag(); 659 660 // invalid subId 661 doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionController). 662 getSubIdUsingPhoneId(anyInt()); 663 assertEquals(false, mPhoneUT.getCallForwardingIndicator()); 664 665 // valid subId, sharedPreference not present 666 int subId1 = 0; 667 int subId2 = 1; 668 doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt()); 669 assertEquals(false, mPhoneUT.getCallForwardingIndicator()); 670 671 // old sharedPreference present 672 String imsi = "1234"; 673 doReturn(imsi).when(mSimRecords).getIMSI(); 674 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 675 SharedPreferences.Editor editor = sp.edit(); 676 editor.putString(Phone.CF_ID, imsi); 677 editor.putInt(Phone.CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_ENABLED); 678 editor.apply(); 679 assertEquals(true, mPhoneUT.getCallForwardingIndicator()); 680 681 // old sharedPreference should be removed now 682 assertEquals(null, sp.getString(Phone.CF_ID, null)); 683 assertEquals(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN, 684 sp.getInt(Phone.CF_ID, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN)); 685 686 // now verify value from new sharedPreference 687 assertEquals(true, mPhoneUT.getCallForwardingIndicator()); 688 689 // check for another subId 690 doReturn(subId2).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt()); 691 assertEquals(false, mPhoneUT.getCallForwardingIndicator()); 692 693 // set value for the new subId in sharedPreference 694 editor.putInt(Phone.CF_STATUS + subId2, IccRecords.CALL_FORWARDING_STATUS_ENABLED); 695 editor.apply(); 696 assertEquals(true, mPhoneUT.getCallForwardingIndicator()); 697 698 // switching back to previous subId, stored value should still be available 699 doReturn(subId1).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt()); 700 assertEquals(true, mPhoneUT.getCallForwardingIndicator()); 701 702 // cleanup 703 editor.remove(Phone.CF_STATUS + subId1); 704 editor.remove(Phone.CF_STATUS + subId2); 705 editor.apply(); 706 } 707 708 @Test 709 @SmallTest 710 public void testEriLoading() { 711 mPhoneUT.mEriManager = mEriManager; 712 mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_CARRIER_CONFIG_CHANGED, 713 null)); 714 waitForMs(100); 715 verify(mEriManager, times(1)).loadEriFile(); 716 } 717} 718