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