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