• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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.services.telephony.rcs;
18 
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.ArgumentMatchers.anyInt;
21 import static org.mockito.ArgumentMatchers.eq;
22 import static org.mockito.Mockito.doReturn;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.times;
26 import static org.mockito.Mockito.verify;
27 
28 import android.app.PropertyInvalidatedCache;
29 import android.content.BroadcastReceiver;
30 import android.content.Intent;
31 import android.os.PersistableBundle;
32 import android.telephony.CarrierConfigManager;
33 import android.telephony.SubscriptionManager;
34 import android.telephony.TelephonyManager;
35 
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import com.android.TelephonyTestBase;
39 import com.android.ims.FeatureConnector;
40 import com.android.ims.RcsFeatureManager;
41 import com.android.internal.telephony.ISub;
42 
43 import org.junit.After;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Captor;
49 import org.mockito.Mock;
50 
51 @RunWith(AndroidJUnit4.class)
52 public class TelephonyRcsServiceTest extends TelephonyTestBase {
53 
54     @Captor ArgumentCaptor<BroadcastReceiver> mReceiverCaptor;
55     @Mock TelephonyRcsService.FeatureFactory mFeatureFactory;
56     @Mock TelephonyRcsService.ResourceProxy mResourceProxy;
57     @Mock UceControllerManager mMockUceSlot0;
58     @Mock UceControllerManager mMockUceSlot1;
59     @Mock SipTransportController mMockSipTransportSlot0;
60     @Mock SipTransportController mMockSipTransportSlot1;
61     @Mock RcsFeatureController.RegistrationHelperFactory mRegistrationFactory;
62     @Mock RcsFeatureController.FeatureConnectorFactory<RcsFeatureManager> mFeatureConnectorFactory;
63     @Mock FeatureConnector<RcsFeatureManager> mFeatureConnector;
64 
65     @Mock
66     private ISub mISub;
67 
68     @Mock
69     private TelephonyManager mTelephonyManager;
70 
71     private RcsFeatureController mFeatureControllerSlot0;
72     private RcsFeatureController mFeatureControllerSlot1;
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         super.setUp();
77         TelephonyManager.setupISubForTest(mISub);
78         TelephonyManager.enableServiceHandleCaching();
79         PropertyInvalidatedCache.disableForTestMode();
80 
81         //set up default slot-> sub ID mappings.
82         setSlotToSubIdMapping(0 /*slotId*/, 1/*subId*/);
83         setSlotToSubIdMapping(1 /*slotId*/, 2/*subId*/);
84 
85         doReturn(mFeatureConnector).when(mFeatureConnectorFactory).create(any(), anyInt(),
86                 any(), any(), any());
87         mFeatureControllerSlot0 = createFeatureController(0 /*slotId*/, 1 /*subId*/);
88         mFeatureControllerSlot1 = createFeatureController(1 /*slotId*/, 2 /*subId*/);
89         doReturn(mFeatureControllerSlot0).when(mFeatureFactory).createController(any(), eq(0),
90                 anyInt());
91         doReturn(mFeatureControllerSlot1).when(mFeatureFactory).createController(any(), eq(1),
92                 anyInt());
93         doReturn(mMockUceSlot0).when(mFeatureFactory).createUceControllerManager(any(), eq(0),
94                 anyInt());
95         doReturn(mMockUceSlot1).when(mFeatureFactory).createUceControllerManager(any(), eq(1),
96                 anyInt());
97         doReturn(mMockSipTransportSlot0).when(mFeatureFactory).createSipTransportController(any(),
98                 eq(0), anyInt());
99         doReturn(mMockSipTransportSlot1).when(mFeatureFactory).createSipTransportController(any(),
100                 eq(1), anyInt());
101         doReturn(true).when(mResourceProxy).getDeviceUceEnabled(any());
102 
103         replaceInstance(TelephonyManager.class, "sInstance", null, mTelephonyManager);
104         doReturn(2).when(mTelephonyManager).getActiveModemCount();
105     }
106 
107     @After
tearDown()108     public void tearDown() throws Exception {
109         super.tearDown();
110     }
111 
112     @Test
testUceControllerPresenceConnected()113     public void testUceControllerPresenceConnected() {
114         setCarrierConfig(1 /*subId*/,
115                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
116                 true /*isEnabled*/);
117         createRcsService(1 /*numSlots*/);
118         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
119         verify(mFeatureControllerSlot0).connect();
120     }
121 
122     @Test
testUceControllerOptionsConnected()123     public void testUceControllerOptionsConnected() {
124         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL,
125                 true /*isEnabled*/);
126         createRcsService(1 /*numSlots*/);
127         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
128         verify(mFeatureControllerSlot0).connect();
129     }
130 
131     @Test
testNoFeaturesEnabled()132     public void testNoFeaturesEnabled() {
133         createRcsService(1 /*numSlots*/);
134         // No carrier config set for UCE.
135         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
136                 UceControllerManager.class);
137         verify(mFeatureControllerSlot0, never()).connect();
138     }
139 
140     @Test
testSipTransportConnected()141     public void testSipTransportConnected() {
142         createRcsService(1 /*numSlots*/);
143         verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot0,
144                 SipTransportController.class);
145         verify(mFeatureControllerSlot0, never()).connect();
146 
147 
148         // Send carrier config update for each slot.
149         setCarrierConfig(1 /*subId*/,
150                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
151                 true /*isEnabled*/);
152         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
153         verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
154                 SipTransportController.class);
155         verify(mFeatureControllerSlot0).connect();
156         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
157     }
158 
159     @Test
testSipTransportConnectedOneSlot()160     public void testSipTransportConnectedOneSlot() {
161         createRcsService(2 /*numSlots*/);
162         verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot0,
163                 SipTransportController.class);
164         verify(mFeatureControllerSlot0, never()).connect();
165         verify(mFeatureControllerSlot0, never()).addFeature(mMockSipTransportSlot1,
166                 SipTransportController.class);
167         verify(mFeatureControllerSlot1, never()).connect();
168 
169 
170         // Send carrier config update for slot 0 only
171         setCarrierConfig(1 /*subId*/,
172                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
173                 true /*isEnabled*/);
174         setCarrierConfig(2 /*subId*/,
175                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
176                 false /*isEnabled*/);
177         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
178         sendCarrierConfigChanged(1 /*slotId*/, 2 /*subId*/);
179         verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
180                 SipTransportController.class);
181         verify(mFeatureControllerSlot1, never()).addFeature(mMockSipTransportSlot0,
182                 SipTransportController.class);
183         verify(mFeatureControllerSlot0).connect();
184         verify(mFeatureControllerSlot1, never()).connect();
185         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
186         verify(mFeatureControllerSlot1, never()).updateAssociatedSubscription(1);
187     }
188 
189     @Test
testNoFeaturesEnabledCarrierConfigChanged()190     public void testNoFeaturesEnabledCarrierConfigChanged() {
191         createRcsService(1 /*numSlots*/);
192         // No carrier config set for UCE.
193 
194         sendCarrierConfigChanged(0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
195         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
196                 UceControllerManager.class);
197         verify(mFeatureControllerSlot0, never()).connect();
198         verify(mFeatureControllerSlot0, never()).updateAssociatedSubscription(anyInt());
199     }
200 
201 
202     @Test
testSlotUpdates()203     public void testSlotUpdates() {
204         setCarrierConfig(1 /*subId*/,
205                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
206                 true /*isEnabled*/);
207         setCarrierConfig(2 /*subId*/,
208                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
209                 true /*isEnabled*/);
210         TelephonyRcsService service = createRcsService(1 /*numSlots*/);
211         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
212         verify(mFeatureControllerSlot0).connect();
213 
214         // there should be no changes if the new num slots = old num
215         service.updateFeatureControllerSize(1 /*newNumSlots*/);
216         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
217                 UceControllerManager.class);
218         verify(mFeatureControllerSlot0, times(1)).connect();
219 
220         // Add a new slot.
221         verify(mFeatureControllerSlot1, never()).addFeature(mMockUceSlot1,
222                 UceControllerManager.class);
223         verify(mFeatureControllerSlot1, never()).connect();
224         service.updateFeatureControllerSize(2 /*newNumSlots*/);
225         // This shouldn't have changed for slot 0.
226         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
227                 UceControllerManager.class);
228         verify(mFeatureControllerSlot0, times(1)).connect();
229         verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
230         verify(mFeatureControllerSlot1, times(1)).connect();
231 
232         // Remove a slot.
233         verify(mFeatureControllerSlot0, never()).destroy();
234         verify(mFeatureControllerSlot1, never()).destroy();
235         service.updateFeatureControllerSize(1 /*newNumSlots*/);
236         // addFeature/connect shouldn't have been called again
237         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
238                 UceControllerManager.class);
239         verify(mFeatureControllerSlot0, times(1)).connect();
240         verify(mFeatureControllerSlot1, times(1)).addFeature(mMockUceSlot1,
241                 UceControllerManager.class);
242         verify(mFeatureControllerSlot1, times(1)).connect();
243         // Verify destroy is only called for slot 1.
244         verify(mFeatureControllerSlot0, never()).destroy();
245         verify(mFeatureControllerSlot1, times(1)).destroy();
246     }
247 
248     @Test
testCarrierConfigUpdateAssociatedSub()249     public void testCarrierConfigUpdateAssociatedSub() {
250         setCarrierConfig(1 /*subId*/,
251                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
252                 true /*isEnabled*/);
253         setCarrierConfig(2 /*subId*/,
254                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
255                 true /*isEnabled*/);
256         createRcsService(2 /*numSlots*/);
257         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
258         verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
259         verify(mFeatureControllerSlot0).connect();
260         verify(mFeatureControllerSlot1).connect();
261 
262 
263         // Send carrier config update for each slot.
264         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
265         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
266         verify(mFeatureControllerSlot1, never()).updateAssociatedSubscription(1);
267         sendCarrierConfigChanged(1 /*slotId*/, 2 /*subId*/);
268         verify(mFeatureControllerSlot0, never()).updateAssociatedSubscription(2);
269         verify(mFeatureControllerSlot1, times(1)).updateAssociatedSubscription(2);
270     }
271 
272     @Test
testCarrierConfigNotifyFeatures()273     public void testCarrierConfigNotifyFeatures() {
274         setCarrierConfig(1 /*subId*/,
275                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
276                 true /*isEnabled*/);
277         createRcsService(1 /*numSlots*/);
278         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
279         verify(mFeatureControllerSlot0).connect();
280 
281 
282         // Send carrier config update twice with no update to subId
283         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
284         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
285         verify(mFeatureControllerSlot0, never()).onCarrierConfigChangedForSubscription();
286         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
287         verify(mFeatureControllerSlot0, times(1)).updateAssociatedSubscription(1);
288         // carrier config changed should be sent here
289         verify(mFeatureControllerSlot0).onCarrierConfigChangedForSubscription();
290     }
291 
292     @Test
testCarrierConfigUpdateUceToNoUce()293     public void testCarrierConfigUpdateUceToNoUce() {
294         setCarrierConfig(1 /*subId*/,
295                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
296                 true /*isEnabled*/);
297         createRcsService(1 /*numSlots*/);
298         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
299         verify(mFeatureControllerSlot0).connect();
300 
301 
302         // Send carrier config update for each slot.
303         setCarrierConfig(1 /*subId*/,
304                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
305                 false /*isEnabled*/);
306         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
307         verify(mFeatureControllerSlot0).removeFeature(UceControllerManager.class);
308         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
309     }
310 
311     @Test
testCarrierConfigUpdateTransportToNoTransport()312     public void testCarrierConfigUpdateTransportToNoTransport() {
313         setCarrierConfig(1 /*subId*/,
314                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
315                 true /*isEnabled*/);
316         createRcsService(1 /*numSlots*/);
317         verify(mFeatureControllerSlot0).addFeature(mMockSipTransportSlot0,
318                 SipTransportController.class);
319         verify(mFeatureControllerSlot0).connect();
320 
321 
322         // Send carrier config update for each slot.
323         setCarrierConfig(1 /*subId*/,
324                 CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL,
325                 false /*isEnabled*/);
326         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
327         verify(mFeatureControllerSlot0).removeFeature(SipTransportController.class);
328         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
329     }
330 
331     @Test
testCarrierConfigUpdateNoUceToUce()332     public void testCarrierConfigUpdateNoUceToUce() {
333         createRcsService(1 /*numSlots*/);
334         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
335                 UceControllerManager.class);
336         verify(mFeatureControllerSlot0, never()).connect();
337 
338 
339         // Send carrier config update for each slot.
340         setCarrierConfig(1 /*subId*/,
341                 CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL,
342                 true /*isEnabled*/);
343         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
344         verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
345         verify(mFeatureControllerSlot0).connect();
346         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
347     }
348 
sendCarrierConfigChanged(int slotId, int subId)349     private void sendCarrierConfigChanged(int slotId, int subId) {
350         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
351         intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, slotId);
352         intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, subId);
353         mReceiverCaptor.getValue().onReceive(mContext, intent);
354     }
355 
setCarrierConfig(int subId, String key, boolean value)356     private void setCarrierConfig(int subId, String key, boolean value) {
357         PersistableBundle bundle = mContext.getCarrierConfig(subId);
358         bundle.putBoolean(key, value);
359     }
360 
setSlotToSubIdMapping(int slotId, int loadedSubId)361     private void setSlotToSubIdMapping(int slotId, int loadedSubId) throws Exception {
362         doReturn(loadedSubId).when(mISub).getSubId(slotId);
363     }
364 
createRcsService(int numSlots)365     private TelephonyRcsService createRcsService(int numSlots) {
366         TelephonyRcsService service = new TelephonyRcsService(mContext, numSlots, mResourceProxy);
367         service.setFeatureFactory(mFeatureFactory);
368         service.initialize();
369         verify(mContext).registerReceiver(mReceiverCaptor.capture(), any());
370         return service;
371     }
372 
createFeatureController(int slotId, int subId)373     private RcsFeatureController createFeatureController(int slotId, int subId) {
374         // Create a spy instead of a mock because TelephonyRcsService relies on state provided by
375         // RcsFeatureController.
376         RcsFeatureController controller = spy(new RcsFeatureController(mContext, slotId, subId,
377                 mRegistrationFactory));
378         controller.setFeatureConnectorFactory(mFeatureConnectorFactory);
379         return controller;
380     }
381 }
382