• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.domainselection;
18 
19 import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
20 
21 import static junit.framework.Assert.assertFalse;
22 import static junit.framework.Assert.assertTrue;
23 import static junit.framework.Assert.assertNotNull;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.doReturn;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 
33 import android.content.BroadcastReceiver;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.content.IntentFilter;
37 import android.net.LinkProperties;
38 import android.os.HandlerThread;
39 import android.os.Looper;
40 import android.telephony.CarrierConfigManager;
41 import android.telephony.PreciseDataConnectionState;
42 import android.telephony.SubscriptionManager;
43 import android.telephony.TelephonyCallback;
44 import android.telephony.TelephonyManager;
45 import android.telephony.data.ApnSetting;
46 import android.testing.TestableLooper;
47 import android.util.Log;
48 
49 import com.android.TestContext;
50 
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.mockito.ArgumentCaptor;
55 import org.mockito.Mock;
56 import org.mockito.MockitoAnnotations;
57 
58 import java.util.concurrent.Executor;
59 
60 /**
61  * Unit tests for DataConnectionStateHelper
62  */
63 public class DataConnectionStateHelperTest {
64     private static final String TAG = "DataConnectionStateHelperTest";
65 
66     private static final int SLOT_0 = 0;
67     private static final int SLOT_1 = 1;
68     private static final int SUB_1 = 1;
69     private static final int SUB_2 = 2;
70 
71     @Mock private TelephonyManager mTm1;
72     @Mock private TelephonyManager mTm2;
73     @Mock private EmergencyCallDomainSelector mDomainSelector;
74 
75     private Context mContext;
76     private HandlerThread mHandlerThread;
77     private TestableLooper mLooper;
78     private DataConnectionStateHelper mEpdnHelper;
79     private CarrierConfigManager mCarrierConfigManager;
80     private TelephonyManager mTelephonyManager;
81 
82     @Before
setUp()83     public void setUp() throws Exception {
84         MockitoAnnotations.initMocks(this);
85         mContext = new TestContext() {
86             private Intent mIntent;
87 
88             @Override
89             public String getSystemServiceName(Class<?> serviceClass) {
90                 if (serviceClass == TelephonyManager.class) {
91                     return Context.TELEPHONY_SERVICE;
92                 } else if (serviceClass == CarrierConfigManager.class) {
93                     return Context.CARRIER_CONFIG_SERVICE;
94                 }
95                 return super.getSystemServiceName(serviceClass);
96             }
97 
98             @Override
99             public String getOpPackageName() {
100                 return "";
101             }
102 
103             @Override
104             public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
105                 return mIntent;
106             }
107 
108             @Override
109             public void sendStickyBroadcast(Intent intent) {
110                 mIntent = intent;
111             }
112         };
113 
114         if (Looper.myLooper() == null) {
115             Looper.prepare();
116         }
117 
118         mHandlerThread = new HandlerThread("DataConnectionStateHelperTest");
119         mHandlerThread.start();
120 
121         try {
122             mLooper = new TestableLooper(mHandlerThread.getLooper());
123         } catch (Exception e) {
124             logd("Unable to create looper from handler.");
125         }
126 
127         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
128         mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
129         doReturn(mTm1).when(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
130         doReturn(mTm2).when(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
131 
132         mEpdnHelper = new DataConnectionStateHelper(mContext, mHandlerThread.getLooper());
133         mEpdnHelper.setEmergencyCallDomainSelector(mDomainSelector);
134     }
135 
136     @After
tearDown()137     public void tearDown() throws Exception {
138         if (mEpdnHelper != null) {
139             mEpdnHelper.destroy();
140             mEpdnHelper = null;
141         }
142 
143         if (mLooper != null) {
144             mLooper.destroy();
145             mLooper = null;
146         }
147     }
148 
149     @Test
testInit()150     public void testInit() throws Exception {
151         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
152                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
153         ArgumentCaptor<Executor> executorCaptor = ArgumentCaptor.forClass(Executor.class);
154 
155         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(executorCaptor.capture(),
156                 callbackCaptor.capture());
157         assertNotNull(executorCaptor.getValue());
158         assertNotNull(callbackCaptor.getValue());
159     }
160 
161     @Test
testCarrierConfigChanged()162     public void testCarrierConfigChanged() throws Exception {
163         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
164                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
165 
166         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
167                 callbackCaptor.capture());
168 
169         CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
170 
171         assertNotNull(callback);
172 
173         callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
174 
175         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
176 
177         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
178                 ArgumentCaptor.forClass(TelephonyCallback.class);
179 
180         // TelephonyCallback for SUB_1 registered
181         verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
182 
183         assertNotNull(telephonyCallbackCaptor1.getValue());
184 
185         callback.onCarrierConfigChanged(SLOT_1, SUB_2, 0, 0);
186 
187         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
188 
189         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
190                 ArgumentCaptor.forClass(TelephonyCallback.class);
191 
192         // TelephonyCallback for SUB_2 registered
193         verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
194 
195         assertNotNull(telephonyCallbackCaptor2.getValue());
196 
197         verify(mTm1, never()).unregisterTelephonyCallback(any());
198         verify(mTm2, never()).unregisterTelephonyCallback(any());
199     }
200 
201     @Test
testSubscriptionChangedOnTheSameSlot()202     public void testSubscriptionChangedOnTheSameSlot() throws Exception {
203         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
204                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
205 
206         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
207                 callbackCaptor.capture());
208 
209         CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
210 
211         assertNotNull(callback);
212 
213         callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
214 
215         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
216 
217         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
218                 ArgumentCaptor.forClass(TelephonyCallback.class);
219 
220         // TelephonyCallback for SUB_1 registered
221         verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
222 
223         TelephonyCallback telephonyCallback1 = telephonyCallbackCaptor1.getValue();
224 
225         assertNotNull(telephonyCallback1);
226 
227         // Subscription changed
228         callback.onCarrierConfigChanged(SLOT_0, SUB_2, 0, 0);
229 
230         // TelephonyCallback for SUB_1 unregistered
231         verify(mTelephonyManager).unregisterTelephonyCallback(eq(telephonyCallback1));
232 
233         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
234 
235         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
236                 ArgumentCaptor.forClass(TelephonyCallback.class);
237 
238         // TelephonyCallback for SUB_2 registered
239         verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
240 
241         TelephonyCallback telephonyCallback2 = telephonyCallbackCaptor2.getValue();
242 
243         assertNotNull(telephonyCallback2);
244     }
245 
246     @Test
testDataConnectionStateChanged()247     public void testDataConnectionStateChanged() throws Exception {
248         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
249                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
250 
251         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
252                 callbackCaptor.capture());
253 
254         CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
255 
256         assertNotNull(callback);
257 
258         callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
259 
260         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
261 
262         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
263                 ArgumentCaptor.forClass(TelephonyCallback.class);
264 
265         // TelephonyCallback for SUB_1 registered
266         verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
267 
268         TelephonyCallback cb1 = telephonyCallbackCaptor1.getValue();
269 
270         assertNotNull(cb1);
271         assertTrue(cb1 instanceof TelephonyCallback.PreciseDataConnectionStateListener);
272 
273         callback.onCarrierConfigChanged(SLOT_1, SUB_2, 0, 0);
274 
275         verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
276 
277         ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
278                 ArgumentCaptor.forClass(TelephonyCallback.class);
279 
280         // TelephonyCallback for SUB_2 registered
281         verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
282 
283         TelephonyCallback cb2 = telephonyCallbackCaptor2.getValue();
284 
285         assertNotNull(cb2);
286         assertTrue(cb2 instanceof TelephonyCallback.PreciseDataConnectionStateListener);
287 
288         TelephonyCallback.PreciseDataConnectionStateListener listener1 =
289                 (TelephonyCallback.PreciseDataConnectionStateListener) cb1;
290         TelephonyCallback.PreciseDataConnectionStateListener listener2 =
291                 (TelephonyCallback.PreciseDataConnectionStateListener) cb2;
292 
293         PreciseDataConnectionState state = getPreciseDataConnectionState(
294                 ApnSetting.TYPE_DEFAULT, TelephonyManager.DATA_CONNECTED);
295         listener1.onPreciseDataConnectionStateChanged(state);
296         listener2.onPreciseDataConnectionStateChanged(state);
297 
298         verify(mDomainSelector, never()).notifyDataConnectionStateChange(anyInt(), anyInt());
299         verify(mDomainSelector, never()).notifyDataConnectionStateChange(anyInt(), anyInt());
300 
301         state = getPreciseDataConnectionState(
302                 ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_CONNECTED);
303         listener1.onPreciseDataConnectionStateChanged(state);
304         listener2.onPreciseDataConnectionStateChanged(state);
305 
306         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
307                 eq(SLOT_0), eq(TelephonyManager.DATA_CONNECTED));
308         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
309                 eq(SLOT_1), eq(TelephonyManager.DATA_CONNECTED));
310 
311         state = getPreciseDataConnectionState(
312                 ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_DISCONNECTING);
313         listener1.onPreciseDataConnectionStateChanged(state);
314         listener2.onPreciseDataConnectionStateChanged(state);
315 
316         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
317                 eq(SLOT_0), eq(TelephonyManager.DATA_DISCONNECTING));
318         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
319                 eq(SLOT_1), eq(TelephonyManager.DATA_DISCONNECTING));
320 
321         state = getPreciseDataConnectionState(
322                 ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_DISCONNECTED);
323         listener1.onPreciseDataConnectionStateChanged(state);
324         listener2.onPreciseDataConnectionStateChanged(state);
325 
326         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
327                 eq(SLOT_0), eq(TelephonyManager.DATA_DISCONNECTED));
328         verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
329                 eq(SLOT_1), eq(TelephonyManager.DATA_DISCONNECTED));
330     }
331 
332     @Test
testEmergencyCallbackModeEnter()333     public void testEmergencyCallbackModeEnter() throws Exception {
334         // Enter ECBM on slot 1
335         mContext.sendStickyBroadcast(getIntent(true, SLOT_1));
336 
337         assertFalse(mEpdnHelper.isInEmergencyCallbackMode(SLOT_0));
338         assertTrue(mEpdnHelper.isInEmergencyCallbackMode(SLOT_1));
339     }
340 
341     @Test
testEmergencyCallbackModeExit()342     public void testEmergencyCallbackModeExit() throws Exception {
343         // Exit ECBM
344         mContext.sendStickyBroadcast(getIntent(false, SLOT_0));
345 
346         assertFalse(mEpdnHelper.isInEmergencyCallbackMode(SLOT_0));
347     }
348 
getIntent(boolean inEcm, int slotIndex)349     private static Intent getIntent(boolean inEcm, int slotIndex) {
350         Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
351         intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, inEcm);
352         intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
353         return intent;
354     }
355 
getPreciseDataConnectionState( int apnType, int state)356     private static PreciseDataConnectionState getPreciseDataConnectionState(
357             int apnType, int state) {
358         return new PreciseDataConnectionState.Builder()
359                 .setTransportType(TRANSPORT_TYPE_WWAN)
360                 .setId(1)
361                 .setState(state)
362                 .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
363                 .setApnSetting(new ApnSetting.Builder()
364                         .setApnTypeBitmask(apnType)
365                         .setApnName("default")
366                         .setEntryName("default")
367                         .build())
368                 .setLinkProperties(new LinkProperties())
369                 .setFailCause(0)
370                 .build();
371     }
372 
logd(String str)373     private static void logd(String str) {
374         Log.d(TAG, str);
375     }
376 }
377