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