GsmCdmaCallTrackerTest.java revision 316deb284df5aff89060007fc7500996dd991ca2
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 */ 16package com.android.internal.telephony; 17 18import android.os.HandlerThread; 19import android.os.PersistableBundle; 20import android.telephony.CarrierConfigManager; 21import android.telephony.DisconnectCause; 22import android.telephony.PhoneNumberUtils; 23import android.telephony.ServiceState; 24import android.test.suitebuilder.annotation.MediumTest; 25import android.test.suitebuilder.annotation.SmallTest; 26 27import android.os.Message; 28import org.junit.After; 29import org.junit.Assert; 30import org.junit.Before; 31import org.junit.Test; 32import org.mockito.Mock; 33import org.mockito.ArgumentCaptor; 34import android.os.Handler; 35 36import static org.junit.Assert.assertNotNull; 37import static org.mockito.Mockito.doReturn; 38import static org.junit.Assert.assertEquals; 39import static org.mockito.Mockito.*; 40import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 41 42 43public class GsmCdmaCallTrackerTest extends TelephonyTest { 44 private static final int VOICE_CALL_STARTED_EVENT = 0; 45 private static final int VOICE_CALL_ENDED_EVENT = 1; 46 private String mDialString = PhoneNumberUtils.stripSeparators("+17005554141"); 47 /* Handler class initiated at the HandlerThread */ 48 private GsmCdmaCallTracker mCTUT; 49 private GsmCdmaCTHandlerThread mGsmCdmaCTHandlerThread; 50 @Mock 51 GsmCdmaCall mCall; 52 @Mock 53 private Handler mHandler; 54 55 private class GsmCdmaCTHandlerThread extends HandlerThread { 56 57 private GsmCdmaCTHandlerThread(String name) { 58 super(name); 59 } 60 @Override 61 public void onLooperPrepared() { 62 mCTUT = new GsmCdmaCallTracker(mPhone); 63 setReady(true); 64 } 65 } 66 67 @Before 68 public void setUp() throws Exception { 69 super.setUp(this.getClass().getSimpleName()); 70 mSimulatedCommands.setRadioPower(true, null); 71 mPhone.mCi = this.mSimulatedCommands; 72 73 mGsmCdmaCTHandlerThread = new GsmCdmaCTHandlerThread(TAG); 74 mGsmCdmaCTHandlerThread.start(); 75 76 waitUntilReady(); 77 logd("GsmCdmaCallTracker initiated, waiting for Power on"); 78 /* Make sure radio state is power on before dial. 79 * When radio state changed from off to on, CallTracker 80 * will poll result from RIL. Avoid dialing triggered at the same*/ 81 waitForMs(100); 82 } 83 84 @After 85 public void tearDown() throws Exception { 86 mCTUT = null; 87 mGsmCdmaCTHandlerThread.quitSafely(); 88 super.tearDown(); 89 } 90 91 @Test 92 @SmallTest 93 public void testMOCallDial() { 94 doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState(); 95 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 96 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 97 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 98 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 99 try { 100 mCTUT.dial(mDialString); 101 waitForMs(100); 102 } catch(Exception ex) { 103 ex.printStackTrace(); 104 Assert.fail("unexpected exception thrown"+ex.getMessage()+ex.getStackTrace()); 105 } 106 107 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 108 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 109 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 110 /* verify the command is sent out to RIL */ 111 verify(mSimulatedCommandsVerifier).dial(eq(PhoneNumberUtils. 112 extractNetworkPortionAlt(mDialString)), anyInt(), 113 eq((UUSInfo) null), 114 isA(Message.class)); 115 } 116 117 @Test 118 @SmallTest 119 public void testMOCallPickUp() { 120 testMOCallDial(); 121 logd("Waiting for POLL CALL response from RIL"); 122 TelephonyTestUtils.waitForMs(50); 123 logd("Pick Up MO call, expecting call state change event "); 124 mSimulatedCommands.progressConnectingToActive(); 125 waitForMs(100); 126 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 127 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 128 } 129 130 @Test 131 @MediumTest 132 public void testMOCallHangup() { 133 testMOCallDial(); 134 logd("Waiting for POLL CALL response from RIL "); 135 TelephonyTestUtils.waitForMs(50); 136 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 137 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 138 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 139 logd("Hang up MO call after MO call established "); 140 try { 141 mCTUT.hangup(mCTUT.mForegroundCall); 142 } catch(Exception ex) { 143 ex.printStackTrace(); 144 Assert.fail("unexpected exception thrown" + ex.getMessage()); 145 } 146 waitForMs(300); 147 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 148 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 149 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 150 } 151 152 @Test 153 @MediumTest 154 public void testMOCallDialPickUpHangup() { 155 testMOCallPickUp(); 156 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 157 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 158 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 159 /* get the reference of the connection before reject */ 160 Connection mConnection = mCTUT.mForegroundCall.getConnections().get(0); 161 assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause()); 162 logd("hang up MO call after pickup"); 163 try { 164 mCTUT.hangup(mCTUT.mForegroundCall); 165 } catch(Exception ex) { 166 ex.printStackTrace(); 167 Assert.fail("unexpected exception thrown" + ex.getMessage()); 168 } 169 /* request send to RIL still in disconnecting state */ 170 waitForMs(300); 171 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 172 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 173 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 174 assertEquals(DisconnectCause.LOCAL, mConnection.getDisconnectCause()); 175 176 } 177 178 @Test 179 @MediumTest 180 public void testMOCallPendingHangUp() { 181 testMOCallDial(); 182 logd("MO call hangup before established[ getting result from RIL ]"); 183 /* poll call result from RIL, find that there is a pendingMO call, 184 * Didn't do anything for hangup, clear during handle poll result */ 185 try { 186 mCTUT.hangup(mCTUT.mForegroundCall); 187 } catch(Exception ex) { 188 ex.printStackTrace(); 189 Assert.fail("unexpected exception thrown" + ex.getMessage()); 190 } 191 waitForMs(300); 192 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 193 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 194 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 195 } 196 197 @Test 198 @MediumTest 199 public void testMOCallSwitch() { 200 testMOCallPickUp(); 201 logd("MO call picked up, initiating a new MO call"); 202 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 203 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 204 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 205 assertEquals(0, mCTUT.mBackgroundCall.getConnections().size()); 206 207 String mDialString = PhoneNumberUtils.stripSeparators("+17005554142"); 208 try { 209 mCTUT.dial(mDialString); 210 } catch(Exception ex) { 211 ex.printStackTrace(); 212 Assert.fail("unexpected exception thrown" + ex.getMessage()); 213 } 214 waitForMs(200); 215 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 216 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 217 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 218 assertEquals(1, mCTUT.mBackgroundCall.getConnections().size()); 219 220 } 221 222 @Test 223 @SmallTest 224 public void testMTCallRinging() { 225 /* Mock there is a MT call mRinging call and try to accept this MT call */ 226 /* if we got a active state followed by another MT call-> move to background call */ 227 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 228 assertEquals(0, mCTUT.mRingingCall.getConnections().size()); 229 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 230 String mDialString = PhoneNumberUtils.stripSeparators("+17005554141"); 231 logd("MT call Ringing"); 232 mSimulatedCommands.triggerRing(mDialString); 233 waitForMs(50); 234 assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); 235 assertEquals(1, mCTUT.mRingingCall.getConnections().size()); 236 } 237 238 @Test 239 @SmallTest 240 public void testMTCallAccept() { 241 testMTCallRinging(); 242 assertEquals(mCTUT.mForegroundCall.getConnections().size(),0); 243 logd("accept the MT call"); 244 try{ 245 mCTUT.acceptCall(); 246 } catch(Exception ex) { 247 ex.printStackTrace(); 248 Assert.fail("unexpected exception thrown" + ex.getMessage()); 249 } 250 verify(mSimulatedCommandsVerifier).acceptCall(isA(Message.class)); 251 /* send to the RIL */ 252 TelephonyTestUtils.waitForMs(50); 253 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 254 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 255 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 256 assertEquals(0, mCTUT.mRingingCall.getConnections().size()); 257 } 258 259 @Test 260 @SmallTest 261 public void testMTCallReject() { 262 testMTCallRinging(); 263 logd("MT call ringing and rejected "); 264 /* get the reference of the connection before reject */ 265 Connection mConnection = mCTUT.mRingingCall.getConnections().get(0); 266 assertNotNull(mConnection); 267 assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause()); 268 try { 269 mCTUT.rejectCall(); 270 } catch(Exception ex) { 271 ex.printStackTrace(); 272 Assert.fail("unexpected exception thrown" + ex.getMessage()); 273 } 274 waitForMs(50); 275 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 276 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 277 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 278 /* ? why rejectCall didnt -> hang up locally to set the cause to LOCAL? */ 279 assertEquals(DisconnectCause.INCOMING_MISSED, mConnection.getDisconnectCause()); 280 281 } 282 283 @Test 284 @MediumTest 285 public void testMOCallSwitchHangupForeGround() { 286 testMOCallSwitch(); 287 logd("Hang up the foreground MO call while dialing "); 288 try { 289 mCTUT.hangup(mCTUT.mForegroundCall); 290 } catch(Exception ex) { 291 ex.printStackTrace(); 292 Assert.fail("unexpected exception thrown" + ex.getMessage()); 293 } 294 waitForMs(300); 295 logd(" Foreground Call is IDLE and BackGround Call is still HOLDING "); 296 /* if we want to hang up foreground call which is alerting state, hangup all */ 297 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 298 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 299 } 300 301 @Test 302 @MediumTest 303 public void testMOCallPickUpHangUpResumeBackGround() { 304 testMOCallSwitch(); 305 logd("Pick up the new MO Call"); 306 try{ 307 mSimulatedCommands.progressConnectingToActive(); 308 } catch(Exception ex) { 309 ex.printStackTrace(); 310 Assert.fail("unexpected exception thrown" + ex.getMessage()); 311 } 312 313 waitForMs(200); 314 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 315 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 316 317 logd("Hang up the new MO Call"); 318 try { 319 mCTUT.hangup(mCTUT.mForegroundCall); 320 } catch(Exception ex) { 321 ex.printStackTrace(); 322 Assert.fail("unexpected exception thrown" + ex.getMessage()); 323 } 324 325 waitForMs(300); 326 logd(" BackGround Call switch to ForeGround Call "); 327 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 328 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 329 } 330 331 @Test @SmallTest 332 public void testVoiceCallStartListener(){ 333 logd("register for voice call started event"); 334 mCTUT.registerForVoiceCallStarted(mHandler, VOICE_CALL_STARTED_EVENT, null); 335 logd("voice call started"); 336 testMOCallPickUp(); 337 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class); 338 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class); 339 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture()); 340 assertEquals(VOICE_CALL_STARTED_EVENT, mCaptorMessage.getValue().what); 341 342 } 343 344 @Test @SmallTest 345 public void testVoiceCallEndedListener(){ 346 logd("register for voice call ended event"); 347 mCTUT.registerForVoiceCallEnded(mHandler, VOICE_CALL_ENDED_EVENT, null); 348 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class); 349 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class); 350 testMOCallHangup(); 351 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture()); 352 assertEquals(VOICE_CALL_ENDED_EVENT, mCaptorMessage.getValue().what); 353 } 354 355 @Test @SmallTest 356 public void testUpdatePhoneType() { 357 // verify getCurrentCalls is called on init 358 verify(mSimulatedCommandsVerifier).getCurrentCalls(any(Message.class)); 359 360 // update phone type (call the function on same thread as the call tracker) 361 Handler updatePhoneTypeHandler = new Handler(mCTUT.getLooper()) { 362 @Override 363 public void handleMessage(Message msg) { 364 mCTUT.updatePhoneType(); 365 } 366 }; 367 updatePhoneTypeHandler.sendEmptyMessage(0); 368 waitForMs(100); 369 370 // verify getCurrentCalls is called on updating phone type 371 verify(mSimulatedCommandsVerifier, times(2)).getCurrentCalls(any(Message.class)); 372 373 // we'd like to verify that if phone type is updated, calls and callTracker go to idle. 374 // However, as soon as phone type is updated, call tracker queries for calls from RIL and 375 // will go back to OFFHOOK 376 377 // call tracker goes to OFFHOOK 378 testMOCallPickUp(); 379 380 // update phone type - call tracker goes to IDLE and then due to getCurrentCalls(), 381 // goes back to OFFHOOK 382 updatePhoneTypeHandler.sendEmptyMessage(0); 383 waitForMs(100); 384 385 // verify CT and calls go to idle 386 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 387 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 388 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 389 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mRingingCall.getState()); 390 } 391} 392 393