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