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