1 /*
2  * Copyright (C) 2021 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.telephony.ims.cts;
18 
19 import static junit.framework.Assert.assertNotNull;
20 import static junit.framework.Assert.assertTrue;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotEquals;
24 import static org.junit.Assert.fail;
25 
26 import android.annotation.NonNull;
27 import android.content.Context;
28 import android.database.ContentObserver;
29 import android.media.AudioManager;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.os.Handler;
33 import android.os.Looper;
34 import android.os.PersistableBundle;
35 import android.platform.test.annotations.RequiresFlagsEnabled;
36 import android.platform.test.flag.junit.CheckFlagsRule;
37 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
38 import android.telecom.Call;
39 import android.telecom.PhoneAccount;
40 import android.telecom.TelecomManager;
41 import android.telecom.VideoProfile;
42 import android.telephony.AccessNetworkConstants;
43 import android.telephony.CallState;
44 import android.telephony.CarrierConfigManager;
45 import android.telephony.PreciseCallState;
46 import android.telephony.SubscriptionManager;
47 import android.telephony.TelephonyCallback;
48 import android.telephony.TelephonyManager;
49 import android.telephony.cts.InCallServiceStateValidator;
50 import android.telephony.emergency.EmergencyNumber;
51 import android.telephony.ims.ImsCallProfile;
52 import android.telephony.ims.ImsCallSessionListener;
53 import android.telephony.ims.ImsManager;
54 import android.telephony.ims.ImsMmTelManager;
55 import android.telephony.ims.ImsStreamMediaProfile;
56 import android.telephony.ims.MediaQualityStatus;
57 import android.telephony.ims.feature.MmTelFeature;
58 import android.telephony.ims.stub.ImsRegistrationImplBase;
59 import android.text.TextUtils;
60 import android.util.Log;
61 
62 import androidx.test.ext.junit.runners.AndroidJUnit4;
63 import androidx.test.platform.app.InstrumentationRegistry;
64 
65 import com.android.compatibility.common.util.ShellIdentityUtils;
66 import com.android.internal.telephony.flags.Flags;
67 
68 import org.junit.After;
69 import org.junit.AfterClass;
70 import org.junit.Before;
71 import org.junit.BeforeClass;
72 import org.junit.Rule;
73 import org.junit.Test;
74 import org.junit.runner.RunWith;
75 
76 import java.util.ArrayList;
77 import java.util.List;
78 import java.util.Map;
79 import java.util.Objects;
80 import java.util.concurrent.CountDownLatch;
81 import java.util.concurrent.LinkedBlockingQueue;
82 import java.util.concurrent.Semaphore;
83 import java.util.concurrent.TimeUnit;
84 import java.util.stream.Collectors;
85 /** CTS tests for ImsCall . */
86 @RunWith(AndroidJUnit4.class)
87 public class ImsCallingTest extends ImsCallingBase {
88 
89     protected static final String LOG_TAG = "CtsImsCallingTest";
90 
91     private Call mCall1 = null;
92     private Call mCall2 = null;
93     private Call mCall3 = null;
94     private Call mConferenceCall = null;
95     private TestImsCallSessionImpl mCallSession1 = null;
96     private TestImsCallSessionImpl mCallSession2 = null;
97     private TestImsCallSessionImpl mCallSession3 = null;
98     private TestImsCallSessionImpl mConfCallSession = null;
99 
100     // the timeout to wait result in milliseconds
101     private static final int WAIT_UPDATE_TIMEOUT_MS = 3000;
102     private static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
103 
104     private static TelephonyManager sTelephonyManager;
105     private static Handler sHandler;
106 
107     static {
initializeLatches()108         initializeLatches();
109     }
110 
111     @Rule
112     public final CheckFlagsRule mCheckFlagsRule =
113             DeviceFlagsValueProvider.createCheckFlagsRule();
114 
115     @BeforeClass
beforeAllTests()116     public static void beforeAllTests() throws Exception {
117         if (!ImsUtils.shouldTestImsCall()) {
118             return;
119         }
120 
121         sTelephonyManager =
122                 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
123 
124         sTestSub = ImsUtils.getPreferredActiveSubId();
125         sTestSlot = SubscriptionManager.getSlotIndex(sTestSub);
126         if (!isSimReady()) {
127             return;
128         }
129 
130         if (Looper.getMainLooper() == null) {
131             Looper.prepareMainLooper();
132         }
133         sHandler = new Handler(Looper.getMainLooper());
134 
135         beforeAllTestsBase();
136     }
137 
isSimReady()138     private static boolean isSimReady() {
139         if (sTelephonyManager.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
140             Log.d(LOG_TAG, "sim is not present");
141             return false;
142         }
143         return true;
144     }
145 
146     @AfterClass
afterAllTests()147     public static void afterAllTests() throws Exception {
148         if (!ImsUtils.shouldTestImsCall()) {
149             return;
150         }
151 
152         if (!isSimReady()) {
153             return;
154         }
155 
156         afterAllTestsBase();
157     }
158 
159     @Before
beforeTest()160     public void beforeTest() throws Exception {
161         if (!ImsUtils.shouldTestImsCall()) {
162             return;
163         }
164 
165         if (!isSimReady()) {
166             fail("This test requires that there is a SIM in the device!");
167         }
168 
169         // Correctness check: ensure that the subscription hasn't changed between tests.
170         int subId = SubscriptionManager.getSubscriptionId(sTestSlot);
171         if (subId != sTestSub) {
172             fail("The found subId " + subId + " does not match the test sub id " + sTestSub);
173         }
174     }
175 
176     @After
afterTest()177     public void afterTest() throws Exception {
178         if (!ImsUtils.shouldTestImsCall()) {
179             return;
180         }
181 
182         if (!isSimReady()) {
183             return;
184         }
185 
186         resetCallSessionObjects();
187 
188         if (!mCalls.isEmpty() && (mCurrentCallId != null)) {
189             Call call = mCalls.get(mCurrentCallId);
190             call.disconnect();
191         }
192 
193         //Set the untracked CountDownLatches which are reseted in ServiceCallBack
194         for (int i = 0; i < LATCH_MAX; i++) {
195             sLatches[i] = new CountDownLatch(1);
196         }
197 
198         if (sServiceConnector != null && sIsBound) {
199             TestImsService imsService = sServiceConnector.getCarrierService();
200             sServiceConnector.disconnectCarrierImsService();
201             sIsBound = false;
202             imsService.waitForExecutorFinish();
203         }
204 
205         tearDownEmergencyCalling();
206     }
207 
208     @Test
testOutGoingCall()209     public void testOutGoingCall() throws Exception {
210         if (!ImsUtils.shouldTestImsCall()) {
211             return;
212         }
213 
214         bindImsService();
215         mServiceCallBack = new ServiceCallBack();
216         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
217 
218         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
219                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
220 
221         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
222         Bundle extras = new Bundle();
223 
224         // Place outgoing call
225         telecomManager.placeCall(imsUri, extras);
226         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
227 
228         Call call = getCall(mCurrentCallId);
229         waitForCallSessionToNotBe(null);
230         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
231 
232         TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature()
233                 .getImsCallsession();
234 
235         isCallActive(call, callSession);
236         call.disconnect();
237 
238         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
239         isCallDisconnected(call, callSession);
240         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
241         waitForUnboundService();
242     }
243 
244     @Test
testOutGoingCallStartFailed()245     public void testOutGoingCallStartFailed() throws Exception {
246         if (!ImsUtils.shouldTestImsCall()) {
247             return;
248         }
249 
250         bindImsService();
251         mServiceCallBack = new ServiceCallBack();
252         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
253 
254         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
255                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
256 
257         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
258         Bundle extras = new Bundle();
259 
260         // Place outgoing call
261         telecomManager.placeCall(imsUri, extras);
262         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
263 
264         Call call = getCall(mCurrentCallId);
265 
266         waitForCallSessionToNotBe(null);
267         TestImsCallSessionImpl callSession =
268                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
269         assertNotNull("Unable to get callSession, its null", callSession);
270         callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_MO_FAILED);
271 
272         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
273         isCallDisconnected(call, callSession);
274         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
275         waitForUnboundService();
276     }
277 
278     @Test
testIncomingCall()279     public void testIncomingCall() throws Exception {
280         if (!ImsUtils.shouldTestImsCall()) {
281             return;
282         }
283         bindImsService();
284         mServiceCallBack = new ServiceCallBack();
285         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
286 
287         Bundle extras = new Bundle();
288         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras);
289         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
290 
291         Call call = getCall(mCurrentCallId);
292         if (call.getDetails().getState() == Call.STATE_RINGING) {
293             call.answer(0);
294         }
295 
296         waitForCallSessionToNotBe(null);
297         TestImsCallSessionImpl callSession =
298                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
299 
300         isCallActive(call, callSession);
301         callSession.terminateIncomingCall();
302 
303         isCallDisconnected(call, callSession);
304         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
305         waitForUnboundService();
306     }
307 
308     @Test
testIncomingCallReturnListener()309     public void testIncomingCallReturnListener() throws Exception {
310         if (!ImsUtils.shouldTestImsCall()) {
311             return;
312         }
313         bindImsService();
314         mServiceCallBack = new ServiceCallBack();
315         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
316 
317         Bundle extras = new Bundle();
318         ImsCallSessionListener isl = sServiceConnector.getCarrierService().getMmTelFeature()
319                 .onIncomingCallReceivedReturnListener(extras);
320         assertTrue("failed to get ImsCallSessionListener..", Objects.nonNull(isl));
321         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
322 
323         Call call = getCall(mCurrentCallId);
324         if (call.getDetails().getState() == Call.STATE_RINGING) {
325             call.answer(0);
326         }
327 
328         waitForCallSessionToNotBe(null);
329         TestImsCallSessionImpl callSession =
330                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
331 
332         isCallActive(call, callSession);
333         callSession.terminateIncomingCall();
334 
335         isCallDisconnected(call, callSession);
336         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
337         waitForUnboundService();
338     }
339 
340     @Test
testIncomingCallReject()341     public void testIncomingCallReject() throws Exception {
342         if (!ImsUtils.shouldTestImsCall()) {
343             return;
344         }
345         bindImsService();
346         mServiceCallBack = new ServiceCallBack();
347         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
348 
349         Bundle extras = new Bundle();
350         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras);
351         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
352 
353         Call call = getCall(mCurrentCallId);
354         if (call.getDetails().getState() == Call.STATE_RINGING) {
355             call.reject(504);
356         }
357 
358         waitForCallSessionToNotBe(null);
359         TestImsCallSessionImpl callSession =
360                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
361 
362         isCallDisconnected(call, callSession);
363         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
364         waitForUnboundService();
365     }
366 
367     @Test
testOutGoingCallForExecutor()368     public void testOutGoingCallForExecutor() throws Exception {
369         if (!ImsUtils.shouldTestImsCall()) {
370             return;
371         }
372 
373         sServiceConnector.setExecutorTestType(true);
374         bindImsService();
375 
376         mServiceCallBack = new ServiceCallBack();
377         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
378 
379         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
380                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
381 
382         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
383         Bundle extras = new Bundle();
384 
385         // Place outgoing call
386         telecomManager.placeCall(imsUri, extras);
387         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
388 
389         Call call = getCall(mCurrentCallId);
390         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
391 
392         waitForCallSessionToNotBe(null);
393         TestImsCallSessionImpl callSession =
394                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
395 
396         isCallActive(call, callSession);
397         call.disconnect();
398 
399         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
400         isCallDisconnected(call, callSession);
401         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
402         waitForUnboundService();
403     }
404 
405     @Test
testOutGoingCallHoldResume()406     public void testOutGoingCallHoldResume() throws Exception {
407         if (!ImsUtils.shouldTestImsCall()) {
408             return;
409         }
410 
411         bindImsService();
412         mServiceCallBack = new ServiceCallBack();
413         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
414 
415         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
416                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
417 
418         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
419         Bundle extras = new Bundle();
420 
421         // Place outgoing call
422         telecomManager.placeCall(imsUri, extras);
423         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
424 
425         Call call = getCall(mCurrentCallId);
426         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
427 
428         waitForCallSessionToNotBe(null);
429         TestImsCallSessionImpl callSession =
430                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
431 
432         isCallActive(call, callSession);
433 
434         // Put on hold
435         call.hold();
436         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
437 
438         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
439         // Put on resume
440         call.unhold();
441         isCallActive(call, callSession);
442         call.disconnect();
443 
444         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
445         isCallDisconnected(call, callSession);
446         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
447         waitForUnboundService();
448     }
449 
450     @Test
testOutGoingCallHoldFailure()451     public void testOutGoingCallHoldFailure() throws Exception {
452         if (!ImsUtils.shouldTestImsCall()) {
453             return;
454         }
455 
456         bindImsService();
457         mServiceCallBack = new ServiceCallBack();
458         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
459 
460         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
461                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
462 
463         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
464         Bundle extras = new Bundle();
465 
466         // Place outgoing call
467         telecomManager.placeCall(imsUri, extras);
468         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
469 
470         Call call = getCall(mCurrentCallId);
471         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
472 
473         waitForCallSessionToNotBe(null);
474         TestImsCallSessionImpl callSession =
475                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
476 
477         isCallActive(call, callSession);
478         callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_FAILED);
479 
480         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
481         call.hold();
482         assertTrue("call is not in Active State", (call.getDetails().getState()
483                 == call.STATE_ACTIVE));
484 
485         call.disconnect();
486 
487         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
488         isCallDisconnected(call, callSession);
489         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
490         waitForUnboundService();
491     }
492 
493     @Test
testOutGoingCallResumeFailure()494     public void testOutGoingCallResumeFailure() throws Exception {
495         if (!ImsUtils.shouldTestImsCall()) {
496             return;
497         }
498 
499         bindImsService();
500         mServiceCallBack = new ServiceCallBack();
501         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
502 
503         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
504                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
505 
506         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
507         Bundle extras = new Bundle();
508 
509         // Place outgoing call
510         telecomManager.placeCall(imsUri, extras);
511         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
512 
513         Call call = getCall(mCurrentCallId);
514         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
515 
516         waitForCallSessionToNotBe(null);
517         TestImsCallSessionImpl callSession =
518                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
519 
520         isCallActive(call, callSession);
521 
522         // Put on hold
523         call.hold();
524         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
525 
526         callSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED);
527         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
528         call.unhold();
529         assertTrue("Call is not in Hold State", (call.getDetails().getState()
530                 == call.STATE_HOLDING));
531 
532         call.disconnect();
533 
534         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
535         isCallDisconnected(call, callSession);
536         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
537         waitForUnboundService();
538     }
539 
540     @Test
testOutGoingCallReceivedHoldResume()541     public void testOutGoingCallReceivedHoldResume() throws Exception {
542         if (!ImsUtils.shouldTestImsCall()) {
543             return;
544         }
545 
546         bindImsService();
547         mServiceCallBack = new ServiceCallBack();
548         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
549 
550         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
551                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
552 
553         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
554         Bundle extras = new Bundle();
555 
556         telecomManager.placeCall(imsUri, extras);
557         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
558 
559         Call call = getCall(mCurrentCallId);
560         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
561 
562         waitForCallSessionToNotBe(null);
563         TestImsCallSessionImpl callSession =
564                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
565         isCallActive(call, callSession);
566 
567         // received hold and checking it is still active and received the connection event
568         // EVENT_CALL_REMOTELY_HELD
569         callSession.sendHoldReceived();
570         assertTrue("Call is not in Active State", (call.getDetails().getState()
571                 == Call.STATE_ACTIVE));
572         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOTELY_HELD, WAIT_FOR_CALL_STATE));
573 
574         // received resume and checking it is still active and received the connection event
575         // EVENT_CALL_REMOTELY_UNHELD
576         callSession.sendResumeReceived();
577         assertTrue("Call is not in Active State", (call.getDetails().getState()
578                 == Call.STATE_ACTIVE));
579         assertTrue(
580                 callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOTELY_UNHELD, WAIT_FOR_CALL_STATE));
581 
582         call.disconnect();
583 
584         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
585         isCallDisconnected(call, callSession);
586         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
587         waitForUnboundService();
588     }
589 
590     @Test
testOutGoingIncomingMultiCall()591     public void testOutGoingIncomingMultiCall() throws Exception {
592         if (!ImsUtils.shouldTestImsCall()) {
593             return;
594         }
595 
596         bindImsService();
597         mServiceCallBack = new ServiceCallBack();
598         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
599 
600         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
601                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
602 
603         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
604         Bundle extras = new Bundle();
605 
606         // Place outgoing call
607         telecomManager.placeCall(imsUri, extras);
608         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
609 
610         Call moCall = getCall(mCurrentCallId);
611         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
612 
613         waitForCallSessionToNotBe(null);
614         TestImsCallSessionImpl moCallSession =
615                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
616         isCallActive(moCall, moCallSession);
617         assertTrue("Call is not in Active State", (moCall.getDetails().getState()
618                 == Call.STATE_ACTIVE));
619 
620         extras.putBoolean("android.telephony.ims.feature.extra.IS_USSD", false);
621         extras.putBoolean("android.telephony.ims.feature.extra.IS_UNKNOWN_CALL", false);
622         extras.putString("android:imsCallID", String.valueOf(++sCounter));
623         extras.putLong("android:phone_id", 123456);
624         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras);
625         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
626 
627         Call mtCall = null;
628         if (mCurrentCallId != null) {
629             mtCall = getCall(mCurrentCallId);
630             if (mtCall.getDetails().getState() == Call.STATE_RINGING) {
631                 mtCall.answer(0);
632             }
633         }
634 
635         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
636         waitForCallSessionToNotBe(null);
637         TestImsCallSessionImpl mtCallSession = sServiceConnector.getCarrierService()
638                 .getMmTelFeature().getImsCallsession();
639         isCallActive(mtCall, mtCallSession);
640         assertTrue("Call is not in Active State", (mtCall.getDetails().getState()
641                 == Call.STATE_ACTIVE));
642 
643         mtCall.disconnect();
644         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
645         isCallDisconnected(mtCall, mtCallSession);
646         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
647 
648         isCallActive(moCall, moCallSession);
649         assertTrue("Call is not in Active State", (moCall.getDetails().getState()
650                 == Call.STATE_ACTIVE));
651 
652         moCall.disconnect();
653         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
654         isCallDisconnected(moCall, moCallSession);
655         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
656 
657         waitForUnboundService();
658     }
659 
660     @Test
testOutGoingIncomingMultiCallAcceptTerminate()661     public void testOutGoingIncomingMultiCallAcceptTerminate() throws Exception {
662         if (!ImsUtils.shouldTestImsCall()) {
663             return;
664         }
665 
666         bindImsService();
667         mServiceCallBack = new ServiceCallBack();
668         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
669 
670         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
671                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
672 
673         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
674         Bundle extras = new Bundle();
675 
676         // Place outgoing call
677         telecomManager.placeCall(imsUri, extras);
678         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
679 
680         Call moCall = getCall(mCurrentCallId);
681         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
682 
683         waitForCallSessionToNotBe(null);
684         TestImsCallSessionImpl moCallSession =
685                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
686         isCallActive(moCall, moCallSession);
687         assertTrue("Call is not in Active State", (moCall.getDetails().getState()
688                 == Call.STATE_ACTIVE));
689 
690         extras.putBoolean("android.telephony.ims.feature.extra.IS_USSD", false);
691         extras.putBoolean("android.telephony.ims.feature.extra.IS_UNKNOWN_CALL", false);
692         extras.putString("android:imsCallID", String.valueOf(++sCounter));
693         extras.putLong("android:phone_id", 123456);
694         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras);
695         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
696         waitForCallSessionToNotBe(null);
697         TestImsCallSessionImpl mtCallSession =
698                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
699         // do not generate an auto hold response here, need to simulate a timing issue.
700         moCallSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_NO_RESPONSE);
701 
702         Call mtCall = null;
703         if (mCurrentCallId != null) {
704             mtCall = getCall(mCurrentCallId);
705             if (mtCall.getDetails().getState() == Call.STATE_RINGING) {
706                 mtCall.answer(0);
707             }
708         }
709 
710         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
711         // simulate user hanging up the MT call at the same time as accept.
712         mtCallSession.terminateIncomingCall();
713         isCallDisconnected(mtCall, mtCallSession);
714         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
715 
716         // then send hold response, which should be reversed, since MT call was disconnected.
717         moCallSession.sendHoldResponse();
718 
719         // MO call should move back to active.
720         isCallActive(moCall, moCallSession);
721         assertTrue("Call is not in Active State", (moCall.getDetails().getState()
722                 == Call.STATE_ACTIVE));
723 
724         moCall.disconnect();
725         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
726         isCallDisconnected(moCall, moCallSession);
727         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
728 
729         waitForUnboundService();
730     }
731 
732     @Test
testOutGoingIncomingMultiCallHoldFailedTerminateByRemote()733     public void testOutGoingIncomingMultiCallHoldFailedTerminateByRemote() throws Exception {
734         if (!ImsUtils.shouldTestImsCall()) {
735             return;
736         }
737 
738         bindImsService();
739         mServiceCallBack = new ServiceCallBack();
740         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
741 
742         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
743                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
744 
745         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
746         Bundle extras = new Bundle();
747 
748         telecomManager.placeCall(imsUri, extras);
749         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
750 
751         Call moCall = getCall(mCurrentCallId);
752         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
753 
754         waitForCallSessionToNotBe(null);
755         TestImsCallSessionImpl moCallSession =
756                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
757         isCallActive(moCall, moCallSession);
758         assertTrue("Call is not in Active State", (moCall.getDetails().getState()
759                 == Call.STATE_ACTIVE));
760 
761         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingCallReceived(extras);
762         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
763         waitForCallSessionToNotBe(null);
764         TestImsCallSessionImpl mtCallSession =
765                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
766         moCallSession.addTestType(TestImsCallSessionImpl.TEST_TYPE_HOLD_NO_RESPONSE);
767 
768         Call mtCall = null;
769         if (mCurrentCallId != null) {
770             mtCall = getCall(mCurrentCallId);
771             if (mtCall.getDetails().getState() == Call.STATE_RINGING) {
772                 mtCall.answer(0);
773             }
774         }
775 
776         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
777         // received holdFailed because the other party of the outgoing call terminated the call
778         waitCallRenegotiating(moCallSession);
779         moCallSession.sendHoldFailRemoteTerminated();
780         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
781         isCallDisconnected(moCall, moCallSession);
782 
783         // incoming call accept again
784         mtCall.answer(0);
785         isCallActive(mtCall, mtCallSession);
786         assertTrue("Call is not in Active State", (mtCall.getDetails().getState()
787                 == Call.STATE_ACTIVE));
788 
789         mtCall.disconnect();
790         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
791         isCallDisconnected(mtCall, mtCallSession);
792         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
793         waitForUnboundService();
794     }
795 
796     @Test
testOutGoingCallSwap()797     public void testOutGoingCallSwap() throws Exception {
798         if (!ImsUtils.shouldTestImsCall()) {
799             return;
800         }
801 
802         bindImsService();
803         mServiceCallBack = new ServiceCallBack();
804         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
805         addOutgoingCalls();
806 
807         // Swap the call
808         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
809         mCall1.unhold();
810         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
811         assertTrue("Call is not in Hold State", (mCall2.getDetails().getState()
812                 == Call.STATE_HOLDING));
813         isCallActive(mCall1, mCallSession1);
814 
815         // After successful call swap disconnect the call
816         mCall1.disconnect();
817         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
818         isCallDisconnected(mCall1, mCallSession1);
819         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
820 
821         //Wait till second call is in active state
822         waitUntilConditionIsTrueOrTimeout(
823                 new Condition() {
824                     @Override
825                     public Object expected() {
826                         return true;
827                     }
828 
829                     @Override
830                     public Object actual() {
831                         return (mCall2.getDetails().getState() == Call.STATE_ACTIVE)
832                                 ? true : false;
833                     }
834                 }, WAIT_FOR_CALL_STATE_ACTIVE, "Call in Active State");
835 
836         isCallActive(mCall2, mCallSession2);
837         mCall2.disconnect();
838         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
839         isCallDisconnected(mCall2, mCallSession2);
840         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
841         waitForUnboundService();
842     }
843 
844     @Test
testOutGoingCallSwapFail()845     public void testOutGoingCallSwapFail() throws Exception {
846         if (!ImsUtils.shouldTestImsCall()) {
847             return;
848         }
849 
850         bindImsService();
851         mServiceCallBack = new ServiceCallBack();
852         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
853         addOutgoingCalls();
854 
855         mCallSession1.addTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED);
856         // Swap the call
857         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
858         mCall1.unhold();
859         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
860         assertTrue("Call is not in Hold State", (mCall1.getDetails().getState()
861                 == Call.STATE_HOLDING));
862 
863         // Wait till second call is in active state
864         waitUntilConditionIsTrueOrTimeout(
865                 new Condition() {
866                     @Override
867                     public Object expected() {
868                         return true;
869                     }
870 
871                     @Override
872                     public Object actual() {
873                         return (mCall2.getDetails().getState() == Call.STATE_ACTIVE)
874                                 ? true : false;
875                     }
876                 }, WAIT_FOR_CALL_STATE_ACTIVE, "Call in Active State");
877 
878         isCallActive(mCall2, mCallSession2);
879         mCallSession1.removeTestType(TestImsCallSessionImpl.TEST_TYPE_RESUME_FAILED);
880         mCall2.disconnect();
881         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
882         isCallDisconnected(mCall2, mCallSession2);
883         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
884 
885         // Wait till second call is in active state
886         isCallActive(mCall1, mCallSession1);
887         mCall1.disconnect();
888         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
889         isCallDisconnected(mCall1, mCallSession1);
890         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
891         waitForUnboundService();
892     }
893 
894     @Test
testConferenceCall()895     public void testConferenceCall() throws Exception {
896         if (!ImsUtils.shouldTestImsCall()) {
897             return;
898         }
899         Log.i(LOG_TAG, "testConference ");
900         bindImsService();
901         mServiceCallBack = new ServiceCallBack();
902         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
903 
904         makeConferenceCall();
905 
906         //Disconnect the conference call.
907         mConferenceCall.disconnect();
908 
909         //Verify conference participant connections are disconnected.
910         assertParticiapantAddedToConference(0);
911         isCallDisconnected(mConferenceCall, mConfCallSession);
912         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
913         waitForUnboundService();
914     }
915 
916     @Test
testConferenceCallFailure()917     public void testConferenceCallFailure() throws Exception {
918         if (!ImsUtils.shouldTestImsCall()) {
919             return;
920         }
921         Log.i(LOG_TAG, "testConferenceCallFailure ");
922         bindImsService();
923         mServiceCallBack = new ServiceCallBack();
924         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
925         addOutgoingCalls();
926         mCallSession2.addTestType(TestImsCallSessionImpl.TEST_TYPE_CONFERENCE_FAILED);
927         addConferenceCall(mCall1, mCall2);
928 
929         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE_MERGE_FAILED);
930         //Verify foreground call is in Active state after merge failed.
931         assertTrue("Call is not in Active State", (mCall2.getDetails().getState()
932                 == Call.STATE_ACTIVE));
933         //Verify background call is in Hold state after merge failed.
934         assertTrue("Call is not in Holding State", (mCall1.getDetails().getState()
935                 == Call.STATE_HOLDING));
936 
937         mCall2.disconnect();
938         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
939         isCallDisconnected(mCall2, mCallSession2);
940         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
941 
942         //Wait till background call is in active state
943         isCallActive(mCall1, mCallSession1);
944         mCall1.disconnect();
945         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
946         isCallDisconnected(mCall1, mCallSession1);
947         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
948         waitForUnboundService();
949     }
950 
951     @Test
testConferenceCallFailureByRemoteTerminated()952     public void testConferenceCallFailureByRemoteTerminated() throws Exception {
953         if (!ImsUtils.shouldTestImsCall()) {
954             return;
955         }
956 
957         bindImsService();
958         mServiceCallBack = new ServiceCallBack();
959         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
960         addOutgoingCalls();
961         mCallSession2.addTestType(
962                 TestImsCallSessionImpl.TEST_TYPE_CONFERENCE_FAILED_REMOTE_TERMINATED);
963         addConferenceCall(mCall1, mCall2);
964         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
965 
966         // first call is terminated by remote
967         mCallSession1.sendTerminatedByRemote();
968         // received mergeFailed due to terminated first call
969         mCallSession2.sendMergedFailed();
970 
971         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
972         // verify foreground call is in Active state after merge failed.
973         assertTrue("Call is not in Active State", (mCall2.getDetails().getState()
974                 == Call.STATE_ACTIVE));
975         // verify background call is in Disconnected state.
976         isCallDisconnected(mCall1, mCallSession1);
977         assertTrue("Call is not in Disconnected State", (mCall1.getDetails().getState()
978                 == Call.STATE_DISCONNECTED));
979 
980         mCall2.disconnect();
981         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
982         isCallDisconnected(mCall2, mCallSession2);
983         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
984         waitForUnboundService();
985     }
986 
987     @Test
testCallJoinExistingConferenceCall()988     public void testCallJoinExistingConferenceCall() throws Exception {
989         if (!ImsUtils.shouldTestImsCall()) {
990             return;
991         }
992 
993         bindImsService();
994         mServiceCallBack = new ServiceCallBack();
995         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
996 
997         makeConferenceCall();
998         // add third outgoing call, third call : active , conference call : hold
999         addThirdOutgoingCall();
1000         mCallSession3.addTestType(TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE);
1001 
1002         mCall3.conference(mConferenceCall);
1003         // Wait for merge complete for the third call:
1004         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_COMPLETE, WAIT_FOR_CALL_STATE));
1005         isCallActive(mConferenceCall, mConfCallSession);
1006 
1007         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
1008         // verify third call disconnected after conference Merge success
1009         assertParticiapantDisconnected(mCall3);
1010 
1011         // verify conference participant connections are connected.
1012         assertParticiapantAddedToConference(3);
1013 
1014         mConferenceCall.disconnect();
1015 
1016         assertParticiapantAddedToConference(0);
1017         isCallDisconnected(mConferenceCall, mConfCallSession);
1018         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1019         waitForUnboundService();
1020     }
1021 
1022     @RequiresFlagsEnabled(Flags.FLAG_CONFERENCE_HOLD_UNHOLD_CHANGED_TO_SEND_MESSAGE)
1023     @Test
testCallJoinExistingConferenceCallAfterCallSwap()1024     public void testCallJoinExistingConferenceCallAfterCallSwap() throws Exception {
1025         if (!ImsUtils.shouldTestImsCall()) {
1026             return;
1027         }
1028 
1029         bindImsService();
1030         mServiceCallBack = new ServiceCallBack();
1031         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1032 
1033         makeConferenceCall();
1034         // add third outgoing call, third call : active , conference call : hold
1035         addThirdOutgoingCall();
1036 
1037         // swap the call
1038         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
1039         mConferenceCall.unhold();
1040         isCallHolding(mCall3, mCallSession3);
1041         assertTrue("Call is not in Hold State", (mCall3.getDetails().getState()
1042                 == Call.STATE_HOLDING));
1043         isCallActive(mConferenceCall, mConfCallSession);
1044 
1045         mConfCallSession.addTestType(
1046                 TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE_AFTER_SWAP);
1047 
1048         // merge call
1049         mConferenceCall.conference(mCall3);
1050         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_START, WAIT_FOR_CALL_STATE));
1051 
1052         // verify third call disconnected.
1053         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1054         assertParticiapantDisconnected(mCall3);
1055 
1056         // verify conference participant connections are connected.
1057         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_COMPLETE, WAIT_FOR_CALL_STATE));
1058         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CHILDREN_CHANGED, WAIT_FOR_CALL_STATE));
1059         assertParticiapantAddedToConference(3);
1060 
1061         isCallActive(mConferenceCall, mConfCallSession);
1062 
1063         // disconnect the conference call.
1064         mConferenceCall.disconnect();
1065 
1066         // verify conference participant connections are disconnected.
1067         assertParticiapantAddedToConference(0);
1068         isCallDisconnected(mConferenceCall, mConfCallSession);
1069         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1070         waitForUnboundService();
1071     }
1072 
1073     @RequiresFlagsEnabled(Flags.FLAG_CONFERENCE_HOLD_UNHOLD_CHANGED_TO_SEND_MESSAGE)
1074     @Test
testCallJoinExistingConferenceCallAfterCallSwapFail()1075     public void testCallJoinExistingConferenceCallAfterCallSwapFail() throws Exception {
1076         if (!ImsUtils.shouldTestImsCall()) {
1077             return;
1078         }
1079 
1080         bindImsService();
1081         mServiceCallBack = new ServiceCallBack();
1082         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1083 
1084         makeConferenceCall();
1085         // add third outgoing call, third call : active , conference call : hold
1086         addThirdOutgoingCall();
1087 
1088         // swap the call
1089         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE);
1090         mConferenceCall.unhold();
1091         isCallHolding(mCall3, mCallSession3);
1092         assertTrue("Call is not in Hold State", (mCall3.getDetails().getState()
1093                 == Call.STATE_HOLDING));
1094         isCallActive(mConferenceCall, mConfCallSession);
1095 
1096         // fail to merge
1097         mConfCallSession.addTestType(
1098                 TestImsCallSessionImpl.TEST_TYPE_JOIN_EXIST_CONFERENCE_FAILED_AFTER_SWAP);
1099 
1100         mConferenceCall.conference(mCall3);
1101         ImsUtils.waitInCurrentState(WAIT_IN_CURRENT_STATE_MERGE_FAILED);
1102 
1103         // verify foreground call is in Active state after merge failed.
1104         assertTrue("Call is not in Active State", (mConferenceCall.getDetails().getState()
1105                 == Call.STATE_ACTIVE));
1106         // verify background call is in Hold state after merge failed.
1107         assertTrue("Call is not in Holding State", (mCall3.getDetails().getState()
1108                 == Call.STATE_HOLDING));
1109 
1110         // disconnect the conference call.
1111         mConferenceCall.disconnect();
1112 
1113         // verify conference participant connections are disconnected.
1114         assertParticiapantAddedToConference(0);
1115         isCallDisconnected(mConferenceCall, mConfCallSession);
1116         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1117 
1118         // verify third call is active
1119         isCallActive(mCall3, mCallSession3);
1120         mCall3.disconnect();
1121         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1122         isCallDisconnected(mCall3, mCallSession3);
1123         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1124         waitForUnboundService();
1125     }
1126 
1127     @Test
testSetCallAudioHandler()1128     public void testSetCallAudioHandler() throws Exception {
1129         if (!ImsUtils.shouldTestImsCall()) {
1130             return;
1131         }
1132 
1133         bindImsService();
1134         mServiceCallBack = new ServiceCallBack();
1135         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1136 
1137         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1138                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1139         AudioManager mAudioManager = (AudioManager) InstrumentationRegistry
1140                 .getInstrumentation().getContext().getSystemService(Context.AUDIO_SERVICE);
1141 
1142         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
1143         Bundle extras = new Bundle();
1144 
1145         mAudioManager.setMode(AudioManager.MODE_NORMAL);
1146         Log.i(LOG_TAG, "testSetCallAudioHandler - Reset AudioMode: " + mAudioManager.getMode());
1147 
1148         // Place outgoing call
1149         telecomManager.placeCall(imsUri, extras);
1150         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1151 
1152         Call call = getCall(mCurrentCallId);
1153         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1154 
1155         waitForCallSessionToNotBe(null);
1156         TimeUnit.MILLISECONDS.sleep(WAIT_UPDATE_TIMEOUT_MS);
1157 
1158         TestImsCallSessionImpl callSession =
1159                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1160 
1161         isCallActive(call, callSession);
1162 
1163         sServiceConnector.getCarrierService().getMmTelFeature()
1164                 .setCallAudioHandler(MmTelFeature.AUDIO_HANDLER_ANDROID);
1165         TimeUnit.MILLISECONDS.sleep(WAIT_UPDATE_TIMEOUT_MS);
1166 
1167         assertNotEquals(AudioManager.MODE_NORMAL, mAudioManager.getMode());
1168         assertEquals(AudioManager.MODE_IN_COMMUNICATION, mAudioManager.getMode());
1169 
1170         call.disconnect();
1171         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1172 
1173         // Place the 2nd outgoing call
1174         telecomManager.placeCall(imsUri, extras);
1175         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1176 
1177         call = getCall(mCurrentCallId);
1178         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1179 
1180         waitForCallSessionToNotBe(null);
1181         TimeUnit.MILLISECONDS.sleep(WAIT_UPDATE_TIMEOUT_MS);
1182         callSession = sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1183 
1184         isCallActive(call, callSession);
1185 
1186         sServiceConnector.getCarrierService().getMmTelFeature()
1187                 .setCallAudioHandler(MmTelFeature.AUDIO_HANDLER_BASEBAND);
1188         TimeUnit.MILLISECONDS.sleep(WAIT_UPDATE_TIMEOUT_MS);
1189 
1190         assertNotEquals(AudioManager.MODE_NORMAL, mAudioManager.getMode());
1191         assertEquals(AudioManager.MODE_IN_CALL, mAudioManager.getMode());
1192 
1193         call.disconnect();
1194 
1195         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1196         isCallDisconnected(call, callSession);
1197         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1198         waitForUnboundService();
1199     }
1200 
1201     @Test
testNotifyCallStateChanged()1202     public void testNotifyCallStateChanged() throws Exception {
1203         if (!ImsUtils.shouldTestImsCall()) {
1204             return;
1205         }
1206 
1207         bindImsService();
1208         mServiceCallBack = new ServiceCallBack();
1209         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1210 
1211         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1212                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1213 
1214         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
1215         Bundle extras = new Bundle();
1216 
1217         // Place outgoing call
1218         telecomManager.placeCall(imsUri, extras);
1219         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1220 
1221         Call call = getCall(mCurrentCallId);
1222         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1223 
1224         waitForCallSessionToNotBe(null);
1225         TestImsCallSessionImpl callSession =
1226                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1227 
1228         isCallActive(call, callSession);
1229         String callSessionId = callSession.getCallId();
1230 
1231         LinkedBlockingQueue<List<CallState>> queue = new LinkedBlockingQueue<>();
1232         ImsCallingTest.TestTelephonyCallbackForCallStateChange testCb =
1233                 new ImsCallingTest.TestTelephonyCallbackForCallStateChange(queue);
1234 
1235         // test registration without permission
1236         try {
1237             sTelephonyManager.registerTelephonyCallback(Runnable::run, testCb);
1238             fail("registerTelephonyCallback requires READ_PRECISE_PHONE_STATE permission.");
1239         } catch (SecurityException e) {
1240             //expected
1241         }
1242 
1243         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
1244                 sTelephonyManager, (tm) -> tm.registerTelephonyCallback(Runnable::run, testCb));
1245 
1246         // Expect to receive cached CallState in TelephonyRegistry when the listener register event.
1247         List<CallState> callStateList = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1248         assertNotNull(callStateList);
1249         assertEquals(1, callStateList.size());
1250         assertEquals(
1251                 PreciseCallState.PRECISE_CALL_STATE_ACTIVE, callStateList.get(0).getCallState());
1252         assertEquals(callSessionId, callStateList.get(0).getImsCallSessionId());
1253         assertEquals(ImsCallProfile.CALL_TYPE_VOICE, callStateList.get(0).getImsCallType());
1254         assertEquals(ImsCallProfile.SERVICE_TYPE_NORMAL,
1255                 callStateList.get(0).getImsCallServiceType());
1256 
1257         // Hold Call.
1258         ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(
1259                 ImsStreamMediaProfile.AUDIO_QUALITY_AMR,
1260                 ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE,
1261                 ImsStreamMediaProfile.VIDEO_QUALITY_QCIF,
1262                 ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE,
1263                 ImsStreamMediaProfile.RTT_MODE_DISABLED);
1264         callSession.hold(mediaProfile);
1265 
1266         //Check receiving CallState change callback.
1267         callStateList = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1268         assertNotNull(callStateList);
1269         assertEquals(1, callStateList.size());
1270         assertEquals(
1271                 PreciseCallState.PRECISE_CALL_STATE_HOLDING, callStateList.get(0).getCallState());
1272         assertEquals(callSessionId, callStateList.get(0).getImsCallSessionId());
1273         assertEquals(ImsCallProfile.CALL_TYPE_VOICE, callStateList.get(0).getImsCallType());
1274         assertEquals(ImsCallProfile.SERVICE_TYPE_NORMAL,
1275                 callStateList.get(0).getImsCallServiceType());
1276 
1277         call.disconnect();
1278 
1279         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1280         isCallDisconnected(call, callSession);
1281         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1282         waitForUnboundService();
1283     }
1284 
1285     @Test
testNotifyMediaCallStatusChanged()1286     public void testNotifyMediaCallStatusChanged() throws Exception {
1287         if (!ImsUtils.shouldTestImsCall()) {
1288             return;
1289         }
1290 
1291         bindImsService();
1292         mServiceCallBack = new ServiceCallBack();
1293         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1294 
1295         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1296                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1297 
1298         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
1299         Bundle extras = new Bundle();
1300 
1301         // Place outgoing call
1302         telecomManager.placeCall(imsUri, extras);
1303         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1304 
1305         Call call = getCall(mCurrentCallId);
1306         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1307 
1308         waitForCallSessionToNotBe(null);
1309         TestImsCallSessionImpl callSession =
1310                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1311 
1312         isCallActive(call, callSession);
1313         String callSessionId = callSession.getCallId();
1314 
1315         LinkedBlockingQueue<MediaQualityStatus> queue = new LinkedBlockingQueue<>();
1316         ImsCallingTest.TestTelephonyCallback testCb =
1317                 new ImsCallingTest.TestTelephonyCallback(queue);
1318 
1319         // test registration without permission
1320         try {
1321             sTelephonyManager.registerTelephonyCallback(Runnable::run, testCb);
1322             fail("registerTelephonyCallback requires READ_PRECISE_PHONE_STATE permission.");
1323         } catch (SecurityException e) {
1324             //expected
1325         }
1326 
1327         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
1328                 sTelephonyManager,
1329                 (tm) -> tm.registerTelephonyCallback(Runnable::run, testCb));
1330 
1331         MediaQualityStatus status = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1332         assertNotNull(status);
1333         assertEquals(callSessionId, status.getCallSessionId());
1334         assertEquals(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO, status.getMediaSessionType());
1335         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, status.getTransportType());
1336         assertEquals(0, status.getRtpPacketLossRate());
1337         assertEquals(0, status.getRtpJitterMillis());
1338         assertEquals(0, status.getRtpInactivityMillis());
1339 
1340         //Notify a new media quality status.
1341         sServiceConnector.getCarrierService().getMmTelFeature()
1342                 .notifyMediaQualityStatusChanged(new MediaQualityStatus(callSessionId,
1343                         MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO,
1344                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
1345                         TEST_RTP_THRESHOLD_PACKET_LOSS_RATE,
1346                         TEST_RTP_THRESHOLD_JITTER_MILLIS,
1347                         TEST_RTP_THRESHOLD_INACTIVITY_TIME_MILLIS));
1348 
1349         status = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1350         assertNotNull(status);
1351         assertEquals(callSessionId, status.getCallSessionId());
1352         assertEquals(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO, status.getMediaSessionType());
1353         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, status.getTransportType());
1354         assertEquals(TEST_RTP_THRESHOLD_PACKET_LOSS_RATE, status.getRtpPacketLossRate());
1355         assertEquals(TEST_RTP_THRESHOLD_JITTER_MILLIS, status.getRtpJitterMillis());
1356         assertEquals(TEST_RTP_THRESHOLD_INACTIVITY_TIME_MILLIS, status.getRtpInactivityMillis());
1357 
1358         call.disconnect();
1359 
1360         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1361         isCallDisconnected(call, callSession);
1362         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1363         waitForUnboundService();
1364     }
1365 
1366     @Test
testOutGoingEmergencyCall()1367     public void testOutGoingEmergencyCall() throws Exception {
1368         if (!ImsUtils.shouldTestImsCall()) {
1369             return;
1370         }
1371 
1372         boolean supportDomainSelection =
1373                 ShellIdentityUtils.invokeMethodWithShellPermissions(sTelephonyManager,
1374                         (tm) -> tm.isDomainSelectionSupported());
1375 
1376         if (supportDomainSelection) {
1377             return;
1378         }
1379 
1380         LinkedBlockingQueue<List<CallState>> queue = new LinkedBlockingQueue<>();
1381         ImsCallingTest.TestTelephonyCallbackForCallStateChange testCb =
1382                 new ImsCallingTest.TestTelephonyCallbackForCallStateChange(queue);
1383         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
1384                 sTelephonyManager, (tm) -> tm.registerTelephonyCallback(Runnable::run, testCb));
1385 
1386         testCb.setTestEmergencyNumber(TEST_EMERGENCY_NUMBER);
1387         setupForEmergencyCalling(TEST_EMERGENCY_NUMBER);
1388         assertTrue(testCb.waitForTestEmergencyNumberConfigured());
1389 
1390         bindImsService();
1391         mServiceCallBack = new ServiceCallBack();
1392         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1393 
1394         // Place outgoing emergency call
1395         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1396                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1397         telecomManager.placeCall(TEST_EMERGENCY_URI, new Bundle());
1398 
1399         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1400         Call call = getCall(mCurrentCallId);
1401         waitForCallSessionToNotBe(null);
1402         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1403 
1404         assertTrue(testCb.waitForOutgoingEmergencyCall(TEST_EMERGENCY_NUMBER));
1405         assertTrue(testCb.waitForCallActive());
1406 
1407         TestImsCallSessionImpl callSession = sServiceConnector.getCarrierService().getMmTelFeature()
1408                 .getImsCallsession();
1409         isCallActive(call, callSession);
1410 
1411         call.disconnect();
1412         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1413         isCallDisconnected(call, callSession);
1414         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1415         waitForUnboundService();
1416     }
1417 
1418     @Test
1419     @RequiresFlagsEnabled(
1420             Flags.FLAG_TERMINATE_ACTIVE_VIDEO_CALL_WHEN_ACCEPTING_SECOND_VIDEO_CALL_AS_AUDIO_ONLY)
testMultipleVideoCallAcceptTerminate()1421     public void testMultipleVideoCallAcceptTerminate() throws Exception {
1422         if (!ImsUtils.shouldTestImsCall()) {
1423             return;
1424         }
1425 
1426         PersistableBundle bundle = new PersistableBundle();
1427         bundle.putBoolean(CarrierConfigManager.KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL,
1428                 true);
1429         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, true);
1430         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false);
1431         overrideCarrierConfig(bundle);
1432 
1433         // Precondition : WFC disabled
1434         Uri callingUri = Uri.withAppendedPath(
1435                 SubscriptionManager.WFC_ENABLED_CONTENT_URI, "" + sTestSub);
1436         CountDownLatch contentObservedLatch = new CountDownLatch(1);
1437         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
1438 
1439         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1440         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
1441 
1442         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
1443                 ImsMmTelManager::isVoWiFiSettingEnabled);
1444         if (isEnabled) {
1445             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
1446                     (m) -> m.setVoWiFiSettingEnabled(false));
1447         }
1448         waitForLatch(contentObservedLatch, observer);
1449 
1450         MmTelFeature.MmTelCapabilities capabilities =
1451                 new MmTelFeature.MmTelCapabilities(
1452                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE
1453                                 | MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
1454 
1455         bindImsServiceForCapabilities(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
1456                 capabilities);
1457 
1458         ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(
1459                 ImsStreamMediaProfile.AUDIO_QUALITY_AMR,
1460                 ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE,
1461                 ImsStreamMediaProfile.VIDEO_QUALITY_QVGA_PORTRAIT,
1462                 ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE,
1463                 ImsStreamMediaProfile.RTT_MODE_DISABLED);
1464         sServiceConnector.getCarrierService().getMmTelFeature()
1465                 .setImsStreamProfileForVt(mediaProfile);
1466 
1467         mServiceCallBack = new ServiceCallBack();
1468         InCallServiceStateValidator.setCallbacks(mServiceCallBack);
1469 
1470         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1471                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1472 
1473         final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter), null);
1474         Bundle extras = new Bundle();
1475         extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
1476                 VideoProfile.STATE_BIDIRECTIONAL);
1477         extras.putInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE, TelephonyManager.NETWORK_TYPE_IWLAN);
1478 
1479         // MO Call
1480         telecomManager.placeCall(imsUri, extras);
1481         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1482 
1483         Call moCall = getCall(mCurrentCallId);
1484         waitForCallSessionToNotBe(null);
1485         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1486 
1487         TestImsCallSessionImpl moCallSession = sServiceConnector.getCarrierService()
1488                 .getMmTelFeature().getImsCallsession();
1489 
1490         isCallActive(moCall, moCallSession);
1491 
1492         // MT Call
1493         extras.putBoolean("android.telephony.ims.feature.extra.IS_USSD", false);
1494         extras.putBoolean("android.telephony.ims.feature.extra.IS_UNKNOWN_CALL", false);
1495         extras.putString("android:imsCallID", String.valueOf(++sCounter));
1496         extras.putLong("android:phone_id", 123456);
1497         sServiceConnector.getCarrierService().getMmTelFeature().onIncomingVtCallReceived(extras);
1498         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1499         waitForCallSessionToNotBe(null);
1500         TestImsCallSessionImpl mtCallSession =
1501                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1502 
1503         Call mtCall = null;
1504         if (mCurrentCallId != null) {
1505             mtCall = getCall(mCurrentCallId);
1506             if (mtCall.getDetails().getState() == Call.STATE_RINGING) {
1507                 mtCall.answer(VideoProfile.STATE_AUDIO_ONLY);
1508             }
1509         }
1510 
1511         // MO call should be terminated
1512         isCallDisconnected(moCall, moCallSession);
1513         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1514 
1515         isCallActive(mtCall, mtCallSession);
1516         mtCall.disconnect();
1517 
1518         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DISCONNECTING, WAIT_FOR_CALL_STATE));
1519         isCallDisconnected(mtCall, mtCallSession);
1520         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE));
1521 
1522         // Return the WFC activation status to before testing.
1523         if (isEnabled) {
1524             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
1525                     (m) -> m.setVoWiFiSettingEnabled(true));
1526         }
1527         waitForLatch(contentObservedLatch, observer);
1528 
1529         waitForUnboundService();
1530     }
1531 
createObserver(Uri observerUri, CountDownLatch latch)1532     private ContentObserver createObserver(Uri observerUri, CountDownLatch latch) {
1533         ContentObserver observer = new ContentObserver(sHandler) {
1534             @Override
1535             public void onChange(boolean selfChange, Uri uri) {
1536                 if (observerUri.equals(uri)) {
1537                     latch.countDown();
1538                 }
1539             }
1540         };
1541         getContext().getContentResolver().registerContentObserver(observerUri, true, observer);
1542         return observer;
1543     }
1544 
waitForLatch(CountDownLatch latch, ContentObserver observer)1545     private void waitForLatch(CountDownLatch latch, ContentObserver observer) {
1546         try {
1547             // Wait for the ContentObserver to fire signalling the change.
1548             latch.await(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1549         } catch (InterruptedException e) {
1550             fail("Interrupted Exception waiting for latch countdown:" + e.getMessage());
1551         } finally {
1552             getContext().getContentResolver().unregisterContentObserver(observer);
1553         }
1554     }
1555 
1556     private class TestTelephonyCallback extends TelephonyCallback
1557             implements TelephonyCallback.MediaQualityStatusChangedListener {
1558         LinkedBlockingQueue<MediaQualityStatus> mTestMediaQualityStatusQueue;
TestTelephonyCallback(LinkedBlockingQueue<MediaQualityStatus> queue)1559         TestTelephonyCallback(LinkedBlockingQueue<MediaQualityStatus> queue) {
1560             mTestMediaQualityStatusQueue = queue;
1561         }
1562         @Override
onMediaQualityStatusChanged(@onNull MediaQualityStatus status)1563         public void onMediaQualityStatusChanged(@NonNull MediaQualityStatus status) {
1564             mTestMediaQualityStatusQueue.offer(status);
1565         }
1566     }
1567 
1568     private class TestTelephonyCallbackForCallStateChange extends TelephonyCallback implements
1569             TelephonyCallback.CallAttributesListener,
1570             TelephonyCallback.PreciseCallStateListener,
1571             TelephonyCallback.OutgoingEmergencyCallListener,
1572             TelephonyCallback.EmergencyNumberListListener {
1573         LinkedBlockingQueue<List<CallState>> mTestCallStateListeQueue;
1574         private EmergencyNumber mLastOutgoingEmergencyNumber;
1575         private String mTestEmergencyNumber;
1576         private Semaphore mOutgoingEmergencyCallSemaphore = new Semaphore(0);
1577         private Semaphore mActiveCallStateSemaphore = new Semaphore(0);
1578         private Semaphore mTestEmergencyNumberSemaphore = new Semaphore(0);
TestTelephonyCallbackForCallStateChange(LinkedBlockingQueue<List<CallState>> queue)1579         TestTelephonyCallbackForCallStateChange(LinkedBlockingQueue<List<CallState>> queue) {
1580             mTestCallStateListeQueue = queue;
1581         }
1582         @Override
onCallStatesChanged(@onNull List<CallState> states)1583         public void onCallStatesChanged(@NonNull List<CallState> states) {
1584             mTestCallStateListeQueue.offer(states);
1585         }
1586 
1587         @Override
onPreciseCallStateChanged(@onNull PreciseCallState callState)1588         public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) {
1589             Log.i(LOG_TAG, "onPreciseCallStateChanged: state=" + callState);
1590             if (callState.getForegroundCallState() == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
1591                 mActiveCallStateSemaphore.release();
1592             }
1593         }
1594 
1595         @Override
onOutgoingEmergencyCall(EmergencyNumber emergencyNumber, int subscriptionId)1596         public void onOutgoingEmergencyCall(EmergencyNumber emergencyNumber, int subscriptionId) {
1597             Log.i(LOG_TAG, "onOutgoingEmergencyCall: emergencyNumber=" + emergencyNumber);
1598             mLastOutgoingEmergencyNumber = emergencyNumber;
1599             mOutgoingEmergencyCallSemaphore.release();
1600         }
1601 
1602         @Override
onEmergencyNumberListChanged(@onNull Map<Integer, List<EmergencyNumber>> emergencyNumberList)1603         public void onEmergencyNumberListChanged(@NonNull Map<Integer,
1604                         List<EmergencyNumber>> emergencyNumberList) {
1605             if (!TextUtils.isEmpty(mTestEmergencyNumber)) {
1606                 for (List<EmergencyNumber> emergencyNumbers : emergencyNumberList.values()) {
1607                     Log.i(LOG_TAG, "onEmergencyNumberListChanged: emergencyNumbers="
1608                             + emergencyNumbers.stream().map(Object::toString).collect(
1609                                     Collectors.joining(", ")));
1610                     for (EmergencyNumber emergencyNumber : emergencyNumbers) {
1611                         if (TextUtils.equals(mTestEmergencyNumber, emergencyNumber.getNumber())) {
1612                             mTestEmergencyNumberSemaphore.release();
1613                             break;
1614                         }
1615                     }
1616                 }
1617             }
1618         }
1619 
waitForCallActive()1620         public boolean waitForCallActive() {
1621             try {
1622                 if (!mActiveCallStateSemaphore.tryAcquire(
1623                         WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
1624                     Log.e(LOG_TAG, "Timed out to receive active call state");
1625                     return false;
1626                 }
1627             } catch (InterruptedException ex) {
1628                 Log.e(LOG_TAG, "waitForCallActive: ex=" + ex);
1629                 return false;
1630             }
1631             return true;
1632         }
1633 
waitForOutgoingEmergencyCall(String expectedNumber)1634         public boolean waitForOutgoingEmergencyCall(String expectedNumber) {
1635             try {
1636                 if (!mOutgoingEmergencyCallSemaphore.tryAcquire(
1637                         WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
1638                     Log.e(LOG_TAG, "Timed out to receive OutgoingEmergencyCall");
1639                     return false;
1640                 }
1641             } catch (InterruptedException ex) {
1642                 Log.e(LOG_TAG, "waitForOutgoingEmergencyCall: ex=" + ex);
1643                 return false;
1644             }
1645 
1646             // At this point we can only be sure that we got AN update, but not necessarily the one
1647             // we are looking for; wait until we see the state we want before verifying further.
1648             waitUntilConditionIsTrueOrTimeout(
1649                     new Condition() {
1650                         @Override
1651                         public Object expected() {
1652                             return true;
1653                         }
1654 
1655                         @Override
1656                         public Object actual() {
1657                             return mLastOutgoingEmergencyNumber != null
1658                                     && mLastOutgoingEmergencyNumber.getNumber().equals(
1659                                             expectedNumber);
1660                         }
1661                     },
1662                     WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
1663                     "Expected emergency number: " + expectedNumber);
1664             return TextUtils.equals(expectedNumber, mLastOutgoingEmergencyNumber.getNumber());
1665         }
1666 
setTestEmergencyNumber(String testEmergencyNumber)1667         public void setTestEmergencyNumber(String testEmergencyNumber) {
1668             mTestEmergencyNumber = testEmergencyNumber;
1669         }
1670 
waitForTestEmergencyNumberConfigured()1671         public boolean waitForTestEmergencyNumberConfigured() {
1672             try {
1673                 if (!mTestEmergencyNumberSemaphore.tryAcquire(
1674                         WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
1675                     Log.e(LOG_TAG, "Timed out to receive expected test emergency number "
1676                             + "configured");
1677                     return false;
1678                 }
1679             } catch (InterruptedException ex) {
1680                 Log.e(LOG_TAG, "waitForTestEmergencyNumberConfigured: ex=" + ex);
1681                 return false;
1682             }
1683             return true;
1684         }
1685     }
1686 
addConferenceCall(Call call1, Call call2)1687     void addConferenceCall(Call call1, Call call2) {
1688         InCallServiceStateValidator inCallService = mServiceCallBack.getService();
1689 
1690         // Verify that the calls have each other on their conferenceable list before proceeding
1691         List<Call> callConfList = new ArrayList<>();
1692         callConfList.add(call2);
1693         assertCallConferenceableList(call1, callConfList);
1694 
1695         callConfList.clear();
1696         callConfList.add(call1);
1697         assertCallConferenceableList(call2, callConfList);
1698 
1699         call2.conference(call1);
1700     }
1701 
assertCallConferenceableList(final Call call, final List<Call> conferenceableList)1702     void assertCallConferenceableList(final Call call, final List<Call> conferenceableList) {
1703         waitUntilConditionIsTrueOrTimeout(
1704                 new Condition() {
1705                     @Override
1706                     public Object expected() {
1707                         return conferenceableList;
1708                     }
1709 
1710                     @Override
1711                     public Object actual() {
1712                         return call.getConferenceableCalls();
1713                     }
1714                 }, WAIT_FOR_CONDITION,
1715                         "Call: " + call + " does not have the correct conferenceable call list."
1716         );
1717     }
1718 
assertParticiapantDisconnected(Call call)1719     private void assertParticiapantDisconnected(Call call) {
1720         waitUntilConditionIsTrueOrTimeout(
1721                 new Condition() {
1722                     @Override
1723                     public Object expected() {
1724                         return true;
1725                     }
1726 
1727                     @Override
1728                     public Object actual() {
1729                         return ((call.getState() == Call.STATE_DISCONNECTED)) ? true : false;
1730                     }
1731                 }, WAIT_FOR_CONDITION, "Call Disconnected");
1732     }
1733 
assertParticiapantAddedToConference(int count)1734     private void assertParticiapantAddedToConference(int count) {
1735         waitUntilConditionIsTrueOrTimeout(
1736                 new Condition() {
1737                     @Override
1738                     public Object expected() {
1739                         return true;
1740                     }
1741 
1742                     @Override
1743                     public Object actual() {
1744                         return (mParticipantCount == count) ? true : false;
1745                     }
1746                 }, WAIT_FOR_CONDITION, "Call Added");
1747     }
1748 
addOutgoingCalls()1749     private void addOutgoingCalls() throws Exception {
1750         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1751                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1752 
1753         // Place first outgoing call
1754         final Uri imsUri1 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter),
1755                 null);
1756         Bundle extras1 = new Bundle();
1757 
1758         telecomManager.placeCall(imsUri1, extras1);
1759         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1760 
1761         mCall1 = getCall(mCurrentCallId);
1762         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1763         waitForCallSessionToNotBe(null);
1764         mCallSession1 = sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1765         isCallActive(mCall1, mCallSession1);
1766         assertTrue("Call is not in Active State", (mCall1.getDetails().getState()
1767                 == Call.STATE_ACTIVE));
1768 
1769         // Place second outgoing call
1770         final Uri imsUri2 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter),
1771                 null);
1772         Bundle extras2 = new Bundle();
1773 
1774         telecomManager.placeCall(imsUri2, extras2);
1775         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1776 
1777         mCall2 = getCall(mCurrentCallId);
1778         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1779         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
1780         assertTrue("Call is not in Hold State", (mCall1.getDetails().getState()
1781                 == Call.STATE_HOLDING));
1782 
1783         // Wait till the object of TestImsCallSessionImpl for second call created.
1784         waitForCallSessionToNotBe(mCallSession1);
1785         mCallSession2 = sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1786         isCallActive(mCall2, mCallSession2);
1787         assertTrue("Call is not in Active State", (mCall2.getDetails().getState()
1788                 == Call.STATE_ACTIVE));
1789     }
1790 
addThirdOutgoingCall()1791     private void addThirdOutgoingCall() {
1792         // add a third outgoing call when a conference call already exists.
1793         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
1794                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
1795         final Uri imsUri3 = Uri.fromParts(PhoneAccount.SCHEME_TEL, String.valueOf(++sCounter),
1796                 null);
1797         Bundle extras3 = new Bundle();
1798 
1799         telecomManager.placeCall(imsUri3, extras3);
1800         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE));
1801         waitNextCallAdded(String.valueOf(sCounter));
1802 
1803         mCall3 = getCall(mCurrentCallId);
1804         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_DIALING, WAIT_FOR_CALL_STATE));
1805         assertTrue(callingTestLatchCountdown(LATCH_IS_CALL_HOLDING, WAIT_FOR_CALL_STATE));
1806         assertTrue("Call is not in Hold State", (mConferenceCall.getDetails().getState()
1807                 == Call.STATE_HOLDING));
1808 
1809         waitForCallSessionToNotBe(mCallSession2);
1810         mCallSession3 =
1811                 sServiceConnector.getCarrierService().getMmTelFeature().getImsCallsession();
1812 
1813         isCallActive(mCall3, mCallSession3);
1814         assertTrue("Call is not in Active State", (mCall3.getDetails().getState()
1815                 == Call.STATE_ACTIVE));
1816     }
1817 
waitForCallSessionToNotBe(TestImsCallSessionImpl previousCallSession)1818     private void waitForCallSessionToNotBe(TestImsCallSessionImpl previousCallSession) {
1819         waitUntilConditionIsTrueOrTimeout(
1820                 new Condition() {
1821                     @Override
1822                     public Object expected() {
1823                         return true;
1824                     }
1825 
1826                     @Override
1827                     public Object actual() {
1828                         TestMmTelFeature mmtelfeatue = sServiceConnector.getCarrierService()
1829                                 .getMmTelFeature();
1830                         return (mmtelfeatue.getImsCallsession() != previousCallSession) ? true
1831                                 : false;
1832                     }
1833                 }, WAIT_FOR_CONDITION, "CallSession Created");
1834     }
1835 
waitNextCallAdded(String expectedUri)1836     private void waitNextCallAdded(String expectedUri) {
1837         callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED, WAIT_FOR_CALL_STATE);
1838         final String[] actualUri = {getCall(mCurrentCallId).getDetails().getHandle().toString()};
1839         waitUntilConditionIsTrueOrTimeout(
1840                 new Condition() {
1841                     @Override
1842                     public Object expected() {
1843                         return true;
1844                     }
1845 
1846                     @Override
1847                     public Object actual() {
1848                         if (!actualUri[0].contains(expectedUri)) {
1849                             assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CALL_ADDED,
1850                                     WAIT_FOR_CALL_STATE));
1851                             actualUri[0] = getCall(
1852                                     mCurrentCallId).getDetails().getHandle().toString();
1853                             return false;
1854                         }
1855                         return true;
1856                     }
1857                 }, WAIT_FOR_CONDITION, "Next Call added");
1858     }
1859 
waitCallRenegotiating(TestImsCallSessionImpl callSession)1860     private void waitCallRenegotiating(TestImsCallSessionImpl callSession) {
1861         waitUntilConditionIsTrueOrTimeout(
1862                 new Condition() {
1863                     @Override
1864                     public Object expected() {
1865                         return true;
1866                     }
1867 
1868                     @Override
1869                     public Object actual() {
1870                         return callSession.isRenegotiating() ? true : false;
1871                     }
1872                 }, WAIT_FOR_CONDITION, callSession.getState() + ", waitCallRenegotiating");
1873     }
1874 
makeConferenceCall()1875     private void makeConferenceCall() throws Exception {
1876         // Initialize the MERGE_START latch with a count of 2 (one for each call of the conference):
1877         overrideLatchCount(LATCH_IS_ON_MERGE_START, 2);
1878 
1879         addOutgoingCalls();
1880         addConferenceCall(mCall1, mCall2);
1881 
1882         // Wait for merge start first and second call
1883         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_START, WAIT_FOR_CALL_STATE));
1884         // Wait for merge complete background call:
1885         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_COMPLETE, WAIT_FOR_CALL_STATE));
1886         // Wait for remove first call
1887         callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE);
1888         // Wait for merge complete foreground call:
1889         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_MERGE_COMPLETE, WAIT_FOR_CALL_STATE));
1890         // Wait for conference call added
1891         assertTrue(
1892                 callingTestLatchCountdown(LATCH_IS_ON_CONFERENCE_CALL_ADDED, WAIT_FOR_CALL_STATE));
1893         // Wait for remove second call
1894         callingTestLatchCountdown(LATCH_IS_ON_CALL_REMOVED, WAIT_FOR_CALL_STATE);
1895         // Wait to add participants in conference
1896         assertTrue("Conference call is not added", mServiceCallBack.getService()
1897                 .getConferenceCallCount() > 0);
1898 
1899         mConferenceCall = mServiceCallBack.getService().getLastConferenceCall();
1900         assertNotNull("Unable to add conference call, its null", mConferenceCall);
1901 
1902         ConferenceHelper confHelper = sServiceConnector.getCarrierService().getMmTelFeature()
1903                 .getConferenceHelper();
1904 
1905         mConfCallSession = confHelper.getConferenceSession();
1906         isCallActive(mConferenceCall, mConfCallSession);
1907         assertTrue("Conference call is not Active", mConfCallSession.isInCall());
1908 
1909         //Verify mCall1 and mCall2 disconnected after conference Merge success
1910         assertParticiapantDisconnected(mCall1);
1911         assertParticiapantDisconnected(mCall2);
1912 
1913         //Verify conference participant connections are connected.
1914         assertTrue(callingTestLatchCountdown(LATCH_IS_ON_CHILDREN_CHANGED, WAIT_FOR_CALL_STATE));
1915         assertParticiapantAddedToConference(2);
1916 
1917         // Since the conference call has been made, remove session1&2 from the confHelper session.
1918         confHelper.removeSession(mCallSession1);
1919         confHelper.removeSession(mCallSession2);
1920     }
1921 
resetCallSessionObjects()1922     private void resetCallSessionObjects() {
1923         mCall1 = mCall2 = mCall3 = mConferenceCall = null;
1924         mCallSession1 = mCallSession2 = mCallSession3 = mConfCallSession = null;
1925         if (sServiceConnector.getCarrierService() == null
1926                 || sServiceConnector.getCarrierService().getMmTelFeature() == null) {
1927             return;
1928         }
1929         ConferenceHelper confHelper = sServiceConnector.getCarrierService().getMmTelFeature()
1930                 .getConferenceHelper();
1931         if (confHelper != null) {
1932             confHelper.clearSessions();
1933         }
1934     }
1935 }
1936