1 /*
2  * Copyright (C) 2015 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 
17 package android.telecom.cts;
18 
19 import static android.telecom.cts.TestUtils.*;
20 
21 import android.content.Context;
22 import android.telecom.CallAudioState;
23 import android.telecom.Call;
24 import android.telecom.Connection;
25 import android.telecom.ConnectionService;
26 import android.telecom.InCallService;
27 import android.telecom.TelecomManager;
28 import android.telecom.VideoProfile;
29 
30 import java.util.List;
31 
32 /**
33  * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
34  * verify the functionality of the Telecom service.
35  */
36 public class ExtendedInCallServiceTest extends BaseTelecomTestWithMockServices {
37 
38     @Override
setUp()39     protected void setUp() throws Exception {
40         super.setUp();
41         if (mShouldTestTelecom) {
42             setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
43         }
44     }
45 
testAddNewOutgoingCallAndThenDisconnect()46     public void testAddNewOutgoingCallAndThenDisconnect() {
47         if (!mShouldTestTelecom) {
48             return;
49         }
50 
51         placeAndVerifyCall();
52         verifyConnectionForOutgoingCall();
53 
54         final MockInCallService inCallService = mInCallCallbacks.getService();
55         inCallService.disconnectLastCall();
56 
57         assertNumCalls(inCallService, 0);
58     }
59 
testMuteAndUnmutePhone()60     public void testMuteAndUnmutePhone() {
61         if (!mShouldTestTelecom) {
62             return;
63         }
64 
65         placeAndVerifyCall();
66         final MockConnection connection = verifyConnectionForOutgoingCall();
67 
68         final MockInCallService inCallService = mInCallCallbacks.getService();
69 
70         final Call call = inCallService.getLastCall();
71 
72         assertCallState(call, Call.STATE_DIALING);
73 
74         assertMuteState(connection, false);
75 
76         // Explicitly call super implementation to enable detection of CTS coverage
77         ((InCallService) inCallService).setMuted(true);
78 
79         assertMuteState(connection, true);
80         assertMuteState(inCallService, true);
81 
82         inCallService.setMuted(false);
83         assertMuteState(connection, false);
84         assertMuteState(inCallService, false);
85     }
86 
testSwitchAudioRoutes()87     public void testSwitchAudioRoutes() {
88         if (!mShouldTestTelecom) {
89             return;
90         }
91 
92         placeAndVerifyCall();
93         final MockConnection connection = verifyConnectionForOutgoingCall();
94 
95         final MockInCallService inCallService = mInCallCallbacks.getService();
96 
97         final Call call = inCallService.getLastCall();
98         assertCallState(call, Call.STATE_DIALING);
99 
100         final int currentInvokeCount = mOnCallAudioStateChangedCounter.getInvokeCount();
101 
102         // Only test speaker and earpiece modes because the other modes are dependent on having
103         // a bluetooth headset or wired headset connected.
104 
105         // Explicitly call super implementation to enable detection of CTS coverage
106         ((InCallService) inCallService).setAudioRoute(CallAudioState.ROUTE_SPEAKER);
107         mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 1,
108                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
109         assertAudioRoute(connection, CallAudioState.ROUTE_SPEAKER);
110         assertAudioRoute(inCallService, CallAudioState.ROUTE_SPEAKER);
111 
112         inCallService.setAudioRoute(CallAudioState.ROUTE_EARPIECE);
113         mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 2,
114                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
115         assertAudioRoute(connection, CallAudioState.ROUTE_EARPIECE);
116         assertAudioRoute(inCallService, CallAudioState.ROUTE_EARPIECE);
117     }
118 
119     /**
120      * Tests that DTMF Tones are sent from the {@link InCallService} to the
121      * {@link ConnectionService} in the correct sequence.
122      *
123      * @see {@link Call#playDtmfTone(char)}
124      * @see {@link Call#stopDtmfTone()}
125      */
testPlayAndStopDtmfTones()126     public void testPlayAndStopDtmfTones() {
127         if (!mShouldTestTelecom) {
128             return;
129         }
130 
131         placeAndVerifyCall();
132         final MockConnection connection = verifyConnectionForOutgoingCall();
133 
134         final MockInCallService inCallService = mInCallCallbacks.getService();
135 
136         final Call call = inCallService.getLastCall();
137         assertCallState(call, Call.STATE_DIALING);
138 
139         assertDtmfString(connection, "");
140 
141         call.playDtmfTone('1');
142         assertDtmfString(connection, "1");
143 
144         call.playDtmfTone('2');
145         assertDtmfString(connection, "12");
146 
147         call.stopDtmfTone();
148         assertDtmfString(connection, "12.");
149 
150         call.playDtmfTone('3');
151         call.playDtmfTone('4');
152         call.playDtmfTone('5');
153         assertDtmfString(connection, "12.345");
154 
155         call.stopDtmfTone();
156         assertDtmfString(connection, "12.345.");
157     }
158 
testHoldAndUnholdCall()159     public void testHoldAndUnholdCall() {
160         if (!mShouldTestTelecom) {
161             return;
162         }
163 
164         placeAndVerifyCall();
165         final MockConnection connection = verifyConnectionForOutgoingCall();
166 
167         final MockInCallService inCallService = mInCallCallbacks.getService();
168 
169         final Call call = inCallService.getLastCall();
170 
171         assertCallState(call, Call.STATE_DIALING);
172 
173         connection.setActive();
174 
175         assertCallState(call, Call.STATE_ACTIVE);
176 
177         call.hold();
178         assertCallState(call, Call.STATE_HOLDING);
179         assertEquals(Connection.STATE_HOLDING, connection.getState());
180 
181         call.unhold();
182         assertCallState(call, Call.STATE_ACTIVE);
183         assertEquals(Connection.STATE_ACTIVE, connection.getState());
184     }
185 
testAnswerIncomingCallAudioOnly()186     public void testAnswerIncomingCallAudioOnly() {
187         if (!mShouldTestTelecom) {
188             return;
189         }
190 
191         addAndVerifyNewIncomingCall(createTestNumber(), null);
192         final MockConnection connection = verifyConnectionForIncomingCall();
193 
194         final MockInCallService inCallService = mInCallCallbacks.getService();
195 
196         final Call call = inCallService.getLastCall();
197 
198         assertCallState(call, Call.STATE_RINGING);
199         assertConnectionState(connection, Connection.STATE_RINGING);
200 
201         call.answer(VideoProfile.STATE_AUDIO_ONLY);
202 
203         assertCallState(call, Call.STATE_ACTIVE);
204         assertConnectionState(connection, Connection.STATE_ACTIVE);
205     }
206 
testAnswerIncomingCallAsVideo_SendsCorrectVideoState()207     public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
208         if (!mShouldTestTelecom) {
209             return;
210         }
211 
212         addAndVerifyNewIncomingCall(createTestNumber(), null);
213         final MockConnection connection = verifyConnectionForIncomingCall();
214 
215         final MockInCallService inCallService = mInCallCallbacks.getService();
216 
217         final Call call = inCallService.getLastCall();
218 
219         assertCallState(call, Call.STATE_RINGING);
220         assertConnectionState(connection, Connection.STATE_RINGING);
221 
222         call.answer(VideoProfile.STATE_BIDIRECTIONAL);
223 
224         assertCallState(call, Call.STATE_ACTIVE);
225         assertConnectionState(connection, Connection.STATE_ACTIVE);
226         assertEquals("Connection did not receive VideoState for answered call",
227                 VideoProfile.STATE_BIDIRECTIONAL, connection.videoState);
228     }
229 
testRejectIncomingCall()230     public void testRejectIncomingCall() {
231         if (!mShouldTestTelecom) {
232             return;
233         }
234 
235         addAndVerifyNewIncomingCall(createTestNumber(), null);
236         final MockConnection connection = verifyConnectionForIncomingCall();
237 
238         final MockInCallService inCallService = mInCallCallbacks.getService();
239 
240         final Call call = inCallService.getLastCall();
241 
242         assertCallState(call, Call.STATE_RINGING);
243         assertConnectionState(connection, Connection.STATE_RINGING);
244 
245         call.reject(false, null);
246 
247         assertCallState(call, Call.STATE_DISCONNECTED);
248         assertConnectionState(connection, Connection.STATE_DISCONNECTED);
249     }
250 
testCanAddCall_CannotAddForExistingDialingCall()251     public void testCanAddCall_CannotAddForExistingDialingCall() {
252         if (!mShouldTestTelecom) {
253             return;
254         }
255 
256         placeAndVerifyCall();
257         verifyConnectionForOutgoingCall();
258 
259         final MockInCallService inCallService = mInCallCallbacks.getService();
260 
261         final Call call = inCallService.getLastCall();
262         assertCallState(call, Call.STATE_DIALING);
263 
264         assertCanAddCall(inCallService, false,
265                 "Should not be able to add call with existing dialing call");
266     }
267 
testCanAddCall_CanAddForExistingActiveCall()268     public void testCanAddCall_CanAddForExistingActiveCall() {
269         if (!mShouldTestTelecom) {
270             return;
271         }
272 
273         placeAndVerifyCall();
274         final MockConnection connection = verifyConnectionForOutgoingCall();
275 
276         final MockInCallService inCallService = mInCallCallbacks.getService();
277 
278         final Call call = inCallService.getLastCall();
279         assertCallState(call, Call.STATE_DIALING);
280 
281         connection.setActive();
282 
283         assertCallState(call, Call.STATE_ACTIVE);
284 
285         assertCanAddCall(inCallService, true,
286                 "Should be able to add call with only one active call");
287     }
288 
testCanAddCall_CannotAddIfTooManyCalls()289     public void testCanAddCall_CannotAddIfTooManyCalls() {
290         if (!mShouldTestTelecom) {
291             return;
292         }
293 
294         placeAndVerifyCall();
295         final MockConnection connection1 = verifyConnectionForOutgoingCall(0);
296         final MockInCallService inCallService = mInCallCallbacks.getService();
297         final Call call1 = inCallService.getLastCall();
298         assertCallState(call1, Call.STATE_DIALING);
299 
300         connection1.setActive();
301 
302         assertCallState(call1, Call.STATE_ACTIVE);
303 
304         placeAndVerifyCall();
305         final MockConnection connection2 = verifyConnectionForOutgoingCall(1);
306 
307         final Call call2 = inCallService.getLastCall();
308         assertCallState(call2, Call.STATE_DIALING);
309         connection2.setActive();
310         assertCallState(call2, Call.STATE_ACTIVE);
311 
312         assertEquals("InCallService should have 2 calls", 2, inCallService.getCallCount());
313 
314         assertCanAddCall(inCallService, false,
315                 "Should not be able to add call with two calls already present");
316 
317         call1.hold();
318         assertCallState(call1, Call.STATE_HOLDING);
319 
320         assertCanAddCall(inCallService, false,
321                 "Should not be able to add call with two calls already present");
322     }
323 
testOnBringToForeground()324     public void testOnBringToForeground() {
325         if (!mShouldTestTelecom) {
326             return;
327         }
328 
329         placeAndVerifyCall();
330         verifyConnectionForOutgoingCall();
331 
332         final MockInCallService inCallService = mInCallCallbacks.getService();
333 
334         final Call call = inCallService.getLastCall();
335 
336         assertCallState(call, Call.STATE_DIALING);
337 
338         assertEquals(0, mOnBringToForegroundCounter.getInvokeCount());
339 
340         final TelecomManager tm =
341             (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
342 
343         tm.showInCallScreen(false);
344 
345         mOnBringToForegroundCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
346 
347         assertFalse((Boolean) mOnBringToForegroundCounter.getArgs(0)[0]);
348 
349         tm.showInCallScreen(true);
350 
351         mOnBringToForegroundCounter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
352 
353         assertTrue((Boolean) mOnBringToForegroundCounter.getArgs(1)[0]);
354     }
355 
testOnPostDialWaitAndContinue()356     public void testOnPostDialWaitAndContinue() {
357         if (!mShouldTestTelecom) {
358             return;
359         }
360 
361         placeAndVerifyCall();
362         final MockConnection connection = verifyConnectionForOutgoingCall();
363         final MockInCallService inCallService = mInCallCallbacks.getService();
364         final Call call = inCallService.getLastCall();
365         assertCallState(call, Call.STATE_DIALING);
366 
367         connection.setActive();
368         assertCallState(call, Call.STATE_ACTIVE);
369 
370         final String postDialString = "12345";
371         ((Connection) connection).setPostDialWait(postDialString);
372         mOnPostDialWaitCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
373 
374         assertEquals(postDialString, mOnPostDialWaitCounter.getArgs(0)[1]);
375         assertEquals(postDialString, call.getRemainingPostDialSequence());
376 
377         final InvokeCounter counter = connection.getInvokeCounter(MockConnection.ON_POST_DIAL_WAIT);
378 
379         call.postDialContinue(true);
380         counter.waitForCount(1);
381         assertTrue((Boolean) counter.getArgs(0)[0]);
382 
383         call.postDialContinue(false);
384         counter.waitForCount(2);
385         assertFalse((Boolean) counter.getArgs(1)[0]);
386     }
387 
testOnCannedTextResponsesLoaded()388     public void testOnCannedTextResponsesLoaded() {
389         if (!mShouldTestTelecom) {
390             return;
391         }
392 
393         addAndVerifyNewIncomingCall(createTestNumber(), null);
394         verifyConnectionForIncomingCall();
395         final MockInCallService inCallService = mInCallCallbacks.getService();
396 
397         final Call call = inCallService.getLastCall();
398 
399         assertCallState(call, Call.STATE_RINGING);
400 
401         // We can't do much to enforce the number and type of responses that are preloaded on
402         // device, so the best we can do is to make sure that the call back is called and
403         // that the returned list is non-empty.
404 
405         // This test should also verify that the callback is called as well, but unfortunately it
406         // is never called right now (b/22952515).
407         // mOnCannedTextResponsesLoadedCounter.waitForCount(1);
408 
409         assertGetCannedTextResponsesNotEmpty(call);
410     }
411 
testGetCalls()412     public void testGetCalls() {
413         if (!mShouldTestTelecom) {
414             return;
415         }
416 
417         placeAndVerifyCall();
418         final MockConnection connection1 = verifyConnectionForOutgoingCall(0);
419         final MockInCallService inCallService = mInCallCallbacks.getService();
420         final Call call1 = inCallService.getLastCall();
421         assertCallState(call1, Call.STATE_DIALING);
422 
423         connection1.setActive();
424 
425         assertCallState(call1, Call.STATE_ACTIVE);
426 
427         List<Call> calls = inCallService.getCalls();
428         assertEquals("InCallService.getCalls() should return list with 1 call.", 1, calls.size());
429         assertEquals(call1, calls.get(0));
430 
431         addAndVerifyNewIncomingCall(createTestNumber(), null);
432         verifyConnectionForIncomingCall();
433 
434         final Call call2 = inCallService.getLastCall();
435         calls = inCallService.getCalls();
436         assertEquals("InCallService.getCalls() should return list with 2 calls.", 2, calls.size());
437         assertEquals(call1, calls.get(0));
438         assertEquals(call2, calls.get(1));
439     }
440 
assertGetCannedTextResponsesNotEmpty(final Call call)441     private void assertGetCannedTextResponsesNotEmpty(final Call call) {
442         waitUntilConditionIsTrueOrTimeout(
443                 new Condition() {
444                     @Override
445                     public Object expected() {
446                         return true;
447                     }
448 
449                     @Override
450                     public Object actual() {
451                         return call.getCannedTextResponses() != null
452                                 && !call.getCannedTextResponses().isEmpty();
453                     }
454 
455                 },
456                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
457                 "Call.getCannedTextResponses should not be empty");
458     }
459 
assertCanAddCall(final InCallService inCallService, final boolean canAddCall, String message)460     private void assertCanAddCall(final InCallService inCallService, final boolean canAddCall,
461             String message) {
462         waitUntilConditionIsTrueOrTimeout(
463                 new Condition() {
464                     @Override
465                     public Object expected() {
466                         return canAddCall;
467                     }
468 
469                     @Override
470                     public Object actual() {
471                         return inCallService.canAddCall();
472                     }
473                 },
474                 WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
475                 message
476         );
477     }
478 }
479