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