Fixed file descriptor leak in telephony unit tests
[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.quit();
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     @FlakyTest
136     @Ignore
137     @Test
138     @MediumTest
139     public void testMOCallHangup() {
140         testMOCallDial();
141         logd("Waiting for POLL CALL response from RIL ");
142         TelephonyTestUtils.waitForMs(50);
143         assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState());
144         assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
145         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
146         logd("Hang up MO call after MO call established ");
147         try {
148             mCTUT.hangup(mCTUT.mForegroundCall);
149         } catch(Exception ex) {
150             ex.printStackTrace();
151             Assert.fail("unexpected exception thrown" + ex.getMessage());
152         }
153         waitForMs(300);
154         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
155         assertEquals(0, mCTUT.mForegroundCall.getConnections().size());
156         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
157     }
158
159     @FlakyTest
160     @Ignore
161     @Test
162     @MediumTest
163     public void testMOCallDialPickUpHangup() {
164         testMOCallPickUp();
165         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
166         assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
167         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
168          /* get the reference of the connection before reject */
169         Connection mConnection = mCTUT.mForegroundCall.getConnections().get(0);
170         assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause());
171         logd("hang up MO call after pickup");
172         try {
173             mCTUT.hangup(mCTUT.mForegroundCall);
174         } catch(Exception ex) {
175             ex.printStackTrace();
176             Assert.fail("unexpected exception thrown" + ex.getMessage());
177         }
178         /* request send to RIL still in disconnecting state */
179         waitForMs(300);
180         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
181         assertEquals(0, mCTUT.mForegroundCall.getConnections().size());
182         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
183         assertEquals(DisconnectCause.LOCAL, mConnection.getDisconnectCause());
184
185     }
186
187     @FlakyTest
188     @Test
189     @MediumTest
190     public void testMOCallPendingHangUp() {
191         testMOCallDial();
192         logd("MO call hangup before established[ getting result from RIL ]");
193         /* poll call result from RIL, find that there is a pendingMO call,
194          * Didn't do anything for hangup, clear during handle poll result */
195         try {
196             mCTUT.hangup(mCTUT.mForegroundCall);
197         } catch(Exception ex) {
198             ex.printStackTrace();
199             Assert.fail("unexpected exception thrown" + ex.getMessage());
200         }
201         waitForMs(300);
202         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
203         assertEquals(0, mCTUT.mForegroundCall.getConnections().size());
204         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
205     }
206
207     @Test
208     @MediumTest
209     public void testMOCallSwitch() {
210         testMOCallPickUp();
211         logd("MO call picked up, initiating a new MO call");
212         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
213         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState());
214         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
215         assertEquals(0, mCTUT.mBackgroundCall.getConnections().size());
216
217         String mDialString = PhoneNumberUtils.stripSeparators("+17005554142");
218         try {
219             mCTUT.dial(mDialString);
220         } catch(Exception ex) {
221             ex.printStackTrace();
222             Assert.fail("unexpected exception thrown" + ex.getMessage());
223         }
224         waitForMs(200);
225         assertEquals(GsmCdmaCall.State.DIALING, mCTUT.mForegroundCall.getState());
226         assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState());
227         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
228         assertEquals(1, mCTUT.mBackgroundCall.getConnections().size());
229
230     }
231
232     @Test
233     @SmallTest
234     @FlakyTest
235     @Ignore
236     public void testMTCallRinging() {
237         /* Mock there is a MT call mRinging call and try to accept this MT call */
238         /* if we got a active state followed by another MT call-> move to background call */
239         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
240         assertEquals(0, mCTUT.mRingingCall.getConnections().size());
241         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
242         String mDialString = PhoneNumberUtils.stripSeparators("+17005554141");
243         logd("MT call Ringing");
244         mSimulatedCommands.triggerRing(mDialString);
245         waitForMs(50);
246         assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
247         assertEquals(1, mCTUT.mRingingCall.getConnections().size());
248     }
249
250     @Test
251     @SmallTest
252     @FlakyTest
253     @Ignore
254     public void testMTCallAccept() {
255         testMTCallRinging();
256         assertEquals(mCTUT.mForegroundCall.getConnections().size(),0);
257         logd("accept the MT call");
258         try{
259             mCTUT.acceptCall();
260         } catch(Exception ex) {
261             ex.printStackTrace();
262             Assert.fail("unexpected exception thrown" + ex.getMessage());
263         }
264         verify(mSimulatedCommandsVerifier).acceptCall(isA(Message.class));
265         /* send to the RIL */
266         TelephonyTestUtils.waitForMs(50);
267         assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
268         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
269         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
270         assertEquals(0, mCTUT.mRingingCall.getConnections().size());
271     }
272
273     @Test
274     @SmallTest
275     public void testMTCallReject() {
276         testMTCallRinging();
277         logd("MT call ringing and rejected ");
278         /* get the reference of the connection before reject */
279         Connection mConnection = mCTUT.mRingingCall.getConnections().get(0);
280         assertNotNull(mConnection);
281         assertEquals(DisconnectCause.NOT_DISCONNECTED, mConnection.getDisconnectCause());
282         try {
283             mCTUT.rejectCall();
284         } catch(Exception ex) {
285             ex.printStackTrace();
286             Assert.fail("unexpected exception thrown" + ex.getMessage());
287         }
288         waitForMs(50);
289         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
290         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
291         assertEquals(0, mCTUT.mForegroundCall.getConnections().size());
292         /* ? why rejectCall didnt -> hang up locally to set the cause to LOCAL? */
293         assertEquals(DisconnectCause.INCOMING_MISSED, mConnection.getDisconnectCause());
294
295     }
296
297     @Test
298     @MediumTest
299     public void testMOCallSwitchHangupForeGround() {
300         testMOCallSwitch();
301         logd("Hang up the foreground MO call while dialing ");
302         try {
303             mCTUT.hangup(mCTUT.mForegroundCall);
304         } catch(Exception ex) {
305             ex.printStackTrace();
306             Assert.fail("unexpected exception thrown" + ex.getMessage());
307         }
308         waitForMs(300);
309         logd(" Foreground Call is IDLE and BackGround Call is still HOLDING ");
310         /* if we want to hang up foreground call which is alerting state, hangup all */
311         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
312         assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState());
313     }
314
315     @FlakyTest
316     @Ignore
317     @Test
318     @MediumTest
319     public void testMOCallPickUpHangUpResumeBackGround() {
320         testMOCallSwitch();
321         logd("Pick up the new MO Call");
322         try{
323             mSimulatedCommands.progressConnectingToActive();
324         } catch(Exception ex) {
325             ex.printStackTrace();
326             Assert.fail("unexpected exception thrown" + ex.getMessage());
327         }
328
329         waitForMs(200);
330         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
331         assertEquals(GsmCdmaCall.State.HOLDING, mCTUT.mBackgroundCall.getState());
332
333         logd("Hang up the new MO Call");
334         try {
335             mCTUT.hangup(mCTUT.mForegroundCall);
336         } catch(Exception ex) {
337             ex.printStackTrace();
338             Assert.fail("unexpected exception thrown" + ex.getMessage());
339         }
340
341         waitForMs(300);
342         logd(" BackGround Call switch to ForeGround Call ");
343         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
344         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState());
345     }
346
347     @Test @SmallTest
348     public void testVoiceCallStartListener(){
349         logd("register for voice call started event");
350         mCTUT.registerForVoiceCallStarted(mHandler, VOICE_CALL_STARTED_EVENT, null);
351         logd("voice call started");
352         testMOCallPickUp();
353         ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
354         ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class);
355         verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture());
356         assertEquals(VOICE_CALL_STARTED_EVENT, mCaptorMessage.getValue().what);
357
358     }
359
360     @FlakyTest
361     @Ignore
362     @Test @SmallTest
363     public void testVoiceCallEndedListener(){
364         logd("register for voice call ended event");
365         mCTUT.registerForVoiceCallEnded(mHandler, VOICE_CALL_ENDED_EVENT, null);
366         ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
367         ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class);
368         testMOCallHangup();
369         verify(mHandler,times(1)).sendMessageAtTime(mCaptorMessage.capture(), mCaptorLong.capture());
370         assertEquals(VOICE_CALL_ENDED_EVENT, mCaptorMessage.getValue().what);
371     }
372
373     @Test @SmallTest
374     public void testUpdatePhoneType() {
375         // verify getCurrentCalls is called on init
376         verify(mSimulatedCommandsVerifier).getCurrentCalls(any(Message.class));
377
378         // update phone type (call the function on same thread as the call tracker)
379         Handler updatePhoneTypeHandler = new Handler(mCTUT.getLooper()) {
380             @Override
381             public void handleMessage(Message msg) {
382                 mCTUT.updatePhoneType();
383             }
384         };
385         updatePhoneTypeHandler.sendEmptyMessage(0);
386         waitForMs(100);
387
388         // verify getCurrentCalls is called on updating phone type
389         verify(mSimulatedCommandsVerifier, times(2)).getCurrentCalls(any(Message.class));
390
391         // we'd like to verify that if phone type is updated, calls and callTracker go to idle.
392         // However, as soon as phone type is updated, call tracker queries for calls from RIL and
393         // will go back to OFFHOOK
394
395         // call tracker goes to OFFHOOK
396         testMOCallPickUp();
397
398         // update phone type - call tracker goes to IDLE and then due to getCurrentCalls(),
399         // goes back to OFFHOOK
400         updatePhoneTypeHandler.sendEmptyMessage(0);
401         waitForMs(100);
402
403         // verify CT and calls go to idle
404         assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
405         assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
406         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState());
407         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mRingingCall.getState());
408     }
409 }
410