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