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