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