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