• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package android.telecom.cts;
18 
19 import static android.media.AudioManager.MODE_IN_CALL;
20 import static android.media.AudioManager.MODE_IN_COMMUNICATION;
21 import static android.telecom.cts.TestUtils.SELF_MANAGED_ACCOUNT_LABEL;
22 import static android.telecom.cts.TestUtils.TEST_SELF_MANAGED_HANDLE_1;
23 import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
24 import static android.telecom.cts.TestUtils.waitOnAllHandlers;
25 
26 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
27 
28 import static org.junit.Assert.assertNotEquals;
29 
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.ServiceConnection;
34 import android.database.Cursor;
35 import android.graphics.Color;
36 import android.media.AudioManager;
37 import android.net.Uri;
38 import android.os.Bundle;
39 import android.os.IBinder;
40 import android.os.OutcomeReceiver;
41 import android.provider.CallLog;
42 import android.telecom.Call;
43 import android.telecom.CallAudioState;
44 import android.telecom.CallEndpoint;
45 import android.telecom.CallEndpointException;
46 import android.telecom.Connection;
47 import android.telecom.ConnectionService;
48 import android.telecom.DisconnectCause;
49 import android.telecom.InCallService;
50 import android.telecom.PhoneAccount;
51 import android.telecom.PhoneAccountHandle;
52 import android.telecom.TelecomManager;
53 import android.telecom.VideoProfile;
54 import android.telecom.cts.selfmanagedcstestapp.ICtsSelfManagedConnectionServiceControl;
55 import android.telecom.cts.selfmanagedcstestappone.CtsSelfManagedConnectionServiceControlOne;
56 import android.util.Log;
57 
58 import com.android.compatibility.common.util.ApiTest;
59 import com.android.compatibility.common.util.CddTest;
60 
61 import java.util.ArrayList;
62 import java.util.List;
63 import java.util.concurrent.CountDownLatch;
64 import java.util.concurrent.Executor;
65 import java.util.concurrent.TimeUnit;
66 import java.util.function.Predicate;
67 
68 /**
69  * CTS tests for the self-managed {@link android.telecom.ConnectionService} APIs.
70  * For more information about these APIs, see {@link android.telecom}, and
71  * {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED}.
72  */
73 
74 public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockServices {
75     private static final String TAG = "SelfManagedConnectionServiceTest";
76     private static final long TIMEOUT = 3000L;
77     private Uri TEST_ADDRESS_1 = Uri.fromParts("sip", "call1@test.com", null);
78     private Uri TEST_ADDRESS_2 = Uri.fromParts("tel", "6505551212", null);
79     private Uri TEST_ADDRESS_3 = Uri.fromParts("tel", "6505551213", null);
80     private Uri TEST_ADDRESS_4 = Uri.fromParts(TestUtils.TEST_URI_SCHEME, "fizzle_schmozle", null);
81 
82     private static final String SELF_MANAGED_CS_CONTROL =
83             "android.telecom.cts.selfmanagedcstestapp.ACTION_SELF_MANAGED_CS_CONTROL";
84 
85     private static final String SELF_MANAGED_CS_PKG_1 =
86             CtsSelfManagedConnectionServiceControlOne.class.getPackage().getName();
87     private static final ComponentName SELF_MANAGED_CS_1 = ComponentName.createRelative(
88             SELF_MANAGED_CS_PKG_1, CtsSelfManagedConnectionServiceControlOne.class.getName());
89 
90     @Override
setUp()91     protected void setUp() throws Exception {
92         super.setUp();
93         NewOutgoingCallBroadcastReceiver.reset();
94         mContext = getInstrumentation().getContext();
95         if (mShouldTestTelecom && TestUtils.hasTelephonyFeature(mContext)) {
96             // Register and enable the CTS ConnectionService; we want to be able to test a managed
97             // ConnectionService alongside a self-managed ConnectionService.
98             // Also set FLAG_SET_DEFAULT to test the case where the call is not expected to go over
99             // the self-managed ConnectionService.
100             setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE | FLAG_SET_DEFAULT);
101 
102             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
103             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_2);
104             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_3);
105             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_4);
106         }
107     }
108 
109     @Override
tearDown()110     protected void tearDown() throws Exception {
111         if (mShouldTestTelecom && TestUtils.hasTelephonyFeature(mContext)) {
112             CtsSelfManagedConnectionService connectionService =
113                     CtsSelfManagedConnectionService.getConnectionService();
114             if (connectionService != null) {
115                 connectionService.tearDown();
116                 mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_1);
117                 mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_2);
118                 mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_3);
119                 mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_4);
120             }
121         }
122         super.tearDown();
123     }
124 
125     private static class TestServiceConnection implements ServiceConnection {
126         private IBinder mService;
127         private final CountDownLatch mLatch = new CountDownLatch(1);
128         private boolean mIsConnected;
129         private final PhoneAccount mAssociatedAccount;
130 
131         private ICtsSelfManagedConnectionServiceControl mControl;
132 
TestServiceConnection(PhoneAccount account)133         TestServiceConnection(PhoneAccount account) {
134             mAssociatedAccount = account;
135         }
136 
137         @Override
onServiceConnected(ComponentName componentName, IBinder service)138         public void onServiceConnected(ComponentName componentName, IBinder service) {
139             Log.i(TAG, "Service Connected: " + componentName);
140             mService = service;
141             mControl = ICtsSelfManagedConnectionServiceControl.Stub.asInterface(service);
142             mIsConnected = true;
143             mLatch.countDown();
144         }
145 
146         @Override
onServiceDisconnected(ComponentName componentName)147         public void onServiceDisconnected(ComponentName componentName) {
148             mService = null;
149         }
150 
getService()151         public IBinder getService() {
152             return mService;
153         }
154 
getInterface()155         public ICtsSelfManagedConnectionServiceControl getInterface() {
156             return mControl;
157         }
158 
getAssociatedAccount()159         public PhoneAccount getAssociatedAccount() {
160             return mAssociatedAccount;
161         }
162 
waitBind()163         public boolean waitBind() {
164             try {
165                 mLatch.await(TIMEOUT, TimeUnit.MILLISECONDS);
166                 return mIsConnected;
167             } catch (InterruptedException e) {
168                 return false;
169             }
170         }
171     }
172 
bindExternalSelfManagedServiceAndRegister( PhoneAccount account)173     private TestServiceConnection bindExternalSelfManagedServiceAndRegister(
174             PhoneAccount account) throws Exception {
175         TestServiceConnection control = setUpControl(SELF_MANAGED_CS_CONTROL, SELF_MANAGED_CS_1,
176                 account);
177         control.getInterface().init();
178         control.getInterface().registerPhoneAccount(account);
179         return control;
180     }
181 
setUpControl(String action, ComponentName componentName, PhoneAccount acct)182     private TestServiceConnection setUpControl(String action, ComponentName componentName,
183             PhoneAccount acct) {
184         Intent bindIntent = new Intent(action);
185         bindIntent.setComponent(componentName);
186 
187         TestServiceConnection serviceConnection = new TestServiceConnection(acct);
188         mContext.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
189         if (!serviceConnection.waitBind()) {
190             fail("fail bind to service");
191         }
192         return serviceConnection;
193     }
194 
tearDownControl(TestServiceConnection c)195     private void tearDownControl(TestServiceConnection c) throws Exception {
196         c.getInterface().unregisterPhoneAccount(c.getAssociatedAccount().getAccountHandle());
197         c.getInterface().deInit();
198         mContext.unbindService(c);
199     }
200 
201     /**
202      * Tests {@link TelecomManager#getSelfManagedPhoneAccounts()} API to ensure it returns a list of
203      * the registered self-managed {@link android.telecom.PhoneAccount}s.
204      */
205     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
206     @ApiTest(apis = {"android.telecom.TelecomManager#getSelfManagedPhoneAccounts"})
testTelecomManagerGetSelfManagedPhoneAccounts()207     public void testTelecomManagerGetSelfManagedPhoneAccounts() {
208         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
209             return;
210         }
211 
212         List<PhoneAccountHandle> phoneAccountHandles =
213                 mTelecomManager.getSelfManagedPhoneAccounts();
214 
215         assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_1));
216         assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_2));
217         assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_3));
218         assertFalse(phoneAccountHandles.contains(TestUtils.TEST_PHONE_ACCOUNT_HANDLE));
219     }
220 
221     /**
222      * Tests the ability to successfully register a self-managed
223      * {@link android.telecom.PhoneAccount}.
224      * <p>
225      * It should be possible to register self-managed Connection Services which suppor the TEL, SIP,
226      * or other URI schemes.
227      */
228     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
229     @ApiTest(apis = {"android.telecom.TelecomManager#registerPhoneAccount",
230             "android.telecom.PhoneAccount"})
testRegisterSelfManagedConnectionService()231     public void testRegisterSelfManagedConnectionService() {
232         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
233             return;
234         }
235         verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_1,
236                 TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
237         verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_2,
238                 TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_2);
239         verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_3,
240                 TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_3);
241     }
242 
243     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
244     @ApiTest(apis = {"android.telecom.TelecomManager#registerPhoneAccount",
245             "android.telecom.PhoneAccount"})
testSelfManagedConnectionServiceRegistrationUnmodifiable()246     public void testSelfManagedConnectionServiceRegistrationUnmodifiable() {
247         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
248             return;
249         }
250 
251         verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_1,
252                 TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
253         PhoneAccount newPhoneAccount = PhoneAccount.builder(
254                         TEST_SELF_MANAGED_HANDLE_1, SELF_MANAGED_ACCOUNT_LABEL)
255                 .setAddress(Uri.parse("sip:test@test.com"))
256                 .setSubscriptionAddress(Uri.parse("sip:test@test.com"))
257                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
258                         | PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
259                         | PhoneAccount.CAPABILITY_VIDEO_CALLING)
260                 .setHighlightColor(Color.BLUE)
261                 .setShortDescription(SELF_MANAGED_ACCOUNT_LABEL)
262                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
263                 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
264                 .build();
265         try {
266             mTelecomManager.registerPhoneAccount(newPhoneAccount);
267             fail("Self-managed phone account can be replaced to a call provider phone account!");
268         } catch (IllegalArgumentException e) {
269             // expected
270         }
271     }
272 
verifyAccountRegistration(PhoneAccountHandle handle, PhoneAccount phoneAccount)273     private void verifyAccountRegistration(PhoneAccountHandle handle, PhoneAccount phoneAccount) {
274         // The phone account is registered in the setup method.
275         assertPhoneAccountRegistered(handle);
276         assertPhoneAccountEnabled(handle);
277         PhoneAccount registeredAccount = mTelecomManager.getPhoneAccount(handle);
278 
279         // It should exist and be the same as the previously registered one.
280         assertNotNull(registeredAccount);
281 
282         // We cannot just check for equality of the PhoneAccount since the one we registered is not
283         // enabled, and the one we get back after registration is.
284         assertPhoneAccountEquals(phoneAccount, registeredAccount);
285 
286         // An important assumption is that self-managed PhoneAccounts are automatically
287         // enabled by default.
288         assertTrue("Self-managed PhoneAccounts must be enabled by default.",
289                 registeredAccount.isEnabled());
290     }
291 
292     /**
293      * This test ensures that a {@link android.telecom.PhoneAccount} declared as self-managed cannot
294      * but is also registered as a call provider is not permitted.
295      *
296      * A self-managed {@link android.telecom.PhoneAccount} cannot also be a call provider.
297      */
298     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
299     @ApiTest(apis = {"android.telecom.TelecomManager#registerPhoneAccount",
300             "android.telecom.PhoneAccount"})
testRegisterCallCapableSelfManagedConnectionService()301     public void testRegisterCallCapableSelfManagedConnectionService() {
302         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
303             return;
304         }
305 
306         // Attempt to register both a call provider and self-managed account.
307         PhoneAccount toRegister = TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1.toBuilder()
308                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
309                         PhoneAccount.CAPABILITY_CALL_PROVIDER)
310                 .build();
311 
312         registerAndExpectFailure(toRegister);
313     }
314 
315     /**
316      * This test ensures that a {@link android.telecom.PhoneAccount} declared as self-managed cannot
317      * but is also registered as a sim subscription is not permitted.
318      *
319      * A self-managed {@link android.telecom.PhoneAccount} cannot also be a SIM subscription.
320      */
321     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
322     @ApiTest(apis = {"android.telecom.TelecomManager#registerPhoneAccount",
323             "android.telecom.PhoneAccount"})
testRegisterSimSelfManagedConnectionService()324     public void testRegisterSimSelfManagedConnectionService() {
325         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
326             return;
327         }
328 
329         // Attempt to register both a call provider and self-managed account.
330         PhoneAccount toRegister = TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1.toBuilder()
331                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
332                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
333                 .build();
334 
335         registerAndExpectFailure(toRegister);
336     }
337 
338     /**
339      * This test ensures that a {@link android.telecom.PhoneAccount} declared as self-managed cannot
340      * but is also registered as a connection manager is not permitted.
341      *
342      * A self-managed {@link android.telecom.PhoneAccount} cannot also be a connection manager.
343      */
344     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
345     @ApiTest(apis = {"android.telecom.TelecomManager#registerPhoneAccount",
346             "android.telecom.PhoneAccount"})
testRegisterConnectionManagerSelfManagedConnectionService()347     public void testRegisterConnectionManagerSelfManagedConnectionService() {
348         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
349             return;
350         }
351 
352         // Attempt to register both a call provider and self-managed account.
353         PhoneAccount toRegister = TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1.toBuilder()
354                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
355                         PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
356                 .build();
357 
358         registerAndExpectFailure(toRegister);
359     }
360 
361     /**
362      * Attempts to register a {@link android.telecom.PhoneAccount}, expecting a security exception
363      * which indicates that invalid capabilities were specified.
364      *
365      * @param toRegister The PhoneAccount to register.
366      */
registerAndExpectFailure(PhoneAccount toRegister)367     private void registerAndExpectFailure(PhoneAccount toRegister) {
368         try {
369             mTelecomManager.registerPhoneAccount(toRegister);
370         } catch (SecurityException se) {
371             assertEquals("Self-managed ConnectionServices cannot also be call capable, " +
372                     "connection managers, or SIM accounts.", se.getMessage());
373             return;
374         }
375         fail("Expected SecurityException");
376     }
377 
378     /**
379      * Tests ability to add a new self-managed incoming connection.
380      */
381     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
382     @ApiTest(apis = {"android.telecom.TelecomManager#addNewIncomingCall"})
testAddSelfManagedIncomingConnection()383     public void testAddSelfManagedIncomingConnection() throws Exception {
384         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
385             return;
386         }
387 
388         addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
389         addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_3);
390         addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_3, TEST_ADDRESS_4);
391     }
392 
addAndVerifyIncomingCall(PhoneAccountHandle handle, Uri address)393     private void addAndVerifyIncomingCall(PhoneAccountHandle handle, Uri address)
394             throws Exception {
395         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager, handle, address);
396 
397         // Ensure Telecom bound to the self managed CS
398         if (!CtsSelfManagedConnectionService.waitForBinding()) {
399             fail("Could not bind to Self-Managed ConnectionService");
400         }
401 
402         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(address);
403 
404         // Expect callback indicating that UI should be shown.
405         connection.getOnShowIncomingUiInvokeCounter().waitForCount(1);
406         setActiveAndVerify(connection);
407 
408         // Ensure that the connection defaulted to voip audio mode.
409         assertTrue(connection.getAudioModeIsVoip());
410         // Ensure AudioManager has correct voip mode.
411         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
412         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
413 
414         // Expect there to be no managed calls at the moment.
415         assertFalse(mTelecomManager.isInManagedCall());
416         assertTrue(mTelecomManager.isInCall());
417 
418         setDisconnectedAndVerify(connection);
419 
420         if (isLoggedCall(handle)) {
421             verifyCallLogging(address, CallLog.Calls.INCOMING_TYPE, handle);
422         }
423     }
424 
425     /**
426      * Tests ensures that Telecom disallow to place outgoing self-managed call when the ongoing
427      * managed call can not be held.
428      */
429     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
430     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testDisallowOutgoingCallWhileOngoingManagedCallCanNotBeHeld()431     public void testDisallowOutgoingCallWhileOngoingManagedCallCanNotBeHeld() throws Exception {
432         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
433             return;
434         }
435 
436         // GIVEN an ongoing managed call that can not be held
437         addAndVerifyNewIncomingCall(createTestNumber(), null);
438         Connection connection = verifyConnectionForIncomingCall();
439         int capabilities = connection.getConnectionCapabilities();
440         capabilities &= ~Connection.CAPABILITY_HOLD;
441         connection.setConnectionCapabilities(capabilities);
442 
443         // answer the incoming call
444         MockInCallService inCallService = mInCallCallbacks.getService();
445         Call call = inCallService.getLastCall();
446         call.answer(VideoProfile.STATE_AUDIO_ONLY);
447         assertConnectionState(connection, Connection.STATE_ACTIVE);
448 
449         // WHEN place a self-managed outgoing call
450         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
451                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
452 
453         // THEN the new outgoing call is failed.
454         CtsSelfManagedConnectionService.waitForBinding();
455         assertTrue(CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
456                 CtsSelfManagedConnectionService.CREATE_OUTGOING_CONNECTION_FAILED_LOCK));
457 
458         assertIsOutgoingCallPermitted(false, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
459     }
460 
461     /**
462      * Tests ensures that Telecom update outgoing self-managed call state disconnected when
463      * remote side call is rejected.
464      */
465     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
466     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testOutgoingCallRejectedByRemoteParty()467     public void testOutgoingCallRejectedByRemoteParty() throws Exception {
468         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
469             return;
470         }
471 
472         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
473                 TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_2);
474 
475         // Ensure Telecom bound to the self managed CS
476         if (!CtsSelfManagedConnectionService.waitForBinding()) {
477             fail("Could not bind to Self-Managed ConnectionService");
478         }
479 
480         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_2);
481         assertNotNull("Self-Managed Connection should NOT be null.", connection);
482         assertTrue("Self-Managed Connection should be outgoing.", !connection.isIncomingCall());
483 
484         // The self-managed ConnectionService must NOT have been prompted to show its incoming call
485         // UI for an outgoing call.
486         assertEquals(connection.getOnShowIncomingUiInvokeCounter().getInvokeCount(), 0);
487 
488         // Expect that the new outgoing call broadcast did not fire for the self-managed calls.
489         assertFalse(NewOutgoingCallBroadcastReceiver.isNewOutgoingCallBroadcastReceived());
490 
491         assertConnectionState(connection, Connection.STATE_INITIALIZING);
492         assertCallState(mInCallCallbacks.getService().getLastCall(), Call.STATE_DIALING);
493 
494         connection.setDialing();
495         assertConnectionState(connection, Connection.STATE_DIALING);
496 
497         connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
498 
499         assertConnectionState(connection, Connection.STATE_DISCONNECTED);
500         assertCallState(mInCallCallbacks.getService().getLastCall(), Call.STATE_DISCONNECTED);
501 
502         setDisconnectedAndVerify(connection);
503     }
504 
505     /**
506      * Tests ensures that Telecom update self-managed call mute state when user sets mute option.
507      */
508     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
509     @ApiTest(apis = {"android.telecom.Connection#onMuteStateChanged"})
testSelfManagedCallMuteAndUnmute()510     public void testSelfManagedCallMuteAndUnmute() throws Exception {
511         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
512             return;
513         }
514 
515         SelfManagedConnection connection = null;
516 
517         try {
518             connection = placeSelfManagedCallAndGetConnection(TestUtils.TEST_SELF_MANAGED_HANDLE_2,
519                     TEST_ADDRESS_2);
520 
521             final MockInCallService inCallService = getInCallService();
522             final Call call = inCallService.getLastCall();
523 
524             assertMuteState(connection, false);
525 
526             // Explicitly call super implementation to enable detection of CTS coverage
527             ((InCallService) inCallService).setMuted(true);
528 
529             assertMuteState(connection, true);
530             assertMuteState(inCallService, true);
531 
532             inCallService.setMuted(false);
533             assertMuteState(connection, false);
534             assertMuteState(inCallService, false);
535         } finally {
536             if (connection != null) {
537                 // disconnect call
538                 connection.disconnectAndDestroy();
539                 // verify the call was disconnected
540                 assertIsInCall(false);
541                 assertIsInManagedCall(false);
542             }
543         }
544     }
545 
546     /**
547      * Tests ensures that Telecom update outgoing self-managed video call video state to false when
548      * remote side call is picked only for audio.
549      */
550     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
551     @ApiTest(apis = {"android.telecom.Connection#onAnswer"})
testVideoCallStateDowngradeToAudio()552     public void testVideoCallStateDowngradeToAudio() throws Exception {
553         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
554             return;
555         }
556 
557         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
558                 TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_2,
559                 VideoProfile.STATE_BIDIRECTIONAL);
560 
561         // Ensure Telecom bound to the self managed CS
562         if (!CtsSelfManagedConnectionService.waitForBinding()) {
563             fail("Could not bind to Self-Managed ConnectionService");
564         }
565 
566         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_2);
567         assertNotNull("Self-Managed Connection should NOT be null.", connection);
568         assertTrue("Self-Managed Connection should be outgoing.", !connection.isIncomingCall());
569 
570         final MockInCallService inCallService = mInCallCallbacks.getService();
571         final Call call = inCallService.getLastCall();
572 
573         connection.setDialing();
574         assertCallState(call, Call.STATE_DIALING);
575 
576         assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
577 
578         connection.setVideoState(VideoProfile.STATE_AUDIO_ONLY);
579 
580         assertEquals(VideoProfile.STATE_AUDIO_ONLY, connection.getVideoState());
581 
582         connection.setActive();
583         assertCallState(call, Call.STATE_ACTIVE);
584 
585         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
586         setDisconnectedAndVerify(connection);
587     }
588 
589     /**
590      * Tests ability to add a new self-managed outgoing connection.
591      * <p>
592      * A self-managed {@link ConnectionService} shall be able to place an outgoing call to tel or
593      * sip {@link Uri}s without being interrupted by system UX or other Telephony-related logic.
594      */
595     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
596     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testAddSelfManagedOutgoingConnection()597     public void testAddSelfManagedOutgoingConnection() throws Exception {
598         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
599             return;
600         }
601         assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
602         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
603 
604         assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_2);
605         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_3);
606 
607         assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_3);
608         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_3, TEST_ADDRESS_4);
609     }
610 
611     /**
612      * Ensure that a self-managed call which does not declare
613      * {@link PhoneAccount#EXTRA_LOG_SELF_MANAGED_CALLS} will NOT be logged in the call log.
614      * We do this as a separate case because we don't want on the logging latch used in the other
615      * tests if we don't expect a call to be logged (it would make the CTS mighty slow).
616      * @throws Exception
617      */
618     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
619     @ApiTest(apis = {"android.telecom.PhoneAccount#EXTRA_LOG_SELF_MANAGED_CALLS"})
testSelfManagedCallNotLogged()620     public void testSelfManagedCallNotLogged() throws Exception {
621         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
622             return;
623         }
624 
625         // First, complete the call which should not be logged.
626         Uri unloggedAddress = getTestNumber();
627         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_1, unloggedAddress);
628 
629         // Next, place a call which we DO expect to be logged.
630         Uri loggedAddress = getTestNumber();
631         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_2, loggedAddress);
632 
633         // The verification code for un-logged numbers doesn't actually wait on the call log latch
634         // since it would cause the tests to all run slow.  However, since we just logged two calls
635         // and the second one would have triggered the call log latch, we can assume that the last
636         // two entries in the call log should:
637         // 1. NOT contain the un-logged call.
638         // 2. CONTAIN the logged call.
639 
640         // Lets get the last two entries in the log in descending order by ID.  This means that the
641         // logged call will be first.
642         Cursor callsCursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null,
643                 null, null, CallLog.Calls._ID + " DESC limit 2;");
644         int numberIndex = callsCursor.getColumnIndex(CallLog.Calls.NUMBER);
645 
646         // Check that we see the expected log call.
647         if (callsCursor.moveToNext()) {
648             String number = callsCursor.getString(numberIndex);
649             assertEquals(loggedAddress.getSchemeSpecificPart(), number);
650         } else {
651             fail("Expected a logged call.");
652         }
653 
654         // Now check to ensure the call we DID NOT want to have logged is indeed not logged.
655         if (callsCursor.moveToNext()) {
656             // Something else was logged; make sure we did not log the call where the PhoneAccount
657             // does not indicate calls should be logged.
658             String number = callsCursor.getString(numberIndex);
659             assertNotEquals(unloggedAddress.getSchemeSpecificPart(), number);
660         } else {
661             // This is great; there was nothing else in the call log!
662         }
663 
664     }
665 
placeAndVerifyOutgoingCall(PhoneAccountHandle handle, Uri address)666     private void placeAndVerifyOutgoingCall(PhoneAccountHandle handle, Uri address) throws Exception {
667 
668         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager, handle, address);
669 
670         // Ensure Telecom bound to the self managed CS
671         if (!CtsSelfManagedConnectionService.waitForBinding()) {
672             fail("Could not bind to Self-Managed ConnectionService");
673         }
674 
675         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(address);
676         assertNotNull("Self-Managed Connection should NOT be null.", connection);
677         assertTrue("Self-Managed Connection should be outgoing.", !connection.isIncomingCall());
678 
679         // The self-managed ConnectionService must NOT have been prompted to show its incoming call
680         // UI for an outgoing call.
681         assertEquals(connection.getOnShowIncomingUiInvokeCounter().getInvokeCount(), 0);
682 
683         setActiveAndVerify(connection);
684 
685         // Ensure that the connection defaulted to voip audio mode.
686         assertTrue(connection.getAudioModeIsVoip());
687         // Ensure AudioManager has correct voip mode.
688         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
689         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
690 
691         // Expect there to be no managed calls at the moment.
692         assertFalse(mTelecomManager.isInManagedCall());
693         // But there should be a call (including self-managed).
694         assertTrue(mTelecomManager.isInCall());
695 
696         // Expect that the new outgoing call broadcast did not fire for the self-managed calls.
697         assertFalse(NewOutgoingCallBroadcastReceiver.isNewOutgoingCallBroadcastReceived());
698 
699         setDisconnectedAndVerify(connection);
700 
701         if (isLoggedCall(handle)) {
702             verifyCallLogging(address, CallLog.Calls.OUTGOING_TYPE, handle);
703         }
704     }
705 
706     /**
707      * Test the scenario where OEM tries to toggle {@link android.telecom.Connection
708      * #setAudioModeIsVoip(boolean)} to false. Telecom should restrict this action as it can cause
709      * unwanted behavior such as audio issues.
710      *
711      * @throws Exception ;should not hit exception.
712      */
713     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
714     @ApiTest(apis = {"android.telecom.Connection#setAudioModeIsVoip"})
testAudioModeRemainsVoip()715     public void testAudioModeRemainsVoip() throws Exception {
716         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
717             return;
718         }
719 
720         SelfManagedConnection connection = null;
721 
722         try {
723             connection = placeSelfManagedCallAndGetConnection(TEST_SELF_MANAGED_HANDLE_1,
724                     TEST_ADDRESS_1);
725 
726             // verify audio mode is voip
727             assertTrue(connection.getAudioModeIsVoip());
728 
729             // send request to change audioModeIsVoip to FALSE
730             connection.setAudioModeIsVoip(false);
731 
732             // verify audio mode is STILL voip (expected)
733             assertTrue(connection.getAudioModeIsVoip());
734         } finally {
735             if (connection != null) {
736                 // disconnect call
737                 connection.disconnectAndDestroy();
738                 // verify the call was disconnected
739                 assertIsInCall(false);
740                 assertIsInManagedCall(false);
741             }
742         }
743     }
744 
745     /**
746      * Test the scenario where a user starts a self-managed call and while that call is active,
747      * starts a sim based call.  This test verifies the audio mode is correct at every point.
748      *
749      * @throws Exception ;should not hit exception.
750      */
751     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
752     @ApiTest(apis = {"android.telecom.Connection#setAudioModeIsVoip"})
testSelfManagedAndSimBasedCallSwapping()753     public void testSelfManagedAndSimBasedCallSwapping() throws Exception {
754         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
755             return;
756         }
757         TestServiceConnection selfManagedConnection = null;
758 
759         Bundle extras = new Bundle();
760         extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
761                 TestUtils.TEST_SIM_PHONE_ACCOUNT.getAccountHandle());
762 
763         try {
764             registerSimAccountIfNeeded();
765             // 1. start a self-managed call & ensure ACTIVE & MODE_IN_COMMUNICATION
766             selfManagedConnection = bindExternalSelfManagedServiceAndRegister(
767                     TestUtils.TEST_SELF_MANAGED_CS_1_PHONE_ACCOUNT_1);
768             placeSelfManagedCallOnTestApp(selfManagedConnection.getInterface(),
769                     TestUtils.TEST_SELF_MANAGED_CS_1_HANDLE_1, TEST_ADDRESS_1);
770             mInCallCallbacks.resetLock();
771 
772             // 2. start an incoming SIM based call
773             placeAndVerifyCall(extras);
774             Connection simBasedConnection = verifyConnectionForOutgoingCall();
775 
776             // 3. assert incoming call is active
777             Call outgoingCall = getInCallService().getLastCall();
778             simBasedConnection.setActive();
779             assertCallState(outgoingCall, Call.STATE_ACTIVE);
780 
781             // 4. assert audio mode id MODE_IN_CALL
782             AudioManager audioManager = mContext.getSystemService(AudioManager.class);
783             assertAudioMode(audioManager, MODE_IN_CALL);
784 
785             // 5. end incoming SIM based call
786             simBasedConnection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
787             simBasedConnection.destroy();
788 
789             // 6. assert the incoming call is disconnected
790             assertCallState(getInCallService().getLastCall(), Call.STATE_DISCONNECTED);
791 
792             // 7. un-hold and assert self-managed call becomes active
793             setRemoteConnectionActiveAndVerify(selfManagedConnection);
794 
795             // 10. assert audio mode is MODE_IN_COMMUNICATION
796             assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
797 
798         } finally {
799             unregisterSimPhoneAccount();
800             if (selfManagedConnection != null) {
801                 tearDownControl(selfManagedConnection);
802             }
803         }
804     }
805 
806     /**
807      * verify TelecomManager#acceptRingingCall does not change the state of a self-managed call from
808      * ringing to active. In short, TelecomManager#acceptRingingCall should not change the state
809      * of any self-manged connection.
810      *
811      * @throws Exception; should not throw exception
812      */
813     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
814     @ApiTest(apis = {"android.telecom.TelecomManager#acceptRingingCall"})
testAcceptRingingCallOnSingleSelfManagedCall()815     public void testAcceptRingingCallOnSingleSelfManagedCall() throws Exception {
816         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
817             return;
818         }
819 
820         SelfManagedConnection selfManagedConnection = null;
821 
822         try {
823             // verify handle can receive incoming self-manged call on the handle
824             assertIsIncomingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_2);
825 
826             // start new incoming self-managed call
827             TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
828                     TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_2);
829             selfManagedConnection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_2);
830 
831             // verify the incoming self-managed call is ringing
832             TestUtils.waitOnAllHandlers(getInstrumentation());
833             assertEquals(Call.STATE_RINGING, selfManagedConnection.getState());
834 
835             // try to accept it but the expectation is Telecom will not answer the ringing call
836             mTelecomManager.acceptRingingCall();
837 
838             // assert there was no change in the ongoing call
839             TestUtils.waitOnAllHandlers(getInstrumentation());
840             assertEquals(Call.STATE_RINGING, selfManagedConnection.getState());
841         } finally {
842             if (selfManagedConnection != null) {
843                 selfManagedConnection.disconnectAndDestroy();
844             }
845         }
846     }
847 
848 
849     /**
850      * verify TelecomManager#acceptRingingCall does not change the state of an active self-managed
851      * call (by holding it) in favor of a new ringing self-managed call that comes in.  In short,
852      * TelecomManager#acceptRingingCall should not change the state of any self-manged connection.
853      *
854      * @throws Exception; should not throw exception
855      */
856     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
857     @ApiTest(apis = {"android.telecom.TelecomManager#acceptRingingCall"})
testAcceptRingingCallOnMultipleSelfManagedCalls()858     public void testAcceptRingingCallOnMultipleSelfManagedCalls() throws Exception {
859         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
860             return;
861         }
862 
863         SelfManagedConnection outgoing_SM_connection = null;
864         SelfManagedConnection incoming_SM_connection = null;
865 
866         try {
867             // verify both handles can place calls
868             assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
869             assertIsIncomingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_2);
870 
871             // create an outgoing self-managed call
872             outgoing_SM_connection = placeSelfManagedCallAndGetConnection(
873                     TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
874             assertEquals(outgoing_SM_connection.getState(), Call.STATE_ACTIVE);
875 
876             // start new incoming call
877             TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
878                     TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_2);
879             incoming_SM_connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_2);
880 
881             // verify the incoming self-managed call is ringing
882             TestUtils.waitOnAllHandlers(getInstrumentation());
883             assertEquals(Call.STATE_RINGING, incoming_SM_connection.getState());
884 
885             // try to accept it but the expectation is Telecom will not answer the ringing call
886             mTelecomManager.acceptRingingCall();
887 
888             // assert there was no change in the 2 ongoing calls
889             TestUtils.waitOnAllHandlers(getInstrumentation());
890             assertEquals(Call.STATE_RINGING, incoming_SM_connection.getState());
891             assertEquals(Call.STATE_ACTIVE, outgoing_SM_connection.getState());
892         } finally {
893             if (outgoing_SM_connection != null) {
894                 outgoing_SM_connection.disconnectAndDestroy();
895             }
896             if (incoming_SM_connection != null) {
897                 incoming_SM_connection.disconnectAndDestroy();
898             }
899         }
900     }
901 
902     /**
903      * Verify TelecomManager#endCall cannot end an active self-managed call.
904      *
905      * @throws Exception; should not throw exception
906      */
907     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
908     @ApiTest(apis = {"android.telecom.TelecomManager#endCall"})
testEndCallOnSelfManagedCallOnActiveCall()909     public void testEndCallOnSelfManagedCallOnActiveCall() throws Exception {
910         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
911             return;
912         }
913 
914         SelfManagedConnection selfManagedConnection = null;
915 
916         try {
917             // start a self-managed call
918             assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
919             selfManagedConnection =
920                     placeSelfManagedCallAndGetConnection(TEST_SELF_MANAGED_HANDLE_1,
921                             TEST_ADDRESS_1);
922 
923             // set the self-managed call active and verify
924             setActiveAndVerify(selfManagedConnection);
925 
926             // try to end it but the expectation is Telecom cannot end the self-managed call
927             assertFalse(mTelecomManager.endCall());
928             TestUtils.waitOnAllHandlers(getInstrumentation());
929             assertEquals(Call.STATE_ACTIVE, selfManagedConnection.getState());
930 
931         } finally {
932             if (selfManagedConnection != null) {
933                 // disconnect call
934                 selfManagedConnection.disconnectAndDestroy();
935             }
936         }
937     }
938 
939     /**
940      * Verify TelecomManager#endCall cannot end a ringing self-managed call.
941      *
942      * @throws Exception; should not throw exception
943      */
944     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
945     @ApiTest(apis = {"android.telecom.TelecomManager#endCall"})
testEndCallOnSelfManagedCallOnRingingCall()946     public void testEndCallOnSelfManagedCallOnRingingCall() throws Exception {
947         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
948             return;
949         }
950 
951         SelfManagedConnection selfManagedConnection = null;
952 
953         try {
954             // start a self-managed call
955             assertIsIncomingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
956             TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
957                     TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
958             selfManagedConnection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
959 
960             // verify the self-managed call is ringing
961             TestUtils.waitOnAllHandlers(getInstrumentation());
962             assertEquals(selfManagedConnection.getState(), Call.STATE_RINGING);
963 
964             // try to end it but the expectation is Telecom cannot end the self-managed call
965             assertFalse(mTelecomManager.endCall());
966 
967             // verify the self-managed call is still ringing
968             TestUtils.waitOnAllHandlers(getInstrumentation());
969             assertEquals(Call.STATE_RINGING, selfManagedConnection.getState());
970 
971         } finally {
972             if (selfManagedConnection != null) {
973                 // disconnect call
974                 selfManagedConnection.disconnectAndDestroy();
975             }
976         }
977     }
978 
979     /**
980      * Tests ability to change the audio route via the
981      * {@link android.telecom.Connection#setAudioRoute(int)} API.
982      */
983     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
984     @ApiTest(apis = {"android.telecom.Connection#setAudioRoute"})
testAudioRoute()985     public void testAudioRoute() throws Exception {
986         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
987             return;
988         }
989         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
990                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
991         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
992         setActiveAndVerify(connection);
993 
994         TestUtils.InvokeCounter counter = connection.getCallAudioStateChangedInvokeCounter();
995         counter.waitForCount(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
996         CallAudioState callAudioState = (CallAudioState) counter.getArgs(0)[0];
997         int availableRoutes = callAudioState.getSupportedRouteMask();
998 
999         // Both the speaker and either wired or earpiece are required to test changing the audio
1000         // route. Skip this test if either of these routes is unavailable.
1001         if ((availableRoutes & CallAudioState.ROUTE_SPEAKER) == 0
1002                 || (availableRoutes & CallAudioState.ROUTE_WIRED_OR_EARPIECE) == 0) {
1003             return;
1004         }
1005 
1006         // Determine what the second route after SPEAKER should be, depending on what's supported.
1007         int secondRoute = (availableRoutes & CallAudioState.ROUTE_EARPIECE) == 0
1008                 ? CallAudioState.ROUTE_WIRED_HEADSET
1009                 : CallAudioState.ROUTE_EARPIECE;
1010 
1011         counter.clearArgs();
1012         connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
1013         counter.waitForPredicate(new Predicate<CallAudioState>() {
1014                 @Override
1015                 public boolean test(CallAudioState cas) {
1016                     return cas.getRoute() == CallAudioState.ROUTE_SPEAKER;
1017                 }
1018             }, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1019 
1020         counter.clearArgs();
1021         connection.setAudioRoute(secondRoute);
1022         counter.waitForPredicate(new Predicate<CallAudioState>() {
1023             @Override
1024             public boolean test(CallAudioState cas) {
1025                 return cas.getRoute() == secondRoute;
1026             }
1027         }, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1028         if (TestUtils.HAS_BLUETOOTH) {
1029             // Call requestBluetoothAudio on a device. This will be a noop since no devices are
1030             // connected.
1031             connection.requestBluetoothAudio(TestUtils.BLUETOOTH_DEVICE1);
1032         }
1033         setDisconnectedAndVerify(connection);
1034     }
1035     /**
1036      * Tests that Telecom will allow the incoming call while the number of self-managed call is not
1037      * exceed the limit.
1038      * @throws Exception
1039      */
1040     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1041     @ApiTest(apis = {"android.telecom.Connection#addNewIncomingCall"})
testIncomingWhileOngoingWithinLimit()1042     public void testIncomingWhileOngoingWithinLimit() throws Exception {
1043         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1044             return;
1045         }
1046 
1047         // Create an ongoing call in the first self-managed PhoneAccount.
1048         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1049                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1050         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
1051         setActiveAndVerify(connection);
1052 
1053         assertIsIncomingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_2);
1054         // Attempt to create a new incoming call for the other PhoneAccount; it should succeed.
1055         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1056                 TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_2);
1057         SelfManagedConnection connection2 = TestUtils.waitForAndGetConnection(TEST_ADDRESS_2);
1058 
1059         connection2.disconnectAndDestroy();
1060         setDisconnectedAndVerify(connection);
1061     }
1062 
1063     /**
1064      * Tests the self-managed ConnectionService has gained the focus when it become active.
1065      */
1066     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1067     @ApiTest(apis = {"android.telecom.ConnectionService#onConnectionServiceFocusLost",
1068             "android.telecom.ConnectionService#onConnectionServiceFocusGained"})
testSelfManagedConnectionServiceGainedFocus()1069     public void testSelfManagedConnectionServiceGainedFocus() throws Exception {
1070         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1071             return;
1072         }
1073 
1074         assertIsIncomingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
1075         // Attempt to create a new Incoming self-managed call
1076         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1077                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1078         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
1079 
1080         setActiveAndVerify(connection);
1081 
1082         // The ConnectionService has gained the focus
1083         assertTrue(CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1084                 CtsSelfManagedConnectionService.FOCUS_GAINED_LOCK));
1085 
1086         setDisconnectedAndVerify(connection);
1087     }
1088 
1089     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1090     @ApiTest(apis = {"android.telecom.ConnectionService#onConnectionServiceFocusLost",
1091             "android.telecom.ConnectionService#onConnectionServiceFocusGained"})
testSelfManagedConnectionServiceLostFocus()1092     public void testSelfManagedConnectionServiceLostFocus() throws Exception {
1093         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1094             return;
1095         }
1096 
1097         // GIVEN an ongoing self-managed call
1098         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1099                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1100         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
1101         setActiveAndVerify(connection);
1102         assertTrue(CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1103                 CtsSelfManagedConnectionService.FOCUS_GAINED_LOCK));
1104 
1105         // WHEN place a managed call
1106         mInCallCallbacks.resetLock();
1107         placeAndVerifyCall();
1108         verifyConnectionForOutgoingCall().setActive();
1109         assertTrue(connectionService.waitForEvent(
1110                 MockConnectionService.EVENT_CONNECTION_SERVICE_FOCUS_GAINED));
1111 
1112         // THEN the self-managed ConnectionService lost the focus
1113 
1114         connection.disconnectAndDestroy();
1115         assertTrue(CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1116                 CtsSelfManagedConnectionService.FOCUS_LOST_LOCK));
1117     }
1118 
1119     /**
1120      * Tests that Telecom will disallow the incoming call while the ringing call is existed.
1121      */
1122     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1123     @ApiTest(apis = {"android.telecom.TelecomManager#addNewIncomingCall"})
testRingCallLimitForOnePhoneAccount()1124     public void testRingCallLimitForOnePhoneAccount() {
1125         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1126             return;
1127         }
1128 
1129         // GIVEN a self-managed call which state is ringing
1130         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1131                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1132 
1133         assertIsIncomingCallPermitted(false, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
1134         // WHEN create a new incoming call for the the same PhoneAccount
1135         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1136                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1137 
1138         // THEN the new incoming call is denied
1139         assertTrue(CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1140                 CtsSelfManagedConnectionService.CREATE_INCOMING_CONNECTION_FAILED_LOCK));
1141     }
1142 
1143     /**
1144      * Tests that Telecom enforces a maximum number of calls for a self-managed ConnectionService.
1145      *
1146      * @throws Exception
1147      */
1148     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1149     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testCallLimit()1150     public void testCallLimit() throws Exception {
1151         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1152             return;
1153         }
1154 
1155         List<SelfManagedConnection> connections = new ArrayList<>();
1156         // Create 10 calls; they should succeed.
1157         for (int ix = 0; ix < 10; ix++) {
1158             Uri address = Uri.fromParts("sip", "test" + ix + "@test.com", null);
1159             // Create an ongoing call in the first self-managed PhoneAccount.
1160             assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
1161             TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1162                     TestUtils.TEST_SELF_MANAGED_HANDLE_1, address);
1163             SelfManagedConnection connection = TestUtils.waitForAndGetConnection(address);
1164             setActiveAndVerify(connection);
1165             connections.add(connection);
1166         }
1167 
1168         // Try adding an 11th.  It should fail to be created.
1169         assertIsIncomingCallPermitted(false, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
1170         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1171                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_2);
1172         assertTrue("Expected onCreateIncomingConnectionFailed callback",
1173                 CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1174                         CtsSelfManagedConnectionService.CREATE_INCOMING_CONNECTION_FAILED_LOCK));
1175 
1176         connections.forEach((selfManagedConnection) ->
1177                 selfManagedConnection.disconnectAndDestroy());
1178 
1179         waitOnAllHandlers(getInstrumentation());
1180     }
1181 
1182     /**
1183      * Start a self-managed call and then dial an emergency call and make sure the self-managed
1184      * call is successfully disconnected.
1185      */
1186     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1187     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testDisconnectSelfManagedCallForEmergency()1188     public void testDisconnectSelfManagedCallForEmergency() throws Exception {
1189         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1190             return;
1191         }
1192         setupForEmergencyCalling(TEST_EMERGENCY_NUMBER);
1193 
1194         Uri address = getTestNumber();
1195         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1196                 TEST_SELF_MANAGED_HANDLE_1, address);
1197         // Ensure Telecom bound to the self managed CS
1198         if (!CtsSelfManagedConnectionService.waitForBinding()) {
1199             fail("Could not bind to Self-Managed ConnectionService");
1200         }
1201         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(address);
1202         assertNotNull("Self-Managed Connection should NOT be null.", connection);
1203         assertTrue("Self-Managed Connection should be outgoing.", !connection.isIncomingCall());
1204         // The self-managed ConnectionService must NOT have been prompted to show its incoming call
1205         // UI for an outgoing call.
1206         assertEquals(connection.getOnShowIncomingUiInvokeCounter().getInvokeCount(), 0);
1207         setActiveAndVerify(connection);
1208 
1209         mInCallCallbacks.resetLock();
1210         placeAndVerifyEmergencyCall(true /*supportsHold*/);
1211         Call eCall = getInCallService().getLastCall();
1212 
1213         assertIsInCall(true);
1214         assertIsInManagedCall(true);
1215         try {
1216             TestUtils.waitOnAllHandlers(getInstrumentation());
1217         } catch (Exception e) {
1218             fail("Failed to wait on handlers " + e);
1219         }
1220         assertCallState(eCall, Call.STATE_DIALING);
1221         // The self-managed Connection should be disconnected!
1222         assertConnectionState(connection, Connection.STATE_DISCONNECTED);
1223     }
1224 
1225     /**
1226      * Start a managed emergency call and then ensure that a subsequent self-managed call fails to
1227      * be created.
1228      */
1229     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
testEmergencyCallOngoingNewOutgoingCall()1230     public void testEmergencyCallOngoingNewOutgoingCall() throws Exception {
1231         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1232             return;
1233         }
1234 
1235         setupForEmergencyCalling(TEST_EMERGENCY_NUMBER);
1236         placeAndVerifyEmergencyCall(true /*supportsHold*/);
1237         assertIsInCall(true);
1238         assertIsInManagedCall(true);
1239         try {
1240             TestUtils.waitOnAllHandlers(getInstrumentation());
1241         } catch (Exception e) {
1242             fail("Failed to wait on handlers " + e);
1243         }
1244 
1245         // Try adding a self managed outgoing call.  It should fail to be created.
1246         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1247                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1248         assertTrue("Expected onCreateOutgoingConnectionFailed callback",
1249                 CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1250                         CtsSelfManagedConnectionService.CREATE_OUTGOING_CONNECTION_FAILED_LOCK));
1251     }
1252 
1253     /**
1254      * Start a managed emergency call and then ensure that a subsequent self-managed call fails to
1255      * be created.
1256      */
1257     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
testEmergencyCallOngoingIncomingCall()1258     public void testEmergencyCallOngoingIncomingCall() throws Exception {
1259         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1260             return;
1261         }
1262 
1263         setupForEmergencyCalling(TEST_EMERGENCY_NUMBER);
1264         placeAndVerifyEmergencyCall(true /*supportsHold*/);
1265         assertIsInCall(true);
1266         assertIsInManagedCall(true);
1267         try {
1268             TestUtils.waitOnAllHandlers(getInstrumentation());
1269         } catch (Exception e) {
1270             fail("Failed to wait on handlers " + e);
1271         }
1272 
1273         // Try adding a self managed incoming call.  It should fail to be created.
1274         TestUtils.addIncomingCall(getInstrumentation(), mTelecomManager,
1275                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1276         assertTrue("Expected onCreateIncomingConnectionFailed callback",
1277                 CtsSelfManagedConnectionService.getConnectionService().waitForUpdate(
1278                         CtsSelfManagedConnectionService.CREATE_INCOMING_CONNECTION_FAILED_LOCK));
1279     }
1280 
1281     /**
1282      * Place a new outgoing call using a self-managed PhoneAccount that is not registered to
1283      * Telecom. Even if the app has CALL_PHONE/MANAGE_OWN_CALLS, the call will be sent as if there
1284      * was no PhoneAccount specified, since only the owner of a self-managed ConnectionService can
1285      * initiate a call to that Service.
1286      */
1287     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1288     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testPlaceCallToNonRegisteredSelfManagedConnectionService()1289     public void testPlaceCallToNonRegisteredSelfManagedConnectionService() throws Exception {
1290         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1291             return;
1292         }
1293 
1294         // Place a new outgoing call request for a self-managed ConnectionService that is not
1295         // registered.
1296         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1297                 TestUtils.TEST_SELF_MANAGED_CS_1_HANDLE_1, TEST_ADDRESS_2);
1298         // verify the default CTS ConnectionService received an incoming connection request because
1299         // we have CALL_PHONE permission.
1300         verifyConnectionForOutgoingCall();
1301     }
1302 
1303     /**
1304      * Place a new outgoing call request to a registered self-managed ConnectionService that
1305      * is owned by a different application.
1306      * Even if the app has CALL_PHONE/MANAGE_OWN_CALLS, the call will be sent as if there
1307      * was no PhoneAccount specified.
1308      */
1309     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1310     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testPlaceCallToRegisteredSelfManagedConnectionService()1311     public void testPlaceCallToRegisteredSelfManagedConnectionService() throws Exception {
1312         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1313             return;
1314         }
1315         TestServiceConnection conn = null;
1316         try {
1317             conn = bindExternalSelfManagedServiceAndRegister(
1318                     TestUtils.TEST_SELF_MANAGED_CS_1_PHONE_ACCOUNT_1);
1319 
1320             // Try to place a call from this CTS app to the self-managed CS. We should not see any
1321             // call to the self-managed CS. Instead, it will go over the default CTS ConnectionService
1322             // because we have CALL_PHONE permission.
1323             TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1324                     TestUtils.TEST_SELF_MANAGED_CS_1_HANDLE_1, TEST_ADDRESS_2);
1325             // verify the CTS default ConnectionService received an incoming connection request.
1326             verifyConnectionForOutgoingCall();
1327         } finally {
1328             if (conn != null) tearDownControl(conn);
1329         }
1330     }
1331 
1332     /**
1333      * Try to start a self-managed call on a ConnectionService that does not have the CALL_PHONE
1334      * permission, only MANAGE_OWN_CALLS. If this happens, the call should fail with a
1335      * SecurityException.
1336      */
1337     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1338     @ApiTest(apis = {"android.telecom.TelecomManager#placeCall"})
testPlaceIncorrectSelfManagedCallFromRemote()1339     public void testPlaceIncorrectSelfManagedCallFromRemote() throws Exception {
1340         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1341             return;
1342         }
1343         TestServiceConnection conn = null;
1344         try {
1345             conn = bindExternalSelfManagedServiceAndRegister(
1346                     TestUtils.TEST_SELF_MANAGED_CS_1_PHONE_ACCOUNT_1);
1347 
1348             // Try to start a self-managed call using this Self-Managed ConnectionService's
1349             // PhoneAccount from the remote, which should fail with a SecurityException because the
1350             // remote does not have the CALL_PHONE permission.
1351             try {
1352                 boolean result = conn.getInterface().placeOutgoingCall(
1353                         TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_2.toString());
1354                 fail("A ConnectionService must not be able to place a self-managed call that "
1355                         + "belongs to another ConnectionService. A SecurityException was expected, "
1356                         + "result: " + result);
1357             } catch (SecurityException e) {
1358                 //expected
1359             }
1360         } finally {
1361             if (conn != null) tearDownControl(conn);
1362         }
1363     }
1364 
1365     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
testCallSwapBetweenTwoSelfManagedConnectionServices()1366     public void testCallSwapBetweenTwoSelfManagedConnectionServices() throws Exception {
1367         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1368             return;
1369         }
1370 
1371         TestServiceConnection conn = bindExternalSelfManagedServiceAndRegister(
1372                 TestUtils.TEST_SELF_MANAGED_CS_1_PHONE_ACCOUNT_1);
1373 
1374         //Place self-managed CS first call from test app
1375         placeSelfManagedCallOnTestApp(conn.getInterface(),
1376                 TestUtils.TEST_SELF_MANAGED_CS_1_HANDLE_1, TEST_ADDRESS_1);
1377 
1378         //Get test app call from inCallService
1379         final MockInCallService inCallService = mInCallCallbacks.getService();
1380         final Call call1 = inCallService.getLastCall();
1381 
1382         // Ensure that the connection defaulted to voip audio mode.
1383         assertTrue(conn.getInterface().getAudioModeIsVoip());
1384         // Ensure AudioManager has correct voip mode.
1385         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
1386         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1387 
1388         //Place self-managed CS second call
1389         SelfManagedConnection connection =
1390                 placeSelfManagedCallAndGetConnection(TestUtils.TEST_SELF_MANAGED_HANDLE_4,
1391                     TEST_ADDRESS_2);
1392 
1393         final Call call2 = inCallService.getLastCall();
1394 
1395         //first call on hold after second call is active
1396         assertCallState(call1, Call.STATE_HOLDING);
1397         assertEquals(conn.getInterface().getConnectionState(), Connection.STATE_HOLDING);
1398         assertCallState(call2, Call.STATE_ACTIVE);
1399         assertConnectionState(connection, Connection.STATE_ACTIVE);
1400 
1401         // Ensure that the connection defaulted to voip audio mode.
1402         assertTrue(connection.getAudioModeIsVoip());
1403         assertTrue(conn.getInterface().getAudioModeIsVoip());
1404         // Ensure AudioManager has correct voip mode.
1405         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1406 
1407         //unhold the first call should keep the second call on hold
1408         call1.unhold();
1409         assertTrue(conn.getInterface().waitOnUnHold());
1410         assertTrue(connection.waitOnHold());
1411         assertCallState(call2, Call.STATE_HOLDING);
1412         assertConnectionState(connection, Connection.STATE_HOLDING);
1413         assertCallState(call1, Call.STATE_ACTIVE);
1414         assertEquals(conn.getInterface().getConnectionState(), Connection.STATE_ACTIVE);
1415 
1416         // Ensure that the connection defaulted to voip audio mode.
1417         assertTrue(connection.getAudioModeIsVoip());
1418         assertTrue(conn.getInterface().getAudioModeIsVoip());
1419         // Ensure AudioManager has correct voip mode.
1420         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1421 
1422         //unhold the first call should keep the second call on hold
1423         call2.unhold();
1424         assertTrue(conn.getInterface().waitOnHold());
1425         assertTrue(connection.waitOnUnHold());
1426         assertCallState(call1, Call.STATE_HOLDING);
1427         assertEquals(conn.getInterface().getConnectionState(), Connection.STATE_HOLDING);
1428         assertCallState(call2, Call.STATE_ACTIVE);
1429         assertConnectionState(connection, Connection.STATE_ACTIVE);
1430 
1431         // Ensure that the connection defaulted to voip audio mode.
1432         assertTrue(connection.getAudioModeIsVoip());
1433         assertTrue(conn.getInterface().getAudioModeIsVoip());
1434         // Ensure AudioManager has correct voip mode.
1435         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1436 
1437         // disconnect active 2nd call
1438         connection.disconnectAndDestroy();
1439 
1440         assertIsInCall(true);
1441         assertIsInManagedCall(false);
1442 
1443         //first call should be on hold
1444         assertCallState(call1, Call.STATE_HOLDING);
1445         assertEquals(conn.getInterface().getConnectionState(), Connection.STATE_HOLDING);
1446 
1447         // Ensure that the connection defaulted to voip audio mode.
1448         assertTrue(conn.getInterface().getAudioModeIsVoip());
1449         // Ensure AudioManager has correct voip mode.
1450         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1451 
1452         //unhold first call
1453         call1.unhold();
1454         assertCallState(call1, Call.STATE_ACTIVE);
1455         assertEquals(conn.getInterface().getConnectionState(), Connection.STATE_ACTIVE);
1456 
1457         // Ensure that the connection defaulted to voip audio mode.
1458         assertTrue(conn.getInterface().getAudioModeIsVoip());
1459         // Ensure AudioManager has correct voip mode.
1460         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1461 
1462         conn.getInterface().disconnectConnection();
1463 
1464         assertCallState(call1, Call.STATE_DISCONNECTED);
1465 
1466         tearDownControl(conn);
1467 
1468         assertIsInCall(false);
1469         assertIsInManagedCall(false);
1470     }
1471 
1472     /**
1473      * Start a self-managed no hold capable call on different app and accept incoming managed call
1474      * should disconnect self-managed call
1475      */
1476     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
testManagedCallWhileNoHoldCapabilitySelfMaganedCallActive()1477     public void testManagedCallWhileNoHoldCapabilitySelfMaganedCallActive() throws Exception {
1478         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1479             return;
1480         }
1481 
1482         // register a self-managed phone account from self-managed CS test app
1483         TestServiceConnection conn = bindExternalSelfManagedServiceAndRegister(
1484                 TestUtils.TEST_SELF_MANAGED_CS_1_PHONE_ACCOUNT_3);
1485 
1486         // place a self-managed call
1487         conn.getInterface().initiateIncomingCall(
1488                 TestUtils.TEST_SELF_MANAGED_CS_1_HANDLE_3, TEST_ADDRESS_2.toString());
1489 
1490         // Wait for Telecom to finish creating the new connection.
1491         try {
1492             TestUtils.waitOnAllHandlers(getInstrumentation());
1493         } catch (Exception e) {
1494             fail("Failed to wait on handlers");
1495         }
1496 
1497         assertTrue(conn.getInterface().waitForBinding());
1498 
1499         conn.getInterface().setConnectionCapabilityNoHold();
1500 
1501         conn.getInterface().setConnectionActive();
1502 
1503         assertEquals(Connection.STATE_ACTIVE, conn.getInterface().getConnectionState());
1504 
1505         // add new managed call
1506         addAndVerifyNewIncomingCall(createTestNumber(), null);
1507         Connection connection = verifyConnectionForIncomingCall();
1508 
1509         assertConnectionState(connection, Connection.STATE_RINGING);
1510         assertEquals(Connection.STATE_ACTIVE, conn.getInterface().getConnectionState());
1511 
1512         // answer the incoming call
1513         MockInCallService inCallService = mInCallCallbacks.getService();
1514         Call call = inCallService.getLastCall();
1515 
1516         call.answer(VideoProfile.STATE_AUDIO_ONLY);
1517 
1518         assertConnectionState(connection, Connection.STATE_ACTIVE);
1519 
1520         assertTrue(conn.getInterface().waitOnDisconnect());
1521         assertEquals(Connection.STATE_DISCONNECTED, conn.getInterface().getConnectionState());
1522 
1523         tearDownControl(conn);
1524 
1525         call.disconnect();
1526     }
1527 
1528     /**
1529      * Tests ability to change the call endpoint via the
1530      * {@link android.telecom.Connection#requestCallEndpointChange} API.
1531      */
1532     @CddTest(requirements = "7.4.1.2/C-12-1,7.4.1.2/C-12-2")
1533     @ApiTest(apis = {"android.telecom.Connection#requestCallEndpointChange"})
testCallEndpoint()1534     public void testCallEndpoint() throws Exception {
1535         if (!mShouldTestTelecom || !TestUtils.hasTelephonyFeature(mContext)) {
1536             return;
1537         }
1538         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager,
1539                 TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
1540         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(TEST_ADDRESS_1);
1541         setActiveAndVerify(connection);
1542 
1543         TestUtils.InvokeCounter currentEndpointCounter =
1544                 connection.getCallEndpointChangedInvokeCounter();
1545         currentEndpointCounter.waitForCount(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1546         CallEndpoint currentEndpoint = (CallEndpoint) currentEndpointCounter.getArgs(0)[0];
1547         int currentEndpointType = currentEndpoint.getEndpointType();
1548 
1549         TestUtils.InvokeCounter availableEndpointsCounter =
1550                 connection.getAvailableEndpointsChangedInvokeCounter();
1551         availableEndpointsCounter.waitForCount(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1552         List<CallEndpoint> availableEndpoints =
1553                 (List<CallEndpoint>) availableEndpointsCounter.getArgs(0)[0];
1554 
1555         CallEndpoint anotherEndpoint = null;
1556         for (CallEndpoint endpoint : availableEndpoints) {
1557             if (endpoint.getEndpointType() != currentEndpointType) {
1558                 anotherEndpoint = endpoint;
1559                 break;
1560             }
1561         }
1562         if (anotherEndpoint != null) {
1563             Executor executor = mContext.getMainExecutor();
1564             final int anotherEndpointType = anotherEndpoint.getEndpointType();
1565             currentEndpointCounter.clearArgs();
1566             connection.requestCallEndpointChange(anotherEndpoint, executor,
1567                     new OutcomeReceiver<>() {
1568                         @Override
1569                         public void onResult(Void result) {}
1570                         @Override
1571                         public void onError(CallEndpointException exception) {}
1572                     });
1573             currentEndpointCounter.waitForPredicate(new Predicate<CallEndpoint>() {
1574                 @Override
1575                 public boolean test(CallEndpoint cep) {
1576                     return cep.getEndpointType() == anotherEndpointType;
1577                 }
1578             }, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1579 
1580             // wait for the CallAudioManager to process the CallAudioRoute update
1581             waitOnAllHandlers(getInstrumentation());
1582 
1583             currentEndpointCounter.clearArgs();
1584             connection.requestCallEndpointChange(currentEndpoint, executor,
1585                     new OutcomeReceiver<>() {
1586                         @Override
1587                         public void onResult(Void result) {}
1588                         @Override
1589                         public void onError(CallEndpointException exception) {}
1590                     });
1591             currentEndpointCounter.waitForPredicate(new Predicate<CallEndpoint>() {
1592                 @Override
1593                 public boolean test(CallEndpoint cep) {
1594                     return cep.getEndpointType() == currentEndpointType;
1595                 }
1596             }, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
1597 
1598         }
1599         setDisconnectedAndVerify(connection);
1600     }
1601 
registerSimAccountIfNeeded()1602     private void registerSimAccountIfNeeded() {
1603         if (mTelecomManager.getPhoneAccount(TestUtils.TEST_SIM_PHONE_ACCOUNT.getAccountHandle())
1604                 == null) {
1605             runWithShellPermissionIdentity(() -> {
1606                 mTelecomManager.registerPhoneAccount(TestUtils.TEST_SIM_PHONE_ACCOUNT);
1607             });
1608         }
1609     }
1610 
unregisterSimPhoneAccount()1611     private void unregisterSimPhoneAccount() {
1612         runWithShellPermissionIdentity(() -> {
1613             mTelecomManager.unregisterPhoneAccount(
1614                     TestUtils.TEST_SIM_PHONE_ACCOUNT.getAccountHandle());
1615         });
1616     }
1617 
setRemoteConnectionActiveAndVerify(TestServiceConnection conn)1618     private void setRemoteConnectionActiveAndVerify(TestServiceConnection conn) throws Exception {
1619         // Set the connection active.
1620         conn.getInterface().setConnectionActive();
1621 
1622         // Check with Telecom if we're in a call.
1623         assertIsInCall(true);
1624         assertIsInManagedCall(false);
1625     }
1626 
1627     /**
1628      * Sets a connection active, and verifies TelecomManager thinks we're in call but not in a
1629      * managed call.
1630      * @param connection The connection.
1631      */
setActiveAndVerify(SelfManagedConnection connection)1632     private void setActiveAndVerify(SelfManagedConnection connection) throws Exception {
1633         // Set the connection active.
1634         connection.setActive();
1635 
1636         // Check with Telecom if we're in a call.
1637         assertIsInCall(true);
1638         assertIsInManagedCall(false);
1639     }
1640 
1641     /**
1642      * Sets a connection to be disconnected, and then waits until the TelecomManager reports it is
1643      * no longer in a call.
1644      * @param connection The connection to disconnect/destroy.
1645      */
setDisconnectedAndVerify(SelfManagedConnection connection)1646     private void setDisconnectedAndVerify(SelfManagedConnection connection) {
1647         // Now, disconnect call and clean it up.
1648         connection.disconnectAndDestroy();
1649 
1650         assertIsInCall(false);
1651         assertIsInManagedCall(false);
1652     }
1653 
1654     /**
1655      * helper method that creates and returns a self-managed connection with a given handle
1656      * and address.  Additionally, some checks are made to ensure the self-managed connection was
1657      * successful.
1658      */
placeSelfManagedCallAndGetConnection(PhoneAccountHandle handle, Uri address)1659     private SelfManagedConnection placeSelfManagedCallAndGetConnection(PhoneAccountHandle handle,
1660             Uri address) throws Exception {
1661         // place a self-managed call
1662         assertIsOutgoingCallPermitted(true, TestUtils.TEST_SELF_MANAGED_HANDLE_1);
1663 
1664         TestUtils.placeOutgoingCall(getInstrumentation(), mTelecomManager, handle, address);
1665 
1666         // Ensure Telecom bound to the self managed CS
1667         if (!CtsSelfManagedConnectionService.waitForBinding()) {
1668             fail("Could not bind to Self-Managed ConnectionService");
1669         }
1670 
1671         SelfManagedConnection connection = TestUtils.waitForAndGetConnection(address);
1672 
1673         assertNotNull("Self-Managed Connection should NOT be null.", connection);
1674         assertTrue("Self-Managed Connection should be outgoing.", !connection.isIncomingCall());
1675 
1676         // The self-managed ConnectionService must NOT have been prompted to show its incoming call
1677         // UI for an outgoing call.
1678         assertEquals(connection.getOnShowIncomingUiInvokeCounter().getInvokeCount(), 0);
1679 
1680         setActiveAndVerify(connection);
1681 
1682         // Ensure that the connection defaulted to voip audio mode.
1683         assertTrue(connection.getAudioModeIsVoip());
1684         // Ensure AudioManager has correct voip mode.
1685         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
1686         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1687 
1688         // Expect there to be no managed calls at the moment.
1689         assertFalse(mTelecomManager.isInManagedCall());
1690         // But there should be a call (including self-managed).
1691         assertTrue(mTelecomManager.isInCall());
1692 
1693         // Expect that the new outgoing call broadcast did not fire for the self-managed calls.
1694         assertFalse(NewOutgoingCallBroadcastReceiver.isNewOutgoingCallBroadcastReceived());
1695 
1696         return connection;
1697     }
1698 
1699     /**
1700      * helper method that creates and returns a self-managed connection with a given handle
1701      * and address.  Additionally, some checks are made to ensure the self-managed connection was
1702      * successful.
1703      */
placeSelfManagedCallOnTestApp( ICtsSelfManagedConnectionServiceControl serviceControl, PhoneAccountHandle handle, Uri address)1704     private void placeSelfManagedCallOnTestApp(
1705             ICtsSelfManagedConnectionServiceControl serviceControl,
1706             PhoneAccountHandle handle, Uri address) throws Exception {
1707         // place a self-managed call
1708         assertTrue(serviceControl.placeOutgoingCall(handle, address.toString()));
1709 
1710         // Wait for Telecom to finish creating the new connection.
1711         try {
1712             TestUtils.waitOnAllHandlers(getInstrumentation());
1713         } catch (Exception e) {
1714             fail("Failed to wait on handlers");
1715         }
1716 
1717         // Ensure Telecom bound to the self managed CS
1718         if (!serviceControl.waitForBinding()) {
1719             fail("Could not bind to Self-Managed ConnectionService");
1720         }
1721 
1722         if (!serviceControl.isConnectionAvailable()) {
1723             fail("Connection not available for Self-Managed ConnectionService");
1724         }
1725 
1726         serviceControl.setConnectionActive();
1727 
1728         assertTrue("Self-Managed Connection should be outgoing.", !serviceControl.isIncomingCall());
1729 
1730         // The self-managed ConnectionService must NOT have been prompted to show its incoming call
1731         // UI for an outgoing call.
1732         assertEquals(serviceControl.getOnShowIncomingUiInvokeCounter(), 0);
1733 
1734         // Ensure that the connection defaulted to voip audio mode.
1735         assertTrue(serviceControl.getAudioModeIsVoip());
1736         // Ensure AudioManager has correct voip mode.
1737         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
1738         assertAudioMode(audioManager, MODE_IN_COMMUNICATION);
1739 
1740         // Expect there to be no managed calls at the moment.
1741         assertFalse(mTelecomManager.isInManagedCall());
1742         // But there should be a call (including self-managed).
1743         assertTrue(mTelecomManager.isInCall());
1744 
1745         // Expect that the new outgoing call broadcast did not fire for the self-managed calls.
1746         assertFalse(NewOutgoingCallBroadcastReceiver.isNewOutgoingCallBroadcastReceived());
1747     }
1748 }
1749