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 android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
20 import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
21 import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT;
22 import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_RAT_BLOCK;
23 import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCKS;
24 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
25 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
26 
27 import static junit.framework.Assert.assertFalse;
28 import static junit.framework.Assert.assertNotNull;
29 import static junit.framework.Assert.assertNull;
30 import static junit.framework.Assert.assertTrue;
31 
32 import static org.junit.Assert.assertArrayEquals;
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertNotEquals;
35 import static org.junit.Assert.fail;
36 import static org.junit.Assume.assumeTrue;
37 
38 import android.annotation.Nullable;
39 import android.app.Activity;
40 import android.app.UiAutomation;
41 import android.content.BroadcastReceiver;
42 import android.content.Context;
43 import android.content.Intent;
44 import android.content.IntentFilter;
45 import android.content.res.Resources;
46 import android.net.Uri;
47 import android.os.Build;
48 import android.os.PersistableBundle;
49 import android.platform.test.annotations.RequiresFlagsEnabled;
50 import android.platform.test.flag.junit.CheckFlagsRule;
51 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
52 import android.telecom.PhoneAccount;
53 import android.telephony.AccessNetworkConstants;
54 import android.telephony.CarrierConfigManager;
55 import android.telephony.SmsManager;
56 import android.telephony.SmsMessage;
57 import android.telephony.SubscriptionManager;
58 import android.telephony.TelephonyManager;
59 import android.telephony.cts.AsyncSmsMessageListener;
60 import android.telephony.cts.CarrierCapability;
61 import android.telephony.cts.SmsReceiverHelper;
62 import android.telephony.cts.util.TelephonyUtils;
63 import android.telephony.ims.ImsException;
64 import android.telephony.ims.ImsManager;
65 import android.telephony.ims.ImsMmTelManager;
66 import android.telephony.ims.ImsRcsManager;
67 import android.telephony.ims.ImsReasonInfo;
68 import android.telephony.ims.ImsRegistrationAttributes;
69 import android.telephony.ims.ImsStateCallback;
70 import android.telephony.ims.MediaThreshold;
71 import android.telephony.ims.ProvisioningManager;
72 import android.telephony.ims.PublishAttributes;
73 import android.telephony.ims.RcsClientConfiguration;
74 import android.telephony.ims.RcsContactUceCapability;
75 import android.telephony.ims.RcsUceAdapter;
76 import android.telephony.ims.RegistrationManager;
77 import android.telephony.ims.RtpHeaderExtensionType;
78 import android.telephony.ims.SipDelegateManager;
79 import android.telephony.ims.SipDetails;
80 import android.telephony.ims.feature.ImsFeature;
81 import android.telephony.ims.feature.MmTelFeature;
82 import android.telephony.ims.feature.RcsFeature;
83 import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
84 import android.telephony.ims.stub.CapabilityExchangeEventListener;
85 import android.telephony.ims.stub.ImsConfigImplBase;
86 import android.telephony.ims.stub.ImsFeatureConfiguration;
87 import android.telephony.ims.stub.ImsRegistrationImplBase;
88 import android.util.ArraySet;
89 import android.util.Base64;
90 import android.util.Pair;
91 
92 import androidx.test.ext.junit.runners.AndroidJUnit4;
93 import androidx.test.platform.app.InstrumentationRegistry;
94 
95 import com.android.compatibility.common.util.ApiTest;
96 import com.android.compatibility.common.util.ShellIdentityUtils;
97 import com.android.internal.telephony.flags.Flags;
98 
99 import org.junit.After;
100 import org.junit.AfterClass;
101 import org.junit.Assert;
102 import org.junit.Before;
103 import org.junit.BeforeClass;
104 import org.junit.Ignore;
105 import org.junit.Rule;
106 import org.junit.Test;
107 import org.junit.runner.RunWith;
108 
109 import java.util.ArrayList;
110 import java.util.Arrays;
111 import java.util.Collection;
112 import java.util.Collections;
113 import java.util.HashSet;
114 import java.util.List;
115 import java.util.Set;
116 import java.util.concurrent.CountDownLatch;
117 import java.util.concurrent.LinkedBlockingQueue;
118 import java.util.concurrent.TimeUnit;
119 
120 /**
121  * CTS tests for ImsService API.
122  */
123 @RunWith(AndroidJUnit4.class)
124 public class ImsServiceTest {
125     @Rule
126     public final CheckFlagsRule mCheckFlagsRule =
127             DeviceFlagsValueProvider.createCheckFlagsRule();
128 
129     private static ImsServiceConnector sServiceConnector;
130 
131     private static final int KEY_VOLTE_PROVISIONING_STATUS =
132             ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
133     private static final int KEY_VT_PROVISIONING_STATUS =
134             ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
135     private static final int KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE =
136             ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
137     private static final int KEY_EAB_PROVISIONING_STATUS =
138             ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
139 
140     private static final int MMTEL_CAP_VOICE = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
141     private static final int MMTEL_CAP_VIDEO = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
142     private static final int MMTEL_CAP_UT = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
143     private static final int MMTEL_CAP_SMS = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS;
144     private static final int MMTEL_CAP_COMPOSER =
145             MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER;
146 
147     private static final int RCS_CAP_NONE = RcsImsCapabilities.CAPABILITY_TYPE_NONE;
148     private static final int RCS_CAP_OPTIONS = RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
149     private static final int RCS_CAP_PRESENCE = RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
150 
151     private static final int IMS_REGI_TECH_NONE = ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
152     private static final int IMS_REGI_TECH_LTE = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
153     private static final int IMS_REGI_TECH_IWLAN = ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
154     private static final int IMS_REGI_TECH_CROSS_SIM =
155             ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
156     private static final int IMS_REGI_TECH_NR = ImsRegistrationImplBase.REGISTRATION_TECH_NR;
157 
158     private static final String SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING =
159             "SUPPORT_PROVISION_STATUS_FOR_CAPABILITY";
160 
161     private static final boolean DEBUG = !"user".equals(Build.TYPE);
162     private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
163     private static final String MSG_CONTENTS = "hi";
164     private static final String EXPECTED_RECEIVED_MESSAGE = "foo5";
165     private static final String DEST_NUMBER = "5555554567";
166     private static final String SRC_NUMBER = "5555551234";
167     private static final byte[] EXPECTED_PDU =
168             new byte[]{1, 0, 10, -127, 85, 85, 85, 33, 67, 0, 0, 2, -24, 52};
169     private static final String RECEIVED_MESSAGE = "B5EhYBMDIPgEC5FhBWKFkPEAAEGQQlGDUooE5ve7Bg==";
170     private static final byte[] STATUS_REPORT_PDU =
171             hexStringToByteArray("0006000681214365919061800000639190618000006300");
172     private static final byte[] CLASS2SMPP_PDU =
173             hexStringToByteArray("07914151551512f221110A8178563412107FF20666B2996C2603");
174     private static final int EXPECTED_MESSAGEREF = 0x11;
175     private static int sTestSlot = 0;
176     private static int sTestSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
177     private static boolean sDeviceUceEnabled;
178     private static boolean sSupportsImsHal = false;
179 
180     private static final int TEST_CONFIG_KEY = 1000;
181     private static final int TEST_CONFIG_VALUE_INT = 0xDEADBEEF;
182     private static final String TEST_CONFIG_VALUE_STRING = "DEADBEEF";
183 
184     private static final String SUPPORT_PUBLISHING_STATE_STRING = "SUPPORT_PUBLISHING_STATE";
185 
186     private static final String TEST_RCS_CONFIG_DEFAULT = "<?xml version=\"1.0\"?>\n"
187             + "<wap-provisioningdoc version=\"1.1\">\n"
188             + "\t<characteristic type=\"APPLICATION\">\n"
189             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
190             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
191             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
192             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
193             + "\t\t\t<characteristic type=\"Ext\">\n"
194             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
195             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
196             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"1\"/>\n"
197             + "\t\t\t\t</characteristic>\n"
198             + "\t\t\t</characteristic>\n"
199             + "\t\t</characteristic>\n"
200             + "\t\t<characteristic type=\"SERVICES\">\n"
201             + "\t\t\t<parm name=\"SupportedRCSProfileVersions\" value=\"UP2.3\"/>\n"
202             + "\t\t\t<parm name=\"ChatAuth\" value=\"1\"/>\n"
203             + "\t\t\t<parm name=\"GroupChatAuth\" value=\"1\"/>\n"
204             + "\t\t\t<parm name=\"ftAuth\" value=\"1\"/>\n"
205             + "\t\t\t<parm name=\"standaloneMsgAuth\" value=\"1\"/>\n"
206             + "\t\t\t<parm name=\"geolocPushAuth\" value=\"1\"/>\n"
207             + "\t\t\t<characteristic type=\"Ext\">\n"
208             + "\t\t\t\t<characteristic type=\"DataOff\">\n"
209             + "\t\t\t\t\t<parm name=\"rcsMessagingDataOff\" value=\"1\"/>\n"
210             + "\t\t\t\t\t<parm name=\"fileTransferDataOff\" value=\"1\"/>\n"
211             + "\t\t\t\t\t<parm name=\"mmsDataOff\" value=\"1\"/>\n"
212             + "\t\t\t\t\t<parm name=\"syncDataOff\" value=\"1\"/>\n"
213             + "\t\t\t\t\t<characteristic type=\"Ext\"/>\n"
214             + "\t\t\t\t</characteristic>\n"
215             + "\t\t\t</characteristic>\n"
216             + "\t\t</characteristic>\n"
217             + "\t</characteristic>\n"
218             + "</wap-provisioningdoc>\n";
219 
220     private static final String TEST_RCS_CONFIG_SINGLE_REGISTRATION_DISABLED =
221             "<?xml version=\"1.0\"?>\n"
222             + "<wap-provisioningdoc version=\"1.1\">\n"
223             + "\t<characteristic type=\"APPLICATION\">\n"
224             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
225             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
226             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
227             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
228             + "\t\t\t<characteristic type=\"Ext\">\n"
229             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
230             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
231             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"0\"/>\n"
232             + "\t\t\t\t</characteristic>\n"
233             + "\t\t\t</characteristic>\n"
234             + "\t\t</characteristic>\n"
235             + "\t</characteristic>\n"
236             + "</wap-provisioningdoc>\n";
237     private static final String TEST_RCS_PRE_CONFIG = "<RCSPreProvisiniongConfig>\n"
238             + "\t<VERS>\n"
239             + "\t\t<version>1</version>\n"
240             + "\t\t<validity>1728000</validity>\n"
241             + "\t</VERS>\n"
242             + "\t<TOKEN>\n"
243             + "\t\t<token>X</token>\n"
244             + "\t</TOKEN>\n"
245             + "\t<EXT>\n"
246             + "\t\t<url>https://rcs.mnc123.mcc456.pub.3gppnetwork.org</url>\n"
247             + "\t</EXT>\n"
248             + "</RCSPreProvisiniongConfig>";
249     private static final int RCS_CONFIG_CB_UNKNOWN = Integer.MAX_VALUE;
250     private static final int RCS_CONFIG_CB_CHANGED = 0;
251     private static final int RCS_CONFIG_CB_ERROR   = 1;
252     private static final int RCS_CONFIG_CB_RESET   = 2;
253     private static final int RCS_CONFIG_CB_DELETE  = 3;
254     private static final int RCS_CONFIG_CB_PREPROV = 4;
255 
256     private static final String CHAT_FEATURE_TAG =
257             "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"";
258     public static final String FILE_TRANSFER_FEATURE_TAG =
259             "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fthttp\"";
260     private static final String CHAT_SERVICE_ID =
261             "org.openmobilealliance:ChatSession";
262     private static final String FILE_TRANSFER_SERVICE_ID =
263             "org.openmobilealliance:File-Transfer-HTTP";
264 
265     private static final int FEATURE_STATE_READY = 0;
266     private static final int TEST_PACKET_LOSS_RATE_THRESHOLD = 17;
267     private static final int TEST_JITTER_THRESHOLD = 74;
268     private static final long TEST_INACTIVITY_MILLIS = 4779;
269 
270     // When ImsService notifies registration or unregistration, framework needs time to handle
271     // that event.
272     public static final int TEST_OPERATION_TIME_MS = 1000;
273 
274     private static CarrierConfigReceiver sReceiver;
275     private static SingleRegistrationCapabilityReceiver sSrcReceiver;
276 
277     private abstract static class BaseReceiver extends BroadcastReceiver {
278         protected CountDownLatch mLatch = new CountDownLatch(1);
279 
clearQueue()280         void clearQueue() {
281             mLatch = new CountDownLatch(1);
282         }
283 
waitForChanged()284         void waitForChanged() throws Exception {
285             mLatch.await(5000, TimeUnit.MILLISECONDS);
286         }
287     }
288 
289     private static class CarrierConfigReceiver extends BaseReceiver {
290         private final int mSubId;
291 
CarrierConfigReceiver(int subId)292         CarrierConfigReceiver(int subId) {
293             mSubId = subId;
294         }
295 
296         @Override
onReceive(Context context, Intent intent)297         public void onReceive(Context context, Intent intent) {
298             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
299                 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
300                 if (mSubId == subId) {
301                     mLatch.countDown();
302                 }
303             }
304         }
305     }
306 
307     private static class SingleRegistrationCapabilityReceiver extends BaseReceiver {
308         private int mCapability;
309         private int mSubId;
310 
SingleRegistrationCapabilityReceiver(int subId)311         SingleRegistrationCapabilityReceiver(int subId) {
312             mSubId = subId;
313         }
314 
315         @Override
onReceive(Context context, Intent intent)316         public void onReceive(Context context, Intent intent) {
317             if (ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE
318                     .equals(intent.getAction())) {
319                 // if sub id in intent is not expected, then intent should be ignored.
320                 int subId = intent.getIntExtra(ProvisioningManager.EXTRA_SUBSCRIPTION_ID,
321                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
322                 if (mSubId != subId) {
323                     return;
324                 }
325 
326                 mCapability = intent.getIntExtra(ProvisioningManager.EXTRA_STATUS,
327                         ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE
328                         | ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE);
329                 mLatch.countDown();
330             }
331         }
332 
getCapability()333         int getCapability() {
334             return mCapability;
335         }
336     }
337 
338     private static class RcsProvisioningCallbackParams {
339         byte[] mConfig;
340         Integer mErrorCode;
341         String mErrorString;
342     }
343 
344     @BeforeClass
beforeAllTests()345     public static void beforeAllTests() throws Exception {
346         if (!ImsUtils.shouldTestImsService()) {
347             return;
348         }
349         TelephonyManager tm = (TelephonyManager) getContext()
350                 .getSystemService(Context.TELEPHONY_SERVICE);
351         Pair<Integer, Integer> halVersion = tm.getHalVersion(TelephonyManager.HAL_SERVICE_IMS);
352         if (!(halVersion.equals(TelephonyManager.HAL_VERSION_UNKNOWN)
353                 || halVersion.equals(TelephonyManager.HAL_VERSION_UNSUPPORTED))) {
354             sSupportsImsHal = true;
355         }
356         sTestSub = ImsUtils.getPreferredActiveSubId();
357         sTestSlot = SubscriptionManager.getSlotIndex(sTestSub);
358 
359         if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
360             return;
361         }
362         sServiceConnector = new ImsServiceConnector(InstrumentationRegistry.getInstrumentation());
363         // Remove all live ImsServices until after these tests are done
364         sServiceConnector.clearAllActiveImsServices(sTestSlot);
365         // Configure SMS receiver based on the Android version.
366         sServiceConnector.setDefaultSmsApp();
367 
368         // Save the original device uce enabled config and override it.
369         sDeviceUceEnabled = sServiceConnector.getDeviceUceEnabled();
370         sServiceConnector.setDeviceUceEnabled(true);
371 
372         sReceiver = new CarrierConfigReceiver(sTestSub);
373         IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
374         // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away.
375         InstrumentationRegistry.getInstrumentation().getContext()
376                 .registerReceiver(sReceiver, filter);
377 
378         sSrcReceiver = new SingleRegistrationCapabilityReceiver(sTestSub);
379         InstrumentationRegistry.getInstrumentation().getContext()
380                 .registerReceiver(sSrcReceiver, new IntentFilter(
381                         ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE));
382     }
383 
384     @AfterClass
afterAllTests()385     public static void afterAllTests() throws Exception {
386         if (!ImsUtils.shouldTestImsService()) {
387             return;
388         }
389         // Restore all ImsService configurations that existed before the test.
390         if (sServiceConnector != null) {
391             sServiceConnector.disconnectServices();
392             sServiceConnector.setDeviceUceEnabled(sDeviceUceEnabled);
393         }
394         sServiceConnector = null;
395 
396         // Ensure there are no CarrierConfig overrides as well as reset the ImsResolver in case the
397         // ImsService override changed in CarrierConfig while we were overriding it.
398         overrideCarrierConfig(null);
399 
400         if (sReceiver != null) {
401             InstrumentationRegistry.getInstrumentation().getContext().unregisterReceiver(sReceiver);
402             sReceiver = null;
403         }
404 
405         if (sSrcReceiver != null) {
406             InstrumentationRegistry.getInstrumentation()
407                     .getContext().unregisterReceiver(sSrcReceiver);
408             sSrcReceiver = null;
409         }
410     }
411 
412     @Before
beforeTest()413     public void beforeTest() throws Exception {
414         if (!ImsUtils.shouldTestImsService()) {
415             return;
416         }
417         TelephonyManager tm = (TelephonyManager) InstrumentationRegistry.getInstrumentation()
418                 .getContext().getSystemService(Context.TELEPHONY_SERVICE);
419         if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
420             fail("This test requires that there is a SIM in the device!");
421         }
422         // Correctness check: ensure that the subscription hasn't changed between tests.
423         int subId = SubscriptionManager.getSubscriptionId(sTestSlot);
424         if (subId != sTestSub) {
425             fail("The found subId " + subId + " does not match the test sub id " + sTestSub);
426         }
427 
428         TestAcsClient.getInstance().reset();
429         sServiceConnector.setSingleRegistrationTestModeEnabled(true);
430     }
431 
432     @After
afterTest()433     public void afterTest() throws Exception {
434         TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
435                 TelephonyUtils.CTS_APP_PACKAGE, SUPPORT_PUBLISHING_STATE_STRING);
436         TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
437                 TelephonyUtils.CTS_APP_PACKAGE, SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
438 
439         if (!ImsUtils.shouldTestImsService()) {
440             return;
441         }
442         // Unbind the ImsService after the test completes.
443         if (sServiceConnector != null) {
444             sServiceConnector.setSingleRegistrationTestModeEnabled(false);
445             sServiceConnector.disconnectCarrierImsService();
446             sServiceConnector.disconnectDeviceImsService();
447         }
448     }
449 
450     @Test
testCarrierImsServiceBindRcsFeature()451     public void testCarrierImsServiceBindRcsFeature() throws Exception {
452         if (!ImsUtils.shouldTestImsService()) {
453             return;
454         }
455         // Connect to the ImsService with the RCS feature.
456         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
457                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
458                 .build()));
459         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
460         // Framework did not call it.
461         sServiceConnector.getCarrierService().waitForLatchCountdown(
462                 TestImsService.LATCH_CREATE_RCS);
463         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
464                 sServiceConnector.getCarrierService().getRcsFeature());
465         assertTrue("Not expected subId received!",
466                 isExpectedSubId(sServiceConnector.getCarrierService().getSubIDs()));
467     }
468 
469     @Test
testCarrierImsServiceBindRcsFeatureForExecutor()470     public void testCarrierImsServiceBindRcsFeatureForExecutor() throws Exception {
471         if (!ImsUtils.shouldTestImsService()) {
472             return;
473         }
474         sServiceConnector.setExecutorTestType(true);
475         // Connect to the ImsService with the RCS feature.
476         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
477                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
478                 .build()));
479         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
480         // Framework did not call it.
481         sServiceConnector.getCarrierService().waitForLatchCountdown(
482                 TestImsService.LATCH_CREATE_RCS);
483         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
484                 sServiceConnector.getCarrierService().getRcsFeature());
485     }
486 
487     @Test
testCarrierImsServiceBindMmTelFeature()488     public void testCarrierImsServiceBindMmTelFeature() throws Exception {
489         if (!ImsUtils.shouldTestImsService()) {
490             return;
491         }
492         // Connect to the ImsService with the MmTel feature.
493         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
494                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
495                 .build()));
496         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
497         // Framework did not call it.
498         sServiceConnector.getCarrierService().waitForLatchCountdown(
499                 TestImsService.LATCH_CREATE_MMTEL);
500         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
501                 sServiceConnector.getCarrierService().getMmTelFeature());
502         // Wait for the framework to set the capabilities on the ImsService
503         sServiceConnector.getCarrierService().waitForLatchCountdown(
504                 TestImsService.LATCH_MMTEL_CAP_SET);
505         assertTrue("Not expected subId received!",
506                 isExpectedSubId(sServiceConnector.getCarrierService().getSubIDs()));
507     }
508 
509     @Test
testCarrierImsServiceBindRcsFeatureEnableDisableIms()510     public void testCarrierImsServiceBindRcsFeatureEnableDisableIms() throws Exception {
511         if (!ImsUtils.shouldTestImsService()) {
512             return;
513         }
514         // Connect to the ImsService with the RCS feature.
515         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
516                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
517                 .build()));
518         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
519         // Framework did not call it.
520         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
521                 TestImsService.LATCH_CREATE_RCS));
522 
523         //Enable IMS and ensure that we receive the call to enable IMS in the ImsService.
524         sServiceConnector.enableImsService(sTestSlot);
525         // Wait for command in ImsService
526         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
527                 TestImsService.LATCH_ENABLE_IMS));
528         assertTrue(sServiceConnector.getCarrierService().isEnabled());
529 
530         //Disable IMS and ensure that we receive the call to enable IMS in the ImsService.
531         sServiceConnector.disableImsService(sTestSlot);
532         // Wait for command in ImsService
533         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
534                 TestImsService.LATCH_DISABLE_IMS));
535         assertFalse(sServiceConnector.getCarrierService().isEnabled());
536         assertTrue("Not expected subId received!",
537                 isExpectedSubId(sServiceConnector.getCarrierService().getSubIDs()));
538     }
539 
540     @Test
testCarrierImsServiceBindRcsChangeToMmtel()541     public void testCarrierImsServiceBindRcsChangeToMmtel() throws Exception {
542         if (!ImsUtils.shouldTestImsService()) {
543             return;
544         }
545         // Connect to the ImsService with the RCS feature.
546         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
547                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
548                 .build()));
549         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
550         // Framework did not call it.
551         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
552                 TestImsService.LATCH_CREATE_RCS));
553 
554         // Change the supported feature to MMTEl
555         sServiceConnector.getCarrierService().getImsService().onUpdateSupportedImsFeatures(
556                 new ImsFeatureConfiguration.Builder()
557                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL).build());
558 
559         // createMmTelFeature should be called.
560         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
561                 TestImsService.LATCH_CREATE_MMTEL));
562 
563         // Wait for the framework to set the capabilities on the ImsService
564         sServiceConnector.getCarrierService().waitForLatchCountdown(
565                 TestImsService.LATCH_MMTEL_CAP_SET);
566         assertTrue("Not expected subId received!",
567                 isExpectedSubId(sServiceConnector.getCarrierService().getSubIDs()));
568     }
569 
570     @Test
testCarrierImsServiceBindRcsChangeToMmtelCompat()571     public void testCarrierImsServiceBindRcsChangeToMmtelCompat() throws Exception {
572         if (!ImsUtils.shouldTestImsService()) {
573             return;
574         }
575         // Connect to the ImsService with the RCS feature.
576         ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
577                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
578                 .build();
579         assertTrue(sServiceConnector.connectCarrierImsServiceLocally());
580         sServiceConnector.getCarrierService().resetState();
581         // Set the flag for ImsService compatibility test.
582         sServiceConnector.getCarrierService().setImsServiceCompat();
583         assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(config));
584         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
585         // Framework did not call it.
586         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
587                 TestImsService.LATCH_CREATE_RCS));
588 
589         // Change the supported feature to MMTEl
590         sServiceConnector.getCarrierService().getImsServiceCompat().onUpdateSupportedImsFeatures(
591                 new ImsFeatureConfiguration.Builder()
592                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL).build());
593 
594         // createMmTelFeature should be called.
595         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
596                 TestImsService.LATCH_CREATE_MMTEL));
597 
598         // Wait for the framework to set the capabilities on the ImsService
599         sServiceConnector.getCarrierService().waitForLatchCountdown(
600                 TestImsService.LATCH_MMTEL_CAP_SET);
601     }
602 
603     @Test
testCarrierImsServiceBindMmTelNoEmergency()604     public void testCarrierImsServiceBindMmTelNoEmergency() throws Exception {
605         if (!ImsUtils.shouldTestImsService()) {
606             return;
607         }
608         // Connect to the ImsService with the MMTEL feature.
609         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
610                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
611                 .build()));
612         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
613         // Framework did not call it.
614         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
615                 TestImsService.LATCH_CREATE_MMTEL));
616         // Wait for the framework to set the capabilities on the ImsService
617         sServiceConnector.getCarrierService().waitForLatchCountdown(
618                 TestImsService.LATCH_MMTEL_CAP_SET);
619     }
620 
621     @Test
testCarrierImsServiceBindMmTelEmergencyEnabled()622     public void testCarrierImsServiceBindMmTelEmergencyEnabled() throws Exception {
623         if (!ImsUtils.shouldTestImsService()) {
624             return;
625         }
626         // Connect to the ImsService with the MMTEL feature.
627         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
628                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
629                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
630                 .build()));
631         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
632         // Framework did not call it.
633         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
634                 TestImsService.LATCH_CREATE_MMTEL));
635         // Wait for the framework to set the capabilities on the ImsService
636         sServiceConnector.getCarrierService().waitForLatchCountdown(
637                 TestImsService.LATCH_MMTEL_CAP_SET);
638         assertTrue("Not expected subId received!",
639                 isExpectedSubId(sServiceConnector.getCarrierService().getSubIDs()));
640     }
641 
642     @Test
testCarrierImsServiceBindNullRcsFeature()643     public void testCarrierImsServiceBindNullRcsFeature() throws Exception {
644         if (!ImsUtils.shouldTestImsService()) {
645             return;
646         }
647         // Connect to the ImsService with the RCS feature.
648         ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
649                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
650                 .build();
651         assertTrue(sServiceConnector.connectCarrierImsServiceLocally());
652         sServiceConnector.getCarrierService().resetState();
653         sServiceConnector.getCarrierService().setNullRcsBinding();
654         assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(config));
655 
656         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
657         // Framework did not call it.
658         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
659                 TestImsService.LATCH_CREATE_RCS));
660         // Check to see if telephony state was reset at some point due to a crash and fail if so
661         assertFalse("ImsService should not crash if there is a null ImsFeature returned",
662                 ImsUtils.retryUntilTrue(() ->
663                         !sServiceConnector.isCarrierServiceStillConfigured(),
664                 5000 /*test timeout*/, 5 /*num times*/));
665     }
666 
667     @Test
testDeviceImsServiceBindRcsFeature()668     public void testDeviceImsServiceBindRcsFeature() throws Exception {
669         if (!ImsUtils.shouldTestImsService()) {
670             return;
671         }
672         // Connect to the ImsService with the RCS feature.
673         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
674                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
675                 .build()));
676         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
677         // Framework did not call it.
678         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
679                 TestImsService.LATCH_CREATE_RCS));
680         // Make sure the RcsFeature was created in the test service.
681         assertTrue("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
682                         + "called!", sServiceConnector.getExternalService().isRcsFeatureCreated());
683     }
684 
685     @Test
testBindDeviceAndCarrierDifferentFeatures()686     public void testBindDeviceAndCarrierDifferentFeatures() throws Exception {
687         if (!ImsUtils.shouldTestImsService()) {
688             return;
689         }
690         // Connect to Device the ImsService with the MMTEL/EMERGENCY_MMTEL feature.
691         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
692                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
693                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
694                 .build()));
695         // Connect to Device the ImsService with the RCS feature.
696         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
697                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
698                 .build()));
699         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
700         // Framework did not call it.
701         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
702                 TestImsService.LATCH_CREATE_MMTEL));
703         // Make sure the MmTelFeature was created in the test service.
704         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was"
705                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
706 
707         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
708                 TestImsService.LATCH_CREATE_RCS));
709         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
710                 sServiceConnector.getCarrierService().getRcsFeature());
711     }
712 
713     @Test
testBindDeviceAndCarrierSameFeature()714     public void testBindDeviceAndCarrierSameFeature() throws Exception {
715         if (!ImsUtils.shouldTestImsService()) {
716             return;
717         }
718         // Connect to Device the ImsService with the RCS feature.
719         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
720                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
721                 .build()));
722 
723         //First MMTEL feature is created on device ImsService.
724         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
725                 TestImsService.LATCH_CREATE_MMTEL));
726         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was "
727                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
728 
729         // Connect to Device the ImsService with the MMTEL feature.
730         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
731                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
732                 .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
733                 .build()));
734 
735         // Next MMTEL feature is created on carrier ImsService (and unbound on device)
736         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
737                 TestImsService.LATCH_CREATE_MMTEL));
738         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
739                 sServiceConnector.getCarrierService().getMmTelFeature());
740 
741         // Ensure that the MmTelFeature was removed on the device ImsService.
742         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
743                 TestImsService.LATCH_REMOVE_MMTEL));
744         assertFalse("Device ImsService was never removed when carrier ImsService took MMTEL."
745                 + "feature.", sServiceConnector.getExternalService().isMmTelFeatureCreated());
746     }
747 
748     @Test
testBindDeviceAndCarrierUpdateToSameFeature()749     public void testBindDeviceAndCarrierUpdateToSameFeature() throws Exception {
750         if (!ImsUtils.shouldTestImsService()) {
751             return;
752         }
753         // Connect to Device the ImsService with the MMTEL feature.
754         assertTrue(sServiceConnector.connectDeviceImsService(new ImsFeatureConfiguration.Builder()
755                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
756                 .build()));
757 
758         //First MMTEL feature is created on device ImsService.
759         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
760                 TestImsService.LATCH_CREATE_MMTEL));
761         assertTrue("Device ImsService created, but TestDeviceImsService#createMmTelFeature was"
762                 + "not called!", sServiceConnector.getExternalService().isMmTelFeatureCreated());
763 
764         // Connect to Device the ImsService with the RCS feature.
765         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
766                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
767                 .build()));
768 
769         // Next Rcs feature is created on carrier ImsService
770         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
771                 TestImsService.LATCH_CREATE_RCS));
772         assertNotNull("ImsService created, but ImsService#createRcsFeature was not called!",
773                 sServiceConnector.getCarrierService().getRcsFeature());
774 
775         // Change the supported feature to MMTEl
776         sServiceConnector.getCarrierService().getImsService().onUpdateSupportedImsFeatures(
777                 new ImsFeatureConfiguration.Builder()
778                         .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
779                         .addFeature(sTestSlot, ImsFeature.FEATURE_EMERGENCY_MMTEL)
780                         .build());
781 
782         // MMTEL feature is created on carrier ImsService
783         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
784                 TestImsService.LATCH_CREATE_MMTEL));
785         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
786                 sServiceConnector.getCarrierService().getMmTelFeature());
787 
788         // Ensure that the MmTelFeature was removed on the device ImsService.
789         assertTrue(sServiceConnector.getExternalService().waitForLatchCountdown(
790                 TestImsService.LATCH_REMOVE_MMTEL));
791         assertFalse("Device ImsService was never removed when carrier ImsService took MMTEL."
792                 + "feature.", sServiceConnector.getExternalService().isMmTelFeatureCreated());
793 
794         // Ensure that the RcsFeature was removed on the carrier ImsService.
795         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
796                 TestImsService.LATCH_REMOVE_RCS));
797         assertNull(sServiceConnector.getCarrierService().getRcsFeature());
798     }
799 
800     @Test
801     @ApiTest(apis = "android.telephony.SmsManager#sendTextMessage")
testMmTelSendSms()802     public void testMmTelSendSms() throws Exception {
803         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
804             return;
805         }
806 
807         setupImsServiceForSms();
808         // Send Message with sent PendingIntent requested
809         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
810                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
811                         InstrumentationRegistry.getInstrumentation().getTargetContext()), null);
812         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
813                 .getSmsImplementation().waitForMessageSentLatch());
814 
815         // Wait for send PendingIntent
816         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
817                 ImsUtils.TEST_TIMEOUT_MS);
818         assertNotNull("SMS send PendingIntent never received", intent);
819         assertEquals("SMS send PendingIntent should have result RESULT_OK",
820                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
821                         Activity.RESULT_CANCELED));
822 
823         // Ensure we receive correct PDU on the other side.
824         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
825         pduWithStatusReport[1] = sServiceConnector.getCarrierService()
826                 .getMmTelFeature().getSmsImplementation().sentPdu[1];
827         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
828                 .getMmTelFeature().getSmsImplementation().sentPdu);
829     }
830 
831     @Test
832     @ApiTest(apis = "android.telephony.SmsManager#sendTextMessage")
testMmTelSendSmsDeliveryReportQCompat()833     public void testMmTelSendSmsDeliveryReportQCompat() throws Exception {
834         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
835             return;
836         }
837 
838         setupImsServiceForSms();
839         // Send Message with sent PendingIntent requested
840         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
841                 DEST_NUMBER, MSG_CONTENTS, null, SmsReceiverHelper.getMessageDeliveredPendingIntent(
842                         InstrumentationRegistry.getInstrumentation().getTargetContext()));
843         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
844                 .getSmsImplementation().waitForMessageSentLatch());
845 
846         // Ensure we receive correct PDU on the other side.
847         // Set TP-Status-Report-Request bit as well for this case.
848         byte messageRef = sServiceConnector.getCarrierService()
849                 .getMmTelFeature().getSmsImplementation().sentPdu[1];
850         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
851         pduWithStatusReport[0] |= 0x20;
852         pduWithStatusReport[1] = messageRef;
853         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
854                 .getMmTelFeature().getSmsImplementation().sentPdu);
855         byte[] pduStatusReport = STATUS_REPORT_PDU.clone();
856         pduStatusReport[2] = messageRef;
857         // Ensure the API works on Q as well as in R+, where it was deprecated.
858         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
859                 .sendReportWaitForAcknowledgeSmsReportPQ(messageRef, SmsMessage.FORMAT_3GPP,
860                         pduStatusReport);
861 
862         // Wait for delivered PendingIntent
863         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageDeliveredIntent(
864                 ImsUtils.TEST_TIMEOUT_MS);
865         assertNotNull("SMS delivered PendingIntent never received", intent);
866         assertEquals("SMS delivered PendingIntent should have result RESULT_OK",
867                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
868                         Activity.RESULT_CANCELED));
869     }
870 
871     @Test
872     @ApiTest(apis = "android.telephony.SmsManager#sendTextMessage")
testMmTelSendSmsDeliveryReportR()873     public void testMmTelSendSmsDeliveryReportR() throws Exception {
874         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
875             return;
876         }
877 
878         setupImsServiceForSms();
879         // Send Message with sent PendingIntent requested
880         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
881                 DEST_NUMBER, MSG_CONTENTS, null, SmsReceiverHelper.getMessageDeliveredPendingIntent(
882                         InstrumentationRegistry.getInstrumentation().getTargetContext()));
883         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
884                 .getSmsImplementation().waitForMessageSentLatch());
885 
886         // Ensure we receive correct PDU on the other side.
887         // Set TP-Status-Report-Request bit as well for this case.
888         byte messageRef = sServiceConnector.getCarrierService()
889                 .getMmTelFeature().getSmsImplementation().sentPdu[1];
890         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
891         pduWithStatusReport[0] |= 0x20;
892         pduWithStatusReport[1] = messageRef;
893         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
894                 .getMmTelFeature().getSmsImplementation().sentPdu);
895 
896         byte[] pduStatusReport = STATUS_REPORT_PDU.clone();
897         pduStatusReport[2] = messageRef;
898         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
899                 .sendReportWaitForAcknowledgeSmsReportR(123456789, SmsMessage.FORMAT_3GPP,
900                         pduStatusReport);
901 
902         // Wait for delivered PendingIntent
903         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageDeliveredIntent(
904                 ImsUtils.TEST_TIMEOUT_MS);
905         assertNotNull("SMS delivered PendingIntent never received", intent);
906         assertEquals("SMS delivered PendingIntent should have result RESULT_OK",
907                 Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
908                         Activity.RESULT_CANCELED));
909     }
910 
911     @Test
912     @ApiTest(apis = "android.telephony.SmsManager#sendTextMessage")
testMmTelSendSmsRSuccess()913     public void testMmTelSendSmsRSuccess() throws Exception {
914         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
915             return;
916         }
917 
918         setupImsServiceForSms();
919 
920         // Send Message
921         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
922                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
923                         InstrumentationRegistry.getInstrumentation().getTargetContext()), null);
924         // Use R specific API for sending SMS result
925         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
926                 .getSmsImplementation().waitForMessageSentLatchSuccess());
927         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
928                 ImsUtils.TEST_TIMEOUT_MS);
929         assertNotNull(intent);
930         assertEquals(Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
931                     Activity.RESULT_CANCELED));
932 
933         // Ensure we receive correct PDU on the other side.
934         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
935         pduWithStatusReport[1] = sServiceConnector.getCarrierService()
936                 .getMmTelFeature().getSmsImplementation().sentPdu[1];
937         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
938                 .getMmTelFeature().getSmsImplementation().sentPdu);
939     }
940 
941     @Test
942     @ApiTest(apis = "android.telephony.SmsManager#sendTextMessage")
testMmTelSendSmsNetworkError()943     public void testMmTelSendSmsNetworkError() throws Exception {
944         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
945             return;
946         }
947 
948         setupImsServiceForSms();
949 
950         // Send Message
951         SmsManager.getSmsManagerForSubscriptionId(sTestSub).sendTextMessage(SRC_NUMBER,
952                 DEST_NUMBER, MSG_CONTENTS, SmsReceiverHelper.getMessageSentPendingIntent(
953                         InstrumentationRegistry.getInstrumentation().getContext()), null);
954         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
955                 .getSmsImplementation().waitForMessageSentLatchError(
956                         SmsManager.RESULT_ERROR_GENERIC_FAILURE, 41));
957         Intent intent = AsyncSmsMessageListener.getInstance().waitForMessageSentIntent(
958                 ImsUtils.TEST_TIMEOUT_MS);
959         assertNotNull(intent);
960         // In the case of error, the PendingIntent result will not report OK
961         assertNotEquals(Activity.RESULT_OK, intent.getIntExtra(SmsReceiverHelper.EXTRA_RESULT_CODE,
962                 Activity.RESULT_OK));
963         // make sure the "errorCode" extra contains the network error code returned by the
964         // ImsService.
965         assertEquals(41, intent.getIntExtra("errorCode", 0));
966 
967         // Ensure we receive correct PDU on the other side.
968         byte[] pduWithStatusReport = EXPECTED_PDU.clone();
969         pduWithStatusReport[1] = sServiceConnector.getCarrierService()
970                 .getMmTelFeature().getSmsImplementation().sentPdu[1];
971         Assert.assertArrayEquals(pduWithStatusReport, sServiceConnector.getCarrierService()
972                 .getMmTelFeature().getSmsImplementation().sentPdu);
973     }
974     @Ignore("The onMemoryAvailable and onMemoryAvailableResult Apis were moved back to @hide for"
975             + " now, so do not want to completely remove this test.")
976     @Test
testMmTelSendMemoryAvailabilityNotification()977     public void testMmTelSendMemoryAvailabilityNotification() throws Exception {
978         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
979             return;
980         }
981         InstrumentationRegistry.getInstrumentation().getUiAutomation()
982                 .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
983         boolean sendSmmaViaIms =  getContext().getResources().getBoolean(
984                 Resources.getSystem().getIdentifier("config_smma_notification_supported_over_ims",
985                         "bool",
986                         "android"));
987         if (!sendSmmaViaIms) {
988             return;
989         }
990         try {
991             setupImsServiceForSms();
992 
993             SmsManager.getSmsManagerForSubscriptionId(sTestSub)
994                         .setStorageMonitorMemoryStatusOverride(false);
995 
996             // Clear cached data before starting test.
997             AsyncSmsMessageListener.getInstance().clear();
998 
999             //Message received
1000             sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
1001                     .receiveSmsWaitForAcknowledgeMemoryFull(123456789, SmsMessage.FORMAT_3GPP,
1002                             Base64.decode(RECEIVED_MESSAGE, Base64.DEFAULT));
1003 
1004             SmsManager.getSmsManagerForSubscriptionId(sTestSub)
1005                         .setStorageMonitorMemoryStatusOverride(true);
1006             assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
1007                     .getSmsImplementation().waitForOnMemoryAvailableLatch());
1008             assertTrue(sServiceConnector.getCarrierService().getMmTelFeature()
1009                     .getSmsImplementation().mMemoryEventReceived);
1010         } catch (SecurityException se) {
1011             fail("Caller with MODIFY_PHONE_STATE should be able to call API");
1012         } finally {
1013             SmsManager.getSmsManagerForSubscriptionId(sTestSub)
1014                         .clearStorageMonitorMemoryStatusOverride();
1015             InstrumentationRegistry.getInstrumentation().getUiAutomation()
1016                     .dropShellPermissionIdentity();
1017         }
1018     }
1019 
1020     @Test
testMmTelReceiveSms()1021     public void testMmTelReceiveSms() throws Exception {
1022         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
1023             return;
1024         }
1025         setupImsServiceForSms();
1026 
1027         // Clear cached data before starting test.
1028         AsyncSmsMessageListener.getInstance().clear();
1029 
1030         // Message received
1031         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
1032                 .receiveSmsWaitForAcknowledge(123456789, SmsMessage.FORMAT_3GPP,
1033                         Base64.decode(RECEIVED_MESSAGE, Base64.DEFAULT));
1034 
1035         // Wait for SMS received intent and ensure it is correct.
1036         String receivedMessage = AsyncSmsMessageListener.getInstance()
1037                 .waitForSmsMessage(ImsUtils.TEST_TIMEOUT_MS);
1038         assertEquals(EXPECTED_RECEIVED_MESSAGE, receivedMessage);
1039     }
1040 
1041     @Test
testMmTelReceiveSMPPClass2Sms()1042     public void testMmTelReceiveSMPPClass2Sms() throws Exception {
1043         if (!ImsUtils.shouldRunSmsImsTests(sTestSub)) {
1044             return;
1045         }
1046 
1047         boolean isViaIms = getContext().getResources().getBoolean(
1048                 Resources.getSystem().getIdentifier("config_smppsim_response_via_ims", "bool",
1049                         "android"));
1050         if (!isViaIms) {
1051             return;
1052         }
1053 
1054         setupImsServiceForSms();
1055 
1056         // Clear cached data before starting test.
1057         AsyncSmsMessageListener.getInstance().clear();
1058 
1059         // Message received
1060         sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
1061                 .receiveSmsWaitForAcknowledge(123456789, SmsMessage.FORMAT_3GPP,
1062                         CLASS2SMPP_PDU);
1063 
1064         assertEquals(EXPECTED_MESSAGEREF, sServiceConnector.getCarrierService().getMmTelFeature()
1065                 .getSmsImplementation().getMessageRef());
1066 
1067     }
1068 
1069     @Test
testGetFeatureState()1070     public void testGetFeatureState() throws Exception {
1071         if (!ImsUtils.shouldTestImsService()) {
1072             return;
1073         }
1074         // This will set feature state to ready
1075         triggerFrameworkConnectToCarrierImsService();
1076 
1077         Integer result = getFeatureState();
1078         assertNotNull(result);
1079         assertEquals("ImsService state should be STATE_READY",
1080                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
1081                 ImsFeature.STATE_READY);
1082         assertTrue("ImsService state is ready, but STATE_READY is not reported.",
1083                 ImsUtils.retryUntilTrue(() -> (getFeatureState() == ImsFeature.STATE_READY)));
1084 
1085         sServiceConnector.getCarrierService().getMmTelFeature().setFeatureState(
1086                 ImsFeature.STATE_INITIALIZING);
1087         result = getFeatureState();
1088         assertNotNull(result);
1089         assertEquals("ImsService state should be STATE_INITIALIZING",
1090                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
1091                 ImsFeature.STATE_INITIALIZING);
1092         assertTrue("ImsService state is initializing, but STATE_INITIALIZING is not reported.",
1093                 ImsUtils.retryUntilTrue(
1094                         () -> (getFeatureState() == ImsFeature.STATE_INITIALIZING)));
1095 
1096         sServiceConnector.getCarrierService().getMmTelFeature().setFeatureState(
1097                 ImsFeature.STATE_UNAVAILABLE);
1098         result = getFeatureState();
1099         assertNotNull(result);
1100         assertEquals("ImsService state should be STATE_UNAVAILABLE",
1101                 sServiceConnector.getCarrierService().getMmTelFeature().getFeatureState(),
1102                 ImsFeature.STATE_UNAVAILABLE);
1103         assertTrue("ImsService state is unavailable, but STATE_UNAVAILABLE is not reported.",
1104                 ImsUtils.retryUntilTrue(
1105                         () -> (getFeatureState() == ImsFeature.STATE_UNAVAILABLE)));
1106     }
1107 
getFeatureState()1108     private Integer getFeatureState() throws Exception {
1109         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1110         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1111         LinkedBlockingQueue<Integer> state = new LinkedBlockingQueue<>(1);
1112         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mmTelManager,
1113                 (m) -> m.getFeatureState(Runnable::run, state::offer), ImsException.class);
1114         return state.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1115     }
1116 
1117     @Test
testMmTelManagerRegistrationCallbackS()1118     public void testMmTelManagerRegistrationCallbackS() throws Exception {
1119         if (!ImsUtils.shouldTestImsService()) {
1120             return;
1121         }
1122 
1123         final ArraySet<String> featureTags = new ArraySet<>();
1124         featureTags.add("featureTag1");
1125         featureTags.add("featureTag2");
1126 
1127         triggerFrameworkConnectToCarrierImsService();
1128 
1129         // Start deregistered
1130         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
1131                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
1132                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
1133 
1134         LinkedBlockingQueue<ImsRegistrationAttributes> mRegQueue =
1135                 new LinkedBlockingQueue<>();
1136         LinkedBlockingQueue<ImsReasonInfo> mDeregQueue =
1137                 new LinkedBlockingQueue<>();
1138         RegistrationManager.RegistrationCallback callback =
1139                 new RegistrationManager.RegistrationCallback() {
1140             @Override
1141             public void onRegistered(ImsRegistrationAttributes attributes) {
1142                 mRegQueue.offer(attributes);
1143             }
1144 
1145             @Override
1146             public void onRegistering(ImsRegistrationAttributes attributes) {
1147                 mRegQueue.offer(attributes);
1148             }
1149 
1150             @Override
1151             public void onUnregistered(ImsReasonInfo info) {
1152                 mDeregQueue.offer(info);
1153             }
1154         };
1155 
1156         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1157         try {
1158             // First try without the correct permissions.
1159             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1160             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1161             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1162             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1163         } catch (SecurityException e) {
1164             //expected
1165         }
1166 
1167         // Latch will count down here (we callback on the state during registration).
1168         try {
1169             automan.adoptShellPermissionIdentity();
1170             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1171             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1172             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1173         } finally {
1174             automan.dropShellPermissionIdentity();
1175         }
1176         ImsReasonInfo deregResult = waitForResult(mDeregQueue);
1177         assertNotNull(deregResult);
1178         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, deregResult.getCode());
1179 
1180         // Start registration
1181         verifyRegistering(IMS_REGI_TECH_LTE, featureTags, mRegQueue,
1182                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
1183 
1184         // move to NR
1185         verifyRegistering(IMS_REGI_TECH_NR, featureTags, mRegQueue,
1186                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
1187 
1188         // move to cross sim
1189         verifyRegistering(IMS_REGI_TECH_CROSS_SIM, featureTags,
1190                 mRegQueue, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
1191                 ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET);
1192 
1193         // Complete registration
1194         verifyRegistered(IMS_REGI_TECH_LTE, featureTags, mRegQueue,
1195                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
1196 
1197         // move to NR
1198         verifyRegistered(IMS_REGI_TECH_NR, featureTags, mRegQueue,
1199                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 0 /*expected flags*/);
1200 
1201         // move to cross sim
1202         verifyRegistered(IMS_REGI_TECH_CROSS_SIM, featureTags,
1203                 mRegQueue, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
1204                 ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET);
1205 
1206         try {
1207             automan.adoptShellPermissionIdentity();
1208             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1209             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1210             mmTelManager.unregisterImsRegistrationCallback(callback);
1211         } finally {
1212             automan.dropShellPermissionIdentity();
1213         }
1214 
1215         try {
1216             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1217             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1218             mmTelManager.unregisterImsRegistrationCallback(callback);
1219             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1220         } catch (SecurityException e) {
1221             //expected
1222         }
1223     }
1224 
1225     @Test
1226     @RequiresFlagsEnabled(Flags.FLAG_EMERGENCY_REGISTRATION_STATE)
testMmTelManagerEmergencyRegistrationCallback()1227     public void testMmTelManagerEmergencyRegistrationCallback() throws Exception {
1228         if (!ImsUtils.shouldTestImsService()) {
1229             return;
1230         }
1231 
1232         final ArraySet<String> featureTags = new ArraySet<>();
1233         featureTags.add("featureTag1");
1234         featureTags.add("featureTag2");
1235 
1236         triggerFrameworkConnectToCarrierImsService();
1237 
1238         // Start deregistered for emergency registration
1239         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
1240             new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
1241                 ImsReasonInfo.CODE_UNSPECIFIED, ""), SUGGESTED_ACTION_NONE,
1242             new ImsRegistrationAttributes.Builder(IMS_REGI_TECH_LTE)
1243                 .setFlagRegistrationTypeEmergency().build());
1244 
1245         LinkedBlockingQueue<ImsRegistrationAttributes> mEmerRegQueue =
1246                 new LinkedBlockingQueue<>();
1247 
1248         LinkedBlockingQueue<Integer> mEmerDeregQueue =
1249                 new LinkedBlockingQueue<>();
1250 
1251         RegistrationManager.RegistrationCallback emerRegCallback =
1252                 new RegistrationManager.RegistrationCallback() {
1253                     @Override
1254                     public void onRegistered(ImsRegistrationAttributes attributes) {
1255                         mEmerRegQueue.offer(attributes);
1256                     }
1257 
1258                     @Override
1259                     public void onRegistering(ImsRegistrationAttributes attributes) {
1260                         mEmerRegQueue.offer(attributes);
1261                     }
1262 
1263                     @Override
1264                     public void onUnregistered(ImsReasonInfo info, int suggestedAction,
1265                             int imsRadioTech) {
1266                         mEmerDeregQueue.offer(info.getCode());
1267                     }
1268                     @Override
1269                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
1270                         mEmerDeregQueue.offer(imsTransportType);
1271                         mEmerDeregQueue.offer(info.getCode());
1272                     }
1273                 };
1274 
1275         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1276         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1277         try {
1278             // First try without the correct permissions.
1279             mmTelManager.registerImsEmergencyRegistrationCallback(getContext().getMainExecutor(),
1280                     emerRegCallback);
1281             fail("registerImsEmergencyRegistrationCallback requires READ_PRECISE_PHONE_STATE "
1282                     + "permission.");
1283         } catch (SecurityException e) {
1284             //expected
1285         }
1286 
1287         // Latch will count down here (we callback on the state during registration).
1288         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
1289                 mmTelManager, (mm) -> {
1290                         try {
1291                             mm.registerImsEmergencyRegistrationCallback(
1292                                     getContext().getMainExecutor(), emerRegCallback);
1293                         } catch (ImsException e) {
1294                             fail("registerImsEmergencyRegistrationCallback failed " + e);
1295                         }
1296                 });
1297 
1298         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mEmerDeregQueue));
1299 
1300         // Start registration for emergency registration
1301         verifyEmergencyRegistering(IMS_REGI_TECH_LTE, featureTags, mEmerRegQueue,
1302                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
1303                 ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
1304 
1305         // Complete registration for emergency registration
1306         verifyEmergencyRegistered(IMS_REGI_TECH_LTE, featureTags, mEmerRegQueue,
1307                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
1308                 ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
1309 
1310         // fail handover to IWLAN for emergency registration
1311         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
1312             new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
1313                 ImsReasonInfo.CODE_UNSPECIFIED, ""), new ImsRegistrationAttributes.Builder(
1314                 IMS_REGI_TECH_IWLAN).setFlagRegistrationTypeEmergency().build());
1315         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mEmerDeregQueue));
1316         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mEmerDeregQueue));
1317 
1318         // handover to NR successfully for emergency registration
1319         verifyEmergencyRegistering(IMS_REGI_TECH_NR, featureTags, mEmerRegQueue,
1320                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
1321                 ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
1322 
1323         verifyEmergencyRegistered(IMS_REGI_TECH_NR, featureTags, mEmerRegQueue,
1324                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
1325                 ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
1326 
1327         // Deregister registration for emergency registration with null reason info
1328         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(null,
1329                 SUGGESTED_ACTION_NONE, new ImsRegistrationAttributes.Builder(
1330                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE).setFlagRegistrationTypeEmergency()
1331                 .build());
1332         assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mEmerDeregQueue));
1333 
1334         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
1335                 mmTelManager, (mm) -> {
1336                     mm.unregisterImsEmergencyRegistrationCallback(emerRegCallback);
1337                 });
1338 
1339         try {
1340             mmTelManager.unregisterImsEmergencyRegistrationCallback(emerRegCallback);
1341             fail("unregisterImsEmergencyRegistrationCallback requires READ_PRECISE_PHONE_STATE "
1342                     + "permission.");
1343         } catch (SecurityException e) {
1344             //expected
1345         }
1346     }
1347 
1348     @Test
testMmTelManagerRegistrationCallback()1349     public void testMmTelManagerRegistrationCallback() throws Exception {
1350         if (!ImsUtils.shouldTestImsService()) {
1351             return;
1352         }
1353 
1354         triggerFrameworkConnectToCarrierImsService();
1355 
1356         // Start deregistered
1357         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
1358                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
1359                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
1360 
1361         // This is a little bit gross looking, but on P devices, I can not define classes that
1362         // extend ImsMmTelManager.RegistrationCallback (because it doesn't exist), so this has to
1363         // happen as an anon class here.
1364         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
1365         ImsMmTelManager.RegistrationCallback callback = new ImsMmTelManager.RegistrationCallback() {
1366             @Override
1367             public void onRegistered(int imsTransportType) {
1368                 mQueue.offer(imsTransportType);
1369             }
1370 
1371             @Override
1372             public void onRegistering(int imsTransportType) {
1373                 mQueue.offer(imsTransportType);
1374             }
1375 
1376             @Override
1377             public void onUnregistered(ImsReasonInfo info) {
1378                 mQueue.offer(info.getCode());
1379             }
1380 
1381             @Override
1382             public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
1383                 mQueue.offer(imsTransportType);
1384                 mQueue.offer(info.getCode());
1385             }
1386         };
1387 
1388         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1389         try {
1390             // First try without the correct permissions.
1391             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1392             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1393             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1394             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1395         } catch (SecurityException e) {
1396             //expected
1397         }
1398 
1399         // Latch will count down here (we callback on the state during registration).
1400         try {
1401             automan.adoptShellPermissionIdentity();
1402             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1403             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1404             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
1405         } finally {
1406             automan.dropShellPermissionIdentity();
1407         }
1408         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
1409 
1410 
1411         // Start registration
1412         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
1413                 IMS_REGI_TECH_LTE);
1414         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
1415 
1416         // Complete registration
1417         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1418                 IMS_REGI_TECH_LTE);
1419         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
1420 
1421         // Fail handover to IWLAN
1422         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
1423                 IMS_REGI_TECH_IWLAN,
1424                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
1425                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
1426         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
1427         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
1428 
1429         // Ensure null ImsReasonInfo still results in non-null callback value.
1430         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
1431                 IMS_REGI_TECH_IWLAN, null);
1432         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
1433         assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
1434 
1435         // Ensure null ImsReasonInfo still results in non-null callback.
1436         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(null);
1437         assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mQueue));
1438 
1439         try {
1440             automan.adoptShellPermissionIdentity();
1441             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1442             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1443             mmTelManager.unregisterImsRegistrationCallback(callback);
1444         } finally {
1445             automan.dropShellPermissionIdentity();
1446         }
1447 
1448         try {
1449             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1450             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
1451             mmTelManager.unregisterImsRegistrationCallback(callback);
1452             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
1453         } catch (SecurityException e) {
1454             //expected
1455         }
1456     }
1457 
1458     @Test
testRcsDeviceCapabilitiesPublish()1459     public void testRcsDeviceCapabilitiesPublish() throws Exception {
1460         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
1461                 TelephonyUtils.CTS_APP_PACKAGE,
1462                 SUPPORT_PUBLISHING_STATE_STRING);
1463 
1464         if (!ImsUtils.shouldTestImsService()) {
1465             return;
1466         }
1467         // Trigger carrier config changed
1468         PersistableBundle bundle = new PersistableBundle();
1469         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1470         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1471         overrideCarrierConfig(bundle);
1472 
1473         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1474         if (imsManager == null) {
1475             fail("Cannot find IMS service");
1476         }
1477 
1478         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1479         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1480 
1481         // Connect to device ImsService with MmTel feature and RCS feature
1482         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1483 
1484         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1485                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1486 
1487         // Register the callback to listen to the publish state changed
1488         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1489         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1490                 new RcsUceAdapter.OnPublishStateChangedListener() {
1491                     public void onPublishStateChange(int state) {
1492                         publishStateQueue.offer(state);
1493                     }
1494                 };
1495 
1496         // Another publish register callback to verify the API
1497         // RcsUceAdapter#removeOnPublishStateChangedListener
1498         LinkedBlockingQueue<Integer> unregisteredPublishStateQueue = new LinkedBlockingQueue<>();
1499         RcsUceAdapter.OnPublishStateChangedListener unregisteredPublishStateCallback =
1500                 new RcsUceAdapter.OnPublishStateChangedListener() {
1501                     public void onPublishStateChange(int state) {
1502                         unregisteredPublishStateQueue.offer(state);
1503                     }
1504                 };
1505 
1506         // Another publish register callback to verify new added API.
1507         // RcsUceAdapter#removeOnPublishStateChangedListener
1508         LinkedBlockingQueue<PublishAttributes> addedNewPublishStateQueue =
1509                 new LinkedBlockingQueue<>();
1510         RcsUceAdapter.OnPublishStateChangedListener addedNewPublishStateCallback =
1511                 new RcsUceAdapter.OnPublishStateChangedListener() {
1512                     public void onPublishStateChange(int state) {
1513                     }
1514                     public void onPublishStateChange(PublishAttributes attributes) {
1515                         addedNewPublishStateQueue.offer(attributes);
1516                     }
1517                 };
1518         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1519         try {
1520             automan.adoptShellPermissionIdentity();
1521             // register three publish state callback
1522             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1523                     publishStateCallback);
1524             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1525                     unregisteredPublishStateCallback);
1526             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1527                     addedNewPublishStateCallback);
1528         } finally {
1529             automan.dropShellPermissionIdentity();
1530         }
1531 
1532         // Verify receiving the publish state callback immediately after registering the callback.
1533         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1534                 waitForIntResult(publishStateQueue));
1535         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1536                 waitForIntResult(unregisteredPublishStateQueue));
1537         PublishAttributes attr = waitForResult(addedNewPublishStateQueue);
1538         assertNull(attr.getSipDetails());
1539         assertTrue(attr.getPresenceTuples().isEmpty());
1540         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, attr.getPublishState());
1541         publishStateQueue.clear();
1542         unregisteredPublishStateQueue.clear();
1543         addedNewPublishStateQueue.clear();
1544 
1545         // Verify the value of getting from the API is NOT_PUBLISHED
1546         try {
1547             automan.adoptShellPermissionIdentity();
1548             int publishState = uceAdapter.getUcePublishState();
1549             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1550         } finally {
1551             automan.dropShellPermissionIdentity();
1552         }
1553 
1554         // Setup the operation of the publish request.
1555         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1556             int networkResp = 200;
1557             String reason = "";
1558             cb.onNetworkResponse(networkResp, reason);
1559             listener.onPublish();
1560         });
1561 
1562         // Unregister the publish state callback
1563         try {
1564             automan.adoptShellPermissionIdentity();
1565             uceAdapter.removeOnPublishStateChangedListener(unregisteredPublishStateCallback);
1566         } finally {
1567             automan.dropShellPermissionIdentity();
1568         }
1569 
1570         // IMS registers
1571         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1572                 IMS_REGI_TECH_LTE);
1573 
1574         // Framework should not trigger the device capabilities publish when the framework doesn't
1575         // receive that the RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE is enabled.
1576         if (publishStateQueue.poll() != null) {
1577             fail("The publish callback should not be called because presence uce is not ready");
1578         }
1579         if (unregisteredPublishStateQueue.poll() != null) {
1580             fail("The de-registered publish callback should not be called");
1581         }
1582 
1583         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1584         RcsImsCapabilities capabilities =
1585                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1586         sServiceConnector.getCarrierService().getRcsFeature()
1587                 .notifyCapabilitiesStatusChanged(capabilities);
1588 
1589         CapabilityExchangeEventListener eventListener =
1590                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1591 
1592         // ImsService triggers to notify framework publish device's capabilities.
1593         eventListener.onRequestPublishCapabilities(
1594                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1595 
1596         // Verify ImsService receive the publish request from framework.
1597         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1598                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1599 
1600         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
1601         attr = waitForResult(addedNewPublishStateQueue);
1602         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, attr.getPublishState());
1603         assertNull(attr.getSipDetails());
1604         assertTrue(attr.getPresenceTuples().isEmpty());
1605 
1606         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1607         attr = waitForResult(addedNewPublishStateQueue);
1608         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, attr.getPublishState());
1609         assertNotNull(attr.getSipDetails());
1610         assertEquals(200, attr.getSipDetails().getResponseCode());
1611         assertTrue(attr.getSipDetails().getResponsePhrase().isEmpty());
1612         publishStateQueue.clear();
1613         addedNewPublishStateQueue.clear();
1614         // Verify the value of getting from the API is PUBLISH_STATE_OK
1615         try {
1616             automan.adoptShellPermissionIdentity();
1617             int publishState = uceAdapter.getUcePublishState();
1618             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1619         } finally {
1620             automan.dropShellPermissionIdentity();
1621         }
1622 
1623         // Unregister the publish state callback
1624         try {
1625             automan.adoptShellPermissionIdentity();
1626             uceAdapter.removeOnPublishStateChangedListener(addedNewPublishStateCallback);
1627         } finally {
1628             automan.dropShellPermissionIdentity();
1629         }
1630 
1631         // ImsService triggers to notify framework publish device's capabilities.
1632         eventListener.onRequestPublishCapabilities(
1633                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1634 
1635         // Verify ImsService receive the publish request from framework.
1636         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1637                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1638 
1639         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
1640         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1641         publishStateQueue.clear();
1642 
1643         if (addedNewPublishStateQueue.poll() != null) {
1644             fail("The de-registered publish callback should not be called");
1645         }
1646 
1647         // ImsService triggers the unpublish notification
1648         eventListener.onUnpublish();
1649 
1650         // Verify the publish state callback will be called with the state "NOT_PUBLISHED"
1651         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1652                 waitForIntResult(publishStateQueue));
1653         publishStateQueue.clear();
1654 
1655         // The unregistered callback should not be called.
1656         if (unregisteredPublishStateQueue.poll() != null) {
1657             fail("The de-registered publish callback should not be called when unpublish");
1658         }
1659 
1660         // Verify the value of getting from the API is NOT_PUBLISHED
1661         try {
1662             automan.adoptShellPermissionIdentity();
1663             int publishState = uceAdapter.getUcePublishState();
1664             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1665         } finally {
1666             automan.dropShellPermissionIdentity();
1667         }
1668         publishStateQueue.clear();
1669 
1670         // ImsService triggers to notify framework publish updated.
1671         eventListener.onPublishUpdated(200, "", 0, "");
1672         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1673         publishStateQueue.clear();
1674 
1675         // Setup the operation of the publish request.
1676         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1677             int networkResp = 999;
1678             String reason = "";
1679             cb.onNetworkResponse(networkResp, reason);
1680             listener.onPublish();
1681         });
1682         eventListener.onRequestPublishCapabilities(
1683                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1684 
1685         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1686                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1687 
1688         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
1689         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
1690         publishStateQueue.clear();
1691 
1692         // Trigger RcsFeature is unavailable
1693         sServiceConnector.getCarrierService().getRcsFeature()
1694                 .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
1695 
1696         // Verify the RcsCapabilityExchangeImplBase will be removed.
1697         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1698                 TestImsService.LATCH_UCE_LISTENER_SET));
1699 
1700         overrideCarrierConfig(null);
1701     }
1702 
1703     @Test
testRcsAttributesPublish()1704     public void testRcsAttributesPublish() throws Exception {
1705         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
1706                 TelephonyUtils.CTS_APP_PACKAGE,
1707                 SUPPORT_PUBLISHING_STATE_STRING);
1708 
1709         if (!ImsUtils.shouldTestImsService()) {
1710             return;
1711         }
1712         // Trigger carrier config changed
1713         PersistableBundle bundle = new PersistableBundle();
1714         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1715         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1716         overrideCarrierConfig(bundle);
1717 
1718         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1719         if (imsManager == null) {
1720             fail("Cannot find IMS service");
1721         }
1722 
1723         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1724         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1725 
1726         // Connect to device ImsService with MmTel feature and RCS feature
1727         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1728 
1729         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1730                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1731 
1732         // Register the callback to listen to the publish state changed
1733         LinkedBlockingQueue<PublishAttributes> publishStateQueue = new LinkedBlockingQueue<>();
1734         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1735                 new RcsUceAdapter.OnPublishStateChangedListener() {
1736                     public void onPublishStateChange(int state) {
1737                     }
1738                     public void onPublishStateChange(PublishAttributes attributes) {
1739                         publishStateQueue.offer(attributes);
1740                     }
1741                 };
1742         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1743         try {
1744             automan.adoptShellPermissionIdentity();
1745             // register three publish state callback
1746             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1747                     publishStateCallback);
1748         } finally {
1749             automan.dropShellPermissionIdentity();
1750         }
1751 
1752         // Verify receiving the publish state callback immediately after registering the callback.
1753         PublishAttributes attr = waitForResult(publishStateQueue);
1754         assertNull(attr.getSipDetails());
1755         assertTrue(attr.getPresenceTuples().isEmpty());
1756         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, attr.getPublishState());
1757         publishStateQueue.clear();
1758 
1759 
1760         // Verify the value of getting from the API is NOT_PUBLISHED
1761         try {
1762             automan.adoptShellPermissionIdentity();
1763             int publishState = uceAdapter.getUcePublishState();
1764             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1765         } finally {
1766             automan.dropShellPermissionIdentity();
1767         }
1768 
1769         // Setup the operation of the publish request.
1770         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1771             int networkResp = 200;
1772             String reason = "OK";
1773             cb.onNetworkResponse(new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
1774                     .setCSeq(1).setSipResponseCode(networkResp, reason)
1775                     .setCallId("TestCallId").build());
1776             listener.onPublish();
1777         });
1778 
1779         // IMS registers
1780         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
1781                 IMS_REGI_TECH_LTE);
1782 
1783         // Framework should not trigger the device capabilities publish when the framework doesn't
1784         // receive that the RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE is enabled.
1785         if (publishStateQueue.poll() != null) {
1786             fail("The publish callback should not be called because presence uce is not ready");
1787         }
1788 
1789         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
1790         RcsImsCapabilities capabilities =
1791                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
1792         sServiceConnector.getCarrierService().getRcsFeature()
1793                 .notifyCapabilitiesStatusChanged(capabilities);
1794 
1795         CapabilityExchangeEventListener eventListener =
1796                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
1797 
1798         // ImsService triggers to notify framework publish device's capabilities.
1799         eventListener.onRequestPublishCapabilities(
1800                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1801 
1802         // Verify ImsService receive the publish request from framework.
1803         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1804                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1805 
1806         attr = waitForResult(publishStateQueue);
1807         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, attr.getPublishState());
1808         assertNull(attr.getSipDetails());
1809 
1810         attr = waitForResult(publishStateQueue);
1811         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, attr.getPublishState());
1812         SipDetails details = attr.getSipDetails();
1813         assertNotNull(details);
1814         assertEquals(SipDetails.METHOD_PUBLISH, details.getMethod());
1815         assertEquals(1, details.getCSeq());
1816         assertEquals(200, details.getResponseCode());
1817         assertEquals("OK", details.getResponsePhrase());
1818         assertEquals(0, details.getReasonHeaderCause());
1819         assertTrue(details.getReasonHeaderText().isEmpty());
1820         assertEquals("TestCallId", details.getCallId());
1821         publishStateQueue.clear();
1822 
1823         // Verify the value of getting from the API is PUBLISH_STATE_OK
1824         try {
1825             automan.adoptShellPermissionIdentity();
1826             int publishState = uceAdapter.getUcePublishState();
1827             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
1828         } finally {
1829             automan.dropShellPermissionIdentity();
1830         }
1831 
1832         // ImsService triggers to notify framework publish device's capabilities.
1833         eventListener.onRequestPublishCapabilities(
1834                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1835 
1836         // Verify ImsService receive the publish request from framework.
1837         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1838                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1839 
1840         attr = waitForResult(publishStateQueue);
1841         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, attr.getPublishState());
1842         attr = waitForResult(publishStateQueue);
1843         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, attr.getPublishState());
1844         publishStateQueue.clear();
1845 
1846         // ImsService triggers the unpublish notification
1847         eventListener.onUnpublish();
1848 
1849         // Verify the publish state callback will be called with the state "NOT_PUBLISHED"
1850         attr = waitForResult(publishStateQueue);
1851         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, attr.getPublishState());
1852         publishStateQueue.clear();
1853 
1854         // Verify the value of getting from the API is NOT_PUBLISHED
1855         try {
1856             automan.adoptShellPermissionIdentity();
1857             int publishState = uceAdapter.getUcePublishState();
1858             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
1859         } finally {
1860             automan.dropShellPermissionIdentity();
1861         }
1862         publishStateQueue.clear();
1863 
1864         // ImsService triggers to notify framework publish updated.
1865         int sipCode = 200;
1866         String reasonPharse = "OK";
1867         int cSeq = 2;
1868         int reasonCause = 0;
1869         String reasonText = "headerText";
1870         String callId = "TestCallId1";
1871         eventListener.onPublishUpdated(new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
1872                 .setCSeq(cSeq).setSipResponseCode(sipCode, reasonPharse)
1873                 .setSipResponseReasonHeader(reasonCause, reasonText).setCallId(callId).build());
1874         attr = waitForResult(publishStateQueue);
1875         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, attr.getPublishState());
1876         details = attr.getSipDetails();
1877         assertNotNull(details);
1878         assertEquals(SipDetails.METHOD_PUBLISH, details.getMethod());
1879         assertEquals(cSeq, details.getCSeq());
1880         assertEquals(sipCode, details.getResponseCode());
1881         assertEquals(reasonPharse, details.getResponsePhrase());
1882         assertEquals(reasonCause, details.getReasonHeaderCause());
1883         assertEquals(reasonText, details.getReasonHeaderText());
1884         assertEquals(callId, details.getCallId());
1885         publishStateQueue.clear();
1886 
1887         // Setup the operation of the publish request.
1888         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1889             // The response code 999 means the PIDF is same as before.
1890             int networkResp = 999;
1891             String reason = "";
1892             cb.onNetworkResponse(new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
1893                     .setCSeq(10).setSipResponseCode(networkResp, reason)
1894                     .setCallId("TestCallId3").build());
1895             listener.onPublish();
1896         });
1897         eventListener.onRequestPublishCapabilities(
1898                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
1899 
1900         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1901                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
1902 
1903         attr = waitForResult(publishStateQueue);
1904         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, attr.getPublishState());
1905         attr = waitForResult(publishStateQueue);
1906         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, attr.getPublishState());
1907         // Verify that the sip info is set to null because the response code 999 is treated
1908         // as a command error.
1909         assertNull(attr.getSipDetails());
1910         publishStateQueue.clear();
1911 
1912         // Trigger RcsFeature is unavailable
1913         sServiceConnector.getCarrierService().getRcsFeature()
1914                 .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
1915 
1916         // Verify the RcsCapabilityExchangeImplBase will be removed.
1917         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
1918                 TestImsService.LATCH_UCE_LISTENER_SET));
1919 
1920         overrideCarrierConfig(null);
1921     }
1922 
1923     @Test
testPublishImsReg()1924     public void testPublishImsReg() throws Exception {
1925         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
1926                 TelephonyUtils.CTS_APP_PACKAGE,
1927                 SUPPORT_PUBLISHING_STATE_STRING);
1928         if (!ImsUtils.shouldTestImsService()) {
1929             return;
1930         }
1931         // Trigger carrier config changed
1932         PersistableBundle bundle = new PersistableBundle();
1933         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
1934         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
1935         overrideCarrierConfig(bundle);
1936 
1937         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
1938         if (imsManager == null) {
1939             fail("Cannot find IMS service");
1940         }
1941 
1942         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
1943         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
1944 
1945         // Connect to device ImsService with MmTel feature and RCS feature
1946         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
1947 
1948         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
1949                 .getRcsFeature().getRcsCapabilityExchangeImpl();
1950 
1951         // Register the callback to listen to the publish state changed
1952         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
1953         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
1954                 new RcsUceAdapter.OnPublishStateChangedListener() {
1955                     public void onPublishStateChange(int state) {
1956                         publishStateQueue.offer(state);
1957                     }
1958                 };
1959 
1960         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
1961         try {
1962             automan.adoptShellPermissionIdentity();
1963             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
1964                     publishStateCallback);
1965         } finally {
1966             automan.dropShellPermissionIdentity();
1967         }
1968 
1969         // Verify receiving the publish state callback immediately after registering the callback.
1970         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
1971                 waitForIntResult(publishStateQueue));
1972         publishStateQueue.clear();
1973 
1974         LinkedBlockingQueue<String> pidfQueue = new LinkedBlockingQueue<>();
1975         // Setup the operation of the publish request.
1976         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
1977             pidfQueue.offer(pidfXml);
1978             int networkResp = 200;
1979             String reason = "";
1980             cb.onNetworkResponse(networkResp, reason);
1981             listener.onPublish();
1982         });
1983 
1984         LinkedBlockingQueue<ImsRegistrationAttributes> mQueue = new LinkedBlockingQueue<>();
1985         RegistrationManager.RegistrationCallback callback =
1986                 new RegistrationManager.RegistrationCallback() {
1987                     @Override
1988                     public void onRegistered(ImsRegistrationAttributes attr) {
1989                         mQueue.offer(attr);
1990                     }
1991 
1992                     @Override
1993                     public void onRegistering(ImsRegistrationAttributes attr) {}
1994 
1995                     @Override
1996                     public void onUnregistered(ImsReasonInfo info) {}
1997 
1998                     @Override
1999                     public void onTechnologyChangeFailed(int type, ImsReasonInfo info) {}
2000                 };
2001         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
2002                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
2003                 ImsException.class);
2004 
2005         // IMS registers
2006         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2007                 IMS_REGI_TECH_LTE);
2008 
2009         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2010         RcsImsCapabilities capabilities =
2011                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2012         sServiceConnector.getCarrierService().getRcsFeature()
2013                 .notifyCapabilitiesStatusChanged(capabilities);
2014 
2015         CapabilityExchangeEventListener eventListener =
2016                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2017 
2018         // ImsService triggers to notify framework publish device's capabilities.
2019         eventListener.onRequestPublishCapabilities(
2020                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2021 
2022         // Verify that the publish is triggered and receive the publish state changed callback.
2023         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2024                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2025 
2026         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
2027         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2028         publishStateQueue.clear();
2029 
2030         // IMS registers
2031         ArraySet<String> featureTags = new ArraySet<>();
2032         // Chat Session
2033         featureTags.add(CHAT_FEATURE_TAG);
2034         featureTags.add(FILE_TRANSFER_FEATURE_TAG);
2035         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
2036                 IMS_REGI_TECH_LTE).setFeatureTags(featureTags).build();
2037         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
2038         waitForParam(mQueue, attr);
2039 
2040         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
2041         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2042         publishStateQueue.clear();
2043 
2044         // Can not verify the pidf fully, but we can ensure that the service id for the feature is
2045         // contained in the XML. Multible PUBLISH requests may occur based on the state of the stack
2046         // at the time of this call, retry to get correct PIDF up to 5 times.
2047         boolean containsChatServiceId = false;
2048         boolean containsFileTransferServiceId = false;
2049         for (int retry = 0; retry < 5; retry++) {
2050             String pidf = waitForResult(pidfQueue);
2051             if (pidf == null) break;
2052             containsChatServiceId = pidf.contains(CHAT_SERVICE_ID);
2053             containsFileTransferServiceId  = pidf.contains(FILE_TRANSFER_SERVICE_ID);
2054             if (containsChatServiceId && containsFileTransferServiceId) break;
2055         }
2056         assertTrue("PIDF XML doesn't contain chat service-id", containsChatServiceId);
2057         assertTrue("PIDF XML doesn't contain FT service-id",
2058                 containsFileTransferServiceId);
2059 
2060         publishStateQueue.clear();
2061         // ImsService triggers to notify framework publish updated.
2062         eventListener.onPublishUpdated(400, "", 0, "");
2063         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR,
2064                 waitForIntResult(publishStateQueue));
2065         publishStateQueue.clear();
2066 
2067         // Trigger RcsFeature is unavailable
2068         sServiceConnector.getCarrierService().getRcsFeature()
2069                 .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
2070 
2071         // Verify the RcsCapabilityExchangeImplBase will be removed.
2072         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2073                 TestImsService.LATCH_UCE_LISTENER_SET));
2074 
2075         overrideCarrierConfig(null);
2076     }
2077 
2078     @Test
testPublishWithImsAssociatedUri()2079     public void testPublishWithImsAssociatedUri() throws Exception {
2080         if (!ImsUtils.shouldTestImsService()) {
2081             return;
2082         }
2083         // Trigger carrier config changed
2084         PersistableBundle bundle = new PersistableBundle();
2085         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2086         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2087         overrideCarrierConfig(bundle);
2088 
2089         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2090         if (imsManager == null) {
2091             fail("Cannot find IMS service");
2092         }
2093 
2094         TelephonyManager tm = (TelephonyManager) getContext()
2095                 .getSystemService(Context.TELEPHONY_SERVICE);
2096 
2097         String mccmnc = tm.getSimOperator();
2098         boolean mTelUriSupported = CarrierCapability.SUPPORT_TEL_URI_PUBLISH.contains(mccmnc);
2099 
2100         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2101         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2102 
2103         // Connect to device ImsService with MmTel feature and RCS feature
2104         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2105 
2106         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2107                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2108 
2109         // Setup the operation of the publish request.
2110         List<String> receivedPidfXml = new ArrayList<>();
2111         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2112             int networkResp = 200;
2113             String reason = "";
2114             receivedPidfXml.add(pidfXml);
2115             cb.onNetworkResponse(networkResp, reason);
2116             listener.onPublish();
2117         });
2118 
2119         Uri imsUri;
2120         if (mTelUriSupported) {
2121             imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "0001112222", null);
2122         } else {
2123             imsUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null);
2124         }
2125 
2126         StringBuilder expectedUriBuilder = new StringBuilder();
2127         expectedUriBuilder.append("<contact>").append(imsUri.toString()).append("</contact>");
2128 
2129         final String expectedUriString = expectedUriBuilder.toString();
2130 
2131         LinkedBlockingQueue<ImsRegistrationAttributes> mQueue = new LinkedBlockingQueue<>();
2132         RegistrationManager.RegistrationCallback callback =
2133                 new RegistrationManager.RegistrationCallback() {
2134                     @Override
2135                     public void onRegistered(ImsRegistrationAttributes attr) {
2136                         mQueue.offer(attr);
2137                     }
2138 
2139                     @Override
2140                     public void onRegistering(ImsRegistrationAttributes attr) {}
2141 
2142                     @Override
2143                     public void onUnregistered(ImsReasonInfo info) {}
2144 
2145                     @Override
2146                     public void onTechnologyChangeFailed(int type, ImsReasonInfo info) {}
2147                 };
2148         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
2149                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
2150                 ImsException.class);
2151 
2152         ArraySet<String> featureTags = new ArraySet<>();
2153         // Chat Session
2154         featureTags.add(CHAT_FEATURE_TAG);
2155         featureTags.add(FILE_TRANSFER_FEATURE_TAG);
2156         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
2157                 IMS_REGI_TECH_LTE).setFeatureTags(featureTags).build();
2158         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
2159         waitForParam(mQueue, attr);
2160 
2161         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2162         RcsImsCapabilities capabilities =
2163                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2164         sServiceConnector.getCarrierService().getRcsFeature()
2165                 .notifyCapabilitiesStatusChanged(capabilities);
2166 
2167         // ImsService triggers to notify framework publish device's capabilities.
2168         CapabilityExchangeEventListener eventListener =
2169                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2170         eventListener.onRequestPublishCapabilities(
2171                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2172 
2173         // Verify ImsService receive the publish request from framework.
2174         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2175                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2176 
2177         // Verify that the ImsService has received the publish request and the received PIDF does
2178         // not contain the associated URI.
2179         assertFalse(receivedPidfXml.isEmpty());
2180         assertFalse(receivedPidfXml.get(0).contains(expectedUriString));
2181 
2182         // Reset the received pidf xml data
2183         receivedPidfXml.clear();
2184 
2185         // Notify the associated URI has changed.
2186         sServiceConnector.getCarrierService().getImsRegistration().onSubscriberAssociatedUriChanged(
2187                 new Uri[] { imsUri });
2188 
2189         // Verify the ImsService does not receive the PUBLISH request because we just finish a
2190         // publish request a moment ago.
2191         assertFalse(sServiceConnector.getCarrierService().waitForLatchCountdown(
2192                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 2000 /* 2 seconds */));
2193 
2194         // Trigger a new publish request
2195         eventListener.onRequestPublishCapabilities(
2196                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2197 
2198         // Verify ImsService receive the publish request from framework.
2199         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2200                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2201 
2202         // Verify that the ImsService has received the publish request and the received PIDF
2203         // contains the associated URI.
2204         assertFalse(receivedPidfXml.isEmpty());
2205         assertTrue(receivedPidfXml.get(0).contains(expectedUriString));
2206 
2207         // Reset the received pidf xml data
2208         receivedPidfXml.clear();
2209 
2210         overrideCarrierConfig(null);
2211     }
2212 
2213     @Test
testRcsCapabilitiesPublishNetworkResponseWithReasonHeader()2214     public void testRcsCapabilitiesPublishNetworkResponseWithReasonHeader() throws Exception {
2215         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
2216                 TelephonyUtils.CTS_APP_PACKAGE,
2217                 SUPPORT_PUBLISHING_STATE_STRING);
2218         if (!ImsUtils.shouldTestImsService()) {
2219             return;
2220         }
2221 
2222         // Trigger carrier config changed
2223         PersistableBundle bundle = new PersistableBundle();
2224         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2225         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2226         overrideCarrierConfig(bundle);
2227 
2228         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2229         if (imsManager == null) {
2230             fail("Cannot find IMS service");
2231         }
2232 
2233         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2234         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2235 
2236         // Connect to device ImsService with MmTel feature and RCS feature
2237         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2238 
2239         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2240                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2241 
2242         // Register the callback to listen to the publish state changed
2243         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
2244         RcsUceAdapter.OnPublishStateChangedListener callback =
2245                 new RcsUceAdapter.OnPublishStateChangedListener() {
2246                     public void onPublishStateChange(int state) {
2247                         publishStateQueue.offer(state);
2248                     }
2249                 };
2250 
2251         // register the publish state callback
2252         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(uceAdapter,
2253                 a -> a.addOnPublishStateChangedListener(getContext().getMainExecutor(), callback),
2254                 ImsException.class,
2255                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
2256 
2257         // Verify receiving the publish state callback immediately after registering the callback.
2258         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
2259                 waitForIntResult(publishStateQueue));
2260         publishStateQueue.clear();
2261 
2262         // Setup the operation of the publish request.
2263         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2264             int networkResp = 200;
2265             String reason = "OK";
2266             cb.onNetworkResponse(networkResp, reason);
2267             listener.onPublish();
2268         });
2269 
2270         // IMS registers
2271         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2272                 IMS_REGI_TECH_LTE);
2273 
2274         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2275         RcsImsCapabilities capabilities =
2276                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2277         sServiceConnector.getCarrierService().getRcsFeature()
2278                 .notifyCapabilitiesStatusChanged(capabilities);
2279 
2280         CapabilityExchangeEventListener eventListener =
2281                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2282 
2283         // ImsService triggers to notify framework publish device's capabilities.
2284         eventListener.onRequestPublishCapabilities(
2285                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2286 
2287         // Verify the ImsService receive the publish request from framework.
2288         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2289                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2290 
2291         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
2292         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2293         publishStateQueue.clear();
2294 
2295         // Verify it is getUcePublishState for the API "getUcePublishState".
2296         int publishState = ShellIdentityUtils.invokeThrowableMethodWithShellPermissions(uceAdapter,
2297                 a -> a.getUcePublishState(),
2298                 ImsException.class,
2299                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
2300         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2301 
2302         // Set the publish request fail (Reason header)
2303         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2304             int networkResp = 200;
2305             String reason = "";
2306             int reasonHeaderCause = 400;
2307             String reasonHeaderText = "Bad Request";
2308             cb.onNetworkResponse(networkResp, reason, reasonHeaderCause, reasonHeaderText);
2309             listener.onPublish();
2310         });
2311 
2312         // ImsService triggers to notify framework publish device's capabilities.
2313         eventListener.onRequestPublishCapabilities(
2314                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2315 
2316         // Verify ImsService receive the publish request from framework.
2317         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2318                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2319 
2320         // Verify that receive the publish failed callback
2321         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
2322         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR,
2323                 waitForIntResult(publishStateQueue));
2324         publishStateQueue.clear();
2325 
2326         publishState = ShellIdentityUtils.invokeThrowableMethodWithShellPermissions(uceAdapter,
2327                 a -> a.getUcePublishState(),
2328                 ImsException.class,
2329                 "android.permission.READ_PRIVILEGED_PHONE_STATE");
2330         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR, publishState);
2331 
2332         overrideCarrierConfig(null);
2333     }
2334 
2335     @Test
testRcsPublishThrottle()2336     public void testRcsPublishThrottle() throws Exception {
2337         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
2338                 TelephonyUtils.CTS_APP_PACKAGE,
2339                 SUPPORT_PUBLISHING_STATE_STRING);
2340         if (!ImsUtils.shouldTestImsService()) {
2341             return;
2342         }
2343 
2344         // Trigger carrier config change
2345         PersistableBundle bundle = new PersistableBundle();
2346         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2347         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2348         overrideCarrierConfig(bundle);
2349 
2350         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2351         if (imsManager == null) {
2352             fail("Cannot get the ImsManager");
2353         }
2354         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2355         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2356 
2357         // Connect to the ImsService
2358         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2359 
2360         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2361                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2362 
2363         // Setup the response of the publish request.
2364         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2365             int networkResp = 200;
2366             String reason = "OK";
2367             cb.onNetworkResponse(networkResp, reason);
2368             listener.onPublish();
2369         });
2370 
2371         // Register the callback to listen to the publish state changed
2372         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
2373         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
2374                 new RcsUceAdapter.OnPublishStateChangedListener() {
2375                     public void onPublishStateChange(int state) {
2376                         publishStateQueue.offer(state);
2377                     }
2378                 };
2379 
2380         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
2381                 .getUiAutomation();
2382         try {
2383             automation.adoptShellPermissionIdentity();
2384             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
2385                     publishStateCallback);
2386         } finally {
2387             automation.dropShellPermissionIdentity();
2388         }
2389 
2390         // Verify receiving the publish state callback immediately after registering the callback.
2391         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
2392                 waitForIntResult(publishStateQueue));
2393         publishStateQueue.clear();
2394 
2395         // IMS registers
2396         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2397                 IMS_REGI_TECH_LTE);
2398 
2399         // Verify the PUBLISH request should not be triggered and the publish state is still
2400         // NOT_PUBLISHED even the IMS is registered.
2401         if (publishStateQueue.poll() != null) {
2402             fail("The PUBLISH request should not be triggered.");
2403         }
2404         try {
2405             automation.adoptShellPermissionIdentity();
2406             int publishState = uceAdapter.getUcePublishState();
2407             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
2408         } finally {
2409             automation.dropShellPermissionIdentity();
2410         }
2411 
2412         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2413         RcsImsCapabilities capabilities =
2414                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2415         sServiceConnector.getCarrierService().getRcsFeature()
2416                 .notifyCapabilitiesStatusChanged(capabilities);
2417 
2418         CapabilityExchangeEventListener eventListener =
2419                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2420 
2421         // Notify framework to send the PUBLISH request to the ImsService.
2422         eventListener.onRequestPublishCapabilities(
2423                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2424 
2425         // Verify that ImsService received the first PUBLISH
2426         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2427                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2428 
2429         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING, waitForIntResult(publishStateQueue));
2430         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2431         publishStateQueue.clear();
2432 
2433         try {
2434             automation.adoptShellPermissionIdentity();
2435             int publishState = uceAdapter.getUcePublishState();
2436             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2437         } finally {
2438             automation.dropShellPermissionIdentity();
2439         }
2440 
2441         // Now enable voice availability
2442         sServiceConnector.getCarrierService().getMmTelFeature()
2443                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
2444                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
2445 
2446         // The published just succeeded. The next publish should not be triggered immediately even
2447         // the device capabilities has changed. Wait 3 seconds to verify the ImsService does not
2448         // receive the publish request from the framework.
2449         assertFalse(sServiceConnector.getCarrierService().waitForLatchCountdown(
2450                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 3000 /* 3 seconds */));
2451 
2452         // However, if the request is triggered from the service, a new publish request should be
2453         // sent immediately.
2454         eventListener.onRequestPublishCapabilities(
2455                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2456 
2457         // Verify the ImsService receive the publish request
2458         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2459                 TestImsService.LATCH_UCE_REQUEST_PUBLISH, 3000 /* Wait up to 3 seconds */));
2460 
2461         overrideCarrierConfig(null);
2462     }
2463 
2464     @Test
testRcsPublishWithSipOptions()2465     public void testRcsPublishWithSipOptions() throws Exception {
2466         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
2467                 TelephonyUtils.CTS_APP_PACKAGE,
2468                 SUPPORT_PUBLISHING_STATE_STRING);
2469         if (!ImsUtils.shouldTestImsService()) {
2470             return;
2471         }
2472 
2473         // Override the carrier config to support SIP OPTIONS
2474         PersistableBundle bundle = new PersistableBundle();
2475         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2476         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
2477         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
2478         overrideCarrierConfig(bundle);
2479 
2480         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2481         if (imsManager == null) {
2482             fail("Cannot get the ImsManager");
2483         }
2484         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2485         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2486 
2487         // Connect to the ImsService
2488         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2489 
2490         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2491                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2492 
2493         // Setup the response of the publish request. In SIP OPTIONS mechanism, ImsService
2494         // should not receive any publish requests.
2495         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2496             fail("ImsService should not receive the PUBLISH request");
2497         });
2498 
2499         // Register the callback to listen to the publish state changed
2500         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
2501         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
2502                 new RcsUceAdapter.OnPublishStateChangedListener() {
2503                     public void onPublishStateChange(int state) {
2504                         publishStateQueue.offer(state);
2505                     }
2506                 };
2507 
2508         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
2509                 .getUiAutomation();
2510 
2511         // Verify receiving the publish state callback immediately after registering the callback
2512         // and the PUBLISH state is OK because the capability mechanism is SIP OPTIONS.
2513         try {
2514             automation.adoptShellPermissionIdentity();
2515             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
2516                     publishStateCallback);
2517             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2518         } finally {
2519             automation.dropShellPermissionIdentity();
2520             publishStateQueue.clear();
2521         }
2522 
2523         // IMS registers
2524         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2525                 IMS_REGI_TECH_LTE);
2526 
2527         // Verify the PUBLISH request should not be triggered and the publish state is still
2528         // OK even the IMS is registered.
2529         if (publishStateQueue.poll() != null) {
2530             fail("The PUBLISH request should not be triggered.");
2531         }
2532         try {
2533             automation.adoptShellPermissionIdentity();
2534             int publishState = uceAdapter.getUcePublishState();
2535             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2536         } finally {
2537             automation.dropShellPermissionIdentity();
2538         }
2539 
2540         // Override the carrier config from SIP OPTIONS to PRESENCE.
2541         bundle = new PersistableBundle();
2542         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2543         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2544         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, false);
2545         overrideCarrierConfig(bundle);
2546 
2547         // When the capability type is changed from SIP OPTIONS to PRESENCE, the publish state
2548         // should be re-initialized to NOT_PUBLISHED
2549         try {
2550             // Verify receiving the callback that the publish state has changed from OK
2551             // to NOT_PUBLISH
2552             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
2553                     waitForIntResult(publishStateQueue));
2554             // Verify it by calling the API getPucePublishState
2555             automation.adoptShellPermissionIdentity();
2556             int publishState = uceAdapter.getUcePublishState();
2557             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
2558         } finally {
2559             publishStateQueue.clear();
2560             automation.dropShellPermissionIdentity();
2561         }
2562 
2563         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2564         RcsImsCapabilities capabilities =
2565                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2566         sServiceConnector.getCarrierService().getRcsFeature()
2567                 .notifyCapabilitiesStatusChanged(capabilities);
2568 
2569         CapabilityExchangeEventListener eventListener =
2570                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2571 
2572         // Setup the operation of the publish request.
2573         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2574             int networkResp = 200;
2575             String reason = "OK";
2576             cb.onNetworkResponse(networkResp, reason);
2577             listener.onPublish();
2578         });
2579 
2580         // Notify framework to send the PUBLISH request to the ImsService.
2581         eventListener.onRequestPublishCapabilities(
2582                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2583 
2584         // Verify that ImsService received the first PUBLISH
2585         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2586                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2587 
2588         // Verify that the publish state should be changed from NOT_PUBLISHED to OK
2589         try {
2590             assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING,
2591                     waitForIntResult(publishStateQueue));
2592             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2593             automation.adoptShellPermissionIdentity();
2594             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, uceAdapter.getUcePublishState());
2595         } finally {
2596             publishStateQueue.clear();
2597             automation.dropShellPermissionIdentity();
2598         }
2599 
2600         overrideCarrierConfig(null);
2601     }
2602 
2603     @Test
testRcsPublishWithAuthorizedErrorResponse()2604     public void testRcsPublishWithAuthorizedErrorResponse() throws Exception {
2605         TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
2606                 TelephonyUtils.CTS_APP_PACKAGE,
2607                 SUPPORT_PUBLISHING_STATE_STRING);
2608         if (!ImsUtils.shouldTestImsService()) {
2609             return;
2610         }
2611 
2612         // Trigger carrier config change
2613         PersistableBundle bundle = new PersistableBundle();
2614         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2615         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2616         overrideCarrierConfig(bundle);
2617 
2618         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2619         if (imsManager == null) {
2620             fail("Cannot get the ImsManager");
2621         }
2622         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2623         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2624 
2625         // Connect to the ImsService
2626         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2627 
2628         // Register the callback to listen to the publish state changed
2629         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
2630         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
2631                 new RcsUceAdapter.OnPublishStateChangedListener() {
2632                     public void onPublishStateChange(int state) {
2633                         publishStateQueue.offer(state);
2634                     }
2635                 };
2636 
2637         final UiAutomation automation = InstrumentationRegistry.getInstrumentation()
2638                 .getUiAutomation();
2639         try {
2640             automation.adoptShellPermissionIdentity();
2641             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
2642                     publishStateCallback);
2643             // Verify receiving the publish state callback after registering the callback.
2644             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
2645                     waitForIntResult(publishStateQueue));
2646         } finally {
2647             publishStateQueue.clear();
2648             automation.dropShellPermissionIdentity();
2649         }
2650 
2651         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2652                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2653 
2654         // Setup the response of the publish request.
2655         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2656             int networkResp = 200;
2657             String reason = "OK";
2658             cb.onNetworkResponse(networkResp, reason);
2659             listener.onPublish();
2660         });
2661 
2662         // IMS registers
2663         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2664                 IMS_REGI_TECH_LTE);
2665 
2666         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2667         RcsImsCapabilities capabilities =
2668                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2669         sServiceConnector.getCarrierService().getRcsFeature()
2670                 .notifyCapabilitiesStatusChanged(capabilities);
2671 
2672         CapabilityExchangeEventListener eventListener =
2673                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2674 
2675         // Notify framework to send the PUBLISH request to the ImsService.
2676         eventListener.onRequestPublishCapabilities(
2677                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2678 
2679         // Verify ImsService receive the publish request from framework.
2680         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2681                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2682 
2683         try {
2684             // Verify the publish state callback is received.
2685             assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING,
2686                     waitForIntResult(publishStateQueue));
2687             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2688             // Verify the value of getting from the API is PUBLISH_STATE_OK
2689             automation.adoptShellPermissionIdentity();
2690             int publishState = uceAdapter.getUcePublishState();
2691             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2692         } finally {
2693             publishStateQueue.clear();
2694             automation.dropShellPermissionIdentity();
2695         }
2696 
2697         // Reply the SIP code 403 FORBIDDEN
2698         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2699             int networkResp = 403;
2700             String reason = "FORBIDDEN";
2701             cb.onNetworkResponse(networkResp, reason);
2702             listener.onPublish();
2703         });
2704 
2705         // Notify framework to send the PUBLISH request to the ImsService.
2706         eventListener.onRequestPublishCapabilities(
2707                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2708 
2709         // Verify ImsService receive the publish request from framework.
2710         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2711                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2712 
2713         try {
2714             // Verify the publish state callback is received.
2715             assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING,
2716                     waitForIntResult(publishStateQueue));
2717             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR,
2718                     waitForIntResult(publishStateQueue));
2719             // Verify the value of getting from the API is PUBLISH_STATE_RCS_PROVISION_ERROR
2720             automation.adoptShellPermissionIdentity();
2721             int publishState = uceAdapter.getUcePublishState();
2722             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR, publishState);
2723         } finally {
2724             publishStateQueue.clear();
2725             automation.dropShellPermissionIdentity();
2726         }
2727 
2728         // Reply the SIP code 504 SERVER TIMEOUT
2729         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2730             int networkResp = 504;
2731             String reason = "SERVER TIMEOUT";
2732             cb.onNetworkResponse(networkResp, reason);
2733             listener.onPublish();
2734         });
2735 
2736         // Notify framework to send the PUBLISH request to the ImsService.
2737         eventListener.onRequestPublishCapabilities(
2738                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2739 
2740         // Verify ImsService receive the publish request from framework.
2741         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2742                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2743 
2744         try {
2745             // Verify the publish state callback is received.
2746             assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING,
2747                     waitForIntResult(publishStateQueue));
2748             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR,
2749                     waitForIntResult(publishStateQueue));
2750             // Verify the value of getting from the API is PUBLISH_STATE_RCS_PROVISION_ERROR
2751             automation.adoptShellPermissionIdentity();
2752             int publishState = uceAdapter.getUcePublishState();
2753             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR, publishState);
2754         } finally {
2755             publishStateQueue.clear();
2756             automation.dropShellPermissionIdentity();
2757         }
2758 
2759         LinkedBlockingQueue<Integer> errorQueue = new LinkedBlockingQueue<>();
2760         LinkedBlockingQueue<Long> errorRetryQueue = new LinkedBlockingQueue<>();
2761         LinkedBlockingQueue<Boolean> completeQueue = new LinkedBlockingQueue<>();
2762         LinkedBlockingQueue<RcsContactUceCapability> capabilityQueue = new LinkedBlockingQueue<>();
2763         RcsUceAdapter.CapabilitiesCallback callback = new RcsUceAdapter.CapabilitiesCallback() {
2764             @Override
2765             public void onCapabilitiesReceived(List<RcsContactUceCapability> capabilities) {
2766                 capabilities.forEach(c -> capabilityQueue.offer(c));
2767             }
2768             @Override
2769             public void onComplete() {
2770                 completeQueue.offer(true);
2771             }
2772             @Override
2773             public void onError(int errorCode, long retryAfterMilliseconds) {
2774                 errorQueue.offer(errorCode);
2775                 errorRetryQueue.offer(retryAfterMilliseconds);
2776             }
2777         };
2778 
2779         capExchangeImpl.setSubscribeOperation((uris, cb) -> {
2780             fail("Should not received the SUBSCRIBE request");
2781         });
2782 
2783         Collection<Uri> contacts = Collections.singletonList(
2784                 Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null));
2785 
2786         try {
2787             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(
2788                     uceAdapter,
2789                     adapter -> adapter.requestCapabilities(contacts, Runnable::run, callback),
2790                     ImsException.class,
2791                     "android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE");
2792         } catch (SecurityException e) {
2793             fail("requestCapabilities should succeed with ACCESS_RCS_USER_CAPABILITY_EXCHANGE. "
2794                     + "Exception: " + e);
2795         } catch (ImsException e) {
2796             fail("requestCapabilities failed " + e);
2797         }
2798 
2799         // Verify the capability request should fail
2800         try {
2801             assertEquals(RcsUceAdapter.ERROR_NOT_AUTHORIZED, waitForIntResult(errorQueue));
2802             assertEquals(Long.valueOf(0L), waitForResult(errorRetryQueue));
2803         } catch (Exception e) {
2804             fail("requestCapabilities with command error failed: " + e);
2805         } finally {
2806             errorQueue.clear();
2807             errorRetryQueue.clear();
2808         }
2809 
2810         // Reset the UCE device state
2811         try {
2812             sServiceConnector.removeUceRequestDisallowedStatus(sTestSlot);
2813         } catch (Exception e) {
2814             fail("Cannot remove request disallowed status: " + e);
2815         }
2816 
2817         // Reply the SIP code 404 NOT FOUND
2818         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2819             int networkResp = 404;
2820             String reason = "NOT FOUND";
2821             cb.onNetworkResponse(networkResp, reason);
2822             listener.onPublish();
2823         });
2824 
2825         // Notify framework to send the PUBLISH request to the ImsService.
2826         eventListener.onRequestPublishCapabilities(
2827                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2828         // Verify ImsService receive the publish request from framework.
2829         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2830                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2831 
2832         // Verify the publish state callback is received.
2833         assertEquals(RcsUceAdapter.PUBLISH_STATE_PUBLISHING,
2834                 waitForIntResult(publishStateQueue));
2835         assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR,
2836                 waitForIntResult(publishStateQueue));
2837         publishStateQueue.clear();
2838         try {
2839             // Verify the value of getting from the API is PUBLISH_STATE_RCS_PROVISION_ERROR
2840             automation.adoptShellPermissionIdentity();
2841             int publishState = uceAdapter.getUcePublishState();
2842             assertEquals(RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR, publishState);
2843         } finally {
2844             automation.dropShellPermissionIdentity();
2845         }
2846 
2847         try {
2848             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(
2849                     uceAdapter,
2850                     adapter -> adapter.requestCapabilities(contacts, Runnable::run, callback),
2851                     ImsException.class,
2852                     "android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE");
2853         } catch (SecurityException e) {
2854             fail("requestCapabilities should succeed with ACCESS_RCS_USER_CAPABILITY_EXCHANGE. "
2855                     + "Exception: " + e);
2856         } catch (ImsException e) {
2857             fail("requestCapabilities failed " + e);
2858         }
2859 
2860         // Reset the UCE device state
2861         try {
2862             sServiceConnector.removeUceRequestDisallowedStatus(sTestSlot);
2863         } catch (Exception e) {
2864             fail("Cannot remove request disallowed status: " + e);
2865         }
2866 
2867         overrideCarrierConfig(null);
2868     }
2869 
2870     @Ignore("the compatibility framework does not currently support changing compatibility flags"
2871             + " on user builds for device side CTS tests. Ignore this test until support is added")
2872     @Test
testRcsPublishWithDisableCompactCommand()2873     public void testRcsPublishWithDisableCompactCommand() throws Exception {
2874         TelephonyUtils.disableCompatCommand(InstrumentationRegistry.getInstrumentation(),
2875                 TelephonyUtils.CTS_APP_PACKAGE,
2876                 SUPPORT_PUBLISHING_STATE_STRING);
2877 
2878         if (!ImsUtils.shouldTestImsService()) {
2879             return;
2880         }
2881         // Trigger carrier config changed
2882         PersistableBundle bundle = new PersistableBundle();
2883         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
2884         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
2885         overrideCarrierConfig(bundle);
2886 
2887         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
2888         if (imsManager == null) {
2889             fail("Cannot find IMS service");
2890         }
2891 
2892         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
2893         RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
2894 
2895         // Connect to device ImsService with MmTel feature and RCS feature
2896         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
2897 
2898         TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
2899                 .getRcsFeature().getRcsCapabilityExchangeImpl();
2900 
2901         // Register the callback to listen to the publish state changed
2902         LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
2903         RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
2904                 new RcsUceAdapter.OnPublishStateChangedListener() {
2905                     public void onPublishStateChange(int state) {
2906                         publishStateQueue.offer(state);
2907                     }
2908                 };
2909 
2910         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
2911         try {
2912             automan.adoptShellPermissionIdentity();
2913             // register publish state callback
2914             uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
2915                     publishStateCallback);
2916         } finally {
2917             automan.dropShellPermissionIdentity();
2918         }
2919         // Verify receiving the publish state callback immediately after registering the callback.
2920         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
2921                 waitForIntResult(publishStateQueue));
2922         publishStateQueue.clear();
2923 
2924         // Verify the value of getting from the API is NOT_PUBLISHED
2925         try {
2926             automan.adoptShellPermissionIdentity();
2927             int publishState = uceAdapter.getUcePublishState();
2928             assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
2929         } finally {
2930             automan.dropShellPermissionIdentity();
2931         }
2932 
2933         // Setup the operation of the publish request.
2934         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
2935             int networkResp = 200;
2936             String reason = "";
2937             cb.onNetworkResponse(networkResp, reason);
2938             listener.onPublish();
2939         });
2940 
2941         // IMS registers
2942         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
2943                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2944 
2945         // Framework should not trigger the device capabilities publish when the framework doesn't
2946         // receive that the RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE is enabled.
2947         if (publishStateQueue.poll() != null) {
2948             fail("The publish callback should not be called because presence uce is not ready");
2949         }
2950 
2951         // Notify framework that the RCS capability status is changed and PRESENCE UCE is enabled.
2952         RcsImsCapabilities capabilities =
2953                 new RcsImsCapabilities(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
2954         sServiceConnector.getCarrierService().getRcsFeature()
2955                 .notifyCapabilitiesStatusChanged(capabilities);
2956 
2957         CapabilityExchangeEventListener eventListener =
2958                 sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
2959 
2960         // ImsService triggers to notify framework publish device's capabilities.
2961         eventListener.onRequestPublishCapabilities(
2962                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2963 
2964         // Verify ImsService receive the publish request from framework.
2965         // Sending Publish means that notifyPendingPublicRequest() has been processed.
2966         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2967                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2968 
2969         // Since framework compatibility is disabled, the newly added publishing state should
2970         // not be set and should be set to PUBLISH_STATE_OK
2971         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2972         publishStateQueue.clear();
2973 
2974         // Verify the value of getting from the API is PUBLISH_STATE_OK
2975         try {
2976             automan.adoptShellPermissionIdentity();
2977             int publishState = uceAdapter.getUcePublishState();
2978             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2979         } finally {
2980             automan.dropShellPermissionIdentity();
2981         }
2982 
2983         // ImsService triggers to notify framework publish device's capabilities.
2984         eventListener.onRequestPublishCapabilities(
2985                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
2986         // Verify ImsService receive the publish request from framework.
2987         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
2988                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
2989 
2990         // Since framework compatibility is disabled, the newly added publishing state should
2991         // not be set and should be set to PUBLISH_STATE_OK
2992         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
2993         publishStateQueue.clear();
2994         // Verify the value of getting from the API is PUBLISH_STATE_OK
2995         try {
2996             automan.adoptShellPermissionIdentity();
2997             int publishState = uceAdapter.getUcePublishState();
2998             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
2999         } finally {
3000             automan.dropShellPermissionIdentity();
3001         }
3002         publishStateQueue.clear();
3003 
3004         // ImsService triggers to notify framework publish updated.
3005         eventListener.onPublishUpdated(400, "", 0, "");
3006         assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR,
3007                 waitForIntResult(publishStateQueue));
3008         publishStateQueue.clear();
3009 
3010         // Verify the value of getting from the API is PUBLISH_STATE_OTHER_ERROR
3011         try {
3012             automan.adoptShellPermissionIdentity();
3013             int publishState = uceAdapter.getUcePublishState();
3014             assertEquals(RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR, publishState);
3015         } finally {
3016             automan.dropShellPermissionIdentity();
3017         }
3018 
3019         // ImsService triggers to notify framework publish device's capabilities.
3020         eventListener.onRequestPublishCapabilities(
3021                 RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
3022 
3023         // Verify ImsService receive the publish request from framework.
3024         // Sending Publish means that notifyPendingPublicRequest() has been processed.
3025         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
3026                 TestImsService.LATCH_UCE_REQUEST_PUBLISH));
3027 
3028         assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
3029                 waitForIntResult(publishStateQueue));
3030         assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
3031         publishStateQueue.clear();
3032 
3033         // Verify the value of getting from the API is PUBLISH_STATE_OK
3034         try {
3035             automan.adoptShellPermissionIdentity();
3036             int publishState = uceAdapter.getUcePublishState();
3037             assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
3038         } finally {
3039             automan.dropShellPermissionIdentity();
3040         }
3041         overrideCarrierConfig(null);
3042     }
3043 
3044     @Test
testRcsManagerRegistrationCallback()3045     public void testRcsManagerRegistrationCallback() throws Exception {
3046         if (!ImsUtils.shouldTestImsService()) {
3047             return;
3048         }
3049 
3050         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3051         if (imsManager == null) {
3052             fail("Cannot find IMS service");
3053         }
3054 
3055         // Connect to device ImsService with RcsFeature
3056         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3057         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
3058 
3059         // Override the carrier config
3060         PersistableBundle bundle = new PersistableBundle();
3061         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
3062         overrideCarrierConfig(bundle);
3063 
3064         // Wait for the framework to set the capabilities on the ImsService
3065         sServiceConnector.getCarrierService().waitForLatchCountdown(
3066                 TestImsService.LATCH_RCS_CAP_SET);
3067 
3068         // Start de-registered
3069         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
3070                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
3071                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3072 
3073         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3074         LinkedBlockingQueue<SipDetails> mDeregiQueue = new LinkedBlockingQueue<>();
3075         RegistrationManager.RegistrationCallback callback =
3076                 new RegistrationManager.RegistrationCallback() {
3077                     @Override
3078                     public void onRegistered(int imsTransportType) {
3079                         mQueue.offer(imsTransportType);
3080                     }
3081 
3082                     @Override
3083                     public void onRegistering(int imsTransportType) {
3084                         mQueue.offer(imsTransportType);
3085                     }
3086 
3087                     @Override
3088                     public void onUnregistered(ImsReasonInfo info) {
3089                         mQueue.offer(info.getCode());
3090                     }
3091 
3092                     @Override
3093                     public void onUnregistered(ImsReasonInfo info, SipDetails details) {
3094                         mQueue.offer(info.getCode());
3095                         mDeregiQueue.offer(details);
3096                     }
3097 
3098                     @Override
3099                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
3100                         mQueue.offer(imsTransportType);
3101                         mQueue.offer(info.getCode());
3102                     }
3103                 };
3104 
3105         // Verify the registerImsRegistrationCallback should fail without the required permission
3106         try {
3107             imsRcsManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
3108             fail("registerImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission.");
3109         } catch (SecurityException e) {
3110             //expected
3111         }
3112 
3113         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
3114                 m -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
3115                 ImsException.class,
3116                 "android.permission.READ_PRECISE_PHONE_STATE");
3117 
3118         // Verify it's not registered
3119         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
3120         assertTrue(mDeregiQueue.isEmpty());
3121 
3122         // Start registration
3123         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
3124                 IMS_REGI_TECH_LTE);
3125         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3126 
3127         // Complete registration
3128         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3129                 IMS_REGI_TECH_LTE);
3130         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3131 
3132         // Fail handover to IWLAN
3133         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
3134                 IMS_REGI_TECH_IWLAN,
3135                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
3136                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3137         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
3138         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
3139 
3140         int cSeq = 1;
3141         int responseCode = 200;
3142         String responsePhrase = "OK";
3143         String callId = "testCall-Id";
3144         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
3145                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
3146                         ImsReasonInfo.CODE_UNSPECIFIED, ""),
3147                 new SipDetails.Builder(SipDetails.METHOD_REGISTER)
3148                                 .setCSeq(cSeq).setSipResponseCode(responseCode, responsePhrase)
3149                                 .setCallId(callId).build()
3150         );
3151         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
3152         SipDetails details = waitForResult(mDeregiQueue);
3153         assertEquals(SipDetails.METHOD_REGISTER, details.getMethod());
3154         assertEquals(cSeq, details.getCSeq());
3155         assertEquals(responseCode, details.getResponseCode());
3156         assertEquals(responsePhrase, details.getResponsePhrase());
3157         assertEquals(callId, details.getCallId());
3158 
3159         // Verify the unregisterImsRegistrationCallback should failure without the permission.
3160         try {
3161             imsRcsManager.unregisterImsRegistrationCallback(callback);
3162             fail("unregisterImsRegistrationCallback requires READ_PRECISE_PHONE_STATE permission");
3163         } catch (SecurityException e) {
3164             //expected
3165         }
3166 
3167         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
3168                 m -> m.unregisterImsRegistrationCallback(callback),
3169                 ImsException.class,
3170                 "android.permission.READ_PRECISE_PHONE_STATE");
3171 
3172         overrideCarrierConfig(null);
3173     }
3174 
3175     @Test
testMmTelManagerRegistrationStateR()3176     public void testMmTelManagerRegistrationStateR() throws Exception {
3177         if (!ImsUtils.shouldTestImsService()) {
3178             return;
3179         }
3180         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3181         RegistrationManager regManager = imsManager.getImsMmTelManager(sTestSub);
3182         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3183 
3184         triggerFrameworkConnectToCarrierImsService();
3185 
3186         // Start deregistered
3187         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
3188                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
3189                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3190 
3191         RegistrationManager.RegistrationCallback callback =
3192                 new RegistrationManager.RegistrationCallback() {
3193                     @Override
3194                     public void onRegistered(int imsTransportType) {
3195                         mQueue.offer(imsTransportType);
3196                     }
3197 
3198                     @Override
3199                     public void onRegistering(int imsTransportType) {
3200                         mQueue.offer(imsTransportType);
3201                     }
3202 
3203                     @Override
3204                     public void onUnregistered(ImsReasonInfo info) {
3205                         mQueue.offer(info.getCode());
3206                     }
3207 
3208                     @Override
3209                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
3210                         mQueue.offer(imsTransportType);
3211                         mQueue.offer(info.getCode());
3212                     }
3213                 };
3214 
3215         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
3216         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mmTelManager,
3217                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
3218                 ImsException.class);
3219         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
3220 
3221         // Ensure that the Framework reports Deregistered correctly
3222         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
3223         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
3224 
3225         // Start registration
3226         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
3227                 IMS_REGI_TECH_LTE);
3228         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3229         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
3230         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3231 
3232         // Complete registration
3233         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3234                 IMS_REGI_TECH_LTE);
3235         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3236         verifyRegistrationState(regManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
3237         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3238 
3239 
3240         // Fail handover to IWLAN
3241         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
3242                 IMS_REGI_TECH_IWLAN,
3243                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
3244                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3245         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
3246         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
3247         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3248 
3249         // handover to IWLAN
3250         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3251                 IMS_REGI_TECH_IWLAN);
3252         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
3253         verifyRegistrationTransportType(regManager, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
3254 
3255         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mmTelManager,
3256                 (m) -> m.unregisterImsRegistrationCallback(callback));
3257     }
3258 
3259     @Test
testRcsManagerRegistrationState()3260     public void testRcsManagerRegistrationState() throws Exception {
3261         if (!ImsUtils.shouldTestImsService()) {
3262             return;
3263         }
3264 
3265         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3266         if (imsManager == null) {
3267             fail("Cannot find IMS service");
3268         }
3269 
3270         // Connect to device ImsService with RcsFeature
3271         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3272 
3273         // Override the carrier config
3274         PersistableBundle bundle = new PersistableBundle();
3275         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
3276         overrideCarrierConfig(bundle);
3277 
3278         sServiceConnector.getCarrierService().waitForLatchCountdown(
3279                 TestImsService.LATCH_RCS_CAP_SET);
3280 
3281         // Start de-registered
3282         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
3283                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
3284                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3285 
3286         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
3287         RegistrationManager.RegistrationCallback callback =
3288                 new RegistrationManager.RegistrationCallback() {
3289                     @Override
3290                     public void onRegistered(int imsTransportType) {
3291                         mQueue.offer(imsTransportType);
3292                     }
3293 
3294                     @Override
3295                     public void onRegistering(int imsTransportType) {
3296                         mQueue.offer(imsTransportType);
3297                     }
3298 
3299                     @Override
3300                     public void onUnregistered(ImsReasonInfo info) {
3301                         mQueue.offer(info.getCode());
3302                     }
3303 
3304                     @Override
3305                     public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
3306                         mQueue.offer(imsTransportType);
3307                         mQueue.offer(info.getCode());
3308                     }
3309                 };
3310 
3311         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
3312         ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(imsRcsManager,
3313                 (m) -> m.registerImsRegistrationCallback(getContext().getMainExecutor(), callback),
3314                 ImsException.class);
3315         assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mQueue));
3316 
3317         // Verify the getRegistrationState should fail without the required permission
3318         try {
3319             imsRcsManager.getRegistrationState(getContext().getMainExecutor(), mQueue::offer);
3320             fail("getRegistrationState requires READ_PRECISE_PHONE_STATE permission.");
3321         } catch (SecurityException e) {
3322             //expected
3323         }
3324 
3325         // Verify the getRegistrationTransportType should fail without the required permission
3326         try {
3327             imsRcsManager.getRegistrationTransportType(getContext().getMainExecutor(),
3328                     mQueue::offer);
3329             fail("getRegistrationTransportType requires READ_PRECISE_PHONE_STATE permission.");
3330         } catch (SecurityException e) {
3331             //expected
3332         }
3333 
3334         // Ensure that the Framework reports Deregistered correctly
3335         verifyRegistrationState(imsRcsManager,
3336                 RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
3337         verifyRegistrationTransportType(imsRcsManager,
3338                 AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
3339 
3340         // Start registration
3341         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
3342                 IMS_REGI_TECH_LTE);
3343         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3344         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
3345         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3346 
3347         // Complete registration
3348         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3349                 IMS_REGI_TECH_LTE);
3350         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3351         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
3352         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3353 
3354         // Start registration over NR
3355         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(
3356                 IMS_REGI_TECH_NR);
3357         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3358         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERING);
3359         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3360 
3361         // Complete registration over NR
3362         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3363                 IMS_REGI_TECH_NR);
3364         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, waitForIntResult(mQueue));
3365         verifyRegistrationState(imsRcsManager, RegistrationManager.REGISTRATION_STATE_REGISTERED);
3366         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3367 
3368         // Fail handover to IWLAN
3369         sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
3370                 IMS_REGI_TECH_IWLAN,
3371                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
3372                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
3373         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
3374         assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mQueue));
3375         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
3376 
3377         // handover to IWLAN
3378         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3379                 IMS_REGI_TECH_IWLAN);
3380         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mQueue));
3381         verifyRegistrationTransportType(imsRcsManager, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
3382         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(imsRcsManager,
3383                 (m) -> m.unregisterImsRegistrationCallback(callback));
3384 
3385         overrideCarrierConfig(null);
3386     }
3387 
3388     @Test
testCapabilityStatusCallback()3389     public void testCapabilityStatusCallback() throws Exception {
3390         if (!ImsUtils.shouldTestImsService()) {
3391             return;
3392         }
3393 
3394         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3395         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
3396 
3397         triggerFrameworkConnectToCarrierImsService();
3398 
3399         // Wait for the framework to set the capabilities on the ImsService
3400         sServiceConnector.getCarrierService().waitForLatchCountdown(
3401                 TestImsService.LATCH_MMTEL_CAP_SET);
3402         MmTelFeature.MmTelCapabilities fwCaps = sServiceConnector.getCarrierService()
3403                 .getMmTelFeature().getCapabilities();
3404         // Make sure we start off with every capability unavailable
3405         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3406                 IMS_REGI_TECH_LTE);
3407         sServiceConnector.getCarrierService().getMmTelFeature()
3408                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities());
3409 
3410         // Make sure the capabilities match the API getter for capabilities
3411         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3412         // Latch will count down here (we callback on the state during registration).
3413         try {
3414             automan.adoptShellPermissionIdentity();
3415             // Make sure we are tracking voice capability over LTE properly.
3416             assertEquals(fwCaps.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
3417                     mmTelManager.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
3418                             IMS_REGI_TECH_LTE));
3419         } finally {
3420             automan.dropShellPermissionIdentity();
3421         }
3422 
3423         // This is a little bit gross looking, but on P devices, I can not define classes that
3424         // extend ImsMmTelManager.CapabilityCallback (because it doesn't exist), so this has to
3425         // happen as an anon class here.
3426         LinkedBlockingQueue<MmTelFeature.MmTelCapabilities> mQueue = new LinkedBlockingQueue<>();
3427         ImsMmTelManager.CapabilityCallback callback = new ImsMmTelManager.CapabilityCallback() {
3428 
3429             @Override
3430             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
3431                 mQueue.offer(capabilities);
3432             }
3433         };
3434 
3435         // Latch will count down here (we callback on the state during registration).
3436         try {
3437             automan.adoptShellPermissionIdentity();
3438             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
3439         } finally {
3440             automan.dropShellPermissionIdentity();
3441         }
3442 
3443         try {
3444             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
3445             fail("registerMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
3446         } catch (SecurityException e) {
3447             //expected
3448         }
3449 
3450         // We should not have voice availability here, we notified the framework earlier.
3451         MmTelFeature.MmTelCapabilities capCb = waitForResult(mQueue);
3452         assertNotNull(capCb);
3453         assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
3454 
3455         // Now enable voice availability
3456         sServiceConnector.getCarrierService().getMmTelFeature()
3457                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
3458                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
3459         capCb = waitForResult(mQueue);
3460         assertNotNull(capCb);
3461         assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
3462 
3463         try {
3464             automan.adoptShellPermissionIdentity();
3465             assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
3466                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
3467                     IMS_REGI_TECH_LTE)));
3468 
3469             mmTelManager.unregisterMmTelCapabilityCallback(callback);
3470         } finally {
3471             automan.dropShellPermissionIdentity();
3472         }
3473 
3474         try {
3475             mmTelManager.unregisterMmTelCapabilityCallback(callback);
3476             fail("unregisterMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
3477         } catch (SecurityException e) {
3478             //expected
3479         }
3480     }
3481 
3482     @Test
testCallComposerCapabilityStatusCallback()3483     public void testCallComposerCapabilityStatusCallback() throws Exception {
3484         if (!ImsUtils.shouldTestImsService()) {
3485             return;
3486         }
3487 
3488         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3489         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
3490 
3491         triggerFrameworkConnectToCarrierImsService();
3492 
3493         // Wait for the framework to set the capabilities on the ImsService
3494         sServiceConnector.getCarrierService().waitForLatchCountdown(
3495                 TestImsService.LATCH_MMTEL_CAP_SET);
3496         MmTelFeature.MmTelCapabilities fwCaps = sServiceConnector.getCarrierService()
3497                 .getMmTelFeature().getCapabilities();
3498         // Make sure we start off with every capability unavailable
3499         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3500                 IMS_REGI_TECH_LTE);
3501         sServiceConnector.getCarrierService().getMmTelFeature()
3502                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities());
3503 
3504         // Make sure the capabilities match the API getter for capabilities
3505         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3506         // Latch will count down here (we callback on the state during registration).
3507         try {
3508             automan.adoptShellPermissionIdentity();
3509             // Make sure we are tracking voice capability over LTE properly.
3510             assertEquals(fwCaps.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
3511                     mmTelManager.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
3512                     IMS_REGI_TECH_LTE));
3513         } finally {
3514             automan.dropShellPermissionIdentity();
3515         }
3516 
3517         LinkedBlockingQueue<MmTelFeature.MmTelCapabilities> mQueue = new LinkedBlockingQueue<>();
3518         ImsMmTelManager.CapabilityCallback callback = new ImsMmTelManager.CapabilityCallback() {
3519 
3520             @Override
3521             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
3522                 mQueue.offer(capabilities);
3523             }
3524         };
3525 
3526         // Latch will count down here (we callback on the state during registration).
3527         try {
3528             automan.adoptShellPermissionIdentity();
3529             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
3530         } finally {
3531             automan.dropShellPermissionIdentity();
3532         }
3533 
3534         try {
3535             mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
3536             fail("registerMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
3537         } catch (SecurityException e) {
3538             //expected
3539         }
3540 
3541         // We should not have voice availability here, we notified the framework earlier.
3542         MmTelFeature.MmTelCapabilities capCb = waitForResult(mQueue);
3543         assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
3544         if (com.android.server.telecom.flags.Flags.businessCallComposer()) {
3545             assertFalse(capCb.isCapable(
3546                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY));
3547         }
3548         // Now enable call composer availability
3549         sServiceConnector.getCarrierService().getMmTelFeature()
3550                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
3551                 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
3552         capCb = waitForResult(mQueue);
3553         assertNotNull(capCb);
3554         assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
3555         if (com.android.server.telecom.flags.Flags.businessCallComposer()) {
3556             assertFalse(capCb.isCapable(
3557                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY));
3558         }
3559 
3560         try {
3561             automan.adoptShellPermissionIdentity();
3562             assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
3563                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER,
3564                     IMS_REGI_TECH_LTE)));
3565         } finally {
3566             automan.dropShellPermissionIdentity();
3567         }
3568 
3569         if (com.android.server.telecom.flags.Flags.businessCallComposer()) {
3570             // Now enable call composer availability
3571             sServiceConnector.getCarrierService().getMmTelFeature()
3572                     .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
3573                             MmTelFeature.MmTelCapabilities
3574                                     .CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY));
3575             capCb = waitForResult(mQueue);
3576             assertNotNull(capCb);
3577             assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities
3578                     .CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY));
3579             assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities
3580                     .CAPABILITY_TYPE_CALL_COMPOSER));
3581 
3582             try {
3583                 automan.adoptShellPermissionIdentity();
3584                 assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
3585                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY,
3586                         IMS_REGI_TECH_LTE)));
3587                 mmTelManager.unregisterMmTelCapabilityCallback(callback);
3588             } finally {
3589                 automan.dropShellPermissionIdentity();
3590             }
3591         }
3592 
3593         try {
3594             mmTelManager.unregisterMmTelCapabilityCallback(callback);
3595             fail("unregisterMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
3596         } catch (SecurityException e) {
3597             //expected
3598         }
3599     }
3600 
3601     /**
3602      * We are specifically testing a race case here such that IsAvailable returns the correct
3603      * capability status during the callback.
3604      */
3605     @Test
testCapabilityStatusWithIsAvailableDuringCallback()3606     public void testCapabilityStatusWithIsAvailableDuringCallback() throws Exception {
3607         if (!ImsUtils.shouldTestImsService()) {
3608             return;
3609         }
3610 
3611         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3612         ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
3613 
3614         triggerFrameworkConnectToCarrierImsService();
3615 
3616         // Wait for the framework to set the capabilities on the ImsService
3617         sServiceConnector.getCarrierService().waitForLatchCountdown(
3618                 TestImsService.LATCH_MMTEL_CAP_SET);
3619 
3620 
3621         // Make sure we start off with every capability unavailable
3622         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3623                 IMS_REGI_TECH_LTE);
3624         MmTelFeature.MmTelCapabilities stdCapabilities = new MmTelFeature.MmTelCapabilities();
3625         sServiceConnector.getCarrierService().getMmTelFeature()
3626                 .notifyCapabilitiesStatusChanged(stdCapabilities);
3627 
3628 
3629         // Make sure the capabilities match the API getter for capabilities
3630         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3631 
3632         //This lock is to keep the shell permissions from being dropped on a different thread
3633         //causing a permission error.
3634         Object lockObj = new Object();
3635 
3636         synchronized (lockObj) {
3637             try {
3638                 automan.adoptShellPermissionIdentity();
3639                 boolean isAvailableBeforeStatusChange = mmTelManager.isAvailable(
3640                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
3641                         IMS_REGI_TECH_LTE);
3642                 assertFalse(isAvailableBeforeStatusChange);
3643             } finally {
3644                 automan.dropShellPermissionIdentity();
3645             }
3646         }
3647 
3648         LinkedBlockingQueue<Boolean> voiceIsAvailable = new LinkedBlockingQueue<>();
3649         ImsMmTelManager.CapabilityCallback verifyCapabilityStatusCallaback =
3650                 new ImsMmTelManager.CapabilityCallback() {
3651             @Override
3652             public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
3653                 synchronized (lockObj) {
3654                     try {
3655                         automan.adoptShellPermissionIdentity();
3656                         boolean isVoiceAvailable = mmTelManager
3657                                 .isAvailable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
3658                                         IMS_REGI_TECH_LTE);
3659 
3660                         voiceIsAvailable.offer(isVoiceAvailable);
3661                     } finally {
3662                         automan.dropShellPermissionIdentity();
3663                     }
3664                 }
3665             }
3666         };
3667 
3668         synchronized (lockObj) {
3669             // Latch will count down here (we callback on the state during registration).
3670             try {
3671                 automan.adoptShellPermissionIdentity();
3672                 mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(),
3673                         verifyCapabilityStatusCallaback);
3674             } finally {
3675                 automan.dropShellPermissionIdentity();
3676             }
3677         }
3678 
3679         // Now enable voice availability
3680         Boolean isAvailableDuringRegister = waitForResult(voiceIsAvailable);
3681         assertNotNull(isAvailableDuringRegister);
3682         assertFalse(isAvailableDuringRegister);
3683         sServiceConnector.getCarrierService().getMmTelFeature()
3684                 .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
3685                         MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE));
3686         Boolean isAvailableAfterStatusChange = waitForResult(voiceIsAvailable);
3687         assertNotNull(isAvailableAfterStatusChange);
3688         assertTrue(isAvailableAfterStatusChange);
3689 
3690         synchronized (lockObj) {
3691             try {
3692                 automan.adoptShellPermissionIdentity();
3693                 mmTelManager.unregisterMmTelCapabilityCallback(verifyCapabilityStatusCallaback);
3694             } finally {
3695                 automan.dropShellPermissionIdentity();
3696             }
3697         }
3698     }
3699 
3700     @Test
testRcsCapabilityStatusCallback()3701     public void testRcsCapabilityStatusCallback() throws Exception {
3702         if (!ImsUtils.shouldTestImsService()) {
3703             return;
3704         }
3705 
3706         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
3707         if (imsManager == null) {
3708             fail("Cannot find IMS service");
3709         }
3710 
3711         // Connect to device ImsService with RcsFeature
3712         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
3713 
3714         int registrationTech = IMS_REGI_TECH_LTE;
3715         ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
3716 
3717         // Make sure we start off with none-capability
3718         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
3719                 IMS_REGI_TECH_LTE);
3720         RcsImsCapabilities noCapabilities = new RcsImsCapabilities(RCS_CAP_NONE);
3721         sServiceConnector.getCarrierService().getRcsFeature()
3722                 .notifyCapabilitiesStatusChanged(noCapabilities);
3723 
3724         // Make sure the capabilities match the API getter for capabilities
3725         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3726         // Latch will count down here (we callback on the state during registration).
3727         try {
3728             automan.adoptShellPermissionIdentity();
3729             // Make sure we are tracking voice capability over LTE properly.
3730             RcsImsCapabilities availability = sServiceConnector.getCarrierService()
3731                     .getRcsFeature().queryCapabilityStatus();
3732             assertFalse(availability.isCapable(RCS_CAP_OPTIONS));
3733             assertFalse(availability.isCapable(RCS_CAP_PRESENCE));
3734         } finally {
3735             automan.dropShellPermissionIdentity();
3736         }
3737 
3738         // Trigger carrier config changed
3739         PersistableBundle bundle = new PersistableBundle();
3740         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
3741         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
3742         overrideCarrierConfig(bundle);
3743 
3744         sServiceConnector.getCarrierService().waitForLatchCountdown(
3745                 TestImsService.LATCH_RCS_CAP_SET);
3746 
3747         // The carrier config changed should trigger RcsFeature#changeEnabledCapabilities
3748         try {
3749             automan.adoptShellPermissionIdentity();
3750             // Checked by isCapable api to make sure RcsFeature#changeEnabledCapabilities is called
3751             assertTrue(ImsUtils.retryUntilTrue(() ->
3752                     imsRcsManager.isCapable(RCS_CAP_OPTIONS, registrationTech)));
3753             assertTrue(ImsUtils.retryUntilTrue(() ->
3754                     imsRcsManager.isCapable(RCS_CAP_PRESENCE, registrationTech)));
3755         } finally {
3756             automan.dropShellPermissionIdentity();
3757         }
3758 
3759         // A queue to receive capability changed
3760         LinkedBlockingQueue<Integer> availabilityChanged = new LinkedBlockingQueue<>();
3761         ImsRcsManager.OnAvailabilityChangedListener callback =
3762                 new ImsRcsManager.OnAvailabilityChangedListener() {
3763             @Override
3764             public void onAvailabilityChanged(
3765                     @RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
3766                 availabilityChanged.offer(capabilities);
3767             }
3768         };
3769 
3770         // Latch will count down here (we callback on the state during registration).
3771         try {
3772             automan.adoptShellPermissionIdentity();
3773             imsRcsManager.addOnAvailabilityChangedListener(
3774                     getContext().getMainExecutor(), callback);
3775         } finally {
3776             automan.dropShellPermissionIdentity();
3777         }
3778 
3779         // Verify the callback and the api isAvailable that the capabilities is NONE in the
3780         // beginning.
3781         int radioTechLTE = IMS_REGI_TECH_LTE;
3782         int capCb = waitForResult(availabilityChanged);
3783         assertEquals(capCb, RCS_CAP_NONE);
3784         availabilityChanged.clear();
3785         try {
3786             automan.adoptShellPermissionIdentity();
3787             assertFalse(imsRcsManager.isAvailable(RCS_CAP_OPTIONS, radioTechLTE));
3788             assertFalse(imsRcsManager.isAvailable(RCS_CAP_PRESENCE, radioTechLTE));
3789         } finally {
3790             automan.dropShellPermissionIdentity();
3791         }
3792 
3793         // Notify capabilities status change to OPTIONS
3794         RcsImsCapabilities optionsCap = new RcsImsCapabilities(RCS_CAP_OPTIONS);
3795         sServiceConnector.getCarrierService().getRcsFeature()
3796                 .notifyCapabilitiesStatusChanged(optionsCap);
3797 
3798         // Verify that the callback onAvailabilityChanged is called with OPTIONS
3799         capCb = waitForResult(availabilityChanged);
3800         assertEquals(capCb, RCS_CAP_OPTIONS);
3801         availabilityChanged.clear();
3802         try {
3803             automan.adoptShellPermissionIdentity();
3804             assertTrue(imsRcsManager.isAvailable(RCS_CAP_OPTIONS, radioTechLTE));
3805         } finally {
3806             automan.dropShellPermissionIdentity();
3807         }
3808 
3809         // Notify capabilities status change to PRESENCE
3810         RcsImsCapabilities presenceCap = new RcsImsCapabilities(RCS_CAP_PRESENCE);
3811         sServiceConnector.getCarrierService().getRcsFeature()
3812                 .notifyCapabilitiesStatusChanged(presenceCap);
3813 
3814         // Verify that the callback onAvailabilityChanged is called with PRESENCE
3815         capCb = waitForResult(availabilityChanged);
3816         assertEquals(capCb, RCS_CAP_PRESENCE);
3817         availabilityChanged.clear();
3818         try {
3819             automan.adoptShellPermissionIdentity();
3820             assertTrue(imsRcsManager.isAvailable(RCS_CAP_PRESENCE, radioTechLTE));
3821         } finally {
3822             automan.dropShellPermissionIdentity();
3823         }
3824 
3825         // Remove availability changed listener
3826         try {
3827             automan.adoptShellPermissionIdentity();
3828             imsRcsManager.removeOnAvailabilityChangedListener(callback);
3829         } finally {
3830             automan.dropShellPermissionIdentity();
3831         }
3832 
3833         // Notify capabilities status changes again.
3834         sServiceConnector.getCarrierService().getRcsFeature()
3835                 .notifyCapabilitiesStatusChanged(optionsCap);
3836 
3837         // The callback should not be called because the listener is removed.
3838         assertTrue(availabilityChanged.isEmpty());
3839 
3840         overrideCarrierConfig(null);
3841     }
3842 
3843     @Test
testProvisioningManagerSetConfig()3844     public void testProvisioningManagerSetConfig() throws Exception {
3845         if (!ImsUtils.shouldTestImsService()) {
3846             return;
3847         }
3848 
3849         triggerFrameworkConnectToCarrierImsService();
3850 
3851         ProvisioningManager provisioningManager =
3852                 ProvisioningManager.createForSubscriptionId(sTestSub);
3853 
3854         // This is a little bit gross looking, but on P devices, I can not define classes that
3855         // extend ProvisioningManager.Callback (because it doesn't exist), so this has to
3856         // happen as an anon class here.
3857         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
3858         LinkedBlockingQueue<Pair<Integer, String>> mStringQueue = new LinkedBlockingQueue<>();
3859         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
3860             @Override
3861             public void onProvisioningIntChanged(int item, int value) {
3862                 mIntQueue.offer(new Pair<>(item, value));
3863             }
3864 
3865             @Override
3866             public void onProvisioningStringChanged(int item, String value) {
3867                 mStringQueue.offer(new Pair<>(item, value));
3868             }
3869         };
3870 
3871         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3872         try {
3873             automan.adoptShellPermissionIdentity();
3874             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
3875                     callback);
3876 
3877             provisioningManager.setProvisioningIntValue(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_INT);
3878             assertTrue(waitForParam(mIntQueue, new Pair<>(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_INT)));
3879             assertEquals(TEST_CONFIG_VALUE_INT,
3880                     provisioningManager.getProvisioningIntValue(TEST_CONFIG_KEY));
3881 
3882             provisioningManager.setProvisioningStringValue(TEST_CONFIG_KEY,
3883                     TEST_CONFIG_VALUE_STRING);
3884             assertTrue(waitForParam(mStringQueue,
3885                     new Pair<>(TEST_CONFIG_KEY, TEST_CONFIG_VALUE_STRING)));
3886             assertEquals(TEST_CONFIG_VALUE_STRING,
3887                     provisioningManager.getProvisioningStringValue(TEST_CONFIG_KEY));
3888 
3889             automan.adoptShellPermissionIdentity();
3890             provisioningManager.unregisterProvisioningChangedCallback(callback);
3891         } finally {
3892             automan.dropShellPermissionIdentity();
3893         }
3894     }
3895 
3896     @Test
testProvisioningManagerWhenMmtelProvisionIsRequired()3897     public void testProvisioningManagerWhenMmtelProvisionIsRequired() throws Exception {
3898         if (!ImsUtils.shouldTestImsService()) {
3899             return;
3900         }
3901 
3902         // test in case provision for mmtel is required
3903         PersistableBundle bundle = new PersistableBundle();
3904 
3905         PersistableBundle innerBundle = new PersistableBundle();
3906         innerBundle.putIntArray(
3907                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY,
3908                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN}
3909         );
3910         innerBundle.putIntArray(
3911                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY,
3912                 new int[]{IMS_REGI_TECH_LTE}
3913         );
3914 
3915         bundle.putPersistableBundle(
3916                 CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE,
3917                 innerBundle);
3918 
3919         overrideCarrierConfig(bundle);
3920 
3921         triggerFrameworkConnectToCarrierImsService();
3922         ProvisioningManager provisioningManager =
3923                 ProvisioningManager.createForSubscriptionId(sTestSub);
3924 
3925         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
3926         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnFeatureChangedQueue =
3927                 new LinkedBlockingQueue<>();
3928 
3929         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
3930             @Override
3931             public void onProvisioningIntChanged(int item, int value) {
3932                 mIntQueue.offer(new Pair<>(item, value));
3933             }
3934         };
3935 
3936         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
3937                 new ProvisioningManager.FeatureProvisioningCallback() {
3938             @Override
3939             public void onFeatureProvisioningChanged(
3940                     @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
3941                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
3942                     boolean isProvisioned) {
3943                 mOnFeatureChangedQueue.offer(new Pair<>(capability,
3944                         new Pair<>(tech, isProvisioned)));
3945             }
3946 
3947             @Override
3948             public void onRcsFeatureProvisioningChanged(
3949                     @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
3950                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
3951                     boolean isProvisioned){
3952             }
3953         };
3954 
3955         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
3956         try {
3957             automan.adoptShellPermissionIdentity();
3958             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
3959                     callback);
3960             provisioningManager.registerFeatureProvisioningChangedCallback(
3961                     getContext().getMainExecutor(), featureProvisioningCallback);
3962 
3963             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
3964                     TelephonyUtils.CTS_APP_PACKAGE,
3965                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
3966 
3967             // Clear Q before testing
3968             // When Callback registered the initial provisioning value can be notified.
3969             mIntQueue.clear();
3970             mOnFeatureChangedQueue.clear();
3971 
3972             // test get/setProvisioningStatusForCapability for VoLTE
3973             assertTrue(provisioningManager.isProvisioningRequiredForCapability(
3974                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
3975             boolean isProvisioned = provisioningManager
3976                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE);
3977             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
3978                     IMS_REGI_TECH_LTE, !isProvisioned);
3979             assertTrue(waitForParam(mOnFeatureChangedQueue,
3980                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_LTE, !isProvisioned))));
3981             assertTrue(waitForParam(mIntQueue,
3982                     new Pair<>(KEY_VOLTE_PROVISIONING_STATUS, !isProvisioned ? 1 : 0)));
3983             assertEquals(!isProvisioned, provisioningManager
3984                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
3985             mIntQueue.clear();
3986             mOnFeatureChangedQueue.clear();
3987             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
3988                     IMS_REGI_TECH_LTE, isProvisioned);
3989             assertTrue(waitForParam(mOnFeatureChangedQueue,
3990                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_LTE, isProvisioned))));
3991             assertTrue(waitForParam(mIntQueue,
3992                     new Pair<>(KEY_VOLTE_PROVISIONING_STATUS, isProvisioned ? 1 : 0)));
3993             assertEquals(isProvisioned, provisioningManager
3994                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
3995 
3996             // test get/setProvisioningStatusForCapability for VoWIFI
3997             assertTrue(provisioningManager.isProvisioningRequiredForCapability(
3998                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
3999             isProvisioned = provisioningManager
4000                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN);
4001             mIntQueue.clear();
4002             mOnFeatureChangedQueue.clear();
4003             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4004                     IMS_REGI_TECH_IWLAN, !isProvisioned);
4005             assertTrue(waitForParam(mOnFeatureChangedQueue,
4006                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_IWLAN, !isProvisioned))));
4007             assertTrue(waitForParam(mIntQueue,
4008                     new Pair<>(KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, !isProvisioned ? 1 : 0)));
4009             assertEquals(!isProvisioned, provisioningManager
4010                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4011             mIntQueue.clear();
4012             mOnFeatureChangedQueue.clear();
4013             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4014                     IMS_REGI_TECH_IWLAN, isProvisioned);
4015             assertTrue(waitForParam(mOnFeatureChangedQueue,
4016                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_IWLAN, isProvisioned))));
4017             assertTrue(waitForParam(mIntQueue,
4018                     new Pair<>(KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, isProvisioned ? 1 : 0)));
4019             assertEquals(isProvisioned, provisioningManager
4020                     .getProvisioningStatusForCapability(MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4021 
4022             // test get/setProvisioningStatusForCapability for VT
4023             assertTrue(provisioningManager.isProvisioningRequiredForCapability(
4024                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4025             isProvisioned = provisioningManager
4026                     .getProvisioningStatusForCapability(MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE);
4027             mIntQueue.clear();
4028             mOnFeatureChangedQueue.clear();
4029             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VIDEO,
4030                     IMS_REGI_TECH_LTE, !isProvisioned);
4031             assertTrue(waitForParam(mOnFeatureChangedQueue,
4032                     new Pair<>(MMTEL_CAP_VIDEO, new Pair<>(IMS_REGI_TECH_LTE, !isProvisioned))));
4033             assertTrue(waitForParam(mIntQueue,
4034                     new Pair<>(KEY_VT_PROVISIONING_STATUS, !isProvisioned ? 1 : 0)));
4035             assertEquals(!isProvisioned, provisioningManager
4036                     .getProvisioningStatusForCapability(MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4037             mIntQueue.clear();
4038             mOnFeatureChangedQueue.clear();
4039             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VIDEO,
4040                     IMS_REGI_TECH_LTE, isProvisioned);
4041             assertTrue(waitForParam(mOnFeatureChangedQueue,
4042                     new Pair<>(MMTEL_CAP_VIDEO, new Pair<>(IMS_REGI_TECH_LTE, isProvisioned))));
4043             assertTrue(waitForParam(mIntQueue,
4044                     new Pair<>(KEY_VT_PROVISIONING_STATUS, isProvisioned ? 1 : 0)));
4045             assertEquals(isProvisioned, provisioningManager
4046                     .getProvisioningStatusForCapability(MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4047 
4048             TelephonyUtils.disableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4049                     TelephonyUtils.CTS_APP_PACKAGE,
4050                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4051 
4052             // test get/setProvisioningStatusForCapability with lower bounding parameters
4053             // when callback is not supported
4054 
4055             isProvisioned = provisioningManager.getProvisioningStatusForCapability(
4056                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE);
4057             mIntQueue.clear();
4058             mOnFeatureChangedQueue.clear();
4059             provisioningManager.setProvisioningStatusForCapability(
4060                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE, !isProvisioned);
4061             assertTrue(waitForParam(mIntQueue,
4062                     new Pair<>(KEY_VOLTE_PROVISIONING_STATUS, !isProvisioned ? 1 : 0)));
4063             assertEquals(!isProvisioned,
4064                     provisioningManager.getProvisioningStatusForCapability(
4065                             MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
4066             isProvisioned = provisioningManager.getProvisioningStatusForCapability(
4067                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN);
4068             mIntQueue.clear();
4069             mOnFeatureChangedQueue.clear();
4070             provisioningManager.setProvisioningStatusForCapability(
4071                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN, !isProvisioned);
4072             assertTrue(waitForParam(mIntQueue,
4073                     new Pair<>(KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, !isProvisioned ? 1 : 0)));
4074             assertEquals(!isProvisioned,
4075                     provisioningManager.getProvisioningStatusForCapability(
4076                             MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4077 
4078             isProvisioned = provisioningManager.getProvisioningStatusForCapability(
4079                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE);
4080             mIntQueue.clear();
4081             mOnFeatureChangedQueue.clear();
4082             provisioningManager.setProvisioningStatusForCapability(
4083                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE, !isProvisioned);
4084             assertTrue(waitForParam(mIntQueue,
4085                     new Pair<>(KEY_VT_PROVISIONING_STATUS, !isProvisioned ? 1 : 0)));
4086             assertEquals(!isProvisioned,
4087                     provisioningManager.getProvisioningStatusForCapability(
4088                             MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4089 
4090             automan.adoptShellPermissionIdentity();
4091             provisioningManager.unregisterProvisioningChangedCallback(callback);
4092             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4093                     featureProvisioningCallback);
4094         } finally {
4095             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4096                     TelephonyUtils.CTS_APP_PACKAGE,
4097                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4098             automan.dropShellPermissionIdentity();
4099         }
4100 
4101         overrideCarrierConfig(null);
4102     }
4103 
4104     @Test
testProvisioningManagerWhenMmtelProvisionIsNotRequired()4105     public void testProvisioningManagerWhenMmtelProvisionIsNotRequired() throws Exception {
4106         if (!ImsUtils.shouldTestImsService()) {
4107             return;
4108         }
4109 
4110         // test in case provision for mmtel is required
4111         PersistableBundle bundle = new PersistableBundle();
4112         PersistableBundle innerBundle = new PersistableBundle();
4113 
4114         bundle.putPersistableBundle(
4115                 CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE,
4116                 innerBundle);
4117         bundle.putBoolean(
4118                 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4119         overrideCarrierConfig(bundle);
4120 
4121         triggerFrameworkConnectToCarrierImsService();
4122         ProvisioningManager provisioningManager =
4123                 ProvisioningManager.createForSubscriptionId(sTestSub);
4124 
4125         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
4126         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnFeatureChangedQueue =
4127                 new LinkedBlockingQueue<>();
4128 
4129 
4130         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {};
4131 
4132         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4133                 new ProvisioningManager.FeatureProvisioningCallback() {
4134             @Override
4135             public void onFeatureProvisioningChanged(
4136                     @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4137                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4138                     boolean isProvisioned) {
4139             }
4140 
4141             @Override
4142             public void onRcsFeatureProvisioningChanged(
4143                     @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4144                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4145                     boolean isProvisioned){
4146             }
4147         };
4148 
4149         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4150         try {
4151             automan.adoptShellPermissionIdentity();
4152             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
4153                     callback);
4154             provisioningManager.registerFeatureProvisioningChangedCallback(
4155                     getContext().getMainExecutor(), featureProvisioningCallback);
4156 
4157             // In case provisioning is not required
4158             // true will be returned regardless of stored value
4159             // ignore set value whatever value is set by app
4160             // therefore set different value from current then check if the value has changed
4161             // test get/setProvisioningStatusForCapability for VoLTE
4162 
4163             // isProvisioningRequiredForCapability should return false because provision is not
4164             // required
4165             assertTrue(!provisioningManager.isProvisioningRequiredForCapability(
4166                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
4167             // However, getProvisioningStatusForCapability() should return true because it does not
4168             // require provision
4169             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4170                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
4171             // put opposite value to check if the key is changed or not
4172             provisioningManager.setProvisioningStatusForCapability(
4173                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE, false);
4174             // key value should not be changed whatever value is set
4175             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4176                     MMTEL_CAP_VOICE, IMS_REGI_TECH_LTE));
4177 
4178             // test case for VoWIFI
4179             assertTrue(!provisioningManager.isProvisioningRequiredForCapability(
4180                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4181             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4182                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4183             provisioningManager.setProvisioningStatusForCapability(
4184                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN, false);
4185             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4186                     MMTEL_CAP_VOICE, IMS_REGI_TECH_IWLAN));
4187 
4188             // test case for VT
4189             assertTrue(!provisioningManager.isProvisioningRequiredForCapability(
4190                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4191             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4192                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4193             provisioningManager.setProvisioningStatusForCapability(
4194                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE, false);
4195             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4196                     MMTEL_CAP_VIDEO, IMS_REGI_TECH_LTE));
4197 
4198             automan.adoptShellPermissionIdentity();
4199             provisioningManager.unregisterProvisioningChangedCallback(callback);
4200             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4201                     featureProvisioningCallback);
4202         } finally {
4203             automan.dropShellPermissionIdentity();
4204         }
4205 
4206         overrideCarrierConfig(null);
4207     }
4208 
4209     @Test
4210     @RequiresFlagsEnabled(Flags.FLAG_NOTIFY_INITIAL_IMS_PROVISIONING_STATUS)
testInitialNotificationForMmTelWhenCallbackRegistered()4211     public void testInitialNotificationForMmTelWhenCallbackRegistered() throws Exception {
4212         if (!ImsUtils.shouldTestImsService()) {
4213             return;
4214         }
4215 
4216         // Change carrier config as MmTel provisioning required
4217         PersistableBundle bundle = new PersistableBundle();
4218         PersistableBundle innerBundle = new PersistableBundle();
4219         innerBundle.putIntArray(
4220                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY,
4221                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_NR}
4222         );
4223         innerBundle.putIntArray(
4224                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY,
4225                 new int[]{IMS_REGI_TECH_LTE}
4226         );
4227         bundle.putPersistableBundle(
4228                 CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE,
4229                 innerBundle);
4230         overrideCarrierConfig(bundle);
4231 
4232         ProvisioningManager provisioningManager =
4233                 ProvisioningManager.createForSubscriptionId(sTestSub);
4234 
4235         // Create Q to check whether callback is called or not
4236         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnFeatureChangedQueue =
4237                 new LinkedBlockingQueue<>();
4238         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4239                 new ProvisioningManager.FeatureProvisioningCallback() {
4240                     @Override
4241                     public void onFeatureProvisioningChanged(
4242                             @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4243                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4244                             boolean isProvisioned) {
4245                         mOnFeatureChangedQueue.offer(new Pair<>(capability,
4246                                 new Pair<>(tech, isProvisioned)));
4247                     }
4248 
4249                     @Override
4250                     public void onRcsFeatureProvisioningChanged(
4251                             @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4252                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4253                             boolean isProvisioned){
4254                     }
4255                 };
4256 
4257         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4258         try {
4259             automan.adoptShellPermissionIdentity();
4260 
4261             // Set provisioning before registering callback
4262             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4263                     IMS_REGI_TECH_LTE, true);
4264             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4265                     IMS_REGI_TECH_IWLAN, true);
4266             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4267                     IMS_REGI_TECH_NR, false);
4268             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VIDEO,
4269                     IMS_REGI_TECH_LTE, true);
4270 
4271             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4272                     TelephonyUtils.CTS_APP_PACKAGE,
4273                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4274 
4275             // Register callback
4276             provisioningManager.registerFeatureProvisioningChangedCallback(
4277                     getContext().getMainExecutor(), featureProvisioningCallback);
4278 
4279             // Verify notification initial provisioning status when the callback registered
4280             // Voice(3) - LTE, IWLAN, NR
4281             assertTrue(waitForParam(mOnFeatureChangedQueue,
4282                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_LTE, true))));
4283             assertTrue(waitForParam(mOnFeatureChangedQueue,
4284                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_IWLAN, true))));
4285             assertTrue(waitForParam(mOnFeatureChangedQueue,
4286                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_NR, false))));
4287             // Video(1) - LTE
4288             assertTrue(waitForParam(mOnFeatureChangedQueue,
4289                     new Pair<>(MMTEL_CAP_VIDEO, new Pair<>(IMS_REGI_TECH_LTE, true))));
4290 
4291             mOnFeatureChangedQueue.clear();
4292             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4293                     featureProvisioningCallback);
4294         } finally {
4295             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4296                     TelephonyUtils.CTS_APP_PACKAGE,
4297                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4298             automan.dropShellPermissionIdentity();
4299         }
4300 
4301         overrideCarrierConfig(null);
4302     }
4303 
4304     @Test
4305     @RequiresFlagsEnabled(Flags.FLAG_NOTIFY_INITIAL_IMS_PROVISIONING_STATUS)
testInitialNotificationForMmTelWhenImsServiceConnected()4306     public void testInitialNotificationForMmTelWhenImsServiceConnected() throws Exception {
4307         if (!ImsUtils.shouldTestImsService()) {
4308             return;
4309         }
4310 
4311         // Change carrier config as MmTel provisioning required
4312         PersistableBundle bundle = new PersistableBundle();
4313         PersistableBundle innerBundle = new PersistableBundle();
4314         innerBundle.putIntArray(
4315                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY,
4316                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_NR}
4317         );
4318         innerBundle.putIntArray(
4319                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY,
4320                 new int[]{IMS_REGI_TECH_LTE}
4321         );
4322         bundle.putPersistableBundle(
4323                 CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE,
4324                 innerBundle);
4325         overrideCarrierConfig(bundle);
4326 
4327         ProvisioningManager provisioningManager =
4328                 ProvisioningManager.createForSubscriptionId(sTestSub);
4329 
4330         // Create Q to check whether callback is called or not
4331         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnFeatureChangedQueue =
4332                 new LinkedBlockingQueue<>();
4333         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4334                 new ProvisioningManager.FeatureProvisioningCallback() {
4335                     @Override
4336                     public void onFeatureProvisioningChanged(
4337                             @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4338                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4339                             boolean isProvisioned) {
4340                         mOnFeatureChangedQueue.offer(new Pair<>(capability,
4341                                 new Pair<>(tech, isProvisioned)));
4342                     }
4343 
4344                     @Override
4345                     public void onRcsFeatureProvisioningChanged(
4346                             @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4347                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4348                             boolean isProvisioned){
4349                     }
4350                 };
4351 
4352         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4353         try {
4354             automan.adoptShellPermissionIdentity();
4355 
4356             // Set provisioning before registering callback
4357             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4358                     IMS_REGI_TECH_LTE, true);
4359             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4360                     IMS_REGI_TECH_IWLAN, true);
4361             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VOICE,
4362                     IMS_REGI_TECH_NR, false);
4363             provisioningManager.setProvisioningStatusForCapability(MMTEL_CAP_VIDEO,
4364                     IMS_REGI_TECH_LTE, true);
4365 
4366             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4367                     TelephonyUtils.CTS_APP_PACKAGE,
4368                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4369 
4370             // Register callback
4371             provisioningManager.registerFeatureProvisioningChangedCallback(
4372                     getContext().getMainExecutor(), featureProvisioningCallback);
4373             // Wait until callback is received
4374             assertTrue(waitForParam(mOnFeatureChangedQueue,
4375                     new Pair<>(MMTEL_CAP_VIDEO, new Pair<>(IMS_REGI_TECH_LTE, true))));
4376             // Clear Q : delete provisioning value received when registering callback
4377             mOnFeatureChangedQueue.clear();
4378 
4379             // Connect ImsService
4380             triggerFrameworkConnectToCarrierImsService();
4381 
4382             // Verify notification initial provisioning status when ImsService connected
4383             // Voice(3) - LTE, IWLAN, NR
4384             assertTrue(waitForParam(mOnFeatureChangedQueue,
4385                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_LTE, true))));
4386             assertTrue(waitForParam(mOnFeatureChangedQueue,
4387                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_IWLAN, true))));
4388             assertTrue(waitForParam(mOnFeatureChangedQueue,
4389                     new Pair<>(MMTEL_CAP_VOICE, new Pair<>(IMS_REGI_TECH_NR, false))));
4390             // Video(1) - LTE
4391             assertTrue(waitForParam(mOnFeatureChangedQueue,
4392                     new Pair<>(MMTEL_CAP_VIDEO, new Pair<>(IMS_REGI_TECH_LTE, true))));
4393 
4394             mOnFeatureChangedQueue.clear();
4395             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4396                     featureProvisioningCallback);
4397         } finally {
4398             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4399                     TelephonyUtils.CTS_APP_PACKAGE,
4400                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4401             automan.dropShellPermissionIdentity();
4402         }
4403 
4404         overrideCarrierConfig(null);
4405     }
4406 
4407     @Test
testProvisioningManagerWhenRcsProvisionIsRequired()4408     public void testProvisioningManagerWhenRcsProvisionIsRequired() throws Exception {
4409         if (!ImsUtils.shouldTestImsSingleRegistration()) {
4410             return;
4411         }
4412 
4413         PersistableBundle bundle = new PersistableBundle();
4414         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
4415                 true);
4416 
4417         PersistableBundle innerBundle = new PersistableBundle();
4418         innerBundle.putIntArray(
4419                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY,
4420                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_CROSS_SIM,
4421                         IMS_REGI_TECH_NR}
4422         );
4423         bundle.putPersistableBundle(
4424                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
4425                 innerBundle);
4426 
4427         overrideCarrierConfig(bundle);
4428 
4429         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
4430 
4431         ProvisioningManager provisioningManager =
4432                 ProvisioningManager.createForSubscriptionId(sTestSub);
4433 
4434         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
4435         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnRcsFeatureChangedQueue =
4436                 new LinkedBlockingQueue<>();
4437 
4438         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
4439             @Override
4440             public void onProvisioningIntChanged(int item, int value) {
4441                 mIntQueue.offer(new Pair<>(item, value));
4442             }
4443 
4444         };
4445 
4446         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4447                 new ProvisioningManager.FeatureProvisioningCallback() {
4448             @Override
4449             public void onFeatureProvisioningChanged(
4450                     @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4451                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4452                     boolean isProvisioned) {
4453             }
4454 
4455             @Override
4456             public void onRcsFeatureProvisioningChanged(
4457                     @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4458                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4459                     boolean isProvisioned) {
4460                 mOnRcsFeatureChangedQueue.offer(
4461                         new Pair<>(capability, new Pair<>(tech, isProvisioned)));
4462             }
4463         };
4464 
4465         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4466         try {
4467             automan.adoptShellPermissionIdentity();
4468             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
4469                     callback);
4470             provisioningManager.registerFeatureProvisioningChangedCallback(
4471                     getContext().getMainExecutor(), featureProvisioningCallback);
4472 
4473             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4474                     TelephonyUtils.CTS_APP_PACKAGE,
4475                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4476 
4477             assertTrue(provisioningManager.isRcsProvisioningRequiredForCapability(
4478                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE));
4479             assertTrue(provisioningManager.isRcsProvisioningRequiredForCapability(
4480                     RCS_CAP_PRESENCE, IMS_REGI_TECH_IWLAN));
4481             assertTrue(provisioningManager.isRcsProvisioningRequiredForCapability(
4482                     RCS_CAP_PRESENCE, IMS_REGI_TECH_CROSS_SIM));
4483             assertTrue(provisioningManager.isRcsProvisioningRequiredForCapability(
4484                     RCS_CAP_PRESENCE, IMS_REGI_TECH_NR));
4485 
4486             // Clear Q before testing
4487             // When Callback registered the initial provisioning value can be notified.
4488             mIntQueue.clear();
4489             mOnRcsFeatureChangedQueue.clear();
4490 
4491             // test get/setRcsProvisioningStatusForCapability for PRESENCE over LTE
4492             boolean isProvisioned = provisioningManager.getRcsProvisioningStatusForCapability(
4493                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE);
4494             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4495                     IMS_REGI_TECH_LTE, !isProvisioned);
4496             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4497                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_LTE, !isProvisioned))));
4498             assertTrue(waitForParam(mIntQueue,
4499                     new Pair<>(KEY_EAB_PROVISIONING_STATUS, !isProvisioned ? 1 : 0)));
4500 
4501             // Wait until framework finishes running
4502             Thread.sleep(TEST_OPERATION_TIME_MS);
4503             // Clear Q before running other test
4504             mIntQueue.clear();
4505             mOnRcsFeatureChangedQueue.clear();
4506 
4507             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4508                     IMS_REGI_TECH_LTE, isProvisioned);
4509             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4510                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_LTE, isProvisioned))));
4511             assertTrue(waitForParam(mIntQueue,
4512                     new Pair<>(KEY_EAB_PROVISIONING_STATUS, isProvisioned ? 1 : 0)));
4513 
4514             // TODO : work for OPTIONS case
4515 
4516             automan.adoptShellPermissionIdentity();
4517             provisioningManager.unregisterProvisioningChangedCallback(callback);
4518             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4519                     featureProvisioningCallback);
4520         } finally {
4521             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4522                     TelephonyUtils.CTS_APP_PACKAGE,
4523                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4524 
4525             automan.dropShellPermissionIdentity();
4526         }
4527 
4528         overrideCarrierConfig(null);
4529 
4530     }
4531 
4532     @Test
testProvisioningManagerWhenRcsProvisionIsNotRequired()4533     public void testProvisioningManagerWhenRcsProvisionIsNotRequired() throws Exception {
4534         if (!ImsUtils.shouldTestImsSingleRegistration()) {
4535             return;
4536         }
4537 
4538         PersistableBundle bundle = new PersistableBundle();
4539         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
4540                 true);
4541 
4542         PersistableBundle innerBundle = new PersistableBundle();
4543         bundle.putPersistableBundle(
4544                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
4545                 innerBundle);
4546         bundle.putBoolean(
4547                 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4548         bundle.putBoolean(
4549                 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4550         overrideCarrierConfig(bundle);
4551 
4552         triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
4553 
4554         ProvisioningManager provisioningManager =
4555                 ProvisioningManager.createForSubscriptionId(sTestSub);
4556         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {};
4557         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4558                 new ProvisioningManager.FeatureProvisioningCallback() {
4559             @Override
4560             public void onFeatureProvisioningChanged(
4561                     @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4562                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4563                     boolean isProvisioned) {
4564             }
4565 
4566             @Override
4567             public void onRcsFeatureProvisioningChanged(
4568                     @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4569                     @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4570                     boolean isProvisioned){
4571             }
4572         };
4573 
4574         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4575         try {
4576             automan.adoptShellPermissionIdentity();
4577             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
4578                     callback);
4579             provisioningManager.registerFeatureProvisioningChangedCallback(
4580                     getContext().getMainExecutor(), featureProvisioningCallback);
4581 
4582             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4583                     TelephonyUtils.CTS_APP_PACKAGE,
4584                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4585 
4586             assertTrue(!provisioningManager.isRcsProvisioningRequiredForCapability(
4587                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE));
4588             assertTrue(!provisioningManager.isRcsProvisioningRequiredForCapability(
4589                     RCS_CAP_PRESENCE, IMS_REGI_TECH_IWLAN));
4590             assertTrue(!provisioningManager.isRcsProvisioningRequiredForCapability(
4591                     RCS_CAP_PRESENCE, IMS_REGI_TECH_CROSS_SIM));
4592             assertTrue(!provisioningManager.isRcsProvisioningRequiredForCapability(
4593                     RCS_CAP_PRESENCE, IMS_REGI_TECH_NR));
4594 
4595             // However, getProvisioningStatusForCapability() should return true because it does not
4596             // require provision
4597             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4598                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE));
4599             // put opposite value to check if the key is changed or not
4600             provisioningManager.setProvisioningStatusForCapability(
4601                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE, false);
4602             // key value should not be changed whatever value is set
4603             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4604                     RCS_CAP_PRESENCE, IMS_REGI_TECH_LTE));
4605 
4606             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4607                     RCS_CAP_PRESENCE, IMS_REGI_TECH_IWLAN));
4608             provisioningManager.setProvisioningStatusForCapability(
4609                     RCS_CAP_PRESENCE, IMS_REGI_TECH_IWLAN, false);
4610             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4611                     RCS_CAP_PRESENCE, IMS_REGI_TECH_IWLAN));
4612 
4613             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4614                     RCS_CAP_PRESENCE, IMS_REGI_TECH_CROSS_SIM));
4615             provisioningManager.setProvisioningStatusForCapability(
4616                     RCS_CAP_PRESENCE, IMS_REGI_TECH_CROSS_SIM, false);
4617             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4618                     RCS_CAP_PRESENCE, IMS_REGI_TECH_CROSS_SIM));
4619 
4620             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4621                     RCS_CAP_PRESENCE, IMS_REGI_TECH_NR));
4622             provisioningManager.setProvisioningStatusForCapability(
4623                     RCS_CAP_PRESENCE, IMS_REGI_TECH_NR, false);
4624             assertTrue(provisioningManager.getProvisioningStatusForCapability(
4625                     RCS_CAP_PRESENCE, IMS_REGI_TECH_NR));
4626 
4627             // TODO : work for OPTIONS case
4628 
4629             automan.adoptShellPermissionIdentity();
4630             provisioningManager.unregisterProvisioningChangedCallback(callback);
4631             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4632                     featureProvisioningCallback);
4633         } finally {
4634             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4635                     TelephonyUtils.CTS_APP_PACKAGE,
4636                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4637 
4638             automan.dropShellPermissionIdentity();
4639         }
4640 
4641         overrideCarrierConfig(null);
4642     }
4643 
4644     @Test
4645     @RequiresFlagsEnabled(Flags.FLAG_NOTIFY_INITIAL_IMS_PROVISIONING_STATUS)
testInitialNotificationForRcsWhenCallbackRegistered()4646     public void testInitialNotificationForRcsWhenCallbackRegistered() throws Exception {
4647         if (!ImsUtils.shouldTestImsSingleRegistration()) {
4648             return;
4649         }
4650 
4651         // Change carrier config as Rcs provisioning required
4652         PersistableBundle bundle = new PersistableBundle();
4653         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
4654                 true);
4655         PersistableBundle innerBundle = new PersistableBundle();
4656         innerBundle.putIntArray(
4657                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY,
4658                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_CROSS_SIM,
4659                         IMS_REGI_TECH_NR}
4660         );
4661         bundle.putPersistableBundle(
4662                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
4663                 innerBundle);
4664         overrideCarrierConfig(bundle);
4665 
4666         ProvisioningManager provisioningManager =
4667                 ProvisioningManager.createForSubscriptionId(sTestSub);
4668 
4669         // Create Q to check whether callback is called or not
4670         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnRcsFeatureChangedQueue =
4671                 new LinkedBlockingQueue<>();
4672         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4673                 new ProvisioningManager.FeatureProvisioningCallback() {
4674                     @Override
4675                     public void onFeatureProvisioningChanged(
4676                             @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4677                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4678                             boolean isProvisioned) {
4679                     }
4680 
4681                     @Override
4682                     public void onRcsFeatureProvisioningChanged(
4683                             @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4684                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4685                             boolean isProvisioned) {
4686                         mOnRcsFeatureChangedQueue.offer(new Pair<>(capability,
4687                                 new Pair<>(tech, isProvisioned)));
4688                     }
4689                 };
4690 
4691         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4692         try {
4693             automan.adoptShellPermissionIdentity();
4694 
4695             // Set provisioning before registering callback
4696             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4697                     IMS_REGI_TECH_LTE, true);
4698             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4699                     IMS_REGI_TECH_IWLAN, true);
4700             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4701                     IMS_REGI_TECH_CROSS_SIM, false);
4702             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4703                     IMS_REGI_TECH_NR, true);
4704 
4705             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4706                     TelephonyUtils.CTS_APP_PACKAGE,
4707                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4708 
4709             provisioningManager.registerFeatureProvisioningChangedCallback(
4710                     getContext().getMainExecutor(), featureProvisioningCallback);
4711 
4712             // Verify notification initial provisioning status when the callback registered
4713             // PRESENCE (4) - LTE, IWLAN, CROSS_SIM, NR
4714             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4715                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_LTE, true))));
4716             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4717                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_IWLAN, true))));
4718             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4719                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_CROSS_SIM, false))));
4720             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4721                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_NR, true))));
4722 
4723             mOnRcsFeatureChangedQueue.clear();
4724             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4725                     featureProvisioningCallback);
4726         } finally {
4727             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4728                     TelephonyUtils.CTS_APP_PACKAGE,
4729                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4730 
4731             automan.dropShellPermissionIdentity();
4732         }
4733 
4734         overrideCarrierConfig(null);
4735     }
4736 
4737     @Test
4738     @RequiresFlagsEnabled(Flags.FLAG_NOTIFY_INITIAL_IMS_PROVISIONING_STATUS)
testInitialNotificationForRcsWhenImsServiceConnected()4739     public void testInitialNotificationForRcsWhenImsServiceConnected() throws Exception {
4740         if (!ImsUtils.shouldTestImsSingleRegistration()) {
4741             return;
4742         }
4743 
4744         // Change carrier config as Rcs provisioning required
4745         PersistableBundle bundle = new PersistableBundle();
4746         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
4747                 true);
4748         PersistableBundle innerBundle = new PersistableBundle();
4749         innerBundle.putIntArray(
4750                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY,
4751                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_CROSS_SIM,
4752                         IMS_REGI_TECH_NR}
4753         );
4754         bundle.putPersistableBundle(
4755                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
4756                 innerBundle);
4757         overrideCarrierConfig(bundle);
4758 
4759         ProvisioningManager provisioningManager =
4760                 ProvisioningManager.createForSubscriptionId(sTestSub);
4761 
4762         // Create Q to check whether callback is called or not
4763         LinkedBlockingQueue<Pair<Integer, Pair<Integer, Boolean>>> mOnRcsFeatureChangedQueue =
4764                 new LinkedBlockingQueue<>();
4765         ProvisioningManager.FeatureProvisioningCallback featureProvisioningCallback =
4766                 new ProvisioningManager.FeatureProvisioningCallback() {
4767                     @Override
4768                     public void onFeatureProvisioningChanged(
4769                             @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
4770                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4771                             boolean isProvisioned) {
4772                     }
4773 
4774                     @Override
4775                     public void onRcsFeatureProvisioningChanged(
4776                             @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
4777                             @ImsRegistrationImplBase.ImsRegistrationTech int tech,
4778                             boolean isProvisioned) {
4779                         mOnRcsFeatureChangedQueue.offer(new Pair<>(capability,
4780                                 new Pair<>(tech, isProvisioned)));
4781                     }
4782                 };
4783 
4784         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4785         try {
4786             automan.adoptShellPermissionIdentity();
4787 
4788             // Set provisioning before registering callback
4789             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4790                     IMS_REGI_TECH_LTE, true);
4791             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4792                     IMS_REGI_TECH_IWLAN, true);
4793             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4794                     IMS_REGI_TECH_CROSS_SIM, false);
4795             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
4796                     IMS_REGI_TECH_NR, true);
4797 
4798             TelephonyUtils.enableCompatCommand(InstrumentationRegistry.getInstrumentation(),
4799                     TelephonyUtils.CTS_APP_PACKAGE,
4800                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4801 
4802             // Register callback
4803             provisioningManager.registerFeatureProvisioningChangedCallback(
4804                     getContext().getMainExecutor(), featureProvisioningCallback);
4805 
4806             // Wait until callback is received
4807             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4808                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_NR, true))));
4809             // Clear Q : delete provisioning value received when registering callback
4810             mOnRcsFeatureChangedQueue.clear();
4811 
4812             // Connect ImsService
4813             triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
4814 
4815             // Verify notification initial provisioning status when ImsService connected
4816             // PRESENCE (4) - LTE, IWLAN, CROSS_SIM, NR
4817             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4818                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_LTE, true))));
4819             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4820                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_IWLAN, true))));
4821             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4822                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_CROSS_SIM, false))));
4823             assertTrue(waitForParam(mOnRcsFeatureChangedQueue,
4824                     new Pair<>(RCS_CAP_PRESENCE, new Pair<>(IMS_REGI_TECH_NR, true))));
4825 
4826             mOnRcsFeatureChangedQueue.clear();
4827             provisioningManager.unregisterFeatureProvisioningChangedCallback(
4828                     featureProvisioningCallback);
4829         } finally {
4830             TelephonyUtils.resetCompatCommand(InstrumentationRegistry.getInstrumentation(),
4831                     TelephonyUtils.CTS_APP_PACKAGE,
4832                     SUPPORT_PROVISION_STATUS_FOR_CAPABILITY_STRING);
4833 
4834             automan.dropShellPermissionIdentity();
4835         }
4836 
4837         overrideCarrierConfig(null);
4838     }
4839 
4840     @Ignore("The ProvisioningManager constants were moved back to @hide for now, don't want to "
4841             + "completely remove test.")
4842     @Test
testProvisioningManagerConstants()4843     public void testProvisioningManagerConstants() throws Exception {
4844         if (!ImsUtils.shouldTestImsService()) {
4845             return;
4846         }
4847 
4848         triggerFrameworkConnectToCarrierImsService();
4849 
4850         ProvisioningManager provisioningManager =
4851                 ProvisioningManager.createForSubscriptionId(sTestSub);
4852 
4853         // This is a little bit gross looking, but on P devices, I can not define classes that
4854         // extend ProvisioningManager.Callback (because it doesn't exist), so this has to
4855         // happen as an anon class here.
4856         LinkedBlockingQueue<Pair<Integer, Integer>> mIntQueue = new LinkedBlockingQueue<>();
4857         LinkedBlockingQueue<Pair<Integer, String>> mStringQueue = new LinkedBlockingQueue<>();
4858         ProvisioningManager.Callback callback = new ProvisioningManager.Callback() {
4859             @Override
4860             public void onProvisioningIntChanged(int item, int value) {
4861                 mIntQueue.offer(new Pair<>(item, value));
4862             }
4863 
4864             @Override
4865             public void onProvisioningStringChanged(int item, String value) {
4866                 mStringQueue.offer(new Pair<>(item, value));
4867             }
4868         };
4869 
4870         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
4871         try {
4872             automan.adoptShellPermissionIdentity();
4873             provisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
4874                     callback);
4875 
4876             verifyStringKey(provisioningManager, mStringQueue,
4877                     ProvisioningManager.KEY_AMR_CODEC_MODE_SET_VALUES, "1,2");
4878             verifyStringKey(provisioningManager, mStringQueue,
4879                     ProvisioningManager.KEY_AMR_WB_CODEC_MODE_SET_VALUES, "1,2");
4880             verifyIntKey(provisioningManager, mIntQueue,
4881                     ProvisioningManager.KEY_SIP_SESSION_TIMER_SEC, 5);
4882             verifyIntKey(provisioningManager, mIntQueue,
4883                     ProvisioningManager.KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC, 5);
4884             verifyIntKey(provisioningManager, mIntQueue,
4885                     ProvisioningManager.KEY_SIP_INVITE_CANCELLATION_TIMER_MS, 5);
4886             verifyIntKey(provisioningManager, mIntQueue,
4887                     ProvisioningManager.KEY_TRANSITION_TO_LTE_DELAY_MS, 5);
4888             verifyIntKey(provisioningManager, mIntQueue,
4889                     ProvisioningManager.KEY_ENABLE_SILENT_REDIAL, 0);
4890             verifyIntKey(provisioningManager, mIntQueue,
4891                     ProvisioningManager.KEY_T1_TIMER_VALUE_MS, 500);
4892             verifyIntKey(provisioningManager, mIntQueue,
4893                     ProvisioningManager.KEY_T2_TIMER_VALUE_MS, 500);
4894             verifyIntKey(provisioningManager, mIntQueue,
4895                     ProvisioningManager.KEY_TF_TIMER_VALUE_MS, 500);
4896             verifyIntKey(provisioningManager, mIntQueue,
4897                     ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS, 0);
4898             verifyIntKey(provisioningManager, mIntQueue,
4899                     ProvisioningManager.KEY_VT_PROVISIONING_STATUS, 0);
4900             verifyStringKey(provisioningManager, mStringQueue,
4901                     ProvisioningManager.KEY_REGISTRATION_DOMAIN_NAME, "test.com");
4902             verifyIntKey(provisioningManager, mIntQueue,
4903                     ProvisioningManager.KEY_SMS_FORMAT, ProvisioningManager.SMS_FORMAT_3GPP);
4904             verifyIntKey(provisioningManager, mIntQueue,
4905                     ProvisioningManager.KEY_SMS_FORMAT, ProvisioningManager.SMS_FORMAT_3GPP2);
4906             verifyIntKey(provisioningManager, mIntQueue,
4907                     ProvisioningManager.KEY_SMS_OVER_IP_ENABLED, 0);
4908             verifyIntKey(provisioningManager, mIntQueue,
4909                     ProvisioningManager.KEY_RCS_PUBLISH_TIMER_SEC, 5);
4910             verifyIntKey(provisioningManager, mIntQueue,
4911                     ProvisioningManager.KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC, 5);
4912             verifyIntKey(provisioningManager, mIntQueue,
4913                     ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED, 0);
4914             verifyIntKey(provisioningManager, mIntQueue,
4915                     ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC, 5);
4916             verifyIntKey(provisioningManager, mIntQueue,
4917                     ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC, 5);
4918             verifyIntKey(provisioningManager, mIntQueue,
4919                     ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC, 5);
4920             verifyIntKey(provisioningManager, mIntQueue,
4921                     ProvisioningManager.KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC, 5);
4922             verifyIntKey(provisioningManager, mIntQueue,
4923                     ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS, 1000);
4924             verifyIntKey(provisioningManager, mIntQueue,
4925                     ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL, 50);
4926             verifyIntKey(provisioningManager, mIntQueue,
4927                     ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC, 5);
4928             verifyIntKey(provisioningManager, mIntQueue,
4929                     ProvisioningManager.KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION, 0);
4930             verifyIntKey(provisioningManager, mIntQueue,
4931                     ProvisioningManager.KEY_EAB_PROVISIONING_STATUS, 0);
4932             verifyIntKey(provisioningManager, mIntQueue,
4933                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE, 0);
4934             verifyIntKey(provisioningManager, mIntQueue,
4935                     ProvisioningManager.KEY_VOICE_OVER_WIFI_MODE_OVERRIDE, 0);
4936             verifyIntKey(provisioningManager, mIntQueue,
4937                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, 0);
4938             verifyIntKey(provisioningManager, mIntQueue,
4939                     ProvisioningManager.KEY_MOBILE_DATA_ENABLED, 0);
4940             verifyIntKey(provisioningManager, mIntQueue,
4941                     ProvisioningManager.KEY_VOLTE_USER_OPT_IN_STATUS, 0);
4942             verifyStringKey(provisioningManager, mStringQueue,
4943                     ProvisioningManager.KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS, "local.fun.com");
4944             verifyIntKey(provisioningManager, mIntQueue,
4945                     ProvisioningManager.KEY_SIP_KEEP_ALIVE_ENABLED, 0);
4946             verifyIntKey(provisioningManager, mIntQueue,
4947                     ProvisioningManager.KEY_REGISTRATION_RETRY_BASE_TIME_SEC, 0);
4948             verifyIntKey(provisioningManager, mIntQueue,
4949                     ProvisioningManager.KEY_REGISTRATION_RETRY_MAX_TIME_SEC, 5);
4950             verifyIntKey(provisioningManager, mIntQueue,
4951                     ProvisioningManager.KEY_RTP_SPEECH_START_PORT, 500);
4952             verifyIntKey(provisioningManager, mIntQueue,
4953                     ProvisioningManager.KEY_RTP_SPEECH_END_PORT, 600);
4954             verifyIntKey(provisioningManager, mIntQueue,
4955                     ProvisioningManager.KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS, 500);
4956             verifyIntKey(provisioningManager, mIntQueue,
4957                     ProvisioningManager.KEY_SIP_INVITE_ACK_WAIT_TIME_MS, 500);
4958             verifyIntKey(provisioningManager, mIntQueue,
4959                     ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS, 500);
4960             verifyIntKey(provisioningManager, mIntQueue,
4961                     ProvisioningManager.KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS, 500);
4962             verifyIntKey(provisioningManager, mIntQueue,
4963                     ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS, 500);
4964             verifyIntKey(provisioningManager, mIntQueue,
4965                     ProvisioningManager.KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS, 500);
4966             verifyIntKey(provisioningManager, mIntQueue,
4967                     ProvisioningManager.KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS, 500);
4968             verifyIntKey(provisioningManager, mIntQueue,
4969                     ProvisioningManager.KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS, 500);
4970             verifyIntKey(provisioningManager, mIntQueue,
4971                     ProvisioningManager.KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS,
4972                     500);
4973             verifyIntKey(provisioningManager, mIntQueue,
4974                     ProvisioningManager.KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE, 0);
4975             verifyIntKey(provisioningManager, mIntQueue,
4976                     ProvisioningManager.KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE, 0);
4977             verifyIntKey(provisioningManager, mIntQueue,
4978                     ProvisioningManager.KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE, 0);
4979             verifyIntKey(provisioningManager, mIntQueue,
4980                     ProvisioningManager.KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE, 0);
4981             verifyIntKey(provisioningManager, mIntQueue,
4982                     ProvisioningManager.KEY_DTMF_WB_PAYLOAD_TYPE, 0);
4983             verifyIntKey(provisioningManager, mIntQueue,
4984                     ProvisioningManager.KEY_DTMF_NB_PAYLOAD_TYPE, 0);
4985             verifyIntKey(provisioningManager, mIntQueue,
4986                     ProvisioningManager.KEY_AMR_DEFAULT_ENCODING_MODE, 0);
4987             verifyIntKey(provisioningManager, mIntQueue,
4988                     ProvisioningManager.KEY_SMS_PUBLIC_SERVICE_IDENTITY, 0);
4989             verifyStringKey(provisioningManager, mStringQueue,
4990                     ProvisioningManager.KEY_SMS_PUBLIC_SERVICE_IDENTITY, "local.fun.com");
4991             verifyIntKey(provisioningManager, mIntQueue,
4992                     ProvisioningManager.KEY_VIDEO_QUALITY, ProvisioningManager.VIDEO_QUALITY_HIGH);
4993             verifyIntKey(provisioningManager, mIntQueue,
4994                     ProvisioningManager.KEY_VIDEO_QUALITY, ProvisioningManager.VIDEO_QUALITY_LOW);
4995             verifyIntKey(provisioningManager, mIntQueue,
4996                     ProvisioningManager.KEY_LTE_THRESHOLD_1, 0);
4997             verifyIntKey(provisioningManager, mIntQueue,
4998                     ProvisioningManager.KEY_LTE_THRESHOLD_2, 0);
4999             verifyIntKey(provisioningManager, mIntQueue,
5000                     ProvisioningManager.KEY_LTE_THRESHOLD_3, 0);
5001             verifyIntKey(provisioningManager, mIntQueue,
5002                     ProvisioningManager.KEY_1X_THRESHOLD, 0);
5003             verifyIntKey(provisioningManager, mIntQueue,
5004                     ProvisioningManager.KEY_WIFI_THRESHOLD_A, 0);
5005             verifyIntKey(provisioningManager, mIntQueue,
5006                     ProvisioningManager.KEY_WIFI_THRESHOLD_B, 0);
5007             verifyIntKey(provisioningManager, mIntQueue,
5008                     ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC, 5);
5009             verifyIntKey(provisioningManager, mIntQueue,
5010                     ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC, 5);
5011             verifyIntKey(provisioningManager, mIntQueue,
5012                     ProvisioningManager.KEY_1X_EPDG_TIMER_SEC, 5);
5013             verifyIntKey(provisioningManager, mIntQueue,
5014                     ProvisioningManager.KEY_MULTIENDPOINT_ENABLED, 0);
5015             verifyIntKey(provisioningManager, mIntQueue,
5016                     ProvisioningManager.KEY_RTT_ENABLED, 0);
5017             verifyStringKey(provisioningManager, mStringQueue,
5018                     ProvisioningManager.KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID, "carrier_spec");
5019 
5020             automan.adoptShellPermissionIdentity();
5021             provisioningManager.unregisterProvisioningChangedCallback(callback);
5022         } finally {
5023             automan.dropShellPermissionIdentity();
5024         }
5025     }
5026 
5027     @Test
testProvisioningManagerProvisioningCaps()5028     public void testProvisioningManagerProvisioningCaps() throws Exception {
5029         if (!ImsUtils.shouldTestImsService()) {
5030             return;
5031         }
5032 
5033         triggerFrameworkConnectToCarrierImsService();
5034 
5035         PersistableBundle bundle = new PersistableBundle();
5036         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true);
5037 
5038         PersistableBundle innerBundle = new PersistableBundle();
5039         innerBundle.putIntArray(
5040                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_UT_INT_ARRAY,
5041                 new int[]{IMS_REGI_TECH_LTE}); // UT/LTE
5042         bundle.putPersistableBundle(
5043                 CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE,
5044                 innerBundle);
5045 
5046         overrideCarrierConfig(bundle);
5047 
5048         ProvisioningManager provisioningManager =
5049                 ProvisioningManager.createForSubscriptionId(sTestSub);
5050 
5051         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5052         try {
5053             automan.adoptShellPermissionIdentity();
5054             boolean provisioningStatus = provisioningManager.getProvisioningStatusForCapability(
5055                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
5056                     IMS_REGI_TECH_LTE);
5057             provisioningManager.setProvisioningStatusForCapability(
5058                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
5059                     IMS_REGI_TECH_LTE, !provisioningStatus);
5060             // Make sure the change in provisioning status is correctly returned.
5061             assertEquals(!provisioningStatus,
5062                     provisioningManager.getProvisioningStatusForCapability(
5063                             MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
5064                             IMS_REGI_TECH_LTE));
5065             // TODO: Enhance test to make sure the provisioning change is also sent to the
5066             // ImsService
5067 
5068             // set back to current status
5069             provisioningManager.setProvisioningStatusForCapability(
5070                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
5071                     IMS_REGI_TECH_LTE, provisioningStatus);
5072         } finally {
5073             automan.dropShellPermissionIdentity();
5074         }
5075 
5076         overrideCarrierConfig(null);
5077     }
5078 
5079     @Test
testProvisioningManagerRcsProvisioningCaps()5080     public void testProvisioningManagerRcsProvisioningCaps() throws Exception {
5081         if (!ImsUtils.shouldTestImsSingleRegistration()) {
5082             return;
5083         }
5084 
5085         triggerFrameworkConnectToCarrierImsService();
5086 
5087         PersistableBundle bundle = new PersistableBundle();
5088         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
5089         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL,
5090                 true);
5091         bundle.putBoolean(CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, true);
5092         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, true);
5093         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
5094                 true);
5095         PersistableBundle innerBundle = new PersistableBundle();
5096         innerBundle.putIntArray(
5097                 CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY,
5098                 new int[]{IMS_REGI_TECH_LTE, IMS_REGI_TECH_IWLAN, IMS_REGI_TECH_CROSS_SIM,
5099                         IMS_REGI_TECH_NR}
5100         );
5101         bundle.putPersistableBundle(
5102                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
5103                 innerBundle);
5104         overrideCarrierConfig(bundle);
5105 
5106 
5107         ProvisioningManager provisioningManager =
5108                 ProvisioningManager.createForSubscriptionId(sTestSub);
5109 
5110         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5111         try {
5112             automan.adoptShellPermissionIdentity();
5113             boolean provisioningStatus = provisioningManager.getRcsProvisioningStatusForCapability(
5114                     RCS_CAP_PRESENCE);
5115             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
5116                     !provisioningStatus);
5117             // Make sure the change in provisioning status is correctly returned.
5118             assertEquals(!provisioningStatus,
5119                     provisioningManager.getRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE));
5120             // TODO: Enhance test to make sure the provisioning change is also sent to the
5121             //  ImsService
5122 
5123             // set back to current status
5124             provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
5125                     provisioningStatus);
5126         } finally {
5127             automan.dropShellPermissionIdentity();
5128         }
5129 
5130         overrideCarrierConfig(null);
5131     }
5132 
5133     @Test
testProvisioningManagerRcsProvisioningChangedCallback()5134     public void testProvisioningManagerRcsProvisioningChangedCallback() throws Exception {
5135         if (!ImsUtils.shouldTestImsSingleRegistration()) {
5136             return;
5137         }
5138 
5139         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5140 
5141         final int errorCode = 403;
5142         final String errorString = "Forbidden";
5143         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5144         LinkedBlockingQueue<Integer> actionQueue = new LinkedBlockingQueue<>();
5145         LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
5146                 new LinkedBlockingQueue<>();
5147         ProvisioningManager.RcsProvisioningCallback cb =
5148                 buildRcsProvisioningCallback(actionQueue, paramsQueue);
5149         ProvisioningManager provisioningManager =
5150                 ProvisioningManager.createForSubscriptionId(sTestSub);
5151         ImsConfigImplBase config = sServiceConnector.getCarrierService().getConfig();
5152 
5153         //notify rcs configuration received, wait rcs gets ready and receives notification
5154         try {
5155             automan.adoptShellPermissionIdentity();
5156             provisioningManager.notifyRcsAutoConfigurationReceived(
5157                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
5158         } finally {
5159             automan.dropShellPermissionIdentity();
5160         }
5161 
5162         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5163         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
5164 
5165         try {
5166             automan.adoptShellPermissionIdentity();
5167             provisioningManager.registerRcsProvisioningCallback(
5168                     getContext().getMainExecutor(), cb);
5169         } finally {
5170             automan.dropShellPermissionIdentity();
5171         }
5172 
5173         //callback is expected immediately
5174         res = waitForIntResult(actionQueue);
5175         assertEquals(res, RCS_CONFIG_CB_CHANGED);
5176         RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
5177         assertNotNull(params);
5178         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG_DEFAULT.getBytes()));
5179 
5180         //verify callback when rcs configuration removed
5181         config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
5182         res = waitForIntResult(actionQueue);
5183         assertEquals(res, RCS_CONFIG_CB_RESET);
5184 
5185         //verify callback when rcs configuration received, compressed
5186         config.getIImsConfig().notifyRcsAutoConfigurationReceived(
5187                 ImsUtils.compressGzip(TEST_RCS_CONFIG_DEFAULT.getBytes()), true);
5188 
5189         res = waitForIntResult(actionQueue);
5190         assertEquals(res, RCS_CONFIG_CB_CHANGED);
5191         params = waitForResult(paramsQueue);
5192         assertNotNull(params);
5193         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG_DEFAULT.getBytes()));
5194 
5195         //verify callback when auto config error received
5196         config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
5197         res = waitForIntResult(actionQueue);
5198         assertEquals(res, RCS_CONFIG_CB_ERROR);
5199         params = waitForResult(paramsQueue);
5200         assertNotNull(params);
5201         assertTrue(params.mErrorCode != null && params.mErrorCode == errorCode);
5202         assertTrue(errorString.equals(params.mErrorString));
5203 
5204         //verify callback when config removed
5205         config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
5206         res = waitForIntResult(actionQueue);
5207         assertEquals(res, RCS_CONFIG_CB_RESET);
5208 
5209         //verify callback when rcs pre-provisioning configuration received
5210         TestAcsClient.getInstance().notifyPreProvisioning(TEST_RCS_PRE_CONFIG.getBytes());
5211 
5212         res = waitForIntResult(actionQueue);
5213         assertEquals(res, RCS_CONFIG_CB_PREPROV);
5214         params = waitForResult(paramsQueue);
5215         assertNotNull(params);
5216         assertTrue(Arrays.equals(params.mConfig, TEST_RCS_PRE_CONFIG.getBytes()));
5217 
5218         //unregister callback and verify not to receive callback any more
5219         try {
5220             automan.adoptShellPermissionIdentity();
5221             provisioningManager.unregisterRcsProvisioningCallback(cb);
5222         } finally {
5223             automan.dropShellPermissionIdentity();
5224         }
5225         res = waitForIntResult(actionQueue);
5226         assertEquals(res, RCS_CONFIG_CB_DELETE);
5227 
5228         config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
5229         res = waitForIntResult(actionQueue, 500);
5230         assertEquals(res, Integer.MAX_VALUE);
5231     }
5232 
5233     @Test
testProvisioningManagerNotifyRcsAutoConfigurationReceived()5234     public void testProvisioningManagerNotifyRcsAutoConfigurationReceived() throws Exception {
5235         if (!ImsUtils.shouldTestImsSingleRegistration()) {
5236             return;
5237         }
5238 
5239         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5240 
5241         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5242         LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
5243         LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
5244                 new LinkedBlockingQueue<>();
5245         ProvisioningManager.RcsProvisioningCallback cb =
5246                 buildRcsProvisioningCallback(clientQueue, paramsQueue);
5247         ProvisioningManager provisioningManager =
5248                 ProvisioningManager.createForSubscriptionId(sTestSub);
5249         String configStr = TEST_RCS_CONFIG_DEFAULT;
5250 
5251         //notify rcs configuration received, wait rcs gets ready and receives notification
5252         try {
5253             automan.adoptShellPermissionIdentity();
5254             provisioningManager.notifyRcsAutoConfigurationReceived(
5255                     configStr.getBytes(), false);
5256         } finally {
5257             automan.dropShellPermissionIdentity();
5258         }
5259 
5260         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5261         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
5262 
5263         try {
5264             automan.adoptShellPermissionIdentity();
5265             provisioningManager.registerRcsProvisioningCallback(
5266                     getContext().getMainExecutor(), cb);
5267         } finally {
5268             automan.dropShellPermissionIdentity();
5269         }
5270 
5271         res = waitForIntResult(clientQueue);
5272         assertEquals(res, RCS_CONFIG_CB_CHANGED);
5273         RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
5274         assertNotNull(params);
5275         assertTrue(Arrays.equals(params.mConfig, configStr.getBytes()));
5276         assertTrue(Arrays.equals(
5277                 configStr.getBytes(), TestAcsClient.getInstance().getConfig()));
5278 
5279         configStr = TEST_RCS_CONFIG_SINGLE_REGISTRATION_DISABLED;
5280         try {
5281             automan.adoptShellPermissionIdentity();
5282             provisioningManager.notifyRcsAutoConfigurationReceived(
5283                     ImsUtils.compressGzip(configStr.getBytes()), true);
5284         } finally {
5285             automan.dropShellPermissionIdentity();
5286         }
5287 
5288         res = waitForIntResult(clientQueue);
5289         assertEquals(res, RCS_CONFIG_CB_CHANGED);
5290         params = waitForResult(paramsQueue);
5291         assertNotNull(params);
5292         assertTrue(Arrays.equals(params.mConfig, configStr.getBytes()));
5293 
5294         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5295         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
5296         assertTrue(Arrays.equals(
5297                 configStr.getBytes(), TestAcsClient.getInstance().getConfig()));
5298     }
5299 
5300     @Test
testProvisioningManagerTriggerRcsReconfiguration()5301     public void testProvisioningManagerTriggerRcsReconfiguration() throws Exception {
5302         if (!ImsUtils.shouldTestImsSingleRegistration()) {
5303             return;
5304         }
5305 
5306         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5307 
5308         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5309         LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
5310         ProvisioningManager.RcsProvisioningCallback cb =
5311                 buildRcsProvisioningCallback(clientQueue, null);
5312 
5313         ProvisioningManager provisioningManager =
5314                 ProvisioningManager.createForSubscriptionId(sTestSub);
5315 
5316         //notify rcs configuration received, wait rcs gets ready and receives notification
5317         try {
5318             automan.adoptShellPermissionIdentity();
5319             provisioningManager.notifyRcsAutoConfigurationReceived(
5320                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
5321         } finally {
5322             automan.dropShellPermissionIdentity();
5323         }
5324 
5325         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5326         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
5327 
5328         //set default rcs config
5329         try {
5330             automan.adoptShellPermissionIdentity();
5331             provisioningManager.registerRcsProvisioningCallback(
5332                     getContext().getMainExecutor(), cb);
5333         } finally {
5334             automan.dropShellPermissionIdentity();
5335         }
5336 
5337         res = waitForIntResult(clientQueue);
5338         assertEquals(res, RCS_CONFIG_CB_CHANGED);
5339 
5340         //test triggerRcsReconfiguration
5341         try {
5342             automan.adoptShellPermissionIdentity();
5343             provisioningManager.triggerRcsReconfiguration();
5344         } finally {
5345             automan.dropShellPermissionIdentity();
5346         }
5347 
5348         res = waitForIntResult(clientQueue);
5349         assertEquals(res, RCS_CONFIG_CB_RESET);
5350 
5351         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5352         assertEquals(res, TestAcsClient.ACTION_CONFIG_REMOVED);
5353 
5354         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5355         assertEquals(res, TestAcsClient.ACTION_TRIGGER_AUTO_CONFIG);
5356     }
5357 
5358     @Test
testProvisioningManagerSetRcsClientConfiguration()5359     public void testProvisioningManagerSetRcsClientConfiguration() throws Exception {
5360         if (!ImsUtils.shouldTestImsSingleRegistration()) {
5361             return;
5362         }
5363         RcsClientConfiguration rcc = new RcsClientConfiguration(
5364                 "1.0", "UP_1.0", "Android", "RCSAndrd-1.0");
5365         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5366 
5367         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5368         ProvisioningManager provisioningManager =
5369                 ProvisioningManager.createForSubscriptionId(sTestSub);
5370 
5371         //notify rcs configuration received, wait rcs gets ready and receives notification
5372         try {
5373             automan.adoptShellPermissionIdentity();
5374             provisioningManager.notifyRcsAutoConfigurationReceived(
5375                     TEST_RCS_CONFIG_DEFAULT.getBytes(), false);
5376         } finally {
5377             automan.dropShellPermissionIdentity();
5378         }
5379 
5380         int res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5381         assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
5382 
5383         try {
5384             automan.adoptShellPermissionIdentity();
5385             provisioningManager.setRcsClientConfiguration(rcc);
5386         } finally {
5387             automan.dropShellPermissionIdentity();
5388         }
5389 
5390         res = waitForIntResult(TestAcsClient.getInstance().getActionQueue());
5391         assertEquals(res, TestAcsClient.ACTION_SET_RCS_CLIENT_CONFIG);
5392         assertEquals(rcc, TestAcsClient.getInstance().getRcc());
5393     }
5394 
5395     @Test
testProvisioningManagerRcsVolteSingleRegistrationCapable()5396     public void testProvisioningManagerRcsVolteSingleRegistrationCapable() throws Exception {
5397         if (!ImsUtils.shouldTestImsService()) {
5398             return;
5399         }
5400         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5401 
5402         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5403         boolean isSingleRegistrationEnabledOnDevice =
5404                 sServiceConnector.getDeviceSingleRegistrationEnabled();
5405         boolean isSingleRegistrationEnabledByCarrier =
5406                 sServiceConnector.getCarrierSingleRegistrationEnabled();
5407 
5408         ProvisioningManager provisioningManager =
5409                 ProvisioningManager.createForSubscriptionId(sTestSub);
5410         PersistableBundle bundle = new PersistableBundle();
5411         bundle.putBoolean(
5412                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
5413                 !isSingleRegistrationEnabledByCarrier);
5414         sSrcReceiver.clearQueue();
5415         overrideCarrierConfig(bundle);
5416         sSrcReceiver.waitForChanged();
5417         int capability = sSrcReceiver.getCapability();
5418 
5419         assertEquals(!isSingleRegistrationEnabledByCarrier,
5420                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
5421         try {
5422             automan.adoptShellPermissionIdentity();
5423             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
5424                     isSingleRegistrationEnabledOnDevice && !isSingleRegistrationEnabledByCarrier);
5425         } finally {
5426             automan.dropShellPermissionIdentity();
5427         }
5428 
5429         bundle = new PersistableBundle();
5430         bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
5431                 isSingleRegistrationEnabledByCarrier);
5432         sSrcReceiver.clearQueue();
5433         overrideCarrierConfig(bundle);
5434         sSrcReceiver.waitForChanged();
5435         capability = sSrcReceiver.getCapability();
5436 
5437         assertEquals(isSingleRegistrationEnabledByCarrier,
5438                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
5439         try {
5440             automan.adoptShellPermissionIdentity();
5441             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
5442                     isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
5443         } finally {
5444             automan.dropShellPermissionIdentity();
5445         }
5446 
5447         sSrcReceiver.clearQueue();
5448         sServiceConnector.setDeviceSingleRegistrationEnabled(!isSingleRegistrationEnabledOnDevice);
5449         sSrcReceiver.waitForChanged();
5450         capability = sSrcReceiver.getCapability();
5451 
5452         assertEquals(!isSingleRegistrationEnabledOnDevice,
5453                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
5454         try {
5455             automan.adoptShellPermissionIdentity();
5456             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
5457                     !isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
5458         } finally {
5459             automan.dropShellPermissionIdentity();
5460         }
5461 
5462         sSrcReceiver.clearQueue();
5463         sServiceConnector.setDeviceSingleRegistrationEnabled(isSingleRegistrationEnabledOnDevice);
5464         sSrcReceiver.waitForChanged();
5465         capability = sSrcReceiver.getCapability();
5466 
5467         assertEquals(isSingleRegistrationEnabledOnDevice,
5468                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
5469         try {
5470             automan.adoptShellPermissionIdentity();
5471             assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
5472                     isSingleRegistrationEnabledOnDevice && isSingleRegistrationEnabledByCarrier);
5473         } finally {
5474             automan.dropShellPermissionIdentity();
5475         }
5476 
5477         sServiceConnector.setDeviceSingleRegistrationEnabled(null);
5478         overrideCarrierConfig(null);
5479         sSrcReceiver.waitForChanged();
5480         capability = sSrcReceiver.getCapability();
5481 
5482         assertEquals(isSingleRegistrationEnabledOnDevice,
5483                 (ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE & capability) == 0);
5484         assertEquals(isSingleRegistrationEnabledByCarrier,
5485                 (ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE & capability) == 0);
5486     }
5487 
5488     /**
5489      * Verifies that the RTP header extensions are set as expected when D2D communication is
5490      * available on the device and for the current carrier.
5491      * @throws Exception
5492      */
5493     @Test
testSetRtpHeaderExtensions()5494     public void testSetRtpHeaderExtensions() throws Exception {
5495         if (!ImsUtils.shouldTestImsService()) {
5496             return;
5497         }
5498         sServiceConnector.setDeviceToDeviceCommunicationEnabled(true);
5499         try {
5500             PersistableBundle bundle = new PersistableBundle();
5501             bundle.putBoolean(
5502                     CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
5503                     true);
5504             bundle.putBoolean(CarrierConfigManager
5505                     .KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL, true);
5506             overrideCarrierConfig(bundle);
5507 
5508             triggerFrameworkConnectToCarrierImsService();
5509 
5510             sServiceConnector.getCarrierService().getMmTelFeature()
5511                     .getOfferedRtpHeaderExtensionLatch().await(5000, TimeUnit.MILLISECONDS);
5512             Set<RtpHeaderExtensionType> extensions = sServiceConnector.getCarrierService()
5513                     .getMmTelFeature().getOfferedRtpHeaderExtensionTypes();
5514 
5515             assertTrue(extensions.size() > 0);
5516         } finally {
5517             sServiceConnector.setDeviceToDeviceCommunicationEnabled(false);
5518             overrideCarrierConfig(null);
5519         }
5520     }
5521 
5522     @Test
testSetMediaThreshold()5523     public void testSetMediaThreshold() throws Exception {
5524         if (!ImsUtils.shouldTestImsService()) {
5525             return;
5526         }
5527         sServiceConnector.setDeviceToDeviceCommunicationEnabled(true);
5528         try {
5529             PersistableBundle bundle = new PersistableBundle();
5530             bundle.putInt(
5531                     CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_PACKET_LOSS_RATE_THRESHOLD_INT,
5532                     TEST_PACKET_LOSS_RATE_THRESHOLD);
5533             bundle.putLong(
5534                     CarrierConfigManager
5535                             .ImsVoice
5536                             .KEY_VOICE_RTP_INACTIVITY_TIME_THRESHOLD_MILLIS_LONG,
5537                     TEST_INACTIVITY_MILLIS);
5538             bundle.putInt(
5539                     CarrierConfigManager
5540                             .ImsVoice.KEY_VOICE_RTP_JITTER_THRESHOLD_MILLIS_INT,
5541                     TEST_JITTER_THRESHOLD);
5542             overrideCarrierConfig(bundle);
5543 
5544             triggerFrameworkConnectToCarrierImsService();
5545 
5546             sServiceConnector.getCarrierService().getMmTelFeature()
5547                     .getSetMediaThresholdLatch(TEST_PACKET_LOSS_RATE_THRESHOLD,
5548                             TEST_JITTER_THRESHOLD, TEST_INACTIVITY_MILLIS)
5549                     .await(10000, TimeUnit.MILLISECONDS);
5550             MediaThreshold threshold =
5551                     sServiceConnector.getCarrierService().getMmTelFeature().getSetMediaThreshold();
5552 
5553             assertNotNull(threshold);
5554             assertArrayEquals(new int[]{TEST_PACKET_LOSS_RATE_THRESHOLD},
5555                     threshold.getThresholdsRtpPacketLossRate());
5556             assertArrayEquals(new int[]{TEST_JITTER_THRESHOLD},
5557                     threshold.getThresholdsRtpJitterMillis());
5558             assertArrayEquals(new long[]{TEST_INACTIVITY_MILLIS},
5559                     threshold.getThresholdsRtpInactivityTimeMillis());
5560         } finally {
5561             sServiceConnector.setDeviceToDeviceCommunicationEnabled(false);
5562             overrideCarrierConfig(null);
5563         }
5564     }
5565 
5566     @Test
testImsMmTelManagerImsStateCallback()5567     public void testImsMmTelManagerImsStateCallback() throws Exception {
5568         if (!ImsUtils.shouldTestImsService()) {
5569             return;
5570         }
5571 
5572         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
5573         if (imsManager == null) {
5574             fail("Cannot find IMS service");
5575         }
5576 
5577         LinkedBlockingQueue<Integer> stateQueue = new LinkedBlockingQueue<>();
5578         ImsStateCallback callback = buildImsStateCallback(stateQueue);
5579 
5580         ImsMmTelManager mmTelManager = null;
5581         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5582         try {
5583             automan.adoptShellPermissionIdentity();
5584             mmTelManager = imsManager.getImsMmTelManager(sTestSub);
5585             mmTelManager.registerImsStateCallback(getContext().getMainExecutor(), callback);
5586         } finally {
5587             automan.dropShellPermissionIdentity();
5588         }
5589 
5590         int reason = waitForIntResult(stateQueue);
5591         assertTrue(reason == ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR
5592                 || reason == ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR
5593                 || reason == ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED
5594                 || reason == ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED
5595                 || reason == ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE
5596                 || reason == ImsStateCallback.REASON_IMS_SERVICE_NOT_READY);
5597 
5598         mmTelManager.unregisterImsStateCallback(callback);
5599 
5600         // Connect to device ImsService with MmTelFeature
5601         triggerFrameworkConnectToCarrierImsService();
5602 
5603         stateQueue = new LinkedBlockingQueue<>();
5604         callback = buildImsStateCallback(stateQueue);
5605 
5606         try {
5607             automan.adoptShellPermissionIdentity();
5608             mmTelManager.registerImsStateCallback(getContext().getMainExecutor(), callback);
5609         } finally {
5610             automan.dropShellPermissionIdentity();
5611         }
5612 
5613         // expects FEATURE_MMTEL STATE_READY
5614         assertEquals(FEATURE_STATE_READY, waitForIntResult(stateQueue));
5615 
5616         if (sServiceConnector != null) {
5617             sServiceConnector.getCarrierService().getMmTelFeature().setFeatureState(
5618                     ImsFeature.STATE_INITIALIZING);
5619         }
5620 
5621         // expects NOT_READY
5622         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_NOT_READY,
5623                 waitForIntResult(stateQueue));
5624 
5625         // Unbind the GTS ImsService
5626         if (sServiceConnector != null) {
5627             sServiceConnector.disconnectCarrierImsService();
5628         }
5629 
5630         // expects DISCONNECTED
5631         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED,
5632                 waitForIntResult(stateQueue));
5633 
5634         mmTelManager.unregisterImsStateCallback(callback);
5635     }
5636 
5637     @Test
testImsRcsManagerImsStateCallback()5638     public void testImsRcsManagerImsStateCallback() throws Exception {
5639         if (!ImsUtils.shouldTestImsService()) {
5640             return;
5641         }
5642 
5643         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
5644         if (imsManager == null) {
5645             fail("Cannot find IMS service");
5646         }
5647 
5648         LinkedBlockingQueue<Integer> rcsQueue = new LinkedBlockingQueue<>();
5649         ImsStateCallback rcsCallback = buildImsStateCallback(rcsQueue);
5650 
5651         LinkedBlockingQueue<Integer> sipQueue = new LinkedBlockingQueue<>();
5652         ImsStateCallback sipCallback = buildImsStateCallback(sipQueue);
5653 
5654         ImsRcsManager imsRcsManager;
5655         SipDelegateManager imsSipManager;
5656         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5657         try {
5658             automan.adoptShellPermissionIdentity();
5659             imsRcsManager = imsManager.getImsRcsManager(sTestSub);
5660             imsRcsManager.registerImsStateCallback(getContext().getMainExecutor(), rcsCallback);
5661             imsSipManager = imsManager.getSipDelegateManager(sTestSub);
5662             imsSipManager.registerImsStateCallback(getContext().getMainExecutor(), sipCallback);
5663         } finally {
5664             automan.dropShellPermissionIdentity();
5665         }
5666 
5667         int reason = waitForIntResult(rcsQueue);
5668         assertTrue(reason == ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR
5669                 || reason == ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR
5670                 || reason == ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED
5671                 || reason == ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED
5672                 || reason == ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE
5673                 || reason == ImsStateCallback.REASON_IMS_SERVICE_NOT_READY);
5674 
5675         reason = waitForIntResult(sipQueue);
5676         assertTrue(reason == ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR
5677                 || reason == ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR
5678                 || reason == ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED
5679                 || reason == ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED
5680                 || reason == ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE
5681                 || reason == ImsStateCallback.REASON_IMS_SERVICE_NOT_READY);
5682 
5683         imsRcsManager.unregisterImsStateCallback(rcsCallback);
5684         imsSipManager.unregisterImsStateCallback(sipCallback);
5685 
5686         // Override the carrier config
5687         PersistableBundle bundle = new PersistableBundle();
5688         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
5689         bundle.putBoolean(
5690                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
5691         overrideCarrierConfig(bundle);
5692 
5693         // Connect to device ImsService with RcsFeature
5694         triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
5695 
5696         rcsQueue = new LinkedBlockingQueue<>();
5697         rcsCallback = buildImsStateCallback(rcsQueue);
5698 
5699         sipQueue = new LinkedBlockingQueue<>();
5700         sipCallback = buildImsStateCallback(sipQueue);
5701 
5702         try {
5703             automan.adoptShellPermissionIdentity();
5704             imsRcsManager.registerImsStateCallback(getContext().getMainExecutor(), rcsCallback);
5705             imsSipManager.registerImsStateCallback(getContext().getMainExecutor(), sipCallback);
5706         } finally {
5707             automan.dropShellPermissionIdentity();
5708         }
5709 
5710         // expects FEATURE_RCS, NO_IMS_SERVICE_CONFIGURED
5711         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5712                 waitForIntResult(rcsQueue));
5713         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5714                 waitForIntResult(sipQueue));
5715 
5716         // Override the carrier config
5717         bundle = new PersistableBundle();
5718         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
5719         overrideCarrierConfig(bundle);
5720 
5721         // Wait for the framework to set the capabilities on the ImsService
5722         sServiceConnector.getCarrierService().waitForLatchCountdown(
5723                 TestImsService.LATCH_RCS_CAP_SET);
5724 
5725         // expects FEATURE_RCS, STATE_READY
5726         assertEquals(FEATURE_STATE_READY, waitForIntResult(rcsQueue));
5727         assertEquals(FEATURE_STATE_READY, waitForIntResult(sipQueue));
5728 
5729         bundle = new PersistableBundle();
5730         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
5731         overrideCarrierConfig(bundle);
5732 
5733         // expects FEATURE_RCS, NO_IMS_SERVICE_CONFIGURED
5734         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5735                 waitForIntResult(rcsQueue));
5736         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5737                 waitForIntResult(sipQueue));
5738 
5739         // Override the carrier config
5740         bundle = new PersistableBundle();
5741         bundle.putBoolean(
5742                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
5743         overrideCarrierConfig(bundle);
5744 
5745         // expects FEATURE_RCS, STATE_READY
5746         assertEquals(FEATURE_STATE_READY, waitForIntResult(rcsQueue));
5747         assertEquals(FEATURE_STATE_READY, waitForIntResult(sipQueue));
5748 
5749         bundle = new PersistableBundle();
5750         bundle.putBoolean(
5751                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
5752         overrideCarrierConfig(bundle);
5753 
5754         // expects FEATURE_RCS, NO_IMS_SERVICE_CONFIGURED
5755         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5756                 waitForIntResult(rcsQueue));
5757         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5758                 waitForIntResult(sipQueue));
5759 
5760         // Override the carrier config
5761         bundle = new PersistableBundle();
5762         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
5763         bundle.putBoolean(
5764                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
5765         overrideCarrierConfig(bundle);
5766 
5767         // expects FEATURE_RCS, STATE_READY
5768         assertEquals(FEATURE_STATE_READY, waitForIntResult(rcsQueue));
5769         assertEquals(FEATURE_STATE_READY, waitForIntResult(sipQueue));
5770 
5771         bundle = new PersistableBundle();
5772         bundle.putBoolean(
5773                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
5774         overrideCarrierConfig(bundle);
5775 
5776         // ensure no change in state since having one active feature
5777         reason = waitForIntResult(rcsQueue, 3000);
5778         assertEquals(Integer.MAX_VALUE, reason);
5779         reason = waitForIntResult(sipQueue, 1000);
5780         assertEquals(Integer.MAX_VALUE, reason);
5781 
5782         bundle = new PersistableBundle();
5783         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
5784         overrideCarrierConfig(bundle);
5785 
5786         // expects FEATURE_RCS, NO_IMS_SERVICE_CONFIGURED
5787         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5788                 waitForIntResult(rcsQueue));
5789         assertEquals(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED,
5790                 waitForIntResult(sipQueue));
5791 
5792         // Override the carrier config
5793         bundle = new PersistableBundle();
5794         bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
5795         overrideCarrierConfig(bundle);
5796 
5797         // expects FEATURE_RCS, STATE_READY
5798         assertEquals(FEATURE_STATE_READY, waitForIntResult(rcsQueue));
5799         assertEquals(FEATURE_STATE_READY, waitForIntResult(sipQueue));
5800 
5801         if (sServiceConnector != null) {
5802             sServiceConnector.getCarrierService().getRcsFeature().setFeatureState(
5803                     ImsFeature.STATE_INITIALIZING);
5804         }
5805 
5806         // expects NOT_READY
5807         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_NOT_READY,
5808                 waitForIntResult(rcsQueue));
5809         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_NOT_READY,
5810                 waitForIntResult(sipQueue));
5811 
5812         // Unbind the GTS ImsService
5813         if (sServiceConnector != null) {
5814             sServiceConnector.disconnectCarrierImsService();
5815         }
5816 
5817         // expects DISCONNECTED
5818         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED,
5819                 waitForIntResult(rcsQueue));
5820         assertEquals(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED,
5821                 waitForIntResult(sipQueue));
5822 
5823         imsRcsManager.unregisterImsStateCallback(rcsCallback);
5824         imsSipManager.unregisterImsStateCallback(sipCallback);
5825     }
5826 
5827     @Test
testUnregisteredCallbackCompatibility()5828     public void testUnregisteredCallbackCompatibility() throws Exception {
5829         if (!ImsUtils.shouldTestImsService()) {
5830             return;
5831         }
5832 
5833         assumeTrue(sSupportsImsHal);
5834 
5835         triggerFrameworkConnectToCarrierImsService();
5836 
5837         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
5838         if (imsManager == null) {
5839             fail("Cannot find IMS service");
5840         }
5841 
5842         LinkedBlockingQueue<Integer> stateQueue = new LinkedBlockingQueue<>();
5843         ImsStateCallback stateCallback = buildImsStateCallback(stateQueue);
5844 
5845         ImsMmTelManager mmTelManager = null;
5846         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5847         try {
5848             automan.adoptShellPermissionIdentity();
5849             mmTelManager = imsManager.getImsMmTelManager(sTestSub);
5850             mmTelManager.registerImsStateCallback(getContext().getMainExecutor(), stateCallback);
5851         } finally {
5852             automan.dropShellPermissionIdentity();
5853         }
5854 
5855         // expects FEATURE_MMTEL STATE_READY
5856         assertEquals(FEATURE_STATE_READY, waitForIntResult(stateQueue));
5857 
5858         mmTelManager.unregisterImsStateCallback(stateCallback);
5859 
5860         // Start de-registered
5861         ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE,
5862                 ImsReasonInfo.CODE_UNSPECIFIED, "");
5863         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(reasonInfo);
5864 
5865         LinkedBlockingQueue<ImsReasonInfo> mDeregQueue =
5866                 new LinkedBlockingQueue<>();
5867         RegistrationManager.RegistrationCallback callback =
5868                 new RegistrationManager.RegistrationCallback() {
5869             @Override
5870             public void onUnregistered(ImsReasonInfo info) {
5871                 mDeregQueue.offer(info);
5872             }
5873         };
5874 
5875         try {
5876             automan.adoptShellPermissionIdentity();
5877             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
5878         } finally {
5879             automan.dropShellPermissionIdentity();
5880         }
5881 
5882         ImsReasonInfo receivedInfo = waitForResult(mDeregQueue);
5883         assertNotNull(receivedInfo);
5884         assertEquals(reasonInfo, receivedInfo);
5885 
5886         // onDeregistered with extra
5887         reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
5888                 ImsReasonInfo.CODE_UNSPECIFIED, "");
5889         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
5890                 reasonInfo, SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_LTE);
5891 
5892         receivedInfo = waitForResult(mDeregQueue);
5893         assertNotNull(receivedInfo);
5894         assertEquals(reasonInfo, receivedInfo);
5895 
5896         try {
5897             automan.adoptShellPermissionIdentity();
5898             mmTelManager.unregisterImsRegistrationCallback(callback);
5899         } finally {
5900             automan.dropShellPermissionIdentity();
5901         }
5902     }
5903 
5904     @Ignore("RegistrationManager.RegistrationCallback#onUnregistered(ImsReasonInfo,int,int)"
5905             + " is hidden. Internal use only.")
5906     @Test
testMmTelManagerRegistrationBlock()5907     public void testMmTelManagerRegistrationBlock() throws Exception {
5908         if (!ImsUtils.shouldTestImsService()) {
5909             return;
5910         }
5911 
5912         assumeTrue(sSupportsImsHal);
5913 
5914         triggerFrameworkConnectToCarrierImsService();
5915 
5916         ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
5917                 ImsReasonInfo.CODE_UNSPECIFIED, "");
5918 
5919         // Start de-registered
5920         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
5921                 reasonInfo, SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NONE);
5922 
5923         LinkedBlockingQueue<Integer> mDeregQueue =
5924                 new LinkedBlockingQueue<>();
5925         RegistrationManager.RegistrationCallback callback =
5926                 new RegistrationManager.RegistrationCallback() {
5927             @Override
5928             public void onUnregistered(ImsReasonInfo info, int suggestedAction,
5929                     int imsRadioTech) {
5930                 mDeregQueue.offer(suggestedAction);
5931             }
5932         };
5933 
5934         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
5935         try {
5936             automan.adoptShellPermissionIdentity();
5937             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
5938             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
5939             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
5940         } finally {
5941             automan.dropShellPermissionIdentity();
5942         }
5943 
5944         int suggestedAction = waitForResult(mDeregQueue);
5945         assertNotEquals(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, suggestedAction);
5946         assertNotEquals(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT, suggestedAction);
5947 
5948         // fatal error
5949         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
5950                 reasonInfo, SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK,
5951                 REGISTRATION_TECH_LTE);
5952 
5953         suggestedAction = waitForResult(mDeregQueue);
5954         assertEquals(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, suggestedAction);
5955 
5956         // repeated error
5957         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
5958                 reasonInfo, SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
5959                 REGISTRATION_TECH_LTE);
5960 
5961         suggestedAction = waitForResult(mDeregQueue);
5962         assertEquals(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT, suggestedAction);
5963 
5964         // without extra
5965         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(reasonInfo);
5966 
5967         suggestedAction = waitForResult(mDeregQueue);
5968         assertEquals(SUGGESTED_ACTION_NONE, suggestedAction);
5969     }
5970 
5971     @Ignore("RegistrationManager.RegistrationCallback#onUnregistered(ImsReasonInfo,int,int)"
5972             + " is hidden. Internal use only.")
5973     @Test
5974     @RequiresFlagsEnabled(
5975             Flags.FLAG_ADD_RAT_RELATED_SUGGESTED_ACTION_TO_IMS_REGISTRATION)
testMmTelManagerRegistrationBlockWithRatSuggestedAction()5976     public void testMmTelManagerRegistrationBlockWithRatSuggestedAction() throws Exception {
5977         if (!ImsUtils.shouldTestImsService()) {
5978             return;
5979         }
5980 
5981         assumeTrue(sSupportsImsHal);
5982 
5983         triggerFrameworkConnectToCarrierImsService();
5984 
5985         ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
5986                 ImsReasonInfo.CODE_UNSPECIFIED, "");
5987 
5988         // Start de-registered
5989         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
5990                 reasonInfo, SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NONE);
5991 
5992         LinkedBlockingQueue<Integer> mDeregQueue =
5993                 new LinkedBlockingQueue<>();
5994         RegistrationManager.RegistrationCallback callback =
5995                 new RegistrationManager.RegistrationCallback() {
5996                     @Override
5997                     public void onUnregistered(ImsReasonInfo info, int suggestedAction,
5998                             int imsRadioTech) {
5999                         mDeregQueue.offer(suggestedAction);
6000                     }
6001                 };
6002 
6003         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
6004         try {
6005             automan.adoptShellPermissionIdentity();
6006             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
6007             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
6008             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
6009         } finally {
6010             automan.dropShellPermissionIdentity();
6011         }
6012 
6013         int suggestedAction = waitForResult(mDeregQueue);
6014         assertNotEquals(SUGGESTED_ACTION_TRIGGER_RAT_BLOCK, suggestedAction);
6015         assertNotEquals(SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCKS, suggestedAction);
6016 
6017         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6018                 reasonInfo, SUGGESTED_ACTION_TRIGGER_RAT_BLOCK,
6019                 REGISTRATION_TECH_LTE);
6020 
6021         suggestedAction = waitForResult(mDeregQueue);
6022         assertEquals(SUGGESTED_ACTION_TRIGGER_RAT_BLOCK, suggestedAction);
6023 
6024         // rat block clear
6025         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6026                 reasonInfo, SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCKS,
6027                 REGISTRATION_TECH_LTE);
6028 
6029         suggestedAction = waitForResult(mDeregQueue);
6030         assertEquals(SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCKS, suggestedAction);
6031 
6032         // without extra
6033         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(reasonInfo);
6034 
6035         suggestedAction = waitForResult(mDeregQueue);
6036         assertEquals(SUGGESTED_ACTION_NONE, suggestedAction);
6037     }
6038 
6039     @Ignore("RegistrationManager.RegistrationCallback#onUnregistered(ImsReasonInfo,int,int)"
6040             + " is hidden. Internal use only.")
6041     @Test
testMmTelManagerRegistrationDeregisteredRadioTech()6042     public void testMmTelManagerRegistrationDeregisteredRadioTech() throws Exception {
6043         if (!ImsUtils.shouldTestImsService()) {
6044             return;
6045         }
6046 
6047         assumeTrue(sSupportsImsHal);
6048 
6049         triggerFrameworkConnectToCarrierImsService();
6050 
6051         ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
6052                 ImsReasonInfo.CODE_UNSPECIFIED, "");
6053 
6054         // Start de-registered
6055         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6056                 reasonInfo, SUGGESTED_ACTION_NONE, REGISTRATION_TECH_LTE);
6057 
6058         LinkedBlockingQueue<Integer> mDeregQueue =
6059                 new LinkedBlockingQueue<>();
6060         RegistrationManager.RegistrationCallback callback =
6061                 new RegistrationManager.RegistrationCallback() {
6062             @Override
6063             public void onUnregistered(ImsReasonInfo info, int suggestedAction,
6064                     int imsRadioTech) {
6065                 mDeregQueue.offer(imsRadioTech);
6066             }
6067         };
6068 
6069         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
6070         try {
6071             automan.adoptShellPermissionIdentity();
6072             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
6073             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
6074             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
6075         } finally {
6076             automan.dropShellPermissionIdentity();
6077         }
6078 
6079         int imsRadioTech = waitForResult(mDeregQueue);
6080         assertEquals(REGISTRATION_TECH_LTE, imsRadioTech);
6081 
6082         // without extra
6083         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(reasonInfo);
6084 
6085         imsRadioTech = waitForResult(mDeregQueue);
6086         assertEquals(REGISTRATION_TECH_NONE, imsRadioTech);
6087     }
6088 
6089     @Test
testImsPhoneNumberWithImsAssociatedUri()6090     public void testImsPhoneNumberWithImsAssociatedUri() throws Exception {
6091         if (!ImsUtils.shouldTestImsService()) {
6092             return;
6093         }
6094 
6095         // bind TestImsService
6096         triggerFrameworkConnectToCarrierImsService();
6097 
6098         // deregistered to set initial state
6099         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6100                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
6101                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
6102 
6103         // To check when framework completes its operation
6104         LinkedBlockingQueue<Integer> mSubscriberQueue = new LinkedBlockingQueue<>(1);
6105         RegistrationManager.RegistrationCallback callback =
6106                 new RegistrationManager.RegistrationCallback() {
6107                     @Override
6108                     public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
6109                         mSubscriberQueue.offer(uris.length);
6110                     }
6111                 };
6112 
6113         // register callback
6114         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
6115         try {
6116             automan.adoptShellPermissionIdentity();
6117             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
6118             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
6119             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
6120         } finally {
6121             automan.dropShellPermissionIdentity();
6122         }
6123 
6124         // trigger complete registration
6125         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
6126                 IMS_REGI_TECH_LTE);
6127 
6128         // trigger notify the associated URI has changed.
6129         Uri[] associatedUris = new Uri[] {
6130                 Uri.parse("sip:+447539447777@ims.x.com"),
6131                 Uri.parse("tel:+447539446666")
6132         };
6133         sServiceConnector.getCarrierService().getImsRegistration()
6134                 .onSubscriberAssociatedUriChanged(associatedUris);
6135 
6136         assertNotEquals(Integer.MAX_VALUE,
6137                 waitForIntResult(mSubscriberQueue, ImsUtils.TEST_TIMEOUT_MS));
6138 
6139         // Wait a second for the onSubscriberAssociatedUriChanged indication to be processed on the
6140         // main telephony thread. Although telephony extracts and stores phone number, accessing to
6141         // phone number is through the SubscriptionManager. Before calling the
6142         // SubscriptionManager#getPhoneNumber, a guard time is required for telephony.
6143         // currently no better way of knowing that telephony has processed this command.
6144         Thread.sleep(TEST_OPERATION_TIME_MS);
6145 
6146         try {
6147             automan.adoptShellPermissionIdentity();
6148             SubscriptionManager sm = (SubscriptionManager) getContext()
6149                     .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6150             String phoneNumber = sm.getPhoneNumber(sTestSub,
6151                     SubscriptionManager.PHONE_NUMBER_SOURCE_IMS);
6152 
6153             // verify Ims phone number
6154             assertEquals("+447539447777", phoneNumber);
6155         } finally {
6156             automan.dropShellPermissionIdentity();
6157         }
6158     }
6159 
6160     @Test
testImsPhoneNumberWithImsAssociatedUriForNonGlobalNumberFormat()6161     public void testImsPhoneNumberWithImsAssociatedUriForNonGlobalNumberFormat() throws Exception {
6162         if (!ImsUtils.shouldTestImsService()) {
6163             return;
6164         }
6165 
6166         // Change carrier config
6167         PersistableBundle bundle = new PersistableBundle();
6168         bundle.putBoolean(
6169                 CarrierConfigManager.Ims.KEY_ALLOW_NON_GLOBAL_PHONE_NUMBER_FORMAT_BOOL, true);
6170         overrideCarrierConfig(bundle);
6171 
6172         // bind TestImsService
6173         triggerFrameworkConnectToCarrierImsService();
6174 
6175         // deregistered to set initial state
6176         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6177                 new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
6178                         ImsReasonInfo.CODE_UNSPECIFIED, ""));
6179 
6180         // To check when framework completes its operation
6181         LinkedBlockingQueue<Integer> mSubscriberQueue = new LinkedBlockingQueue<>(1);
6182         RegistrationManager.RegistrationCallback callback =
6183                 new RegistrationManager.RegistrationCallback() {
6184                     @Override
6185                     public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
6186                         mSubscriberQueue.offer(uris.length);
6187                     }
6188                 };
6189 
6190         // register callback
6191         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
6192         try {
6193             automan.adoptShellPermissionIdentity();
6194             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
6195             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
6196             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
6197         } finally {
6198             automan.dropShellPermissionIdentity();
6199         }
6200 
6201         // trigger complete registration
6202         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
6203                 IMS_REGI_TECH_LTE);
6204 
6205         // trigger notify the associated URI has changed.
6206         Uri[] associatedUris = new Uri[] {
6207                 Uri.parse("sip:447539447777@ims.x.com"),
6208                 Uri.parse("tel:447539446666")
6209         };
6210         sServiceConnector.getCarrierService().getImsRegistration()
6211                 .onSubscriberAssociatedUriChanged(associatedUris);
6212 
6213         assertNotEquals(Integer.MAX_VALUE,
6214                 waitForIntResult(mSubscriberQueue, ImsUtils.TEST_TIMEOUT_MS));
6215 
6216         // Wait a second for the onSubscriberAssociatedUriChanged indication to be processed on the
6217         // main telephony thread. Although telephony extracts and stores phone number, accessing to
6218         // phone number is through the SubscriptionManager. Before calling the
6219         // SubscriptionManager#getPhoneNumber, a guard time is required for telephony.
6220         // currently no better way of knowing that telephony has processed this command.
6221         Thread.sleep(TEST_OPERATION_TIME_MS);
6222 
6223         try {
6224             automan.adoptShellPermissionIdentity();
6225             SubscriptionManager sm = (SubscriptionManager) getContext()
6226                     .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6227             String phoneNumber = sm.getPhoneNumber(sTestSub,
6228                     SubscriptionManager.PHONE_NUMBER_SOURCE_IMS);
6229 
6230             // verify Ims phone number
6231             assertEquals("447539447777", phoneNumber);
6232         } finally {
6233             automan.dropShellPermissionIdentity();
6234         }
6235 
6236         overrideCarrierConfig(null);
6237     }
6238 
6239     @Test
6240     @RequiresFlagsEnabled(
6241             Flags.FLAG_CLEAR_CACHED_IMS_PHONE_NUMBER_WHEN_DEVICE_LOST_IMS_REGISTRATION)
testClearImsPhoneNumberWithImsAssociatedUri()6242     public void testClearImsPhoneNumberWithImsAssociatedUri() throws Exception {
6243         if (!ImsUtils.shouldTestImsService()) {
6244             return;
6245         }
6246 
6247         // Bind TestImsService
6248         triggerFrameworkConnectToCarrierImsService();
6249 
6250         ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
6251                 ImsReasonInfo.CODE_UNSPECIFIED, "");
6252 
6253         // IMS is deregistered to set initial state
6254         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6255                 reasonInfo, RegistrationManager.SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NONE);
6256 
6257         // To check when framework completes its operation
6258         LinkedBlockingQueue<Integer> mSubscriberQueue = new LinkedBlockingQueue<>(1);
6259         LinkedBlockingQueue<Integer> mUnregiQueue = new LinkedBlockingQueue<>(1);
6260         RegistrationManager.RegistrationCallback callback =
6261                 new RegistrationManager.RegistrationCallback() {
6262                     @Override
6263                     public void onUnregistered(ImsReasonInfo info, int suggestedAction,
6264                             int imsRadioTech) {
6265                         if (imsRadioTech != REGISTRATION_TECH_NONE) {
6266                             mUnregiQueue.offer(imsRadioTech);
6267                         }
6268                     }
6269 
6270                     @Override
6271                     public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
6272                         mSubscriberQueue.offer(uris.length);
6273                     }
6274                 };
6275 
6276         // Register callback
6277         final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
6278         try {
6279             automan.adoptShellPermissionIdentity();
6280             android.telephony.ims.ImsManager imsManager = getContext().getSystemService(
6281                     android.telephony.ims.ImsManager.class);
6282             ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
6283             mmTelManager.registerImsRegistrationCallback(getContext().getMainExecutor(), callback);
6284         } finally {
6285             automan.dropShellPermissionIdentity();
6286         }
6287 
6288         // Trigger IMS registration
6289         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
6290                 IMS_REGI_TECH_LTE);
6291 
6292         // Trigger the associated URI has changed.
6293         Uri[] associatedUris = new Uri[] {
6294                 Uri.parse("sip:+447539447777@ims.x.com"),
6295                 Uri.parse("tel:+447539446666")
6296         };
6297         sServiceConnector.getCarrierService().getImsRegistration()
6298                 .onSubscriberAssociatedUriChanged(associatedUris);
6299 
6300         assertNotEquals(Integer.MAX_VALUE,
6301                 waitForIntResult(mSubscriberQueue, ImsUtils.TEST_TIMEOUT_MS));
6302 
6303         // Wait a second for the onSubscriberAssociatedUriChanged indication to be processed on the
6304         // main telephony thread. Although telephony extracts and stores phone number, accessing to
6305         // phone number is through the SubscriptionManager. Before calling the
6306         // SubscriptionManager#getPhoneNumber, a guard time is required for telephony.
6307         // Currently no better way of knowing that telephony has processed this command.
6308         Thread.sleep(TEST_OPERATION_TIME_MS);
6309 
6310         SubscriptionManager sm = (SubscriptionManager) getContext()
6311                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6312         try {
6313             automan.adoptShellPermissionIdentity();
6314 
6315             String phoneNumber = sm.getPhoneNumber(sTestSub,
6316                     SubscriptionManager.PHONE_NUMBER_SOURCE_IMS);
6317 
6318             // Verify Ims phone number
6319             assertEquals("+447539447777", phoneNumber);
6320         } finally {
6321             automan.dropShellPermissionIdentity();
6322         }
6323 
6324         // Trigger IMS de-registration
6325         sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
6326                 reasonInfo, RegistrationManager.SUGGESTED_ACTION_NONE, REGISTRATION_TECH_LTE);
6327 
6328         assertNotEquals(Integer.MAX_VALUE,
6329                 waitForIntResult(mUnregiQueue, ImsUtils.TEST_TIMEOUT_MS));
6330 
6331         // Wait a second for the onDeregistered indication to be processed on the
6332         // main telephony thread. Although telephony clear phone number, accessing to
6333         // phone number is through the SubscriptionManager. Before calling the
6334         // SubscriptionManager#getPhoneNumber, a guard time is required for telephony.
6335         // Currently no better way of knowing that telephony has processed this command.
6336         Thread.sleep(TEST_OPERATION_TIME_MS);
6337 
6338         try {
6339             automan.adoptShellPermissionIdentity();
6340 
6341             String phoneNumber = sm.getPhoneNumber(sTestSub,
6342                     SubscriptionManager.PHONE_NUMBER_SOURCE_IMS);
6343 
6344             // verify Ims phone number
6345             assertEquals("", phoneNumber);
6346         } finally {
6347             automan.dropShellPermissionIdentity();
6348         }
6349     }
6350 
verifyIntKey(ProvisioningManager pm, LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)6351     private void verifyIntKey(ProvisioningManager pm,
6352             LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)
6353             throws Exception {
6354         pm.setProvisioningIntValue(key, value);
6355         assertTrue(waitForParam(intQueue, new Pair<>(key, value)));
6356         assertEquals(value, pm.getProvisioningIntValue(key));
6357     }
6358 
verifyStringKey(ProvisioningManager pm, LinkedBlockingQueue<Pair<Integer, String>> strQueue, int key, String value)6359     private void verifyStringKey(ProvisioningManager pm,
6360             LinkedBlockingQueue<Pair<Integer, String>> strQueue, int key, String value)
6361             throws Exception {
6362         pm.setProvisioningStringValue(key, value);
6363         assertTrue(waitForParam(strQueue, new Pair<>(key, value)));
6364         assertEquals(value, pm.getProvisioningStringValue(key));
6365     }
6366 
setupImsServiceForSms()6367     private void setupImsServiceForSms() throws Exception {
6368         MmTelFeature.MmTelCapabilities capabilities = new MmTelFeature.MmTelCapabilities(
6369                 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS);
6370         // Set up MMTEL
6371         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
6372                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
6373                 .build()));
6374         // Wait until MMTEL is created and onFeatureReady is called
6375         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
6376                 TestImsService.LATCH_CREATE_MMTEL));
6377         assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
6378                 TestImsService.LATCH_MMTEL_READY));
6379         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
6380         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
6381                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
6382                 sTestSlot, serviceSlot);
6383         // Wait until ImsSmsDispatcher connects and calls onReady.
6384         assertTrue(sServiceConnector.getCarrierService().getMmTelFeature().getSmsImplementation()
6385                 .waitForOnReadyLatch());
6386         // Set Registered and SMS capable
6387         sServiceConnector.getCarrierService().getMmTelFeature().setCapabilities(capabilities);
6388         sServiceConnector.getCarrierService().getImsService()
6389                 .getRegistrationForSubscription(sTestSlot, sTestSub)
6390                 .onRegistered(IMS_REGI_TECH_IWLAN);
6391         sServiceConnector.getCarrierService().getMmTelFeature()
6392                 .notifyCapabilitiesStatusChanged(capabilities);
6393 
6394         // Wait a second for the notifyCapabilitiesStatusChanged indication to be processed on the
6395         // main telephony thread - currently no better way of knowing that telephony has processed
6396         // this command. SmsManager#isImsSmsSupported() is @hide and must be updated to use new API.
6397         Thread.sleep(1000);
6398     }
6399 
triggerFrameworkConnectToLocalImsServiceBindRcsFeature()6400     private void triggerFrameworkConnectToLocalImsServiceBindRcsFeature() throws Exception {
6401         // Connect to the ImsService with the RCS feature.
6402         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
6403                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
6404                 .build()));
6405         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
6406         // Framework did not call it.
6407         assertTrue("Did not receive createRcsFeature", sServiceConnector.getCarrierService()
6408                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_RCS));
6409         assertTrue("Did not receive RcsFeature#onReady", sServiceConnector.getCarrierService()
6410                 .waitForLatchCountdown(TestImsService.LATCH_RCS_READY));
6411         // Make sure the RcsFeature was created in the test service.
6412         assertNotNull("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
6413                 + "called!", sServiceConnector.getCarrierService().getRcsFeature());
6414         int serviceSlot = sServiceConnector.getCarrierService().getRcsFeature().getSlotIndex();
6415         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
6416                         + "assigned slot (" + serviceSlot + "+ for the associated RcsFeature",
6417                 sTestSlot, serviceSlot);
6418     }
6419 
triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature()6420     private void triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature() throws Exception {
6421         // Connect to the ImsService with the RCS feature.
6422         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
6423                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
6424                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
6425                 .build()));
6426 
6427         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
6428         // Framework did not call it.
6429         assertTrue("Did not receive createMmTelFeature", sServiceConnector.getCarrierService()
6430                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_MMTEL));
6431         assertTrue("Did not receive MmTelFeature#onReady", sServiceConnector.getCarrierService()
6432                 .waitForLatchCountdown(TestImsService.LATCH_MMTEL_READY));
6433         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
6434                 sServiceConnector.getCarrierService().getMmTelFeature());
6435         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
6436         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
6437                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
6438                 sTestSlot, serviceSlot);
6439 
6440         // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
6441         // Framework did not call it.
6442         assertTrue("Did not receive createRcsFeature", sServiceConnector.getCarrierService()
6443                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_RCS));
6444         assertTrue("Did not receive RcsFeature#onReady", sServiceConnector.getCarrierService()
6445                 .waitForLatchCountdown(TestImsService.LATCH_RCS_READY));
6446         // Make sure the RcsFeature was created in the test service.
6447         assertNotNull("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
6448                 + "called!", sServiceConnector.getCarrierService().getRcsFeature());
6449         assertTrue("Did not receive RcsFeature#setCapabilityExchangeEventListener",
6450                 sServiceConnector.getCarrierService().waitForLatchCountdown(
6451                         TestImsService.LATCH_UCE_LISTENER_SET));
6452         serviceSlot = sServiceConnector.getCarrierService().getRcsFeature().getSlotIndex();
6453         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
6454                         + "assigned slot (" + serviceSlot + "+ for the associated RcsFeature",
6455                 sTestSlot, serviceSlot);
6456     }
6457 
triggerFrameworkConnectToCarrierImsService()6458     private void triggerFrameworkConnectToCarrierImsService() throws Exception {
6459         // Connect to the ImsService with the MmTel feature.
6460         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
6461                 .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
6462                 .build()));
6463         // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
6464         // Framework did not call it.
6465         assertTrue("Did not receive createMmTelFeature", sServiceConnector.getCarrierService()
6466                 .waitForLatchCountdown(TestImsService.LATCH_CREATE_MMTEL));
6467         assertTrue("Did not receive MmTelFeature#onReady", sServiceConnector.getCarrierService()
6468                 .waitForLatchCountdown(TestImsService.LATCH_MMTEL_READY));
6469         assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
6470                 sServiceConnector.getCarrierService().getMmTelFeature());
6471         int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
6472         assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
6473                         + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
6474                 sTestSlot, serviceSlot);
6475     }
6476 
buildImsStateCallback(final LinkedBlockingQueue<Integer> stateQueue)6477     private ImsStateCallback buildImsStateCallback(final LinkedBlockingQueue<Integer> stateQueue) {
6478         return new ImsStateCallback() {
6479             @Override
6480             public void onUnavailable(int reason) {
6481                 stateQueue.offer(reason);
6482             }
6483 
6484             @Override
6485             public void onAvailable() {
6486                 stateQueue.offer(FEATURE_STATE_READY);
6487             }
6488 
6489             @Override
6490             public void onError() {
6491                 stateQueue.offer(-1);
6492             }
6493         };
6494     }
6495 
6496     private ProvisioningManager.RcsProvisioningCallback buildRcsProvisioningCallback(
6497             LinkedBlockingQueue<Integer> actionQueue,
6498             LinkedBlockingQueue<RcsProvisioningCallbackParams> paramQueue) {
6499         return new ProvisioningManager.RcsProvisioningCallback() {
6500             @Override
6501             public void onConfigurationChanged(byte[] configXml) {
6502                 super.onConfigurationChanged(configXml);
6503                 actionQueue.offer(RCS_CONFIG_CB_CHANGED);
6504                 if (paramQueue != null) {
6505                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
6506                     params.mConfig = configXml;
6507                     paramQueue.offer(params);
6508                 }
6509             }
6510 
6511             @Override
6512             public void onAutoConfigurationErrorReceived(int code, String str) {
6513                 super.onAutoConfigurationErrorReceived(code, str);
6514                 actionQueue.offer(RCS_CONFIG_CB_ERROR);
6515                 if (paramQueue != null) {
6516                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
6517                     params.mErrorCode = code;
6518                     params.mErrorString = str;
6519                     paramQueue.offer(params);
6520                 }
6521             }
6522 
6523             @Override
6524             public void onConfigurationReset() {
6525                 super.onConfigurationReset();
6526                 actionQueue.offer(RCS_CONFIG_CB_RESET);
6527             }
6528 
6529             @Override
6530             public void onRemoved() {
6531                 super.onRemoved();
6532                 actionQueue.offer(RCS_CONFIG_CB_DELETE);
6533             }
6534 
6535             @Override
6536             public void onPreProvisioningReceived(byte[] configXml) {
6537                 super.onPreProvisioningReceived(configXml);
6538                 actionQueue.offer(RCS_CONFIG_CB_PREPROV);
6539                 if (paramQueue != null) {
6540                     RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
6541                     params.mConfig = configXml;
6542                     paramQueue.offer(params);
6543                 }
6544             }
6545         };
6546     }
6547     // Waiting for ImsRcsManager to become public before implementing RegistrationManager,
6548     // Duplicate these methods for now.
6549     private void verifyRegistrationState(ImsRcsManager regManager, int expectedState)
6550             throws Exception {
6551         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
6552         assertTrue(ImsUtils.retryUntilTrue(() -> {
6553             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
6554                     (m) -> m.getRegistrationState(getContext().getMainExecutor(), mQueue::offer),
6555                     "android.permission.READ_PRECISE_PHONE_STATE");
6556             return waitForIntResult(mQueue) == expectedState;
6557         }));
6558     }
6559 
6560     // Waiting for ImsRcsManager to become public before implementing RegistrationManager,
6561     // Duplicate these methods for now.
6562     private void verifyRegistrationTransportType(ImsRcsManager regManager,
6563             int expectedTransportType) throws Exception {
6564         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
6565         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
6566                 (m) -> m.getRegistrationTransportType(getContext().getMainExecutor(),
6567                         mQueue::offer),
6568                 "android.permission.READ_PRECISE_PHONE_STATE");
6569         assertEquals(expectedTransportType, waitForIntResult(mQueue));
6570     }
6571 
6572     private void verifyRegistrationState(RegistrationManager regManager, int expectedState)
6573             throws Exception {
6574         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
6575         assertTrue(ImsUtils.retryUntilTrue(() -> {
6576             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
6577                     (m) -> m.getRegistrationState(getContext().getMainExecutor(), mQueue::offer));
6578             return waitForIntResult(mQueue) == expectedState;
6579         }));
6580     }
6581 
6582     private void verifyRegistrationTransportType(RegistrationManager regManager,
6583             int expectedTransportType) throws Exception {
6584         LinkedBlockingQueue<Integer> mQueue = new LinkedBlockingQueue<>();
6585         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(regManager,
6586                 (m) -> m.getRegistrationTransportType(getContext().getMainExecutor(),
6587                         mQueue::offer));
6588         assertEquals(expectedTransportType, waitForIntResult(mQueue));
6589     }
6590 
6591     private void verifyRegistering(int tech, ArraySet<String> featureTags,
6592             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
6593             int expectedAttrFlags) throws Exception {
6594         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
6595                 .setFeatureTags(featureTags).build();
6596         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(attr);
6597         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
6598         assertNotNull(attrResult);
6599         assertEquals(tech, attrResult.getRegistrationTechnology());
6600         assertEquals(expectedTransport, attrResult.getTransportType());
6601         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
6602         assertEquals(featureTags, attrResult.getFeatureTags());
6603     }
6604 
6605     private void verifyRegistered(int tech, ArraySet<String> featureTags,
6606             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
6607             int expectedAttrFlags) throws Exception {
6608         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
6609                 .setFeatureTags(featureTags).build();
6610         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
6611         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
6612         assertNotNull(attrResult);
6613         assertEquals(tech, attrResult.getRegistrationTechnology());
6614         assertEquals(expectedTransport, attrResult.getTransportType());
6615         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
6616         assertEquals(featureTags, attrResult.getFeatureTags());
6617     }
6618     private void verifyEmergencyRegistering(int tech, ArraySet<String> featureTags,
6619             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
6620             int expectedAttrFlags) throws Exception {
6621         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
6622                     .setFeatureTags(featureTags).setFlagRegistrationTypeEmergency().build();
6623         sServiceConnector.getCarrierService().getImsRegistration().onRegistering(attr);
6624         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
6625         assertNotNull(attrResult);
6626         assertEquals(tech, attrResult.getRegistrationTechnology());
6627         assertEquals(expectedTransport, attrResult.getTransportType());
6628         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
6629         assertEquals(featureTags, attrResult.getFeatureTags());
6630     }
6631 
6632     private void verifyEmergencyRegistered(int tech, ArraySet<String> featureTags,
6633             LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
6634             int expectedAttrFlags) throws Exception {
6635         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
6636                     .setFeatureTags(featureTags).setFlagRegistrationTypeEmergency().build();
6637         sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
6638         ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
6639         assertNotNull(attrResult);
6640         assertEquals(tech, attrResult.getRegistrationTechnology());
6641         assertEquals(expectedTransport, attrResult.getTransportType());
6642         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
6643         assertEquals(featureTags, attrResult.getFeatureTags());
6644     }
6645 
6646     private <T> boolean waitForParam(LinkedBlockingQueue<T> queue, T waitParam) throws Exception {
6647         T result;
6648         while ((result = waitForResult(queue)) != null) {
6649             if (waitParam.equals(result)) {
6650                 return true;
6651             }
6652         }
6653         return false;
6654     }
6655 
6656     private <T> T waitForResult(LinkedBlockingQueue<T> queue) throws Exception {
6657         return queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
6658     }
6659 
6660     private int waitForIntResult(LinkedBlockingQueue<Integer> queue) throws Exception {
6661         Integer result = queue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
6662         return result != null ? result : Integer.MAX_VALUE;
6663     }
6664 
6665     private int waitForIntResult(LinkedBlockingQueue<Integer> queue, int timeout)
6666             throws Exception {
6667         Integer result = queue.poll(timeout, TimeUnit.MILLISECONDS);
6668         return result != null ? result : Integer.MAX_VALUE;
6669     }
6670 
6671     private static void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
6672         CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getInstrumentation()
6673                 .getContext().getSystemService(CarrierConfigManager.class);
6674         sReceiver.clearQueue();
6675         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(carrierConfigManager,
6676                 (m) -> m.overrideConfig(sTestSub, bundle));
6677         sReceiver.waitForChanged();
6678     }
6679 
6680     private static Context getContext() {
6681         return InstrumentationRegistry.getInstrumentation().getContext();
6682     }
6683 
6684     // Copied from com.android.internal.util.HexDump
6685     private static byte[] hexStringToByteArray(String hexString) {
6686         int length = hexString.length();
6687         byte[] buffer = new byte[length / 2];
6688 
6689         for (int i = 0; i < length; i += 2) {
6690             buffer[i / 2] =
6691                     (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
6692         }
6693 
6694         return buffer;
6695     }
6696 
6697     // Copied from com.android.internal.util.HexDump
6698     private static int toByte(char c) {
6699         if (c >= '0' && c <= '9') return (c - '0');
6700         if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
6701         if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
6702 
6703         throw new RuntimeException("Invalid hex char '" + c + "'");
6704     }
6705 
6706     private boolean isExpectedSubId(HashSet<Integer> subIDs) {
6707         return (subIDs.size() == 1) && subIDs.contains(sTestSub);
6708     }
6709 }
6710