2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.android.internal.telephony;
18 import android.os.HandlerThread;
19 import android.os.SystemProperties;
20 import android.telephony.DisconnectCause;
21 import android.telephony.PhoneNumberUtils;
22 import android.telephony.ServiceState;
23 import android.test.suitebuilder.annotation.SmallTest;
24 import android.util.Log;
25 import com.android.internal.telephony.test.SimulatedCommands;
26 import com.android.internal.telephony.test.SimulatedCommandsVerifier;
27 import android.os.Message;
28 import org.junit.After;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.mockito.Mock;
33 import org.mockito.MockitoAnnotations;
34 import org.mockito.ArgumentCaptor;
35 import android.os.Handler;
36 import android.util.SparseArray;
38 import static org.junit.Assert.assertFalse;
39 import static org.junit.Assert.assertNotNull;
40 import static org.mockito.Mockito.doReturn;
41 import static org.junit.Assert.assertEquals;
42 import static org.mockito.Mockito.*;
44 import java.lang.reflect.Field;
46 public class GsmCdmaCallTrackerTest {
47 private static final String TAG = "GsmCdmaCallTrackerTest";
48 private static final int VOICE_CALL_STARTED_EVENT = 0;
49 private static final int VOICE_CALL_ENDED_EVENT = 1;
50 private Object mLock = new Object();
51 private boolean mReady = false;
52 private SimulatedCommands mCi;
53 private ContextFixture mcontextFixture;
55 String mDialString = PhoneNumberUtils.stripSeparators("+17005554141");
56 /* Handler class initiated at the HandlerThread */
57 private GsmCdmaCallTracker mCT;
63 ServiceState mServiceState;
65 private SimulatedCommandsVerifier mSimulatedCommandsVerifier;
67 private Handler mHandler;
69 private TelephonyEventLog mTelephonyEventLog;
71 private class GsmCdmaCTHandlerThread extends HandlerThread {
73 private GsmCdmaCTHandlerThread(String name) {
77 public void onLooperPrepared() {
78 synchronized (mLock) {
79 mCT = TelephonyComponentFactory.getInstance().makeGsmCdmaCallTracker(mPhone);
85 private void waitUntilReady() {
87 synchronized (mLock) {
96 public void setUp() throws Exception {
97 MockitoAnnotations.initMocks(this);
98 mcontextFixture = new ContextFixture();
99 mCi = new SimulatedCommands();
100 mCi.setRadioPower(true, null);
101 mPhone.mCi = this.mCi;
102 doReturn(mServiceState).when(mPhone).getServiceState();
103 doReturn(mcontextFixture.getTestDouble()).when(mPhone).getContext();
104 doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType();
105 doReturn(true).when(mPhone).isPhoneTypeGsm();
106 mcontextFixture.putStringArrayResource(com.android.internal.R.array.dial_string_replace,
108 Field field = SimulatedCommandsVerifier.class.getDeclaredField("sInstance");
109 field.setAccessible(true);
110 field.set(null, mSimulatedCommandsVerifier);
113 field = TelephonyEventLog.class.getDeclaredField("sInstances");
114 field.setAccessible(true);
115 SparseArray<TelephonyEventLog> mTelephonyEventArr = new SparseArray<TelephonyEventLog>();
116 mTelephonyEventArr.put(mPhone.getPhoneId(), mTelephonyEventLog);
117 field.set(null,mTelephonyEventArr);
119 new GsmCdmaCTHandlerThread(TAG).start();
122 logd("GsmCdmaCallTracker initiated");
123 logd("Waiting for Power on");
124 /* Make sure radio state is power on before dial.
125 * When radio state changed from off to on, CallTracker
126 * will poll result from RIL. Avoid dialing triggered at the same*/
127 TelephonyTestUtils.waitForMs(100);
131 public void tearDown() throws Exception {
137 public void testMOCallDial() {
138 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
139 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
140 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.IDLE);
141 assertEquals(mCT.mForegroundCall.getConnections().size(), 0);
143 assertFalse(mPhone.getServiceState().getState()!= ServiceState.STATE_POWER_OFF);
144 assertFalse(mCT.mRingingCall.isRinging());
145 assertFalse(mCT.mForegroundCall.getState().isAlive());
146 assertFalse(!SystemProperties.get(
147 TelephonyProperties.PROPERTY_DISABLE_CALL, "false").equals("true"));
150 mCT.dial(mDialString);
151 } catch(Exception ex) {
152 ex.printStackTrace();
153 Assert.fail("unexpected exception thrown"+ex.getMessage());
156 assertEquals(mCT.getState(), PhoneConstants.State.OFFHOOK);
157 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.DIALING);
158 assertEquals(mCT.mForegroundCall.getConnections().size(), 1);
159 /* verify the command is sent out to RIL */
160 verify(mSimulatedCommandsVerifier).dial(eq(PhoneNumberUtils.
161 extractNetworkPortionAlt(mDialString)), anyInt(),
168 public void testMOCallPickUp() {
170 logd("Waiting for POLL CALL response from RIL");
171 TelephonyTestUtils.waitForMs(50);
172 logd("Pick Up MO call, expecting call state change event ");
173 mCi.progressConnectingToActive();
174 TelephonyTestUtils.waitForMs(100);
175 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
176 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.IDLE);
181 public void testMOCallHangup() {
183 logd("Waiting for POLL CALL response from RIL ");
184 TelephonyTestUtils.waitForMs(50);
185 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.DIALING);
186 assertEquals(mCT.getState(), PhoneConstants.State.OFFHOOK);
187 assertEquals(mCT.mForegroundCall.getConnections().size(), 1);
188 logd("Hang up MO call after MO call established ");
190 mCT.hangup(mCT.mForegroundCall);
191 } catch(Exception ex) {
192 ex.printStackTrace();
193 Assert.fail("unexpected exception thrown" + ex.getMessage());
195 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.DISCONNECTING);
196 /* request send to RIL still in disconnecting state */
197 TelephonyTestUtils.waitForMs(50);
198 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
199 assertEquals(mCT.mForegroundCall.getConnections().size(),0);
200 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
205 public void testMOCallDialPickUpHangup() {
207 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
208 assertEquals(mCT.getState(), PhoneConstants.State.OFFHOOK);
209 assertEquals(mCT.mForegroundCall.getConnections().size(),1);
210 /* get the reference of the connection before reject */
211 Connection mConnection = mCT.mForegroundCall.getConnections().get(0);
212 assertEquals(mConnection.getDisconnectCause(), DisconnectCause.NOT_DISCONNECTED);
213 logd("hang up MO call after pickup");
215 mCT.hangup(mCT.mForegroundCall);
216 } catch(Exception ex) {
217 ex.printStackTrace();
218 Assert.fail("unexpected exception thrown" + ex.getMessage());
220 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.DISCONNECTING);
221 /* request send to RIL still in disconnecting state */
222 TelephonyTestUtils.waitForMs(50);
223 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
224 assertEquals(mCT.mForegroundCall.getConnections().size(), 0);
225 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
226 assertEquals(mConnection.getDisconnectCause(), DisconnectCause.LOCAL);
232 public void testMOCallPendingHangUp() {
234 logd("MO call hangup before established[ getting result from RIL ]");
235 /* poll call result from RIL, find that there is a pendingMO call,
236 * Didn't do anything for hangup, clear during handle poll result */
238 mCT.hangup(mCT.mForegroundCall);
239 } catch(Exception ex) {
240 ex.printStackTrace();
241 Assert.fail("unexpected exception thrown" + ex.getMessage());
243 TelephonyTestUtils.waitForMs(50);
244 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
245 assertEquals(mCT.mForegroundCall.getConnections().size(),0);
246 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
251 public void testMOCallSwitch() {
253 logd("MO call picked up, initiating a new MO call");
254 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
255 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.IDLE);
256 assertEquals(mCT.mForegroundCall.getConnections().size(), 1);
257 assertEquals(mCT.mBackgroundCall.getConnections().size(), 0);
259 String mDialString = PhoneNumberUtils.stripSeparators("+17005554142");
261 mCT.dial(mDialString);
262 } catch(Exception ex) {
263 ex.printStackTrace();
264 Assert.fail("unexpected exception thrown" + ex.getMessage());
266 TelephonyTestUtils.waitForMs(100);
267 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.DIALING);
268 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.HOLDING);
269 assertEquals(mCT.mForegroundCall.getConnections().size(), 1);
270 assertEquals(mCT.mBackgroundCall.getConnections().size(), 1);
276 public void testMTCallRinging() {
277 /* Mock there is a MT call mRinging call and try to accept this MT call */
278 /* if we got a active state followed by another MT call-> move to background call */
279 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
280 assertEquals(mCT.mRingingCall.getConnections().size(), 0);
281 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
282 String mDialString = PhoneNumberUtils.stripSeparators("+17005554141");
283 logd("MT call Ringing");
284 mCi.triggerRing(mDialString);
285 TelephonyTestUtils.waitForMs(50);
286 assertEquals(mCT.getState(), PhoneConstants.State.RINGING);
287 assertEquals(mCT.mRingingCall.getConnections().size(), 1);
292 public void testMTCallAccept() {
294 assertEquals(mCT.mForegroundCall.getConnections().size(),0);
295 logd("accept the MT call");
298 } catch(Exception ex) {
299 ex.printStackTrace();
300 Assert.fail("unexpected exception thrown" + ex.getMessage());
302 verify(mSimulatedCommandsVerifier).acceptCall(isA(Message.class));
303 /* send to the RIL */
304 TelephonyTestUtils.waitForMs(50);
305 assertEquals(mCT.getState(), PhoneConstants.State.OFFHOOK);
306 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
307 assertEquals(mCT.mForegroundCall.getConnections().size(),1);
308 assertEquals(mCT.mRingingCall.getConnections().size(),0);
313 public void testMTCallReject() {
315 logd("MT call ringing and rejected ");
316 /* get the reference of the connection before reject */
317 Connection mConnection = mCT.mRingingCall.getConnections().get(0);
318 assertNotNull(mConnection);
319 assertEquals(mConnection.getDisconnectCause(), DisconnectCause.NOT_DISCONNECTED);
322 } catch(Exception ex) {
323 ex.printStackTrace();
324 Assert.fail("unexpected exception thrown" + ex.getMessage());
326 TelephonyTestUtils.waitForMs(50);
327 assertEquals(mCT.getState(), PhoneConstants.State.IDLE);
328 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
329 assertEquals(mCT.mForegroundCall.getConnections().size(), 0);
330 /* ? why rejectCall didnt -> hang up locally to set the cause to LOCAL? */
331 assertEquals(mConnection.getDisconnectCause(), DisconnectCause.INCOMING_MISSED);
337 public void testMOCallSwitchHangupForeGround() {
339 logd("Hang up the foreground MO call while dialing ");
341 mCT.hangup(mCT.mForegroundCall);
342 } catch(Exception ex) {
343 ex.printStackTrace();
344 Assert.fail("unexpected exception thrown" + ex.getMessage());
346 TelephonyTestUtils.waitForMs(100);
347 logd(" Foreground Call is IDLE and BackGround Call is still HOLDING ");
348 /* if we want to hang up foreground call which is alerting state, hangup all */
349 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.IDLE);
350 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.HOLDING);
355 public void testMOCallPickUpHangUpResumeBackGround() {
357 logd("Pick up the new MO Call");
359 mCi.progressConnectingToActive();
360 } catch(Exception ex) {
361 ex.printStackTrace();
362 Assert.fail("unexpected exception thrown" + ex.getMessage());
365 TelephonyTestUtils.waitForMs(100);
366 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
367 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.HOLDING);
369 logd("Hang up the new MO Call");
371 mCT.hangup(mCT.mForegroundCall);
372 } catch(Exception ex) {
373 ex.printStackTrace();
374 Assert.fail("unexpected exception thrown" + ex.getMessage());
377 TelephonyTestUtils.waitForMs(100);
378 logd(" BackGround Call switch to ForeGround Call ");
379 assertEquals(mCT.mForegroundCall.getState(), GsmCdmaCall.State.ACTIVE);
380 assertEquals(mCT.mBackgroundCall.getState(), GsmCdmaCall.State.IDLE);
384 public void testVoiceCallStartListener(){
385 logd("register for voice call started event");
386 mCT.registerForVoiceCallStarted(mHandler, VOICE_CALL_STARTED_EVENT, null);
387 logd("voice call started");
389 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
390 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class);
391 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture());
392 assertEquals(VOICE_CALL_STARTED_EVENT, mCaptorMessage.getValue().what);
397 public void testVoiceCallEndedListener(){
398 logd("register for voice call ended event");
399 mCT.registerForVoiceCallEnded(mHandler, VOICE_CALL_ENDED_EVENT, null);
400 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
401 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class);
403 verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture());
404 assertEquals(VOICE_CALL_ENDED_EVENT, mCaptorMessage.getValue().what);
407 private static void logd(String s) {