1 /*
2  * Copyright (C) 2015 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.systemui.statusbar.connectivity;
18 
19 import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
20 import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
21 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_DENIED;
22 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
23 
24 import static junit.framework.Assert.assertEquals;
25 import static junit.framework.Assert.assertNotNull;
26 import static junit.framework.Assert.assertTrue;
27 
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.Matchers.anyInt;
30 import static org.mockito.Matchers.eq;
31 import static org.mockito.Matchers.isA;
32 import static org.mockito.Mockito.atLeastOnce;
33 import static org.mockito.Mockito.doAnswer;
34 import static org.mockito.Mockito.doReturn;
35 import static org.mockito.Mockito.mock;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
38 
39 import android.app.Instrumentation;
40 import android.net.ConnectivityManager;
41 import android.net.Network;
42 import android.net.NetworkCapabilities;
43 import android.net.NetworkRequest;
44 import android.net.NetworkScoreManager;
45 import android.net.vcn.VcnTransportInfo;
46 import android.net.wifi.WifiInfo;
47 import android.net.wifi.WifiManager;
48 import android.os.Handler;
49 import android.provider.Settings;
50 import android.provider.Settings.Global;
51 import android.telephony.CellSignalStrength;
52 import android.telephony.NetworkRegistrationInfo;
53 import android.telephony.ServiceState;
54 import android.telephony.SignalStrength;
55 import android.telephony.SubscriptionInfo;
56 import android.telephony.SubscriptionManager;
57 import android.telephony.TelephonyDisplayInfo;
58 import android.telephony.TelephonyManager;
59 import android.testing.TestableLooper;
60 import android.testing.TestableResources;
61 import android.util.Log;
62 
63 import androidx.test.InstrumentationRegistry;
64 
65 import com.android.settingslib.R;
66 import com.android.settingslib.graph.SignalDrawable;
67 import com.android.settingslib.mobile.MobileMappings.Config;
68 import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults;
69 import com.android.settingslib.mobile.TelephonyIcons;
70 import com.android.settingslib.net.DataUsageController;
71 import com.android.systemui.SysuiTestCase;
72 import com.android.systemui.broadcast.BroadcastDispatcher;
73 import com.android.systemui.demomode.DemoModeController;
74 import com.android.systemui.dump.DumpManager;
75 import com.android.systemui.log.LogBuffer;
76 import com.android.systemui.settings.UserTracker;
77 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
78 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy;
79 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
80 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
81 import com.android.systemui.telephony.TelephonyListenerManager;
82 import com.android.systemui.util.CarrierConfigTracker;
83 import com.android.systemui.util.concurrency.FakeExecutor;
84 import com.android.systemui.util.time.FakeSystemClock;
85 
86 import org.junit.After;
87 import org.junit.Before;
88 import org.junit.Rule;
89 import org.junit.rules.TestWatcher;
90 import org.junit.runner.Description;
91 import org.mockito.ArgumentCaptor;
92 import org.mockito.Mockito;
93 import org.mockito.MockitoSession;
94 
95 import java.io.PrintWriter;
96 import java.io.StringWriter;
97 import java.util.ArrayList;
98 import java.util.List;
99 
100 public class NetworkControllerBaseTest extends SysuiTestCase {
101     private static final String TAG = "NetworkControllerBaseTest";
102     protected static final int DEFAULT_LEVEL = 2;
103     protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL;
104     protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL;
105     protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
106     protected static final int DEFAULT_QS_ICON = TelephonyIcons.ICON_3G;
107     protected static final String NO_DATA_STRING = "Data disabled";
108     protected static final String NOT_DEFAULT_DATA_STRING = "Not default data";
109 
110     protected NetworkControllerImpl mNetworkController;
111     protected MobileSignalController mMobileSignalController;
112     protected SignalStrength mSignalStrength;
113     protected ServiceState mServiceState;
114     protected TelephonyDisplayInfo mTelephonyDisplayInfo;
115     protected NetworkRegistrationInfo mFakeRegInfo;
116     protected ConnectivityManager mMockCm;
117     protected WifiManager mMockWm;
118     protected NetworkScoreManager mMockNsm;
119     protected SubscriptionManager mMockSm;
120     protected TelephonyManager mMockTm;
121     protected TelephonyListenerManager mTelephonyListenerManager;
122     protected BroadcastDispatcher mMockBd;
123     protected UserTracker mUserTracker;
124     protected Config mConfig;
125     protected CallbackHandler mCallbackHandler;
126     protected SubscriptionDefaults mMockSubDefaults;
127     protected DeviceProvisionedController mMockProvisionController;
128     protected DeviceProvisionedListener mUserCallback;
129     protected Instrumentation mInstrumentation;
130     protected DemoModeController mDemoModeController;
131     protected CarrierConfigTracker mCarrierConfigTracker;
132     protected FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
133     protected Handler mMainHandler;
134     // Use a real mobile mappings object since lots of tests rely on it
135     protected FakeMobileMappingsProxy mMobileMappingsProxy = new FakeMobileMappingsProxy();
136     protected WifiStatusTrackerFactory mWifiStatusTrackerFactory;
137     protected MobileSignalControllerFactory mMobileFactory;
138 
139     protected int mSubId;
140 
141     private NetworkCapabilities mNetCapabilities;
142     private ConnectivityManager.NetworkCallback mDefaultCallbackInWifiTracker;
143     private ConnectivityManager.NetworkCallback mDefaultCallbackInNetworkController;
144     private ConnectivityManager.NetworkCallback mNetworkCallback;
145 
146     MockitoSession mMockingSession = null;
147 
148     @Rule
149     public TestWatcher failWatcher = new TestWatcher() {
150         @Override
151         protected void failed(Throwable e, Description description) {
152             if (mNetworkController == null) {
153                 Log.d(TAG, "mNetworkController = null!");
154                 return;
155             }
156             // Print out mNetworkController state if the test fails.
157             StringWriter sw = new StringWriter();
158             PrintWriter pw = new PrintWriter(sw);
159             mNetworkController.dump(pw, null);
160             pw.flush();
161             Log.d(TAG, sw.toString());
162         }
163     };
164 
165     @Before
setUp()166     public void setUp() throws Exception {
167         mInstrumentation = InstrumentationRegistry.getInstrumentation();
168         Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0);
169         TestableResources res = mContext.getOrCreateTestableResources();
170         res.addOverride(R.string.cell_data_off_content_description, NO_DATA_STRING);
171         res.addOverride(R.string.not_default_data_content_description, NOT_DEFAULT_DATA_STRING);
172 
173         mDemoModeController = mock(DemoModeController.class);
174         mMockWm = mock(WifiManager.class);
175         mMockTm = mock(TelephonyManager.class);
176         mTelephonyListenerManager = mock(TelephonyListenerManager.class);
177         mMockSm = mock(SubscriptionManager.class);
178         mMockCm = mock(ConnectivityManager.class);
179         mMockBd = mock(BroadcastDispatcher.class);
180         mUserTracker = mock(UserTracker.class);
181         mMockNsm = mock(NetworkScoreManager.class);
182         mMockSubDefaults = mock(SubscriptionDefaults.class);
183         mCarrierConfigTracker = mock(CarrierConfigTracker.class);
184         mMainHandler = mock(Handler.class);
185         mNetCapabilities = new NetworkCapabilities();
186         when(mMockTm.isDataCapable()).thenReturn(true);
187         when(mMockTm.createForSubscriptionId(anyInt())).thenReturn(mMockTm);
188 
189         doAnswer(invocation -> {
190             ((Runnable) invocation.getArgument(0)).run();
191             return null;
192         }).when(mMainHandler).post(any());
193         doAnswer(invocation -> {
194             int rssi = invocation.getArgument(0);
195             if (rssi < -88) return 0;
196             if (rssi < -77) return 1;
197             if (rssi < -66) return 2;
198             if (rssi < -55) return 3;
199             return 4;
200         }).when(mMockWm).calculateSignalLevel(anyInt());
201         when(mMockWm.getMaxSignalLevel()).thenReturn(4);
202 
203         mSignalStrength = mock(SignalStrength.class);
204         mServiceState = mock(ServiceState.class);
205         mTelephonyDisplayInfo = mock(TelephonyDisplayInfo.class);
206 
207         mFakeRegInfo = new NetworkRegistrationInfo.Builder()
208                 .setTransportType(TRANSPORT_TYPE_WWAN)
209                 .setDomain(DOMAIN_PS)
210                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
211                 .build();
212         doReturn(mFakeRegInfo).when(mServiceState)
213                 .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
214         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mTelephonyDisplayInfo).getNetworkType();
215         doReturn(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE).when(mTelephonyDisplayInfo)
216                 .getOverrideNetworkType();
217         mConfig = new Config();
218         mConfig.hspaDataDistinguishable = true;
219         mCallbackHandler = mock(CallbackHandler.class);
220 
221         mMockProvisionController = mock(DeviceProvisionedController.class);
222         when(mMockProvisionController.isCurrentUserSetup()).thenReturn(true);
223         doAnswer(invocation -> {
224             mUserCallback = (DeviceProvisionedListener) invocation.getArguments()[0];
225             TestableLooper.get(this).processAllMessages();
226             return null;
227         }).when(mMockProvisionController).addCallback(any());
228 
229         mWifiStatusTrackerFactory = new WifiStatusTrackerFactory(
230                 mContext, mMockWm, mMockNsm, mMockCm, mMainHandler);
231         // Most of these tests rely on the actual MobileMappings behavior
232         mMobileMappingsProxy.setUseRealImpl(true);
233         mMobileFactory = new MobileSignalControllerFactory(
234                 mContext,
235                 mCallbackHandler,
236                 mCarrierConfigTracker,
237                 mMobileMappingsProxy
238         );
239 
240         mNetworkController = new NetworkControllerImpl(mContext,
241                 mMockCm,
242                 mMockTm,
243                 mTelephonyListenerManager,
244                 mMockWm,
245                 mMockSm,
246                 mConfig,
247                 TestableLooper.get(this).getLooper(),
248                 mFakeExecutor,
249                 mCallbackHandler,
250                 mock(AccessPointControllerImpl.class),
251                 mock(StatusBarPipelineFlags.class),
252                 mock(DataUsageController.class),
253                 mMockSubDefaults,
254                 mMockProvisionController,
255                 mMockBd,
256                 mUserTracker,
257                 mDemoModeController,
258                 mCarrierConfigTracker,
259                 mWifiStatusTrackerFactory,
260                 mMobileFactory,
261                 mMainHandler,
262                 mock(DumpManager.class),
263                 mock(LogBuffer.class)
264         );
265         setupNetworkController();
266 
267         // Trigger blank callbacks to always get the current state (some tests don't trigger
268         // changes from default state).
269         mNetworkController.addCallback(mock(SignalCallback.class));
270         mNetworkController.addEmergencyListener(null);
271     }
272 
273     @After
tearDown()274     public void tearDown() throws Exception {
275         if (mMockingSession != null) {
276             mMockingSession.finishMocking();
277         }
278     }
279 
setupNetworkController()280     protected void setupNetworkController() {
281         // For now just pretend to be the data sim, so we can test that too.
282         mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
283         when(mMockTm.isDataConnectionAllowed()).thenReturn(true);
284         setDefaultSubId(mSubId);
285         setSubscriptions(mSubId);
286         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
287         ArgumentCaptor<ConnectivityManager.NetworkCallback> callbackArg =
288                 ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
289         verify(mMockCm, atLeastOnce())
290             .registerDefaultNetworkCallback(callbackArg.capture(), isA(Handler.class));
291         int captureSize = callbackArg.getAllValues().size();
292         assertTrue(captureSize > 1);
293         assertEquals(captureSize % 2, 0);
294         mDefaultCallbackInWifiTracker = callbackArg.getAllValues().get(captureSize - 2);
295         mDefaultCallbackInNetworkController = callbackArg.getAllValues().get(captureSize - 1);
296         assertNotNull(mDefaultCallbackInWifiTracker);
297         assertNotNull(mDefaultCallbackInNetworkController);
298         verify(mMockCm, atLeastOnce()).registerNetworkCallback(
299                 isA(NetworkRequest.class), callbackArg.capture(), isA(Handler.class));
300         mNetworkCallback = callbackArg.getValue();
301         assertNotNull(mNetworkCallback);
302     }
303 
setDefaultSubId(int subId)304     protected void setDefaultSubId(int subId) {
305         when(mMockSubDefaults.getDefaultDataSubId()).thenReturn(subId);
306         when(mMockSubDefaults.getDefaultVoiceSubId()).thenReturn(subId);
307         when(mMockSubDefaults.getActiveDataSubId()).thenReturn(subId);
308     }
309 
setSubscriptions(int... subIds)310     protected void setSubscriptions(int... subIds) {
311         List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
312         for (int subId : subIds) {
313             SubscriptionInfo subscription = mock(SubscriptionInfo.class);
314             when(subscription.getSubscriptionId()).thenReturn(subId);
315             subs.add(subscription);
316         }
317         when(mMockSm.getActiveSubscriptionInfoList()).thenReturn(subs);
318         when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(subs);
319         mNetworkController.doUpdateMobileControllers();
320     }
321 
322     // 2 Bars 3G GSM.
setupDefaultSignal()323     public void setupDefaultSignal() {
324         setIsGsm(true);
325         setVoiceRegState(ServiceState.STATE_IN_SERVICE);
326         setGsmRoaming(false);
327         setLevel(DEFAULT_LEVEL);
328         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
329                 TelephonyManager.NETWORK_TYPE_UMTS);
330         setConnectivityViaCallbackInNetworkController(
331                 NetworkCapabilities.TRANSPORT_CELLULAR, true, true, null);
332     }
333 
setConnectivityViaCallbackInNetworkControllerForVcn( int networkType, boolean validated, boolean isConnected, VcnTransportInfo info)334     public void setConnectivityViaCallbackInNetworkControllerForVcn(
335             int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
336         final NetworkCapabilities.Builder builder =
337                 new NetworkCapabilities.Builder(mNetCapabilities);
338         builder.setTransportInfo(info);
339         setConnectivityCommon(builder, networkType, validated, isConnected);
340         mDefaultCallbackInNetworkController.onCapabilitiesChanged(
341                 mock(Network.class), builder.build());
342     }
343 
setConnectivityViaCallbackInNetworkController( Network network, NetworkCapabilities networkCapabilities)344     public void setConnectivityViaCallbackInNetworkController(
345             Network network, NetworkCapabilities networkCapabilities) {
346         mDefaultCallbackInNetworkController.onCapabilitiesChanged(network, networkCapabilities);
347     }
348 
setConnectivityViaCallbackInNetworkController( int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo)349     public void setConnectivityViaCallbackInNetworkController(
350             int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
351         final NetworkCapabilities.Builder builder =
352                 new NetworkCapabilities.Builder(mNetCapabilities);
353         if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
354             builder.setTransportInfo(wifiInfo);
355         }
356         setConnectivityCommon(builder, networkType, validated, isConnected);
357         mDefaultCallbackInNetworkController.onCapabilitiesChanged(
358                 mock(Network.class), builder.build());
359     }
360 
setConnectivityViaDefaultAndNormalCallbackInWifiTracker( Network network, NetworkCapabilities networkCapabilities)361     public void setConnectivityViaDefaultAndNormalCallbackInWifiTracker(
362             Network network, NetworkCapabilities networkCapabilities) {
363         mNetworkCallback.onAvailable(network);
364         mNetworkCallback.onCapabilitiesChanged(network, networkCapabilities);
365         mDefaultCallbackInWifiTracker.onCapabilitiesChanged(network, networkCapabilities);
366     }
367 
setConnectivityViaCallbackInWifiTracker( int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo)368     public void setConnectivityViaCallbackInWifiTracker(
369             int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
370         final NetworkCapabilities.Builder builder =
371                 new NetworkCapabilities.Builder(mNetCapabilities);
372         if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
373             builder.setTransportInfo(wifiInfo);
374         }
375         setConnectivityCommon(builder, networkType, validated, isConnected);
376         if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
377             if (isConnected) {
378                 final NetworkCapabilities newCap = builder.build();
379                 mNetworkCallback.onAvailable(mock(Network.class));
380                 mNetworkCallback.onCapabilitiesChanged(mock(Network.class), newCap);
381             } else {
382                 mNetworkCallback.onLost(mock(Network.class));
383             }
384         }
385     }
386 
setConnectivityViaCallbackInWifiTrackerForVcn( int networkType, boolean validated, boolean isConnected, VcnTransportInfo info)387     public void setConnectivityViaCallbackInWifiTrackerForVcn(
388             int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
389         final NetworkCapabilities.Builder builder =
390                 new NetworkCapabilities.Builder(mNetCapabilities);
391         builder.setTransportInfo(info);
392         setConnectivityCommon(builder, networkType, validated, isConnected);
393         if (networkType == NetworkCapabilities.TRANSPORT_CELLULAR) {
394             if (isConnected) {
395                 final NetworkCapabilities newCap = builder.build();
396                 mNetworkCallback.onAvailable(mock(Network.class));
397                 mNetworkCallback.onCapabilitiesChanged(mock(Network.class), newCap);
398                 mDefaultCallbackInWifiTracker.onCapabilitiesChanged(mock(Network.class), newCap);
399             } else {
400                 mNetworkCallback.onLost(mock(Network.class));
401             }
402         }
403     }
404 
setConnectivityViaDefaultCallbackInWifiTracker( int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo)405     public void setConnectivityViaDefaultCallbackInWifiTracker(
406             int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
407         final NetworkCapabilities.Builder builder =
408                 new NetworkCapabilities.Builder(mNetCapabilities);
409         if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
410             builder.setTransportInfo(wifiInfo);
411         }
412         setConnectivityCommon(builder, networkType, validated, isConnected);
413         mDefaultCallbackInWifiTracker.onCapabilitiesChanged(
414                 mock(Network.class), builder.build());
415     }
416 
setConnectivityCommon(NetworkCapabilities.Builder builder, int networkType, boolean validated, boolean isConnected)417     private static void setConnectivityCommon(NetworkCapabilities.Builder builder,
418             int networkType, boolean validated, boolean isConnected) {
419         // TODO: Separate out into several NetworkCapabilities.
420         if (isConnected) {
421             builder.addTransportType(networkType);
422         } else {
423             builder.removeTransportType(networkType);
424         }
425         if (validated) {
426             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
427         } else {
428             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
429         }
430     }
431 
setGsmRoaming(boolean isRoaming)432     public void setGsmRoaming(boolean isRoaming) {
433         when(mServiceState.getRoaming()).thenReturn(isRoaming);
434         updateServiceState();
435     }
436 
setCdmaRoaming(boolean isRoaming)437     public void setCdmaRoaming(boolean isRoaming) {
438         when(mMockTm.getCdmaEnhancedRoamingIndicatorDisplayNumber()).thenReturn(
439                 isRoaming ? TelephonyManager.ERI_ON : TelephonyManager.ERI_OFF);
440     }
441 
setVoiceRegState(int voiceRegState)442     public void setVoiceRegState(int voiceRegState) {
443         when(mServiceState.getState()).thenReturn(voiceRegState);
444         when(mServiceState.getVoiceRegState()).thenReturn(voiceRegState);
445         updateServiceState();
446     }
447 
setDataRegInService(boolean inService)448     public void setDataRegInService(boolean inService) {
449         // mFakeRegInfo#isInService()
450         // Utils#isInService uses NetworkRegistrationInfo#isInService(). Since we can't
451         // mock the answer here, just set the bit based on what the caller wants
452         NetworkRegistrationInfo.Builder builder = new NetworkRegistrationInfo.Builder()
453                 .setTransportType(TRANSPORT_TYPE_WWAN)
454                 .setDomain(DOMAIN_PS)
455                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE);
456 
457         if (inService) {
458             builder.setRegistrationState(REGISTRATION_STATE_HOME);
459         } else {
460             builder.setRegistrationState(REGISTRATION_STATE_DENIED);
461         }
462 
463         NetworkRegistrationInfo fakeRegInfo = builder.build();
464         when(mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN))
465                 .thenReturn(fakeRegInfo);
466 
467         updateServiceState();
468     }
469 
setIsEmergencyOnly(boolean isEmergency)470     public void setIsEmergencyOnly(boolean isEmergency) {
471         when(mServiceState.isEmergencyOnly()).thenReturn(isEmergency);
472         updateServiceState();
473     }
474 
setCdmaLevel(int level)475     public void setCdmaLevel(int level) {
476         when(mSignalStrength.getCdmaLevel()).thenReturn(level);
477         updateSignalStrength();
478     }
479 
setLevel(int level)480     public void setLevel(int level) {
481         when(mSignalStrength.getLevel()).thenReturn(level);
482         updateSignalStrength();
483     }
484 
setIsGsm(boolean gsm)485     public void setIsGsm(boolean gsm) {
486         when(mSignalStrength.isGsm()).thenReturn(gsm);
487         updateSignalStrength();
488     }
489 
setCdmaEri(int index, int mode)490     public void setCdmaEri(int index, int mode) {
491         // TODO: Figure this out.
492     }
493 
updateSignalStrength()494     private void updateSignalStrength() {
495         Log.d(TAG, "Sending Signal Strength: " + mSignalStrength);
496         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
497                 .onSignalStrengthsChanged(mSignalStrength);
498     }
499 
updateServiceState()500     protected void updateServiceState() {
501         Log.d(TAG, "Sending Service State: " + mServiceState);
502         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
503                 .onServiceStateChanged(mServiceState);
504         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
505                 .onDisplayInfoChanged(mTelephonyDisplayInfo);
506     }
507 
updateDataConnectionState(int dataState, int dataNetType)508     public void updateDataConnectionState(int dataState, int dataNetType) {
509         NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder()
510                 .setTransportType(TRANSPORT_TYPE_WWAN)
511                 .setDomain(DOMAIN_PS)
512                 .setAccessNetworkTechnology(dataNetType)
513                 .build();
514         when(mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN))
515                 .thenReturn(fakeRegInfo);
516         when(mTelephonyDisplayInfo.getNetworkType()).thenReturn(dataNetType);
517         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
518                 .onDataConnectionStateChanged(dataState, dataNetType);
519     }
520 
updateDataActivity(int dataActivity)521     public void updateDataActivity(int dataActivity) {
522         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
523                 .onDataActivity(dataActivity);
524     }
525 
setCarrierNetworkChange(boolean enable)526     public void setCarrierNetworkChange(boolean enable) {
527         Log.d(TAG, "setCarrierNetworkChange(" + enable + ")");
528         mMobileSignalController.mMobileStatusTracker.getTelephonyCallback()
529                 .onCarrierNetworkChange(enable);
530     }
531 
verifyHasNoSims(boolean hasNoSimsVisible)532     protected void verifyHasNoSims(boolean hasNoSimsVisible) {
533         verify(mCallbackHandler, Mockito.atLeastOnce()).setNoSims(
534                 eq(hasNoSimsVisible), eq(false));
535     }
536 
verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean dataIn, boolean dataOut)537     protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon,
538             boolean dataIn, boolean dataOut) {
539         ArgumentCaptor<MobileDataIndicators> indicatorsArg =
540                 ArgumentCaptor.forClass(MobileDataIndicators.class);
541 
542         verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
543                     indicatorsArg.capture());
544         MobileDataIndicators expected = indicatorsArg.getValue();
545         int state = SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(),
546                 false);
547         assertEquals("Visibility in, quick settings", visible, expected.qsIcon.visible);
548         assertEquals("Signal icon in, quick settings", state, expected.qsIcon.icon);
549         assertEquals("Data icon in, quick settings", typeIcon, expected.qsType);
550         assertEquals("Data direction in, in quick settings", dataIn,
551                 expected.activityIn);
552         assertEquals("Data direction out, in quick settings", dataOut,
553                 expected.activityOut);
554     }
555 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon)556     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) {
557         verifyLastMobileDataIndicators(visible, icon, typeIcon, false);
558     }
559 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean roaming)560     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
561             boolean roaming) {
562         verifyLastMobileDataIndicators(visible, icon, typeIcon, roaming, true);
563     }
564 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean roaming, boolean inet)565     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
566             boolean roaming, boolean inet) {
567         ArgumentCaptor<MobileDataIndicators> indicatorsArg =
568                 ArgumentCaptor.forClass(MobileDataIndicators.class);
569 
570         // TODO: Verify all fields.
571         verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
572                 indicatorsArg.capture());
573         MobileDataIndicators expected = indicatorsArg.getValue();
574         int state = icon == -1 ? 0
575                 : SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(),
576                         !inet);
577         assertEquals("Signal icon in status bar", state, expected.statusIcon.icon);
578         assertEquals("Data icon in status bar", typeIcon, expected.statusType);
579         assertEquals("Visibility in status bar", visible, expected.statusIcon.visible);
580     }
581 
verifyLastMobileDataIndicatorsForVcn(boolean visible, int level, int typeIcon, boolean inet)582     protected void verifyLastMobileDataIndicatorsForVcn(boolean visible, int level, int typeIcon,
583             boolean inet) {
584         ArgumentCaptor<MobileDataIndicators> indicatorsArg =
585                 ArgumentCaptor.forClass(MobileDataIndicators.class);
586 
587         verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
588                 indicatorsArg.capture());
589 
590         MobileDataIndicators expected = indicatorsArg.getValue();
591         int state = SignalDrawable.getState(
592                 level, CellSignalStrength.getNumSignalStrengthLevels(), !inet);
593         assertEquals("Signal icon in status bar", state, expected.statusIcon.icon);
594         assertEquals("Data icon in status bar", typeIcon, expected.statusType);
595         assertEquals("Visibility in status bar", visible, expected.statusIcon.visible);
596     }
597 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut)598     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
599             boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) {
600         verifyLastMobileDataIndicators(
601                 visible, icon, typeIcon, qsVisible, qsIcon, qsTypeIcon, dataIn, dataOut, false);
602     }
603 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut, boolean cutOut)604     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
605             boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut,
606             boolean cutOut) {
607         verifyLastMobileDataIndicators(
608                 visible, icon, typeIcon, qsVisible, qsIcon, qsTypeIcon, dataIn, dataOut, cutOut,
609                 null, null, visible);
610     }
611 
verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut, boolean cutOut, CharSequence typeContentDescription, CharSequence typeContentDescriptionHtml, boolean showQs)612     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
613             boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut,
614             boolean cutOut, CharSequence typeContentDescription,
615             CharSequence typeContentDescriptionHtml, boolean showQs) {
616         ArgumentCaptor<MobileDataIndicators> indicatorsArg =
617                 ArgumentCaptor.forClass(MobileDataIndicators.class);
618         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
619         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
620         ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class);
621         ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
622         ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
623         ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
624         ArgumentCaptor<CharSequence> typeContentDescriptionArg =
625                 ArgumentCaptor.forClass(CharSequence.class);
626         ArgumentCaptor<CharSequence> typeContentDescriptionHtmlArg =
627                 ArgumentCaptor.forClass(CharSequence.class);
628 
629         verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
630                 indicatorsArg.capture());
631 
632         MobileDataIndicators expected = indicatorsArg.getValue();
633 
634         int numSignalStrengthBins = CellSignalStrength.getNumSignalStrengthLevels();
635         if (mMobileSignalController.mInflateSignalStrengths) {
636             numSignalStrengthBins++;
637             icon++;
638         }
639         int state = SignalDrawable.getState(icon, numSignalStrengthBins, cutOut);
640         assertEquals("Data icon in status bar", typeIcon, expected.statusType);
641         assertEquals("Signal icon in status bar", state, expected.statusIcon.icon);
642         assertEquals("Visibility in status bar", visible, expected.statusIcon.visible);
643 
644         if (showQs) {
645             assertEquals("Visibility in quick settings", qsVisible, expected.qsIcon.visible);
646             assertEquals("Signal icon in quick settings", state, expected.qsIcon.icon);
647         } else {
648             assertEquals("Cellular is not default", null, expected.qsIcon);
649         }
650         assertEquals("Data icon in quick settings", qsTypeIcon, expected.qsType);
651         assertEquals("Data direction in in quick settings", dataIn,
652                 expected.activityIn);
653         assertEquals("Data direction out in quick settings", dataOut,
654                 expected.activityOut);
655         if (typeContentDescription != null) { // Only check if it was provided
656             assertEquals("Type content description", typeContentDescription,
657                     expected.typeContentDescription);
658         }
659         if (typeContentDescriptionHtml != null) { // Only check if it was provided
660             assertEquals("Type content description (html)", typeContentDescriptionHtml,
661                     expected.typeContentDescriptionHtml);
662         }
663     }
664 
verifyLastCallStrength(int icon)665     protected void verifyLastCallStrength(int icon) {
666         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
667         verify(mCallbackHandler, Mockito.atLeastOnce()).setCallIndicator(
668                 iconArg.capture(),
669                 anyInt());
670         assertEquals("Call strength, in status bar", icon, (int) iconArg.getValue().icon);
671     }
672 
assertNetworkNameEquals(String expected)673     protected void assertNetworkNameEquals(String expected) {
674         assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
675     }
676 
assertDataNetworkNameEquals(String expected)677     protected void assertDataNetworkNameEquals(String expected) {
678         assertEquals("Data network name", expected, mNetworkController.getMobileDataNetworkName());
679     }
680 }
681 
682