1 /*
2  * Copyright (C) 2019 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.assertFalse;
20 import static junit.framework.Assert.assertNotNull;
21 import static junit.framework.Assert.assertNull;
22 import static junit.framework.Assert.assertTrue;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotEquals;
26 import static org.junit.Assert.fail;
27 
28 import android.app.Activity;
29 import android.app.UiAutomation;
30 import android.content.BroadcastReceiver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.net.Uri;
35 import android.os.PersistableBundle;
36 import android.telecom.PhoneAccount;
37 import android.telephony.AccessNetworkConstants;
38 import android.telephony.CarrierConfigManager;
39 import android.telephony.SmsManager;
40 import android.telephony.SmsMessage;
41 import android.telephony.SubscriptionManager;
42 import android.telephony.TelephonyManager;
43 import android.telephony.cts.AsyncSmsMessageListener;
44 import android.telephony.cts.CarrierCapability;
45 import android.telephony.cts.SmsReceiverHelper;
46 import android.telephony.ims.ImsException;
47 import android.telephony.ims.ImsManager;
48 import android.telephony.ims.ImsMmTelManager;
49 import android.telephony.ims.ImsRcsManager;
50 import android.telephony.ims.ImsReasonInfo;
51 import android.telephony.ims.ImsRegistrationAttributes;
52 import android.telephony.ims.ProvisioningManager;
53 import android.telephony.ims.RcsClientConfiguration;
54 import android.telephony.ims.RcsContactUceCapability;
55 import android.telephony.ims.RcsUceAdapter;
56 import android.telephony.ims.RegistrationManager;
57 import android.telephony.ims.RtpHeaderExtensionType;
58 import android.telephony.ims.feature.ImsFeature;
59 import android.telephony.ims.feature.MmTelFeature;
60 import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
61 import android.telephony.ims.stub.CapabilityExchangeEventListener;
62 import android.telephony.ims.stub.ImsConfigImplBase;
63 import android.telephony.ims.stub.ImsFeatureConfiguration;
64 import android.telephony.ims.stub.ImsRegistrationImplBase;
65 import android.util.ArraySet;
66 import android.util.Base64;
67 import android.util.Pair;
68 
69 import androidx.test.ext.junit.runners.AndroidJUnit4;
70 import androidx.test.platform.app.InstrumentationRegistry;
71 
72 import com.android.compatibility.common.util.ShellIdentityUtils;
73 
74 import org.junit.After;
75 import org.junit.AfterClass;
76 import org.junit.Assert;
77 import org.junit.Before;
78 import org.junit.BeforeClass;
79 import org.junit.Ignore;
80 import org.junit.Test;
81 import org.junit.runner.RunWith;
82 
83 import java.util.ArrayList;
84 import java.util.Arrays;
85 import java.util.Collection;
86 import java.util.Collections;
87 import java.util.List;
88 import java.util.Set;
89 import java.util.concurrent.CountDownLatch;
90 import java.util.concurrent.LinkedBlockingQueue;
91 import java.util.concurrent.TimeUnit;
92 
93 import android.util.Log;
94 
95 /**
96  * CTS tests for ImsService API.
97  */
98 @RunWith(AndroidJUnit4.class)
99 public class ImsServiceTest {
100 
101     private static ImsServiceConnector sServiceConnector;
102 
103     private static final int RCS_CAP_NONE = RcsImsCapabilities.CAPABILITY_TYPE_NONE;
104     private static final int RCS_CAP_OPTIONS = RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
105     private static final int RCS_CAP_PRESENCE = RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
106 
107     private static final String MSG_CONTENTS = "hi";
108     private static final String EXPECTED_RECEIVED_MESSAGE = "foo5";
109     private static final String DEST_NUMBER = "5555554567";
110     private static final String SRC_NUMBER = "5555551234";
111     private static final byte[] EXPECTED_PDU =
112             new byte[]{1, 0, 10, -127, 85, 85, 85, 33, 67, 0, 0, 2, -24, 52};
113     private static final String RECEIVED_MESSAGE = "B5EhYBMDIPgEC5FhBWKFkPEAAEGQQlGDUooE5ve7Bg==";
114     private static final byte[] STATUS_REPORT_PDU =
115             hexStringToByteArray("0006000681214365919061800000639190618000006300");
116 
117     private static int sTestSlot = 0;
118     private static int sTestSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
119     private static boolean sDeviceUceEnabled;
120 
121     private static final int TEST_CONFIG_KEY = 1000;
122     private static final int TEST_CONFIG_VALUE_INT = 0xDEADBEEF;
123     private static final String TEST_CONFIG_VALUE_STRING = "DEADBEEF";
124 
125     private static final String TEST_RCS_CONFIG_DEFAULT = "<?xml version=\"1.0\"?>\n"
126             + "<wap-provisioningdoc version=\"1.1\">\n"
127             + "\t<characteristic type=\"APPLICATION\">\n"
128             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
129             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
130             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
131             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
132             + "\t\t\t<characteristic type=\"Ext\">\n"
133             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
134             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
135             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"1\"/>\n"
136             + "\t\t\t\t</characteristic>\n"
137             + "\t\t\t</characteristic>\n"
138             + "\t\t</characteristic>\n"
139             + "\t\t<characteristic type=\"SERVICES\">\n"
140             + "\t\t\t<parm name=\"SupportedRCSProfileVersions\" value=\"UP2.3\"/>\n"
141             + "\t\t\t<parm name=\"ChatAuth\" value=\"1\"/>\n"
142             + "\t\t\t<parm name=\"GroupChatAuth\" value=\"1\"/>\n"
143             + "\t\t\t<parm name=\"ftAuth\" value=\"1\"/>\n"
144             + "\t\t\t<parm name=\"standaloneMsgAuth\" value=\"1\"/>\n"
145             + "\t\t\t<parm name=\"geolocPushAuth\" value=\"1\"/>\n"
146             + "\t\t\t<characteristic type=\"Ext\">\n"
147             + "\t\t\t\t<characteristic type=\"DataOff\">\n"
148             + "\t\t\t\t\t<parm name=\"rcsMessagingDataOff\" value=\"1\"/>\n"
149             + "\t\t\t\t\t<parm name=\"fileTransferDataOff\" value=\"1\"/>\n"
150             + "\t\t\t\t\t<parm name=\"mmsDataOff\" value=\"1\"/>\n"
151             + "\t\t\t\t\t<parm name=\"syncDataOff\" value=\"1\"/>\n"
152             + "\t\t\t\t\t<characteristic type=\"Ext\"/>\n"
153             + "\t\t\t\t</characteristic>\n"
154             + "\t\t\t</characteristic>\n"
155             + "\t\t</characteristic>\n"
156             + "\t</characteristic>\n"
157             + "</wap-provisioningdoc>\n";
158 
159     private static final String TEST_RCS_CONFIG_SINGLE_REGISTRATION_DISABLED =
160             "<?xml version=\"1.0\"?>\n"
161             + "<wap-provisioningdoc version=\"1.1\">\n"
162             + "\t<characteristic type=\"APPLICATION\">\n"
163             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
164             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
165             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
166             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
167             + "\t\t\t<characteristic type=\"Ext\">\n"
168             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
169             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
170             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"0\"/>\n"
171             + "\t\t\t\t</characteristic>\n"
172             + "\t\t\t</characteristic>\n"
173             + "\t\t</characteristic>\n"
174             + "\t</characteristic>\n"
175             + "</wap-provisioningdoc>\n";
176     private static final String TEST_RCS_PRE_CONFIG = "<RCSPreProvisiniongConfig>\n"
177             + "\t<VERS>\n"
178             + "\t\t<version>1</version>\n"
179             + "\t\t<validity>1728000</validity>\n"
180             + "\t</VERS>\n"
181             + "\t<TOKEN>\n"
182             + "\t\t<token>X</token>\n"
183             + "\t</TOKEN>\n"
184             + "\t<EXT>\n"
185             + "\t\t<url>https://rcs.mnc123.mcc456.pub.3gppnetwork.org</url>\n"
186             + "\t</EXT>\n"
187             + "</RCSPreProvisiniongConfig>";
188     private static final int RCS_CONFIG_CB_UNKNOWN = Integer.MAX_VALUE;
189     private static final int RCS_CONFIG_CB_CHANGED = 0;
190     private static final int RCS_CONFIG_CB_ERROR   = 1;
191     private static final int RCS_CONFIG_CB_RESET   = 2;
192     private static final int RCS_CONFIG_CB_DELETE  = 3;
193     private static final int RCS_CONFIG_CB_PREPROV = 4;
194 
195     private static final String CHAT_FEATURE_TAG =
196             "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"";
197     public static final String FILE_TRANSFER_FEATURE_TAG =
198             "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fthttp\"";
199     private static final String CHAT_SERVICE_ID =
200             "org.openmobilealliance:ChatSession";
201     private static final String FILE_TRANSFER_SERVICE_ID =
202             "org.openmobilealliance:File-Transfer-HTTP";
203 
204     private static CarrierConfigReceiver sReceiver;
205     private static SingleRegistrationCapabilityReceiver sSrcReceiver;
206 
207     private abstract static class BaseReceiver extends BroadcastReceiver {
208         protected CountDownLatch mLatch = new CountDownLatch(1);
209 
clearQueue()210         void clearQueue() {
211             mLatch = new CountDownLatch(1);
212         }
213 
waitForChanged()214         void waitForChanged() throws Exception {
215             mLatch.await(5000, TimeUnit.MILLISECONDS);
216         }
217     }
218 
219     private static class CarrierConfigReceiver extends BaseReceiver {
220         private final int mSubId;
221 
CarrierConfigReceiver(int subId)222         CarrierConfigReceiver(int subId) {
223             mSubId = subId;
224         }
225 
226         @Override
onReceive(Context context, Intent intent)227         public void onReceive(Context context, Intent intent) {
228             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
229                 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
230                 if (mSubId == subId) {
231                     mLatch.countDown();
232                 }
233             }
234         }
235     }
236 
237     private static class SingleRegistrationCapabilityReceiver extends BaseReceiver {
238         private int mCapability;
239 
240         @Override
onReceive(Context context, Intent intent)241         public void onReceive(Context context, Intent intent) {
242             if (ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE
243                     .equals(intent.getAction())) {
244                 mCapability = intent.getIntExtra(ProvisioningManager.EXTRA_STATUS,
245                         ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE
246                         | ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE);
247                 mLatch.countDown();
248             }
249         }
250 
getCapability()251         int getCapability() {
252             return mCapability;
253         }
254     }
255 
256     private static class RcsProvisioningCallbackParams {
257         byte[] mConfig;
258         Integer mErrorCode;
259         String mErrorString;
260     }
261 
262     @BeforeClass
beforeAllTests()263     public static void beforeAllTests() throws Exception {
264         if (!ImsUtils.shouldTestImsService()) {
265             return;
266         }
267 
268         TelephonyManager tm = (TelephonyManager) getContext()
269                 .getSystemService(Context.TELEPHONY_SERVICE);
270         sTestSub = ImsUtils.getPreferredActiveSubId();
271         sTestSlot = SubscriptionManager.getSlotIndex(sTestSub);
272         if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
273             return;
274         }
275         sServiceConnector = new ImsServiceConnector(InstrumentationRegistry.getInstrumentation());
276         // Remove all live ImsServices until after these tests are done
277         sServiceConnector.clearAllActiveImsServices(sTestSlot);
278         // Configure SMS receiver based on the Android version.
279         sServiceConnector.setDefaultSmsApp();
280 
281         // Save the original device uce enabled config and override it.
282         sDeviceUceEnabled = sServiceConnector.getDeviceUceEnabled();
283         sServiceConnector.setDeviceUceEnabled(true);
284 
285         sReceiver = new CarrierConfigReceiver(sTestSub);
286         IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
287         // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away.
288         InstrumentationRegistry.getInstrumentation().getContext()
289                 .registerReceiver(sReceiver, filter);
290 
291         sSrcReceiver = new SingleRegistrationCapabilityReceiver();
292         InstrumentationRegistry.getInstrumentation().getContext()
293                 .registerReceiver(sSrcReceiver, new IntentFilter(
294                         ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE));
295     }
296 
297     @AfterClass
afterAllTests()298     public static void afterAllTests() throws Exception {
299         if (!ImsUtils.shouldTestImsService()) {
300             return;
301         }
302         // Restore all ImsService configurations that existed before the test.
303         if (sServiceConnector != null) {
304             sServiceConnector.disconnectServices();
305             sServiceConnector.setDeviceUceEnabled(sDeviceUceEnabled);
306         }
307         sServiceConnector = null;
308 
309         // Ensure there are no CarrierConfig overrides as well as reset the ImsResolver in case the
310         // ImsService override changed in CarrierConfig while we were overriding it.
311         overrideCarrierConfig(null);
312 
313         if (sReceiver != null) {
314             InstrumentationRegistry.getInstrumentation().getContext().unregisterReceiver(sReceiver);
315             sReceiver = null;
316         }
317 
318         if (sSrcReceiver != null) {
319             InstrumentationRegistry.getInstrumentation()
320                     .getContext().unregisterReceiver(sSrcReceiver);
321             sSrcReceiver = null;
322         }
323     }
324 
325     @Before
beforeTest()326     public void beforeTest() throws Exception {
327         if (!ImsUtils.shouldTestImsService()) {
328             return;
329         }
330         TelephonyManager tm = (TelephonyManager) InstrumentationRegistry.getInstrumentation()
331                 .getContext().getSystemService(Context.TELEPHONY_SERVICE);
332         if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
333             fail("This test requires that there is a SIM in the device!");
334         }
335         // Correctness check: ensure that the subscription hasn't changed between tests.
336         int[] subs = SubscriptionManager.getSubId(sTestSlot);
337 
338         if (subs == null) {
339             fail("This test requires there is an active subscription in slot " + sTestSlot);
340         }
341         boolean isFound = false;
342         for (int sub : subs) {
343             isFound |= (sTestSub == sub);
344         }
345         if (!isFound) {
346             fail("Invalid state found: the test subscription in slot " + sTestSlot + " changed "
347                     + "during this test.");
348         }
349 
350         TestAcsClient.getInstance().reset();
351         sServiceConnector.setSingleRegistrationTestModeEnabled(true);
352     }
353 
354     @After
afterTest()355     public void afterTest() throws Exception {
356         if (!ImsUtils.shouldTestImsService()) {
357             return;
358         }
359         // Unbind the GTS ImsService after the test completes.
360         if (sServiceConnector != null) {
361             sServiceConnector.setSingleRegistrationTestModeEnabled(false);
362             sServiceConnector.disconnectCarrierImsService();
363             sServiceConnector.disconnectDeviceImsService();
364         }
365     }
366 
367     @Test
testCarrierImsServiceBindRcsFeature()368     public void testCarrierImsServiceBindRcsFeature() throws Exception {
369         if (!ImsUtils.shouldTestImsService()) {
370             return;
371         }
372         // Connect to the ImsService with the RCS feature.
373         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
374                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
375                 .build()));
376         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
377         // Framework did not call it.
378         sServiceConnector.getCarrierService().waitForLatchCountdown(
379                 TestImsService.LATCH_CREATE_RCS);
380         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
381                 sServiceConnector.getCarrierService().getRcsFeature());
382     }
383 
384     @Test
testCarrierImsServiceBindMmTelFeature()385     public void testCarrierImsServiceBindMmTelFeature() throws Exception {
386         if (!ImsUtils.shouldTestImsService()) {
387             return;
388         }
389         // Connect to the ImsService with the MmTel feature.
390         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
391                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
392                 .build()));
393         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
394         // Framework did not call it.
395         sServiceConnector.getCarrierService().waitForLatchCountdown(
396                 TestImsService.LATCH_CREATE_MMTEL);
397         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
398                 sServiceConnector.getCarrierService().getMmTelFeature());
399         // Wait for the framework to set the capabilities on the ImsService
400         sServiceConnector.getCarrierService().waitForLatchCountdown(
401                 TestImsService.LATCH_MMTEL_CAP_SET);
402     }
403 
404     @Test
testCarrierImsServiceBindRcsFeatureEnableDisableIms()405     public void testCarrierImsServiceBindRcsFeatureEnableDisableIms() throws Exception {
406         if (!ImsUtils.shouldTestImsService()) {
407             return;
408         }
409         // Connect to the ImsService with the RCS feature.
410         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
411                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
412                 .build()));
413         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
414         // Framework did not call it.
415         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
416                 TestImsService.LATCH_CREATE_RCS));
417 
418         //Enable IMS and ensure that we receive the call to enable IMS in the ImsService.
419         sServiceConnector.enableImsService(sTestSlot);
420         // Wait for command in ImsService
421         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
422                 TestImsService.LATCH_ENABLE_IMS));
423         assertTrue(sServiceConnector.getCarrierService().isEnabled());
424 
425         //Disable IMS and ensure that we receive the call to enable IMS in the ImsService.
426         sServiceConnector.disableImsService(sTestSlot);
427         // Wait for command in ImsService
428         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
429                 TestImsService.LATCH_DISABLE_IMS));
430         assertFalse(sServiceConnector.getCarrierService().isEnabled());
431     }
432 
433     @Test
testCarrierImsServiceBindRcsChangeToMmtel()434     public void testCarrierImsServiceBindRcsChangeToMmtel() throws Exception {
435         if (!ImsUtils.shouldTestImsService()) {
436             return;
437         }
438         // Connect to the ImsService with the RCS feature.
439         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
440                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
441                 .build()));
442         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
443         // Framework did not call it.
444         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
445                 TestImsService.LATCH_CREATE_RCS));
446 
447         // Change the supported feature to MMTEl
448         sServiceConnector.getCarrierService().getImsService().onUpdateSupportedImsFeatures(
449                 new ImsFeatureConfiguration.Builder()
450                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL).build());
451 
452         // createMmTelFeature should be called.
453         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
454                 TestImsService.LATCH_CREATE_MMTEL));
455 
456         // Wait for the framework to set the capabilities on the ImsService
457         sServiceConnector.getCarrierService().waitForLatchCountdown(
458                 TestImsService.LATCH_MMTEL_CAP_SET);
459     }
460 
461     @Test
testCarrierImsServiceBindMmTelNoEmergency()462     public void testCarrierImsServiceBindMmTelNoEmergency() throws Exception {
463         if (!ImsUtils.shouldTestImsService()) {
464             return;
465         }
466         // Connect to the ImsService with the MMTEL feature.
467         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
468                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
469                 .build()));
470         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
471         // Framework did not call it.
472         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
473                 TestImsService.LATCH_CREATE_MMTEL));
474         // Wait for the framework to set the capabilities on the ImsService
475         sServiceConnector.getCarrierService().waitForLatchCountdown(
476                 TestImsService.LATCH_MMTEL_CAP_SET);
477     }
478 
479     @Test
testCarrierImsServiceBindMmTelEmergencyEnabled()480     public void testCarrierImsServiceBindMmTelEmergencyEnabled() throws Exception {
481         if (!ImsUtils.shouldTestImsService()) {
482             return;
483         }
484         // Connect to the ImsService with the MMTEL feature.
485         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
486                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
487                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
488                 .build()));
489         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
490         // Framework did not call it.
491         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
492                 TestImsService.LATCH_CREATE_MMTEL));
493         // Wait for the framework to set the capabilities on the ImsService
494         sServiceConnector.getCarrierService().waitForLatchCountdown(
495                 TestImsService.LATCH_MMTEL_CAP_SET);
496     }
497 
498     @Test
testCarrierImsServiceBindNullRcsFeature()499     public void testCarrierImsServiceBindNullRcsFeature() throws Exception {
500         if (!ImsUtils.shouldTestImsService()) {
501             return;
502         }
503         // Connect to the ImsService with the RCS feature.
504         ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
505                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
506                 .build();
507         assertTrue(sServiceConnector.connectCarrierImsServiceLocally());
508         sServiceConnector.getCarrierService().resetState();
509         sServiceConnector.getCarrierService().setNullRcsBinding();
510         assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(config));
511 
512         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
513         // Framework did not call it.
514         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
515                 TestImsService.LATCH_CREATE_RCS));
516         // Check to see if telephony state was reset at some point due to a crash and fail if so
517         assertFalse("ImsService should not crash if there is a null ImsFeature returned",
518                 ImsUtils.retryUntilTrue(() ->
519                         !sServiceConnector.isCarrierServiceStillConfigured(),
520                 5000 /*test timeout*/, 5 /*num times*/));
521     }
522 
523     @Test
testDeviceImsServiceBindRcsFeature()524     public void testDeviceImsServiceBindRcsFeature() throws Exception {
525         if (!ImsUtils.shouldTestImsService()) {
526             return;
527         }
528         // Connect to the ImsService with the RCS feature.
529         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
530                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
531                 .build()));
532         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
533         // Framework did not call it.
534         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
535                 TestImsService.LATCH_CREATE_RCS));
536         // Make sure the RcsFeature was created in the test service.
537         assertTrue("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
538                         + "called!", sServiceConnector.getExternalService().isRcsFeatureCreated());
539     }
540 
541     @Test
testBindDeviceAndCarrierDifferentFeatures()542     public void testBindDeviceAndCarrierDifferentFeatures() throws Exception {
543         if (!ImsUtils.shouldTestImsService()) {
544             return;
545         }
546         // Connect to Device the ImsService with the MMTEL/EMERGENCY_MMTEL feature.
547         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
548                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
549                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
550                 .build()));
551         // Connect to Device the ImsService with the RCS feature.
552         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
553                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
554                 .build()));
555         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
556         // Framework did not call it.
557         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
558                 TestImsService.LATCH_CREATE_MMTEL));
559         // Make sure the MmTelFeature was created in the test service.
560         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was"
561                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
562 
563         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
564                 TestImsService.LATCH_CREATE_RCS));
565         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
566                 sServiceConnector.getCarrierService().getRcsFeature());
567     }
568 
569     @Test
testBindDeviceAndCarrierSameFeature()570     public void testBindDeviceAndCarrierSameFeature() throws Exception {
571         if (!ImsUtils.shouldTestImsService()) {
572             return;
573         }
574         // Connect to Device the ImsService with the RCS feature.
575         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
576                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
577                 .build()));
578 
579         //First MMTEL feature is created on device ImsService.
580         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
581                 TestImsService.LATCH_CREATE_MMTEL));
582         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was "
583                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
584 
585         // Connect to Device the ImsService with the MMTEL feature.
586         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
587                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
588                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
589                 .build()));
590 
591         // Next MMTEL feature is created on carrier ImsService (and unbound on device)
592         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
593                 TestImsService.LATCH_CREATE_MMTEL));
594         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
595                 sServiceConnector.getCarrierService().getMmTelFeature());
596 
597         // Ensure that the MmTelFeature was removed on the device ImsService.
598         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
599                 TestImsService.LATCH_REMOVE_MMTEL));
600         assertFalse("Device ImsService was never removed when carrier ImsService took MMTEL."
601                 + "feature.", sServiceConnector.getExternalService().isMmTelFeatureCreated());
602     }
603 
604     @Test
testBindDeviceAndCarrierUpdateToSameFeature()605     public void testBindDeviceAndCarrierUpdateToSameFeature() throws Exception {
606         if (!ImsUtils.shouldTestImsService()) {
607             return;
608         }
609         // Connect to Device the ImsService with the MMTEL feature.
610         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
611                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
612                 .build()));
613 
614         //First MMTEL feature is created on device ImsService.
615         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
616                 TestImsService.LATCH_CREATE_MMTEL));
617         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was"
618                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
619 
620         // Connect to Device the ImsService with the RCS feature.
621         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
622                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
623                 .build()));
624 
625         // Next Rcs feature is created on carrier ImsService
626         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
627                 TestImsService.LATCH_CREATE_RCS));
628         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
629                 sServiceConnector.getCarrierService().getRcsFeature());
630 
631         // Change the supported feature to MMTEl
632         sServiceConnector.getCarrierService().getImsService().onUpdateSupportedImsFeatures(
633                 new ImsFeatureConfiguration.Builder()
634                         .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
635                         .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
636                         .build());
637 
638         // MMTEL feature is created on carrier ImsService
639         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
640                 TestImsService.LATCH_CREATE_MMTEL));
641         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
642                 sServiceConnector.getCarrierService().getMmTelFeature());
643 
644         // Ensure that the MmTelFeature was removed on the device ImsService.
645         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
646                 TestImsService.LATCH_REMOVE_MMTEL));
647         assertFalse("Device ImsService was never removed when carrier ImsService took MMTEL."
648                 + "feature.", sServiceConnector.getExternalService().isMmTelFeatureCreated());
649 
650         // Ensure that the RcsFeature was removed on the carrier ImsService.
651         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
652                 TestImsService.LATCH_REMOVE_RCS));
653         assertNull(sServiceConnector.getCarrierService().getRcsFeature());
654     }
655 
656     @Test
testMmTelSendSms()657     public void testMmTelSendSms() throws Exception {
658         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
659             return;
660         }
661 
662         setupImsServiceForSms();
663         // Send Message with sent PendingIntent requested
664         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
665                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
666                         InstrumentationRegistry.getInstrumentation().getTargetContext()), null);
667         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
668                 .getSmsImplementation().waitForMessageSentLatch());
669 
670         // Wait for send PendingIntent
671         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
672                 ImsUtils.TEST_TIMEOUT_MS);
673         assertNotNull("SMS send PendingIntent never received", intent);
674         assertEquals("SMS send PendingIntent should have result RESULT_OK",
675                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
676                         Activity.RESULT_CANCELED));
677 
678         // Ensure we receive correct PDU on the other side.
679         Assert.assertArrayEquals(EXPECTED_PDU, sServiceConnector.getCarrierService()
680                 .getMmTelFeature().getSmsImplementation().sentPdu);
681     }
682 
683     @Test
testMmTelSendSmsDeliveryReportQCompat()684     public void testMmTelSendSmsDeliveryReportQCompat() throws Exception {
685         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
686             return;
687         }
688 
689         setupImsServiceForSms();
690         // Send Message with sent PendingIntent requested
691         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
692                 DEST_NUMBER, MSG_CONTENTS, null, SmsReceiverHelper.getMessageDeliveredPendingIntent(
693                         InstrumentationRegistry.getInstrumentation().getTargetContext()));
694         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
695                 .getSmsImplementation().waitForMessageSentLatch());
696 
697         // Ensure we receive correct PDU on the other side.
698         // Set TP-Status-Report-Request bit as well for this case.
699         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
700         pduWithStatusReport[0] |= 0x20;
701         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
702                 .getMmTelFeature().getSmsImplementation().sentPdu);
703 
704         // Ensure the API works on Q as well as in R+, where it was deprecated.
705         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
706                 .sendReportWaitForAcknowledgeSmsReportPQ(0, SmsMessage.FORMAT_3GPP,
707                         STATUS_REPORT_PDU);
708 
709         // Wait for delivered PendingIntent
710         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageDeliveredIntent(
711                 ImsUtils.TEST_TIMEOUT_MS);
712         assertNotNull("SMS delivered PendingIntent never received", intent);
713         assertEquals("SMS delivered PendingIntent should have result RESULT_OK",
714                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
715                         Activity.RESULT_CANCELED));
716     }
717 
718     @Test
testMmTelSendSmsDeliveryReportR()719     public void testMmTelSendSmsDeliveryReportR() throws Exception {
720         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
721             return;
722         }
723 
724         setupImsServiceForSms();
725         // Send Message with sent PendingIntent requested
726         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
727                 DEST_NUMBER, MSG_CONTENTS, null, SmsReceiverHelper.getMessageDeliveredPendingIntent(
728                         InstrumentationRegistry.getInstrumentation().getTargetContext()));
729         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
730                 .getSmsImplementation().waitForMessageSentLatch());
731 
732         // Ensure we receive correct PDU on the other side.
733         // Set TP-Status-Report-Request bit as well for this case.
734         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
735         pduWithStatusReport[0] |= 0x20;
736         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
737                 .getMmTelFeature().getSmsImplementation().sentPdu);
738 
739         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
740                 .sendReportWaitForAcknowledgeSmsReportR(123456789, SmsMessage.FORMAT_3GPP,
741                         STATUS_REPORT_PDU);
742 
743         // Wait for delivered PendingIntent
744         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageDeliveredIntent(
745                 ImsUtils.TEST_TIMEOUT_MS);
746         assertNotNull("SMS delivered PendingIntent never received", intent);
747         assertEquals("SMS delivered PendingIntent should have result RESULT_OK",
748                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
749                         Activity.RESULT_CANCELED));
750     }
751 
752     @Test
testMmTelSendSmsRSuccess()753     public void testMmTelSendSmsRSuccess() throws Exception {
754         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
755             return;
756         }
757 
758         setupImsServiceForSms();
759 
760         // Send Message
761         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
762                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
763                         InstrumentationRegistry.getInstrumentation().getTargetContext()), null);
764         // Use R specific API for sending SMS result
765         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
766                 .getSmsImplementation().waitForMessageSentLatchSuccess());
767         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
768                 ImsUtils.TEST_TIMEOUT_MS);
769         assertNotNull(intent);
770         assertEquals(Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
771                     Activity.RESULT_CANCELED));
772 
773         // Ensure we receive correct PDU on the other side.
774         Assert.assertArrayEquals(EXPECTED_PDU, sServiceConnector.getCarrierService()
775                 .getMmTelFeature().getSmsImplementation().sentPdu);
776     }
777 
778     @Test
testMmTelSendSmsNetworkError()779     public void testMmTelSendSmsNetworkError() throws Exception {
780         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
781             return;
782         }
783 
784         setupImsServiceForSms();
785 
786         // Send Message
787         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
788                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
789                         InstrumentationRegistry.getInstrumentation().getContext()), null);
790         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
791                 .getSmsImplementation().waitForMessageSentLatchError(
792                         SmsManager.RESULT_ERROR_GENERIC_FAILURE, 41));
793         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
794                 ImsUtils.TEST_TIMEOUT_MS);
795         assertNotNull(intent);
796         // In the case of error, the PendingIntent result will not report OK
797         assertNotEquals(Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
798                 Activity.RESULT_OK));
799         // make sure the "errorCode" extra contains the network error code returned by the
800         // ImsService.
801         assertEquals(41, intent.getIntExtra("errorCode", 0));
802 
803         // Ensure we receive correct PDU on the other side.
804         Assert.assertArrayEquals(EXPECTED_PDU, sServiceConnector.getCarrierService()
805                 .getMmTelFeature().getSmsImplementation().sentPdu);
806     }
807 
808     @Test
testMmTelReceiveSms()809     public void testMmTelReceiveSms() throws Exception {
810         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
811             return;
812         }
813 
814         setupImsServiceForSms();
815 
816         // Message received
817         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
818                 .receiveSmsWaitForAcknowledge(123456789, SmsMessage.FORMAT_3GPP,
819                         Base64.decode(RECEIVED_MESSAGE, Base64.DEFAULT));
820 
821         // Wait for SMS received intent and ensure it is correct.
822         String receivedMessage = AsyncSmsMessageListener.getInstance()
823                 .waitForSmsMessage(ImsUtils.TEST_TIMEOUT_MS);
824         assertEquals(EXPECTED_RECEIVED_MESSAGE, receivedMessage);
825     }
826 
827     @Test
testGetFeatureState()828     public void testGetFeatureState() throws Exception {
829         if (!ImsUtils.shouldTestImsService()) {
830             return;
831         }
832         // This will set feature state to ready
833         triggerFrameworkConnectToCarrierImsService();
834 
835         Integer result = getFeatureState();
836         assertNotNull(result);
837         assertEquals("ImsService state should be STATE_READY",
838                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
839                 ImsFeature.STATE_READY);
840         assertTrue("ImsService state is ready, but STATE_READY is not reported.",
841                 ImsUtils.retryUntilTrue(() -> (getFeatureState() == ImsFeature.STATE_READY)));
842 
843         sServiceConnector.getCarrierService().getMmTelFeature().setFeatureState(
844                 ImsFeature.STATE_INITIALIZING);
845         result = getFeatureState();
846         assertNotNull(result);
847         assertEquals("ImsService state should be STATE_INITIALIZING",
848                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
849                 ImsFeature.STATE_INITIALIZING);
850         assertTrue("ImsService state is initializing, but STATE_INITIALIZING is not reported.",
851                 ImsUtils.retryUntilTrue(
852                         () -> (getFeatureState() == ImsFeature.STATE_INITIALIZING)));
853 
854         sServiceConnector.getCarrierService().getMmTelFeature().setFeatureState(
855                 ImsFeature.STATE_UNAVAILABLE);
856         result = getFeatureState();
857         assertNotNull(result);
858         assertEquals("ImsService state should be STATE_UNAVAILABLE",
859                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
860                 ImsFeature.STATE_UNAVAILABLE);
861         assertTrue("ImsService state is unavailable, but STATE_UNAVAILABLE is not reported.",
862                 ImsUtils.retryUntilTrue(
863                         () -> (getFeatureState() == ImsFeature.STATE_UNAVAILABLE)));
864     }
865 
getFeatureState()866     private Integer getFeatureState() throws Exception {
867         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
868         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
869         LinkedBlockingQueue<Integer> state = new LinkedBlockingQueue<>(1);
870         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mmTelManager,
871                 (m) -> m.getFeatureState(Runnable::run, state::offer), ImsException.class);
872         return state.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
873     }
874 
875     @Test
testMmTelManagerRegistrationCallbackS()876     public void testMmTelManagerRegistrationCallbackS() throws Exception {
877         if (!ImsUtils.shouldTestImsService()) {
878             return;
879         }
880 
881         final ArraySet<String> featureTags = new ArraySet<>();
882         featureTags.add("featureTag1");
883         featureTags.add("featureTag2");
884 
885         triggerFrameworkConnectToCarrierImsService();
886 
887         // Start deregistered
888         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
889                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
890                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
891 
892         LinkedBlockingQueue<ImsRegistrationAttributes> mRegQueue =
893                 new LinkedBlockingQueue<>();
894         LinkedBlockingQueue<ImsReasonInfo> mDeregQueue =
895                 new LinkedBlockingQueue<>();
896         RegistrationManager.RegistrationCallback callback =
897                 new RegistrationManager.RegistrationCallback() {
898             @Override
899             public void onRegistered(ImsRegistrationAttributes attributes) {
900                 mRegQueue.offer(attributes);
901             }
902 
903             @Override
904             public void onRegistering(ImsRegistrationAttributes attributes) {
905                 mRegQueue.offer(attributes);
906             }
907 
908             @Override
909             public void onUnregistered(ImsReasonInfo info) {
910                 mDeregQueue.offer(info);
911             }
912         };
913 
914         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
915         try {
916             // First try without the correct permissions.
917             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
918             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
919             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
920             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
921         } catch (SecurityException e) {
922             //expected
923         }
924 
925         // Latch will count down here (we callback on the state during registration).
926         try {
927             automan.adoptShellPermissionIdentity();
928             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
929             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
930             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
931         } finally {
932             automan.dropShellPermissionIdentity();
933         }
934         ImsReasonInfo deregResult = waitForResult(mDeregQueue);
935         assertNotNull(deregResult);
936         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, deregResult.getCode());
937 
938         // Start registration
939         verifyRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_LTE, featureTags, mRegQueue,
940                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
941 
942         // move to NR
943         verifyRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_NR, featureTags, mRegQueue,
944                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
945 
946         // move to cross sim
947         verifyRegistering(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM, featureTags,
948                 mRegQueue, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
949                 ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET);
950 
951         // Complete registration
952         verifyRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_LTE, featureTags, mRegQueue,
953                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
954 
955         // move to NR
956         verifyRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_NR, featureTags, mRegQueue,
957                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
958 
959         // move to cross sim
960         verifyRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM, featureTags,
961                 mRegQueue, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
962                 ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET);
963 
964         try {
965             automan.adoptShellPermissionIdentity();
966             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
967             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
968             mmTelManager.unregisterImsRegistrationCallback(callback);
969         } finally {
970             automan.dropShellPermissionIdentity();
971         }
972 
973         try {
974             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
975             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
976             mmTelManager.unregisterImsRegistrationCallback(callback);
977             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
978         } catch (SecurityException e) {
979             //expected
980         }
981     }
982 
983     @Test
testMmTelManagerRegistrationCallback()984     public void testMmTelManagerRegistrationCallback() throws Exception {
985         if (!ImsUtils.shouldTestImsService()) {
986             return;
987         }
988 
989         triggerFrameworkConnectToCarrierImsService();
990 
991         // Start deregistered
992         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
993                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
994                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
995 
996         // This is a little bit gross looking, but on P devices, I can not define classes that
997         // extend ImsMmTelManager.RegistrationCallback (because it doesn't exist), so this has to
998         // happen as an anon class here.
999         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
1000         ImsMmTelManager.RegistrationCallback callback = new ImsMmTelManager.RegistrationCallback() {
1001             @Override
1002             public void onRegistered(int imsTransportType) {
1003                 mQueue.offer(imsTransportType);
1004             }
1005 
1006             @Override
1007             public void onRegistering(int imsTransportType) {
1008                 mQueue.offer(imsTransportType);
1009             }
1010 
1011             @Override
1012             public void onUnregistered(ImsReasonInfo info) {
1013                 mQueue.offer(info.getCode());
1014             }
1015 
1016             @Override
1017             public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
1018                 mQueue.offer(imsTransportType);
1019                 mQueue.offer(info.getCode());
1020             }
1021         };
1022 
1023         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1024         try {
1025             // First try without the correct permissions.
1026             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1027             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1028             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1029             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1030         } catch (SecurityException e) {
1031             //expected
1032         }
1033 
1034         // Latch will count down here (we callback on the state during registration).
1035         try {
1036             automan.adoptShellPermissionIdentity();
1037             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1038             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1039             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1040         } finally {
1041             automan.dropShellPermissionIdentity();
1042         }
1043         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
1044 
1045 
1046         // Start registration
1047         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
1048                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1049         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
1050 
1051         // Complete registration
1052         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1053                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1054         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
1055 
1056         // Fail handover to IWLAN
1057         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
1058                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
1059                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
1060                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
1061         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
1062         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
1063 
1064         // Ensure null ImsReasonInfo still results in non-null callback value.
1065         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
1066                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, null);
1067         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
1068         assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
1069 
1070         // Ensure null ImsReasonInfo still results in non-null callback.
1071         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(null);
1072         assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
1073 
1074         try {
1075             automan.adoptShellPermissionIdentity();
1076             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1077             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1078             mmTelManager.unregisterImsRegistrationCallback(callback);
1079         } finally {
1080             automan.dropShellPermissionIdentity();
1081         }
1082 
1083         try {
1084             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1085             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1086             mmTelManager.unregisterImsRegistrationCallback(callback);
1087             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1088         } catch (SecurityException e) {
1089             //expected
1090         }
1091     }
1092 
1093     @Test
testRcsDeviceCapabilitiesPublish()1094     public void testRcsDeviceCapabilitiesPublish() throws Exception {
1095         if (!ImsUtils.shouldTestImsService()) {
1096             return;
1097         }
1098         // Trigger carrier config changed
1099         PersistableBundle bundle = new PersistableBundle();
1100         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1101         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1102         overrideCarrierConfig(bundle);
1103 
1104         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1105         if (imsManager == null) {
1106             fail("Cannot find IMS service");
1107         }
1108 
1109         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1110         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1111 
1112         // Connect to device ImsService with MmTel feature and RCS feature
1113         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1114 
1115         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1116                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1117 
1118         // Register the callback to listen to the publish state changed
1119         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1120         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1121                 new RcsUceAdapter.OnPublishStateChangedListener() {
1122                     public void onPublishStateChange(int state) {
1123                         publishStateQueue.offer(state);
1124                     }
1125                 };
1126 
1127         // Another publish register callback to verify the API
1128         // RcsUceAdapter#removeOnPublishStateChangedListener
1129         LinkedBlockingQueue<Integer> unregisteredPublishStateQueue = new LinkedBlockingQueue<>();
1130         RcsUceAdapter.OnPublishStateChangedListener unregisteredPublishStateCallback =
1131                 new RcsUceAdapter.OnPublishStateChangedListener() {
1132                     public void onPublishStateChange(int state) {
1133                         unregisteredPublishStateQueue.offer(state);
1134                     }
1135                 };
1136 
1137         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1138         try {
1139             automan.adoptShellPermissionIdentity();
1140             // register two publish state callback
1141             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1142                     publishStateCallback);
1143             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1144                     unregisteredPublishStateCallback);
1145         } finally {
1146             automan.dropShellPermissionIdentity();
1147         }
1148 
1149         // Verify receiving the publish state callback immediately after registering the callback.
1150         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1151                 waitForIntResult(publishStateQueue));
1152         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1153                 waitForIntResult(unregisteredPublishStateQueue));
1154         publishStateQueue.clear();
1155         unregisteredPublishStateQueue.clear();
1156 
1157         // Verify the value of getting from the API is NOT_PUBLISHED
1158         try {
1159             automan.adoptShellPermissionIdentity();
1160             int publishState = uceAdapter.getUcePublishState();
1161             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1162         } finally {
1163             automan.dropShellPermissionIdentity();
1164         }
1165 
1166         // Setup the operation of the publish request.
1167         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1168             int networkResp = 200;
1169             String reason = "";
1170             cb.onNetworkResponse(networkResp, reason);
1171             listener.onPublish();
1172         });
1173 
1174         // Unregister the publish state callback
1175         try {
1176             automan.adoptShellPermissionIdentity();
1177             uceAdapter.removeOnPublishStateChangedListener(unregisteredPublishStateCallback);
1178         } finally {
1179             automan.dropShellPermissionIdentity();
1180         }
1181 
1182         // IMS registers
1183         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1184                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1185 
1186         // Framework should not trigger the device capabilities publish when the framework doesn't
1187         // receive that the RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE is enabled.
1188         if (publishStateQueue.poll() != null) {
1189             fail("The publish callback should not be called because presence uce is not ready");
1190         }
1191         if (unregisteredPublishStateQueue.poll() != null) {
1192             fail("The de-registered publish callback should not be called");
1193         }
1194 
1195         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1196         RcsImsCapabilities capabilities =
1197                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1198         sServiceConnector.getCarrierService().getRcsFeature()
1199                 .notifyCapabilitiesStatusChanged(capabilities);
1200 
1201         CapabilityExchangeEventListener eventListener =
1202                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1203 
1204         // ImsService triggers to notify framework publish device's capabilities.
1205         eventListener.onRequestPublishCapabilities(
1206                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1207 
1208         // Verify ImsService receive the publish request from framework.
1209         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1210                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1211         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1212         publishStateQueue.clear();
1213 
1214         // Verify the value of getting from the API is PUBLISH_STATE_OK
1215         try {
1216             automan.adoptShellPermissionIdentity();
1217             int publishState = uceAdapter.getUcePublishState();
1218             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1219         } finally {
1220             automan.dropShellPermissionIdentity();
1221         }
1222 
1223         // ImsService triggers to notify framework publish device's capabilities.
1224         eventListener.onRequestPublishCapabilities(
1225                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1226 
1227         // Verify ImsService receive the publish request from framework.
1228         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1229                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1230 
1231         // ImsService triggers the unpublish notification
1232         eventListener.onUnpublish();
1233 
1234         // Verify the publish state callback will be called with the state "NOT_PUBLISHED"
1235         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1236                 waitForIntResult(publishStateQueue));
1237         publishStateQueue.clear();
1238 
1239         // The unregistered callback should not be called.
1240         if (unregisteredPublishStateQueue.poll() != null) {
1241             fail("The de-registered publish callback should not be called when unpublish");
1242         }
1243 
1244         // Verify the value of getting from the API is NOT_PUBLISHED
1245         try {
1246             automan.adoptShellPermissionIdentity();
1247             int publishState = uceAdapter.getUcePublishState();
1248             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1249         } finally {
1250             automan.dropShellPermissionIdentity();
1251         }
1252 
1253         // Trigger RcsFeature is unavailable
1254         sServiceConnector.getCarrierService().getRcsFeature()
1255                 .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
1256 
1257         // Verify the RcsCapabilityExchangeImplBase will be removed.
1258         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1259                 TestImsService.LATCH_UCE_LISTENER_SET));
1260 
1261         overrideCarrierConfig(null);
1262     }
1263 
1264     @Test
testPublishImsReg()1265     public void testPublishImsReg() throws Exception {
1266         if (!ImsUtils.shouldTestImsService()) {
1267             return;
1268         }
1269         // Trigger carrier config changed
1270         PersistableBundle bundle = new PersistableBundle();
1271         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1272         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1273         overrideCarrierConfig(bundle);
1274 
1275         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1276         if (imsManager == null) {
1277             fail("Cannot find IMS service");
1278         }
1279 
1280         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1281         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1282 
1283         // Connect to device ImsService with MmTel feature and RCS feature
1284         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1285 
1286         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1287                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1288 
1289         // Register the callback to listen to the publish state changed
1290         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1291         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1292                 publishStateQueue::offer;
1293 
1294         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1295         try {
1296             automan.adoptShellPermissionIdentity();
1297             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1298                     publishStateCallback);
1299         } finally {
1300             automan.dropShellPermissionIdentity();
1301         }
1302 
1303         // Verify receiving the publish state callback immediately after registering the callback.
1304         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1305                 waitForIntResult(publishStateQueue));
1306         publishStateQueue.clear();
1307 
1308         LinkedBlockingQueue<String> pidfQueue = new LinkedBlockingQueue<>();
1309         // Setup the operation of the publish request.
1310         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1311             pidfQueue.offer(pidfXml);
1312             int networkResp = 200;
1313             String reason = "";
1314             cb.onNetworkResponse(networkResp, reason);
1315             listener.onPublish();
1316         });
1317 
1318         LinkedBlockingQueue<ImsRegistrationAttributes> mQueue = new LinkedBlockingQueue<>();
1319         RegistrationManager.RegistrationCallback callback =
1320                 new RegistrationManager.RegistrationCallback() {
1321                     @Override
1322                     public void onRegistered(ImsRegistrationAttributes attr) {
1323                         mQueue.offer(attr);
1324                     }
1325 
1326                     @Override
1327                     public void onRegistering(ImsRegistrationAttributes attr) {}
1328 
1329                     @Override
1330                     public void onUnregistered(ImsReasonInfo info) {}
1331 
1332                     @Override
1333                     public void onTechnologyChangeFailed(int type, ImsReasonInfo info) {}
1334                 };
1335         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
1336                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
1337                 ImsException.class);
1338 
1339         // IMS registers
1340         ArraySet<String> featureTags = new ArraySet<>();
1341         // Chat Session
1342         featureTags.add(CHAT_FEATURE_TAG);
1343         featureTags.add(FILE_TRANSFER_FEATURE_TAG);
1344         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
1345                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE).setFeatureTags(featureTags).build();
1346         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
1347         waitForParam(mQueue, attr);
1348 
1349         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1350         RcsImsCapabilities capabilities =
1351                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1352         sServiceConnector.getCarrierService().getRcsFeature()
1353                 .notifyCapabilitiesStatusChanged(capabilities);
1354 
1355         CapabilityExchangeEventListener eventListener =
1356                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1357 
1358         // ImsService triggers to notify framework publish device's capabilities.
1359         eventListener.onRequestPublishCapabilities(
1360                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1361 
1362         // Verify that the publish is triggered and receive the publish state changed callback.
1363         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1364                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1365         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1366         publishStateQueue.clear();
1367 
1368         // Can not verify the pidf fully, but we can ensure that the service id for the feature is
1369         // contained in the XML. Multible PUBLISH requests may occur based on the state of the stack
1370         // at the time of this call, retry to get correct PIDF up to 5 times.
1371         boolean containsChatServiceId = false;
1372         boolean containsFileTransferServiceId = false;
1373         for (int retry = 0; retry < 5; retry++) {
1374             String pidf = waitForResult(pidfQueue);
1375             if (pidf == null) break;
1376             containsChatServiceId = pidf.contains(CHAT_SERVICE_ID);
1377             containsFileTransferServiceId  = pidf.contains(FILE_TRANSFER_SERVICE_ID);
1378             if (containsChatServiceId && containsFileTransferServiceId) break;
1379         }
1380         assertTrue("PIDF XML doesn't contain chat service-id", containsChatServiceId);
1381         assertTrue("PIDF XML doesn't contain FT service-id",
1382                 containsFileTransferServiceId);
1383 
1384         // Trigger RcsFeature is unavailable
1385         sServiceConnector.getCarrierService().getRcsFeature()
1386                 .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
1387 
1388         // Verify the RcsCapabilityExchangeImplBase will be removed.
1389         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1390                 TestImsService.LATCH_UCE_LISTENER_SET));
1391 
1392         overrideCarrierConfig(null);
1393     }
1394 
1395     @Test
testPublishWithImsAssociatedUri()1396     public void testPublishWithImsAssociatedUri() throws Exception {
1397         if (!ImsUtils.shouldTestImsService()) {
1398             return;
1399         }
1400         // Trigger carrier config changed
1401         PersistableBundle bundle = new PersistableBundle();
1402         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1403         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1404         overrideCarrierConfig(bundle);
1405 
1406         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1407         if (imsManager == null) {
1408             fail("Cannot find IMS service");
1409         }
1410 
1411         TelephonyManager tm = (TelephonyManager) getContext()
1412                 .getSystemService(Context.TELEPHONY_SERVICE);
1413 
1414         String mccmnc = tm.getSimOperator();
1415         boolean mTelUriSupported = CarrierCapability.SUPPORT_TEL_URI_PUBLISH.contains(mccmnc);
1416 
1417         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1418         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1419 
1420         // Connect to device ImsService with MmTel feature and RCS feature
1421         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1422 
1423         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1424                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1425 
1426         // Setup the operation of the publish request.
1427         List<String> receivedPidfXml = new ArrayList<>();
1428         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1429             int networkResp = 200;
1430             String reason = "";
1431             cb.onNetworkResponse(networkResp, reason);
1432             listener.onPublish();
1433             receivedPidfXml.add(pidfXml);
1434         });
1435 
1436         Uri imsUri;
1437         if (mTelUriSupported) {
1438             imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "0001112222", null);
1439         } else {
1440             imsUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null);
1441         }
1442 
1443         StringBuilder expectedUriBuilder = new StringBuilder();
1444         expectedUriBuilder.append("<contact>").append(imsUri.toString()).append("</contact>");
1445 
1446         final String expectedUriString = expectedUriBuilder.toString();
1447 
1448         // IMS registers
1449         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1450                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1451 
1452         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1453         RcsImsCapabilities capabilities =
1454                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1455         sServiceConnector.getCarrierService().getRcsFeature()
1456                 .notifyCapabilitiesStatusChanged(capabilities);
1457 
1458         // ImsService triggers to notify framework publish device's capabilities.
1459         CapabilityExchangeEventListener eventListener =
1460                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1461         eventListener.onRequestPublishCapabilities(
1462                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1463 
1464         // Verify ImsService receive the publish request from framework.
1465         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1466                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1467 
1468         // Verify that the ImsService has received the publish request and the received PIDF does
1469         // not contain the associated URI.
1470         assertFalse(receivedPidfXml.isEmpty());
1471         assertFalse(receivedPidfXml.get(0).contains(expectedUriString));
1472 
1473         // Reset the received pidf xml data
1474         receivedPidfXml.clear();
1475 
1476         // Notify the associated URI has changed.
1477         sServiceConnector.getCarrierService().getImsRegistration().onSubscriberAssociatedUriChanged(
1478                 new Uri[] { imsUri });
1479 
1480         // Verify the ImsService does not receive the PUBLISH request because we just finish a
1481         // publish request a moment ago.
1482         assertFalse(sServiceConnector.getCarrierService().waitForLatchCountdown(
1483                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 2000 /* 2 seconds */));
1484 
1485         // Trigger a new publish request
1486         eventListener.onRequestPublishCapabilities(
1487                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1488 
1489         // Verify ImsService receive the publish request from framework.
1490         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1491                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1492 
1493         // Verify that the ImsService has received the publish request and the received PIDF
1494         // contains the associated URI.
1495         assertFalse(receivedPidfXml.isEmpty());
1496         assertTrue(receivedPidfXml.get(0).contains(expectedUriString));
1497 
1498         overrideCarrierConfig(null);
1499     }
1500 
1501     @Test
testRcsCapabilitiesPublishNetworkResponseWithReasonHeader()1502     public void testRcsCapabilitiesPublishNetworkResponseWithReasonHeader() throws Exception {
1503         if (!ImsUtils.shouldTestImsService()) {
1504             return;
1505         }
1506 
1507         // Trigger carrier config changed
1508         PersistableBundle bundle = new PersistableBundle();
1509         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1510         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1511         overrideCarrierConfig(bundle);
1512 
1513         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1514         if (imsManager == null) {
1515             fail("Cannot find IMS service");
1516         }
1517 
1518         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1519         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1520 
1521         // Connect to device ImsService with MmTel feature and RCS feature
1522         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1523 
1524         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1525                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1526 
1527         // Register the callback to listen to the publish state changed
1528         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1529         RcsUceAdapter.OnPublishStateChangedListener callback =
1530                 new RcsUceAdapter.OnPublishStateChangedListener() {
1531                     public void onPublishStateChange(int state) {
1532                         publishStateQueue.offer(state);
1533                     }
1534                 };
1535 
1536         // register the publish state callback
1537         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(uceAdapter,
1538                 a -> a.addOnPublishStateChangedListener(getContext().getMainExecutor(), callback),
1539                 ImsException.class,
1540                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
1541 
1542         // Verify receiving the publish state callback immediately after registering the callback.
1543         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1544                 waitForIntResult(publishStateQueue));
1545         publishStateQueue.clear();
1546 
1547         // Setup the operation of the publish request.
1548         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1549             int networkResp = 200;
1550             String reason = "OK";
1551             cb.onNetworkResponse(networkResp, reason);
1552             listener.onPublish();
1553         });
1554 
1555         // IMS registers
1556         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1557                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1558 
1559         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1560         RcsImsCapabilities capabilities =
1561                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1562         sServiceConnector.getCarrierService().getRcsFeature()
1563                 .notifyCapabilitiesStatusChanged(capabilities);
1564 
1565         CapabilityExchangeEventListener eventListener =
1566                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1567 
1568         // ImsService triggers to notify framework publish device's capabilities.
1569         eventListener.onRequestPublishCapabilities(
1570                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1571 
1572         // Verify the ImsService receive the publish request from framework.
1573         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1574                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1575         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1576         publishStateQueue.clear();
1577 
1578         // Verify it is getUcePublishState for the API "getUcePublishState".
1579         int publishState = ShellIdentityUtils.invokeThrowableMethodWithShellPermissions(uceAdapter,
1580                 a -> a.getUcePublishState(),
1581                 ImsException.class,
1582                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
1583         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1584 
1585         // Set the publish request fail (Reason header)
1586         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1587             int networkResp = 200;
1588             String reason = "";
1589             int reasonHeaderCause = 400;
1590             String reasonHeaderText = "Bad Request";
1591             cb.onNetworkResponse(networkResp, reason, reasonHeaderCause, reasonHeaderText);
1592             listener.onPublish();
1593         });
1594 
1595         // ImsService triggers to notify framework publish device's capabilities.
1596         eventListener.onRequestPublishCapabilities(
1597                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1598 
1599         // Verify ImsService receive the publish request from framework.
1600         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1601                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1602 
1603         // Verify that receive the publish failed callback
1604         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR,
1605                 waitForIntResult(publishStateQueue));
1606         publishStateQueue.clear();
1607 
1608         publishState = ShellIdentityUtils.invokeThrowableMethodWithShellPermissions(uceAdapter,
1609                 a -> a.getUcePublishState(),
1610                 ImsException.class,
1611                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
1612         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR, publishState);
1613 
1614         overrideCarrierConfig(null);
1615     }
1616 
1617     @Test
testRcsPublishThrottle()1618     public void testRcsPublishThrottle() throws Exception {
1619         if (!ImsUtils.shouldTestImsService()) {
1620             return;
1621         }
1622 
1623         // Trigger carrier config change
1624         PersistableBundle bundle = new PersistableBundle();
1625         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1626         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1627         overrideCarrierConfig(bundle);
1628 
1629         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1630         if (imsManager == null) {
1631             fail("Cannot get the ImsManager");
1632         }
1633         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1634         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1635 
1636         // Connect to the ImsService
1637         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1638 
1639         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1640                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1641 
1642         // Setup the response of the publish request.
1643         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1644             int networkResp = 200;
1645             String reason = "OK";
1646             cb.onNetworkResponse(networkResp, reason);
1647             listener.onPublish();
1648         });
1649 
1650         // Register the callback to listen to the publish state changed
1651         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1652         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1653                 new RcsUceAdapter.OnPublishStateChangedListener() {
1654                     public void onPublishStateChange(int state) {
1655                         publishStateQueue.offer(state);
1656                     }
1657                 };
1658 
1659         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
1660                 .getUiAutomation();
1661         try {
1662             automation.adoptShellPermissionIdentity();
1663             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1664                     publishStateCallback);
1665         } finally {
1666             automation.dropShellPermissionIdentity();
1667         }
1668 
1669         // Verify receiving the publish state callback immediately after registering the callback.
1670         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1671                 waitForIntResult(publishStateQueue));
1672         publishStateQueue.clear();
1673 
1674         // IMS registers
1675         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1676                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1677 
1678         // Verify the PUBLISH request should not be triggered and the publish state is still
1679         // NOT_PUBLISHED even the IMS is registered.
1680         if (publishStateQueue.poll() != null) {
1681             fail("The PUBLISH request should not be triggered.");
1682         }
1683         try {
1684             automation.adoptShellPermissionIdentity();
1685             int publishState = uceAdapter.getUcePublishState();
1686             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1687         } finally {
1688             automation.dropShellPermissionIdentity();
1689         }
1690 
1691         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1692         RcsImsCapabilities capabilities =
1693                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1694         sServiceConnector.getCarrierService().getRcsFeature()
1695                 .notifyCapabilitiesStatusChanged(capabilities);
1696 
1697         CapabilityExchangeEventListener eventListener =
1698                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1699 
1700         // Notify framework to send the PUBLISH request to the ImsService.
1701         eventListener.onRequestPublishCapabilities(
1702                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1703 
1704         // Verify that ImsService received the first PUBLISH
1705         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1706                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1707         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1708         publishStateQueue.clear();
1709         try {
1710             automation.adoptShellPermissionIdentity();
1711             int publishState = uceAdapter.getUcePublishState();
1712             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1713         } finally {
1714             automation.dropShellPermissionIdentity();
1715         }
1716 
1717         // Now enable voice availability
1718         sServiceConnector.getCarrierService().getMmTelFeature()
1719                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
1720                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
1721 
1722         // The published just succeeded. The next publish should not be triggered immediately even
1723         // the device capabilities has changed. Wait 3 seconds to verify the ImsService does not
1724         // receive the publish request from the framework.
1725         assertFalse(sServiceConnector.getCarrierService().waitForLatchCountdown(
1726                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 3000 /* 3 seconds */));
1727 
1728         // However, if the request is triggered from the service, a new publish request should be
1729         // sent immediately.
1730         eventListener.onRequestPublishCapabilities(
1731                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1732 
1733         // Verify the ImsService receive the publish request
1734         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1735                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 3000 /* Wait up to 3 seconds */));
1736 
1737         overrideCarrierConfig(null);
1738     }
1739 
1740     @Test
testRcsPublishWithSipOptions()1741     public void testRcsPublishWithSipOptions() throws Exception {
1742         if (!ImsUtils.shouldTestImsService()) {
1743             return;
1744         }
1745 
1746         // Override the carrier config to support SIP OPTIONS
1747         PersistableBundle bundle = new PersistableBundle();
1748         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1749         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
1750         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
1751         overrideCarrierConfig(bundle);
1752 
1753         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1754         if (imsManager == null) {
1755             fail("Cannot get the ImsManager");
1756         }
1757         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1758         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1759 
1760         // Connect to the ImsService
1761         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1762 
1763         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1764                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1765 
1766         // Setup the response of the publish request. In SIP OPTIONS mechanism, ImsService
1767         // should not receive any publish requests.
1768         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1769             fail("ImsService should not receive the PUBLISH request");
1770         });
1771 
1772         // Register the callback to listen to the publish state changed
1773         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1774         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1775                 new RcsUceAdapter.OnPublishStateChangedListener() {
1776                     public void onPublishStateChange(int state) {
1777                         publishStateQueue.offer(state);
1778                     }
1779                 };
1780 
1781         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
1782                 .getUiAutomation();
1783 
1784         // Verify receiving the publish state callback immediately after registering the callback
1785         // and the PUBLISH state is OK because the capability mechanism is SIP OPTIONS.
1786         try {
1787             automation.adoptShellPermissionIdentity();
1788             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1789                     publishStateCallback);
1790             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1791         } finally {
1792             automation.dropShellPermissionIdentity();
1793             publishStateQueue.clear();
1794         }
1795 
1796         // IMS registers
1797         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1798                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1799 
1800         // Verify the PUBLISH request should not be triggered and the publish state is still
1801         // OK even the IMS is registered.
1802         if (publishStateQueue.poll() != null) {
1803             fail("The PUBLISH request should not be triggered.");
1804         }
1805         try {
1806             automation.adoptShellPermissionIdentity();
1807             int publishState = uceAdapter.getUcePublishState();
1808             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1809         } finally {
1810             automation.dropShellPermissionIdentity();
1811         }
1812 
1813         // Override the carrier config from SIP OPTIONS to PRESENCE.
1814         bundle = new PersistableBundle();
1815         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1816         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1817         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, false);
1818         overrideCarrierConfig(bundle);
1819 
1820         // When the capability type is changed from SIP OPTIONS to PRESENCE, the publish state
1821         // should be re-initialized to NOT_PUBLISHED
1822         try {
1823             // Verify receiving the callback that the publish state has changed from OK
1824             // to NOT_PUBLISH
1825             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1826                     waitForIntResult(publishStateQueue));
1827             // Verify it by calling the API getPucePublishState
1828             automation.adoptShellPermissionIdentity();
1829             int publishState = uceAdapter.getUcePublishState();
1830             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1831         } finally {
1832             publishStateQueue.clear();
1833             automation.dropShellPermissionIdentity();
1834         }
1835 
1836         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1837         RcsImsCapabilities capabilities =
1838                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1839         sServiceConnector.getCarrierService().getRcsFeature()
1840                 .notifyCapabilitiesStatusChanged(capabilities);
1841 
1842         CapabilityExchangeEventListener eventListener =
1843                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1844 
1845         // Setup the operation of the publish request.
1846         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1847             int networkResp = 200;
1848             String reason = "OK";
1849             cb.onNetworkResponse(networkResp, reason);
1850             listener.onPublish();
1851         });
1852 
1853         // Notify framework to send the PUBLISH request to the ImsService.
1854         eventListener.onRequestPublishCapabilities(
1855                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1856 
1857         // Verify that ImsService received the first PUBLISH
1858         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1859                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1860 
1861         // Verify that the publish state should be changed from NOT_PUBLISHED to OK
1862         try {
1863             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1864             automation.adoptShellPermissionIdentity();
1865             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, uceAdapter.getUcePublishState());
1866         } finally {
1867             publishStateQueue.clear();
1868             automation.dropShellPermissionIdentity();
1869         }
1870 
1871         overrideCarrierConfig(null);
1872     }
1873 
1874     @Test
testRcsPublishWithAuthorizedErrorResponse()1875     public void testRcsPublishWithAuthorizedErrorResponse() throws Exception {
1876         if (!ImsUtils.shouldTestImsService()) {
1877             return;
1878         }
1879 
1880         // Trigger carrier config change
1881         PersistableBundle bundle = new PersistableBundle();
1882         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1883         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1884         overrideCarrierConfig(bundle);
1885 
1886         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1887         if (imsManager == null) {
1888             fail("Cannot get the ImsManager");
1889         }
1890         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1891         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1892 
1893         // Connect to the ImsService
1894         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1895 
1896         // Register the callback to listen to the publish state changed
1897         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1898         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1899                 new RcsUceAdapter.OnPublishStateChangedListener() {
1900                     public void onPublishStateChange(int state) {
1901                         publishStateQueue.offer(state);
1902                     }
1903                 };
1904 
1905         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
1906                 .getUiAutomation();
1907         try {
1908             automation.adoptShellPermissionIdentity();
1909             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1910                     publishStateCallback);
1911             // Verify receiving the publish state callback after registering the callback.
1912             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1913                     waitForIntResult(publishStateQueue));
1914         } finally {
1915             publishStateQueue.clear();
1916             automation.dropShellPermissionIdentity();
1917         }
1918 
1919         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1920                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1921 
1922         // Setup the response of the publish request.
1923         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1924             int networkResp = 200;
1925             String reason = "OK";
1926             cb.onNetworkResponse(networkResp, reason);
1927             listener.onPublish();
1928         });
1929 
1930         // IMS registers
1931         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1932                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
1933 
1934         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1935         RcsImsCapabilities capabilities =
1936                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1937         sServiceConnector.getCarrierService().getRcsFeature()
1938                 .notifyCapabilitiesStatusChanged(capabilities);
1939 
1940         CapabilityExchangeEventListener eventListener =
1941                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1942 
1943         // Notify framework to send the PUBLISH request to the ImsService.
1944         eventListener.onRequestPublishCapabilities(
1945                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1946 
1947         // Verify ImsService receive the publish request from framework.
1948         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1949                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1950 
1951         try {
1952             // Verify the publish state callback is received.
1953             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1954             // Verify the value of getting from the API is PUBLISH_STATE_OK
1955             automation.adoptShellPermissionIdentity();
1956             int publishState = uceAdapter.getUcePublishState();
1957             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1958         } finally {
1959             publishStateQueue.clear();
1960             automation.dropShellPermissionIdentity();
1961         }
1962 
1963         // Reply the SIP code 403 FORBIDDEN
1964         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1965             int networkResp = 403;
1966             String reason = "FORBIDDEN";
1967             cb.onNetworkResponse(networkResp, reason);
1968             listener.onPublish();
1969         });
1970 
1971         // Notify framework to send the PUBLISH request to the ImsService.
1972         eventListener.onRequestPublishCapabilities(
1973                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1974 
1975         try {
1976             // Verify the publish state callback is received.
1977             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR,
1978                     waitForIntResult(publishStateQueue));
1979             // Verify the value of getting from the API is PUBLISH_STATE_RCS_PROVISION_ERROR
1980             automation.adoptShellPermissionIdentity();
1981             int publishState = uceAdapter.getUcePublishState();
1982             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR, publishState);
1983         } finally {
1984             publishStateQueue.clear();
1985             automation.dropShellPermissionIdentity();
1986         }
1987 
1988         LinkedBlockingQueue<Integer> errorQueue = new LinkedBlockingQueue<>();
1989         LinkedBlockingQueue<Long> errorRetryQueue = new LinkedBlockingQueue<>();
1990         LinkedBlockingQueue<Boolean> completeQueue = new LinkedBlockingQueue<>();
1991         LinkedBlockingQueue<RcsContactUceCapability> capabilityQueue = new LinkedBlockingQueue<>();
1992         RcsUceAdapter.CapabilitiesCallback callback = new RcsUceAdapter.CapabilitiesCallback() {
1993             @Override
1994             public void onCapabilitiesReceived(List<RcsContactUceCapability> capabilities) {
1995                 capabilities.forEach(c -> capabilityQueue.offer(c));
1996             }
1997             @Override
1998             public void onComplete() {
1999                 completeQueue.offer(true);
2000             }
2001             @Override
2002             public void onError(int errorCode, long retryAfterMilliseconds) {
2003                 errorQueue.offer(errorCode);
2004                 errorRetryQueue.offer(retryAfterMilliseconds);
2005             }
2006         };
2007 
2008         capExchangeImpl.setSubscribeOperation((uris, cb) -> {
2009             fail("Should not received the SUBSCRIBE request");
2010         });
2011 
2012         Collection<Uri> contacts = Collections.singletonList(
2013                 Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null));
2014 
2015         try {
2016             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(
2017                     uceAdapter,
2018                     adapter -> adapter.requestCapabilities(contacts, Runnable::run, callback),
2019                     ImsException.class,
2020                     "android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE");
2021         } catch (SecurityException e) {
2022             fail("requestCapabilities should succeed with ACCESS_RCS_USER_CAPABILITY_EXCHANGE. "
2023                     + "Exception: " + e);
2024         } catch (ImsException e) {
2025             fail("requestCapabilities failed " + e);
2026         }
2027 
2028         // Verify the capability request should fail
2029         try {
2030             assertEquals(RcsUceAdapter.ERROR_NOT_AUTHORIZED, waitForIntResult(errorQueue));
2031             assertEquals(Long.valueOf(0L), waitForResult(errorRetryQueue));
2032         } catch (Exception e) {
2033             fail("requestCapabilities with command error failed: " + e);
2034         } finally {
2035             errorQueue.clear();
2036             errorRetryQueue.clear();
2037         }
2038 
2039         // Reset the UCE device state
2040         try {
2041             sServiceConnector.removeUceRequestDisallowedStatus(sTestSlot);
2042         } catch (Exception e) {
2043             fail("Cannot remove request disallowed status: " + e);
2044         }
2045 
2046         // Reply the SIP code 404 NOT FOUND
2047         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2048             int networkResp = 404;
2049             String reason = "NOT FOUND";
2050             cb.onNetworkResponse(networkResp, reason);
2051             listener.onPublish();
2052         });
2053 
2054         // Notify framework to send the PUBLISH request to the ImsService.
2055         eventListener.onRequestPublishCapabilities(
2056                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2057 
2058         try {
2059             // Verify the value of getting from the API is PUBLISH_STATE_RCS_PROVISION_ERROR
2060             automation.adoptShellPermissionIdentity();
2061             int publishState = uceAdapter.getUcePublishState();
2062             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR, publishState);
2063         } finally {
2064             publishStateQueue.clear();
2065             automation.dropShellPermissionIdentity();
2066         }
2067 
2068         try {
2069             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(
2070                     uceAdapter,
2071                     adapter -> adapter.requestCapabilities(contacts, Runnable::run, callback),
2072                     ImsException.class,
2073                     "android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE");
2074         } catch (SecurityException e) {
2075             fail("requestCapabilities should succeed with ACCESS_RCS_USER_CAPABILITY_EXCHANGE. "
2076                     + "Exception: " + e);
2077         } catch (ImsException e) {
2078             fail("requestCapabilities failed " + e);
2079         }
2080 
2081         // Reset the UCE device state
2082         try {
2083             sServiceConnector.removeUceRequestDisallowedStatus(sTestSlot);
2084         } catch (Exception e) {
2085             fail("Cannot remove request disallowed status: " + e);
2086         }
2087 
2088         overrideCarrierConfig(null);
2089     }
2090 
2091     @Test
testRcsManagerRegistrationCallback()2092     public void testRcsManagerRegistrationCallback() throws Exception {
2093         if (!ImsUtils.shouldTestImsService()) {
2094             return;
2095         }
2096 
2097         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2098         if (imsManager == null) {
2099             fail("Cannot find IMS service");
2100         }
2101 
2102         // Connect to device ImsService with RcsFeature
2103         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
2104         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2105 
2106         // Override the carrier config
2107         PersistableBundle bundle = new PersistableBundle();
2108         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2109         overrideCarrierConfig(bundle);
2110 
2111         // Wait for the framework to set the capabilities on the ImsService
2112         sServiceConnector.getCarrierService().waitForLatchCountdown(
2113                 TestImsService.LATCH_RCS_CAP_SET);
2114 
2115         // Start de-registered
2116         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
2117                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
2118                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2119 
2120         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
2121         RegistrationManager.RegistrationCallback callback =
2122                 new RegistrationManager.RegistrationCallback() {
2123                     @Override
2124                     public void onRegistered(int imsTransportType) {
2125                         mQueue.offer(imsTransportType);
2126                     }
2127 
2128                     @Override
2129                     public void onRegistering(int imsTransportType) {
2130                         mQueue.offer(imsTransportType);
2131                     }
2132 
2133                     @Override
2134                     public void onUnregistered(ImsReasonInfo info) {
2135                         mQueue.offer(info.getCode());
2136                     }
2137 
2138                     @Override
2139                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
2140                         mQueue.offer(imsTransportType);
2141                         mQueue.offer(info.getCode());
2142                     }
2143                 };
2144 
2145         // Verify the registerImsRegistrationCallback should fail without the required permission
2146         try {
2147             imsRcsManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
2148             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
2149         } catch (SecurityException e) {
2150             //expected
2151         }
2152 
2153         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
2154                 m -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
2155                 ImsException.class,
2156                 "android.permission.READ_PRECISE_PHONE_STATE");
2157 
2158         // Verify it's not registered
2159         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
2160 
2161         // Start registration
2162         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
2163                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2164         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2165 
2166         // Complete registration
2167         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2168                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2169         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2170 
2171         // Fail handover to IWLAN
2172         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
2173                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
2174                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
2175                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2176         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
2177         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
2178 
2179         // Verify the unregisterImsRegistrationCallback should failure without the permission.
2180         try {
2181             imsRcsManager.unregisterImsRegistrationCallback(callback);
2182             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission");
2183         } catch (SecurityException e) {
2184             //expected
2185         }
2186 
2187         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
2188                 m -> m.unregisterImsRegistrationCallback(callback),
2189                 ImsException.class,
2190                 "android.permission.READ_PRECISE_PHONE_STATE");
2191 
2192         overrideCarrierConfig(null);
2193     }
2194 
2195     @Test
testMmTelManagerRegistrationStateR()2196     public void testMmTelManagerRegistrationStateR() throws Exception {
2197         if (!ImsUtils.shouldTestImsService()) {
2198             return;
2199         }
2200         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2201         RegistrationManager regManager = imsManager.getImsMmTelManager(sTestSub);
2202         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
2203 
2204         triggerFrameworkConnectToCarrierImsService();
2205 
2206         // Start deregistered
2207         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
2208                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
2209                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2210 
2211         RegistrationManager.RegistrationCallback callback =
2212                 new RegistrationManager.RegistrationCallback() {
2213                     @Override
2214                     public void onRegistered(int imsTransportType) {
2215                         mQueue.offer(imsTransportType);
2216                     }
2217 
2218                     @Override
2219                     public void onRegistering(int imsTransportType) {
2220                         mQueue.offer(imsTransportType);
2221                     }
2222 
2223                     @Override
2224                     public void onUnregistered(ImsReasonInfo info) {
2225                         mQueue.offer(info.getCode());
2226                     }
2227 
2228                     @Override
2229                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
2230                         mQueue.offer(imsTransportType);
2231                         mQueue.offer(info.getCode());
2232                     }
2233                 };
2234 
2235         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
2236         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mmTelManager,
2237                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
2238                 ImsException.class);
2239         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
2240 
2241         // Ensure that the Framework reports Deregistered correctly
2242         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
2243         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
2244 
2245         // Start registration
2246         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
2247                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2248         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2249         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
2250         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2251 
2252         // Complete registration
2253         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2254                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2255         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2256         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
2257         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2258 
2259 
2260         // Fail handover to IWLAN
2261         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
2262                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
2263                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
2264                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2265         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
2266         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
2267         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2268 
2269         // handover to IWLAN
2270         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2271                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
2272         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
2273         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
2274 
2275         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mmTelManager,
2276                 (m) -> m.unregisterImsRegistrationCallback(callback));
2277     }
2278 
2279     @Test
testRcsManagerRegistrationState()2280     public void testRcsManagerRegistrationState() throws Exception {
2281         if (!ImsUtils.shouldTestImsService()) {
2282             return;
2283         }
2284 
2285         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2286         if (imsManager == null) {
2287             fail("Cannot find IMS service");
2288         }
2289 
2290         // Connect to device ImsService with RcsFeature
2291         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
2292 
2293         // Override the carrier config
2294         PersistableBundle bundle = new PersistableBundle();
2295         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2296         overrideCarrierConfig(bundle);
2297 
2298         sServiceConnector.getCarrierService().waitForLatchCountdown(
2299                 TestImsService.LATCH_RCS_CAP_SET);
2300 
2301         // Start de-registered
2302         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
2303                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
2304                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2305 
2306         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
2307         RegistrationManager.RegistrationCallback callback =
2308                 new RegistrationManager.RegistrationCallback() {
2309                     @Override
2310                     public void onRegistered(int imsTransportType) {
2311                         mQueue.offer(imsTransportType);
2312                     }
2313 
2314                     @Override
2315                     public void onRegistering(int imsTransportType) {
2316                         mQueue.offer(imsTransportType);
2317                     }
2318 
2319                     @Override
2320                     public void onUnregistered(ImsReasonInfo info) {
2321                         mQueue.offer(info.getCode());
2322                     }
2323 
2324                     @Override
2325                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
2326                         mQueue.offer(imsTransportType);
2327                         mQueue.offer(info.getCode());
2328                     }
2329                 };
2330 
2331         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2332         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
2333                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
2334                 ImsException.class);
2335         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
2336 
2337         // Verify the getRegistrationState should fail without the required permission
2338         try {
2339             imsRcsManager.getRegistrationState(getContext().getMainExecutor(), mQueue::offer);
2340             fail("getRegistrationState requires READ_PRECISE_PHONE_STATE permission.");
2341         } catch (SecurityException e) {
2342             //expected
2343         }
2344 
2345         // Verify the getRegistrationTransportType should fail without the required permission
2346         try {
2347             imsRcsManager.getRegistrationTransportType(getContext().getMainExecutor(),
2348                     mQueue::offer);
2349             fail("getRegistrationTransportType requires READ_PRECISE_PHONE_STATE permission.");
2350         } catch (SecurityException e) {
2351             //expected
2352         }
2353 
2354         // Ensure that the Framework reports Deregistered correctly
2355         verifyRegistrationState(imsRcsManager,
2356                 RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
2357         verifyRegistrationTransportType(imsRcsManager,
2358                 AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
2359 
2360         // Start registration
2361         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
2362                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2363         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2364         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
2365         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2366 
2367         // Complete registration
2368         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2369                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2370         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2371         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
2372         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2373 
2374         // Start registration over NR
2375         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
2376                 ImsRegistrationImplBase.REGISTRATION_TECH_NR);
2377         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2378         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
2379         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2380 
2381         // Complete registration over NR
2382         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2383                 ImsRegistrationImplBase.REGISTRATION_TECH_NR);
2384         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
2385         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
2386         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2387 
2388         // Fail handover to IWLAN
2389         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
2390                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
2391                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
2392                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
2393         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
2394         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
2395         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
2396 
2397         // handover to IWLAN
2398         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2399                 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
2400         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
2401         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
2402         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(imsRcsManager,
2403                 (m) -> m.unregisterImsRegistrationCallback(callback));
2404 
2405         overrideCarrierConfig(null);
2406     }
2407 
2408     @Test
testCapabilityStatusCallback()2409     public void testCapabilityStatusCallback() throws Exception {
2410         if (!ImsUtils.shouldTestImsService()) {
2411             return;
2412         }
2413 
2414         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2415         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
2416 
2417         triggerFrameworkConnectToCarrierImsService();
2418 
2419         // Wait for the framework to set the capabilities on the ImsService
2420         sServiceConnector.getCarrierService().waitForLatchCountdown(
2421                 TestImsService.LATCH_MMTEL_CAP_SET);
2422         MmTelFeature.MmTelCapabilities fwCaps = sServiceConnector.getCarrierService()
2423                 .getMmTelFeature().getCapabilities();
2424         // Make sure we start off with every capability unavailable
2425         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2426                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2427         sServiceConnector.getCarrierService().getMmTelFeature()
2428                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities());
2429 
2430         // Make sure the capabilities match the API getter for capabilities
2431         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2432         // Latch will count down here (we callback on the state during registration).
2433         try {
2434             automan.adoptShellPermissionIdentity();
2435             // Make sure we are tracking voice capability over LTE properly.
2436             assertEquals(fwCaps.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
2437                     mmTelManager.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2438                             ImsRegistrationImplBase.REGISTRATION_TECH_LTE));
2439         } finally {
2440             automan.dropShellPermissionIdentity();
2441         }
2442 
2443         // This is a little bit gross looking, but on P devices, I can not define classes that
2444         // extend ImsMmTelManager.CapabilityCallback (because it doesn't exist), so this has to
2445         // happen as an anon class here.
2446         LinkedBlockingQueue<MmTelFeature.MmTelCapabilities> mQueue = new LinkedBlockingQueue<>();
2447         ImsMmTelManager.CapabilityCallback callback = new ImsMmTelManager.CapabilityCallback() {
2448 
2449             @Override
2450             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
2451                 mQueue.offer(capabilities);
2452             }
2453         };
2454 
2455         // Latch will count down here (we callback on the state during registration).
2456         try {
2457             automan.adoptShellPermissionIdentity();
2458             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
2459         } finally {
2460             automan.dropShellPermissionIdentity();
2461         }
2462 
2463         try {
2464             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
2465             fail("registerMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
2466         } catch (SecurityException e) {
2467             //expected
2468         }
2469 
2470         // We should not have voice availability here, we notified the framework earlier.
2471         MmTelFeature.MmTelCapabilities capCb = waitForResult(mQueue);
2472         assertNotNull(capCb);
2473         assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
2474 
2475         // Now enable voice availability
2476         sServiceConnector.getCarrierService().getMmTelFeature()
2477                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
2478                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
2479         capCb = waitForResult(mQueue);
2480         assertNotNull(capCb);
2481         assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
2482 
2483         try {
2484             automan.adoptShellPermissionIdentity();
2485             assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
2486                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2487                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE)));
2488 
2489             mmTelManager.unregisterMmTelCapabilityCallback(callback);
2490         } finally {
2491             automan.dropShellPermissionIdentity();
2492         }
2493 
2494         try {
2495             mmTelManager.unregisterMmTelCapabilityCallback(callback);
2496             fail("unregisterMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
2497         } catch (SecurityException e) {
2498             //expected
2499         }
2500     }
2501 
2502     @Test
testCallComposerCapabilityStatusCallback()2503     public void testCallComposerCapabilityStatusCallback() throws Exception {
2504         if (!ImsUtils.shouldTestImsService()) {
2505             return;
2506         }
2507 
2508         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2509         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
2510 
2511         triggerFrameworkConnectToCarrierImsService();
2512 
2513         // Wait for the framework to set the capabilities on the ImsService
2514         sServiceConnector.getCarrierService().waitForLatchCountdown(
2515                 TestImsService.LATCH_MMTEL_CAP_SET);
2516         MmTelFeature.MmTelCapabilities fwCaps = sServiceConnector.getCarrierService()
2517                 .getMmTelFeature().getCapabilities();
2518         // Make sure we start off with every capability unavailable
2519         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2520                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2521         sServiceConnector.getCarrierService().getMmTelFeature()
2522                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities());
2523 
2524         // Make sure the capabilities match the API getter for capabilities
2525         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2526         // Latch will count down here (we callback on the state during registration).
2527         try {
2528             automan.adoptShellPermissionIdentity();
2529             // Make sure we are tracking voice capability over LTE properly.
2530             assertEquals(fwCaps.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
2531                     mmTelManager.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2532                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE));
2533         } finally {
2534             automan.dropShellPermissionIdentity();
2535         }
2536 
2537         LinkedBlockingQueue<MmTelFeature.MmTelCapabilities> mQueue = new LinkedBlockingQueue<>();
2538         ImsMmTelManager.CapabilityCallback callback = new ImsMmTelManager.CapabilityCallback() {
2539 
2540             @Override
2541             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
2542                 mQueue.offer(capabilities);
2543             }
2544         };
2545 
2546         // Latch will count down here (we callback on the state during registration).
2547         try {
2548             automan.adoptShellPermissionIdentity();
2549             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
2550         } finally {
2551             automan.dropShellPermissionIdentity();
2552         }
2553 
2554         try {
2555             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
2556             fail("registerMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
2557         } catch (SecurityException e) {
2558             //expected
2559         }
2560 
2561         // We should not have voice availability here, we notified the framework earlier.
2562         MmTelFeature.MmTelCapabilities capCb = waitForResult(mQueue);
2563         assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
2564 
2565         // Now enable call composer availability
2566         sServiceConnector.getCarrierService().getMmTelFeature()
2567                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
2568                 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
2569         capCb = waitForResult(mQueue);
2570         assertNotNull(capCb);
2571         assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
2572 
2573         try {
2574             automan.adoptShellPermissionIdentity();
2575             assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
2576                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER,
2577                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE)));
2578 
2579             mmTelManager.unregisterMmTelCapabilityCallback(callback);
2580         } finally {
2581             automan.dropShellPermissionIdentity();
2582         }
2583 
2584         try {
2585             mmTelManager.unregisterMmTelCapabilityCallback(callback);
2586             fail("unregisterMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
2587         } catch (SecurityException e) {
2588             //expected
2589         }
2590     }
2591 
2592     /**
2593      * We are specifically testing a race case here such that IsAvailable returns the correct
2594      * capability status during the callback.
2595      */
2596     @Test
testCapabilityStatusWithIsAvailableDuringCallback()2597     public void testCapabilityStatusWithIsAvailableDuringCallback() throws Exception {
2598         if (!ImsUtils.shouldTestImsService()) {
2599             return;
2600         }
2601 
2602         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2603         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
2604 
2605         triggerFrameworkConnectToCarrierImsService();
2606 
2607         // Wait for the framework to set the capabilities on the ImsService
2608         sServiceConnector.getCarrierService().waitForLatchCountdown(
2609                 TestImsService.LATCH_MMTEL_CAP_SET);
2610 
2611 
2612         // Make sure we start off with every capability unavailable
2613         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2614                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2615         MmTelFeature.MmTelCapabilities stdCapabilities = new MmTelFeature.MmTelCapabilities();
2616         sServiceConnector.getCarrierService().getMmTelFeature()
2617                 .notifyCapabilitiesStatusChanged(stdCapabilities);
2618 
2619 
2620         // Make sure the capabilities match the API getter for capabilities
2621         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2622 
2623         //This lock is to keep the shell permissions from being dropped on a different thread
2624         //causing a permission error.
2625         Object lockObj = new Object();
2626 
2627         synchronized (lockObj) {
2628             try {
2629                 automan.adoptShellPermissionIdentity();
2630                 boolean isAvailableBeforeStatusChange = mmTelManager.isAvailable(
2631                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2632                         ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2633                 assertFalse(isAvailableBeforeStatusChange);
2634             } finally {
2635                 automan.dropShellPermissionIdentity();
2636             }
2637         }
2638 
2639         LinkedBlockingQueue<Boolean> voiceIsAvailable = new LinkedBlockingQueue<>();
2640         ImsMmTelManager.CapabilityCallback verifyCapabilityStatusCallaback =
2641                 new ImsMmTelManager.CapabilityCallback() {
2642             @Override
2643             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
2644                 synchronized (lockObj) {
2645                     try {
2646                         automan.adoptShellPermissionIdentity();
2647                         boolean isVoiceAvailable = mmTelManager
2648                                 .isAvailable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2649                                         ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2650 
2651                         voiceIsAvailable.offer(isVoiceAvailable);
2652                     } finally {
2653                         automan.dropShellPermissionIdentity();
2654                     }
2655                 }
2656             }
2657         };
2658 
2659         synchronized (lockObj) {
2660             // Latch will count down here (we callback on the state during registration).
2661             try {
2662                 automan.adoptShellPermissionIdentity();
2663                 mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(),
2664                         verifyCapabilityStatusCallaback);
2665             } finally {
2666                 automan.dropShellPermissionIdentity();
2667             }
2668         }
2669 
2670         // Now enable voice availability
2671         Boolean isAvailableDuringRegister = waitForResult(voiceIsAvailable);
2672         assertNotNull(isAvailableDuringRegister);
2673         assertFalse(isAvailableDuringRegister);
2674         sServiceConnector.getCarrierService().getMmTelFeature()
2675                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
2676                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
2677         Boolean isAvailableAfterStatusChange = waitForResult(voiceIsAvailable);
2678         assertNotNull(isAvailableAfterStatusChange);
2679         assertTrue(isAvailableAfterStatusChange);
2680 
2681         synchronized (lockObj) {
2682             try {
2683                 automan.adoptShellPermissionIdentity();
2684                 mmTelManager.unregisterMmTelCapabilityCallback(verifyCapabilityStatusCallaback);
2685             } finally {
2686                 automan.dropShellPermissionIdentity();
2687             }
2688         }
2689     }
2690 
2691     @Test
testRcsCapabilityStatusCallback()2692     public void testRcsCapabilityStatusCallback() throws Exception {
2693         if (!ImsUtils.shouldTestImsService()) {
2694             return;
2695         }
2696 
2697         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2698         if (imsManager == null) {
2699             fail("Cannot find IMS service");
2700         }
2701 
2702         // Connect to device ImsService with RcsFeature
2703         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
2704 
2705         int registrationTech = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
2706         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2707 
2708         // Make sure we start off with none-capability
2709         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2710                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2711         RcsImsCapabilities noCapabilities = new RcsImsCapabilities(RCS_CAP_NONE);
2712         sServiceConnector.getCarrierService().getRcsFeature()
2713                 .notifyCapabilitiesStatusChanged(noCapabilities);
2714 
2715         // Make sure the capabilities match the API getter for capabilities
2716         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2717         // Latch will count down here (we callback on the state during registration).
2718         try {
2719             automan.adoptShellPermissionIdentity();
2720             // Make sure we are tracking voice capability over LTE properly.
2721             RcsImsCapabilities availability = sServiceConnector.getCarrierService()
2722                     .getRcsFeature().queryCapabilityStatus();
2723             assertFalse(availability.isCapable(RCS_CAP_OPTIONS));
2724             assertFalse(availability.isCapable(RCS_CAP_PRESENCE));
2725         } finally {
2726             automan.dropShellPermissionIdentity();
2727         }
2728 
2729         // Trigger carrier config changed
2730         PersistableBundle bundle = new PersistableBundle();
2731         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
2732         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2733         overrideCarrierConfig(bundle);
2734 
2735         sServiceConnector.getCarrierService().waitForLatchCountdown(
2736                 TestImsService.LATCH_RCS_CAP_SET);
2737 
2738         // The carrier config changed should trigger RcsFeature#changeEnabledCapabilities
2739         try {
2740             automan.adoptShellPermissionIdentity();
2741             // Checked by isCapable api to make sure RcsFeature#changeEnabledCapabilities is called
2742             assertTrue(ImsUtils.retryUntilTrue(() ->
2743                     imsRcsManager.isCapable(RCS_CAP_OPTIONS, registrationTech)));
2744             assertTrue(ImsUtils.retryUntilTrue(() ->
2745                     imsRcsManager.isCapable(RCS_CAP_PRESENCE, registrationTech)));
2746         } finally {
2747             automan.dropShellPermissionIdentity();
2748         }
2749 
2750         // A queue to receive capability changed
2751         LinkedBlockingQueue<Integer> availabilityChanged = new LinkedBlockingQueue<>();
2752         ImsRcsManager.OnAvailabilityChangedListener callback =
2753                 new ImsRcsManager.OnAvailabilityChangedListener() {
2754             @Override
2755             public void onAvailabilityChanged(
2756                     @RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
2757                 availabilityChanged.offer(capabilities);
2758             }
2759         };
2760 
2761         // Latch will count down here (we callback on the state during registration).
2762         try {
2763             automan.adoptShellPermissionIdentity();
2764             imsRcsManager.addOnAvailabilityChangedListener(
2765                     getContext().getMainExecutor(), callback);
2766         } finally {
2767             automan.dropShellPermissionIdentity();
2768         }
2769 
2770         // Verify the callback and the api isAvailable that the capabilities is NONE in the
2771         // beginning.
2772         int radioTechLTE = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
2773         int capCb = waitForResult(availabilityChanged);
2774         assertEquals(capCb, RCS_CAP_NONE);
2775         availabilityChanged.clear();
2776         try {
2777             automan.adoptShellPermissionIdentity();
2778             assertFalse(imsRcsManager.isAvailable(RCS_CAP_OPTIONS, radioTechLTE));
2779             assertFalse(imsRcsManager.isAvailable(RCS_CAP_PRESENCE, radioTechLTE));
2780         } finally {
2781             automan.dropShellPermissionIdentity();
2782         }
2783 
2784         // Notify capabilities status change to OPTIONS
2785         RcsImsCapabilities optionsCap = new RcsImsCapabilities(RCS_CAP_OPTIONS);
2786         sServiceConnector.getCarrierService().getRcsFeature()
2787                 .notifyCapabilitiesStatusChanged(optionsCap);
2788 
2789         // Verify that the callback onAvailabilityChanged is called with OPTIONS
2790         capCb = waitForResult(availabilityChanged);
2791         assertEquals(capCb, RCS_CAP_OPTIONS);
2792         availabilityChanged.clear();
2793         try {
2794             automan.adoptShellPermissionIdentity();
2795             assertTrue(imsRcsManager.isAvailable(RCS_CAP_OPTIONS, radioTechLTE));
2796         } finally {
2797             automan.dropShellPermissionIdentity();
2798         }
2799 
2800         // Notify capabilities status change to PRESENCE
2801         RcsImsCapabilities presenceCap = new RcsImsCapabilities(RCS_CAP_PRESENCE);
2802         sServiceConnector.getCarrierService().getRcsFeature()
2803                 .notifyCapabilitiesStatusChanged(presenceCap);
2804 
2805         // Verify that the callback onAvailabilityChanged is called with PRESENCE
2806         capCb = waitForResult(availabilityChanged);
2807         assertEquals(capCb, RCS_CAP_PRESENCE);
2808         availabilityChanged.clear();
2809         try {
2810             automan.adoptShellPermissionIdentity();
2811             assertTrue(imsRcsManager.isAvailable(RCS_CAP_PRESENCE, radioTechLTE));
2812         } finally {
2813             automan.dropShellPermissionIdentity();
2814         }
2815 
2816         // Remove availability changed listener
2817         try {
2818             automan.adoptShellPermissionIdentity();
2819             imsRcsManager.removeOnAvailabilityChangedListener(callback);
2820         } finally {
2821             automan.dropShellPermissionIdentity();
2822         }
2823 
2824         // Notify capabilities status changes again.
2825         sServiceConnector.getCarrierService().getRcsFeature()
2826                 .notifyCapabilitiesStatusChanged(optionsCap);
2827 
2828         // The callback should not be called because the listener is removed.
2829         assertTrue(availabilityChanged.isEmpty());
2830 
2831         overrideCarrierConfig(null);
2832     }
2833 
2834     @Test
testProvisioningManagerSetConfig()2835     public void testProvisioningManagerSetConfig() throws Exception {
2836         if (!ImsUtils.shouldTestImsService()) {
2837             return;
2838         }
2839 
2840         triggerFrameworkConnectToCarrierImsService();
2841 
2842         ProvisioningManager provisioningManager =
2843                 ProvisioningManager.createForSubscriptionId(sTestSub);
2844 
2845         // This is a little bit gross looking, but on P devices, I can not define classes that
2846         // extend ProvisioningManager.Callback (because it doesn't exist), so this has to
2847         // happen as an anon class here.
2848         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
2849         LinkedBlockingQueue<Pair<Integer, String>> mStringQueue = new LinkedBlockingQueue<>();
2850         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
2851             @Override
2852             public void onProvisioningIntChanged(int item, int value) {
2853                 mIntQueue.offer(new Pair<>(item, value));
2854             }
2855 
2856             @Override
2857             public void onProvisioningStringChanged(int item, String value) {
2858                 mStringQueue.offer(new Pair<>(item, value));
2859             }
2860         };
2861 
2862         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2863         try {
2864             automan.adoptShellPermissionIdentity();
2865             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
2866                     callback);
2867 
2868             provisioningManager.setProvisioningIntValue(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_INT);
2869             assertTrue(waitForParam(mIntQueue, new Pair<>(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_INT)));
2870             assertEquals(TEST_CONFIG_VALUE_INT,
2871                     provisioningManager.getProvisioningIntValue(TEST_CONFIG_KEY));
2872 
2873             provisioningManager.setProvisioningStringValue(TEST_CONFIG_KEY,
2874                     TEST_CONFIG_VALUE_STRING);
2875             assertTrue(waitForParam(mStringQueue,
2876                     new Pair<>(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_STRING)));
2877             assertEquals(TEST_CONFIG_VALUE_STRING,
2878                     provisioningManager.getProvisioningStringValue(TEST_CONFIG_KEY));
2879 
2880             automan.adoptShellPermissionIdentity();
2881             provisioningManager.unregisterProvisioningChangedCallback(callback);
2882         } finally {
2883             automan.dropShellPermissionIdentity();
2884         }
2885     }
2886 
2887     @Ignore("The ProvisioningManager constants were moved back to @hide for now, don't want to "
2888             + "completely remove test.")
2889     @Test
testProvisioningManagerConstants()2890     public void testProvisioningManagerConstants() throws Exception {
2891         if (!ImsUtils.shouldTestImsService()) {
2892             return;
2893         }
2894 
2895         triggerFrameworkConnectToCarrierImsService();
2896 
2897         ProvisioningManager provisioningManager =
2898                 ProvisioningManager.createForSubscriptionId(sTestSub);
2899 
2900         // This is a little bit gross looking, but on P devices, I can not define classes that
2901         // extend ProvisioningManager.Callback (because it doesn't exist), so this has to
2902         // happen as an anon class here.
2903         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
2904         LinkedBlockingQueue<Pair<Integer, String>> mStringQueue = new LinkedBlockingQueue<>();
2905         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
2906             @Override
2907             public void onProvisioningIntChanged(int item, int value) {
2908                 mIntQueue.offer(new Pair<>(item, value));
2909             }
2910 
2911             @Override
2912             public void onProvisioningStringChanged(int item, String value) {
2913                 mStringQueue.offer(new Pair<>(item, value));
2914             }
2915         };
2916 
2917         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2918         try {
2919             automan.adoptShellPermissionIdentity();
2920             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
2921                     callback);
2922 
2923             verifyStringKey(provisioningManager, mStringQueue,
2924                     ProvisioningManager.KEY_AMR_CODEC_MODE_SET_VALUES, "1,2");
2925             verifyStringKey(provisioningManager, mStringQueue,
2926                     ProvisioningManager.KEY_AMR_WB_CODEC_MODE_SET_VALUES, "1,2");
2927             verifyIntKey(provisioningManager, mIntQueue,
2928                     ProvisioningManager.KEY_SIP_SESSION_TIMER_SEC, 5);
2929             verifyIntKey(provisioningManager, mIntQueue,
2930                     ProvisioningManager.KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC, 5);
2931             verifyIntKey(provisioningManager, mIntQueue,
2932                     ProvisioningManager.KEY_SIP_INVITE_CANCELLATION_TIMER_MS, 5);
2933             verifyIntKey(provisioningManager, mIntQueue,
2934                     ProvisioningManager.KEY_TRANSITION_TO_LTE_DELAY_MS, 5);
2935             verifyIntKey(provisioningManager, mIntQueue,
2936                     ProvisioningManager.KEY_ENABLE_SILENT_REDIAL, 0);
2937             verifyIntKey(provisioningManager, mIntQueue,
2938                     ProvisioningManager.KEY_T1_TIMER_VALUE_MS, 500);
2939             verifyIntKey(provisioningManager, mIntQueue,
2940                     ProvisioningManager.KEY_T2_TIMER_VALUE_MS, 500);
2941             verifyIntKey(provisioningManager, mIntQueue,
2942                     ProvisioningManager.KEY_TF_TIMER_VALUE_MS, 500);
2943             verifyIntKey(provisioningManager, mIntQueue,
2944                     ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS, 0);
2945             verifyIntKey(provisioningManager, mIntQueue,
2946                     ProvisioningManager.KEY_VT_PROVISIONING_STATUS, 0);
2947             verifyStringKey(provisioningManager, mStringQueue,
2948                     ProvisioningManager.KEY_REGISTRATION_DOMAIN_NAME, "test.com");
2949             verifyIntKey(provisioningManager, mIntQueue,
2950                     ProvisioningManager.KEY_SMS_FORMAT, ProvisioningManager.SMS_FORMAT_3GPP);
2951             verifyIntKey(provisioningManager, mIntQueue,
2952                     ProvisioningManager.KEY_SMS_FORMAT, ProvisioningManager.SMS_FORMAT_3GPP2);
2953             verifyIntKey(provisioningManager, mIntQueue,
2954                     ProvisioningManager.KEY_SMS_OVER_IP_ENABLED, 0);
2955             verifyIntKey(provisioningManager, mIntQueue,
2956                     ProvisioningManager.KEY_RCS_PUBLISH_TIMER_SEC, 5);
2957             verifyIntKey(provisioningManager, mIntQueue,
2958                     ProvisioningManager.KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC, 5);
2959             verifyIntKey(provisioningManager, mIntQueue,
2960                     ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED, 0);
2961             verifyIntKey(provisioningManager, mIntQueue,
2962                     ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC, 5);
2963             verifyIntKey(provisioningManager, mIntQueue,
2964                     ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC, 5);
2965             verifyIntKey(provisioningManager, mIntQueue,
2966                     ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC, 5);
2967             verifyIntKey(provisioningManager, mIntQueue,
2968                     ProvisioningManager.KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC, 5);
2969             verifyIntKey(provisioningManager, mIntQueue,
2970                     ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS, 1000);
2971             verifyIntKey(provisioningManager, mIntQueue,
2972                     ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL, 50);
2973             verifyIntKey(provisioningManager, mIntQueue,
2974                     ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC, 5);
2975             verifyIntKey(provisioningManager, mIntQueue,
2976                     ProvisioningManager.KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION, 0);
2977             verifyIntKey(provisioningManager, mIntQueue,
2978                     ProvisioningManager.KEY_EAB_PROVISIONING_STATUS, 0);
2979             verifyIntKey(provisioningManager, mIntQueue,
2980                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE, 0);
2981             verifyIntKey(provisioningManager, mIntQueue,
2982                     ProvisioningManager.KEY_VOICE_OVER_WIFI_MODE_OVERRIDE, 0);
2983             verifyIntKey(provisioningManager, mIntQueue,
2984                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, 0);
2985             verifyIntKey(provisioningManager, mIntQueue,
2986                     ProvisioningManager.KEY_MOBILE_DATA_ENABLED, 0);
2987             verifyIntKey(provisioningManager, mIntQueue,
2988                     ProvisioningManager.KEY_VOLTE_USER_OPT_IN_STATUS, 0);
2989             verifyStringKey(provisioningManager, mStringQueue,
2990                     ProvisioningManager.KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS, "local.fun.com");
2991             verifyIntKey(provisioningManager, mIntQueue,
2992                     ProvisioningManager.KEY_SIP_KEEP_ALIVE_ENABLED, 0);
2993             verifyIntKey(provisioningManager, mIntQueue,
2994                     ProvisioningManager.KEY_REGISTRATION_RETRY_BASE_TIME_SEC, 0);
2995             verifyIntKey(provisioningManager, mIntQueue,
2996                     ProvisioningManager.KEY_REGISTRATION_RETRY_MAX_TIME_SEC, 5);
2997             verifyIntKey(provisioningManager, mIntQueue,
2998                     ProvisioningManager.KEY_RTP_SPEECH_START_PORT, 500);
2999             verifyIntKey(provisioningManager, mIntQueue,
3000                     ProvisioningManager.KEY_RTP_SPEECH_END_PORT, 600);
3001             verifyIntKey(provisioningManager, mIntQueue,
3002                     ProvisioningManager.KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS, 500);
3003             verifyIntKey(provisioningManager, mIntQueue,
3004                     ProvisioningManager.KEY_SIP_INVITE_ACK_WAIT_TIME_MS, 500);
3005             verifyIntKey(provisioningManager, mIntQueue,
3006                     ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS, 500);
3007             verifyIntKey(provisioningManager, mIntQueue,
3008                     ProvisioningManager.KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS, 500);
3009             verifyIntKey(provisioningManager, mIntQueue,
3010                     ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS, 500);
3011             verifyIntKey(provisioningManager, mIntQueue,
3012                     ProvisioningManager.KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS, 500);
3013             verifyIntKey(provisioningManager, mIntQueue,
3014                     ProvisioningManager.KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS, 500);
3015             verifyIntKey(provisioningManager, mIntQueue,
3016                     ProvisioningManager.KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS, 500);
3017             verifyIntKey(provisioningManager, mIntQueue,
3018                     ProvisioningManager.KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS,
3019                     500);
3020             verifyIntKey(provisioningManager, mIntQueue,
3021                     ProvisioningManager.KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE, 0);
3022             verifyIntKey(provisioningManager, mIntQueue,
3023                     ProvisioningManager.KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE, 0);
3024             verifyIntKey(provisioningManager, mIntQueue,
3025                     ProvisioningManager.KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE, 0);
3026             verifyIntKey(provisioningManager, mIntQueue,
3027                     ProvisioningManager.KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE, 0);
3028             verifyIntKey(provisioningManager, mIntQueue,
3029                     ProvisioningManager.KEY_DTMF_WB_PAYLOAD_TYPE, 0);
3030             verifyIntKey(provisioningManager, mIntQueue,
3031                     ProvisioningManager.KEY_DTMF_NB_PAYLOAD_TYPE, 0);
3032             verifyIntKey(provisioningManager, mIntQueue,
3033                     ProvisioningManager.KEY_AMR_DEFAULT_ENCODING_MODE, 0);
3034             verifyIntKey(provisioningManager, mIntQueue,
3035                     ProvisioningManager.KEY_SMS_PUBLIC_SERVICE_IDENTITY, 0);
3036             verifyStringKey(provisioningManager, mStringQueue,
3037                     ProvisioningManager.KEY_SMS_PUBLIC_SERVICE_IDENTITY, "local.fun.com");
3038             verifyIntKey(provisioningManager, mIntQueue,
3039                     ProvisioningManager.KEY_VIDEO_QUALITY, ProvisioningManager.VIDEO_QUALITY_HIGH);
3040             verifyIntKey(provisioningManager, mIntQueue,
3041                     ProvisioningManager.KEY_VIDEO_QUALITY, ProvisioningManager.VIDEO_QUALITY_LOW);
3042             verifyIntKey(provisioningManager, mIntQueue,
3043                     ProvisioningManager.KEY_LTE_THRESHOLD_1, 0);
3044             verifyIntKey(provisioningManager, mIntQueue,
3045                     ProvisioningManager.KEY_LTE_THRESHOLD_2, 0);
3046             verifyIntKey(provisioningManager, mIntQueue,
3047                     ProvisioningManager.KEY_LTE_THRESHOLD_3, 0);
3048             verifyIntKey(provisioningManager, mIntQueue,
3049                     ProvisioningManager.KEY_1X_THRESHOLD, 0);
3050             verifyIntKey(provisioningManager, mIntQueue,
3051                     ProvisioningManager.KEY_WIFI_THRESHOLD_A, 0);
3052             verifyIntKey(provisioningManager, mIntQueue,
3053                     ProvisioningManager.KEY_WIFI_THRESHOLD_B, 0);
3054             verifyIntKey(provisioningManager, mIntQueue,
3055                     ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC, 5);
3056             verifyIntKey(provisioningManager, mIntQueue,
3057                     ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC, 5);
3058             verifyIntKey(provisioningManager, mIntQueue,
3059                     ProvisioningManager.KEY_1X_EPDG_TIMER_SEC, 5);
3060             verifyIntKey(provisioningManager, mIntQueue,
3061                     ProvisioningManager.KEY_MULTIENDPOINT_ENABLED, 0);
3062             verifyIntKey(provisioningManager, mIntQueue,
3063                     ProvisioningManager.KEY_RTT_ENABLED, 0);
3064             verifyStringKey(provisioningManager, mStringQueue,
3065                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID, "carrier_spec");
3066 
3067             automan.adoptShellPermissionIdentity();
3068             provisioningManager.unregisterProvisioningChangedCallback(callback);
3069         } finally {
3070             automan.dropShellPermissionIdentity();
3071         }
3072     }
3073 
3074     @Test
testProvisioningManagerProvisioningCaps()3075     public void testProvisioningManagerProvisioningCaps() throws Exception {
3076         if (!ImsUtils.shouldTestImsService()) {
3077             return;
3078         }
3079 
3080         triggerFrameworkConnectToCarrierImsService();
3081 
3082         PersistableBundle bundle = new PersistableBundle();
3083         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true);
3084         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, true);
3085         overrideCarrierConfig(bundle);
3086 
3087         ProvisioningManager provisioningManager =
3088                 ProvisioningManager.createForSubscriptionId(sTestSub);
3089 
3090         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3091         try {
3092             automan.adoptShellPermissionIdentity();
3093             boolean provisioningStatus = provisioningManager.getProvisioningStatusForCapability(
3094                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
3095                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
3096             provisioningManager.setProvisioningStatusForCapability(
3097                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
3098                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE, !provisioningStatus);
3099             // Make sure the change in provisioning status is correctly returned.
3100             assertEquals(!provisioningStatus,
3101                     provisioningManager.getProvisioningStatusForCapability(
3102                             MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
3103                             ImsRegistrationImplBase.REGISTRATION_TECH_LTE));
3104             // TODO: Enhance test to make sure the provisioning change is also sent to the
3105             // ImsService
3106 
3107             // set back to current status
3108             provisioningManager.setProvisioningStatusForCapability(
3109                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
3110                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE, provisioningStatus);
3111         } finally {
3112             automan.dropShellPermissionIdentity();
3113         }
3114 
3115         overrideCarrierConfig(null);
3116     }
3117 
3118     @Test
testProvisioningManagerRcsProvisioningCaps()3119     public void testProvisioningManagerRcsProvisioningCaps() throws Exception {
3120         if (!ImsUtils.shouldTestImsService()) {
3121             return;
3122         }
3123 
3124         triggerFrameworkConnectToCarrierImsService();
3125 
3126         PersistableBundle bundle = new PersistableBundle();
3127         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
3128         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL,
3129                 true);
3130         bundle.putBoolean(CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, true);
3131         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, true);
3132         overrideCarrierConfig(bundle);
3133 
3134         ProvisioningManager provisioningManager =
3135                 ProvisioningManager.createForSubscriptionId(sTestSub);
3136 
3137         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3138         try {
3139             automan.adoptShellPermissionIdentity();
3140             boolean provisioningStatus = provisioningManager.getRcsProvisioningStatusForCapability(
3141                     RCS_CAP_PRESENCE);
3142             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
3143                     !provisioningStatus);
3144             // Make sure the change in provisioning status is correctly returned.
3145             assertEquals(!provisioningStatus,
3146                     provisioningManager.getRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE));
3147             // TODO: Enhance test to make sure the provisioning change is also sent to the
3148             // ImsService
3149 
3150             // set back to current status
3151             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
3152                     provisioningStatus);
3153         } finally {
3154             automan.dropShellPermissionIdentity();
3155         }
3156 
3157         overrideCarrierConfig(null);
3158     }
3159 
3160     @Test
testProvisioningManagerRcsProvisioningChangedCallback()3161     public void testProvisioningManagerRcsProvisioningChangedCallback() throws Exception {
3162         if (!ImsUtils.shouldTestImsService()) {
3163             return;
3164         }
3165 
3166         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3167 
3168         final int errorCode = 403;
3169         final String errorString = "Forbidden";
3170         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3171         LinkedBlockingQueue<Integer> actionQueue = new LinkedBlockingQueue<>();
3172         LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
3173                 new LinkedBlockingQueue<>();
3174         ProvisioningManager.RcsProvisioningCallback cb =
3175                 buildRcsProvisioningCallback(actionQueue, paramsQueue);
3176         ProvisioningManager provisioningManager =
3177                 ProvisioningManager.createForSubscriptionId(sTestSub);
3178         ImsConfigImplBase config = sServiceConnector.getCarrierService().getConfig();
3179 
3180         //notify rcs configuration received, wait rcs gets ready and receives notification
3181         try {
3182             automan.adoptShellPermissionIdentity();
3183             provisioningManager.notifyRcsAutoConfigurationReceived(
3184                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
3185         } finally {
3186             automan.dropShellPermissionIdentity();
3187         }
3188 
3189         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3190         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
3191 
3192         try {
3193             automan.adoptShellPermissionIdentity();
3194             provisioningManager.registerRcsProvisioningCallback(
3195                     getContext().getMainExecutor(), cb);
3196         } finally {
3197             automan.dropShellPermissionIdentity();
3198         }
3199 
3200         //callback is expected immediately
3201         res = waitForIntResult(actionQueue);
3202         assertEquals(res, RCS_CONFIG_CB_CHANGED);
3203         RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
3204         assertNotNull(params);
3205         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG_DEFAULT.getBytes()));
3206 
3207         //verify callback when rcs configuration removed
3208         config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
3209         res = waitForIntResult(actionQueue);
3210         assertEquals(res, RCS_CONFIG_CB_RESET);
3211 
3212         //verify callback when rcs configuration received, compressed
3213         config.getIImsConfig().notifyRcsAutoConfigurationReceived(
3214                 ImsUtils.compressGzip(TEST_RCS_CONFIG_DEFAULT.getBytes()), true);
3215 
3216         res = waitForIntResult(actionQueue);
3217         assertEquals(res, RCS_CONFIG_CB_CHANGED);
3218         params = waitForResult(paramsQueue);
3219         assertNotNull(params);
3220         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG_DEFAULT.getBytes()));
3221 
3222         //verify callback when auto config error received
3223         config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
3224         res = waitForIntResult(actionQueue);
3225         assertEquals(res, RCS_CONFIG_CB_ERROR);
3226         params = waitForResult(paramsQueue);
3227         assertNotNull(params);
3228         assertTrue(params.mErrorCode != null && params.mErrorCode == errorCode);
3229         assertTrue(errorString.equals(params.mErrorString));
3230 
3231         //verify callback when config removed
3232         config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
3233         res = waitForIntResult(actionQueue);
3234         assertEquals(res, RCS_CONFIG_CB_RESET);
3235 
3236         //verify callback when rcs pre-provisioning configuration received
3237         TestAcsClient.getInstance().notifyPreProvisioning(TEST_RCS_PRE_CONFIG.getBytes());
3238 
3239         res = waitForIntResult(actionQueue);
3240         assertEquals(res, RCS_CONFIG_CB_PREPROV);
3241         params = waitForResult(paramsQueue);
3242         assertNotNull(params);
3243         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_PRE_CONFIG.getBytes()));
3244 
3245         //unregister callback and verify not to receive callback any more
3246         try {
3247             automan.adoptShellPermissionIdentity();
3248             provisioningManager.unregisterRcsProvisioningCallback(cb);
3249         } finally {
3250             automan.dropShellPermissionIdentity();
3251         }
3252         res = waitForIntResult(actionQueue);
3253         assertEquals(res, RCS_CONFIG_CB_DELETE);
3254 
3255         config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
3256         res = waitForIntResult(actionQueue, 500);
3257         assertEquals(res, Integer.MAX_VALUE);
3258     }
3259 
3260     @Test
testProvisioningManagerNotifyRcsAutoConfigurationReceived()3261     public void testProvisioningManagerNotifyRcsAutoConfigurationReceived() throws Exception {
3262         if (!ImsUtils.shouldTestImsService()) {
3263             return;
3264         }
3265 
3266         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3267 
3268         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3269         LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
3270         LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
3271                 new LinkedBlockingQueue<>();
3272         ProvisioningManager.RcsProvisioningCallback cb =
3273                 buildRcsProvisioningCallback(clientQueue, paramsQueue);
3274         ProvisioningManager provisioningManager =
3275                 ProvisioningManager.createForSubscriptionId(sTestSub);
3276         String configStr = TEST_RCS_CONFIG_DEFAULT;
3277 
3278         //notify rcs configuration received, wait rcs gets ready and receives notification
3279         try {
3280             automan.adoptShellPermissionIdentity();
3281             provisioningManager.notifyRcsAutoConfigurationReceived(
3282                     configStr.getBytes(), false);
3283         } finally {
3284             automan.dropShellPermissionIdentity();
3285         }
3286 
3287         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3288         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
3289 
3290         try {
3291             automan.adoptShellPermissionIdentity();
3292             provisioningManager.registerRcsProvisioningCallback(
3293                     getContext().getMainExecutor(), cb);
3294         } finally {
3295             automan.dropShellPermissionIdentity();
3296         }
3297 
3298         res = waitForIntResult(clientQueue);
3299         assertEquals(res, RCS_CONFIG_CB_CHANGED);
3300         RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
3301         assertNotNull(params);
3302         assertTrue(Arrays.equals(params.mConfig, configStr.getBytes()));
3303         assertTrue(Arrays.equals(
3304                 configStr.getBytes(), TestAcsClient.getInstance().getConfig()));
3305 
3306         configStr = TEST_RCS_CONFIG_SINGLE_REGISTRATION_DISABLED;
3307         try {
3308             automan.adoptShellPermissionIdentity();
3309             provisioningManager.notifyRcsAutoConfigurationReceived(
3310                     ImsUtils.compressGzip(configStr.getBytes()), true);
3311         } finally {
3312             automan.dropShellPermissionIdentity();
3313         }
3314 
3315         res = waitForIntResult(clientQueue);
3316         assertEquals(res, RCS_CONFIG_CB_CHANGED);
3317         params = waitForResult(paramsQueue);
3318         assertNotNull(params);
3319         assertTrue(Arrays.equals(params.mConfig, configStr.getBytes()));
3320 
3321         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3322         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
3323         assertTrue(Arrays.equals(
3324                 configStr.getBytes(), TestAcsClient.getInstance().getConfig()));
3325     }
3326 
3327     @Test
testProvisioningManagerTriggerRcsReconfiguration()3328     public void testProvisioningManagerTriggerRcsReconfiguration() throws Exception {
3329         if (!ImsUtils.shouldTestImsService()) {
3330             return;
3331         }
3332 
3333         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3334 
3335         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3336         LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
3337         ProvisioningManager.RcsProvisioningCallback cb =
3338                 buildRcsProvisioningCallback(clientQueue, null);
3339 
3340         ProvisioningManager provisioningManager =
3341                 ProvisioningManager.createForSubscriptionId(sTestSub);
3342 
3343         //notify rcs configuration received, wait rcs gets ready and receives notification
3344         try {
3345             automan.adoptShellPermissionIdentity();
3346             provisioningManager.notifyRcsAutoConfigurationReceived(
3347                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
3348         } finally {
3349             automan.dropShellPermissionIdentity();
3350         }
3351 
3352         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3353         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
3354 
3355         //set default rcs config
3356         try {
3357             automan.adoptShellPermissionIdentity();
3358             provisioningManager.registerRcsProvisioningCallback(
3359                     getContext().getMainExecutor(), cb);
3360         } finally {
3361             automan.dropShellPermissionIdentity();
3362         }
3363 
3364         res = waitForIntResult(clientQueue);
3365         assertEquals(res, RCS_CONFIG_CB_CHANGED);
3366 
3367         //test triggerRcsReconfiguration
3368         try {
3369             automan.adoptShellPermissionIdentity();
3370             provisioningManager.triggerRcsReconfiguration();
3371         } finally {
3372             automan.dropShellPermissionIdentity();
3373         }
3374 
3375         res = waitForIntResult(clientQueue);
3376         assertEquals(res, RCS_CONFIG_CB_RESET);
3377 
3378         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3379         assertEquals(res, TestAcsClient.ACTION_CONFIG_REMOVED);
3380 
3381         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3382         assertEquals(res, TestAcsClient.ACTION_TRIGGER_AUTO_CONFIG);
3383     }
3384 
3385     @Test
testProvisioningManagerSetRcsClientConfiguration()3386     public void testProvisioningManagerSetRcsClientConfiguration() throws Exception {
3387         if (!ImsUtils.shouldTestImsService()) {
3388             return;
3389         }
3390         RcsClientConfiguration rcc = new RcsClientConfiguration(
3391                 "1.0", "UP_1.0", "Android", "RCSAndrd-1.0");
3392         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3393 
3394         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3395         ProvisioningManager provisioningManager =
3396                 ProvisioningManager.createForSubscriptionId(sTestSub);
3397 
3398         //notify rcs configuration received, wait rcs gets ready and receives notification
3399         try {
3400             automan.adoptShellPermissionIdentity();
3401             provisioningManager.notifyRcsAutoConfigurationReceived(
3402                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
3403         } finally {
3404             automan.dropShellPermissionIdentity();
3405         }
3406 
3407         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3408         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
3409 
3410         try {
3411             automan.adoptShellPermissionIdentity();
3412             provisioningManager.setRcsClientConfiguration(rcc);
3413         } finally {
3414             automan.dropShellPermissionIdentity();
3415         }
3416 
3417         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
3418         assertEquals(res, TestAcsClient.ACTION_SET_RCS_CLIENT_CONFIG);
3419         assertEquals(rcc, TestAcsClient.getInstance().getRcc());
3420     }
3421 
3422     @Test
testProvisioningManagerRcsVolteSingleRegistrationCapable()3423     public void testProvisioningManagerRcsVolteSingleRegistrationCapable() throws Exception {
3424         if (!ImsUtils.shouldTestImsService()) {
3425             return;
3426         }
3427         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3428 
3429         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3430         boolean isSingleRegistrationEnabledOnDevice =
3431                 sServiceConnector.getDeviceSingleRegistrationEnabled();
3432         boolean isSingleRegistrationEnabledByCarrier =
3433                 sServiceConnector.getCarrierSingleRegistrationEnabled();
3434 
3435         ProvisioningManager provisioningManager =
3436                 ProvisioningManager.createForSubscriptionId(sTestSub);
3437         PersistableBundle bundle = new PersistableBundle();
3438         bundle.putBoolean(
3439                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
3440                 !isSingleRegistrationEnabledByCarrier);
3441         sSrcReceiver.clearQueue();
3442         overrideCarrierConfig(bundle);
3443         sSrcReceiver.waitForChanged();
3444         int capability = sSrcReceiver.getCapability();
3445 
3446         assertEquals(!isSingleRegistrationEnabledByCarrier,
3447                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
3448         try {
3449             automan.adoptShellPermissionIdentity();
3450             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
3451                     isSingleRegistrationEnabledOnDevice && !isSingleRegistrationEnabledByCarrier);
3452         } finally {
3453             automan.dropShellPermissionIdentity();
3454         }
3455 
3456         bundle = new PersistableBundle();
3457         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
3458                 isSingleRegistrationEnabledByCarrier);
3459         sSrcReceiver.clearQueue();
3460         overrideCarrierConfig(bundle);
3461         sSrcReceiver.waitForChanged();
3462         capability = sSrcReceiver.getCapability();
3463 
3464         assertEquals(isSingleRegistrationEnabledByCarrier,
3465                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
3466         try {
3467             automan.adoptShellPermissionIdentity();
3468             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
3469                     isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
3470         } finally {
3471             automan.dropShellPermissionIdentity();
3472         }
3473 
3474         sSrcReceiver.clearQueue();
3475         sServiceConnector.setDeviceSingleRegistrationEnabled(!isSingleRegistrationEnabledOnDevice);
3476         sSrcReceiver.waitForChanged();
3477         capability = sSrcReceiver.getCapability();
3478 
3479         assertEquals(!isSingleRegistrationEnabledOnDevice,
3480                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
3481         try {
3482             automan.adoptShellPermissionIdentity();
3483             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
3484                     !isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
3485         } finally {
3486             automan.dropShellPermissionIdentity();
3487         }
3488 
3489         sSrcReceiver.clearQueue();
3490         sServiceConnector.setDeviceSingleRegistrationEnabled(isSingleRegistrationEnabledOnDevice);
3491         sSrcReceiver.waitForChanged();
3492         capability = sSrcReceiver.getCapability();
3493 
3494         assertEquals(isSingleRegistrationEnabledOnDevice,
3495                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
3496         try {
3497             automan.adoptShellPermissionIdentity();
3498             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
3499                     isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
3500         } finally {
3501             automan.dropShellPermissionIdentity();
3502         }
3503 
3504         sServiceConnector.setDeviceSingleRegistrationEnabled(null);
3505         overrideCarrierConfig(null);
3506         sSrcReceiver.waitForChanged();
3507         capability = sSrcReceiver.getCapability();
3508 
3509         assertEquals(isSingleRegistrationEnabledOnDevice,
3510                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
3511         assertEquals(isSingleRegistrationEnabledByCarrier,
3512                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
3513     }
3514 
3515     /**
3516      * Verifies that the RTP header extensions are set as expected when D2D communication is
3517      * available on the device and for the current carrier.
3518      * @throws Exception
3519      */
3520     @Test
testSetRtpHeaderExtensions()3521     public void testSetRtpHeaderExtensions() throws Exception {
3522         if (!ImsUtils.shouldTestImsService()) {
3523             return;
3524         }
3525         sServiceConnector.setDeviceToDeviceCommunicationEnabled(true);
3526         try {
3527             PersistableBundle bundle = new PersistableBundle();
3528             bundle.putBoolean(
3529                     CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
3530                     true);
3531             bundle.putBoolean(CarrierConfigManager
3532                     .KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL, true);
3533             overrideCarrierConfig(bundle);
3534 
3535             triggerFrameworkConnectToCarrierImsService();
3536 
3537             sServiceConnector.getCarrierService().getMmTelFeature()
3538                     .getOfferedRtpHeaderExtensionLatch().await(5000, TimeUnit.MILLISECONDS);
3539             Set<RtpHeaderExtensionType> extensions = sServiceConnector.getCarrierService()
3540                     .getMmTelFeature().getOfferedRtpHeaderExtensionTypes();
3541 
3542             assertTrue(extensions.size() > 0);
3543         } finally {
3544             sServiceConnector.setDeviceToDeviceCommunicationEnabled(false);
3545             overrideCarrierConfig(null);
3546         }
3547     }
3548 
verifyIntKey(ProvisioningManager pm, LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)3549     private void verifyIntKey(ProvisioningManager pm,
3550             LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)
3551             throws Exception {
3552         pm.setProvisioningIntValue(key, value);
3553         assertTrue(waitForParam(intQueue, new Pair<>(key, value)));
3554         assertEquals(value, pm.getProvisioningIntValue(key));
3555     }
3556 
verifyStringKey(ProvisioningManager pm, LinkedBlockingQueue<Pair<Integer, String>> strQueue, int key, String value)3557     private void verifyStringKey(ProvisioningManager pm,
3558             LinkedBlockingQueue<Pair<Integer, String>> strQueue, int key, String value)
3559             throws Exception {
3560         pm.setProvisioningStringValue(key, value);
3561         assertTrue(waitForParam(strQueue, new Pair<>(key, value)));
3562         assertEquals(value, pm.getProvisioningStringValue(key));
3563     }
3564 
setupImsServiceForSms()3565     private void setupImsServiceForSms() throws Exception {
3566         MmTelFeature.MmTelCapabilities capabilities = new MmTelFeature.MmTelCapabilities(
3567                 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS);
3568         // Set up MMTEL
3569         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
3570                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
3571                 .build()));
3572         // Wait until MMTEL is created and onFeatureReady is called
3573         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
3574                 TestImsService.LATCH_CREATE_MMTEL));
3575         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
3576                 TestImsService.LATCH_MMTEL_READY));
3577         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
3578         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
3579                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
3580                 sTestSlot, serviceSlot);
3581         // Wait until ImsSmsDispatcher connects and calls onReady.
3582         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
3583                 .waitForOnReadyLatch());
3584         // Set Registered and SMS capable
3585         sServiceConnector.getCarrierService().getMmTelFeature().setCapabilities(capabilities);
3586         sServiceConnector.getCarrierService().getImsService().getRegistration(0).onRegistered(1);
3587         sServiceConnector.getCarrierService().getMmTelFeature()
3588                 .notifyCapabilitiesStatusChanged(capabilities);
3589 
3590         // Wait a second for the notifyCapabilitiesStatusChanged indication to be processed on the
3591         // main telephony thread - currently no better way of knowing that telephony has processed
3592         // this command. SmsManager#isImsSmsSupported() is @hide and must be updated to use new API.
3593         Thread.sleep(1000);
3594     }
3595 
triggerFrameworkConnectToLocalImsServiceBindRcsFeature()3596     private void triggerFrameworkConnectToLocalImsServiceBindRcsFeature() throws Exception {
3597         // Connect to the ImsService with the RCS feature.
3598         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
3599                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
3600                 .build()));
3601         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
3602         // Framework did not call it.
3603         assertTrue("Did not receive createRcsFeature", sServiceConnector.getCarrierService()
3604                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_RCS));
3605         assertTrue("Did not receive RcsFeature#onReady", sServiceConnector.getCarrierService()
3606                 .waitForLatchCountdown(TestImsService.LATCH_RCS_READY));
3607         // Make sure the RcsFeature was created in the test service.
3608         assertNotNull("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
3609                 + "called!", sServiceConnector.getCarrierService().getRcsFeature());
3610         int serviceSlot = sServiceConnector.getCarrierService().getRcsFeature().getSlotIndex();
3611         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
3612                         + "assigned slot (" + serviceSlot + "+ for the associated RcsFeature",
3613                 sTestSlot, serviceSlot);
3614     }
3615 
triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature()3616     private void triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature() throws Exception {
3617         // Connect to the ImsService with the RCS feature.
3618         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
3619                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
3620                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
3621                 .build()));
3622 
3623         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
3624         // Framework did not call it.
3625         assertTrue("Did not receive createMmTelFeature", sServiceConnector.getCarrierService()
3626                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_MMTEL));
3627         assertTrue("Did not receive MmTelFeature#onReady", sServiceConnector.getCarrierService()
3628                 .waitForLatchCountdown(TestImsService.LATCH_MMTEL_READY));
3629         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
3630                 sServiceConnector.getCarrierService().getMmTelFeature());
3631         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
3632         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
3633                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
3634                 sTestSlot, serviceSlot);
3635 
3636         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
3637         // Framework did not call it.
3638         assertTrue("Did not receive createRcsFeature", sServiceConnector.getCarrierService()
3639                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_RCS));
3640         assertTrue("Did not receive RcsFeature#onReady", sServiceConnector.getCarrierService()
3641                 .waitForLatchCountdown(TestImsService.LATCH_RCS_READY));
3642         // Make sure the RcsFeature was created in the test service.
3643         assertNotNull("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
3644                 + "called!", sServiceConnector.getCarrierService().getRcsFeature());
3645         assertTrue("Did not receive RcsFeature#setCapabilityExchangeEventListener",
3646                 sServiceConnector.getCarrierService().waitForLatchCountdown(
3647                         TestImsService.LATCH_UCE_LISTENER_SET));
3648         serviceSlot = sServiceConnector.getCarrierService().getRcsFeature().getSlotIndex();
3649         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
3650                         + "assigned slot (" + serviceSlot + "+ for the associated RcsFeature",
3651                 sTestSlot, serviceSlot);
3652     }
3653 
triggerFrameworkConnectToCarrierImsService()3654     private void triggerFrameworkConnectToCarrierImsService() throws Exception {
3655         // Connect to the ImsService with the MmTel feature.
3656         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
3657                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
3658                 .build()));
3659         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
3660         // Framework did not call it.
3661         assertTrue("Did not receive createMmTelFeature", sServiceConnector.getCarrierService()
3662                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_MMTEL));
3663         assertTrue("Did not receive MmTelFeature#onReady", sServiceConnector.getCarrierService()
3664                 .waitForLatchCountdown(TestImsService.LATCH_MMTEL_READY));
3665         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
3666                 sServiceConnector.getCarrierService().getMmTelFeature());
3667         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
3668         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
3669                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
3670                 sTestSlot, serviceSlot);
3671     }
3672 
buildRcsProvisioningCallback( LinkedBlockingQueue<Integer> actionQueue, LinkedBlockingQueue<RcsProvisioningCallbackParams> paramQueue)3673     private ProvisioningManager.RcsProvisioningCallback buildRcsProvisioningCallback(
3674             LinkedBlockingQueue<Integer> actionQueue,
3675             LinkedBlockingQueue<RcsProvisioningCallbackParams> paramQueue) {
3676         return new ProvisioningManager.RcsProvisioningCallback() {
3677             @Override
3678             public void onConfigurationChanged(byte[] configXml) {
3679                 super.onConfigurationChanged(configXml);
3680                 actionQueue.offer(RCS_CONFIG_CB_CHANGED);
3681                 if (paramQueue != null) {
3682                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
3683                     params.mConfig = configXml;
3684                     paramQueue.offer(params);
3685                 }
3686             }
3687 
3688             @Override
3689             public void onAutoConfigurationErrorReceived(int code, String str) {
3690                 super.onAutoConfigurationErrorReceived(code, str);
3691                 actionQueue.offer(RCS_CONFIG_CB_ERROR);
3692                 if (paramQueue != null) {
3693                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
3694                     params.mErrorCode = code;
3695                     params.mErrorString = str;
3696                     paramQueue.offer(params);
3697                 }
3698             }
3699 
3700             @Override
3701             public void onConfigurationReset() {
3702                 super.onConfigurationReset();
3703                 actionQueue.offer(RCS_CONFIG_CB_RESET);
3704             }
3705 
3706             @Override
3707             public void onRemoved() {
3708                 super.onRemoved();
3709                 actionQueue.offer(RCS_CONFIG_CB_DELETE);
3710             }
3711 
3712             @Override
3713             public void onPreProvisioningReceived(byte[] configXml) {
3714                 super.onPreProvisioningReceived(configXml);
3715                 actionQueue.offer(RCS_CONFIG_CB_PREPROV);
3716                 if (paramQueue != null) {
3717                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
3718                     params.mConfig = configXml;
3719                     paramQueue.offer(params);
3720                 }
3721             }
3722         };
3723     }
3724     // Waiting for ImsRcsManager to become public before implementing RegistrationManager,
3725     // Duplicate these methods for now.
3726     private void verifyRegistrationState(ImsRcsManager regManager, int expectedState)
3727             throws Exception {
3728         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3729         assertTrue(ImsUtils.retryUntilTrue(() -> {
3730             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
3731                     (m) -> m.getRegistrationState(getContext().getMainExecutor(), mQueue::offer),
3732                     "android.permission.READ_PRECISE_PHONE_STATE");
3733             return waitForIntResult(mQueue) == expectedState;
3734         }));
3735     }
3736 
3737     // Waiting for ImsRcsManager to become public before implementing RegistrationManager,
3738     // Duplicate these methods for now.
3739     private void verifyRegistrationTransportType(ImsRcsManager regManager,
3740             int expectedTransportType) throws Exception {
3741         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3742         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
3743                 (m) -> m.getRegistrationTransportType(getContext().getMainExecutor(),
3744                         mQueue::offer),
3745                 "android.permission.READ_PRECISE_PHONE_STATE");
3746         assertEquals(expectedTransportType, waitForIntResult(mQueue));
3747     }
3748 
3749     private void verifyRegistrationState(RegistrationManager regManager, int expectedState)
3750             throws Exception {
3751         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3752         assertTrue(ImsUtils.retryUntilTrue(() -> {
3753             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
3754                     (m) -> m.getRegistrationState(getContext().getMainExecutor(), mQueue::offer));
3755             return waitForIntResult(mQueue) == expectedState;
3756         }));
3757     }
3758 
3759     private void verifyRegistrationTransportType(RegistrationManager regManager,
3760             int expectedTransportType) throws Exception {
3761         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3762         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
3763                 (m) -> m.getRegistrationTransportType(getContext().getMainExecutor(),
3764                         mQueue::offer));
3765         assertEquals(expectedTransportType, waitForIntResult(mQueue));
3766     }
3767 
3768     private void verifyRegistering(int tech, ArraySet<String> featureTags,
3769             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
3770             int expectedAttrFlags) throws Exception {
3771         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
3772                 .setFeatureTags(featureTags).build();
3773         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(attr);
3774         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
3775         assertNotNull(attrResult);
3776         assertEquals(tech, attrResult.getRegistrationTechnology());
3777         assertEquals(expectedTransport, attrResult.getTransportType());
3778         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
3779         assertEquals(featureTags, attrResult.getFeatureTags());
3780     }
3781 
3782     private void verifyRegistered(int tech, ArraySet<String> featureTags,
3783             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
3784             int expectedAttrFlags) throws Exception {
3785         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
3786                 .setFeatureTags(featureTags).build();
3787         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
3788         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
3789         assertNotNull(attrResult);
3790         assertEquals(tech, attrResult.getRegistrationTechnology());
3791         assertEquals(expectedTransport, attrResult.getTransportType());
3792         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
3793         assertEquals(featureTags, attrResult.getFeatureTags());
3794     }
3795 
3796     private <T> boolean waitForParam(LinkedBlockingQueue<T> queue, T waitParam) throws Exception {
3797         T result;
3798         while ((result = waitForResult(queue)) != null) {
3799             if (waitParam.equals(result)) {
3800                 return true;
3801             }
3802         }
3803         return false;
3804     }
3805 
3806     private <T> T waitForResult(LinkedBlockingQueue<T> queue) throws Exception {
3807         return queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3808     }
3809 
3810     private int waitForIntResult(LinkedBlockingQueue<Integer> queue) throws Exception {
3811         Integer result = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
3812         return result != null ? result : Integer.MAX_VALUE;
3813     }
3814 
3815     private int waitForIntResult(LinkedBlockingQueue<Integer> queue, int timeout)
3816             throws Exception {
3817         Integer result = queue.poll(timeout, TimeUnit.MILLISECONDS);
3818         return result != null ? result : Integer.MAX_VALUE;
3819     }
3820 
3821     private static void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
3822         CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getInstrumentation()
3823                 .getContext().getSystemService(CarrierConfigManager.class);
3824         sReceiver.clearQueue();
3825         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(carrierConfigManager,
3826                 (m) -> m.overrideConfig(sTestSub, bundle));
3827         sReceiver.waitForChanged();
3828     }
3829 
3830     private static Context getContext() {
3831         return InstrumentationRegistry.getInstrumentation().getContext();
3832     }
3833 
3834     // Copied from com.android.internal.util.HexDump
3835     private static byte[] hexStringToByteArray(String hexString) {
3836         int length = hexString.length();
3837         byte[] buffer = new byte[length / 2];
3838 
3839         for (int i = 0; i < length; i += 2) {
3840             buffer[i / 2] =
3841                     (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
3842         }
3843 
3844         return buffer;
3845     }
3846 
3847     // Copied from com.android.internal.util.HexDump
3848     private static int toByte(char c) {
3849         if (c >= '0' && c <= '9') return (c - '0');
3850         if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
3851         if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
3852 
3853         throw new RuntimeException("Invalid hex char '" + c + "'");
3854     }
3855 }
3856