1   /*
2  * Copyright (C) 2019 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 package com.android.ons;
17 
18 import static org.junit.Assert.assertThrows;
19 import static org.mockito.Mockito.any;
20 import static org.mockito.Mockito.doReturn;
21 import static org.mockito.Mockito.never;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.compat.testing.PlatformCompatChangeRule;
27 import android.content.BroadcastReceiver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.pm.PackageManager;
31 import android.os.Build;
32 import android.os.Looper;
33 import android.os.RemoteException;
34 import android.os.UserManager;
35 import android.platform.test.flag.junit.SetFlagsRule;
36 import android.telephony.AvailableNetworkInfo;
37 import android.telephony.CarrierConfigManager;
38 import android.telephony.SubscriptionInfo;
39 import android.telephony.SubscriptionManager;
40 import android.telephony.TelephonyFrameworkInitializer;
41 import android.telephony.TelephonyManager;
42 import android.util.Log;
43 
44 import androidx.test.runner.AndroidJUnit4;
45 
46 import com.android.internal.telephony.IOns;
47 import com.android.internal.telephony.ISetOpportunisticDataCallback;
48 import com.android.internal.telephony.IUpdateAvailableNetworksCallback;
49 import com.android.internal.telephony.flags.Flags;
50 
51 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
52 
53 import org.junit.After;
54 import org.junit.Before;
55 import org.junit.Rule;
56 import org.junit.Test;
57 import org.junit.rules.TestRule;
58 import org.junit.runner.RunWith;
59 import org.mockito.ArgumentCaptor;
60 import org.mockito.Mock;
61 
62 import java.lang.reflect.Field;
63 import java.util.ArrayList;
64 import java.util.HashMap;
65 
66 @RunWith(AndroidJUnit4.class)
67 public class OpportunisticNetworkServiceTest extends ONSBaseTest {
68     // SetFlagsRule will be used for Telephony feature flag
69     @Rule
70     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
71     @Rule
72     public TestRule compatChangeRule = new PlatformCompatChangeRule();
73 
74     private static final String TAG = "ONSTest";
75     private String pkgForDebug;
76     private String pkgForFeature;
77     private int mResult;
78     private IOns iOpportunisticNetworkService;
79     private Looper mLooper;
80     private OpportunisticNetworkService mOpportunisticNetworkService;
81     private static final String CARRIER_APP_CONFIG_NAME = "carrierApp";
82     private static final String SYSTEM_APP_CONFIG_NAME = "systemApp";
83 
84     @Mock
85     private HashMap<String, ONSConfigInput> mockONSConfigInputHashMap;
86     @Mock
87     private ONSProfileSelector mockProfileSelector;
88     @Mock
89     private CarrierConfigManager mCarrierConfigManager;
90     @Mock
91     private ONSProfileActivator mONSProfileActivator;
92     @Mock
93     private UserManager mUserManager;
94     @Mock
95     private Context mMockContext;
96     @Mock
97     private PackageManager mPackageManager;
98 
99     @Before
setUp()100     public void setUp() throws Exception {
101         super.setUp("ONSTest");
102         pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
103         pkgForFeature = mContext != null ? mContext.getAttributionTag() : null;
104         Intent intent = new Intent(mContext, OpportunisticNetworkService.class);
105         new Thread(new Runnable() {
106             @Override
107             public void run() {
108                 Looper.prepare();
109                 mOpportunisticNetworkService = new OpportunisticNetworkService();
110                 mOpportunisticNetworkService.initialize(mContext);
111                 mOpportunisticNetworkService.mSubscriptionManager = mSubscriptionManager;
112                 mOpportunisticNetworkService.mPackageManager = mPackageManager;
113                 for (int retry = 2; retry > 0; retry--) {
114 
115                     iOpportunisticNetworkService = (IOns) mOpportunisticNetworkService.onBind(null);
116 
117                     if (iOpportunisticNetworkService != null) {
118                         break;
119                     }
120 
121                     try {
122                         Thread.sleep(100);
123                     } catch (Exception e) {
124                         Log.e(TAG, e.toString());
125                     }
126                 }
127                 mLooper = Looper.myLooper();
128                 setReady(true);
129                 Looper.loop();
130             }
131         }).start();
132         waitUntilReady(300);
133 
134         // In order not to affect the existing implementation, define a telephony feature
135         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_DATA))
136                 .thenReturn(true);
137         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS))
138                 .thenReturn(true);
139     }
140 
141     @After
tearDown()142     public void tearDown() throws Exception {
143         super.tearDown();
144         mOpportunisticNetworkService.onDestroy();
145         if (mLooper != null) {
146             mLooper.quit();
147             mLooper.getThread().join();
148         }
149     }
150 
151     @Test
testCheckEnable()152     public void testCheckEnable() {
153         boolean isEnable = true;
154         try {
155             iOpportunisticNetworkService.setEnable(false, pkgForDebug);
156             isEnable = iOpportunisticNetworkService.isEnabled(pkgForDebug);
157         } catch (RemoteException ex) {
158             Log.e(TAG, "RemoteException", ex);
159         }
160         assertEquals(false, isEnable);
161     }
162 
163     @Test
testHandleSimStateChange()164     public void testHandleSimStateChange() {
165         mResult = -1;
166         ArrayList<String> mccMncs = new ArrayList<>();
167         mccMncs.add("310210");
168         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
169                 new ArrayList<Integer>());
170         ArrayList<AvailableNetworkInfo> availableNetworkInfos =
171                 new ArrayList<AvailableNetworkInfo>();
172         availableNetworkInfos.add(availableNetworkInfo);
173         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
174             @Override
175             public void onComplete(int result) {
176                 mResult = result;
177                 Log.d(TAG, "result: " + result);
178             }
179         };
180         ONSConfigInput onsConfigInput = new ONSConfigInput(availableNetworkInfos, mCallback);
181         onsConfigInput.setPrimarySub(1);
182         onsConfigInput.setPreferredDataSub(availableNetworkInfos.get(0).getSubId());
183         ArrayList<SubscriptionInfo> subscriptionInfos = new ArrayList<SubscriptionInfo>();
184 
185         // Case 1: There is no Carrier app using ONS.
186         doReturn(null).when(mockONSConfigInputHashMap).get(CARRIER_APP_CONFIG_NAME);
187         mOpportunisticNetworkService.mIsEnabled = true;
188         mOpportunisticNetworkService.mONSConfigInputHashMap = mockONSConfigInputHashMap;
189         mOpportunisticNetworkService.handleSimStateChange();
190         waitForMs(500);
191         verify(mockONSConfigInputHashMap, never()).get(SYSTEM_APP_CONFIG_NAME);
192 
193         // Case 2: There is a Carrier app using ONS and no System app input.
194         doReturn(subscriptionInfos).when(mSubscriptionManager).getActiveSubscriptionInfoList(false);
195         doReturn(onsConfigInput).when(mockONSConfigInputHashMap).get(CARRIER_APP_CONFIG_NAME);
196         doReturn(null).when(mockONSConfigInputHashMap).get(SYSTEM_APP_CONFIG_NAME);
197         mOpportunisticNetworkService.mIsEnabled = true;
198         mOpportunisticNetworkService.mONSConfigInputHashMap = mockONSConfigInputHashMap;
199         mOpportunisticNetworkService.handleSimStateChange();
200         waitForMs(50);
201         verify(mockONSConfigInputHashMap,times(1)).get(SYSTEM_APP_CONFIG_NAME);
202     }
203 
204     @Test
testSystemPreferredDataWhileCarrierAppIsActive()205     public void testSystemPreferredDataWhileCarrierAppIsActive() {
206         mResult = -1;
207         ArrayList<String> mccMncs = new ArrayList<>();
208         mccMncs.add("310210");
209         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
210             new ArrayList<Integer>());
211         ArrayList<AvailableNetworkInfo> availableNetworkInfos =
212             new ArrayList<AvailableNetworkInfo>();
213         availableNetworkInfos.add(availableNetworkInfo);
214         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
215             @Override
216             public void onComplete(int result) {
217                 mResult = result;
218                 Log.d(TAG, "result: " + result);
219             }
220         };
221         ONSConfigInput onsConfigInput = new ONSConfigInput(availableNetworkInfos, mCallback);
222         onsConfigInput.setPrimarySub(1);
223         onsConfigInput.setPreferredDataSub(availableNetworkInfos.get(0).getSubId());
224         ArrayList<SubscriptionInfo> subscriptionInfos = new ArrayList<SubscriptionInfo>();
225 
226         doReturn(subscriptionInfos).when(mSubscriptionManager).getActiveSubscriptionInfoList(false);
227         doReturn(onsConfigInput).when(mockONSConfigInputHashMap).get(CARRIER_APP_CONFIG_NAME);
228         mOpportunisticNetworkService.mIsEnabled = true;
229         mOpportunisticNetworkService.mONSConfigInputHashMap = mockONSConfigInputHashMap;
230 
231         mResult = -1;
232         ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
233             @Override
234             public void onComplete(int result) {
235                 Log.d(TAG, "callbackStub, mResult end:" + result);
236                 mResult = result;
237             }
238         };
239 
240         try {
241             IOns onsBinder = (IOns)mOpportunisticNetworkService.onBind(null);
242             onsBinder.setPreferredDataSubscriptionId(
243                     SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, callbackStub,
244                     pkgForDebug);
245         } catch (RemoteException ex) {
246             Log.e(TAG, "RemoteException", ex);
247         }
248         waitForMs(50);
249         assertEquals(TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED, mResult);
250     }
251 
252     @Test
testSetPreferredDataSubscriptionId()253     public void testSetPreferredDataSubscriptionId() {
254         mResult = -1;
255         ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
256             @Override
257             public void onComplete(int result) {
258                 Log.d(TAG, "callbackStub, mResult end:" + result);
259                 mResult = result;
260             }
261         };
262 
263         try {
264             assertNotNull(iOpportunisticNetworkService);
265             iOpportunisticNetworkService.setPreferredDataSubscriptionId(5, false, callbackStub,
266                     pkgForDebug);
267         } catch (RemoteException ex) {
268             Log.e(TAG, "RemoteException", ex);
269         }
270         assertEquals(
271                 TelephonyManager.SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE, mResult);
272     }
273 
274     @Test
testGetPreferredDataSubscriptionId()275     public void testGetPreferredDataSubscriptionId() {
276         assertNotNull(iOpportunisticNetworkService);
277         mResult = -1;
278         try {
279             mResult = iOpportunisticNetworkService.getPreferredDataSubscriptionId(pkgForDebug,
280                     pkgForFeature);
281             Log.d(TAG, "testGetPreferredDataSubscriptionId: " + mResult);
282             assertNotNull(mResult);
283         } catch (RemoteException ex) {
284             Log.e(TAG, "RemoteException", ex);
285         }
286     }
287 
288     @Test
testUpdateAvailableNetworksWithInvalidArguments()289     public void testUpdateAvailableNetworksWithInvalidArguments() {
290         mResult = -1;
291         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
292             @Override
293             public void onComplete(int result) {
294                 Log.d(TAG, "mResult end:" + result);
295                 mResult = result;
296             }
297         };
298 
299         ArrayList<String> mccMncs = new ArrayList<>();
300         mccMncs.add("310210");
301         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
302                 new ArrayList<Integer>());
303         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<>();
304         availableNetworkInfos.add(availableNetworkInfo);
305 
306         try {
307             iOpportunisticNetworkService.updateAvailableNetworks(availableNetworkInfos, mCallback,
308                     pkgForDebug);
309         } catch (RemoteException ex) {
310             Log.e(TAG, "RemoteException", ex);
311         }
312         assertEquals(
313                 TelephonyManager.UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE, mResult);
314     }
315 
316     @Test
testUpdateAvailableNetworksWithSuccess()317     public void testUpdateAvailableNetworksWithSuccess() {
318         mResult = -1;
319         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
320             @Override
321             public void onComplete(int result) {
322                 Log.d(TAG, "mResult end:" + result);
323                 mResult = result;
324             }
325         };
326         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<>();
327         try {
328             iOpportunisticNetworkService.setEnable(false, pkgForDebug);
329             iOpportunisticNetworkService.updateAvailableNetworks(availableNetworkInfos, mCallback,
330                     pkgForDebug);
331         } catch (RemoteException ex) {
332             Log.e(TAG, "RemoteException", ex);
333         }
334         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_SUCCESS, mResult);
335     }
336 
337     @Test
testPriorityRuleOfActivatingAvailableNetworks()338     public void testPriorityRuleOfActivatingAvailableNetworks() {
339         ArrayList<String> mccMncs = new ArrayList<>();
340         mccMncs.add("310210");
341         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
342                 new ArrayList<Integer>());
343         ArrayList<AvailableNetworkInfo> availableNetworkInfos =
344                 new ArrayList<AvailableNetworkInfo>();
345         availableNetworkInfos.add(availableNetworkInfo);
346         mResult = -1;
347         IUpdateAvailableNetworksCallback mCallback = new IUpdateAvailableNetworksCallback.Stub() {
348             @Override
349             public void onComplete(int result) {
350                 mResult = result;
351                 Log.d(TAG, "result: " + result);
352             }
353         };
354         ONSConfigInput onsConfigInput = new ONSConfigInput(availableNetworkInfos, mCallback);
355         onsConfigInput.setPrimarySub(1);
356         onsConfigInput.setPreferredDataSub(availableNetworkInfos.get(0).getSubId());
357         doReturn(onsConfigInput).when(mockONSConfigInputHashMap).get(CARRIER_APP_CONFIG_NAME);
358         doReturn(true).when(mockProfileSelector).hasOpprotunisticSub(any());
359         doReturn(false).when(mockProfileSelector).containStandaloneOppSubs(any());
360         mOpportunisticNetworkService.mIsEnabled = true;
361         mOpportunisticNetworkService.mONSConfigInputHashMap = mockONSConfigInputHashMap;
362         mOpportunisticNetworkService.mProfileSelector = mockProfileSelector;
363 
364         // Assume carrier app has updated available networks at first.
365         // Then system app updated available networks which is not standalone.
366         try {
367             IOns onsBinder = (IOns) mOpportunisticNetworkService.onBind(null);
368             onsBinder.updateAvailableNetworks(availableNetworkInfos, mCallback, pkgForDebug);
369         } catch (RemoteException ex) {
370             Log.e(TAG, "RemoteException", ex);
371         }
372         verify(mockProfileSelector, never()).startProfileSelection(any(), any());
373 
374         // System app updated available networks which contain standalone network.
375         doReturn(true).when(mockProfileSelector).containStandaloneOppSubs(any());
376         try {
377             IOns onsBinder = (IOns) mOpportunisticNetworkService.onBind(null);
378             onsBinder.updateAvailableNetworks(availableNetworkInfos, mCallback, pkgForDebug);
379         } catch (RemoteException ex) {
380             Log.e(TAG, "RemoteException", ex);
381         }
382         verify(mockProfileSelector, times(1)).startProfileSelection(any(), any());
383 
384         // System app updated available networks which equal to null.
385         // Case1: start carrier app request, if there is a carrier app request.
386         availableNetworkInfos.clear();
387         try {
388             IOns onsBinder = (IOns) mOpportunisticNetworkService.onBind(null);
389             onsBinder.updateAvailableNetworks(availableNetworkInfos, mCallback, pkgForDebug);
390         } catch (RemoteException ex) {
391             Log.e(TAG, "RemoteException", ex);
392         }
393         verify(mockProfileSelector, times(2)).startProfileSelection(any(), any());
394 
395         // System app updated available networks which equal to null.
396         // Case2: stop profile selection, if there is no any carrier app request.
397         doReturn(null).when(mockONSConfigInputHashMap).get(CARRIER_APP_CONFIG_NAME);
398         try {
399             IOns onsBinder = (IOns) mOpportunisticNetworkService.onBind(null);
400             onsBinder.updateAvailableNetworks(availableNetworkInfos, mCallback, pkgForDebug);
401         } catch (RemoteException ex) {
402             Log.e(TAG, "RemoteException", ex);
403         }
404         verify(mockProfileSelector, times(1)).stopProfileSelection(any());
405     }
406 
407     @Test
testCarrierConfigChangedUnlocked()408     public void testCarrierConfigChangedUnlocked() {
409         mOpportunisticNetworkService.mUserManager = mUserManager;
410         mOpportunisticNetworkService.mONSProfileActivator = mONSProfileActivator;
411         mOpportunisticNetworkService.mCarrierConfigManager = mCarrierConfigManager;
412         mOpportunisticNetworkService.registerCarrierConfigChangListener();
413         mOpportunisticNetworkService.mContext = mMockContext;
414 
415         CarrierConfigManager.CarrierConfigChangeListener CarrierConfigChangeListener;
416 
417         final ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerCaptor =
418                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
419 
420         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
421                 listenerCaptor.capture());
422         CarrierConfigChangeListener = listenerCaptor.getAllValues().get(0);
423 
424         // CarrierConfigChange in lock state
425         when(mUserManager.isUserUnlocked()).thenReturn(false);
426         CarrierConfigChangeListener.onCarrierConfigChanged(0, 0, 0, 0);
427         verify(mONSProfileActivator, never()).handleCarrierConfigChange();
428 
429         // handle CarrierConfigChange when state is changed from lock to unlock
430         final ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
431                 ArgumentCaptor.forClass(BroadcastReceiver.class);
432 
433         verify(mMockContext).registerReceiver(broadcastReceiverCaptor.capture(), any());
434         broadcastReceiverCaptor.getValue().onReceive(mMockContext,
435                 new Intent(Intent.ACTION_USER_UNLOCKED));
436         verify(mONSProfileActivator, times(1)).handleCarrierConfigChange();
437 
438         // CarrierConfigChange in Unlock state
439         when(mUserManager.isUserUnlocked()).thenReturn(true);
440         CarrierConfigChangeListener.onCarrierConfigChanged(0, 0, 0, 0);
441         verify(mONSProfileActivator, times(2)).handleCarrierConfigChange();
442     }
443 
444     @Test
445     @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
testTelephonyFeatureAndCompatChanges()446     public void testTelephonyFeatureAndCompatChanges() throws Exception {
447         mSetFlagsRule.enableFlags(Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
448 
449         ArrayList<String> mccMncs = new ArrayList<>();
450         mccMncs.add("310210");
451         AvailableNetworkInfo availableNetworkInfo = new AvailableNetworkInfo(1, 1, mccMncs,
452                 new ArrayList<Integer>());
453         ArrayList<AvailableNetworkInfo> availableNetworkInfos = new ArrayList<>();
454         availableNetworkInfos.add(availableNetworkInfo);
455 
456         // Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined
457         try {
458             // FEATURE_TELEPHONY_DATA
459             iOpportunisticNetworkService.setPreferredDataSubscriptionId(
460                     SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null, pkgForDebug);
461             iOpportunisticNetworkService.getPreferredDataSubscriptionId(pkgForDebug, pkgForFeature);
462 
463             // FEATURE_TELEPHONY_RADIO_ACCESS
464             iOpportunisticNetworkService.setEnable(false, pkgForDebug);
465             iOpportunisticNetworkService.isEnabled(pkgForDebug);
466             iOpportunisticNetworkService.updateAvailableNetworks(availableNetworkInfos, null,
467                     pkgForDebug);
468         } catch (Exception e) {
469             fail("Not expect exception " + e.getMessage());
470         }
471 
472         // Replace field to set SDK version of vendor partition to Android V
473         int vendorApiLevel = Build.VERSION_CODES.VANILLA_ICE_CREAM;
474         replaceInstance(OpportunisticNetworkService.class, "mVendorApiLevel",
475                 mOpportunisticNetworkService, vendorApiLevel);
476 
477         // FEATURE_TELEPHONY_DATA is not defined, expect UnsupportedOperationException.
478         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_DATA))
479                 .thenReturn(false);
480 
481         assertThrows(UnsupportedOperationException.class,
482                 () -> iOpportunisticNetworkService.setPreferredDataSubscriptionId(
483                         SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null, pkgForDebug));
484         assertThrows(UnsupportedOperationException.class,
485                 () -> iOpportunisticNetworkService.getPreferredDataSubscriptionId(
486                         pkgForDebug, pkgForFeature));
487 
488         // FEATURE_TELEPHONY_DATA is not defined, expect UnsupportedOperationException.
489         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS))
490                 .thenReturn(false);
491         assertThrows(UnsupportedOperationException.class,
492                 () -> iOpportunisticNetworkService.setEnable(false, pkgForDebug));
493         assertThrows(UnsupportedOperationException.class,
494                 () -> iOpportunisticNetworkService.isEnabled(pkgForDebug));
495         assertThrows(UnsupportedOperationException.class,
496                 () -> iOpportunisticNetworkService.updateAvailableNetworks(
497                         availableNetworkInfos, null, pkgForDebug));
498     }
499 
replaceInstance(final Class c, final String instanceName, final Object obj, final Object newValue)500     private void replaceInstance(final Class c, final String instanceName, final Object obj,
501             final Object newValue) throws Exception {
502         Field field = c.getDeclaredField(instanceName);
503         field.setAccessible(true);
504         field.set(obj, newValue);
505     }
506 
getIOns()507     private IOns getIOns() {
508         return IOns.Stub.asInterface(
509                 TelephonyFrameworkInitializer
510                         .getTelephonyServiceManager()
511                         .getOpportunisticNetworkServiceRegisterer()
512                         .get());
513     }
514 
waitForMs(long ms)515     public static void waitForMs(long ms) {
516         try {
517             Thread.sleep(ms);
518         } catch (InterruptedException e) {
519             Log.d(TAG, "InterruptedException while waiting: " + e);
520         }
521     }
522 }
523