1 /* 2 * Copyright (C) 2020 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.telephony.ims.cts; 18 19 import static junit.framework.Assert.assertNotNull; 20 import static junit.framework.Assert.assertTrue; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNull; 25 import static org.junit.Assert.fail; 26 27 import static java.nio.charset.StandardCharsets.UTF_8; 28 29 import android.content.BroadcastReceiver; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.net.InetAddresses; 34 import android.net.Uri; 35 import android.os.Parcel; 36 import android.os.PersistableBundle; 37 import android.telephony.CarrierConfigManager; 38 import android.telephony.SubscriptionManager; 39 import android.telephony.TelephonyManager; 40 import android.telephony.cts.util.TelephonyUtils; 41 import android.telephony.ims.DelegateRegistrationState; 42 import android.telephony.ims.DelegateRequest; 43 import android.telephony.ims.FeatureTagState; 44 import android.telephony.ims.ImsException; 45 import android.telephony.ims.ImsManager; 46 import android.telephony.ims.ImsService; 47 import android.telephony.ims.ImsStateCallback; 48 import android.telephony.ims.SipDelegateConfiguration; 49 import android.telephony.ims.SipDelegateManager; 50 import android.telephony.ims.SipDialogState; 51 import android.telephony.ims.SipDialogStateCallback; 52 import android.telephony.ims.SipMessage; 53 import android.telephony.ims.feature.ImsFeature; 54 import android.telephony.ims.stub.ImsFeatureConfiguration; 55 import android.util.ArraySet; 56 57 import androidx.test.ext.junit.runners.AndroidJUnit4; 58 import androidx.test.platform.app.InstrumentationRegistry; 59 60 import com.android.compatibility.common.util.ShellIdentityUtils; 61 62 import org.junit.After; 63 import org.junit.AfterClass; 64 import org.junit.Before; 65 import org.junit.BeforeClass; 66 import org.junit.Ignore; 67 import org.junit.Test; 68 import org.junit.runner.RunWith; 69 70 import java.net.InetSocketAddress; 71 import java.util.Arrays; 72 import java.util.Collections; 73 import java.util.List; 74 import java.util.Set; 75 import java.util.concurrent.Callable; 76 import java.util.concurrent.CountDownLatch; 77 import java.util.concurrent.TimeUnit; 78 import java.util.stream.Collectors; 79 80 /** 81 * CTS tests for {@link SipDelegateManager} API. 82 */ 83 @RunWith(AndroidJUnit4.class) 84 public class SipDelegateManagerTest { 85 private static final String MMTEL_TAG = 86 "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\""; 87 private static final String ONE_TO_ONE_CHAT_TAG = 88 "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.msg\""; 89 private static final String GROUP_CHAT_TAG = 90 "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.session\""; 91 private static final String FILE_TRANSFER_HTTP_TAG = 92 "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.fthttp\""; 93 private static final String CHATBOT_COMMUNICATION_USING_SESSION_TAG = 94 "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.chatbot\""; 95 private static final String[] DEFAULT_FEATURE_TAGS = { 96 ONE_TO_ONE_CHAT_TAG, GROUP_CHAT_TAG, FILE_TRANSFER_HTTP_TAG, 97 CHATBOT_COMMUNICATION_USING_SESSION_TAG}; 98 99 private static class CarrierConfigReceiver extends BroadcastReceiver { 100 private CountDownLatch mLatch = new CountDownLatch(1); 101 private final int mSubId; 102 CarrierConfigReceiver(int subId)103 CarrierConfigReceiver(int subId) { 104 mSubId = subId; 105 } 106 107 @Override onReceive(Context context, Intent intent)108 public void onReceive(Context context, Intent intent) { 109 if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) { 110 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1); 111 if (mSubId == subId) { 112 mLatch.countDown(); 113 } 114 } 115 } 116 clearQueue()117 void clearQueue() { 118 mLatch = new CountDownLatch(1); 119 } 120 waitForCarrierConfigChanged()121 void waitForCarrierConfigChanged() throws Exception { 122 mLatch.await(5000, TimeUnit.MILLISECONDS); 123 } 124 } 125 126 /** 127 * Encapsulates the interfaces created during SipDelegateManager testing. 128 */ 129 public class TransportInterfaces { 130 public final DelegateRequest request; 131 public final Set<FeatureTagState> deniedTags; 132 public final SipDelegateManager manager; 133 public TestSipTransport transport; 134 public TestImsRegistration reg; 135 public TestSipDelegate delegate; 136 public TestSipDelegateConnection delegateConn; 137 private final int mDelegateIndex; 138 TransportInterfaces(DelegateRequest request, Set<FeatureTagState> deniedTags, int delegateIndex)139 public TransportInterfaces(DelegateRequest request, Set<FeatureTagState> deniedTags, 140 int delegateIndex) { 141 this.request = request; 142 this.deniedTags = deniedTags; 143 manager = getSipDelegateManager(); 144 mDelegateIndex = delegateIndex; 145 } 146 connect()147 public void connect() throws Exception { 148 assertTrue(sServiceConnector.setDefaultSmsApp()); 149 connectTestImsServiceWithSipTransportAndConfig(); 150 151 transport = sServiceConnector.getCarrierService().getSipTransport(); 152 reg = sServiceConnector.getCarrierService().getImsRegistration(); 153 delegateConn = new TestSipDelegateConnection(request); 154 155 delegate = createSipDelegateConnectionAndVerify(manager, delegateConn, 156 transport, deniedTags, mDelegateIndex); 157 assertNotNull(delegate); 158 // ensure we got a callback for initial reg state. 159 verifyUpdateRegistrationCalled(reg); 160 161 InetSocketAddress localAddr = new InetSocketAddress( 162 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 163 InetSocketAddress serverAddr = new InetSocketAddress( 164 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 165 SipDelegateConfiguration c = new SipDelegateConfiguration.Builder(1, 166 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr).build(); 167 // send first SIP config and verify 168 verifyRegisteredAndSendSipConfig(delegateConn, delegate, request.getFeatureTags(), 169 deniedTags, c); 170 } 171 172 /** 173 * Create a connection between fake app interface and fake ImsService impl and set up the 174 * framework to accept incoming/outgoing messages. Once done, verify the transport is open. 175 */ connectAndVerify()176 public void connectAndVerify() throws Exception { 177 connect(); 178 179 // Verify message transport is open. 180 verifyOutgoingTransport(delegateConn, delegate); 181 verifyIncomingTransport(delegateConn, delegate); 182 } 183 } 184 185 private static int sTestSlot = 0; 186 private static int sTestSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 187 private static ImsServiceConnector sServiceConnector; 188 private static CarrierConfigReceiver sReceiver; 189 private static int sUpdatedStateSize = 0; 190 private static boolean sUpdatedState = false; 191 192 @BeforeClass beforeAllTests()193 public static void beforeAllTests() throws Exception { 194 // First, only populate test slot/sub 195 if (!ImsUtils.shouldTestTelephony()) { 196 return; 197 } 198 199 TelephonyManager tm = (TelephonyManager) getContext() 200 .getSystemService(Context.TELEPHONY_SERVICE); 201 sTestSub = ImsUtils.getPreferredActiveSubId(); 202 sTestSlot = SubscriptionManager.getSlotIndex(sTestSub); 203 if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) { 204 return; 205 } 206 // Next, only start tests that require ImsResolver to bind to test ImsService if 207 // feature FEATURE_TELEPHONY_IMS is supported on this device. 208 if (!ImsUtils.shouldTestImsService()) { 209 return; 210 } 211 sServiceConnector = new ImsServiceConnector(InstrumentationRegistry.getInstrumentation()); 212 // Remove all live ImsServices until after these tests are done 213 sServiceConnector.clearAllActiveImsServices(sTestSlot); 214 215 sReceiver = new CarrierConfigReceiver(sTestSub); 216 IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 217 // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away. 218 InstrumentationRegistry.getInstrumentation().getContext() 219 .registerReceiver(sReceiver, filter); 220 221 if (!ImsUtils.shouldTestImsSingleRegistration()) { 222 // override FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION setting for this test to enable 223 // APIs. 224 sServiceConnector.setDeviceSingleRegistrationEnabled(true); 225 } 226 227 setFeatureTagsCarrierAllowed(DEFAULT_FEATURE_TAGS); 228 } 229 230 @AfterClass afterAllTests()231 public static void afterAllTests() throws Exception { 232 // Only clean up ImsResolver overrides if feature FEATURE_TELEPHONY_IMS is supported. 233 if (!ImsUtils.shouldTestImsService()) { 234 return; 235 } 236 237 // Restore all ImsService configurations that existed before the test. 238 if (sServiceConnector != null) { 239 sServiceConnector.disconnectServices(); 240 } 241 sServiceConnector = null; 242 243 // Ensure there are no CarrierConfig overrides as well as reset the ImsResolver in case the 244 // ImsService override changed in CarrierConfig while we were overriding it. 245 overrideCarrierConfig(null); 246 247 if (sReceiver != null) { 248 InstrumentationRegistry.getInstrumentation().getContext().unregisterReceiver(sReceiver); 249 sReceiver = null; 250 } 251 } 252 253 @Before beforeTest()254 public void beforeTest() { 255 if (!ImsUtils.shouldTestTelephony()) { 256 return; 257 } 258 TelephonyManager tm = (TelephonyManager) InstrumentationRegistry.getInstrumentation() 259 .getContext().getSystemService(Context.TELEPHONY_SERVICE); 260 if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) { 261 fail("This test requires that there is a SIM in the device!"); 262 } 263 // Correctness check: ensure that the subscription hasn't changed between tests. 264 int subId = SubscriptionManager.getSubscriptionId(sTestSlot); 265 if (subId != sTestSub) { 266 fail("The found subId " + subId + " does not match the test sub id " + sTestSub); 267 } 268 } 269 270 @After afterTest()271 public void afterTest() throws Exception { 272 if (!ImsUtils.shouldTestImsService()) { 273 return; 274 } 275 // Unbind the ImsService after the test completes only if feature FEATURE_TELEPHONY_IMS 276 // is enabled. 277 if (sServiceConnector != null) { 278 sServiceConnector.disconnectCarrierImsService(); 279 sServiceConnector.restoreDefaultSmsApp(); 280 } 281 } 282 283 @Test 284 // Note this test can run on devices with only feature FEATURE_TELEPHONY, so ImsResolver may not 285 // be running. testIncorrectPermissions()286 public void testIncorrectPermissions() throws Exception { 287 if (!ImsUtils.shouldTestTelephony()) { 288 return; 289 } 290 SipDelegateManager manager = getSipDelegateManager(); 291 try { 292 manager.isSupported(); 293 fail("isSupported requires READ_PRIVILEGED_PHONE_STATE or " 294 + "PERFORM_IMS_SINGLE_REGISTRATION"); 295 } catch (SecurityException e) { 296 //expected 297 } 298 try { 299 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 300 manager, SipDelegateManager::isSupported, ImsException.class, 301 "android.permission.PERFORM_IMS_SINGLE_REGISTRATION"); 302 } catch (ImsException e) { 303 // Not a problem, only checking permissions here. 304 } catch (SecurityException e) { 305 fail("isSupported requires READ_PRIVILEGED_PHONE_STATE or " 306 + "PERFORM_IMS_SINGLE_REGISTRATION, exception:" + e); 307 } 308 try { 309 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 310 manager, SipDelegateManager::isSupported, ImsException.class, 311 "android.permission.READ_PRIVILEGED_PHONE_STATE"); 312 313 } catch (ImsException e) { 314 // Not a problem, only checking permissions here. 315 } catch (SecurityException e) { 316 fail("isSupported requires READ_PRIVILEGED_PHONE_STATE or " 317 + "PERFORM_IMS_SINGLE_REGISTRATION, exception:" + e); 318 } 319 320 DelegateRequest d = new DelegateRequest(Collections.emptySet()); 321 TestSipDelegateConnection c = new TestSipDelegateConnection(d); 322 try { 323 manager.createSipDelegate(d, Runnable::run, c, c); 324 fail("createSipDelegate requires PERFORM_IMS_SINGLE_REGISTRATION"); 325 } catch (SecurityException e) { 326 //expected 327 } 328 329 330 ImsStateCallback callback = new ImsStateCallback() { 331 @Override 332 public void onUnavailable(int reason) { } 333 @Override 334 public void onAvailable() { } 335 @Override 336 public void onError() { } 337 }; 338 339 try { 340 manager.registerImsStateCallback(Runnable::run, callback); 341 fail("registerImsStateCallback requires PERFORM_IMS_SINGLE_REGISTRATION or " 342 + "READ_PRIVILEGED_PHONE_STATE permission."); 343 } catch (SecurityException e) { 344 //expected 345 } catch (ImsException ignore) { 346 fail("registerImsStateCallback requires PERFORM_IMS_SINGLE_REGISTRATION or " 347 + "READ_PRIVILEGED_PHONE_STATE permission."); 348 } 349 350 try { 351 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(manager, 352 m -> m.registerImsStateCallback(Runnable::run, callback), 353 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION"); 354 } catch (SecurityException e) { 355 fail("registerImsStateCallback requires PERFORM_IMS_SINGLE_REGISTRATION permission."); 356 } catch (ImsException ignore) { 357 // don't care, permission check passed 358 } 359 360 try { 361 manager.unregisterImsStateCallback(callback); 362 } catch (SecurityException e) { 363 fail("uregisterImsStateCallback requires no permission."); 364 } 365 366 try { 367 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(manager, 368 m -> m.registerImsStateCallback(Runnable::run, callback), 369 ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE"); 370 } catch (SecurityException e) { 371 fail("registerImsStateCallback requires READ_PRIVILEGED_PHONE_STATE permission."); 372 } catch (ImsException ignore) { 373 // don't care, permission check passed 374 } 375 376 try { 377 manager.unregisterImsStateCallback(callback); 378 } catch (SecurityException e) { 379 // unreachable, already passed permission check 380 fail("uregisterImsStateCallback requires no permission."); 381 } 382 } 383 384 @Test testSipDialogStateChanges()385 public void testSipDialogStateChanges() throws Exception { 386 if (!ImsUtils.shouldTestImsService()) { 387 return; 388 } 389 SipDialogStateCallback callback = new SipDialogStateCallback() { 390 @Override 391 public void onActiveSipDialogsChanged(List<SipDialogState> dialogs) { 392 int confirmedSize = dialogs.stream().filter( 393 d -> d.getState() == SipDialogState.STATE_CONFIRMED) 394 .collect(Collectors.toSet()).size(); 395 if (confirmedSize > 0) { 396 sUpdatedState = true; 397 } else { 398 sUpdatedState = false; 399 } 400 } 401 @Override 402 public void onError() { } 403 }; 404 405 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 406 Collections.emptySet(), 0); 407 ifaces.connect(); 408 try { 409 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(ifaces.manager, 410 m -> m.registerSipDialogStateCallback(Runnable::run, callback), 411 ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE"); 412 } catch (SecurityException e) { 413 fail("registerSipDialogStateCallback requires READ_PRIVILEGED_PHONE_STATE permission."); 414 } catch (ImsException ignore) { 415 // don't care, permission check passed 416 } 417 ifaces.delegateConn.setOperationCountDownLatch(1); 418 ifaces.delegateConn.waitForCountDown(1000); 419 // Send invite 420 SipDialogAttributes attr = new SipDialogAttributes(); 421 sendChatInvite(attr, ifaces); 422 assertFalse(sUpdatedState); 423 // receive 200 OK 424 receive200OkResponse(attr, ifaces); 425 ifaces.delegateConn.setOperationCountDownLatch(1); 426 ifaces.delegateConn.waitForCountDown(1000); 427 // SipDialog Confirmed 428 assertTrue(sUpdatedState); 429 // Send ACK 430 sendAck(attr, ifaces); 431 // Send BYE 432 sendByeRequest(attr, ifaces); 433 // SipDialog Closed 434 ifaces.delegateConn.setOperationCountDownLatch(1); 435 ifaces.delegateConn.waitForCountDown(1000); 436 assertFalse(sUpdatedState); 437 438 // Send the cleanup, which will trigger destroy to complete. 439 ifaces.delegateConn.sendCleanupSession(attr.callId); 440 ifaces.delegate.verifyCleanupSession(attr.callId); 441 ifaces.delegateConn.setOperationCountDownLatch(1); 442 ifaces.delegateConn.waitForCountDown(1000); 443 try { 444 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(ifaces.manager, 445 m -> m.unregisterSipDialogStateCallback(callback), 446 ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE"); 447 } catch (SecurityException e) { 448 fail("registerSipDialogStateCallback requires READ_PRIVILEGED_PHONE_STATE permission."); 449 } 450 destroySipDelegateAndVerify(ifaces); 451 assertEquals("There should be no more delegates", 0, 452 ifaces.transport.getDelegates().size()); 453 verifyUpdateRegistrationCalled(ifaces.reg); 454 } 455 456 @Test testSipDialogStateChangesOnMultipleDelegates()457 public void testSipDialogStateChangesOnMultipleDelegates() throws Exception { 458 if (!ImsUtils.shouldTestImsService()) { 459 return; 460 } 461 InetSocketAddress localAddr = new InetSocketAddress( 462 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 463 InetSocketAddress serverAddr = new InetSocketAddress( 464 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 465 SipDelegateConfiguration c = new SipDelegateConfiguration.Builder(1, 466 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr).build(); 467 468 SipDialogStateCallback callback = new SipDialogStateCallback() { 469 @Override 470 public void onActiveSipDialogsChanged(List<SipDialogState> dialogs) { 471 sUpdatedStateSize = dialogs.stream() 472 .filter(d -> d.getState() == SipDialogState.STATE_CONFIRMED) 473 .collect(Collectors.toList()).size(); 474 } 475 @Override 476 public void onError() { } 477 }; 478 479 SipDelegateManager manager = getSipDelegateManager(); 480 assertTrue(sServiceConnector.setDefaultSmsApp()); 481 connectTestImsServiceWithSipTransportAndConfig(); 482 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 483 TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration(); 484 485 // create delegate#1 486 DelegateRequest request1 = getChatOnlyRequest(); 487 TestSipDelegateConnection delegateConn1 = new TestSipDelegateConnection(request1); 488 TestSipDelegate delegate1 = createSipDelegateConnectionAndVerify(manager, delegateConn1, 489 transportImpl, Collections.emptySet(), 0); 490 Set<String> registeredTags1 = new ArraySet<>(request1.getFeatureTags()); 491 assertNotNull(delegate1); 492 verifyRegisteredAndSendSipConfig(delegateConn1, delegate1, registeredTags1, 493 Collections.emptySet(), c); 494 //delegate : 1, dialog confirmed : 0 495 assertEquals(0, sUpdatedStateSize); 496 try { 497 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(manager, 498 m -> m.registerSipDialogStateCallback(Runnable::run, callback), 499 ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE"); 500 } catch (SecurityException e) { 501 fail("registerSipDialogStateCallback requires READ_PRIVILEGED_PHONE_STATE permission."); 502 } catch (ImsException ignore) { 503 // don't care, permission check passed 504 } 505 // INVITE/200OK on Delegate#1 506 SipDialogAttributes attr = new SipDialogAttributes(); 507 SipDialogAttributes invAttr = attr.fromExisting().copyWithNewBranch(); 508 invAttr.addAcceptContactTag(GROUP_CHAT_TAG); 509 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, 510 invAttr); 511 delegateConn1.sendMessageAndVerifyCompletedSuccessfully(invite); 512 SipMessage resp = SipMessageUtils.generateSipResponse("200", "OK", 513 attr); 514 delegate1.receiveMessageAndVerifyReceivedCalled(resp); 515 delegateConn1.verifyMessageReceived(resp); 516 delegateConn1.setOperationCountDownLatch(1); 517 delegateConn1.waitForCountDown(/*ImsUtils.TEST_TIMEOUT_MS*/1000); 518 //delegate : 1, dialog confirmed : 1 519 assertEquals(1, sUpdatedStateSize); 520 521 // create delegate#2 522 DelegateRequest request2 = getDefaultRequest(); 523 TestSipDelegateConnection delegateConn2 = new TestSipDelegateConnection(request2); 524 Set<String> registeredTags2 = new ArraySet<>(request2.getFeatureTags()); 525 TestSipDelegate delegate2 = createSipDelegateConnectionAndVerify(manager, delegateConn2, 526 transportImpl, Collections.emptySet(), 1); 527 assertNotNull(delegate2); 528 verifyUpdateRegistrationCalled(regImpl); 529 Set<FeatureTagState> deniedSet = generateDeniedSetFromRequest(request1.getFeatureTags(), 530 request2.getFeatureTags(), 531 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE); 532 verifyRegisteredAndSendSipConfig(delegateConn2, delegate2, registeredTags2, deniedSet, c); 533 // INVITE/200OK on Delegate#2 534 SipDialogAttributes attr2 = new SipDialogAttributes(); 535 SipDialogAttributes invAttr2 = attr2.fromExisting().copyWithNewBranch(); 536 invAttr2.addAcceptContactTag(CHATBOT_COMMUNICATION_USING_SESSION_TAG); 537 SipMessage invite2 = SipMessageUtils.generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, 538 invAttr2); 539 delegateConn2.sendMessageAndVerifyCompletedSuccessfully(invite2); 540 SipMessage resp2 = SipMessageUtils.generateSipResponse("200", "OK", 541 attr2); 542 delegate2.receiveMessageAndVerifyReceivedCalled(resp2); 543 delegateConn2.verifyMessageReceived(resp2); 544 delegateConn2.setOperationCountDownLatch(1); 545 delegateConn2.waitForCountDown(/*ImsUtils.TEST_TIMEOUT_MS*/1000); 546 //delegate : 2, dialog confirmed : 2 547 assertEquals(2, sUpdatedStateSize); 548 // Destroying delegate 1 will transfer all feature tags over to delegate 2 549 destroySipDelegate(manager, transportImpl, delegateConn1, delegate1); 550 // If one delegate is destroyed in multiple delegates, 551 // it internally triggers the destruction of the remaining delegates 552 // and then the recreation of another delegate with the new feature set that it supports. 553 verifySipDelegateDestroyed(transportImpl, delegate2); 554 delegateConn2.setOperationCountDownLatch(1); 555 delegateConn2.waitForCountDown(/*ImsUtils.TEST_TIMEOUT_MS*/1000); 556 //delegate : 1, dialog confirmed : 0 557 assertEquals(0, sUpdatedStateSize); 558 delegate2 = getSipDelegate(transportImpl, Collections.emptySet(), 0); 559 verifyUpdateRegistrationCalled(regImpl); 560 verifyRegisteredAndSendSipConfig(delegateConn2, delegate2, request2.getFeatureTags(), 561 Collections.emptySet(), c); 562 destroySipDelegateAndVerifyConnDestroyed(manager, transportImpl, delegateConn2, delegate2); 563 assertEquals("There should be no more delegates", 0, 564 transportImpl.getDelegates().size()); 565 } 566 567 @Test 568 // Note this test can run on devices with only feature FEATURE_TELEPHONY, so ImsResolver may not 569 // be running. testFeatureImsNotSupported()570 public void testFeatureImsNotSupported() throws Exception { 571 if (!ImsUtils.shouldTestTelephony()) { 572 return; 573 } 574 575 if (sServiceConnector != null) { 576 // Override FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION for this test so that telephony 577 // will report not enabled. 578 sServiceConnector.setDeviceSingleRegistrationEnabled(false); 579 } 580 581 try { 582 SipDelegateManager manager = getSipDelegateManager(); 583 584 try { 585 // If FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION is not supported this should 586 // return false. 587 Boolean result = ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 588 manager, SipDelegateManager::isSupported, ImsException.class, 589 "android.permission.PERFORM_IMS_SINGLE_REGISTRATION"); 590 assertNotNull(result); 591 assertFalse("isSupported should return false on devices that do not " 592 + "support feature FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION", result); 593 } catch (SecurityException e) { 594 fail("isSupported requires PERFORM_IMS_SINGLE_REGISTRATION permission"); 595 } 596 597 try { 598 // If FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION is not supported, this should throw 599 // an ImsException 600 DelegateRequest request = new DelegateRequest(Collections.emptySet()); 601 TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request); 602 ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn( 603 manager, (m) -> m.createSipDelegate(request, Runnable::run, 604 delegateConn, delegateConn), ImsException.class, 605 "android.permission.PERFORM_IMS_SINGLE_REGISTRATION"); 606 fail("createSipDelegate should throw an ImsException with code " 607 + "CODE_ERROR_UNSUPPORTED_OPERATION on devices that do not support feature " 608 + "FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION"); 609 } catch (SecurityException e) { 610 fail("isSupported requires PERFORM_IMS_SINGLE_REGISTRATION permission"); 611 } catch (ImsException e) { 612 // expecting CODE_ERROR_UNSUPPORTED_OPERATION 613 if (e.getCode() != ImsException.CODE_ERROR_UNSUPPORTED_OPERATION) { 614 fail("createSipDelegate should throw an ImsException with code " 615 + "CODE_ERROR_UNSUPPORTED_OPERATION on devices that do not support " 616 + "feature FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION"); 617 } 618 } 619 } finally { 620 if (sServiceConnector != null) { 621 // restore override for the rest of the tests. 622 sServiceConnector.setDeviceSingleRegistrationEnabled(true); 623 } 624 } 625 } 626 627 @Test testIsSupportedWithSipTransportCapable()628 public void testIsSupportedWithSipTransportCapable() throws Exception { 629 if (!ImsUtils.shouldTestImsService()) { 630 return; 631 } 632 PersistableBundle b = new PersistableBundle(); 633 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 634 overrideCarrierConfig(b); 635 connectTestImsServiceWithSipTransport(); 636 637 SipDelegateManager manager = getSipDelegateManager(); 638 Boolean result = null; 639 try { 640 result = callUntilImsServiceIsAvailable(() -> 641 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions(manager, 642 SipDelegateManager::isSupported, ImsException.class, 643 "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 644 } catch (SecurityException e) { 645 fail("isSupported requires PERFORM_IMS_SINGLE_REGISTRATION permission"); 646 } 647 assertNotNull(result); 648 assertTrue("isSupported should return true", result); 649 } 650 651 @Test testIsSupportedWithSipTransportCapableCarrierConfigNotSet()652 public void testIsSupportedWithSipTransportCapableCarrierConfigNotSet() throws Exception { 653 if (!ImsUtils.shouldTestImsService()) { 654 return; 655 } 656 PersistableBundle b = new PersistableBundle(); 657 // Carrier Config is explicitly set to not support single registration. 658 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false); 659 overrideCarrierConfig(b); 660 connectTestImsServiceWithSipTransport(); 661 662 Boolean result = callUntilImsServiceIsAvailable(() -> 663 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 664 getSipDelegateManager(), SipDelegateManager::isSupported, 665 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 666 assertNotNull(result); 667 assertFalse("isSupported should return false if" 668 + "CarrierConfigManager.Ims.KEY_RCS_SINGLE_REGISTRATION_REQUIRED_BOOL is set to " 669 + "false", result); 670 } 671 672 @Ignore("Disabling for integration b/175766573") 673 @Test testIsSupportedWithSipTransportCapableOnlyRcs()674 public void testIsSupportedWithSipTransportCapableOnlyRcs() throws Exception { 675 if (!ImsUtils.shouldTestImsService()) { 676 return; 677 } 678 PersistableBundle b = new PersistableBundle(); 679 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 680 overrideCarrierConfig(b); 681 682 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 683 // set SipTransport as supported with RCS only attached. 684 sServiceConnector.getCarrierService().addCapabilities( 685 ImsService.CAPABILITY_SIP_DELEGATE_CREATION); 686 sServiceConnector.getCarrierService().setSipTransportImplemented(); 687 688 ImsFeatureConfiguration c = getConfigForRcs(); 689 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 690 verifyImsServiceState(c); 691 692 Boolean result = callUntilImsServiceIsAvailable(() -> 693 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 694 getSipDelegateManager(), SipDelegateManager::isSupported, 695 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 696 assertNotNull(result); 697 assertFalse("isSupported should return false in the case that the ImsService is only " 698 + "attached for RCS and not MMTEL and RCS", result); 699 } 700 701 702 @Test testIsSupportedWithSipTransportCapableButNotImplemented()703 public void testIsSupportedWithSipTransportCapableButNotImplemented() throws Exception { 704 if (!ImsUtils.shouldTestImsService()) { 705 return; 706 } 707 PersistableBundle b = new PersistableBundle(); 708 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 709 overrideCarrierConfig(b); 710 711 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 712 // SipTransport set as capable, but no SipTransport implementation is returned. 713 sServiceConnector.getCarrierService().addCapabilities( 714 ImsService.CAPABILITY_SIP_DELEGATE_CREATION); 715 ImsFeatureConfiguration c = getConfigForMmTelAndRcs(); 716 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 717 verifyImsServiceState(c); 718 719 Boolean result = callUntilImsServiceIsAvailable(() -> 720 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 721 getSipDelegateManager(), SipDelegateManager::isSupported, 722 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 723 assertNotNull(result); 724 assertFalse("isSupported should return false in the case that SipTransport is not " 725 + "implemented", result); 726 } 727 728 @Test testIsSupportedWithSipTransportImplementedButNotCapable()729 public void testIsSupportedWithSipTransportImplementedButNotCapable() throws Exception { 730 if (!ImsUtils.shouldTestImsService()) { 731 return; 732 } 733 PersistableBundle b = new PersistableBundle(); 734 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 735 overrideCarrierConfig(b); 736 737 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 738 // SipTransport is set as Implemented, but not Capable 739 sServiceConnector.getCarrierService().setSipTransportImplemented(); 740 ImsFeatureConfiguration c = getConfigForMmTelAndRcs(); 741 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 742 verifyImsServiceState(c); 743 744 Boolean result = callUntilImsServiceIsAvailable(() -> 745 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 746 getSipDelegateManager(), SipDelegateManager::isSupported, 747 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 748 assertNotNull(result); 749 assertFalse("isSupported should return false in the case that SipTransport is not " 750 + "set as capable in ImsService#getImsServiceCapabilities", result); 751 } 752 753 @Test testIsSupportedWithSipTransportNotImplementedNotCapable()754 public void testIsSupportedWithSipTransportNotImplementedNotCapable() throws Exception { 755 if (!ImsUtils.shouldTestImsService()) { 756 return; 757 } 758 PersistableBundle b = new PersistableBundle(); 759 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 760 overrideCarrierConfig(b); 761 762 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 763 // Not Implemented/capable 764 ImsFeatureConfiguration c = getConfigForMmTelAndRcs(); 765 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 766 verifyImsServiceState(c); 767 768 Boolean result = callUntilImsServiceIsAvailable(() -> 769 ShellIdentityUtils.invokeThrowableMethodWithShellPermissions( 770 getSipDelegateManager(), SipDelegateManager::isSupported, 771 ImsException.class, "android.permission.PERFORM_IMS_SINGLE_REGISTRATION")); 772 assertNotNull(result); 773 assertFalse("isSupported should return false in the case that SipTransport is not " 774 + "set as capable in ImsService#getImsServiceCapabilities", result); 775 } 776 777 @Test testCreateDestroyDelegateNotDefaultMessagingApp()778 public void testCreateDestroyDelegateNotDefaultMessagingApp() throws Exception { 779 if (!ImsUtils.shouldTestImsService()) { 780 return; 781 } 782 connectTestImsServiceWithSipTransportAndConfig(); 783 784 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 785 TestImsRegistration imsReg = sServiceConnector.getCarrierService().getImsRegistration(); 786 SipDelegateManager manager = getSipDelegateManager(); 787 DelegateRequest request = getDefaultRequest(); 788 TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request); 789 790 // wait for onCreated and registration state change to be called. 791 createSipDelegateConnectionNoDelegateExpected(manager, delegateConn, transportImpl); 792 793 // TODO deal with this case better when we can filter messages. 794 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_SIP_MESSAGE, 795 SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD); 796 797 delegateConn.triggerFullNetworkRegistration(manager, 403, "FORBIDDEN"); 798 // wait 5 seconds, this should not return. 799 TestImsRegistration.NetworkRegistrationInfo info = 800 imsReg.getNextFullNetworkRegRequest(5000); 801 assertNull("If there is no valid SipTransport, this should not be called", info); 802 803 destroySipDelegateConnectionNoDelegate(manager, delegateConn); 804 } 805 806 @Test testCreateDelegateBasicUseCases()807 public void testCreateDelegateBasicUseCases() throws Exception { 808 if (!ImsUtils.shouldTestImsService()) { 809 return; 810 } 811 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 812 Collections.emptySet(), 0); 813 ifaces.connectAndVerify(); 814 815 // Ensure requests to perform a full network re-registration work properly. 816 verifyFullRegistrationTriggered(ifaces); 817 818 destroySipDelegateAndVerify(ifaces); 819 assertEquals("There should be no more delegates", 0, 820 ifaces.transport.getDelegates().size()); 821 verifyUpdateRegistrationCalled(ifaces.reg); 822 } 823 824 @Test testImsServiceDisconnected()825 public void testImsServiceDisconnected() throws Exception { 826 if (!ImsUtils.shouldTestImsService()) { 827 return; 828 } 829 assertTrue(sServiceConnector.setDefaultSmsApp()); 830 connectTestImsServiceWithSipTransportAndConfig(); 831 832 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 833 TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration(); 834 SipDelegateManager manager = getSipDelegateManager(); 835 DelegateRequest request = getDefaultRequest(); 836 TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request); 837 838 TestSipDelegate delegate = createSipDelegateConnectionAndVerify(manager, delegateConn, 839 transportImpl, Collections.emptySet(), 0); 840 assertNotNull(delegate); 841 verifyUpdateRegistrationCalled(regImpl); 842 843 InetSocketAddress localAddr = new InetSocketAddress( 844 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 845 InetSocketAddress serverAddr = new InetSocketAddress( 846 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 847 SipDelegateConfiguration c = new SipDelegateConfiguration.Builder(1, 848 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr).build(); 849 verifyRegisteredAndSendSipConfig(delegateConn, delegate, request.getFeatureTags(), 850 Collections.emptySet(), c); 851 852 verifyOutgoingTransport(delegateConn, delegate); 853 verifyIncomingTransport(delegateConn, delegate); 854 855 sServiceConnector.disconnectCarrierImsService(); 856 // unbind ImsService suddenly and wait for on destroyed 857 delegateConn.setOperationCountDownLatch(1); 858 transportImpl.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 859 delegate.notifyOnDestroyed( 860 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD); 861 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 862 delegateConn.verifyDestroyed( 863 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD); 864 } 865 866 @Test testCreateDelegateTestInvalidSipMessages()867 public void testCreateDelegateTestInvalidSipMessages() throws Exception { 868 if (!ImsUtils.shouldTestImsService()) { 869 return; 870 } 871 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 872 Collections.emptySet(), 0); 873 ifaces.connectAndVerify(); 874 875 // Verify restricted SIP request methods are not sent to the delegate. 876 sendRestrictedRequestsAndVerifyFailed(ifaces.delegateConn); 877 // Verify malformed messages are not sent to the delegate. 878 sendInvalidRequestsAndVerifyFailed(ifaces.delegateConn); 879 880 destroySipDelegateAndVerify(ifaces); 881 assertEquals("There should be no more delegates", 0, 882 ifaces.transport.getDelegates().size()); 883 verifyUpdateRegistrationCalled(ifaces.reg); 884 } 885 886 @Test testDelegateRegistrationChanges()887 public void testDelegateRegistrationChanges() throws Exception { 888 if (!ImsUtils.shouldTestImsService()) { 889 return; 890 } 891 try { 892 TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(), 893 TelephonyUtils.CTS_APP_PACKAGE, 894 TelephonyUtils.SUPPORT_REGISTERING_DELEGATE_STATE_STRING); 895 TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(), 896 TelephonyUtils.CTS_APP_PACKAGE, 897 TelephonyUtils.SUPPORT_DEREGISTERING_LOSING_PDN_STATE_STRING); 898 899 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 900 Collections.emptySet(), 0); 901 ifaces.connectAndVerify(); 902 Set<String> registeredTags = new ArraySet<>(ifaces.request.getFeatureTags()); 903 904 // move reg state to registering, deregistering and then deregistered 905 ifaces.delegateConn.setOperationCountDownLatch(1); 906 DelegateRegistrationState s = getRegisteringRegistrationState(registeredTags); 907 ifaces.delegate.notifyImsRegistrationUpdate(s); 908 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 909 ifaces.delegateConn.verifyRegistrationStateEquals(s); 910 911 ifaces.delegateConn.setOperationCountDownLatch(1); 912 s = getDeregisteringState(registeredTags, 913 DelegateRegistrationState.DEREGISTERING_REASON_LOSING_PDN); 914 ifaces.delegate.notifyImsRegistrationUpdate(s); 915 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 916 ifaces.delegateConn.verifyRegistrationStateEquals(s); 917 918 ifaces.delegateConn.setOperationCountDownLatch(1); 919 s = getRegisteredRegistrationState(registeredTags); 920 ifaces.delegate.notifyImsRegistrationUpdate(s); 921 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 922 ifaces.delegateConn.verifyRegistrationStateEquals(s); 923 924 destroySipDelegateAndVerify(ifaces); 925 assertEquals("There should be no more delegates", 0, 926 ifaces.transport.getDelegates().size()); 927 } finally { 928 TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(), 929 TelephonyUtils.CTS_APP_PACKAGE, 930 TelephonyUtils.SUPPORT_REGISTERING_DELEGATE_STATE_STRING); 931 TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(), 932 TelephonyUtils.CTS_APP_PACKAGE, 933 TelephonyUtils.SUPPORT_DEREGISTERING_LOSING_PDN_STATE_STRING); 934 } 935 } 936 937 @Ignore("the compatibility framework does not currently support changing compatibility flags" 938 + "on user builds for device side CTS tests. Ignore this test until support is added") 939 @Test testDelegateRegistrationChangesCompatDisabled()940 public void testDelegateRegistrationChangesCompatDisabled() throws Exception { 941 if (!ImsUtils.shouldTestImsService()) { 942 return; 943 } 944 try { 945 TelephonyUtils.disableCompatCommand(InstrumentationRegistry.getInstrumentation(), 946 TelephonyUtils.CTS_APP_PACKAGE, 947 TelephonyUtils.SUPPORT_REGISTERING_DELEGATE_STATE_STRING); 948 TelephonyUtils.disableCompatCommand(InstrumentationRegistry.getInstrumentation(), 949 TelephonyUtils.CTS_APP_PACKAGE, 950 TelephonyUtils.SUPPORT_DEREGISTERING_LOSING_PDN_STATE_STRING); 951 952 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 953 Collections.emptySet(), 0); 954 ifaces.connectAndVerify(); 955 Set<String> registeredTags = new ArraySet<>(ifaces.request.getFeatureTags()); 956 957 // The registering state should move to the deregistered state 958 // with the reason DEREGISTERED_REASON_NOT_REGISTERED when the registering state is not 959 // supported. 960 ifaces.delegateConn.setOperationCountDownLatch(1); 961 DelegateRegistrationState s = getRegisteringRegistrationState(registeredTags); 962 ifaces.delegate.notifyImsRegistrationUpdate(s); 963 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 964 s = getDeregisteredState(registeredTags, 965 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED); 966 ifaces.delegateConn.verifyRegistrationStateEquals(s); 967 968 // The reason DEREGISTERING_REASON_LOSING_PDN of the deregistering state will be changed 969 // to the reason DEREGISTERING_REASON_PDN_CHANGE when DEREGISTERING_LOSING_PDN_STATE is 970 // not supported. 971 ifaces.delegateConn.setOperationCountDownLatch(1); 972 s = getDeregisteringState(registeredTags, 973 DelegateRegistrationState.DEREGISTERING_REASON_LOSING_PDN); 974 ifaces.delegate.notifyImsRegistrationUpdate(s); 975 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 976 s = getDeregisteringState(registeredTags, 977 DelegateRegistrationState.DEREGISTERING_REASON_PDN_CHANGE); 978 ifaces.delegateConn.verifyRegistrationStateEquals(s); 979 980 ifaces.delegateConn.setOperationCountDownLatch(1); 981 s = getRegisteredRegistrationState(registeredTags); 982 ifaces.delegate.notifyImsRegistrationUpdate(s); 983 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 984 ifaces.delegateConn.verifyRegistrationStateEquals(s); 985 986 destroySipDelegateAndVerify(ifaces); 987 assertEquals("There should be no more delegates", 0, 988 ifaces.transport.getDelegates().size()); 989 } finally { 990 TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(), 991 TelephonyUtils.CTS_APP_PACKAGE, 992 TelephonyUtils.SUPPORT_REGISTERING_DELEGATE_STATE_STRING); 993 TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(), 994 TelephonyUtils.CTS_APP_PACKAGE, 995 TelephonyUtils.SUPPORT_DEREGISTERING_LOSING_PDN_STATE_STRING); 996 } 997 } 998 999 @Test testCreateMultipleDelegates()1000 public void testCreateMultipleDelegates() throws Exception { 1001 if (!ImsUtils.shouldTestImsService()) { 1002 return; 1003 } 1004 assertTrue(sServiceConnector.setDefaultSmsApp()); 1005 connectTestImsServiceWithSipTransportAndConfig(); 1006 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 1007 TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration(); 1008 SipDelegateManager manager = getSipDelegateManager(); 1009 1010 DelegateRequest request1 = getChatOnlyRequest(); 1011 TestSipDelegateConnection delegateConn1 = new TestSipDelegateConnection(request1); 1012 Set<String> registeredTags1 = new ArraySet<>(request1.getFeatureTags()); 1013 TestSipDelegate delegate1 = createSipDelegateConnectionAndVerify(manager, delegateConn1, 1014 transportImpl, Collections.emptySet(), 0); 1015 assertNotNull(delegate1); 1016 1017 InetSocketAddress localAddr = new InetSocketAddress( 1018 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 1019 InetSocketAddress serverAddr = new InetSocketAddress( 1020 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 1021 SipDelegateConfiguration c = new SipDelegateConfiguration.Builder(1, 1022 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr).build(); 1023 verifyRegisteredAndSendSipConfig(delegateConn1, delegate1, registeredTags1, 1024 Collections.emptySet(), c); 1025 1026 // This will only be granted File transfer FT 1027 DelegateRequest request2 = getDefaultRequest(); 1028 TestSipDelegateConnection delegateConn2 = new TestSipDelegateConnection(request2); 1029 Set<String> registeredTags2 = new ArraySet<>(); 1030 registeredTags2.add(FILE_TRANSFER_HTTP_TAG); 1031 TestSipDelegate delegate2 = createSipDelegateConnectionAndVerify(manager, delegateConn2, 1032 transportImpl, Collections.emptySet(), 1); 1033 assertNotNull(delegate2); 1034 verifyUpdateRegistrationCalled(regImpl); 1035 Set<FeatureTagState> deniedSet = generateDeniedSetFromRequest(request1.getFeatureTags(), 1036 request2.getFeatureTags(), 1037 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE); 1038 verifyRegisteredAndSendSipConfig(delegateConn2, delegate2, registeredTags2, 1039 deniedSet, c); 1040 1041 // Destroying delegate 1 will transfer all feature tags over to delegate 2 1042 destroySipDelegate(manager, transportImpl, delegateConn1, delegate1); 1043 // This internally triggers the destruction of the internal delegate2 and then recreation 1044 // of another delegate with the new feature set that it supports. 1045 verifySipDelegateDestroyed(transportImpl, delegate2); 1046 delegate2 = getSipDelegate(transportImpl, Collections.emptySet(), 0); 1047 verifyUpdateRegistrationCalled(regImpl); 1048 verifyRegisteredAndSendSipConfig(delegateConn2, delegate2, request2.getFeatureTags(), 1049 Collections.emptySet(), c); 1050 1051 destroySipDelegateAndVerifyConnDestroyed(manager, transportImpl, delegateConn2, delegate2); 1052 assertEquals("There should be no more delegates", 0, 1053 transportImpl.getDelegates().size()); 1054 } 1055 1056 @Test testCreateDelegateMessagingAppChangesToApp()1057 public void testCreateDelegateMessagingAppChangesToApp() throws Exception { 1058 if (!ImsUtils.shouldTestImsService()) { 1059 return; 1060 } 1061 // start with no features granted 1062 connectTestImsServiceWithSipTransportAndConfig(); 1063 1064 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 1065 TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration(); 1066 SipDelegateManager manager = getSipDelegateManager(); 1067 DelegateRequest request = getDefaultRequest(); 1068 TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request); 1069 1070 // wait for onCreated and registration state change to be called. 1071 createSipDelegateConnectionNoDelegateExpected(manager, delegateConn, transportImpl); 1072 1073 // Make this app the DMA 1074 regImpl.resetLatch(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, 1); 1075 assertTrue(sServiceConnector.setDefaultSmsApp()); 1076 assertTrue(regImpl.waitForLatchCountDown(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, 1077 ImsUtils.TEST_TIMEOUT_MS)); 1078 TestSipDelegate delegate = getSipDelegate(transportImpl, Collections.emptySet(), 0); 1079 verifyUpdateRegistrationCalled(regImpl); 1080 InetSocketAddress localAddr = new InetSocketAddress( 1081 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 1082 InetSocketAddress serverAddr = new InetSocketAddress( 1083 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 1084 SipDelegateConfiguration c = new SipDelegateConfiguration.Builder(1, 1085 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr).build(); 1086 verifyRegisteredAndSendSipConfig(delegateConn, delegate, request.getFeatureTags(), 1087 Collections.emptySet(), c); 1088 destroySipDelegateAndVerifyConnDestroyed(manager, transportImpl, delegateConn, delegate); 1089 assertEquals("There should be no more delegates", 0, 1090 transportImpl.getDelegates().size()); 1091 } 1092 1093 @Test testCreateDelegateMessagingAppChangesAwayFromApp()1094 public void testCreateDelegateMessagingAppChangesAwayFromApp() throws Exception { 1095 if (!ImsUtils.shouldTestImsService()) { 1096 return; 1097 } 1098 // Make this app the DMA 1099 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1100 Collections.emptySet(), 0); 1101 ifaces.connectAndVerify(); 1102 1103 // Move DMA to another app, we should receive a registration update. 1104 ifaces.reg.resetLatch(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, 1); 1105 sServiceConnector.restoreDefaultSmsApp(); 1106 assertTrue(ifaces.reg.waitForLatchCountDown( 1107 TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, ImsUtils.TEST_TIMEOUT_MS)); 1108 // we should get another reg update with all tags denied. 1109 ifaces.delegateConn.setOperationCountDownLatch(1); 1110 verifySipDelegateDestroyed(ifaces.transport, ifaces.delegate); 1111 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1112 ifaces.delegateConn.verifyRegistrationStateEmpty(); 1113 // All requested features should have been denied due to the app not being the default sms 1114 // app. 1115 ifaces.delegateConn.verifyAllDenied(SipDelegateManager.DENIED_REASON_NOT_ALLOWED); 1116 // There should not be any delegates left, as the only delegate should have been cleaned up. 1117 assertEquals("SipDelegate should not have any delegates", 0, 1118 ifaces.transport.getDelegates().size()); 1119 verifyUpdateRegistrationCalled(ifaces.reg); 1120 destroySipDelegateConnectionNoDelegate(ifaces.manager, ifaces.delegateConn); 1121 } 1122 1123 @Test testParcelUnparcelDelegateRequest()1124 public void testParcelUnparcelDelegateRequest() { 1125 ArraySet<String> testTags = new ArraySet<>(); 1126 testTags.add(MMTEL_TAG); 1127 testTags.add(ONE_TO_ONE_CHAT_TAG); 1128 testTags.add(GROUP_CHAT_TAG); 1129 testTags.add(FILE_TRANSFER_HTTP_TAG); 1130 DelegateRequest r = new DelegateRequest(testTags); 1131 Parcel p = Parcel.obtain(); 1132 r.writeToParcel(p, 0); 1133 p.setDataPosition(0); 1134 DelegateRequest unparcelled = DelegateRequest.CREATOR.createFromParcel(p); 1135 assertEquals(r, unparcelled); 1136 assertEquals(r.getFeatureTags(), unparcelled.getFeatureTags()); 1137 } 1138 1139 @Test testParcelUnparcelFeatureTagState()1140 public void testParcelUnparcelFeatureTagState() { 1141 FeatureTagState f = new FeatureTagState(MMTEL_TAG, 1142 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED); 1143 Parcel p = Parcel.obtain(); 1144 f.writeToParcel(p, 0); 1145 p.setDataPosition(0); 1146 FeatureTagState unparcelled = FeatureTagState.CREATOR.createFromParcel(p); 1147 assertEquals(f, unparcelled); 1148 assertEquals(f.getFeatureTag(), unparcelled.getFeatureTag()); 1149 assertEquals(f.getState(), unparcelled.getState()); 1150 } 1151 1152 @Test testParcelUnparcelRegistrationState()1153 public void testParcelUnparcelRegistrationState() { 1154 ArraySet<String> regTags = new ArraySet<>(); 1155 regTags.add(MMTEL_TAG); 1156 ArraySet<String> registeringTags = new ArraySet<>(); 1157 registeringTags.add(CHATBOT_COMMUNICATION_USING_SESSION_TAG); 1158 DelegateRegistrationState s = new DelegateRegistrationState.Builder() 1159 .addRegisteredFeatureTags(regTags) 1160 .addRegisteredFeatureTag(ONE_TO_ONE_CHAT_TAG) 1161 .addDeregisteringFeatureTag(GROUP_CHAT_TAG, 1162 DelegateRegistrationState.DEREGISTERING_REASON_PDN_CHANGE) 1163 .addDeregisteredFeatureTag(FILE_TRANSFER_HTTP_TAG, 1164 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED) 1165 .addRegisteringFeatureTags(registeringTags) 1166 .build(); 1167 Parcel p = Parcel.obtain(); 1168 s.writeToParcel(p, 0); 1169 p.setDataPosition(0); 1170 DelegateRegistrationState unparcel = DelegateRegistrationState.CREATOR.createFromParcel(p); 1171 assertEquals(s, unparcel); 1172 assertEquals(s.getRegisteredFeatureTags(), unparcel.getRegisteredFeatureTags()); 1173 assertEquals(s.getDeregisteringFeatureTags(), unparcel.getDeregisteringFeatureTags()); 1174 assertEquals(s.getDeregisteredFeatureTags(), unparcel.getDeregisteredFeatureTags()); 1175 assertEquals(s.getRegisteringFeatureTags(), unparcel.getRegisteringFeatureTags()); 1176 } 1177 1178 @Test testParcelUnparcelConfiguration()1179 public void testParcelUnparcelConfiguration() { 1180 // Set everything to a non-default value 1181 SipDelegateConfiguration c = generateNewTestConfig(); 1182 assertEquals(1, c.getVersion()); 1183 assertEquals(SipDelegateConfiguration.SIP_TRANSPORT_TCP, c.getTransportType()); 1184 assertEquals("1.1.1.1", c.getLocalAddress().getAddress().getHostAddress()); 1185 assertEquals(80, c.getLocalAddress().getPort()); 1186 assertEquals("2.2.2.2", c.getSipServerAddress().getAddress().getHostAddress()); 1187 assertEquals(81, c.getSipServerAddress().getPort()); 1188 assertTrue(c.isSipCompactFormEnabled()); 1189 assertTrue(c.isSipKeepaliveEnabled()); 1190 assertEquals(508, c.getMaxUdpPayloadSizeBytes()); 1191 assertEquals("test1", c.getPublicUserIdentifier()); 1192 assertEquals("test2", c.getPrivateUserIdentifier()); 1193 assertEquals("test.domain", c.getHomeDomain()); 1194 assertEquals("testImei", c.getImei()); 1195 assertEquals("sipauth", c.getSipAuthenticationHeader()); 1196 assertEquals("sipnonce", c.getSipAuthenticationNonce()); 1197 assertEquals("srvroute", c.getSipServiceRouteHeader()); 1198 assertEquals("path", c.getSipPathHeader()); 1199 assertEquals("ua", c.getSipUserAgentHeader()); 1200 assertEquals("user", c.getSipContactUserParameter()); 1201 assertEquals("pani", c.getSipPaniHeader()); 1202 assertEquals("plani", c.getSipPlaniHeader()); 1203 assertEquals("cni", c.getSipCniHeader()); 1204 assertEquals("uri", c.getSipAssociatedUriHeader()); 1205 Uri gruuUri = Uri.parse("sip:blah@gruu.net"); 1206 assertEquals(gruuUri, c.getPublicGruuUri()); 1207 1208 Parcel p = Parcel.obtain(); 1209 c.writeToParcel(p, 0); 1210 p.setDataPosition(0); 1211 SipDelegateConfiguration unparcelConfig = 1212 SipDelegateConfiguration.CREATOR.createFromParcel(p); 1213 assertEquals(c, unparcelConfig); 1214 } 1215 1216 // this test is required to avoid pre-submit check (API coverage check FAIL) 1217 @Test testSipDialogStateDescribeContents()1218 public void testSipDialogStateDescribeContents() { 1219 SipDialogState state = new SipDialogState.Builder(SipDialogState.STATE_CONFIRMED).build(); 1220 assertNotNull(state); 1221 int describe = state.describeContents(); 1222 assertTrue(describe == 0); 1223 } 1224 1225 @Test testParcelUnparcelSipDialogState()1226 public void testParcelUnparcelSipDialogState() { 1227 SipDialogState state = new SipDialogState.Builder(SipDialogState.STATE_CONFIRMED).build(); 1228 assertEquals(SipDialogState.STATE_CONFIRMED, state.getState()); 1229 Parcel p = Parcel.obtain(); 1230 state.writeToParcel(p, 0); 1231 p.setDataPosition(0); 1232 SipDialogState unparcelled = SipDialogState.CREATOR.createFromParcel(p); 1233 assertEquals(state, unparcelled); 1234 assertEquals(state.getState() , unparcelled.getState()); 1235 } 1236 1237 @Test testCopyConfiguration()1238 public void testCopyConfiguration() { 1239 // Set everything to a non-default value 1240 SipDelegateConfiguration c = generateNewTestConfig(); 1241 // The config should be exactly the same, but with an incremented version. 1242 SipDelegateConfiguration configInc = new SipDelegateConfiguration.Builder(c).build(); 1243 assertEquals(2, configInc.getVersion()); 1244 assertEquals(SipDelegateConfiguration.SIP_TRANSPORT_TCP, configInc.getTransportType()); 1245 assertEquals("1.1.1.1", configInc.getLocalAddress().getAddress().getHostAddress()); 1246 assertEquals(80, configInc.getLocalAddress().getPort()); 1247 assertEquals("2.2.2.2", 1248 configInc.getSipServerAddress().getAddress().getHostAddress()); 1249 assertEquals(81, configInc.getSipServerAddress().getPort()); 1250 assertTrue(configInc.isSipCompactFormEnabled()); 1251 assertTrue(configInc.isSipKeepaliveEnabled()); 1252 assertEquals(508, configInc.getMaxUdpPayloadSizeBytes()); 1253 assertEquals("test1", configInc.getPublicUserIdentifier()); 1254 assertEquals("test2", configInc.getPrivateUserIdentifier()); 1255 assertEquals("test.domain", configInc.getHomeDomain()); 1256 assertEquals("testImei", configInc.getImei()); 1257 assertEquals("sipauth", configInc.getSipAuthenticationHeader()); 1258 assertEquals("sipnonce", configInc.getSipAuthenticationNonce()); 1259 assertEquals("srvroute", configInc.getSipServiceRouteHeader()); 1260 assertEquals("path", configInc.getSipPathHeader()); 1261 assertEquals("ua", configInc.getSipUserAgentHeader()); 1262 assertEquals("user", configInc.getSipContactUserParameter()); 1263 assertEquals("pani", configInc.getSipPaniHeader()); 1264 assertEquals("plani", configInc.getSipPlaniHeader()); 1265 assertEquals("cni", configInc.getSipCniHeader()); 1266 assertEquals("uri", configInc.getSipAssociatedUriHeader()); 1267 Uri gruuUri = Uri.parse("sip:blah@gruu.net"); 1268 assertEquals(gruuUri, configInc.getPublicGruuUri()); 1269 SipDelegateConfiguration.IpSecConfiguration ipSecConfig = configInc.getIpSecConfiguration(); 1270 assertEquals(123, ipSecConfig.getLocalTxPort()); 1271 assertEquals(124, ipSecConfig.getLocalRxPort()); 1272 assertEquals(125, ipSecConfig.getLastLocalTxPort()); 1273 assertEquals(126, ipSecConfig.getRemoteTxPort()); 1274 assertEquals(127, ipSecConfig.getRemoteRxPort()); 1275 assertEquals(128, ipSecConfig.getLastRemoteTxPort()); 1276 assertEquals("secverify", ipSecConfig.getSipSecurityVerifyHeader()); 1277 InetSocketAddress natAddr = configInc.getNatSocketAddress(); 1278 assertEquals("3.3.3.3", natAddr.getAddress().getHostAddress()); 1279 assertEquals(129, natAddr.getPort()); 1280 } 1281 1282 @Test testParcelUnparcelSipMessage()1283 public void testParcelUnparcelSipMessage() { 1284 String startLine = 1285 "INVITE sip:12345678@[2607:fc20:3806:2a44:0:6:42ae:5b01]:49155 SIP/2.0\r\n"; 1286 String header = "Via: SIP/2.0/TCP [FD00:976A:C202:1808::1]:65529;" 1287 + "branch=z9hG4bKg3Zqkv7iivdfzmfqu68sro3cuht97q846\r\n" 1288 + "To: <sip:12345678;phone-context=xxx.com@xxx.com;user=phone>\r\n" 1289 + "From: <sip:12345679@xxx.com>;tag=ABC\r\n" 1290 + "Call-ID: 000050B04074-79e-fc9b8700-29df64-5f3e5811-26fa8\r\n"; 1291 String branch = "z9hG4bKg3Zqkv7iivdfzmfqu68sro3cuht97q846"; 1292 String callId = "000050B04074-79e-fc9b8700-29df64-5f3e5811-26fa8"; 1293 byte[] bytes = new byte[1]; 1294 bytes[0] = 'a'; 1295 SipMessage m = new SipMessage(startLine, header, bytes); 1296 Parcel p = Parcel.obtain(); 1297 m.writeToParcel(p, 0); 1298 p.setDataPosition(0); 1299 SipMessage unparcel = SipMessage.CREATOR.createFromParcel(p); 1300 assertEquals(m, unparcel); 1301 assertEquals(m.getStartLine(), unparcel.getStartLine()); 1302 assertEquals(m.getHeaderSection(), unparcel.getHeaderSection()); 1303 assertTrue(Arrays.equals(m.getContent(), unparcel.getContent())); 1304 assertEquals(branch, m.getViaBranchParameter()); 1305 assertEquals(callId, m.getCallIdParameter()); 1306 assertEquals(m.getViaBranchParameter(), unparcel.getViaBranchParameter()); 1307 assertEquals(m.getCallIdParameter(), unparcel.getCallIdParameter()); 1308 } 1309 1310 @Test testEncodeSipMessage()1311 public void testEncodeSipMessage() { 1312 String startLine = 1313 "INVITE sip:12345678@[2607:fc20:3806:2a44:0:6:42ae:5b01]:49155 SIP/2.0\r\n"; 1314 String header = "Via: SIP/2.0/TCP [FD00:976A:C202:1808::1]:65529;" 1315 + "branch=z9hG4bKg3Zqkv7iivdfzmfqu68sro3cuht97q846\r\n" 1316 + "To: <sip:12345678;phone-context=xxx.com@xxx.com;" 1317 + "user=phone>\r\n" 1318 + "From: <sip:12345679@xxx.com>;" 1319 + "tag=h7g4Esbg_mavodi-e-10b-123-6-ffffffff-_000050B04074-79e-fc9b8700-29df65" 1320 + "-5f3e5811-27196\r\n" 1321 + "Call-ID: 000050B04074-79e-fc9b8700-29df64-5f3e5811-26fa8\r\n"; 1322 byte[] content1 = ("v=0\r\n" 1323 + "o=- 10 1000 IN IP6 FD00:976A:C202:1808::1\r\n" 1324 + "s=VOIP\r\n" 1325 + "c=IN IP6 fd00:976a:c002:1940::4\r\n").getBytes(UTF_8); 1326 byte[] content2 = new byte[0]; 1327 1328 SipMessage m = new SipMessage(startLine, header, content1); 1329 byte[] encodedMsg = m.toEncodedMessage(); 1330 String decodedStr = new String(encodedMsg, UTF_8); 1331 SipMessage decodedMsg = generateSipMessage(decodedStr); 1332 assertEquals(decodedMsg.getStartLine(), m.getStartLine()); 1333 assertEquals(decodedMsg.getHeaderSection(), m.getHeaderSection()); 1334 assertTrue(Arrays.equals(decodedMsg.getContent(), m.getContent())); 1335 1336 // Test empty content 1337 m = new SipMessage(startLine, header, content2); 1338 encodedMsg = m.toEncodedMessage(); 1339 decodedStr = new String(encodedMsg, UTF_8); 1340 decodedMsg = generateSipMessage(decodedStr); 1341 assertEquals(decodedMsg.getStartLine(), m.getStartLine()); 1342 assertEquals(decodedMsg.getHeaderSection(), m.getHeaderSection()); 1343 assertTrue(Arrays.equals(decodedMsg.getContent(), m.getContent())); 1344 } 1345 1346 @Test testFeatureTagDeniedByCarrierConfig()1347 public void testFeatureTagDeniedByCarrierConfig() throws Exception { 1348 if (!ImsUtils.shouldTestImsService()) { 1349 return; 1350 } 1351 1352 setFeatureTagsCarrierAllowed(new String[]{FILE_TRANSFER_HTTP_TAG}); 1353 assertTrue(sServiceConnector.setDefaultSmsApp()); 1354 connectTestImsServiceWithSipTransportAndConfig(); 1355 TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport(); 1356 SipDelegateManager manager = getSipDelegateManager(); 1357 DelegateRequest request = getDefaultRequest(); 1358 TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request); 1359 Set<String> deniedTags = new ArraySet<>(request.getFeatureTags()); 1360 deniedTags.remove(FILE_TRANSFER_HTTP_TAG); 1361 1362 TestSipDelegate delegate = createSipDelegateConnectionAndVerify(manager, delegateConn, 1363 transportImpl, getDeniedTagsForReason(deniedTags, 1364 SipDelegateManager.DENIED_REASON_NOT_ALLOWED), 0); 1365 assertNotNull(delegate); 1366 1367 Set<String> registeredTags = new ArraySet<>( 1368 Arrays.asList(new String[]{FILE_TRANSFER_HTTP_TAG})); 1369 delegateConn.setOperationCountDownLatch(1); 1370 DelegateRegistrationState s = getRegisteredRegistrationState(registeredTags); 1371 delegate.notifyImsRegistrationUpdate(s); 1372 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1373 delegateConn.verifyRegistrationStateEquals(s); 1374 destroySipDelegateAndVerifyConnDestroyed(manager, transportImpl, delegateConn, delegate); 1375 assertEquals("There should be no more delegates", 0, 1376 transportImpl.getDelegates().size()); 1377 setFeatureTagsCarrierAllowed(getDefaultRequest().getFeatureTags().toArray(new String[0])); 1378 } 1379 1380 @Test testCloseActiveDialog()1381 public void testCloseActiveDialog() throws Exception { 1382 if (!ImsUtils.shouldTestImsService()) { 1383 return; 1384 } 1385 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1386 Collections.emptySet(), 0); 1387 ifaces.connect(); 1388 // Send invite 1389 SipDialogAttributes attr = new SipDialogAttributes(); 1390 sendChatInvite(attr, ifaces); 1391 // send close from app 1392 ifaces.delegateConn.disconnect(ifaces.manager, 1393 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1394 // Registration state will change to deregistering during this time. 1395 ifaces.delegateConn.setOperationCountDownLatch(1); 1396 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1397 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1398 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1399 // receive 200 OK 1400 receive200OkResponse(attr, ifaces); 1401 // Send ACK 1402 sendAck(attr, ifaces); 1403 // Send BYE 1404 sendByeRequest(attr, ifaces); 1405 // destroy should not be called until cleanupSession is sent. 1406 assertFalse(ifaces.transport.isLatchCountDownFinished( 1407 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1408 1409 ifaces.delegateConn.setOperationCountDownLatch(1); 1410 // Send the cleanup, which will trigger destroy to complete. 1411 ifaces.delegateConn.sendCleanupSession(attr.callId); 1412 ifaces.delegate.verifyCleanupSession(attr.callId); 1413 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1414 ifaces.delegate.notifyOnDestroyed( 1415 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1416 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1417 ifaces.delegateConn.verifyDestroyed( 1418 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1419 1420 assertEquals("There should be no more delegates", 0, 1421 ifaces.transport.getDelegates().size()); 1422 verifyUpdateRegistrationCalled(ifaces.reg); 1423 } 1424 1425 @Test testReceivedActiveDialogClose()1426 public void testReceivedActiveDialogClose() throws Exception { 1427 if (!ImsUtils.shouldTestImsService()) { 1428 return; 1429 } 1430 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1431 Collections.emptySet(), 0); 1432 ifaces.connect(); 1433 // receive invite 1434 SipDialogAttributes attr = new SipDialogAttributes(); 1435 receiveChatInvite(attr, ifaces); 1436 // send close from app 1437 ifaces.delegateConn.disconnect(ifaces.manager, 1438 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1439 // Registration state will change to deregistering during this time. 1440 ifaces.delegateConn.setOperationCountDownLatch(1); 1441 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1442 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1443 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1444 // Send 200 OK 1445 send200OkResponse(attr, ifaces); 1446 // receive ACK 1447 receiveAck(attr, ifaces); 1448 // Send BYE 1449 receiveByeRequest(attr, ifaces); 1450 ifaces.delegateConn.setOperationCountDownLatch(1); 1451 // Send the cleanup, which will trigger destroy to complete. 1452 ifaces.delegateConn.sendCleanupSession(attr.callId); 1453 ifaces.delegate.verifyCleanupSession(attr.callId); 1454 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1455 ifaces.delegate.notifyOnDestroyed( 1456 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1457 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1458 ifaces.delegateConn.verifyDestroyed( 1459 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1460 1461 assertEquals("There should be no more delegates", 0, 1462 ifaces.transport.getDelegates().size()); 1463 verifyUpdateRegistrationCalled(ifaces.reg); 1464 } 1465 1466 @Test testActiveDialogPendingNewInvite()1467 public void testActiveDialogPendingNewInvite() throws Exception { 1468 if (!ImsUtils.shouldTestImsService()) { 1469 return; 1470 } 1471 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1472 Collections.emptySet(), 0); 1473 ifaces.connect(); 1474 // Send invite 1475 SipDialogAttributes attr = new SipDialogAttributes(); 1476 sendChatInvite(attr, ifaces); 1477 // send close from app 1478 ifaces.delegateConn.disconnect(ifaces.manager, 1479 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1480 // Registration state will change to deregistering during this time. 1481 ifaces.delegateConn.setOperationCountDownLatch(1); 1482 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1483 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1484 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1485 // receive 200 OK 1486 receive200OkResponse(attr, ifaces); 1487 // Send ACK 1488 sendAck(attr, ifaces); 1489 // Send invite 1490 SipDialogAttributes attr2 = new SipDialogAttributes(); 1491 attr2.addAcceptContactTag(ONE_TO_ONE_CHAT_TAG); 1492 // Should be denied because the transport is now restricted 1493 sendDeniedChatInvite(attr2, ifaces, 1494 SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED); 1495 // Send BYE on original invite 1496 sendByeRequest(attr, ifaces); 1497 // destroy should not be called until cleanupSession is sent. 1498 assertFalse(ifaces.transport.isLatchCountDownFinished( 1499 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1500 ifaces.delegateConn.setOperationCountDownLatch(1); 1501 // Send the cleanup, which will trigger destroy to complete. 1502 ifaces.delegateConn.sendCleanupSession(attr.callId); 1503 ifaces.delegate.verifyCleanupSession(attr.callId); 1504 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1505 ifaces.delegate.notifyOnDestroyed( 1506 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1507 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1508 ifaces.delegateConn.verifyDestroyed( 1509 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1510 1511 assertEquals("There should be no more delegates", 0, 1512 ifaces.transport.getDelegates().size()); 1513 verifyUpdateRegistrationCalled(ifaces.reg); 1514 } 1515 1516 @Test testCloseSessionByePendingCleanup()1517 public void testCloseSessionByePendingCleanup() throws Exception { 1518 if (!ImsUtils.shouldTestImsService()) { 1519 return; 1520 } 1521 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1522 Collections.emptySet(), 0); 1523 ifaces.connect(); 1524 // Send invite 1525 SipDialogAttributes attr = new SipDialogAttributes(); 1526 sendChatInvite(attr, ifaces); 1527 // send close from app 1528 ifaces.delegateConn.disconnect(ifaces.manager, 1529 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1530 // receive 200 OK 1531 receive200OkResponse(attr, ifaces); 1532 // Send ACK 1533 sendAck(attr, ifaces); 1534 // Send BYE 1535 sendByeRequest(attr, ifaces); 1536 assertFalse(ifaces.transport.isLatchCountDownFinished( 1537 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1538 // Registration state will change to deregistering during this time. 1539 ifaces.delegateConn.setOperationCountDownLatch(1); 1540 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1541 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1542 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1543 // waiting for delegate connection onDestroy to be called. 1544 ifaces.delegateConn.setOperationCountDownLatch(1); 1545 // no cleanupSession called, so cleanup session should be called from internal and then 1546 // the delegate should be closed. 1547 ifaces.delegate.verifyCleanupSession(attr.callId); 1548 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1549 ifaces.delegate.notifyOnDestroyed( 1550 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1551 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1552 ifaces.delegateConn.verifyDestroyed( 1553 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1554 assertEquals("There should be no more delegates", 0, 1555 ifaces.transport.getDelegates().size()); 1556 verifyUpdateRegistrationCalled(ifaces.reg); 1557 } 1558 1559 @Test testCloseSessionPendingBye()1560 public void testCloseSessionPendingBye() throws Exception { 1561 if (!ImsUtils.shouldTestImsService()) { 1562 return; 1563 } 1564 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1565 Collections.emptySet(), 0); 1566 ifaces.connect(); 1567 // Send invite 1568 SipDialogAttributes attr = new SipDialogAttributes(); 1569 sendChatInvite(attr, ifaces); 1570 // send close from app 1571 ifaces.delegateConn.disconnect(ifaces.manager, 1572 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1573 // receive 200 OK 1574 receive200OkResponse(attr, ifaces); 1575 // Send ACK 1576 sendAck(attr, ifaces); 1577 // Don't send BYE or cleanupSession 1578 assertFalse(ifaces.transport.isLatchCountDownFinished( 1579 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1580 // Registration state will change to deregistering during this time. 1581 ifaces.delegateConn.setOperationCountDownLatch(1); 1582 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1583 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1584 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1585 // waiting for delegate connection onDestroy to be called. 1586 ifaces.delegateConn.setOperationCountDownLatch(1); 1587 // no cleanupSession called, so cleanup session should be called from internal and then 1588 // the delegate should be closed. 1589 ifaces.delegate.verifyCleanupSession(attr.callId); 1590 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1591 ifaces.delegate.notifyOnDestroyed( 1592 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1593 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1594 ifaces.delegateConn.verifyDestroyed( 1595 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1596 assertEquals("There should be no more delegates", 0, 1597 ifaces.transport.getDelegates().size()); 1598 verifyUpdateRegistrationCalled(ifaces.reg); 1599 } 1600 1601 @Test testCloseMultipleSessionsPendingBye()1602 public void testCloseMultipleSessionsPendingBye() throws Exception { 1603 if (!ImsUtils.shouldTestImsService()) { 1604 return; 1605 } 1606 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1607 Collections.emptySet(), 0); 1608 ifaces.connect(); 1609 // Send invite 1 1610 SipDialogAttributes attr = new SipDialogAttributes(); 1611 sendChatInvite(attr, ifaces); 1612 // Send invite 2 1613 SipDialogAttributes attr2 = new SipDialogAttributes(); 1614 sendChatInvite(attr2, ifaces); 1615 // send close from app 1616 ifaces.delegateConn.disconnect(ifaces.manager, 1617 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1618 // receive 200 OK 1619 receive200OkResponse(attr, ifaces); 1620 receive200OkResponse(attr2, ifaces); 1621 // Send ACK 1622 sendAck(attr, ifaces); 1623 sendAck(attr2, ifaces); 1624 // Don't send BYE or cleanupSession 1625 assertFalse(ifaces.transport.isLatchCountDownFinished( 1626 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1627 // Registration state will change to deregistering during this time. 1628 ifaces.delegateConn.setOperationCountDownLatch(1); 1629 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1630 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1631 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1632 // waiting for delegate connection onDestroy to be called. 1633 ifaces.delegateConn.setOperationCountDownLatch(1); 1634 // no cleanupSession called, so cleanup session should be called from internal and then 1635 // the delegate should be closed. 1636 ifaces.delegate.verifyCleanupSession(attr.callId, attr2.callId); 1637 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1638 ifaces.delegate.notifyOnDestroyed( 1639 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1640 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1641 ifaces.delegateConn.verifyDestroyed( 1642 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1643 assertEquals("There should be no more delegates", 0, 1644 ifaces.transport.getDelegates().size()); 1645 verifyUpdateRegistrationCalled(ifaces.reg); 1646 } 1647 1648 @Test testCloseSessionBye()1649 public void testCloseSessionBye() throws Exception { 1650 if (!ImsUtils.shouldTestImsService()) { 1651 return; 1652 } 1653 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1654 Collections.emptySet(), 0); 1655 ifaces.connect(); 1656 // Send invite 1657 SipDialogAttributes attr = new SipDialogAttributes(); 1658 sendChatInvite(attr, ifaces); 1659 // receive 200 OK 1660 receive200OkResponse(attr, ifaces); 1661 // Send ACK 1662 sendAck(attr, ifaces); 1663 // send close from app 1664 ifaces.delegateConn.disconnect(ifaces.manager, 1665 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1666 // Send BYE 1667 sendByeRequest(attr, ifaces); 1668 assertFalse(ifaces.transport.isLatchCountDownFinished( 1669 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1670 // Registration state will change to deregistering during this time. 1671 ifaces.delegateConn.setOperationCountDownLatch(1); 1672 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1673 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1674 DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)); 1675 // waiting for delegate connection onDestroy to be called. 1676 ifaces.delegateConn.setOperationCountDownLatch(1); 1677 // Send the cleanup, which will trigger destroy to complete. 1678 ifaces.delegateConn.sendCleanupSession(attr.callId); 1679 ifaces.delegate.verifyCleanupSession(attr.callId); 1680 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1681 ifaces.delegate.notifyOnDestroyed( 1682 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1683 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1684 ifaces.delegateConn.verifyDestroyed( 1685 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1686 assertEquals("There should be no more delegates", 0, 1687 ifaces.transport.getDelegates().size()); 1688 verifyUpdateRegistrationCalled(ifaces.reg); 1689 } 1690 1691 @Test testSwitchAppPendingBye()1692 public void testSwitchAppPendingBye() throws Exception { 1693 if (!ImsUtils.shouldTestImsService()) { 1694 return; 1695 } 1696 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1697 Collections.emptySet(), 0); 1698 ifaces.connect(); 1699 // Send invite 1700 SipDialogAttributes attr = new SipDialogAttributes(); 1701 sendChatInvite(attr, ifaces); 1702 // receive 200 OK 1703 receive200OkResponse(attr, ifaces); 1704 // Restore the default SMS app. 1705 sServiceConnector.restoreDefaultSmsApp(); 1706 // Registration state will change to deregistering during this time. 1707 ifaces.delegateConn.setOperationCountDownLatch(1); 1708 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1709 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1710 DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING)); 1711 // Don't send BYE or cleanup, session should still be cleaned up. 1712 assertFalse(ifaces.transport.isLatchCountDownFinished( 1713 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1714 // wait for delegate connection feature tag state to be updated with denied features. 1715 ifaces.delegateConn.setOperationCountDownLatch(1); 1716 // verify framework internally calls cleanup on the session before destroy. 1717 ifaces.delegate.verifyCleanupSession(attr.callId); 1718 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1719 ifaces.delegate.notifyOnDestroyed( 1720 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1721 assertEquals("There should be no more delegates", 0, 1722 ifaces.transport.getDelegates().size()); 1723 verifyUpdateRegistrationCalled(ifaces.reg); 1724 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1725 ifaces.delegateConn.verifyRegistrationStateEmpty(); 1726 ifaces.delegateConn.verifyAllDenied(SipDelegateManager.DENIED_REASON_NOT_ALLOWED); 1727 } 1728 1729 @Test testSwitchAppActiveSession()1730 public void testSwitchAppActiveSession() throws Exception { 1731 if (!ImsUtils.shouldTestImsService()) { 1732 return; 1733 } 1734 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1735 Collections.emptySet(), 0); 1736 ifaces.connect(); 1737 // Send invite 1738 SipDialogAttributes attr = new SipDialogAttributes(); 1739 sendChatInvite(attr, ifaces); 1740 // receive 200 OK 1741 receive200OkResponse(attr, ifaces); 1742 // Restore the default SMS app. 1743 sServiceConnector.restoreDefaultSmsApp(); 1744 // Registration state will change to deregistering during this time. 1745 ifaces.delegateConn.setOperationCountDownLatch(1); 1746 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1747 assertTrue(ifaces.delegateConn.verifyDeregisteringStateContains(ONE_TO_ONE_CHAT_TAG, 1748 DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING)); 1749 // BYE should still be able to be sent 1750 sendByeRequest(attr, ifaces); 1751 assertFalse(ifaces.transport.isLatchCountDownFinished( 1752 TestSipTransport.LATCH_DESTROY_DELEGATE)); 1753 // wait for delegate connection feature tag state to be updated with denied features. 1754 ifaces.delegateConn.setOperationCountDownLatch(1); 1755 // Send the cleanup, which will trigger delegate destroy to complete. 1756 ifaces.delegateConn.sendCleanupSession(attr.callId); 1757 ifaces.delegate.verifyCleanupSession(attr.callId); 1758 ifaces.transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 1759 ifaces.delegate.notifyOnDestroyed( 1760 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 1761 assertEquals("There should be no more delegates", 0, 1762 ifaces.transport.getDelegates().size()); 1763 verifyUpdateRegistrationCalled(ifaces.reg); 1764 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 1765 ifaces.delegateConn.verifyAllDenied(SipDelegateManager.DENIED_REASON_NOT_ALLOWED); 1766 } 1767 1768 @Test testActiveSessionDeregistering()1769 public void testActiveSessionDeregistering() throws Exception { 1770 if (!ImsUtils.shouldTestImsService()) { 1771 return; 1772 } 1773 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1774 Collections.emptySet(), 0); 1775 ifaces.connect(); 1776 // Send invite 1777 SipDialogAttributes attr = new SipDialogAttributes(); 1778 sendChatInvite(attr, ifaces); 1779 // move chat to deregistering 1780 Set<String> regFeatures = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 1781 regFeatures.remove(ONE_TO_ONE_CHAT_TAG); 1782 DelegateRegistrationState state = getDeregisteringState(regFeatures, 1783 Collections.singleton(ONE_TO_ONE_CHAT_TAG), 1784 DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE); 1785 verifyRegistrationState(ifaces, state); 1786 // receive 200 OK 1787 receive200OkResponse(attr, ifaces); 1788 // Send ACK 1789 sendAck(attr, ifaces); 1790 // Send BYE and clean up 1791 sendByeRequest(attr, ifaces); 1792 ifaces.delegateConn.sendCleanupSession(attr.callId); 1793 ifaces.delegate.verifyCleanupSession(attr.callId); 1794 1795 destroySipDelegateAndVerify(ifaces); 1796 assertEquals("There should be no more delegates", 0, 1797 ifaces.transport.getDelegates().size()); 1798 verifyUpdateRegistrationCalled(ifaces.reg); 1799 } 1800 1801 @Test testActiveSessionDeregisteringNoResponse()1802 public void testActiveSessionDeregisteringNoResponse() throws Exception { 1803 if (!ImsUtils.shouldTestImsService()) { 1804 return; 1805 } 1806 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1807 Collections.emptySet(), 0); 1808 ifaces.connect(); 1809 // Send invite 1810 SipDialogAttributes attr = new SipDialogAttributes(); 1811 sendChatInvite(attr, ifaces); 1812 // move chat to deregistering 1813 Set<String> regFeatures = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 1814 regFeatures.remove(ONE_TO_ONE_CHAT_TAG); 1815 DelegateRegistrationState state = getDeregisteringState(regFeatures, 1816 Collections.singleton(ONE_TO_ONE_CHAT_TAG), 1817 DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE); 1818 verifyRegistrationState(ifaces, state); 1819 // receive 200 OK 1820 receive200OkResponse(attr, ifaces); 1821 // Send ACK 1822 sendAck(attr, ifaces); 1823 // Don't send BYE or cleanup and ensure that we still get call to clean up after timeout. 1824 ifaces.delegate.verifyCleanupSession(attr.callId); 1825 1826 destroySipDelegateAndVerify(ifaces); 1827 assertEquals("There should be no more delegates", 0, 1828 ifaces.transport.getDelegates().size()); 1829 verifyUpdateRegistrationCalled(ifaces.reg); 1830 } 1831 1832 @Test testMultipleActiveSessionDeregisteringNoResponse()1833 public void testMultipleActiveSessionDeregisteringNoResponse() throws Exception { 1834 if (!ImsUtils.shouldTestImsService()) { 1835 return; 1836 } 1837 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1838 Collections.emptySet(), 0); 1839 ifaces.connect(); 1840 // Send invite 1 1841 SipDialogAttributes attr = new SipDialogAttributes(); 1842 sendChatInvite(attr, ifaces); 1843 // Send invite 2 1844 SipDialogAttributes attr2 = new SipDialogAttributes(); 1845 sendChatInvite(attr2, ifaces); 1846 // move chat to deregistering 1847 Set<String> regFeatures = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 1848 regFeatures.remove(ONE_TO_ONE_CHAT_TAG); 1849 DelegateRegistrationState state = getDeregisteringState(regFeatures, 1850 Collections.singleton(ONE_TO_ONE_CHAT_TAG), 1851 DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE); 1852 verifyRegistrationState(ifaces, state); 1853 // receive 200 OK for invite 1 1854 receive200OkResponse(attr, ifaces); 1855 // Don't send BYE or cleanup and ensure that we still get call to clean up after timeout. 1856 ifaces.delegate.verifyCleanupSession(attr.callId, attr2.callId); 1857 destroySipDelegateAndVerify(ifaces); 1858 assertEquals("There should be no more delegates", 0, 1859 ifaces.transport.getDelegates().size()); 1860 verifyUpdateRegistrationCalled(ifaces.reg); 1861 } 1862 1863 @Test testActiveSessionDeregisteringNewInviteDenied()1864 public void testActiveSessionDeregisteringNewInviteDenied() throws Exception { 1865 if (!ImsUtils.shouldTestImsService()) { 1866 return; 1867 } 1868 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1869 Collections.emptySet(), 0); 1870 ifaces.connect(); 1871 // Send invite 1872 SipDialogAttributes attr = new SipDialogAttributes(); 1873 sendChatInvite(attr, ifaces); 1874 // move chat to deregistering 1875 Set<String> regFeatures = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 1876 regFeatures.remove(ONE_TO_ONE_CHAT_TAG); 1877 DelegateRegistrationState state = getDeregisteringState(regFeatures, 1878 Collections.singleton(ONE_TO_ONE_CHAT_TAG), 1879 DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE); 1880 verifyRegistrationState(ifaces, state); 1881 // receive 200 OK 1882 receive200OkResponse(attr, ifaces); 1883 // Send ACK 1884 sendAck(attr, ifaces); 1885 // send a new invite over the same feature tag, which should be denied because the tag 1886 // is deregistering 1887 SipDialogAttributes attr2 = new SipDialogAttributes(); 1888 attr2.addAcceptContactTag(ONE_TO_ONE_CHAT_TAG); 1889 sendDeniedChatInvite(attr2, ifaces, 1890 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG); 1891 // Send BYE and clean up 1892 sendByeRequest(attr, ifaces); 1893 ifaces.delegateConn.sendCleanupSession(attr.callId); 1894 ifaces.delegate.verifyCleanupSession(attr.callId); 1895 1896 destroySipDelegateAndVerify(ifaces); 1897 assertEquals("There should be no more delegates", 0, 1898 ifaces.transport.getDelegates().size()); 1899 verifyUpdateRegistrationCalled(ifaces.reg); 1900 } 1901 1902 @Test testInviteDeniedTag()1903 public void testInviteDeniedTag() throws Exception { 1904 if (!ImsUtils.shouldTestImsService()) { 1905 return; 1906 } 1907 // Deny ONE_TO_ONE_CHAT access to this delegate 1908 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1909 Collections.singleton(new FeatureTagState(ONE_TO_ONE_CHAT_TAG, 1910 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE)), 0); 1911 ifaces.connect(); 1912 // send a new invite over the chat feature tag, which should be denied because the tag was 1913 // denied 1914 SipDialogAttributes attr = new SipDialogAttributes(); 1915 attr.addAcceptContactTag(ONE_TO_ONE_CHAT_TAG); 1916 sendDeniedChatInvite(attr, ifaces, 1917 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG); 1918 1919 destroySipDelegateAndVerify(ifaces); 1920 assertEquals("There should be no more delegates", 0, 1921 ifaces.transport.getDelegates().size()); 1922 verifyUpdateRegistrationCalled(ifaces.reg); 1923 } 1924 1925 @Test testInviteAcceptContactNotAssociated()1926 public void testInviteAcceptContactNotAssociated() throws Exception { 1927 if (!ImsUtils.shouldTestImsService()) { 1928 return; 1929 } 1930 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1931 Collections.emptySet(), 0); 1932 ifaces.connect(); 1933 // send a new invite over the MMTEL feature tag, which is not in the set of feature tags 1934 // associated with this delegate. 1935 SipDialogAttributes attr = new SipDialogAttributes(); 1936 attr.addAcceptContactTag(MMTEL_TAG); 1937 sendDeniedChatInvite(attr, ifaces, 1938 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG); 1939 1940 destroySipDelegateAndVerify(ifaces); 1941 assertEquals("There should be no more delegates", 0, 1942 ifaces.transport.getDelegates().size()); 1943 verifyUpdateRegistrationCalled(ifaces.reg); 1944 } 1945 1946 @Test testIncomingInviteDeregistering()1947 public void testIncomingInviteDeregistering() throws Exception { 1948 if (!ImsUtils.shouldTestImsService()) { 1949 return; 1950 } 1951 TransportInterfaces ifaces = new TransportInterfaces(getDefaultRequest(), 1952 Collections.emptySet(), 0); 1953 ifaces.connect(); 1954 // move chat to deregistering 1955 Set<String> regFeatures = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 1956 regFeatures.remove(ONE_TO_ONE_CHAT_TAG); 1957 DelegateRegistrationState state = getDeregisteringState(regFeatures, 1958 Collections.singleton(ONE_TO_ONE_CHAT_TAG), 1959 DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE); 1960 verifyRegistrationState(ifaces, state); 1961 // receive invite, which can not be blocked 1962 SipDialogAttributes attr = new SipDialogAttributes(); 1963 receiveChatInvite(attr, ifaces); 1964 // ensure delegate connection can still respond to the request, even if in restricted state. 1965 send200OkResponse(attr, ifaces); 1966 receiveAck(attr, ifaces); 1967 // receive BYE and clean up 1968 receiveByeRequest(attr, ifaces); 1969 ifaces.delegateConn.sendCleanupSession(attr.callId); 1970 ifaces.delegate.verifyCleanupSession(attr.callId); 1971 1972 destroySipDelegateAndVerify(ifaces); 1973 assertEquals("There should be no more delegates", 0, 1974 ifaces.transport.getDelegates().size()); 1975 verifyUpdateRegistrationCalled(ifaces.reg); 1976 } 1977 generateSipMessage(String str)1978 private SipMessage generateSipMessage(String str) { 1979 String crlf = "\r\n"; 1980 String[] components = str.split(crlf); 1981 String startLine = ""; 1982 String header = ""; 1983 String content = ""; 1984 StringBuilder sb = new StringBuilder(); 1985 int idx = 1; 1986 if (components.length > 0) { 1987 startLine = components[0] + crlf; 1988 } 1989 // generate sip header 1990 idx = composeSipSection(idx, components, sb); 1991 header = sb.toString(); 1992 1993 idx++; 1994 sb.setLength(0); 1995 // generate sip body 1996 idx = composeSipSection(idx, components, sb); 1997 content = sb.toString(); 1998 1999 return new SipMessage(startLine, header, content.getBytes(UTF_8)); 2000 } 2001 composeSipSection(int index, String[] components, StringBuilder sb)2002 private int composeSipSection(int index, String[] components, StringBuilder sb) { 2003 String crlf = "\r\n"; 2004 while (index < components.length) { 2005 if (components[index].length() > 0) { 2006 sb.append(components[index]).append(crlf); 2007 index++; 2008 } else { 2009 break; 2010 } 2011 } 2012 return index; 2013 } 2014 sendChatInvite(SipDialogAttributes attr, TransportInterfaces ifaces)2015 private void sendChatInvite(SipDialogAttributes attr, 2016 TransportInterfaces ifaces) throws Exception { 2017 SipDialogAttributes invAttr = attr.fromExisting().copyWithNewBranch(); 2018 invAttr.addAcceptContactTag(ONE_TO_ONE_CHAT_TAG); 2019 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, 2020 invAttr); 2021 sendMessageAndVerifyAck(invite, ifaces); 2022 } 2023 sendDeniedChatInvite(SipDialogAttributes attr, TransportInterfaces ifaces, int denyReason)2024 private void sendDeniedChatInvite(SipDialogAttributes attr, 2025 TransportInterfaces ifaces, int denyReason) throws Exception { 2026 SipDialogAttributes invAttr = attr.fromExisting().copyWithNewBranch(); 2027 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, 2028 invAttr); 2029 ifaces.delegateConn.sendMessageAndVerifyFailure(invite, denyReason); 2030 } 2031 receiveChatInvite(SipDialogAttributes attr, TransportInterfaces ifaces)2032 private void receiveChatInvite(SipDialogAttributes attr, 2033 TransportInterfaces ifaces) throws Exception { 2034 SipDialogAttributes invAttr = attr.fromExisting().copyWithNewBranch(); 2035 invAttr.addAcceptContactTag(ONE_TO_ONE_CHAT_TAG); 2036 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, 2037 invAttr); 2038 receiveMessageAndVerifyAck(invite, ifaces); 2039 } 2040 send200OkResponse(SipDialogAttributes attr, TransportInterfaces ifaces)2041 private void send200OkResponse(SipDialogAttributes attr, 2042 TransportInterfaces ifaces) throws Exception { 2043 attr.setToTag(); 2044 // do not update branch here, as it is a response to a request. 2045 SipMessage resp = SipMessageUtils.generateSipResponse("200", "OK", 2046 attr); 2047 sendMessageAndVerifyAck(resp, ifaces); 2048 } 2049 receive200OkResponse(SipDialogAttributes attr, TransportInterfaces ifaces)2050 private void receive200OkResponse(SipDialogAttributes attr, 2051 TransportInterfaces ifaces) throws Exception { 2052 attr.setToTag(); 2053 // do not update branch here, as it is a response to a request. 2054 SipMessage resp = SipMessageUtils.generateSipResponse("200", "OK", 2055 attr); 2056 receiveMessageAndVerifyAck(resp, ifaces); 2057 } 2058 sendAck(SipDialogAttributes attr, TransportInterfaces ifaces)2059 private void sendAck(SipDialogAttributes attr, 2060 TransportInterfaces ifaces) throws Exception { 2061 attr = attr.copyWithNewBranch(); 2062 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.ACK_SIP_METHOD, 2063 attr); 2064 sendMessageAndVerifyAck(invite, ifaces); 2065 } 2066 receiveAck(SipDialogAttributes attr, TransportInterfaces ifaces)2067 private void receiveAck(SipDialogAttributes attr, 2068 TransportInterfaces ifaces) throws Exception { 2069 attr = attr.copyWithNewBranch(); 2070 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.ACK_SIP_METHOD, 2071 attr); 2072 receiveMessageAndVerifyAck(invite, ifaces); 2073 } 2074 sendByeRequest(SipDialogAttributes attr, TransportInterfaces ifaces)2075 private void sendByeRequest(SipDialogAttributes attr, 2076 TransportInterfaces ifaces) throws Exception { 2077 attr = attr.copyWithNewBranch(); 2078 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, 2079 attr); 2080 sendMessageAndVerifyAck(invite, ifaces); 2081 } 2082 receiveByeRequest(SipDialogAttributes attr, TransportInterfaces ifaces)2083 private void receiveByeRequest(SipDialogAttributes attr, 2084 TransportInterfaces ifaces) throws Exception { 2085 attr = attr.copyWithNewBranch(); 2086 SipMessage invite = SipMessageUtils.generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, 2087 attr); 2088 receiveMessageAndVerifyAck(invite, ifaces); 2089 } 2090 createSipDelegateConnectionNoDelegateExpected(SipDelegateManager manager, TestSipDelegateConnection conn, TestSipTransport transport)2091 private void createSipDelegateConnectionNoDelegateExpected(SipDelegateManager manager, 2092 TestSipDelegateConnection conn, TestSipTransport transport) throws Exception { 2093 // wait for onCreated and reg state changed 2094 conn.setOperationCountDownLatch(2); 2095 conn.connect(manager); 2096 conn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2097 conn.verifyDelegateCreated(); 2098 conn.verifyRegistrationStateEmpty(); 2099 // All requested features should have been denied due to the app not being the default sms 2100 // app. 2101 conn.verifyAllDenied(SipDelegateManager.DENIED_REASON_NOT_ALLOWED); 2102 // There should not have been a call to create a SipDelegate on the service side, since all 2103 // features were denied due to permissions issues. 2104 assertEquals("SipDelegate should not have been created", 0, 2105 transport.getDelegates().size()); 2106 } 2107 destroySipDelegateConnectionNoDelegate(SipDelegateManager manager, TestSipDelegateConnection delegateConn)2108 private void destroySipDelegateConnectionNoDelegate(SipDelegateManager manager, 2109 TestSipDelegateConnection delegateConn) throws Exception { 2110 delegateConn.setOperationCountDownLatch(1); 2111 delegateConn.disconnect(manager, 2112 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2113 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2114 delegateConn.verifyDestroyed( 2115 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2116 } 2117 destroySipDelegate(SipDelegateManager manager, TestSipTransport transportImpl, TestSipDelegateConnection delegateConn, TestSipDelegate delegate)2118 private void destroySipDelegate(SipDelegateManager manager, 2119 TestSipTransport transportImpl, TestSipDelegateConnection delegateConn, 2120 TestSipDelegate delegate) throws Exception { 2121 delegateConn.disconnect(manager, 2122 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2123 transportImpl.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 2124 delegate.notifyOnDestroyed( 2125 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2126 2127 } 2128 destroySipDelegateAndVerifyConnDestroyed(SipDelegateManager manager, TestSipTransport transportImpl, TestSipDelegateConnection delegateConn, TestSipDelegate delegate)2129 private void destroySipDelegateAndVerifyConnDestroyed(SipDelegateManager manager, 2130 TestSipTransport transportImpl, TestSipDelegateConnection delegateConn, 2131 TestSipDelegate delegate) throws Exception { 2132 delegateConn.setOperationCountDownLatch(1); 2133 destroySipDelegate(manager, transportImpl, delegateConn, delegate); 2134 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2135 delegateConn.verifyDestroyed( 2136 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2137 } 2138 destroySipDelegateAndVerify(TransportInterfaces ifaces)2139 private void destroySipDelegateAndVerify(TransportInterfaces ifaces) throws Exception { 2140 // wait for on destroyed 2141 destroySipDelegateAndVerifyConnDestroyed(ifaces.manager, ifaces.transport, 2142 ifaces.delegateConn, ifaces.delegate); 2143 } 2144 verifySipDelegateDestroyed(TestSipTransport transportImpl, TestSipDelegate delegate)2145 private void verifySipDelegateDestroyed(TestSipTransport transportImpl, 2146 TestSipDelegate delegate) { 2147 transportImpl.waitForLatchCountdownAndReset(TestSipTransport.LATCH_DESTROY_DELEGATE); 2148 delegate.notifyOnDestroyed( 2149 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 2150 } 2151 createSipDelegateConnectionAndVerify(SipDelegateManager manager, TestSipDelegateConnection conn, TestSipTransport transport, Set<FeatureTagState> deniedTags, int delegateIndex)2152 private TestSipDelegate createSipDelegateConnectionAndVerify(SipDelegateManager manager, 2153 TestSipDelegateConnection conn, TestSipTransport transport, 2154 Set<FeatureTagState> deniedTags, int delegateIndex) throws Exception { 2155 conn.setOperationCountDownLatch(1); 2156 conn.connect(manager); 2157 TestSipDelegate d = getSipDelegate(transport, deniedTags, delegateIndex); 2158 conn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2159 conn.verifyDelegateCreated(); 2160 return d; 2161 } 2162 getSipDelegate(TestSipTransport transport, Set<FeatureTagState> deniedTags, int delegateIndex)2163 private TestSipDelegate getSipDelegate(TestSipTransport transport, 2164 Set<FeatureTagState> deniedTags, int delegateIndex) { 2165 transport.waitForLatchCountdownAndReset(TestSipTransport.LATCH_CREATE_DELEGATE); 2166 // There must have been a call to create a SipDelegate on the service side. 2167 assertEquals("SipDelegate should have been created", delegateIndex + 1, 2168 transport.getDelegates().size()); 2169 TestSipDelegate d = transport.getDelegates().get(delegateIndex); 2170 d.notifyOnCreated(deniedTags); 2171 return d; 2172 } 2173 verifyRegisteredAndSendSipConfig(TestSipDelegateConnection delegateConn, TestSipDelegate delegate, Set<String> registeredTags, Set<FeatureTagState> deniedTags, SipDelegateConfiguration sipConfig)2174 private void verifyRegisteredAndSendSipConfig(TestSipDelegateConnection delegateConn, 2175 TestSipDelegate delegate, Set<String> registeredTags, 2176 Set<FeatureTagState> deniedTags, SipDelegateConfiguration sipConfig) { 2177 // wait for reg change to be called 2178 delegateConn.setOperationCountDownLatch(1); 2179 DelegateRegistrationState s = getRegisteredRegistrationState(registeredTags); 2180 delegate.notifyImsRegistrationUpdate(s); 2181 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2182 delegateConn.verifyRegistrationStateRegistered(registeredTags); 2183 delegateConn.verifyDenied(deniedTags); 2184 2185 // send config change as well. 2186 sendConfigChange(sipConfig, delegateConn, delegate); 2187 } 2188 generateDeniedSetFromRequest(Set<String> grantedTags, Set<String> newTags, int reason)2189 private Set<FeatureTagState> generateDeniedSetFromRequest(Set<String> grantedTags, 2190 Set<String> newTags, int reason) { 2191 // Deny features from newTags that are already granted in grantedTags. 2192 return grantedTags.stream().filter(newTags::contains) 2193 .map(s -> new FeatureTagState(s, reason)) 2194 .collect(Collectors.toSet()); 2195 } 2196 verifyUpdateRegistrationCalled(TestImsRegistration regImpl)2197 private void verifyUpdateRegistrationCalled(TestImsRegistration regImpl) { 2198 regImpl.resetLatch(TestImsRegistration.LATCH_UPDATE_REGISTRATION, 1); 2199 // it is okay to reset and wait here (without race conditions) because there is a 2200 // second delay between triggering update registration and the latch being triggered. 2201 assertTrue(regImpl.waitForLatchCountDown(TestImsRegistration.LATCH_UPDATE_REGISTRATION, 2202 ImsUtils.TEST_TIMEOUT_MS)); 2203 } 2204 sendRestrictedRequestsAndVerifyFailed( TestSipDelegateConnection delegateConn)2205 private void sendRestrictedRequestsAndVerifyFailed( 2206 TestSipDelegateConnection delegateConn) throws Exception { 2207 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_INVALID_SIP_REGISTER, 2208 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE); 2209 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_INVALID_SIP_PUBLISH, 2210 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE); 2211 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_INVALID_SIP_OPTIONS, 2212 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE); 2213 delegateConn.sendMessageAndVerifyFailure( 2214 SipMessageUtils.TEST_INVALID_SIP_SUBSCRIBE_PRESENCE, 2215 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS); 2216 } 2217 verifyFullRegistrationTriggered(TransportInterfaces ifaces)2218 private void verifyFullRegistrationTriggered(TransportInterfaces ifaces) throws Exception { 2219 ifaces.delegateConn.verifyDelegateCreated(); 2220 ifaces.delegateConn.triggerFullNetworkRegistration(ifaces.manager, 403, "FORBIDDEN"); 2221 TestImsRegistration.NetworkRegistrationInfo info = 2222 ifaces.reg.getNextFullNetworkRegRequest(ImsUtils.TEST_TIMEOUT_MS); 2223 assertNotNull("full registration requested, but ImsRegistrationImplBase " 2224 + "implementation did not receive a request.", info); 2225 assertEquals(403, info.sipCode); 2226 assertEquals("FORBIDDEN", info.sipReason); 2227 } 2228 sendInvalidRequestsAndVerifyFailed( TestSipDelegateConnection delegateConn)2229 private void sendInvalidRequestsAndVerifyFailed( 2230 TestSipDelegateConnection delegateConn) throws Exception { 2231 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_SIP_MESSAGE_INVALID_REQUEST, 2232 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE); 2233 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_SIP_MESSAGE_INVALID_RESPONSE, 2234 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE); 2235 } 2236 verifyOutgoingTransport(TestSipDelegateConnection delegateConn, TestSipDelegate delegate)2237 private void verifyOutgoingTransport(TestSipDelegateConnection delegateConn, 2238 TestSipDelegate delegate) throws Exception { 2239 // Send a message and ensure it gets received on the other end as well as acked 2240 delegateConn.sendMessageAndVerifyCompletedSuccessfully(SipMessageUtils.TEST_SIP_MESSAGE); 2241 delegate.verifyMessageSend(SipMessageUtils.TEST_SIP_MESSAGE); 2242 delegateConn.sendCleanupSession(SipMessageUtils.TEST_SIP_MESSAGE.getCallIdParameter()); 2243 delegate.verifyCleanupSession(SipMessageUtils.TEST_SIP_MESSAGE.getCallIdParameter()); 2244 // send a message and notify connection that it failed 2245 delegate.setSendMessageDenyReason( 2246 SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE); 2247 delegateConn.sendMessageAndVerifyFailure(SipMessageUtils.TEST_SIP_MESSAGE, 2248 SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE); 2249 delegate.verifyMessageSend(SipMessageUtils.TEST_SIP_MESSAGE); 2250 } 2251 sendMessageAndVerifyAck(SipMessage message, TransportInterfaces ifaces)2252 private void sendMessageAndVerifyAck(SipMessage message, 2253 TransportInterfaces ifaces) throws Exception { 2254 // Send a message and ensure it gets received on the other end as well as acked 2255 ifaces.delegateConn.sendMessageAndVerifyCompletedSuccessfully(message); 2256 } 2257 verifyIncomingTransport(TestSipDelegateConnection delegateConn, TestSipDelegate delegate)2258 private void verifyIncomingTransport(TestSipDelegateConnection delegateConn, 2259 TestSipDelegate delegate) throws Exception { 2260 // Receive a message and ensure it gets received on the other end as well as acked 2261 delegate.receiveMessageAndVerifyReceivedCalled(SipMessageUtils.TEST_SIP_MESSAGE); 2262 delegateConn.verifyMessageReceived(SipMessageUtils.TEST_SIP_MESSAGE); 2263 // Receive a message and have connection notify that it didn't complete 2264 delegateConn.setReceivedMessageErrorResponseReason( 2265 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_BODY_CONTENT); 2266 delegate.receiveMessageAndVerifyReceiveErrorCalled(SipMessageUtils.TEST_SIP_MESSAGE, 2267 SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_BODY_CONTENT); 2268 } 2269 receiveMessageAndVerifyAck(SipMessage message, TransportInterfaces ifaces)2270 private void receiveMessageAndVerifyAck(SipMessage message, 2271 TransportInterfaces ifaces) throws Exception { 2272 // Receive a message and ensure it gets received on the other end as well as acked 2273 ifaces.delegate.receiveMessageAndVerifyReceivedCalled(message); 2274 ifaces.delegateConn.verifyMessageReceived(message); 2275 } 2276 verifyRegistrationState(TransportInterfaces ifaces, DelegateRegistrationState state)2277 private void verifyRegistrationState(TransportInterfaces ifaces, 2278 DelegateRegistrationState state) { 2279 ifaces.delegateConn.setOperationCountDownLatch(1); 2280 ifaces.delegate.notifyImsRegistrationUpdate(state); 2281 ifaces.delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2282 ifaces.delegateConn.verifyRegistrationStateEquals(state); 2283 } 2284 getDeregisteringState(Set<String> registered, Set<String> deregistering, int deregisteringReason)2285 private DelegateRegistrationState getDeregisteringState(Set<String> registered, 2286 Set<String> deregistering, int deregisteringReason) { 2287 DelegateRegistrationState.Builder b = new DelegateRegistrationState.Builder(); 2288 b.addRegisteredFeatureTags(registered); 2289 for (String dereg : deregistering) { 2290 b.addDeregisteringFeatureTag(dereg, deregisteringReason); 2291 } 2292 return b.build(); 2293 } 2294 sendConfigChange(SipDelegateConfiguration c, TestSipDelegateConnection delegateConn, TestSipDelegate delegate)2295 private void sendConfigChange(SipDelegateConfiguration c, 2296 TestSipDelegateConnection delegateConn, TestSipDelegate delegate) { 2297 delegateConn.setOperationCountDownLatch(1); 2298 delegate.notifyConfigurationUpdate(c); 2299 delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS); 2300 delegateConn.verifyConfigEquals(c); 2301 } 2302 2303 /** 2304 * @return A new test SipDelegateConfiguration that has all fields populated.1 2305 */ generateNewTestConfig()2306 private SipDelegateConfiguration generateNewTestConfig() { 2307 InetSocketAddress localAddr = new InetSocketAddress( 2308 InetAddresses.parseNumericAddress("1.1.1.1"), 80); 2309 InetSocketAddress serverAddr = new InetSocketAddress( 2310 InetAddresses.parseNumericAddress("2.2.2.2"), 81); 2311 SipDelegateConfiguration.Builder b = new SipDelegateConfiguration.Builder(1, 2312 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr); 2313 b.setSipCompactFormEnabled(true); 2314 b.setSipKeepaliveEnabled(true); 2315 b.setMaxUdpPayloadSizeBytes(508); 2316 b.setPublicUserIdentifier("test1"); 2317 b.setPrivateUserIdentifier("test2"); 2318 b.setHomeDomain("test.domain"); 2319 b.setImei("testImei"); 2320 b.setSipAuthenticationHeader("sipauth"); 2321 b.setSipAuthenticationNonce("sipnonce"); 2322 b.setSipServiceRouteHeader("srvroute"); 2323 b.setSipPathHeader("path"); 2324 b.setSipUserAgentHeader("ua"); 2325 b.setSipContactUserParameter("user"); 2326 b.setSipPaniHeader("pani"); 2327 b.setSipPlaniHeader("plani"); 2328 b.setSipCniHeader("cni"); 2329 b.setSipAssociatedUriHeader("uri"); 2330 Uri gruuUri = Uri.parse("sip:blah@gruu.net"); 2331 b.setPublicGruuUri(gruuUri); 2332 SipDelegateConfiguration.IpSecConfiguration ipSecConfig = 2333 new SipDelegateConfiguration.IpSecConfiguration(123, 124, 2334 125, 126, 127, 128, "secverify"); 2335 assertEquals(123, ipSecConfig.getLocalTxPort()); 2336 assertEquals(124, ipSecConfig.getLocalRxPort()); 2337 assertEquals(125, ipSecConfig.getLastLocalTxPort()); 2338 assertEquals(126, ipSecConfig.getRemoteTxPort()); 2339 assertEquals(127, ipSecConfig.getRemoteRxPort()); 2340 assertEquals(128, ipSecConfig.getLastRemoteTxPort()); 2341 assertEquals("secverify", ipSecConfig.getSipSecurityVerifyHeader()); 2342 b.setIpSecConfiguration(ipSecConfig); 2343 InetSocketAddress natAddr = new InetSocketAddress( 2344 InetAddresses.parseNumericAddress("3.3.3.3"), 129); 2345 b.setNatSocketAddress(natAddr); 2346 assertEquals("3.3.3.3", natAddr.getAddress().getHostAddress()); 2347 assertEquals(129, natAddr.getPort()); 2348 return b.build(); 2349 } 2350 getRegisteredRegistrationState(Set<String> registered)2351 private DelegateRegistrationState getRegisteredRegistrationState(Set<String> registered) { 2352 return new DelegateRegistrationState.Builder().addRegisteredFeatureTags(registered).build(); 2353 } 2354 getRegisteringRegistrationState(Set<String> registering)2355 private DelegateRegistrationState getRegisteringRegistrationState(Set<String> registering) { 2356 return new DelegateRegistrationState.Builder().addRegisteringFeatureTags(registering) 2357 .build(); 2358 } 2359 getDeregisteringState(Set<String> deregisterTags, int reason)2360 private DelegateRegistrationState getDeregisteringState(Set<String> deregisterTags, 2361 int reason) { 2362 DelegateRegistrationState.Builder b = new DelegateRegistrationState.Builder(); 2363 for (String t : deregisterTags) { 2364 b.addDeregisteringFeatureTag(t, reason); 2365 } 2366 return b.build(); 2367 } 2368 getDeregisteredState(Set<String> deregisterTags, int reason)2369 private DelegateRegistrationState getDeregisteredState(Set<String> deregisterTags, 2370 int reason) { 2371 DelegateRegistrationState.Builder b = new DelegateRegistrationState.Builder(); 2372 for (String t : deregisterTags) { 2373 b.addDeregisteredFeatureTag(t, reason); 2374 } 2375 return b.build(); 2376 } 2377 2378 connectTestImsServiceWithSipTransportAndConfig()2379 private void connectTestImsServiceWithSipTransportAndConfig() throws Exception { 2380 PersistableBundle b = new PersistableBundle(); 2381 b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true); 2382 overrideCarrierConfig(b); 2383 2384 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 2385 sServiceConnector.getCarrierService().addCapabilities( 2386 ImsService.CAPABILITY_SIP_DELEGATE_CREATION); 2387 sServiceConnector.getCarrierService().setSipTransportImplemented(); 2388 ImsFeatureConfiguration c = getConfigForMmTelAndRcs(); 2389 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 2390 verifyImsServiceState(c); 2391 } 2392 2393 connectTestImsServiceWithSipTransport()2394 private void connectTestImsServiceWithSipTransport() throws Exception { 2395 assertTrue(sServiceConnector.connectCarrierImsServiceLocally()); 2396 sServiceConnector.getCarrierService().addCapabilities( 2397 ImsService.CAPABILITY_SIP_DELEGATE_CREATION); 2398 sServiceConnector.getCarrierService().setSipTransportImplemented(); 2399 ImsFeatureConfiguration c = getConfigForMmTelAndRcs(); 2400 assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c)); 2401 verifyImsServiceState(c); 2402 } 2403 verifyImsServiceState(ImsFeatureConfiguration config)2404 private void verifyImsServiceState(ImsFeatureConfiguration config) { 2405 for (ImsFeatureConfiguration.FeatureSlotPair p : config.getServiceFeatures()) { 2406 switch (p.featureType) { 2407 case ImsFeature.FEATURE_MMTEL: { 2408 sServiceConnector.getCarrierService().waitForLatchCountdown( 2409 TestImsService.LATCH_CREATE_MMTEL); 2410 assertNotNull("ImsService created, but ImsService#createMmTelFeature was not " 2411 + "called!", sServiceConnector.getCarrierService().getMmTelFeature()); 2412 break; 2413 } 2414 case ImsFeature.FEATURE_RCS: { 2415 sServiceConnector.getCarrierService().waitForLatchCountdown( 2416 TestImsService.LATCH_CREATE_RCS); 2417 assertNotNull("ImsService created, but ImsService#createRcsFeature was not " 2418 + "called!", sServiceConnector.getCarrierService().getRcsFeature()); 2419 break; 2420 } 2421 } 2422 } 2423 } 2424 2425 /** 2426 * Wait up to five seconds (retrying a command 1 time per second) until ImsExceptions due to the 2427 * ImsService not being available go away. If the ImsService never becomes available, this 2428 * method will return null. 2429 */ callUntilImsServiceIsAvailable(Callable<T> command)2430 private <T> T callUntilImsServiceIsAvailable(Callable<T> command) throws Exception { 2431 int retry = 0; 2432 while (retry < 5) { 2433 try { 2434 return command.call(); 2435 } catch (ImsException e) { 2436 // we want to absorb only the unavailable error, as telephony may still be 2437 // internally setting up. Any other type of ImsException is unexpected. 2438 if (e.getCode() != ImsException.CODE_ERROR_SERVICE_UNAVAILABLE) { 2439 throw e; 2440 } 2441 } 2442 Thread.sleep(1000); 2443 retry++; 2444 } 2445 return null; 2446 } 2447 getDefaultRequest()2448 private DelegateRequest getDefaultRequest() { 2449 ArraySet<String> features = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS)); 2450 return new DelegateRequest(features); 2451 } 2452 getChatOnlyRequest()2453 private DelegateRequest getChatOnlyRequest() { 2454 ArraySet<String> features = new ArraySet<>(3); 2455 features.add(ONE_TO_ONE_CHAT_TAG); 2456 features.add(GROUP_CHAT_TAG); 2457 return new DelegateRequest(features); 2458 } 2459 getConfigForMmTelAndRcs()2460 private ImsFeatureConfiguration getConfigForMmTelAndRcs() { 2461 return new ImsFeatureConfiguration.Builder() 2462 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL) 2463 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL) 2464 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS) 2465 .build(); 2466 } 2467 getConfigForRcs()2468 private ImsFeatureConfiguration getConfigForRcs() { 2469 return new ImsFeatureConfiguration.Builder() 2470 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS) 2471 .build(); 2472 } 2473 getDeniedTagsForReason(Set<String> deniedTags, int reason)2474 private Set<FeatureTagState> getDeniedTagsForReason(Set<String> deniedTags, int reason) { 2475 return deniedTags.stream().map(t -> new FeatureTagState(t, reason)) 2476 .collect(Collectors.toSet()); 2477 } 2478 overrideCarrierConfig(PersistableBundle bundle)2479 private static void overrideCarrierConfig(PersistableBundle bundle) throws Exception { 2480 CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getInstrumentation() 2481 .getContext().getSystemService(CarrierConfigManager.class); 2482 sReceiver.clearQueue(); 2483 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(carrierConfigManager, 2484 (m) -> m.overrideConfig(sTestSub, bundle)); 2485 sReceiver.waitForCarrierConfigChanged(); 2486 } 2487 setFeatureTagsCarrierAllowed(String[] tags)2488 private static void setFeatureTagsCarrierAllowed(String[] tags) throws Exception { 2489 PersistableBundle bundle = new PersistableBundle(); 2490 bundle.putStringArray(CarrierConfigManager.Ims.KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY, 2491 tags); 2492 overrideCarrierConfig(bundle); 2493 } 2494 getSipDelegateManager()2495 private SipDelegateManager getSipDelegateManager() { 2496 ImsManager imsManager = getContext().getSystemService(ImsManager.class); 2497 assertNotNull(imsManager); 2498 return imsManager.getSipDelegateManager(sTestSub); 2499 } 2500 getContext()2501 private static Context getContext() { 2502 return InstrumentationRegistry.getInstrumentation().getContext(); 2503 } 2504 } 2505