1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.phone;
18 
19 import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
20 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED;
21 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
22 
23 import static junit.framework.Assert.assertEquals;
24 import static junit.framework.Assert.assertFalse;
25 import static junit.framework.Assert.assertNull;
26 import static junit.framework.Assert.assertTrue;
27 
28 import static org.mockito.Matchers.any;
29 import static org.mockito.Matchers.anyBoolean;
30 import static org.mockito.Matchers.anyInt;
31 import static org.mockito.Matchers.eq;
32 import static org.mockito.Mockito.atLeastOnce;
33 import static org.mockito.Mockito.doAnswer;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.times;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
38 
39 import android.app.role.OnRoleHoldersChangedListener;
40 import android.app.role.RoleManager;
41 import android.content.BroadcastReceiver;
42 import android.content.ContentValues;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.pm.PackageManager;
46 import android.content.res.Resources;
47 import android.database.Cursor;
48 import android.net.Uri;
49 import android.os.Handler;
50 import android.os.HandlerThread;
51 import android.os.Looper;
52 import android.os.PersistableBundle;
53 import android.os.UserHandle;
54 import android.provider.Telephony.SimInfo;
55 import android.telephony.CarrierConfigManager;
56 import android.telephony.SubscriptionManager;
57 import android.telephony.TelephonyRegistryManager;
58 import android.telephony.ims.ProvisioningManager;
59 import android.telephony.ims.RcsConfig;
60 import android.telephony.ims.aidl.IImsConfig;
61 import android.telephony.ims.aidl.IRcsConfigCallback;
62 import android.test.mock.MockContentProvider;
63 import android.test.mock.MockContentResolver;
64 import android.testing.TestableLooper;
65 import android.util.Log;
66 
67 import androidx.test.filters.SmallTest;
68 
69 import com.android.ims.FeatureConnector;
70 import com.android.ims.RcsFeatureManager;
71 import com.android.internal.telephony.ITelephony;
72 import com.android.internal.telephony.metrics.RcsStats;
73 
74 import org.junit.After;
75 import org.junit.Before;
76 import org.junit.Test;
77 import org.mockito.ArgumentCaptor;
78 import org.mockito.Captor;
79 import org.mockito.Mock;
80 import org.mockito.MockitoAnnotations;
81 import org.mockito.invocation.InvocationOnMock;
82 import org.mockito.stubbing.Answer;
83 
84 import java.util.ArrayList;
85 import java.util.Arrays;
86 import java.util.List;
87 import java.util.concurrent.Executor;
88 
89 /**
90  * Unit tests for RcsProvisioningMonitor
91  */
92 public class RcsProvisioningMonitorTest {
93     private static final String TAG = "RcsProvisioningMonitorTest";
94     private static final String CONFIG_DEFAULT = "<?xml version=\"1.0\"?>\n"
95             + "<wap-provisioningdoc version=\"1.1\">\n"
96             + "\t<characteristic type=\"APPLICATION\">\n"
97             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
98             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
99             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
100             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
101             + "\t\t\t<characteristic type=\"Ext\">\n"
102             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
103             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
104             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"1\"/>\n"
105             + "\t\t\t\t</characteristic>\n"
106             + "\t\t\t</characteristic>\n"
107             + "\t\t</characteristic>\n"
108             + "\t\t<characteristic type=\"SERVICES\">\n"
109             + "\t\t\t<parm name=\"SupportedRCSProfileVersions\" value=\"UP2.3\"/>\n"
110             + "\t\t\t<parm name=\"ChatAuth\" value=\"1\"/>\n"
111             + "\t\t\t<parm name=\"GroupChatAuth\" value=\"1\"/>\n"
112             + "\t\t\t<parm name=\"ftAuth\" value=\"1\"/>\n"
113             + "\t\t\t<parm name=\"standaloneMsgAuth\" value=\"1\"/>\n"
114             + "\t\t\t<parm name=\"geolocPushAuth\" value=\"1\"/>\n"
115             + "\t\t\t<characteristic type=\"Ext\">\n"
116             + "\t\t\t\t<characteristic type=\"DataOff\">\n"
117             + "\t\t\t\t\t<parm name=\"rcsMessagingDataOff\" value=\"1\"/>\n"
118             + "\t\t\t\t\t<parm name=\"fileTransferDataOff\" value=\"1\"/>\n"
119             + "\t\t\t\t\t<parm name=\"mmsDataOff\" value=\"1\"/>\n"
120             + "\t\t\t\t\t<parm name=\"syncDataOff\" value=\"1\"/>\n"
121             + "\t\t\t\t\t<characteristic type=\"Ext\"/>\n"
122             + "\t\t\t\t</characteristic>\n"
123             + "\t\t\t</characteristic>\n"
124             + "\t\t</characteristic>\n"
125             + "\t</characteristic>\n"
126             + "</wap-provisioningdoc>\n";
127 
128     private static final String CONFIG_SINGLE_REGISTRATION_DISABLED = "<?xml version=\"1.0\"?>\n"
129             + "<wap-provisioningdoc version=\"1.1\">\n"
130             + "\t<characteristic type=\"APPLICATION\">\n"
131             + "\t\t<parm name=\"AppID\" value=\"urn:oma:mo:ext-3gpp-ims:1.0\"/>\n"
132             + "\t\t<characteristic type=\"3GPP_IMS\">\n"
133             + "\t\t\t<parm name=\"AppID\" value=\"ap2001\"/>\n"
134             + "\t\t\t<parm name=\"Name\" value=\"RCS IMS Settings\"/>\n"
135             + "\t\t\t<characteristic type=\"Ext\">\n"
136             + "\t\t\t\t<characteristic type=\"GSMA\">\n"
137             + "\t\t\t\t\t<parm name=\"AppRef\" value=\"IMS-Setting\"/>\n"
138             + "\t\t\t\t\t<parm name=\"rcsVolteSingleRegistration\" value=\"0\"/>\n"
139             + "\t\t\t\t</characteristic>\n"
140             + "\t\t\t</characteristic>\n"
141             + "\t\t</characteristic>\n"
142             + "\t</characteristic>\n"
143             + "</wap-provisioningdoc>\n";
144     private static final int FAKE_SUB_ID_BASE = 0x0FFFFFF0;
145     private static final String DEFAULT_MESSAGING_APP1 = "DMA1";
146     private static final String DEFAULT_MESSAGING_APP2 = "DMA2";
147 
148     private RcsProvisioningMonitor mRcsProvisioningMonitor;
149     private Handler mHandler;
150     private HandlerThread mHandlerThread;
151     private TestableLooper mLooper;
152     private PersistableBundle mBundle;
153     private MockContentResolver mContentResolver = new MockContentResolver();
154     private SimInfoContentProvider mProvider;
155     private BroadcastReceiver mReceiver;
156     private static final int TEST_SUB_ID = 1;
157     @Mock
158     private Cursor mCursor;
159     @Mock
160     private SubscriptionManager mSubscriptionManager;
161     private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener;
162     @Mock
163     private TelephonyRegistryManager mTelephonyRegistryManager;
164     @Mock
165     private CarrierConfigManager mCarrierConfigManager;
166     private OnRoleHoldersChangedListener mRoleHolderChangedListener;
167     @Mock
168     private RcsProvisioningMonitor.RoleManagerAdapter mRoleManager;
169     @Mock
170     private ITelephony.Stub mITelephony;
171     @Mock
172     private RcsFeatureManager mFeatureManager;
173     @Mock
174     private RcsProvisioningMonitor.FeatureConnectorFactory<RcsFeatureManager> mFeatureFactory;
175     @Mock
176     private FeatureConnector<RcsFeatureManager> mFeatureConnector;
177     @Captor
178     ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mConnectorListener;
179     @Mock
180     private IImsConfig.Stub mIImsConfig;
181     @Mock
182     private Resources mResources;
183     @Mock
184     private PhoneGlobals mPhone;
185     @Mock
186     private IRcsConfigCallback mCallback;
187     @Mock
188     private PackageManager mPackageManager;
189     @Mock
190     private RcsStats mRcsStats;
191     @Mock
192     private RcsStats.RcsProvisioningCallback mRcsProvisioningCallback;
193 
194     private Executor mExecutor = new Executor() {
195         @Override
196         public void execute(Runnable r) {
197             r.run();
198         }
199     };
200 
201     private class SimInfoContentProvider extends MockContentProvider {
202         private Cursor mCursor;
203         private ContentValues mValues;
204 
SimInfoContentProvider(Context context)205         SimInfoContentProvider(Context context) {
206             super(context);
207         }
208 
setCursor(Cursor cursor)209         public void setCursor(Cursor cursor) {
210             mCursor = cursor;
211         }
212 
213         @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)214         public Cursor query(Uri uri, String[] projection, String selection,
215                 String[] selectionArgs, String sortOrder) {
216             return mCursor;
217         }
218 
219         @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)220         public int update(Uri uri, ContentValues values,
221                 String selection, String[] selectionArgs) {
222             mValues = values;
223             return 1;
224         }
225 
getContentValues()226         ContentValues getContentValues() {
227             return mValues;
228         }
229     }
230 
231     @Before
setUp()232     public void setUp() throws Exception {
233         MockitoAnnotations.initMocks(this);
234 
235         when(mPhone.getResources()).thenReturn(mResources);
236         when(mPhone.getPackageManager()).thenReturn(mPackageManager);
237         when(mPackageManager.hasSystemFeature(
238                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
239         when(mPhone.getMainExecutor()).thenReturn(mExecutor);
240         when(mPhone.getSystemServiceName(eq(CarrierConfigManager.class)))
241                 .thenReturn(Context.CARRIER_CONFIG_SERVICE);
242         when(mPhone.getSystemServiceName(eq(SubscriptionManager.class)))
243                 .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
244         when(mPhone.getSystemServiceName(eq(TelephonyRegistryManager.class)))
245                 .thenReturn(Context.TELEPHONY_REGISTRY_SERVICE);
246         when(mPhone.getSystemServiceName(eq(RoleManager.class)))
247                 .thenReturn(Context.ROLE_SERVICE);
248         when(mPhone.getSystemService(eq(Context.CARRIER_CONFIG_SERVICE)))
249                 .thenReturn(mCarrierConfigManager);
250         when(mPhone.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
251                 .thenReturn(mSubscriptionManager);
252         when(mPhone.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE)))
253                 .thenReturn(mTelephonyRegistryManager);
254 
255         mBundle = new PersistableBundle();
256         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
257 
258         doAnswer(new Answer<Void>() {
259             @Override
260             public Void answer(InvocationOnMock invocation) throws Throwable {
261                 mReceiver = (BroadcastReceiver) invocation.getArguments()[0];
262                 return null;
263             }
264         }).when(mPhone).registerReceiver(any(BroadcastReceiver.class), any());
265 
266         doAnswer(new Answer<Void>() {
267             @Override
268             public Void answer(InvocationOnMock invocation) throws Throwable {
269                 mSubChangedListener = (SubscriptionManager.OnSubscriptionsChangedListener)
270                         invocation.getArguments()[0];
271                 return null;
272             }
273         }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(
274                 any(SubscriptionManager.OnSubscriptionsChangedListener.class),
275                 any());
276 
277         doAnswer(new Answer<Void>() {
278             @Override
279             public Void answer(InvocationOnMock invocation) throws Throwable {
280                 mRoleHolderChangedListener = (OnRoleHoldersChangedListener)
281                         invocation.getArguments()[1];
282                 return null;
283             }
284         }).when(mRoleManager).addOnRoleHoldersChangedListenerAsUser(any(Executor.class),
285                 any(OnRoleHoldersChangedListener.class), any(UserHandle.class));
286         List<String> dmas = new ArrayList<>();
287         dmas.add(DEFAULT_MESSAGING_APP1);
288         when(mRoleManager.getRoleHolders(eq(RoleManager.ROLE_SMS))).thenReturn(dmas);
289 
290         mProvider = new SimInfoContentProvider(mPhone);
291         mProvider.setCursor(mCursor);
292         mContentResolver.addProvider(SimInfo.CONTENT_URI.getAuthority(), mProvider);
293         when(mPhone.getContentResolver()).thenReturn(mContentResolver);
294         when(mCursor.moveToFirst()).thenReturn(true);
295         when(mCursor.getColumnIndexOrThrow(any())).thenReturn(1);
296         when(mCursor.getBlob(anyInt())).thenReturn(
297                 RcsConfig.compressGzip(CONFIG_DEFAULT.getBytes()));
298 
299         mHandlerThread = new HandlerThread("RcsProvisioningMonitorTest");
300         mHandlerThread.start();
301     }
302 
303     @After
tearDown()304     public void tearDown() throws Exception {
305         if (mRcsProvisioningMonitor != null) {
306             mRcsProvisioningMonitor.destroy();
307             mRcsProvisioningMonitor = null;
308         }
309 
310         if (mLooper != null) {
311             mLooper.destroy();
312             mLooper = null;
313         }
314     }
315 
316     @Test
317     @SmallTest
testInitWithSavedConfig()318     public void testInitWithSavedConfig() throws Exception {
319         createMonitor(3);
320 
321         for (int i = 0; i < 3; i++) {
322             assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(),
323                     mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i)));
324         }
325 
326         verify(mIImsConfig, times(3)).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
327     }
328 
329     @Test
330     @SmallTest
testInitWithoutSavedConfig()331     public void testInitWithoutSavedConfig() throws Exception {
332         when(mCursor.getBlob(anyInt())).thenReturn(null);
333         createMonitor(3);
334 
335         //Should not notify null config
336         verify(mIImsConfig, never()).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
337     }
338 
339     @Test
340     @SmallTest
testSubInfoChanged()341     public void testSubInfoChanged() throws Exception {
342         createMonitor(3);
343 
344         for (int i = 0; i < 3; i++) {
345             assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(),
346                     mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i)));
347         }
348 
349         verify(mIImsConfig, times(3)).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
350 
351         makeFakeActiveSubIds(1);
352         mExecutor.execute(() -> mSubChangedListener.onSubscriptionsChanged());
353         processAllMessages();
354 
355         for (int i = 1; i < 3; i++) {
356             assertNull(mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i));
357         }
358         verify(mIImsConfig, times(2)).notifyRcsAutoConfigurationRemoved();
359     }
360 
361     @Test
362     @SmallTest
testDefaultMessagingApplicationChangedWithAcs()363     public void testDefaultMessagingApplicationChangedWithAcs() throws Exception {
364         createMonitor(1);
365         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
366         mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
367         processAllMessages();
368         byte[] configCached = mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE);
369 
370         assertNull(configCached);
371         assertNull(mProvider.getContentValues().get(SimInfo.COLUMN_RCS_CONFIG));
372         verify(mIImsConfig, atLeastOnce()).notifyRcsAutoConfigurationRemoved();
373         verify(mIImsConfig, atLeastOnce()).triggerRcsReconfiguration();
374         // The api should only be called when monitor is initilized.
375         verify(mIImsConfig, times(1))
376                 .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
377     }
378 
379     @Test
380     @SmallTest
testDefaultMessagingApplicationChangedWithoutAcs()381     public void testDefaultMessagingApplicationChangedWithoutAcs() throws Exception {
382         createMonitor(1);
383         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
384         mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
385         processAllMessages();
386         byte[] configCached = mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE);
387 
388         assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(), configCached));
389         verify(mIImsConfig, times(1)).notifyRcsAutoConfigurationRemoved();
390         // The api should be called 2 times, one happens when monitor is initilized,
391         // Another happens when DMS is changed.
392         verify(mIImsConfig, times(2))
393                 .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
394     }
395 
396     @Test
397     @SmallTest
testCarrierConfigChanged()398     public void testCarrierConfigChanged() throws Exception {
399         createMonitor(1);
400         // should not broadcast message if carrier config is not ready
401         verify(mPhone, never()).sendBroadcast(any(), any());
402 
403         when(mPackageManager.hasSystemFeature(
404                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
405         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
406         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
407         mBundle.putBoolean(
408                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
409 
410         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
411         processAllMessages();
412 
413         verify(mPhone, times(1)).sendBroadcast(captorIntent.capture(), any());
414         Intent capturedIntent = captorIntent.getValue();
415         assertEquals(capturedIntent.getAction(),
416                 ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
417         assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
418                 ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
419         assertEquals(ProvisioningManager.STATUS_CAPABLE,
420                 capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
421 
422         mBundle.putBoolean(
423                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
424         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
425         processAllMessages();
426 
427         verify(mPhone, times(2)).sendBroadcast(captorIntent.capture(), any());
428         capturedIntent = captorIntent.getValue();
429         assertEquals(capturedIntent.getAction(),
430                 ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
431         assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
432                 ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
433         assertEquals(ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE,
434                 capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
435 
436 
437         when(mPackageManager.hasSystemFeature(
438                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(false);
439         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
440         processAllMessages();
441 
442         verify(mPhone, times(3)).sendBroadcast(captorIntent.capture(), any());
443         capturedIntent = captorIntent.getValue();
444         assertEquals(capturedIntent.getAction(),
445                 ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
446         assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
447                 ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
448         assertEquals(ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE
449                 | ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE,
450                 capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
451     }
452 
453     @Test
454     @SmallTest
testUpdateConfig()455     public void testUpdateConfig() throws Exception {
456         createMonitor(1);
457         final ArgumentCaptor<byte[]> argumentBytes = ArgumentCaptor.forClass(byte[].class);
458 
459         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
460         processAllMessages();
461 
462         verify(mIImsConfig, atLeastOnce()).notifyRcsAutoConfigurationReceived(
463                 argumentBytes.capture(), eq(false));
464         assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(), argumentBytes.getValue()));
465     }
466 
467     @Test
468     @SmallTest
testRequestReconfig()469     public void testRequestReconfig() throws Exception {
470         createMonitor(1);
471 
472         mRcsProvisioningMonitor.requestReconfig(FAKE_SUB_ID_BASE);
473         processAllMessages();
474 
475         verify(mIImsConfig, times(1)).notifyRcsAutoConfigurationRemoved();
476         verify(mIImsConfig, times(1)).triggerRcsReconfiguration();
477     }
478 
479     @Test
480     @SmallTest
testIsRcsVolteSingleRegistrationEnabled()481     public void testIsRcsVolteSingleRegistrationEnabled() throws Exception {
482         createMonitor(1);
483 
484         when(mPackageManager.hasSystemFeature(
485                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(false);
486         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
487         mBundle.putBoolean(
488                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
489         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
490         processAllMessages();
491         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
492 
493         when(mPackageManager.hasSystemFeature(
494                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
495         mBundle.putBoolean(
496                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
497         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
498         processAllMessages();
499         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
500 
501 
502         when(mPackageManager.hasSystemFeature(
503                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(false);
504         mBundle.putBoolean(
505                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
506         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
507         processAllMessages();
508         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
509 
510         when(mPackageManager.hasSystemFeature(
511                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
512         mBundle.putBoolean(
513                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
514         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
515         processAllMessages();
516         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
517 
518         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, null, false);
519         processAllMessages();
520         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
521 
522         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
523         processAllMessages();
524         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
525 
526         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE,
527                 CONFIG_SINGLE_REGISTRATION_DISABLED.getBytes(), false);
528         processAllMessages();
529         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
530 
531         assertNull(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(
532                 FAKE_SUB_ID_BASE + 1));
533     }
534 
535     @Test
536     @SmallTest
testRegisterThenUnregisterCallback()537     public void testRegisterThenUnregisterCallback() throws Exception {
538         createMonitor(1);
539 
540         boolean result = mRcsProvisioningMonitor.registerRcsProvisioningCallback(
541                 FAKE_SUB_ID_BASE, mCallback);
542 
543         assertTrue(result);
544         verify(mIImsConfig, times(1)).addRcsConfigCallback(eq(mCallback));
545 
546         result = mRcsProvisioningMonitor.unregisterRcsProvisioningCallback(
547                 FAKE_SUB_ID_BASE, mCallback);
548 
549         assertTrue(result);
550         verify(mIImsConfig, times(1)).removeRcsConfigCallback(eq(mCallback));
551         verify(mCallback, times(1)).onRemoved();
552     }
553 
554     @Test
555     @SmallTest
testCallbackRemovedWhenSubInfoChanged()556     public void testCallbackRemovedWhenSubInfoChanged() throws Exception {
557         createMonitor(1);
558 
559         boolean result = mRcsProvisioningMonitor.registerRcsProvisioningCallback(
560                 FAKE_SUB_ID_BASE, mCallback);
561         makeFakeActiveSubIds(0);
562         mExecutor.execute(() -> mSubChangedListener.onSubscriptionsChanged());
563         processAllMessages();
564 
565         assertTrue(result);
566         verify(mIImsConfig, times(1)).removeRcsConfigCallback(eq(mCallback));
567         verify(mCallback, times(1)).onRemoved();
568     }
569 
570     @Test
571     @SmallTest
testCallbackRemovedWhenDmaChanged()572     public void testCallbackRemovedWhenDmaChanged() throws Exception {
573         createMonitor(1);
574 
575         boolean result = mRcsProvisioningMonitor.registerRcsProvisioningCallback(
576                 FAKE_SUB_ID_BASE, mCallback);
577         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
578         processAllMessages();
579 
580         assertTrue(result);
581         verify(mIImsConfig, times(1)).removeRcsConfigCallback(eq(mCallback));
582         verify(mCallback, times(1)).onRemoved();
583     }
584 
585     @Test
586     @SmallTest
testSendBroadcastWhenDmaChanged()587     public void testSendBroadcastWhenDmaChanged() throws Exception {
588         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
589         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
590         createMonitor(1);
591         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
592         processAllMessages();
593 
594         // should not broadcast message as no carrier config change happens
595         verify(mPhone, never()).sendBroadcast(any(), any());
596 
597         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
598         when(mPackageManager.hasSystemFeature(
599                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
600         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
601         mBundle.putBoolean(
602                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
603 
604         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
605         processAllMessages();
606 
607         verify(mPhone, times(1)).sendBroadcast(captorIntent.capture(), any());
608         Intent capturedIntent = captorIntent.getValue();
609         assertEquals(capturedIntent.getAction(),
610                 ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
611 
612         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP1);
613         processAllMessages();
614 
615         // should broadcast message when default messaging application changed if carrier config
616         // has been loaded
617         verify(mPhone, times(2)).sendBroadcast(captorIntent.capture(), any());
618         capturedIntent = captorIntent.getValue();
619         assertEquals(capturedIntent.getAction(),
620                 ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
621     }
622 
623     @Test
624     @SmallTest
testRcsConnectedAndDisconnected()625     public void testRcsConnectedAndDisconnected() throws Exception {
626         createMonitor(1);
627         mRcsProvisioningMonitor.registerRcsProvisioningCallback(
628                 FAKE_SUB_ID_BASE, mCallback);
629 
630         verify(mIImsConfig, times(1))
631                 .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
632 
633         mConnectorListener.getValue().connectionUnavailable(0);
634 
635         verify(mCallback, times(1)).onRemoved();
636     }
637 
638     @Test
639     @SmallTest
testOverrideDeviceSingleRegistrationEnabled()640     public void testOverrideDeviceSingleRegistrationEnabled() throws Exception {
641         createMonitor(1);
642 
643         when(mPackageManager.hasSystemFeature(
644                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
645         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
646         mBundle.putBoolean(
647                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
648         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
649         processAllMessages();
650         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
651 
652         mRcsProvisioningMonitor.overrideDeviceSingleRegistrationEnabled(false);
653         processAllMessages();
654         assertFalse(mRcsProvisioningMonitor.getDeviceSingleRegistrationEnabled());
655         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
656 
657         mRcsProvisioningMonitor.overrideDeviceSingleRegistrationEnabled(null);
658         processAllMessages();
659         assertTrue(mRcsProvisioningMonitor.getDeviceSingleRegistrationEnabled());
660         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
661 
662         when(mPackageManager.hasSystemFeature(
663                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(false);
664         //use carrier config change to refresh the value as system feature is static
665         mBundle.putBoolean(
666                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
667         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
668         processAllMessages();
669 
670         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
671 
672         mRcsProvisioningMonitor.overrideDeviceSingleRegistrationEnabled(true);
673         processAllMessages();
674         assertTrue(mRcsProvisioningMonitor.getDeviceSingleRegistrationEnabled());
675         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
676 
677         mRcsProvisioningMonitor.overrideDeviceSingleRegistrationEnabled(null);
678         processAllMessages();
679         assertFalse(mRcsProvisioningMonitor.getDeviceSingleRegistrationEnabled());
680         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
681     }
682 
683     @Test
684     @SmallTest
testTestModeEnabledAndDisabled()685     public void testTestModeEnabledAndDisabled() throws Exception {
686         when(mCursor.getBlob(anyInt())).thenReturn(null);
687         createMonitor(1);
688 
689         verify(mCursor, times(1)).getBlob(anyInt());
690 
691         mRcsProvisioningMonitor.setTestModeEnabled(true);
692         processAllMessages();
693 
694         //should not query db in test mode
695         verify(mCursor, times(1)).getBlob(anyInt());
696         assertNull(mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE));
697 
698         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
699         processAllMessages();
700 
701         //config cahced in monitor should be updated, but db should not
702         assertNull(mProvider.getContentValues());
703         assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(),
704                 mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE)));
705 
706         //verify if monitor goes back to normal mode
707         mRcsProvisioningMonitor.setTestModeEnabled(false);
708         processAllMessages();
709 
710         verify(mCursor, times(2)).getBlob(anyInt());
711         assertNull(mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE));
712 
713         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
714         processAllMessages();
715 
716         assertTrue(Arrays.equals(CONFIG_DEFAULT.getBytes(),
717                 mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE)));
718         assertTrue(Arrays.equals(RcsConfig.compressGzip(CONFIG_DEFAULT.getBytes()),
719                 (byte[]) mProvider.getContentValues().get(SimInfo.COLUMN_RCS_CONFIG)));
720     }
721 
722     @Test
723     @SmallTest
testOverrideCarrierSingleRegistrationEnabled()724     public void testOverrideCarrierSingleRegistrationEnabled() throws Exception {
725         createMonitor(1);
726 
727         when(mPackageManager.hasSystemFeature(
728                 eq(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION))).thenReturn(true);
729         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
730         mBundle.putBoolean(
731                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
732         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
733         processAllMessages();
734         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
735 
736         mRcsProvisioningMonitor
737                 .overrideCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE, false);
738         processAllMessages();
739         assertFalse(mRcsProvisioningMonitor.getCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
740         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
741 
742         mRcsProvisioningMonitor
743                 .overrideCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE, null);
744         processAllMessages();
745         assertTrue(mRcsProvisioningMonitor.getCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
746         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
747 
748         mBundle.putBoolean(
749                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
750         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
751         processAllMessages();
752         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
753 
754         mRcsProvisioningMonitor
755                 .overrideCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE, true);
756         processAllMessages();
757         assertTrue(mRcsProvisioningMonitor.getCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
758         assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
759 
760         mRcsProvisioningMonitor
761                 .overrideCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE, null);
762         processAllMessages();
763         assertFalse(mRcsProvisioningMonitor.getCarrierSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
764         assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
765     }
766 
767     @Test
768     @SmallTest
testOverrideImsFeatureValidation()769     public void testOverrideImsFeatureValidation() throws Exception {
770         createMonitor(1);
771 
772         mRcsProvisioningMonitor.overrideImsFeatureValidation(FAKE_SUB_ID_BASE, false);
773         assertFalse(mRcsProvisioningMonitor.getImsFeatureValidationOverride(FAKE_SUB_ID_BASE));
774 
775         mRcsProvisioningMonitor.overrideImsFeatureValidation(FAKE_SUB_ID_BASE, true);
776         assertTrue(mRcsProvisioningMonitor.getImsFeatureValidationOverride(FAKE_SUB_ID_BASE));
777 
778         mRcsProvisioningMonitor.overrideImsFeatureValidation(FAKE_SUB_ID_BASE, null);
779         assertNull(mRcsProvisioningMonitor.getImsFeatureValidationOverride(FAKE_SUB_ID_BASE));
780     }
781 
782     @Test
783     @SmallTest
testMetricsAcsNotUsed()784     public void testMetricsAcsNotUsed() throws Exception {
785         createMonitor(1);
786 
787         // Not used ACS
788         mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
789         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
790         processAllMessages();
791         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
792         processAllMessages();
793         verify(mRcsStats, never()).onRcsAcsProvisioningStats(anyInt(), anyInt(),
794                 anyInt(), anyBoolean());
795     }
796 
797     @Test
798     @SmallTest
testMetricsAcsUsed()799     public void testMetricsAcsUsed() throws Exception {
800         when(mRcsStats.getRcsProvisioningCallback(anyInt(), anyBoolean()))
801                 .thenReturn(mRcsProvisioningCallback);
802         createMonitor(1);
803 
804         verify(mIImsConfig, times(1))
805                 .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
806         // verify RcsStats.getRcsProvisioningCallback() is called
807         verify(mRcsStats, times(1)).getRcsProvisioningCallback(
808                 eq(FAKE_SUB_ID_BASE), anyBoolean());
809         // verify registered callback obj which comes from RcsStats.getRcsProvisioningCallback()
810         verify(mIImsConfig, times(1))
811                 .addRcsConfigCallback(eq(mRcsProvisioningCallback));
812 
813         // Config data received and ACS used
814         int errorCode = 200;
815         mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
816         broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
817         processAllMessages();
818         mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
819         processAllMessages();
820         verify(mRcsStats, times(1)).onRcsAcsProvisioningStats(eq(FAKE_SUB_ID_BASE), eq(errorCode),
821                 eq(RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML), anyBoolean());
822     }
823 
824     @Test
825     @SmallTest
testMetricsClientProvisioningStats()826     public void testMetricsClientProvisioningStats() throws Exception {
827         createMonitor(1);
828 
829         // reconfig trigger
830         mRcsProvisioningMonitor.requestReconfig(FAKE_SUB_ID_BASE);
831         processAllMessages();
832         verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
833                 eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION));
834 
835         // DMA changed
836         updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
837         processAllMessages();
838         verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
839                 eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED));
840     }
841 
createMonitor(int subCount)842     private void createMonitor(int subCount) throws Exception {
843         if (Looper.myLooper() == null) {
844             Looper.prepare();
845         }
846         makeFakeActiveSubIds(subCount);
847         when(mFeatureFactory.create(any(), anyInt(), mConnectorListener.capture(), any(), any()))
848                 .thenReturn(mFeatureConnector);
849         when(mFeatureManager.getConfig()).thenReturn(mIImsConfig);
850         mRcsProvisioningMonitor = new RcsProvisioningMonitor(mPhone, mHandlerThread.getLooper(),
851                 mRoleManager, mFeatureFactory, mRcsStats);
852         mHandler = mRcsProvisioningMonitor.getHandler();
853         try {
854             mLooper = new TestableLooper(mHandler.getLooper());
855         } catch (Exception e) {
856             logd("Unable to create looper from handler.");
857         }
858         mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
859 
860         verify(mFeatureConnector, atLeastOnce()).connect();
861     }
862 
broadcastCarrierConfigChange(int subId)863     private void broadcastCarrierConfigChange(int subId) {
864         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
865         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
866         mExecutor.execute(() -> {
867             mReceiver.onReceive(mPhone, intent);
868         });
869     }
870 
makeFakeActiveSubIds(int count)871     private void makeFakeActiveSubIds(int count) {
872         final int[] subIds = new int[count];
873         for (int i = 0; i < count; i++) {
874             subIds[i] = FAKE_SUB_ID_BASE + i;
875         }
876         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(subIds);
877     }
878 
updateDefaultMessageApplication(String packageName)879     private void updateDefaultMessageApplication(String packageName) {
880         List<String> dmas = new ArrayList<>();
881         dmas.add(packageName);
882         when(mRoleManager.getRoleHolders(eq(RoleManager.ROLE_SMS))).thenReturn(dmas);
883         mExecutor.execute(() -> mRoleHolderChangedListener.onRoleHoldersChanged(
884                 RoleManager.ROLE_SMS, UserHandle.ALL));
885     }
886 
processAllMessages()887     private void processAllMessages() {
888         while (!mLooper.getLooper().getQueue().isIdle()) {
889             mLooper.processAllMessages();
890         }
891     }
892 
logd(String str)893     private static void logd(String str) {
894         Log.d(TAG, str);
895     }
896 }
897