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