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