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.SystemProperties; 20import android.telephony.DisconnectCause; 21import android.telephony.PhoneNumberUtils; 22import android.telephony.ServiceState; 23import android.test.suitebuilder.annotation.SmallTest; 24 25import com.android.internal.telephony.test.SimulatedCommandsVerifier; 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.assertFalse; 36import static org.junit.Assert.assertNotNull; 37import static org.junit.Assert.assertTrue; 38import static org.mockito.Mockito.doReturn; 39import static org.junit.Assert.assertEquals; 40import static org.mockito.Mockito.*; 41import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 42 43 44public class GsmCdmaCallTrackerTest extends TelephonyTest { 45 private static final int VOICE_CALL_STARTED_EVENT = 0; 46 private static final int VOICE_CALL_ENDED_EVENT = 1; 47 private String mDialString = PhoneNumberUtils.stripSeparators("+17005554141"); 48 /* Handler class initiated at the HandlerThread */ 49 private GsmCdmaCallTracker mCTUT; 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 mContextFixture.putStringArrayResource(com.android.internal.R.array.dial_string_replace, 73 new String[]{}); 74 75 new GsmCdmaCTHandlerThread(TAG).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 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 } catch(Exception ex) { 102 ex.printStackTrace(); 103 Assert.fail("unexpected exception thrown"+ex.getMessage()+ex.getStackTrace()); 104 } 105 106 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 107 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 108 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 109 /* verify the command is sent out to RIL */ 110 verify(mSimulatedCommandsVerifier).dial(eq(PhoneNumberUtils. 111 extractNetworkPortionAlt(mDialString)), anyInt(), 112 eq((UUSInfo) null), 113 isA(Message.class)); 114 } 115 116 @Test 117 @SmallTest 118 public void testMOCallPickUp() { 119 testMOCallDial(); 120 logd("Waiting for POLL CALL response from RIL"); 121 TelephonyTestUtils.waitForMs(50); 122 logd("Pick Up MO call, expecting call state change event "); 123 mSimulatedCommands.progressConnectingToActive(); 124 waitForMs(100); 125 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 126 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 127 } 128 129 @Test 130 @SmallTest 131 public void testMOCallHangup() { 132 testMOCallDial(); 133 logd("Waiting for POLL CALL response from RIL "); 134 TelephonyTestUtils.waitForMs(50); 135 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 136 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 137 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 138 logd("Hang up MO call after MO call established "); 139 try { 140 mCTUT.hangup(mCTUT.mForegroundCall); 141 } catch(Exception ex) { 142 ex.printStackTrace(); 143 Assert.fail("unexpected exception thrown" + ex.getMessage()); 144 } 145 waitForMs(200); 146 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 147 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 148 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 149 } 150 151 @Test 152 @SmallTest 153 public void testMOCallDialPickUpHangup() { 154 testMOCallPickUp(); 155 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 156 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 157 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 158 /* get the reference of the connection before reject */ 159 Connection mConnection = mCTUT.mForegroundCall.getConnections().get(0); 160 assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause()); 161 logd("hang up MO call after pickup"); 162 try { 163 mCTUT.hangup(mCTUT.mForegroundCall); 164 } catch(Exception ex) { 165 ex.printStackTrace(); 166 Assert.fail("unexpected exception thrown" + ex.getMessage()); 167 } 168 /* request send to RIL still in disconnecting state */ 169 waitForMs(200); 170 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 171 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 172 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 173 assertEquals(DisconnectCause.LOCAL, mConnection.getDisconnectCause()); 174 175 } 176 177 @Test 178 @SmallTest 179 public void testMOCallPendingHangUp() { 180 testMOCallDial(); 181 logd("MO call hangup before established[ getting result from RIL ]"); 182 /* poll call result from RIL, find that there is a pendingMO call, 183 * Didn't do anything for hangup, clear during handle poll result */ 184 try { 185 mCTUT.hangup(mCTUT.mForegroundCall); 186 } catch(Exception ex) { 187 ex.printStackTrace(); 188 Assert.fail("unexpected exception thrown" + ex.getMessage()); 189 } 190 waitForMs(200); 191 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 192 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 193 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 194 } 195 196 @Test 197 @SmallTest 198 public void testMOCallSwitch() { 199 testMOCallPickUp(); 200 logd("MO call picked up, initiating a new MO call"); 201 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 202 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 203 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 204 assertEquals(0, mCTUT.mBackgroundCall.getConnections().size()); 205 206 String mDialString = PhoneNumberUtils.stripSeparators("+17005554142"); 207 try { 208 mCTUT.dial(mDialString); 209 } catch(Exception ex) { 210 ex.printStackTrace(); 211 Assert.fail("unexpected exception thrown" + ex.getMessage()); 212 } 213 waitForMs(200); 214 assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState()); 215 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 216 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 217 assertEquals(1, mCTUT.mBackgroundCall.getConnections().size()); 218 219 } 220 221 @Test 222 @SmallTest 223 public void testMTCallRinging() { 224 /* Mock there is a MT call mRinging call and try to accept this MT call */ 225 /* if we got a active state followed by another MT call-> move to background call */ 226 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 227 assertEquals(0, mCTUT.mRingingCall.getConnections().size()); 228 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 229 String mDialString = PhoneNumberUtils.stripSeparators("+17005554141"); 230 logd("MT call Ringing"); 231 mSimulatedCommands.triggerRing(mDialString); 232 waitForMs(50); 233 assertEquals(PhoneConstants.State.RINGING, mCTUT.getState()); 234 assertEquals(1, mCTUT.mRingingCall.getConnections().size()); 235 } 236 237 @Test 238 @SmallTest 239 public void testMTCallAccept() { 240 testMTCallRinging(); 241 assertEquals(mCTUT.mForegroundCall.getConnections().size(),0); 242 logd("accept the MT call"); 243 try{ 244 mCTUT.acceptCall(); 245 } catch(Exception ex) { 246 ex.printStackTrace(); 247 Assert.fail("unexpected exception thrown" + ex.getMessage()); 248 } 249 verify(mSimulatedCommandsVerifier).acceptCall(isA(Message.class)); 250 /* send to the RIL */ 251 TelephonyTestUtils.waitForMs(50); 252 assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState()); 253 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 254 assertEquals(1, mCTUT.mForegroundCall.getConnections().size()); 255 assertEquals(0, mCTUT.mRingingCall.getConnections().size()); 256 } 257 258 @Test 259 @SmallTest 260 public void testMTCallReject() { 261 testMTCallRinging(); 262 logd("MT call ringing and rejected "); 263 /* get the reference of the connection before reject */ 264 Connection mConnection = mCTUT.mRingingCall.getConnections().get(0); 265 assertNotNull(mConnection); 266 assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause()); 267 try { 268 mCTUT.rejectCall(); 269 } catch(Exception ex) { 270 ex.printStackTrace(); 271 Assert.fail("unexpected exception thrown" + ex.getMessage()); 272 } 273 waitForMs(50); 274 assertEquals(PhoneConstants.State.IDLE, mCTUT.getState()); 275 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 276 assertEquals(0, mCTUT.mForegroundCall.getConnections().size()); 277 /* ? why rejectCall didnt -> hang up locally to set the cause to LOCAL? */ 278 assertEquals(DisconnectCause.INCOMING_MISSED, mConnection.getDisconnectCause()); 279 280 } 281 282 @Test 283 @SmallTest 284 public void testMOCallSwitchHangupForeGround() { 285 testMOCallSwitch(); 286 logd("Hang up the foreground MO call while dialing "); 287 try { 288 mCTUT.hangup(mCTUT.mForegroundCall); 289 } catch(Exception ex) { 290 ex.printStackTrace(); 291 Assert.fail("unexpected exception thrown" + ex.getMessage()); 292 } 293 waitForMs(200); 294 logd(" Foreground Call is IDLE and BackGround Call is still HOLDING "); 295 /* if we want to hang up foreground call which is alerting state, hangup all */ 296 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState()); 297 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 298 } 299 300 @Test 301 @SmallTest 302 public void testMOCallPickUpHangUpResumeBackGround() { 303 testMOCallSwitch(); 304 logd("Pick up the new MO Call"); 305 try{ 306 mSimulatedCommands.progressConnectingToActive(); 307 } catch(Exception ex) { 308 ex.printStackTrace(); 309 Assert.fail("unexpected exception thrown" + ex.getMessage()); 310 } 311 312 waitForMs(200); 313 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 314 assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState()); 315 316 logd("Hang up the new MO Call"); 317 try { 318 mCTUT.hangup(mCTUT.mForegroundCall); 319 } catch(Exception ex) { 320 ex.printStackTrace(); 321 Assert.fail("unexpected exception thrown" + ex.getMessage()); 322 } 323 324 waitForMs(200); 325 logd(" BackGround Call switch to ForeGround Call "); 326 assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState()); 327 assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState()); 328 } 329 330 @Test @SmallTest 331 public void testVoiceCallStartListener(){ 332 logd("register for voice call started event"); 333 mCTUT.registerForVoiceCallStarted(mHandler, VOICE_CALL_STARTED_EVENT, null); 334 logd("voice call started"); 335 testMOCallPickUp(); 336 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class); 337 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class); 338 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture()); 339 assertEquals(VOICE_CALL_STARTED_EVENT, mCaptorMessage.getValue().what); 340 341 } 342 343 @Test @SmallTest 344 public void testVoiceCallEndedListener(){ 345 logd("register for voice call ended event"); 346 mCTUT.registerForVoiceCallEnded(mHandler, VOICE_CALL_ENDED_EVENT, null); 347 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class); 348 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class); 349 testMOCallHangup(); 350 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture()); 351 assertEquals(VOICE_CALL_ENDED_EVENT, mCaptorMessage.getValue().what); 352 } 353 354 @Test @SmallTest 355 public void testUpdatePhoneType() { 356 // verify getCurrentCalls is called on init 357 verify(mSimulatedCommandsVerifier).getCurrentCalls(any(Message.class)); 358 359 // update phone type 360 mCTUT.updatePhoneType(); 361 362 // verify getCurrentCalls is called on updating phone type 363 verify(mSimulatedCommandsVerifier, times(2)).getCurrentCalls(any(Message.class)); 364 } 365} 366 367