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