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