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