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.policy; 18 19 import android.content.Intent; 20 import android.net.ConnectivityManager; 21 import android.net.NetworkCapabilities; 22 import android.net.wifi.WifiManager; 23 import android.os.Looper; 24 import android.provider.Settings; 25 import android.provider.Settings.Global; 26 import android.telephony.PhoneStateListener; 27 import android.telephony.ServiceState; 28 import android.telephony.SignalStrength; 29 import android.telephony.SubscriptionInfo; 30 import android.telephony.SubscriptionManager; 31 import android.telephony.TelephonyManager; 32 import android.util.Log; 33 import com.android.internal.telephony.cdma.EriInfo; 34 import com.android.settingslib.net.DataUsageController; 35 import com.android.systemui.statusbar.phone.SignalDrawable; 36 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; 37 import com.android.systemui.statusbar.policy.NetworkController.IconState; 38 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; 39 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config; 40 import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults; 41 import com.android.systemui.SysuiTestCase; 42 43 import org.junit.Before; 44 import org.junit.Rule; 45 import org.junit.rules.TestWatcher; 46 import org.junit.runner.Description; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Mockito; 49 50 import java.io.PrintWriter; 51 import java.io.StringWriter; 52 import java.util.ArrayList; 53 import java.util.List; 54 55 import static junit.framework.Assert.assertEquals; 56 57 import static org.mockito.Matchers.any; 58 import static org.mockito.Matchers.anyBoolean; 59 import static org.mockito.Matchers.anyInt; 60 import static org.mockito.Matchers.anyString; 61 import static org.mockito.Matchers.eq; 62 import static org.mockito.Mockito.doAnswer; 63 import static org.mockito.Mockito.mock; 64 import static org.mockito.Mockito.when; 65 66 public class NetworkControllerBaseTest extends SysuiTestCase { 67 private static final String TAG = "NetworkControllerBaseTest"; 68 protected static final int DEFAULT_LEVEL = 2; 69 protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL; 70 protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL; 71 protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G; 72 protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_DATA_3G; 73 74 protected NetworkControllerImpl mNetworkController; 75 protected MobileSignalController mMobileSignalController; 76 protected PhoneStateListener mPhoneStateListener; 77 protected SignalStrength mSignalStrength; 78 protected ServiceState mServiceState; 79 protected ConnectivityManager mMockCm; 80 protected WifiManager mMockWm; 81 protected SubscriptionManager mMockSm; 82 protected TelephonyManager mMockTm; 83 protected Config mConfig; 84 protected CallbackHandler mCallbackHandler; 85 protected SubscriptionDefaults mMockSubDefaults; 86 protected DeviceProvisionedController mMockProvisionController; 87 protected DeviceProvisionedListener mUserCallback; 88 89 protected int mSubId; 90 91 private NetworkCapabilities mNetCapabilities; 92 93 @Rule 94 public TestWatcher failWatcher = new TestWatcher() { 95 @Override 96 protected void failed(Throwable e, Description description) { 97 // Print out mNetworkController state if the test fails. 98 StringWriter sw = new StringWriter(); 99 PrintWriter pw = new PrintWriter(sw); 100 mNetworkController.dump(null, pw, null); 101 pw.flush(); 102 Log.d(TAG, sw.toString()); 103 } 104 }; 105 106 @Before 107 public void setUp() throws Exception { 108 Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0); 109 mMockWm = mock(WifiManager.class); 110 mMockTm = mock(TelephonyManager.class); 111 mMockSm = mock(SubscriptionManager.class); 112 mMockCm = mock(ConnectivityManager.class); 113 mMockSubDefaults = mock(SubscriptionDefaults.class); 114 mNetCapabilities = new NetworkCapabilities(); 115 when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true); 116 when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn( 117 new NetworkCapabilities[] { mNetCapabilities }); 118 119 mSignalStrength = mock(SignalStrength.class); 120 mServiceState = mock(ServiceState.class); 121 122 mConfig = new Config(); 123 mConfig.hspaDataDistinguishable = true; 124 mCallbackHandler = mock(CallbackHandler.class); 125 126 mMockProvisionController = mock(DeviceProvisionedController.class); 127 when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(true); 128 doAnswer(invocation -> { 129 mUserCallback = (DeviceProvisionedListener) invocation.getArguments()[0]; 130 mUserCallback.onUserSetupChanged(); 131 mUserCallback.onDeviceProvisionedChanged(); 132 return null; 133 }).when(mMockProvisionController).addCallback(any()); 134 135 mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, 136 mConfig, Looper.getMainLooper(), mCallbackHandler, 137 mock(AccessPointControllerImpl.class), mock(DataUsageController.class), 138 mMockSubDefaults, mMockProvisionController); 139 setupNetworkController(); 140 141 // Trigger blank callbacks to always get the current state (some tests don't trigger 142 // changes from default state). 143 mNetworkController.addCallback(mock(SignalCallback.class)); 144 mNetworkController.addEmergencyListener(null); 145 } 146 147 protected void setupNetworkController() { 148 // For now just pretend to be the data sim, so we can test that too. 149 mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 150 when(mMockTm.getDataEnabled(mSubId)).thenReturn(true); 151 setDefaultSubId(mSubId); 152 setSubscriptions(mSubId); 153 mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId); 154 mPhoneStateListener = mMobileSignalController.mPhoneStateListener; 155 } 156 157 protected void setDefaultSubId(int subId) { 158 when(mMockSubDefaults.getDefaultDataSubId()).thenReturn(subId); 159 when(mMockSubDefaults.getDefaultVoiceSubId()).thenReturn(subId); 160 } 161 162 protected void setSubscriptions(int... subIds) { 163 List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>(); 164 for (int subId : subIds) { 165 SubscriptionInfo subscription = mock(SubscriptionInfo.class); 166 when(subscription.getSubscriptionId()).thenReturn(subId); 167 subs.add(subscription); 168 } 169 when(mMockSm.getActiveSubscriptionInfoList()).thenReturn(subs); 170 mNetworkController.doUpdateMobileControllers(); 171 } 172 173 protected NetworkControllerImpl setUpNoMobileData() { 174 when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false); 175 NetworkControllerImpl networkControllerNoMobile 176 = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm, 177 mConfig, mContext.getMainLooper(), mCallbackHandler, 178 mock(AccessPointControllerImpl.class), 179 mock(DataUsageController.class), mMockSubDefaults, 180 mock(DeviceProvisionedController.class)); 181 182 setupNetworkController(); 183 184 return networkControllerNoMobile; 185 186 } 187 188 // 2 Bars 3G GSM. 189 public void setupDefaultSignal() { 190 setIsGsm(true); 191 setVoiceRegState(ServiceState.STATE_IN_SERVICE); 192 setGsmRoaming(false); 193 setLevel(DEFAULT_LEVEL); 194 updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 195 TelephonyManager.NETWORK_TYPE_UMTS); 196 setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, true, true); 197 } 198 199 public void setConnectivity(int networkType, boolean inetCondition, boolean isConnected) { 200 Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION); 201 // TODO: Separate out into several NetworkCapabilities. 202 if (isConnected) { 203 mNetCapabilities.addTransportType(networkType); 204 } else { 205 mNetCapabilities.removeTransportType(networkType); 206 } 207 if (inetCondition) { 208 mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); 209 } else { 210 mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); 211 } 212 213 mNetworkController.onReceive(mContext, i); 214 } 215 216 public void setGsmRoaming(boolean isRoaming) { 217 when(mServiceState.getRoaming()).thenReturn(isRoaming); 218 updateServiceState(); 219 } 220 221 public void setCdmaRoaming(boolean isRoaming) { 222 when(mServiceState.getCdmaEriIconIndex()).thenReturn(isRoaming ? 223 EriInfo.ROAMING_INDICATOR_ON : EriInfo.ROAMING_INDICATOR_OFF); 224 when(mServiceState.getCdmaEriIconMode()).thenReturn(isRoaming ? 225 EriInfo.ROAMING_ICON_MODE_NORMAL : -1); 226 updateServiceState(); 227 } 228 229 public void setVoiceRegState(int voiceRegState) { 230 when(mServiceState.getVoiceRegState()).thenReturn(voiceRegState); 231 updateServiceState(); 232 } 233 234 public void setDataRegState(int dataRegState) { 235 when(mServiceState.getDataRegState()).thenReturn(dataRegState); 236 updateServiceState(); 237 } 238 239 public void setIsEmergencyOnly(boolean isEmergency) { 240 when(mServiceState.isEmergencyOnly()).thenReturn(isEmergency); 241 updateServiceState(); 242 } 243 244 public void setCdmaLevel(int level) { 245 when(mSignalStrength.getCdmaLevel()).thenReturn(level); 246 updateSignalStrength(); 247 } 248 249 public void setLevel(int level) { 250 when(mSignalStrength.getLevel()).thenReturn(level); 251 updateSignalStrength(); 252 } 253 254 public void setIsGsm(boolean gsm) { 255 when(mSignalStrength.isGsm()).thenReturn(gsm); 256 updateSignalStrength(); 257 } 258 259 public void setCdmaEri(int index, int mode) { 260 // TODO: Figure this out. 261 } 262 263 private void updateSignalStrength() { 264 Log.d(TAG, "Sending Signal Strength: " + mSignalStrength); 265 mPhoneStateListener.onSignalStrengthsChanged(mSignalStrength); 266 } 267 268 protected void updateServiceState() { 269 Log.d(TAG, "Sending Service State: " + mServiceState); 270 mPhoneStateListener.onServiceStateChanged(mServiceState); 271 } 272 273 public void updateCallState(int state) { 274 // Inputs not currently used in NetworkControllerImpl. 275 mPhoneStateListener.onCallStateChanged(state, "0123456789"); 276 } 277 278 public void updateDataConnectionState(int dataState, int dataNetType) { 279 when(mServiceState.getDataNetworkType()).thenReturn(dataNetType); 280 mPhoneStateListener.onDataConnectionStateChanged(dataState, dataNetType); 281 } 282 283 public void updateDataActivity(int dataActivity) { 284 mPhoneStateListener.onDataActivity(dataActivity); 285 } 286 287 public void setCarrierNetworkChange(boolean enable) { 288 Log.d(TAG, "setCarrierNetworkChange(" + enable + ")"); 289 mPhoneStateListener.onCarrierNetworkChange(enable); 290 } 291 292 protected void verifyHasNoSims(boolean hasNoSimsVisible) { 293 Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setNoSims( 294 eq(hasNoSimsVisible), eq(false)); 295 } 296 297 protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon, 298 boolean dataIn, boolean dataOut) { 299 ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); 300 ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); 301 ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class); 302 ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class); 303 304 Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( 305 any(), 306 iconArg.capture(), 307 anyInt(), 308 typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(), 309 anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean()); 310 IconState iconState = iconArg.getValue(); 311 int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, 312 false); 313 assertEquals("Visibility in, quick settings", visible, iconState.visible); 314 assertEquals("Signal icon in, quick settings", state, iconState.icon); 315 assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue()); 316 assertEquals("Data direction in, in quick settings", dataIn, 317 (boolean) dataInArg.getValue()); 318 assertEquals("Data direction out, in quick settings", dataOut, 319 (boolean) dataOutArg.getValue()); 320 } 321 322 protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) { 323 verifyLastMobileDataIndicators(visible, icon, typeIcon, false); 324 } 325 326 protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, 327 boolean roaming) { 328 verifyLastMobileDataIndicators(visible, icon, typeIcon, roaming, true); 329 } 330 331 protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, 332 boolean roaming, boolean inet) { 333 ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); 334 ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); 335 336 // TODO: Verify all fields. 337 Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( 338 iconArg.capture(), 339 any(), 340 typeIconArg.capture(), 341 anyInt(), anyBoolean(), anyBoolean(), anyString(), anyString(), anyBoolean(), 342 anyInt(), eq(roaming)); 343 IconState iconState = iconArg.getValue(); 344 345 int state = icon == -1 ? 0 346 : SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, !inet); 347 assertEquals("Signal icon in status bar", state, iconState.icon); 348 assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); 349 assertEquals("Visibility in status bar", visible, iconState.visible); 350 } 351 352 protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, 353 boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) { 354 ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); 355 ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); 356 ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class); 357 ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class); 358 ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class); 359 ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class); 360 361 Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( 362 iconArg.capture(), 363 qsIconArg.capture(), 364 typeIconArg.capture(), 365 qsTypeIconArg.capture(), 366 dataInArg.capture(), 367 dataOutArg.capture(), 368 anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean()); 369 370 IconState iconState = iconArg.getValue(); 371 372 int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, 373 false); 374 assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); 375 assertEquals("Signal icon in status bar", state, iconState.icon); 376 assertEquals("Visibility in status bar", visible, iconState.visible); 377 378 iconState = qsIconArg.getValue(); 379 assertEquals("Visibility in quick settings", qsVisible, iconState.visible); 380 assertEquals("Signal icon in quick settings", state, iconState.icon); 381 assertEquals("Data icon in quick settings", qsTypeIcon, (int) qsTypeIconArg.getValue()); 382 assertEquals("Data direction in in quick settings", dataIn, 383 (boolean) dataInArg.getValue()); 384 assertEquals("Data direction out in quick settings", dataOut, 385 (boolean) dataOutArg.getValue()); 386 } 387 388 protected void assertNetworkNameEquals(String expected) { 389 assertEquals("Network name", expected, mMobileSignalController.getState().networkName); 390 } 391 } 392