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.server.wifi; 18 19 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; 20 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; 21 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED; 22 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE; 23 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY; 24 25 import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION; 26 27 import static org.junit.Assert.assertArrayEquals; 28 import static org.junit.Assert.assertEquals; 29 import static org.junit.Assert.assertFalse; 30 import static org.junit.Assert.assertNotEquals; 31 import static org.junit.Assert.assertNotNull; 32 import static org.junit.Assert.assertNull; 33 import static org.junit.Assert.assertTrue; 34 import static org.mockito.Mockito.any; 35 import static org.mockito.Mockito.anyBoolean; 36 import static org.mockito.Mockito.anyByte; 37 import static org.mockito.Mockito.anyInt; 38 import static org.mockito.Mockito.anyLong; 39 import static org.mockito.Mockito.anyObject; 40 import static org.mockito.Mockito.anyString; 41 import static org.mockito.Mockito.argThat; 42 import static org.mockito.Mockito.atLeastOnce; 43 import static org.mockito.Mockito.doAnswer; 44 import static org.mockito.Mockito.doReturn; 45 import static org.mockito.Mockito.eq; 46 import static org.mockito.Mockito.inOrder; 47 import static org.mockito.Mockito.mock; 48 import static org.mockito.Mockito.never; 49 import static org.mockito.Mockito.reset; 50 import static org.mockito.Mockito.spy; 51 import static org.mockito.Mockito.times; 52 import static org.mockito.Mockito.verify; 53 import static org.mockito.Mockito.verifyNoMoreInteractions; 54 import static org.mockito.Mockito.when; 55 import static org.mockito.Mockito.withSettings; 56 57 import android.app.ActivityManager; 58 import android.app.test.MockAnswerUtil.AnswerWithArguments; 59 import android.app.test.TestAlarmManager; 60 import android.bluetooth.BluetoothAdapter; 61 import android.content.Context; 62 import android.content.Intent; 63 import android.content.pm.PackageManager; 64 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 65 import android.net.ConnectivityManager; 66 import android.net.DhcpResultsParcelable; 67 import android.net.InetAddresses; 68 import android.net.Layer2InformationParcelable; 69 import android.net.Layer2PacketParcelable; 70 import android.net.LinkAddress; 71 import android.net.LinkProperties; 72 import android.net.MacAddress; 73 import android.net.Network; 74 import android.net.NetworkAgent; 75 import android.net.NetworkAgentConfig; 76 import android.net.NetworkCapabilities; 77 import android.net.NetworkInfo; 78 import android.net.NetworkSpecifier; 79 import android.net.StaticIpConfiguration; 80 import android.net.ip.IIpClient; 81 import android.net.ip.IpClientCallbacks; 82 import android.net.wifi.IActionListener; 83 import android.net.wifi.ScanResult; 84 import android.net.wifi.SupplicantState; 85 import android.net.wifi.WifiConfiguration; 86 import android.net.wifi.WifiConfiguration.KeyMgmt; 87 import android.net.wifi.WifiEnterpriseConfig; 88 import android.net.wifi.WifiInfo; 89 import android.net.wifi.WifiManager; 90 import android.net.wifi.WifiNetworkAgentSpecifier; 91 import android.net.wifi.WifiScanner; 92 import android.net.wifi.WifiSsid; 93 import android.net.wifi.hotspot2.IProvisioningCallback; 94 import android.net.wifi.hotspot2.OsuProvider; 95 import android.net.wifi.nl80211.WifiNl80211Manager; 96 import android.net.wifi.p2p.WifiP2pManager; 97 import android.os.BatteryStatsManager; 98 import android.os.Binder; 99 import android.os.Bundle; 100 import android.os.Handler; 101 import android.os.HandlerThread; 102 import android.os.IBinder; 103 import android.os.IPowerManager; 104 import android.os.IThermalService; 105 import android.os.Looper; 106 import android.os.Message; 107 import android.os.Messenger; 108 import android.os.PowerManager; 109 import android.os.Process; 110 import android.os.UserManager; 111 import android.os.test.TestLooper; 112 import android.provider.Settings; 113 import android.telephony.SubscriptionInfo; 114 import android.telephony.SubscriptionManager; 115 import android.telephony.TelephonyManager; 116 import android.test.mock.MockContentProvider; 117 import android.test.mock.MockContentResolver; 118 import android.util.Log; 119 import android.util.Pair; 120 121 import androidx.test.filters.SmallTest; 122 123 import com.android.dx.mockito.inline.extended.ExtendedMockito; 124 import com.android.internal.util.AsyncChannel; 125 import com.android.internal.util.IState; 126 import com.android.internal.util.StateMachine; 127 import com.android.server.wifi.hotspot2.NetworkDetail; 128 import com.android.server.wifi.hotspot2.PasspointManager; 129 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil; 130 import com.android.server.wifi.proto.nano.WifiMetricsProto; 131 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent; 132 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent; 133 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStats; 134 import com.android.server.wifi.util.RssiUtilTest; 135 import com.android.server.wifi.util.ScanResultUtil; 136 import com.android.server.wifi.util.WifiPermissionsUtil; 137 import com.android.server.wifi.util.WifiPermissionsWrapper; 138 import com.android.wifi.resources.R; 139 140 import org.junit.After; 141 import org.junit.Before; 142 import org.junit.Test; 143 import org.mockito.ArgumentCaptor; 144 import org.mockito.ArgumentMatcher; 145 import org.mockito.InOrder; 146 import org.mockito.Mock; 147 import org.mockito.MockitoAnnotations; 148 import org.mockito.MockitoSession; 149 import org.mockito.quality.Strictness; 150 151 import java.io.ByteArrayOutputStream; 152 import java.io.PrintWriter; 153 import java.lang.reflect.Field; 154 import java.lang.reflect.InvocationTargetException; 155 import java.lang.reflect.Method; 156 import java.nio.charset.StandardCharsets; 157 import java.util.ArrayList; 158 import java.util.Arrays; 159 import java.util.BitSet; 160 import java.util.Collections; 161 import java.util.List; 162 import java.util.concurrent.CountDownLatch; 163 import java.util.function.Consumer; 164 165 /** 166 * Unit tests for {@link com.android.server.wifi.ClientModeImpl}. 167 */ 168 @SmallTest 169 public class ClientModeImplTest extends WifiBaseTest { 170 public static final String TAG = "ClientModeImplTest"; 171 172 private static final int MANAGED_PROFILE_UID = 1100000; 173 private static final int OTHER_USER_UID = 1200000; 174 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE = 175 (ActivityManager.isLowRamDeviceStatic() 176 ? ClientModeImpl.NUM_LOG_RECS_VERBOSE_LOW_MEMORY 177 : ClientModeImpl.NUM_LOG_RECS_VERBOSE); 178 private static final int FRAMEWORK_NETWORK_ID = 0; 179 private static final int PASSPOINT_NETWORK_ID = 1; 180 private static final int TEST_RSSI = -54; 181 private static final int TEST_NETWORK_ID = 54; 182 private static final int WPS_SUPPLICANT_NETWORK_ID = 5; 183 private static final int WPS_FRAMEWORK_NETWORK_ID = 10; 184 private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; 185 private static final String OP_PACKAGE_NAME = "com.xxx"; 186 private static final int TEST_UID = Process.SYSTEM_UID + 1000; 187 private static final MacAddress TEST_GLOBAL_MAC_ADDRESS = 188 MacAddress.fromString("10:22:34:56:78:92"); 189 private static final MacAddress TEST_LOCAL_MAC_ADDRESS = 190 MacAddress.fromString("2a:53:43:c3:56:21"); 191 private static final MacAddress TEST_DEFAULT_MAC_ADDRESS = 192 MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 193 194 // NetworkAgent creates threshold ranges with Integers 195 private static final int RSSI_THRESHOLD_MAX = -30; 196 private static final int RSSI_THRESHOLD_MIN = -76; 197 // Threshold breach callbacks are called with bytes 198 private static final byte RSSI_THRESHOLD_BREACH_MIN = -80; 199 private static final byte RSSI_THRESHOLD_BREACH_MAX = -20; 200 201 private static final int DATA_SUBID = 1; 202 private static final int CARRIER_ID_1 = 100; 203 204 private long mBinderToken; 205 private MockitoSession mSession; 206 mockWithInterfaces(Class<T> class1, Class<?>... interfaces)207 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 208 return mock(class1, withSettings().extraInterfaces(interfaces)); 209 } 210 enableDebugLogs()211 private void enableDebugLogs() { 212 mCmi.enableVerboseLogging(1); 213 } 214 getFrameworkFacade()215 private FrameworkFacade getFrameworkFacade() throws Exception { 216 FrameworkFacade facade = mock(FrameworkFacade.class); 217 218 doAnswer(new AnswerWithArguments() { 219 public void answer( 220 Context context, String ifname, IpClientCallbacks callback) { 221 mIpClientCallback = callback; 222 callback.onIpClientCreated(mIpClient); 223 } 224 }).when(facade).makeIpClient(any(), anyString(), any()); 225 226 return facade; 227 } 228 getContext()229 private Context getContext() throws Exception { 230 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 231 232 Context context = mock(Context.class); 233 when(context.getPackageManager()).thenReturn(mPackageManager); 234 235 MockContentResolver mockContentResolver = new MockContentResolver(); 236 mockContentResolver.addProvider(Settings.AUTHORITY, 237 new MockContentProvider(context) { 238 @Override 239 public Bundle call(String method, String arg, Bundle extras) { 240 return new Bundle(); 241 } 242 }); 243 when(context.getContentResolver()).thenReturn(mockContentResolver); 244 245 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn( 246 new PowerManager(context, mock(IPowerManager.class), mock(IThermalService.class), 247 new Handler())); 248 249 mAlarmManager = new TestAlarmManager(); 250 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 251 mAlarmManager.getAlarmManager()); 252 253 when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( 254 mConnectivityManager); 255 256 when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME); 257 258 when(context.getSystemService(ActivityManager.class)).thenReturn( 259 mock(ActivityManager.class)); 260 261 WifiP2pManager p2pm = mock(WifiP2pManager.class); 262 when(context.getSystemService(WifiP2pManager.class)).thenReturn(p2pm); 263 final CountDownLatch untilDone = new CountDownLatch(1); 264 mP2pThread = new HandlerThread("WifiP2pMockThread") { 265 @Override 266 protected void onLooperPrepared() { 267 untilDone.countDown(); 268 } 269 }; 270 mP2pThread.start(); 271 untilDone.await(); 272 Handler handler = new Handler(mP2pThread.getLooper()); 273 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 274 275 return context; 276 } 277 getMockResources()278 private MockResources getMockResources() { 279 MockResources resources = new MockResources(); 280 return resources; 281 } 282 getCurrentState()283 private IState getCurrentState() throws 284 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 285 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 286 method.setAccessible(true); 287 return (IState) method.invoke(mCmi); 288 } 289 getCmiHandlerThread(ClientModeImpl cmi)290 private static HandlerThread getCmiHandlerThread(ClientModeImpl cmi) throws 291 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 292 Field field = StateMachine.class.getDeclaredField("mSmThread"); 293 field.setAccessible(true); 294 return (HandlerThread) field.get(cmi); 295 } 296 stopLooper(final Looper looper)297 private static void stopLooper(final Looper looper) throws Exception { 298 new Handler(looper).post(new Runnable() { 299 @Override 300 public void run() { 301 looper.quitSafely(); 302 } 303 }); 304 } 305 dumpState()306 private void dumpState() { 307 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 308 PrintWriter writer = new PrintWriter(stream); 309 mCmi.dump(null, writer, null); 310 writer.flush(); 311 Log.d(TAG, "ClientModeImpl state -" + stream.toString()); 312 } 313 getGoogleGuestScanDetail(int rssi, String bssid, int freq)314 private static ScanDetail getGoogleGuestScanDetail(int rssi, String bssid, int freq) { 315 ScanResult.InformationElement[] ie = new ScanResult.InformationElement[1]; 316 ie[0] = ScanResults.generateSsidIe(sSSID); 317 NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq); 318 ScanDetail detail = new ScanDetail(nd, sWifiSsid, bssid, "", rssi, freq, 319 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 320 there older than scan start */ 321 ie, new ArrayList<String>(), ScanResults.generateIERawDatafromScanResultIE(ie)); 322 323 return detail; 324 } 325 getMockScanResults()326 private ArrayList<ScanDetail> getMockScanResults() { 327 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 328 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 329 330 list.add(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 331 return list; 332 } 333 injectDhcpSuccess(DhcpResultsParcelable dhcpResults)334 private void injectDhcpSuccess(DhcpResultsParcelable dhcpResults) { 335 mIpClientCallback.onNewDhcpResults(dhcpResults); 336 mIpClientCallback.onProvisioningSuccess(new LinkProperties()); 337 } 338 injectDhcpFailure()339 private void injectDhcpFailure() { 340 mIpClientCallback.onNewDhcpResults((DhcpResultsParcelable) null); 341 mIpClientCallback.onProvisioningFailure(new LinkProperties()); 342 } 343 344 static final String sSSID = "\"GoogleGuest\""; 345 static final String SSID_NO_QUOTE = sSSID.replace("\"", ""); 346 static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(SSID_NO_QUOTE); 347 static final String sBSSID = "01:02:03:04:05:06"; 348 static final String sBSSID1 = "02:01:04:03:06:05"; 349 static final int sFreq = 2437; 350 static final int sFreq1 = 5240; 351 static final String WIFI_IFACE_NAME = "mockWlan"; 352 static final String sFilsSsid = "FILS-AP"; 353 354 ClientModeImpl mCmi; 355 HandlerThread mWifiCoreThread; 356 HandlerThread mP2pThread; 357 HandlerThread mSyncThread; 358 AsyncChannel mCmiAsyncChannel; 359 AsyncChannel mNetworkAgentAsyncChannel; 360 TestAlarmManager mAlarmManager; 361 MockWifiMonitor mWifiMonitor; 362 TestLooper mLooper; 363 Context mContext; 364 MockResources mResources; 365 FrameworkFacade mFrameworkFacade; 366 IpClientCallbacks mIpClientCallback; 367 OsuProvider mOsuProvider; 368 WifiConfiguration mConnectedNetwork; 369 WifiCarrierInfoManager mWifiCarrierInfoManager; 370 371 @Mock WifiScanner mWifiScanner; 372 @Mock SupplicantStateTracker mSupplicantStateTracker; 373 @Mock WifiMetrics mWifiMetrics; 374 @Mock UserManager mUserManager; 375 @Mock BackupManagerProxy mBackupManagerProxy; 376 @Mock WifiCountryCode mCountryCode; 377 @Mock WifiInjector mWifiInjector; 378 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 379 @Mock BssidBlocklistMonitor mBssidBlocklistMonitor; 380 @Mock PropertyService mPropertyService; 381 @Mock BuildProperties mBuildProperties; 382 @Mock IBinder mPackageManagerBinder; 383 @Mock SarManager mSarManager; 384 @Mock WifiConfigManager mWifiConfigManager; 385 @Mock WifiNative mWifiNative; 386 @Mock WifiScoreCard mWifiScoreCard; 387 @Mock WifiHealthMonitor mWifiHealthMonitor; 388 @Mock WifiTrafficPoller mWifiTrafficPoller; 389 @Mock WifiConnectivityManager mWifiConnectivityManager; 390 @Mock WifiStateTracker mWifiStateTracker; 391 @Mock PasspointManager mPasspointManager; 392 @Mock SelfRecovery mSelfRecovery; 393 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 394 @Mock IIpClient mIpClient; 395 @Mock TelephonyManager mTelephonyManager; 396 @Mock TelephonyManager mDataTelephonyManager; 397 @Mock WrongPasswordNotifier mWrongPasswordNotifier; 398 @Mock Clock mClock; 399 @Mock ScanDetailCache mScanDetailCache; 400 @Mock BaseWifiDiagnostics mWifiDiagnostics; 401 @Mock ConnectivityManager mConnectivityManager; 402 @Mock IProvisioningCallback mProvisioningCallback; 403 @Mock HandlerThread mWifiHandlerThread; 404 @Mock WifiPermissionsWrapper mWifiPermissionsWrapper; 405 @Mock WakeupController mWakeupController; 406 @Mock WifiDataStall mWifiDataStall; 407 @Mock WifiNetworkFactory mWifiNetworkFactory; 408 @Mock UntrustedWifiNetworkFactory mUntrustedWifiNetworkFactory; 409 @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; 410 @Mock LinkProbeManager mLinkProbeManager; 411 @Mock PackageManager mPackageManager; 412 @Mock WifiLockManager mWifiLockManager; 413 @Mock AsyncChannel mNullAsyncChannel; 414 @Mock Handler mNetworkAgentHandler; 415 @Mock BatteryStatsManager mBatteryStatsManager; 416 @Mock MboOceController mMboOceController; 417 @Mock SubscriptionManager mSubscriptionManager; 418 @Mock ConnectionFailureNotifier mConnectionFailureNotifier; 419 @Mock EapFailureNotifier mEapFailureNotifier; 420 @Mock SimRequiredNotifier mSimRequiredNotifier; 421 @Mock ThroughputPredictor mThroughputPredictor; 422 @Mock ScanRequestProxy mScanRequestProxy; 423 @Mock DeviceConfigFacade mDeviceConfigFacade; 424 @Mock Network mNetwork; 425 426 final ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor = 427 ArgumentCaptor.forClass(WifiConfigManager.OnNetworkUpdateListener.class); 428 ClientModeImplTest()429 public ClientModeImplTest() throws Exception { 430 } 431 432 @Before setUp()433 public void setUp() throws Exception { 434 Log.d(TAG, "Setting up ..."); 435 436 // Ensure looper exists 437 mLooper = new TestLooper(); 438 439 MockitoAnnotations.initMocks(this); 440 441 /** uncomment this to enable logs from ClientModeImpls */ 442 // enableDebugLogs(); 443 mWifiMonitor = new MockWifiMonitor(); 444 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 445 when(mWifiInjector.getClock()).thenReturn(new Clock()); 446 when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog); 447 when(mWifiInjector.getPropertyService()).thenReturn(mPropertyService); 448 when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties); 449 when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class)); 450 when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics); 451 when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager); 452 when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); 453 when(mWifiInjector.makeWifiConnectivityManager(any())) 454 .thenReturn(mWifiConnectivityManager); 455 when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager); 456 when(mWifiInjector.getWifiStateTracker()).thenReturn(mWifiStateTracker); 457 when(mWifiInjector.getWifiMonitor()).thenReturn(mWifiMonitor); 458 when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative); 459 when(mWifiInjector.getWifiTrafficPoller()).thenReturn(mWifiTrafficPoller); 460 when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); 461 when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil); 462 when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager); 463 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 464 when(mWifiInjector.getClock()).thenReturn(mClock); 465 when(mWifiHandlerThread.getLooper()).thenReturn(mLooper.getLooper()); 466 when(mWifiInjector.getWifiHandlerThread()).thenReturn(mWifiHandlerThread); 467 when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper); 468 when(mWifiInjector.getWakeupController()).thenReturn(mWakeupController); 469 when(mWifiInjector.getScoringParams()).thenReturn(new ScoringParams()); 470 when(mWifiInjector.getWifiDataStall()).thenReturn(mWifiDataStall); 471 when(mWifiInjector.makeWifiNetworkFactory(any(), any())).thenReturn(mWifiNetworkFactory); 472 when(mWifiInjector.makeUntrustedWifiNetworkFactory(any(), any())) 473 .thenReturn(mUntrustedWifiNetworkFactory); 474 when(mWifiInjector.getWifiNetworkSuggestionsManager()) 475 .thenReturn(mWifiNetworkSuggestionsManager); 476 when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard); 477 when(mWifiInjector.getWifiHealthMonitor()).thenReturn(mWifiHealthMonitor); 478 when(mWifiInjector.getWifiLockManager()).thenReturn(mWifiLockManager); 479 when(mWifiInjector.getWifiThreadRunner()) 480 .thenReturn(new WifiThreadRunner(new Handler(mLooper.getLooper()))); 481 when(mWifiInjector.makeConnectionFailureNotifier(any())) 482 .thenReturn(mConnectionFailureNotifier); 483 when(mWifiInjector.getBssidBlocklistMonitor()).thenReturn(mBssidBlocklistMonitor); 484 when(mWifiInjector.getThroughputPredictor()).thenReturn(mThroughputPredictor); 485 when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy); 486 when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); 487 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any())) 488 .thenReturn(Pair.create(Process.INVALID_UID, "")); 489 when(mWifiNative.initialize()).thenReturn(true); 490 when(mWifiNative.getFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn( 491 TEST_GLOBAL_MAC_ADDRESS); 492 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 493 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 494 WifiNative.ConnectionCapabilities cap = new WifiNative.ConnectionCapabilities(); 495 cap.wifiStandard = ScanResult.WIFI_STANDARD_11AC; 496 when(mWifiNative.getConnectionCapabilities(WIFI_IFACE_NAME)).thenReturn(cap); 497 when(mWifiNative.setMacAddress(eq(WIFI_IFACE_NAME), anyObject())) 498 .then(new AnswerWithArguments() { 499 public boolean answer(String iface, MacAddress mac) { 500 when(mWifiNative.getMacAddress(iface)).thenReturn(mac.toString()); 501 return true; 502 } 503 }); 504 doAnswer(new AnswerWithArguments() { 505 public MacAddress answer( 506 WifiConfiguration config) { 507 return config.getRandomizedMacAddress(); 508 } 509 }).when(mWifiConfigManager).getRandomizedMacAndUpdateIfNeeded(any()); 510 when(mWifiNative.connectToNetwork(any(), any())).thenReturn(true); 511 512 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 513 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 514 515 mFrameworkFacade = getFrameworkFacade(); 516 mContext = getContext(); 517 518 mResources = getMockResources(); 519 mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, true); 520 mResources.setIntArray(R.array.config_wifiRssiLevelThresholds, 521 RssiUtilTest.RSSI_THRESHOLDS); 522 mResources.setInteger(R.integer.config_wifiPollRssiIntervalMilliseconds, 3000); 523 when(mContext.getResources()).thenReturn(mResources); 524 when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext); 525 526 when(mFrameworkFacade.getIntegerSetting(mContext, 527 Settings.Global.WIFI_FREQUENCY_BAND, 528 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 529 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 530 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 531 when(mWifiPermissionsWrapper.getLocalMacAddressPermission(anyInt())) 532 .thenReturn(PackageManager.PERMISSION_DENIED); 533 doAnswer(inv -> { 534 mIpClientCallback.onQuit(); 535 return null; 536 }).when(mIpClient).shutdown(); 537 when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(), anyInt(), any(), 538 anyInt())).thenReturn(mNetwork); 539 List<SubscriptionInfo> subList = Arrays.asList(mock(SubscriptionInfo.class)); 540 when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subList); 541 when(mSubscriptionManager.getActiveSubscriptionIdList()) 542 .thenReturn(new int[]{DATA_SUBID}); 543 544 WifiCarrierInfoManager tu = new WifiCarrierInfoManager(mTelephonyManager, 545 mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class), 546 mock(WifiContext.class), mock(WifiConfigStore.class), mock(Handler.class), 547 mWifiMetrics); 548 mWifiCarrierInfoManager = spy(tu); 549 // static mocking 550 mSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT) 551 .spyStatic(MacAddress.class) 552 .startMocking(); 553 initializeCmi(); 554 555 mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 556 mConnectedNetwork = spy(WifiConfigurationTestUtil.createOpenNetwork()); 557 when(mNullAsyncChannel.sendMessageSynchronously(any())).thenReturn(null); 558 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null)); 559 when(mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()).thenReturn(true); 560 when(mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled()).thenReturn(true); 561 when(mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()).thenReturn(true); 562 when(mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()).thenReturn( 563 DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS); 564 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 565 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 566 when(mWifiScoreCard.detectAbnormalDisconnection()) 567 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 568 when(mThroughputPredictor.predictMaxTxThroughput(any())).thenReturn(90); 569 when(mThroughputPredictor.predictMaxRxThroughput(any())).thenReturn(80); 570 } 571 registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger, Handler wrappedHandler)572 private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger, 573 Handler wrappedHandler) { 574 final AsyncChannel channel = new AsyncChannel(); 575 Handler handler = new Handler(mLooper.getLooper()) { 576 @Override 577 public void handleMessage(Message msg) { 578 switch (msg.what) { 579 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 580 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 581 consumer.accept(channel); 582 } else { 583 Log.d(TAG, "Failed to connect Command channel " + this); 584 } 585 break; 586 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 587 Log.d(TAG, "Command channel disconnected " + this); 588 break; 589 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 590 Log.d(TAG, "Command channel fully connected " + this); 591 break; 592 default: 593 if (wrappedHandler != null) { 594 wrappedHandler.handleMessage(msg); 595 } 596 break; 597 } 598 } 599 }; 600 601 channel.connect(mContext, handler, messenger); 602 mLooper.dispatchAll(); 603 } 604 registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger)605 private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger) { 606 registerAsyncChannel(consumer, messenger, null /* wrappedHandler */); 607 } 608 initializeCmi()609 private void initializeCmi() throws Exception { 610 mCmi = new ClientModeImpl(mContext, mFrameworkFacade, mLooper.getLooper(), 611 mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative, 612 mWrongPasswordNotifier, mSarManager, mWifiTrafficPoller, mLinkProbeManager, 613 mBatteryStatsManager, mSupplicantStateTracker, mMboOceController, 614 mWifiCarrierInfoManager, mEapFailureNotifier, mSimRequiredNotifier); 615 mCmi.start(); 616 mWifiCoreThread = getCmiHandlerThread(mCmi); 617 618 registerAsyncChannel((x) -> { 619 mCmiAsyncChannel = x; 620 }, mCmi.getMessenger()); 621 622 mBinderToken = Binder.clearCallingIdentity(); 623 624 /* Send the BOOT_COMPLETED message to setup some CMI state. */ 625 mCmi.handleBootCompleted(); 626 mLooper.dispatchAll(); 627 628 verify(mWifiNetworkFactory, atLeastOnce()).register(); 629 verify(mUntrustedWifiNetworkFactory, atLeastOnce()).register(); 630 verify(mWifiConfigManager, atLeastOnce()).addOnNetworkUpdateListener( 631 mConfigUpdateListenerCaptor.capture()); 632 assertNotNull(mConfigUpdateListenerCaptor.getValue()); 633 634 mCmi.initialize(); 635 mLooper.dispatchAll(); 636 } 637 638 @After cleanUp()639 public void cleanUp() throws Exception { 640 Binder.restoreCallingIdentity(mBinderToken); 641 642 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 643 if (mWifiCoreThread != null) stopLooper(mWifiCoreThread.getLooper()); 644 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 645 646 mWifiCoreThread = null; 647 mP2pThread = null; 648 mSyncThread = null; 649 mCmiAsyncChannel = null; 650 mNetworkAgentAsyncChannel = null; 651 mNetworkAgentHandler = null; 652 mCmi = null; 653 mSession.finishMocking(); 654 } 655 656 @Test createNew()657 public void createNew() throws Exception { 658 assertEquals("DefaultState", getCurrentState().getName()); 659 660 mCmi.handleBootCompleted(); 661 mLooper.dispatchAll(); 662 assertEquals("DefaultState", getCurrentState().getName()); 663 } 664 665 @Test loadComponentsInStaMode()666 public void loadComponentsInStaMode() throws Exception { 667 startSupplicantAndDispatchMessages(); 668 assertEquals("DisconnectedState", getCurrentState().getName()); 669 } 670 671 @Test checkInitialStateStickyWhenDisabledMode()672 public void checkInitialStateStickyWhenDisabledMode() throws Exception { 673 mLooper.dispatchAll(); 674 assertEquals("DefaultState", getCurrentState().getName()); 675 assertEquals(ClientModeImpl.DISABLED_MODE, mCmi.getOperationalModeForTest()); 676 677 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 678 mLooper.dispatchAll(); 679 assertEquals(ClientModeImpl.DISABLED_MODE, mCmi.getOperationalModeForTest()); 680 assertEquals("DefaultState", getCurrentState().getName()); 681 } 682 683 @Test shouldStartSupplicantWhenConnectModeRequested()684 public void shouldStartSupplicantWhenConnectModeRequested() throws Exception { 685 // The first time we start out in DefaultState, we sit around here. 686 mLooper.dispatchAll(); 687 assertEquals("DefaultState", getCurrentState().getName()); 688 assertEquals(ClientModeImpl.DISABLED_MODE, mCmi.getOperationalModeForTest()); 689 690 // But if someone tells us to enter connect mode, we start up supplicant 691 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 692 mLooper.dispatchAll(); 693 assertEquals("DisconnectedState", getCurrentState().getName()); 694 } 695 696 /** 697 * Test that mode changes accurately reflect the value for isWifiEnabled. 698 */ 699 @Test checkIsWifiEnabledForModeChanges()700 public void checkIsWifiEnabledForModeChanges() throws Exception { 701 // Check initial state 702 mLooper.dispatchAll(); 703 assertEquals("DefaultState", getCurrentState().getName()); 704 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 705 706 // switch to connect mode and verify wifi is reported as enabled 707 startSupplicantAndDispatchMessages(); 708 709 assertEquals("DisconnectedState", getCurrentState().getName()); 710 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 711 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 712 assertEquals("enabled", mCmi.syncGetWifiStateByName()); 713 714 // now disable wifi and verify the reported wifi state 715 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_DISABLED); 716 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 717 mLooper.dispatchAll(); 718 assertEquals(ClientModeImpl.DISABLED_MODE, mCmi.getOperationalModeForTest()); 719 assertEquals("DefaultState", getCurrentState().getName()); 720 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 721 assertEquals("disabled", mCmi.syncGetWifiStateByName()); 722 verify(mContext, never()).sendStickyBroadcastAsUser( 723 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 724 } 725 726 private class WifiEnablingStateIntentMatcher implements ArgumentMatcher<Intent> { 727 @Override matches(Intent intent)728 public boolean matches(Intent intent) { 729 if (WifiManager.WIFI_STATE_CHANGED_ACTION != intent.getAction()) { 730 // not the correct type 731 return false; 732 } 733 return WifiManager.WIFI_STATE_ENABLING 734 == intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 735 WifiManager.WIFI_STATE_DISABLED); 736 } 737 } 738 canForgetNetwork()739 private void canForgetNetwork() throws Exception { 740 when(mWifiConfigManager.removeNetwork(eq(0), anyInt(), any())).thenReturn(true); 741 IActionListener connectActionListener = mock(IActionListener.class); 742 mCmi.forget(0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 743 mLooper.dispatchAll(); 744 verify(connectActionListener).onSuccess(); 745 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), any()); 746 } 747 748 /** 749 * Verifies that configs can be removed when not in client mode. 750 */ 751 @Test canForgetNetworkConfigWhenWifiDisabled()752 public void canForgetNetworkConfigWhenWifiDisabled() throws Exception { 753 canForgetNetwork(); 754 } 755 756 /** 757 * Verifies that configs can be forgotten when in client mode. 758 */ 759 @Test canForgetNetworkConfigInClientMode()760 public void canForgetNetworkConfigInClientMode() throws Exception { 761 initializeAndAddNetworkAndVerifySuccess(); 762 canForgetNetwork(); 763 } 764 canSaveNetworkConfig()765 private void canSaveNetworkConfig() throws Exception { 766 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 767 768 int networkId = TEST_NETWORK_ID; 769 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 770 .thenReturn(new NetworkUpdateResult(networkId)); 771 when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt(), any())) 772 .thenReturn(true); 773 774 IActionListener connectActionListener = mock(IActionListener.class); 775 mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 776 mLooper.dispatchAll(); 777 verify(connectActionListener).onSuccess(); 778 779 verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()); 780 verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt(), any()); 781 } 782 783 /** 784 * Verifies that configs can be saved when not in client mode. 785 */ 786 @Test canSaveNetworkConfigWhenWifiDisabled()787 public void canSaveNetworkConfigWhenWifiDisabled() throws Exception { 788 canSaveNetworkConfig(); 789 } 790 791 /** 792 * Verifies that configs can be saved when in client mode. 793 */ 794 @Test canSaveNetworkConfigInClientMode()795 public void canSaveNetworkConfigInClientMode() throws Exception { 796 loadComponentsInStaMode(); 797 canSaveNetworkConfig(); 798 } 799 800 /** 801 * Verifies that null configs are rejected in SAVE_NETWORK message. 802 */ 803 @Test saveNetworkConfigFailsWithNullConfig()804 public void saveNetworkConfigFailsWithNullConfig() throws Exception { 805 IActionListener connectActionListener = mock(IActionListener.class); 806 mCmi.save(null, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 807 mLooper.dispatchAll(); 808 verify(connectActionListener).onFailure(WifiManager.ERROR); 809 810 verify(mWifiConfigManager, never()) 811 .addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()); 812 verify(mWifiConfigManager, never()) 813 .enableNetwork(anyInt(), anyBoolean(), anyInt(), any()); 814 } 815 816 /** 817 * Verifies that configs save fails when the addition of network fails. 818 */ 819 @Test saveNetworkConfigFailsWithConfigAddFailure()820 public void saveNetworkConfigFailsWithConfigAddFailure() throws Exception { 821 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 822 823 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 824 .thenReturn(new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID)); 825 826 IActionListener connectActionListener = mock(IActionListener.class); 827 mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 828 mLooper.dispatchAll(); 829 verify(connectActionListener).onFailure(WifiManager.ERROR); 830 831 verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()); 832 verify(mWifiConfigManager, never()) 833 .enableNetwork(anyInt(), anyBoolean(), anyInt(), any()); 834 } 835 836 /** 837 * Verifies that configs save fails when the enable of network fails. 838 */ 839 @Test saveNetworkConfigFailsWithConfigEnableFailure()840 public void saveNetworkConfigFailsWithConfigEnableFailure() throws Exception { 841 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 842 843 int networkId = 5; 844 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 845 .thenReturn(new NetworkUpdateResult(networkId)); 846 when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt(), any())) 847 .thenReturn(false); 848 849 IActionListener connectActionListener = mock(IActionListener.class); 850 mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 851 mLooper.dispatchAll(); 852 verify(connectActionListener).onFailure(WifiManager.ERROR); 853 854 verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()); 855 verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt(), any()); 856 } 857 858 /** 859 * Helper method to move through startup states. 860 */ startSupplicantAndDispatchMessages()861 private void startSupplicantAndDispatchMessages() throws Exception { 862 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_ENABLED); 863 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 864 865 mLooper.dispatchAll(); 866 867 verify(mWifiLastResortWatchdog, atLeastOnce()).clearAllFailureCounts(); 868 869 assertEquals("DisconnectedState", getCurrentState().getName()); 870 } 871 initializeMocksForAddedNetwork(boolean isHidden)872 private void initializeMocksForAddedNetwork(boolean isHidden) throws Exception { 873 WifiConfiguration config = new WifiConfiguration(); 874 config.networkId = FRAMEWORK_NETWORK_ID; 875 config.SSID = sSSID; 876 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 877 config.hiddenSSID = isHidden; 878 879 when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(config)); 880 when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config); 881 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 882 } 883 initializeAndAddNetworkAndVerifySuccess()884 private void initializeAndAddNetworkAndVerifySuccess() throws Exception { 885 initializeAndAddNetworkAndVerifySuccess(false); 886 } 887 initializeAndAddNetworkAndVerifySuccess(boolean isHidden)888 private void initializeAndAddNetworkAndVerifySuccess(boolean isHidden) throws Exception { 889 loadComponentsInStaMode(); 890 initializeMocksForAddedNetwork(isHidden); 891 } 892 setupAndStartConnectSequence(WifiConfiguration config)893 private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception { 894 when(mWifiConfigManager.enableNetwork( 895 eq(config.networkId), eq(true), anyInt(), any())) 896 .thenReturn(true); 897 when(mWifiConfigManager.updateLastConnectUid(eq(config.networkId), anyInt())) 898 .thenReturn(true); 899 when(mWifiConfigManager.getConfiguredNetwork(eq(config.networkId))) 900 .thenReturn(config); 901 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking( 902 eq(config.networkId))).thenReturn(config); 903 904 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 905 906 IActionListener connectActionListener = mock(IActionListener.class); 907 mCmi.connect(null, config.networkId, mock(Binder.class), connectActionListener, 0, 908 Binder.getCallingUid()); 909 mLooper.dispatchAll(); 910 verify(mWifiConfigManager).userEnabledNetwork(config.networkId); 911 verify(connectActionListener).onSuccess(); 912 } 913 validateSuccessfulConnectSequence(WifiConfiguration config)914 private void validateSuccessfulConnectSequence(WifiConfiguration config) { 915 verify(mWifiConfigManager).enableNetwork( 916 eq(config.networkId), eq(true), anyInt(), any()); 917 verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); 918 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 919 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 920 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 921 } 922 validateFailureConnectSequence(WifiConfiguration config)923 private void validateFailureConnectSequence(WifiConfiguration config) { 924 verify(mWifiConfigManager).enableNetwork( 925 eq(config.networkId), eq(true), anyInt(), any()); 926 verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); 927 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 928 verify(mWifiConfigManager, never()) 929 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 930 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 931 } 932 933 /** 934 * Tests the network connection initiation sequence with the default network request pending 935 * from WifiNetworkFactory. 936 * This simulates the connect sequence using the public 937 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 938 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 939 */ 940 @Test triggerConnect()941 public void triggerConnect() throws Exception { 942 loadComponentsInStaMode(); 943 WifiConfiguration config = mConnectedNetwork; 944 config.networkId = FRAMEWORK_NETWORK_ID; 945 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 946 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 947 setupAndStartConnectSequence(config); 948 validateSuccessfulConnectSequence(config); 949 } 950 951 /** 952 * Tests the network connection initiation sequence with the default network request pending 953 * from WifiNetworkFactory. 954 * This simulates the connect sequence using the public 955 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 956 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 957 */ 958 @Test triggerConnectFromNonSettingsApp()959 public void triggerConnectFromNonSettingsApp() throws Exception { 960 loadComponentsInStaMode(); 961 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 962 config.networkId = FRAMEWORK_NETWORK_ID; 963 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(Process.myUid())) 964 .thenReturn(false); 965 setupAndStartConnectSequence(config); 966 verify(mWifiConfigManager).enableNetwork( 967 eq(config.networkId), eq(true), anyInt(), any()); 968 verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(config.networkId)); 969 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 970 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 971 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 972 } 973 974 /** 975 * Tests the network connection initiation sequence with no network request pending from 976 * from WifiNetworkFactory. 977 * This simulates the connect sequence using the public 978 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 979 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 980 */ 981 @Test triggerConnectWithNoNetworkRequest()982 public void triggerConnectWithNoNetworkRequest() throws Exception { 983 loadComponentsInStaMode(); 984 // Remove the network requests. 985 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 986 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 987 988 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 989 config.networkId = FRAMEWORK_NETWORK_ID; 990 setupAndStartConnectSequence(config); 991 validateFailureConnectSequence(config); 992 } 993 994 /** 995 * Tests the entire successful network connection flow. 996 */ 997 @Test connect()998 public void connect() throws Exception { 999 triggerConnect(); 1000 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 1001 config.carrierId = CARRIER_ID_1; 1002 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1003 .thenReturn(mScanDetailCache); 1004 1005 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 1006 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 1007 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 1008 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 1009 1010 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1011 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); 1012 mLooper.dispatchAll(); 1013 1014 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1015 mLooper.dispatchAll(); 1016 1017 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1018 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1019 mLooper.dispatchAll(); 1020 1021 assertEquals("ObtainingIpState", getCurrentState().getName()); 1022 1023 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 1024 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 1025 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 1026 dhcpResults.baseConfiguration.ipAddress = 1027 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 1028 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 1029 dhcpResults.leaseDuration = 3600; 1030 1031 injectDhcpSuccess(dhcpResults); 1032 mLooper.dispatchAll(); 1033 1034 // Verify WifiMetrics logging for metered metrics based on DHCP results 1035 verify(mWifiMetrics).addMeteredStat(any(), anyBoolean()); 1036 WifiInfo wifiInfo = mCmi.getWifiInfo(); 1037 assertNotNull(wifiInfo); 1038 assertEquals(sBSSID, wifiInfo.getBSSID()); 1039 assertEquals(sFreq, wifiInfo.getFrequency()); 1040 assertTrue(sWifiSsid.equals(wifiInfo.getWifiSsid())); 1041 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1042 // Ensure the connection stats for the network is updated. 1043 verify(mWifiConfigManager).updateNetworkAfterConnect(FRAMEWORK_NETWORK_ID); 1044 verify(mWifiConfigManager).updateRandomizedMacExpireTime(any(), anyLong()); 1045 1046 // Anonymous Identity is not set. 1047 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1048 verify(mWifiStateTracker).updateState(eq(WifiStateTracker.CONNECTED)); 1049 assertEquals("ConnectedState", getCurrentState().getName()); 1050 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionSuccess(); 1051 verify(mWifiLockManager).updateWifiClientConnected(true); 1052 verify(mWifiNative).getConnectionCapabilities(any()); 1053 verify(mThroughputPredictor).predictMaxTxThroughput(any()); 1054 verify(mWifiMetrics).setConnectionMaxSupportedLinkSpeedMbps(90, 80); 1055 verify(mWifiDataStall).setConnectionCapabilities(any()); 1056 assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); 1057 } 1058 setupEapSimConnection()1059 private void setupEapSimConnection() throws Exception { 1060 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1061 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1062 mConnectedNetwork.carrierId = CARRIER_ID_1; 1063 doReturn(DATA_SUBID).when(mWifiCarrierInfoManager) 1064 .getBestMatchSubscriptionId(any(WifiConfiguration.class)); 1065 when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); 1066 when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 1067 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1068 1069 triggerConnect(); 1070 1071 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1072 .thenReturn(mScanDetailCache); 1073 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 1074 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 1075 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 1076 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 1077 1078 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1079 mLooper.dispatchAll(); 1080 assertEquals("ObtainingIpState", getCurrentState().getName()); 1081 } 1082 1083 /** 1084 * When the SIM card was removed, if the current wifi connection is not using it, the connection 1085 * should be kept. 1086 */ 1087 @Test testResetSimWhenNonConnectedSimRemoved()1088 public void testResetSimWhenNonConnectedSimRemoved() throws Exception { 1089 setupEapSimConnection(); 1090 doReturn(true).when(mWifiCarrierInfoManager).isSimPresent(eq(DATA_SUBID)); 1091 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1092 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1093 mLooper.dispatchAll(); 1094 1095 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); 1096 1097 assertEquals("ObtainingIpState", getCurrentState().getName()); 1098 } 1099 1100 /** 1101 * When the SIM card was removed, if the current wifi connection is using it, the connection 1102 * should be disconnected, otherwise, the connection shouldn't be impacted. 1103 */ 1104 @Test testResetSimWhenConnectedSimRemoved()1105 public void testResetSimWhenConnectedSimRemoved() throws Exception { 1106 setupEapSimConnection(); 1107 doReturn(false).when(mWifiCarrierInfoManager).isSimPresent(eq(DATA_SUBID)); 1108 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1109 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1110 mLooper.dispatchAll(); 1111 1112 verify(mSimRequiredNotifier).showSimRequiredNotification(any(), any()); 1113 assertEquals("DisconnectingState", getCurrentState().getName()); 1114 } 1115 1116 /** 1117 * When the default data SIM is changed, if the current wifi connection is carrier wifi, 1118 * the connection should be disconnected. 1119 */ 1120 @Test testResetSimWhenDefaultDataSimChanged()1121 public void testResetSimWhenDefaultDataSimChanged() throws Exception { 1122 setupEapSimConnection(); 1123 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1124 ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); 1125 mLooper.dispatchAll(); 1126 1127 assertEquals("DisconnectingState", getCurrentState().getName()); 1128 } 1129 1130 /** 1131 * Tests anonymous identity is set again whenever a connection is established for the carrier 1132 * that supports encrypted IMSI and anonymous identity and no real pseudonym was provided. 1133 */ 1134 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym()1135 public void testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym() throws Exception { 1136 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1137 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1138 when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); 1139 when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 1140 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1141 1142 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1143 MockitoSession mockSession = ExtendedMockito.mockitoSession() 1144 .mockStatic(SubscriptionManager.class) 1145 .startMocking(); 1146 when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID); 1147 doReturn(true).when(mWifiCarrierInfoManager).isImsiEncryptionInfoAvailable(anyInt()); 1148 1149 // Initial value should be "not set" 1150 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1151 1152 triggerConnect(); 1153 1154 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1155 assertEquals(expectedAnonymousIdentity, 1156 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1157 1158 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1159 .thenReturn(mScanDetailCache); 1160 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 1161 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 1162 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 1163 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 1164 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1165 .thenReturn(expectedAnonymousIdentity); 1166 1167 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1168 mLooper.dispatchAll(); 1169 1170 verify(mWifiNative).getEapAnonymousIdentity(any()); 1171 1172 // Post connection value should remain "not set" 1173 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1174 // verify that WifiConfigManager#addOrUpdateNetwork() was called to clear any previously 1175 // stored pseudonym. i.e. to enable Encrypted IMSI for subsequent connections. 1176 // Note: This test will fail if future logic will have additional conditions that would 1177 // trigger "add or update network" operation. The test needs to be updated to account for 1178 // this change. 1179 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1180 mockSession.finishMocking(); 1181 } 1182 1183 /** 1184 * Tests anonymous identity is set again whenever a connection is established for the carrier 1185 * that supports encrypted IMSI and anonymous identity but real pseudonym was provided for 1186 * subsequent connections. 1187 */ 1188 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym()1189 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym() 1190 throws Exception { 1191 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1192 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1193 when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); 1194 when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 1195 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1196 1197 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1198 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 1199 MockitoSession mockSession = ExtendedMockito.mockitoSession() 1200 .mockStatic(SubscriptionManager.class) 1201 .startMocking(); 1202 when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID); 1203 doReturn(true).when(mWifiCarrierInfoManager).isImsiEncryptionInfoAvailable(anyInt()); 1204 1205 triggerConnect(); 1206 1207 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1208 assertEquals(expectedAnonymousIdentity, 1209 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1210 1211 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1212 .thenReturn(mScanDetailCache); 1213 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 1214 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 1215 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 1216 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 1217 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1218 .thenReturn(pseudonym); 1219 1220 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1221 mLooper.dispatchAll(); 1222 1223 verify(mWifiNative).getEapAnonymousIdentity(any()); 1224 assertEquals(pseudonym, 1225 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1226 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1227 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1228 // pseudonym usage in all subsequent connections. 1229 // Note: This test will fail if future logic will have additional conditions that would 1230 // trigger "add or update network" operation. The test needs to be updated to account for 1231 // this change. 1232 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1233 mockSession.finishMocking(); 1234 } 1235 1236 /** 1237 * Tests anonymous identity is set again whenever a connection is established for the carrier 1238 * that supports encrypted IMSI and anonymous identity but real but not decorated pseudonym was 1239 * provided for subsequent connections. 1240 */ 1241 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym()1242 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym() 1243 throws Exception { 1244 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1245 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1246 when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); 1247 when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 1248 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1249 1250 String realm = "wlan.mnc456.mcc123.3gppnetwork.org"; 1251 String expectedAnonymousIdentity = "anonymous"; 1252 String pseudonym = "83bcca9384fca"; 1253 MockitoSession mockSession = ExtendedMockito.mockitoSession() 1254 .mockStatic(SubscriptionManager.class) 1255 .startMocking(); 1256 when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID); 1257 doReturn(true).when(mWifiCarrierInfoManager).isImsiEncryptionInfoAvailable(anyInt()); 1258 1259 triggerConnect(); 1260 1261 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1262 assertEquals(expectedAnonymousIdentity + "@" + realm, 1263 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1264 1265 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1266 .thenReturn(mScanDetailCache); 1267 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 1268 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 1269 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 1270 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 1271 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1272 .thenReturn(pseudonym); 1273 1274 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1275 mLooper.dispatchAll(); 1276 1277 verify(mWifiNative).getEapAnonymousIdentity(any()); 1278 assertEquals(pseudonym + "@" + realm, 1279 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1280 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1281 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1282 // pseudonym usage in all subsequent connections. 1283 // Note: This test will fail if future logic will have additional conditions that would 1284 // trigger "add or update network" operation. The test needs to be updated to account for 1285 // this change. 1286 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1287 mockSession.finishMocking(); 1288 } 1289 /** 1290 * Tests the Passpoint information is set in WifiInfo for Passpoint AP connection. 1291 */ 1292 @Test connectPasspointAp()1293 public void connectPasspointAp() throws Exception { 1294 loadComponentsInStaMode(); 1295 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 1296 config.SSID = sWifiSsid.toString(); 1297 config.BSSID = sBSSID; 1298 config.networkId = FRAMEWORK_NETWORK_ID; 1299 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 1300 setupAndStartConnectSequence(config); 1301 validateSuccessfulConnectSequence(config); 1302 1303 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1304 new StateChangeResult(FRAMEWORK_NETWORK_ID, sWifiSsid, sBSSID, 1305 SupplicantState.ASSOCIATING)); 1306 mLooper.dispatchAll(); 1307 1308 WifiInfo wifiInfo = mCmi.getWifiInfo(); 1309 assertNotNull(wifiInfo); 1310 assertEquals(WifiConfigurationTestUtil.TEST_FQDN, wifiInfo.getPasspointFqdn()); 1311 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 1312 wifiInfo.getPasspointProviderFriendlyName()); 1313 } 1314 1315 /** 1316 * Tests that Passpoint fields in WifiInfo are reset when connecting to a non-Passpoint network 1317 * during DisconnectedState. 1318 * @throws Exception 1319 */ 1320 @Test testResetWifiInfoPasspointFields()1321 public void testResetWifiInfoPasspointFields() throws Exception { 1322 loadComponentsInStaMode(); 1323 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 1324 config.SSID = sWifiSsid.toString(); 1325 config.BSSID = sBSSID; 1326 config.networkId = PASSPOINT_NETWORK_ID; 1327 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 1328 setupAndStartConnectSequence(config); 1329 validateSuccessfulConnectSequence(config); 1330 1331 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1332 new StateChangeResult(PASSPOINT_NETWORK_ID, sWifiSsid, sBSSID, 1333 SupplicantState.ASSOCIATING)); 1334 mLooper.dispatchAll(); 1335 1336 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1337 new StateChangeResult(FRAMEWORK_NETWORK_ID, sWifiSsid, sBSSID, 1338 SupplicantState.ASSOCIATING)); 1339 mLooper.dispatchAll(); 1340 1341 WifiInfo wifiInfo = mCmi.getWifiInfo(); 1342 assertNotNull(wifiInfo); 1343 assertNull(wifiInfo.getPasspointFqdn()); 1344 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1345 } 1346 1347 /** 1348 * Tests the OSU information is set in WifiInfo for OSU AP connection. 1349 */ 1350 @Test connectOsuAp()1351 public void connectOsuAp() throws Exception { 1352 loadComponentsInStaMode(); 1353 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 1354 osuConfig.SSID = sWifiSsid.toString(); 1355 osuConfig.BSSID = sBSSID; 1356 osuConfig.osu = true; 1357 osuConfig.networkId = FRAMEWORK_NETWORK_ID; 1358 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 1359 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 1360 setupAndStartConnectSequence(osuConfig); 1361 validateSuccessfulConnectSequence(osuConfig); 1362 1363 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1364 new StateChangeResult(FRAMEWORK_NETWORK_ID, sWifiSsid, sBSSID, 1365 SupplicantState.ASSOCIATING)); 1366 mLooper.dispatchAll(); 1367 1368 WifiInfo wifiInfo = mCmi.getWifiInfo(); 1369 assertNotNull(wifiInfo); 1370 assertTrue(wifiInfo.isOsuAp()); 1371 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 1372 wifiInfo.getPasspointProviderFriendlyName()); 1373 } 1374 1375 /** 1376 * Tests that OSU fields in WifiInfo are reset when connecting to a non-OSU network during 1377 * DisconnectedState. 1378 * @throws Exception 1379 */ 1380 @Test testResetWifiInfoOsuFields()1381 public void testResetWifiInfoOsuFields() throws Exception { 1382 loadComponentsInStaMode(); 1383 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 1384 osuConfig.SSID = sWifiSsid.toString(); 1385 osuConfig.BSSID = sBSSID; 1386 osuConfig.osu = true; 1387 osuConfig.networkId = PASSPOINT_NETWORK_ID; 1388 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 1389 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 1390 setupAndStartConnectSequence(osuConfig); 1391 validateSuccessfulConnectSequence(osuConfig); 1392 1393 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1394 new StateChangeResult(PASSPOINT_NETWORK_ID, sWifiSsid, sBSSID, 1395 SupplicantState.ASSOCIATING)); 1396 mLooper.dispatchAll(); 1397 1398 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1399 new StateChangeResult(FRAMEWORK_NETWORK_ID, sWifiSsid, sBSSID, 1400 SupplicantState.ASSOCIATING)); 1401 mLooper.dispatchAll(); 1402 1403 WifiInfo wifiInfo = mCmi.getWifiInfo(); 1404 assertNotNull(wifiInfo); 1405 assertFalse(wifiInfo.isOsuAp()); 1406 } 1407 1408 /** 1409 * Verify that WifiStateTracker is called if wifi is disabled while connected. 1410 */ 1411 @Test verifyWifiStateTrackerUpdatedWhenDisabled()1412 public void verifyWifiStateTrackerUpdatedWhenDisabled() throws Exception { 1413 connect(); 1414 1415 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 1416 mLooper.dispatchAll(); 1417 verify(mWifiStateTracker).updateState(eq(WifiStateTracker.DISCONNECTED)); 1418 } 1419 1420 /** 1421 * Tests the network connection initiation sequence with no network request pending from 1422 * from WifiNetworkFactory when we're already connected to a different network. 1423 * This simulates the connect sequence using the public 1424 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 1425 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1426 */ 1427 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnected()1428 public void triggerConnectWithNoNetworkRequestAndAlreadyConnected() throws Exception { 1429 // Simulate the first connection. 1430 connect(); 1431 1432 // Remove the network requests. 1433 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1434 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1435 1436 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1437 config.networkId = FRAMEWORK_NETWORK_ID + 1; 1438 setupAndStartConnectSequence(config); 1439 validateSuccessfulConnectSequence(config); 1440 verify(mWifiPermissionsUtil, atLeastOnce()).checkNetworkSettingsPermission(anyInt()); 1441 } 1442 1443 /** 1444 * Tests the network connection initiation sequence from a non-privileged app with no network 1445 * request pending from from WifiNetworkFactory when we're already connected to a different 1446 * network. 1447 * This simulates the connect sequence using the public 1448 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 1449 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1450 */ 1451 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp()1452 public void triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp() 1453 throws Exception { 1454 // Simulate the first connection. 1455 connect(); 1456 1457 // Remove the network requests. 1458 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1459 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1460 1461 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 1462 1463 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1464 config.networkId = FRAMEWORK_NETWORK_ID + 1; 1465 setupAndStartConnectSequence(config); 1466 verify(mWifiConfigManager).enableNetwork( 1467 eq(config.networkId), eq(true), anyInt(), any()); 1468 verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(config.networkId)); 1469 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1470 verify(mWifiConfigManager, never()) 1471 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 1472 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 1473 verify(mWifiPermissionsUtil, times(4)).checkNetworkSettingsPermission(anyInt()); 1474 } 1475 1476 @Test enableWithInvalidNetworkId()1477 public void enableWithInvalidNetworkId() throws Exception { 1478 initializeAndAddNetworkAndVerifySuccess(); 1479 when(mWifiConfigManager.getConfiguredNetwork(eq(0))).thenReturn(null); 1480 1481 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 1482 1483 IActionListener connectActionListener = mock(IActionListener.class); 1484 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1485 mLooper.dispatchAll(); 1486 verify(connectActionListener).onFailure(anyInt()); 1487 1488 verify(mWifiConfigManager, never()).enableNetwork(eq(0), eq(true), anyInt(), any()); 1489 verify(mWifiConfigManager, never()).updateLastConnectUid(eq(0), anyInt()); 1490 } 1491 1492 /** 1493 * If caller tries to connect to a network that is already connected, the connection request 1494 * should succeed. 1495 * 1496 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 1497 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 1498 */ 1499 @Test reconnectToConnectedNetworkWithNetworkId()1500 public void reconnectToConnectedNetworkWithNetworkId() throws Exception { 1501 connect(); 1502 1503 // try to reconnect 1504 IActionListener connectActionListener = mock(IActionListener.class); 1505 mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 1506 Binder.getCallingUid()); 1507 mLooper.dispatchAll(); 1508 verify(connectActionListener).onSuccess(); 1509 1510 // Verify that we didn't trigger a second connection. 1511 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1512 } 1513 1514 /** 1515 * If caller tries to connect to a network that is already connected, the connection request 1516 * should succeed. 1517 * 1518 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 1519 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 1520 */ 1521 @Test reconnectToConnectedNetworkWithConfig()1522 public void reconnectToConnectedNetworkWithConfig() throws Exception { 1523 connect(); 1524 1525 // try to reconnect 1526 WifiConfiguration config = new WifiConfiguration(); 1527 config.networkId = FRAMEWORK_NETWORK_ID; 1528 when(mWifiConfigManager.addOrUpdateNetwork(eq(config), anyInt())) 1529 .thenReturn(new NetworkUpdateResult(FRAMEWORK_NETWORK_ID)); 1530 IActionListener connectActionListener = mock(IActionListener.class); 1531 mCmi.connect(config, WifiConfiguration.INVALID_NETWORK_ID, mock(Binder.class), 1532 connectActionListener, 0, Binder.getCallingUid()); 1533 mLooper.dispatchAll(); 1534 verify(connectActionListener).onSuccess(); 1535 1536 // Verify that we didn't trigger a second connection. 1537 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1538 } 1539 1540 /** 1541 * If caller tries to connect to a network that is already connecting, the connection request 1542 * should succeed. 1543 * 1544 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 1545 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did not trigger a 1546 * new connection. 1547 */ 1548 @Test reconnectToConnectingNetwork()1549 public void reconnectToConnectingNetwork() throws Exception { 1550 triggerConnect(); 1551 1552 // try to reconnect to the same network (before connection is established). 1553 IActionListener connectActionListener = mock(IActionListener.class); 1554 mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 1555 Binder.getCallingUid()); 1556 mLooper.dispatchAll(); 1557 verify(connectActionListener).onSuccess(); 1558 1559 // Verify that we didn't trigger a second connection. 1560 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1561 } 1562 1563 /** 1564 * If caller tries to connect to a network that is already connecting, the connection request 1565 * should succeed. 1566 * 1567 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 1568 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did trigger a new 1569 * connection. 1570 */ 1571 @Test reconnectToConnectingNetworkWithCredentialChange()1572 public void reconnectToConnectingNetworkWithCredentialChange() throws Exception { 1573 triggerConnect(); 1574 1575 // try to reconnect to the same network with a credential changed (before connection is 1576 // established). 1577 WifiConfiguration config = new WifiConfiguration(); 1578 config.networkId = FRAMEWORK_NETWORK_ID; 1579 NetworkUpdateResult networkUpdateResult = 1580 new NetworkUpdateResult(false /* ip */, false /* proxy */, true /* credential */); 1581 networkUpdateResult.setNetworkId(FRAMEWORK_NETWORK_ID); 1582 when(mWifiConfigManager.addOrUpdateNetwork(eq(config), anyInt())) 1583 .thenReturn(networkUpdateResult); 1584 IActionListener connectActionListener = mock(IActionListener.class); 1585 mCmi.connect(config, WifiConfiguration.INVALID_NETWORK_ID, mock(Binder.class), 1586 connectActionListener, 0, Binder.getCallingUid()); 1587 mLooper.dispatchAll(); 1588 verify(connectActionListener).onSuccess(); 1589 1590 // Verify that we triggered a second connection. 1591 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1592 } 1593 1594 /** 1595 * If caller tries to connect to a network that previously failed connection, the connection 1596 * request should succeed. 1597 * 1598 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 1599 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 1600 * and did trigger a new * connection. 1601 */ 1602 @Test connectAfterAssociationRejection()1603 public void connectAfterAssociationRejection() throws Exception { 1604 triggerConnect(); 1605 1606 // fail the connection. 1607 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 1608 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, sBSSID); 1609 mLooper.dispatchAll(); 1610 1611 IActionListener connectActionListener = mock(IActionListener.class); 1612 mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 1613 Binder.getCallingUid()); 1614 mLooper.dispatchAll(); 1615 verify(connectActionListener).onSuccess(); 1616 1617 // Verify that we triggered a second connection. 1618 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1619 } 1620 1621 /** 1622 * If caller tries to connect to a network that previously failed connection, the connection 1623 * request should succeed. 1624 * 1625 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 1626 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 1627 * and did trigger a new * connection. 1628 */ 1629 @Test connectAfterConnectionFailure()1630 public void connectAfterConnectionFailure() throws Exception { 1631 triggerConnect(); 1632 1633 // fail the connection. 1634 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, FRAMEWORK_NETWORK_ID, 0, sBSSID); 1635 mLooper.dispatchAll(); 1636 1637 IActionListener connectActionListener = mock(IActionListener.class); 1638 mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 1639 Binder.getCallingUid()); 1640 mLooper.dispatchAll(); 1641 verify(connectActionListener).onSuccess(); 1642 1643 // Verify that we triggered a second connection. 1644 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1645 } 1646 1647 /** 1648 * If caller tries to connect to a new network while still provisioning the current one, 1649 * the connection attempt should succeed. 1650 */ 1651 @Test connectWhileObtainingIp()1652 public void connectWhileObtainingIp() throws Exception { 1653 initializeAndAddNetworkAndVerifySuccess(); 1654 1655 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 1656 1657 IActionListener connectActionListener = mock(IActionListener.class); 1658 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1659 mLooper.dispatchAll(); 1660 verify(connectActionListener).onSuccess(); 1661 1662 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1663 1664 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1665 mLooper.dispatchAll(); 1666 1667 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1668 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1669 mLooper.dispatchAll(); 1670 1671 assertEquals("ObtainingIpState", getCurrentState().getName()); 1672 reset(mWifiNative); 1673 1674 // Connect to a different network 1675 WifiConfiguration config = new WifiConfiguration(); 1676 config.networkId = TEST_NETWORK_ID; 1677 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 1678 1679 mCmi.connect(null, TEST_NETWORK_ID, mock(Binder.class), null, 0, Binder.getCallingUid()); 1680 mLooper.dispatchAll(); 1681 1682 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1683 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 1684 mLooper.dispatchAll(); 1685 1686 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1687 1688 } 1689 1690 /** 1691 * Tests that manual connection to a network (from settings app) logs the correct nominator ID. 1692 */ 1693 @Test testManualConnectNominator()1694 public void testManualConnectNominator() throws Exception { 1695 initializeAndAddNetworkAndVerifySuccess(); 1696 1697 WifiConfiguration config = new WifiConfiguration(); 1698 config.networkId = TEST_NETWORK_ID; 1699 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 1700 1701 IActionListener connectActionListener = mock(IActionListener.class); 1702 mCmi.connect(null, TEST_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 1703 Process.SYSTEM_UID); 1704 mLooper.dispatchAll(); 1705 verify(connectActionListener).onSuccess(); 1706 1707 verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, 1708 WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); 1709 } 1710 1711 @Test testDhcpFailure()1712 public void testDhcpFailure() throws Exception { 1713 initializeAndAddNetworkAndVerifySuccess(); 1714 1715 IActionListener connectActionListener = mock(IActionListener.class); 1716 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1717 mLooper.dispatchAll(); 1718 verify(connectActionListener).onSuccess(); 1719 1720 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1721 1722 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1723 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); 1724 mLooper.dispatchAll(); 1725 1726 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 1727 mLooper.dispatchAll(); 1728 verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID, sSSID); 1729 1730 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1731 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1732 mLooper.dispatchAll(); 1733 1734 assertEquals("ObtainingIpState", getCurrentState().getName()); 1735 injectDhcpFailure(); 1736 mLooper.dispatchAll(); 1737 1738 assertEquals("DisconnectingState", getCurrentState().getName()); 1739 // Verify this is not counted as a IP renewal failure 1740 verify(mWifiMetrics, never()).incrementIpRenewalFailure(); 1741 // Verifies that WifiLastResortWatchdog be notified 1742 // by DHCP failure 1743 verify(mWifiLastResortWatchdog, times(2)).noteConnectionFailureAndTriggerIfNeeded( 1744 sSSID, sBSSID, WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1745 verify(mBssidBlocklistMonitor, times(2)).handleBssidConnectionFailure(sBSSID, 1746 sSSID, BssidBlocklistMonitor.REASON_DHCP_FAILURE, false); 1747 verify(mBssidBlocklistMonitor, times(2)).handleBssidConnectionFailure(sBSSID, sSSID, 1748 BssidBlocklistMonitor.REASON_DHCP_FAILURE, false); 1749 verify(mBssidBlocklistMonitor, never()).handleDhcpProvisioningSuccess(sBSSID, sSSID); 1750 verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID, sSSID); 1751 } 1752 1753 /** 1754 * Verify that a IP renewal failure is logged when IP provisioning fail in the 1755 * ConnectedState. 1756 */ 1757 @Test testDhcpRenewalMetrics()1758 public void testDhcpRenewalMetrics() throws Exception { 1759 connect(); 1760 injectDhcpFailure(); 1761 mLooper.dispatchAll(); 1762 1763 verify(mWifiMetrics).incrementIpRenewalFailure(); 1764 } 1765 1766 /** 1767 * Verify that the network selection status will be updated with DISABLED_AUTHENTICATION_FAILURE 1768 * when wrong password authentication failure is detected and the network had been 1769 * connected previously. 1770 */ 1771 @Test testWrongPasswordWithPreviouslyConnected()1772 public void testWrongPasswordWithPreviouslyConnected() throws Exception { 1773 initializeAndAddNetworkAndVerifySuccess(); 1774 1775 IActionListener connectActionListener = mock(IActionListener.class); 1776 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1777 mLooper.dispatchAll(); 1778 verify(connectActionListener).onSuccess(); 1779 1780 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1781 1782 WifiConfiguration config = new WifiConfiguration(); 1783 config.getNetworkSelectionStatus().setHasEverConnected(true); 1784 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 1785 1786 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1787 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 1788 mLooper.dispatchAll(); 1789 1790 verify(mWrongPasswordNotifier, never()).onWrongPasswordError(anyString()); 1791 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 1792 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE)); 1793 1794 assertEquals("DisconnectedState", getCurrentState().getName()); 1795 } 1796 1797 /** 1798 * Verify that the network selection status will be updated with DISABLED_BY_WRONG_PASSWORD 1799 * when wrong password authentication failure is detected and the network has never been 1800 * connected. 1801 */ 1802 @Test testWrongPasswordWithNeverConnected()1803 public void testWrongPasswordWithNeverConnected() throws Exception { 1804 initializeAndAddNetworkAndVerifySuccess(); 1805 1806 IActionListener connectActionListener = mock(IActionListener.class); 1807 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1808 mLooper.dispatchAll(); 1809 verify(connectActionListener).onSuccess(); 1810 1811 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1812 1813 WifiConfiguration config = new WifiConfiguration(); 1814 config.SSID = sSSID; 1815 config.getNetworkSelectionStatus().setHasEverConnected(false); 1816 config.carrierId = CARRIER_ID_1; 1817 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 1818 1819 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1820 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 1821 mLooper.dispatchAll(); 1822 1823 verify(mWrongPasswordNotifier).onWrongPasswordError(eq(sSSID)); 1824 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 1825 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)); 1826 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionAuthFailure(); 1827 assertEquals("DisconnectedState", getCurrentState().getName()); 1828 } 1829 1830 /** 1831 * Verify that the network selection status will be updated with DISABLED_BY_WRONG_PASSWORD 1832 * when wrong password authentication failure is detected and the network is unknown. 1833 */ 1834 @Test testWrongPasswordWithNullNetwork()1835 public void testWrongPasswordWithNullNetwork() throws Exception { 1836 initializeAndAddNetworkAndVerifySuccess(); 1837 1838 IActionListener connectActionListener = mock(IActionListener.class); 1839 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1840 mLooper.dispatchAll(); 1841 verify(connectActionListener).onSuccess(); 1842 1843 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1844 1845 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 1846 1847 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1848 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 1849 mLooper.dispatchAll(); 1850 1851 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 1852 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)); 1853 assertEquals("DisconnectedState", getCurrentState().getName()); 1854 } 1855 1856 /** 1857 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 1858 * is called when a Authentication failure is detected with a vendor specific EAP Error 1859 * of certification expired while using EAP-SIM 1860 * In this test case, it is assumed that the network had been connected previously. 1861 */ 1862 @Test testEapSimErrorVendorSpecific()1863 public void testEapSimErrorVendorSpecific() throws Exception { 1864 when(mWifiMetrics.startConnectionEvent(any(), anyString(), anyInt())).thenReturn(80000); 1865 initializeAndAddNetworkAndVerifySuccess(); 1866 1867 IActionListener connectActionListener = mock(IActionListener.class); 1868 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1869 mLooper.dispatchAll(); 1870 verify(connectActionListener).onSuccess(); 1871 1872 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1873 1874 WifiConfiguration config = new WifiConfiguration(); 1875 config.SSID = sSSID; 1876 config.getNetworkSelectionStatus().setHasEverConnected(true); 1877 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 1878 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 1879 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 1880 MockitoSession mockSession = ExtendedMockito.mockitoSession() 1881 .mockStatic(SubscriptionManager.class) 1882 .startMocking(); 1883 when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID); 1884 when(SubscriptionManager.isValidSubscriptionId(anyInt())).thenReturn(true); 1885 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 1886 .thenReturn(WifiHealthMonitor.REASON_AUTH_FAILURE); 1887 1888 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1889 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 1890 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED); 1891 mLooper.dispatchAll(); 1892 1893 verify(mEapFailureNotifier).onEapFailure( 1894 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED, config); 1895 verify(mDataTelephonyManager).resetCarrierKeysForImsiEncryption(); 1896 mockSession.finishMocking(); 1897 verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled(); 1898 verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString()); 1899 verify(mWifiDiagnostics, times(2)).takeBugReport(anyString(), anyString()); 1900 } 1901 1902 /** 1903 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 1904 * is not called when a Authentication failure is detected with a vendor specific EAP Error 1905 * of certification expired while using other methods than EAP-SIM, EAP-AKA, or EAP-AKA'. 1906 */ 1907 @Test testEapTlsErrorVendorSpecific()1908 public void testEapTlsErrorVendorSpecific() throws Exception { 1909 initializeAndAddNetworkAndVerifySuccess(); 1910 1911 IActionListener connectActionListener = mock(IActionListener.class); 1912 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1913 mLooper.dispatchAll(); 1914 verify(connectActionListener).onSuccess(); 1915 1916 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1917 1918 WifiConfiguration config = new WifiConfiguration(); 1919 config.getNetworkSelectionStatus().setHasEverConnected(true); 1920 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 1921 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 1922 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 1923 1924 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1925 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 1926 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED); 1927 mLooper.dispatchAll(); 1928 1929 verify(mDataTelephonyManager, never()).resetCarrierKeysForImsiEncryption(); 1930 } 1931 1932 /** 1933 * Verify that the network selection status will be updated with 1934 * DISABLED_AUTHENTICATION_NO_SUBSCRIBED when service is not subscribed. 1935 */ 1936 @Test testEapSimNoSubscribedError()1937 public void testEapSimNoSubscribedError() throws Exception { 1938 initializeAndAddNetworkAndVerifySuccess(); 1939 1940 IActionListener connectActionListener = mock(IActionListener.class); 1941 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1942 mLooper.dispatchAll(); 1943 verify(connectActionListener).onSuccess(); 1944 1945 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1946 1947 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 1948 1949 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 1950 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 1951 WifiNative.EAP_SIM_NOT_SUBSCRIBED); 1952 mLooper.dispatchAll(); 1953 1954 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 1955 eq(WifiConfiguration.NetworkSelectionStatus 1956 .DISABLED_AUTHENTICATION_NO_SUBSCRIPTION)); 1957 } 1958 1959 @Test testBadNetworkEvent()1960 public void testBadNetworkEvent() throws Exception { 1961 initializeAndAddNetworkAndVerifySuccess(); 1962 1963 IActionListener connectActionListener = mock(IActionListener.class); 1964 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 1965 mLooper.dispatchAll(); 1966 verify(connectActionListener).onSuccess(); 1967 1968 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 1969 1970 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 1971 mLooper.dispatchAll(); 1972 1973 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1974 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1975 mLooper.dispatchAll(); 1976 1977 assertEquals("DisconnectedState", getCurrentState().getName()); 1978 verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString()); 1979 } 1980 1981 1982 @Test getWhatToString()1983 public void getWhatToString() throws Exception { 1984 assertEquals("CMD_CHANNEL_HALF_CONNECTED", mCmi.getWhatToString( 1985 AsyncChannel.CMD_CHANNEL_HALF_CONNECTED)); 1986 assertEquals("CMD_PRE_DHCP_ACTION", mCmi.getWhatToString(CMD_PRE_DHCP_ACTION)); 1987 assertEquals("CMD_IP_REACHABILITY_LOST", mCmi.getWhatToString( 1988 ClientModeImpl.CMD_IP_REACHABILITY_LOST)); 1989 } 1990 1991 @Test disconnect()1992 public void disconnect() throws Exception { 1993 when(mWifiScoreCard.detectAbnormalDisconnection()) 1994 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 1995 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 1996 connect(); 1997 inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(true); 1998 1999 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, sBSSID); 2000 mLooper.dispatchAll(); 2001 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2002 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 2003 mLooper.dispatchAll(); 2004 2005 verify(mWifiStateTracker).updateState(eq(WifiStateTracker.DISCONNECTED)); 2006 verify(mWifiNetworkSuggestionsManager).handleDisconnect(any(), any()); 2007 assertEquals("DisconnectedState", getCurrentState().getName()); 2008 inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(false); 2009 verify(mWifiScoreCard).detectAbnormalDisconnection(); 2010 verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); 2011 } 2012 2013 /** 2014 * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected 2015 * to true. 2016 * 2017 * Test: Successfully create and connect to a network. Check the config and verify 2018 * WifiConfiguration.getHasEverConnected() is true. 2019 */ 2020 @Test setHasEverConnectedTrueOnConnect()2021 public void setHasEverConnectedTrueOnConnect() throws Exception { 2022 connect(); 2023 verify(mWifiConfigManager, atLeastOnce()).updateNetworkAfterConnect(0); 2024 } 2025 2026 /** 2027 * Fail network connection attempt and verify HasEverConnected remains false. 2028 * 2029 * Test: Successfully create a network but fail when connecting. Check the config and verify 2030 * WifiConfiguration.getHasEverConnected() is false. 2031 */ 2032 @Test connectionFailureDoesNotSetHasEverConnectedTrue()2033 public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception { 2034 testDhcpFailure(); 2035 verify(mWifiConfigManager, never()).updateNetworkAfterConnect(0); 2036 } 2037 2038 @Test iconQueryTest()2039 public void iconQueryTest() throws Exception { 2040 // TODO(b/31065385): Passpoint config management. 2041 } 2042 2043 @Test verboseLogRecSizeIsGreaterThanNormalSize()2044 public void verboseLogRecSizeIsGreaterThanNormalSize() { 2045 assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > ClientModeImpl.NUM_LOG_RECS_NORMAL); 2046 } 2047 2048 /** 2049 * Verifies that, by default, we allow only the "normal" number of log records. 2050 */ 2051 @Test normalLogRecSizeIsUsedByDefault()2052 public void normalLogRecSizeIsUsedByDefault() { 2053 assertEquals(ClientModeImpl.NUM_LOG_RECS_NORMAL, mCmi.getLogRecMaxSize()); 2054 } 2055 2056 /** 2057 * Verifies that, in verbose mode, we allow a larger number of log records. 2058 */ 2059 @Test enablingVerboseLoggingUpdatesLogRecSize()2060 public void enablingVerboseLoggingUpdatesLogRecSize() { 2061 mCmi.enableVerboseLogging(1); 2062 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mCmi.getLogRecMaxSize()); 2063 } 2064 2065 @Test disablingVerboseLoggingClearsRecords()2066 public void disablingVerboseLoggingClearsRecords() { 2067 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 2068 mLooper.dispatchAll(); 2069 assertTrue(mCmi.getLogRecSize() >= 1); 2070 2071 mCmi.enableVerboseLogging(0); 2072 assertEquals(0, mCmi.getLogRecSize()); 2073 } 2074 2075 @Test disablingVerboseLoggingUpdatesLogRecSize()2076 public void disablingVerboseLoggingUpdatesLogRecSize() { 2077 mCmi.enableVerboseLogging(1); 2078 mCmi.enableVerboseLogging(0); 2079 assertEquals(ClientModeImpl.NUM_LOG_RECS_NORMAL, mCmi.getLogRecMaxSize()); 2080 } 2081 2082 @Test logRecsIncludeDisconnectCommand()2083 public void logRecsIncludeDisconnectCommand() { 2084 // There's nothing special about the DISCONNECT command. It's just representative of 2085 // "normal" commands. 2086 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 2087 mLooper.dispatchAll(); 2088 assertEquals(1, mCmi.copyLogRecs() 2089 .stream() 2090 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_DISCONNECT) 2091 .count()); 2092 } 2093 2094 @Test logRecsExcludeRssiPollCommandByDefault()2095 public void logRecsExcludeRssiPollCommandByDefault() { 2096 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 2097 mLooper.dispatchAll(); 2098 assertEquals(0, mCmi.copyLogRecs() 2099 .stream() 2100 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 2101 .count()); 2102 } 2103 2104 @Test logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled()2105 public void logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled() { 2106 mCmi.enableVerboseLogging(1); 2107 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 2108 mLooper.dispatchAll(); 2109 assertEquals(1, mCmi.copyLogRecs() 2110 .stream() 2111 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 2112 .count()); 2113 } 2114 2115 /** 2116 * Verify that syncStartSubscriptionProvisioning will redirect calls with right parameters 2117 * to {@link PasspointManager} with expected true being returned when in client mode. 2118 */ 2119 @Test syncStartSubscriptionProvisioningInClientMode()2120 public void syncStartSubscriptionProvisioningInClientMode() throws Exception { 2121 loadComponentsInStaMode(); 2122 when(mPasspointManager.startSubscriptionProvisioning(anyInt(), 2123 any(OsuProvider.class), any(IProvisioningCallback.class))).thenReturn(true); 2124 mLooper.startAutoDispatch(); 2125 assertTrue(mCmi.syncStartSubscriptionProvisioning( 2126 OTHER_USER_UID, mOsuProvider, mProvisioningCallback, mCmiAsyncChannel)); 2127 verify(mPasspointManager).startSubscriptionProvisioning(OTHER_USER_UID, mOsuProvider, 2128 mProvisioningCallback); 2129 mLooper.stopAutoDispatch(); 2130 } 2131 2132 /** 2133 * Verify that syncStartSubscriptionProvisioning will be a no-op and return false before 2134 * SUPPLICANT_START command is received by the CMI. 2135 */ 2136 @Test syncStartSubscriptionProvisioningBeforeSupplicantOrAPStart()2137 public void syncStartSubscriptionProvisioningBeforeSupplicantOrAPStart() throws Exception { 2138 mLooper.startAutoDispatch(); 2139 assertFalse(mCmi.syncStartSubscriptionProvisioning( 2140 OTHER_USER_UID, mOsuProvider, mProvisioningCallback, mCmiAsyncChannel)); 2141 mLooper.stopAutoDispatch(); 2142 verify(mPasspointManager, never()).startSubscriptionProvisioning( 2143 anyInt(), any(OsuProvider.class), any(IProvisioningCallback.class)); 2144 } 2145 2146 /** 2147 * Verify that syncStartSubscriptionProvisioning will be a no-op and return false when not in 2148 * client mode. 2149 */ 2150 @Test syncStartSubscriptionProvisioningNoOpWifiDisabled()2151 public void syncStartSubscriptionProvisioningNoOpWifiDisabled() throws Exception { 2152 mLooper.startAutoDispatch(); 2153 assertFalse(mCmi.syncStartSubscriptionProvisioning( 2154 OTHER_USER_UID, mOsuProvider, mProvisioningCallback, mCmiAsyncChannel)); 2155 mLooper.stopAutoDispatch(); 2156 verify(mPasspointManager, never()).startSubscriptionProvisioning( 2157 anyInt(), any(OsuProvider.class), any(IProvisioningCallback.class)); 2158 } 2159 2160 /** 2161 * Test that we disconnect from a network if it was removed while we are in the 2162 * ObtainingIpState. 2163 */ 2164 @Test disconnectFromNetworkWhenRemovedWhileObtainingIpAddr()2165 public void disconnectFromNetworkWhenRemovedWhileObtainingIpAddr() throws Exception { 2166 initializeAndAddNetworkAndVerifySuccess(); 2167 2168 when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt(), any())) 2169 .thenReturn(true); 2170 when(mWifiConfigManager.updateLastConnectUid(eq(0), anyInt())).thenReturn(true); 2171 2172 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 2173 2174 IActionListener connectActionListener = mock(IActionListener.class); 2175 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 2176 mLooper.dispatchAll(); 2177 verify(connectActionListener).onSuccess(); 2178 2179 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 2180 verify(mWifiConnectivityManager).setUserConnectChoice(eq(0)); 2181 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2182 .thenReturn(mScanDetailCache); 2183 2184 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 2185 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 2186 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 2187 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 2188 2189 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 2190 mLooper.dispatchAll(); 2191 2192 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2193 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 2194 mLooper.dispatchAll(); 2195 2196 assertEquals("ObtainingIpState", getCurrentState().getName()); 2197 2198 // now remove the config 2199 reset(connectActionListener); 2200 when(mWifiConfigManager.removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt(), any())) 2201 .thenReturn(true); 2202 mCmi.forget(FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0, 2203 Binder.getCallingUid()); 2204 mLooper.dispatchAll(); 2205 verify(connectActionListener).onSuccess(); 2206 verify(mWifiConfigManager).removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt(), any()); 2207 // trigger removal callback to trigger disconnect. 2208 WifiConfiguration removedConfig = new WifiConfiguration(); 2209 removedConfig.networkId = FRAMEWORK_NETWORK_ID; 2210 mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedConfig); 2211 2212 reset(mWifiConfigManager); 2213 2214 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)).thenReturn(null); 2215 2216 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 2217 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 2218 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 2219 dhcpResults.baseConfiguration.ipAddress = 2220 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 2221 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 2222 dhcpResults.leaseDuration = 3600; 2223 2224 injectDhcpSuccess(dhcpResults); 2225 mLooper.dispatchAll(); 2226 2227 assertEquals("DisconnectingState", getCurrentState().getName()); 2228 } 2229 2230 /** 2231 * Test verifying that interface Supplicant update for inactive driver does not trigger 2232 * SelfRecovery when WifiNative reports the interface is up. 2233 */ 2234 @Test testSupplicantUpdateDriverInactiveIfaceUpClientModeDoesNotTriggerSelfRecovery()2235 public void testSupplicantUpdateDriverInactiveIfaceUpClientModeDoesNotTriggerSelfRecovery() 2236 throws Exception { 2237 // Trigger initialize to capture the death handler registration. 2238 loadComponentsInStaMode(); 2239 2240 when(mWifiNative.isInterfaceUp(eq(WIFI_IFACE_NAME))).thenReturn(true); 2241 2242 // make sure supplicant has been reported as inactive 2243 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2244 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(""), null, 2245 SupplicantState.INTERFACE_DISABLED)); 2246 mLooper.dispatchAll(); 2247 2248 // CMI should trigger self recovery, but not disconnect until externally triggered 2249 verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_STA_IFACE_DOWN)); 2250 } 2251 2252 /** 2253 * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. 2254 */ 2255 @Test testWifiInfoUpdatedUponSupplicantStateChangedEvent()2256 public void testWifiInfoUpdatedUponSupplicantStateChangedEvent() throws Exception { 2257 // Connect to network with |sBSSID|, |sFreq|. 2258 connect(); 2259 2260 // Set the scan detail cache for roaming target. 2261 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2262 .thenReturn(mScanDetailCache); 2263 when(mScanDetailCache.getScanDetail(sBSSID1)).thenReturn( 2264 getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1)); 2265 when(mScanDetailCache.getScanResult(sBSSID1)).thenReturn( 2266 getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1).getScanResult()); 2267 2268 // This simulates the behavior of roaming to network with |sBSSID1|, |sFreq1|. 2269 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. 2270 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2271 new StateChangeResult(0, sWifiSsid, sBSSID1, SupplicantState.COMPLETED)); 2272 mLooper.dispatchAll(); 2273 2274 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2275 assertEquals(sBSSID1, wifiInfo.getBSSID()); 2276 assertEquals(sFreq1, wifiInfo.getFrequency()); 2277 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2278 2279 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2280 new StateChangeResult(0, sWifiSsid, sBSSID1, SupplicantState.DISCONNECTED)); 2281 mLooper.dispatchAll(); 2282 2283 wifiInfo = mCmi.getWifiInfo(); 2284 assertNull(wifiInfo.getBSSID()); 2285 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 2286 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, wifiInfo.getNetworkId()); 2287 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2288 } 2289 2290 /** 2291 * Verifies that WifiInfo is updated upon CMD_ASSOCIATED_BSSID event. 2292 */ 2293 @Test testWifiInfoUpdatedUponAssociatedBSSIDEvent()2294 public void testWifiInfoUpdatedUponAssociatedBSSIDEvent() throws Exception { 2295 // Connect to network with |sBSSID|, |sFreq|. 2296 connect(); 2297 2298 // Set the scan detail cache for roaming target. 2299 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2300 .thenReturn(mScanDetailCache); 2301 when(mScanDetailCache.getScanDetail(sBSSID1)).thenReturn( 2302 getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1)); 2303 when(mScanDetailCache.getScanResult(sBSSID1)).thenReturn( 2304 getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1).getScanResult()); 2305 2306 // This simulates the behavior of roaming to network with |sBSSID1|, |sFreq1|. 2307 // Send a CMD_ASSOCIATED_BSSID, verify WifiInfo is updated. 2308 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, sBSSID1); 2309 mLooper.dispatchAll(); 2310 2311 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2312 assertEquals(sBSSID1, wifiInfo.getBSSID()); 2313 assertEquals(sFreq1, wifiInfo.getFrequency()); 2314 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2315 } 2316 2317 /** 2318 * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not 2319 * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState. 2320 * This protects ClientModeImpl from getting into a bad state where WifiInfo says wifi is 2321 * already Connected or Connecting, (when it is in-fact Disconnected), so 2322 * WifiConnectivityManager does not attempt any new Connections, freezing wifi. 2323 */ 2324 @Test testWifiInfoCleanedUpEnteringExitingConnectModeState()2325 public void testWifiInfoCleanedUpEnteringExitingConnectModeState() throws Exception { 2326 InOrder inOrder = inOrder(mWifiConnectivityManager, mWifiNetworkFactory); 2327 InOrder inOrderSarMgr = inOrder(mSarManager); 2328 InOrder inOrderMetrics = inOrder(mWifiMetrics); 2329 Log.i(TAG, mCmi.getCurrentState().getName()); 2330 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 2331 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2332 wifiInfo.setBSSID(initialBSSID); 2333 2334 // Set CMI to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager 2335 startSupplicantAndDispatchMessages(); 2336 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2337 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2338 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); 2339 inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true)); 2340 inOrderMetrics.verify(mWifiMetrics) 2341 .setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 2342 inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_ENABLED); 2343 assertNull(wifiInfo.getBSSID()); 2344 2345 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated 2346 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2347 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 2348 mLooper.dispatchAll(); 2349 assertEquals(sBSSID, wifiInfo.getBSSID()); 2350 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2351 2352 // Set CMI to DISABLED_MODE, verify state and wifi disabled in ConnectivityManager, and 2353 // WifiInfo is reset() and state set to DISCONNECTED 2354 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_DISABLED); 2355 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 2356 mLooper.dispatchAll(); 2357 2358 assertEquals(ClientModeImpl.DISABLED_MODE, mCmi.getOperationalModeForTest()); 2359 assertEquals("DefaultState", getCurrentState().getName()); 2360 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 2361 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false)); 2362 inOrder.verify(mWifiNetworkFactory).setWifiState(eq(false)); 2363 inOrderMetrics.verify(mWifiMetrics).setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED); 2364 inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_DISABLED); 2365 assertNull(wifiInfo.getBSSID()); 2366 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2367 2368 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated 2369 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2370 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 2371 mLooper.dispatchAll(); 2372 assertNull(wifiInfo.getBSSID()); 2373 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2374 2375 // Set the bssid to something, so we can verify it is cleared (just in case) 2376 wifiInfo.setBSSID(initialBSSID); 2377 2378 // Set CMI to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager, 2379 // and WifiInfo has been reset 2380 startSupplicantAndDispatchMessages(); 2381 2382 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2383 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2384 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); 2385 inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true)); 2386 inOrderMetrics.verify(mWifiMetrics) 2387 .setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 2388 inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_ENABLED); 2389 assertEquals("DisconnectedState", getCurrentState().getName()); 2390 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2391 assertNull(wifiInfo.getBSSID()); 2392 } 2393 2394 /** 2395 * Test that connected SSID and BSSID are exposed to system server. 2396 * Also tests that {@link ClientModeImpl#syncRequestConnectionInfo()} always 2397 * returns a copy of WifiInfo. 2398 */ 2399 @Test testConnectedIdsAreVisibleFromSystemServer()2400 public void testConnectedIdsAreVisibleFromSystemServer() throws Exception { 2401 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2402 // Get into a connected state, with known BSSID and SSID 2403 connect(); 2404 assertEquals(sBSSID, wifiInfo.getBSSID()); 2405 assertEquals(sWifiSsid, wifiInfo.getWifiSsid()); 2406 2407 WifiInfo connectionInfo = mCmi.syncRequestConnectionInfo(); 2408 2409 assertNotEquals(wifiInfo, connectionInfo); 2410 assertEquals(wifiInfo.getSSID(), connectionInfo.getSSID()); 2411 assertEquals(wifiInfo.getBSSID(), connectionInfo.getBSSID()); 2412 assertEquals(wifiInfo.getMacAddress(), connectionInfo.getMacAddress()); 2413 } 2414 2415 /** 2416 * Test that reconnectCommand() triggers connectivity scan when ClientModeImpl 2417 * is in DisconnectedMode. 2418 */ 2419 @Test testReconnectCommandWhenDisconnected()2420 public void testReconnectCommandWhenDisconnected() throws Exception { 2421 // Connect to network with |sBSSID|, |sFreq|, and then disconnect. 2422 disconnect(); 2423 2424 mCmi.reconnectCommand(ClientModeImpl.WIFI_WORK_SOURCE); 2425 mLooper.dispatchAll(); 2426 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 2427 } 2428 2429 /** 2430 * Test that reconnectCommand() doesn't trigger connectivity scan when ClientModeImpl 2431 * is in ConnectedMode. 2432 */ 2433 @Test testReconnectCommandWhenConnected()2434 public void testReconnectCommandWhenConnected() throws Exception { 2435 // Connect to network with |sBSSID|, |sFreq|. 2436 connect(); 2437 2438 mCmi.reconnectCommand(ClientModeImpl.WIFI_WORK_SOURCE); 2439 mLooper.dispatchAll(); 2440 verify(mWifiConnectivityManager, never()) 2441 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 2442 } 2443 2444 /** 2445 * Adds the network without putting ClientModeImpl into ConnectMode. 2446 */ 2447 @Test addNetworkInDefaultState()2448 public void addNetworkInDefaultState() throws Exception { 2449 // We should not be in initial state now. 2450 assertTrue("DefaultState".equals(getCurrentState().getName())); 2451 initializeMocksForAddedNetwork(false); 2452 verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(0)); 2453 } 2454 2455 /** 2456 * Verifies that ClientModeImpl sets and unsets appropriate 'RecentFailureReason' values 2457 * on a WifiConfiguration when it fails association, authentication, or successfully connects 2458 */ 2459 @Test testExtraFailureReason_ApIsBusy()2460 public void testExtraFailureReason_ApIsBusy() throws Exception { 2461 // Setup CONNECT_MODE & a WifiConfiguration 2462 initializeAndAddNetworkAndVerifySuccess(); 2463 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 2464 // targetNetworkId state) 2465 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2466 mLooper.dispatchAll(); 2467 // Simulate an ASSOCIATION_REJECTION_EVENT, due to the AP being busy 2468 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 2469 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, sBSSID); 2470 mLooper.dispatchAll(); 2471 verify(mWifiConfigManager).setRecentFailureAssociationStatus(eq(0), 2472 eq(WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA)); 2473 assertEquals("DisconnectedState", getCurrentState().getName()); 2474 2475 // Simulate an AUTHENTICATION_FAILURE_EVENT, which should clear the ExtraFailureReason 2476 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2477 mLooper.dispatchAll(); 2478 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 0, 0, null); 2479 mLooper.dispatchAll(); 2480 verify(mWifiConfigManager, times(1)).clearRecentFailureReason(eq(0)); 2481 verify(mWifiConfigManager, times(1)).setRecentFailureAssociationStatus(anyInt(), anyInt()); 2482 2483 // Simulate a NETWORK_CONNECTION_EVENT which should clear the ExtraFailureReason 2484 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2485 mLooper.dispatchAll(); 2486 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null); 2487 mLooper.dispatchAll(); 2488 verify(mWifiConfigManager, times(2)).clearRecentFailureReason(eq(0)); 2489 verify(mWifiConfigManager, times(1)).setRecentFailureAssociationStatus(anyInt(), anyInt()); 2490 } 2491 makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, long timeSinceLastSelected)2492 private WifiConfiguration makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, 2493 long timeSinceLastSelected) { 2494 long lastSelectedTimestamp = 45666743454L; 2495 2496 when(mClock.getElapsedSinceBootMillis()).thenReturn( 2497 lastSelectedTimestamp + timeSinceLastSelected); 2498 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(lastSelectedTimestamp); 2499 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(lastSelectedNetworkId); 2500 2501 WifiConfiguration currentConfig = new WifiConfiguration(); 2502 currentConfig.networkId = lastSelectedNetworkId; 2503 return currentConfig; 2504 } 2505 2506 /** 2507 * Test that the helper method 2508 * {@link ClientModeImpl#shouldEvaluateWhetherToSendExplicitlySelected(WifiConfiguration)} 2509 * returns true when we connect to the last selected network before expiration of 2510 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 2511 */ 2512 @Test testShouldEvaluateWhetherToSendExplicitlySelected_SameNetworkNotExpired()2513 public void testShouldEvaluateWhetherToSendExplicitlySelected_SameNetworkNotExpired() { 2514 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2515 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2516 assertTrue(mCmi.shouldEvaluateWhetherToSendExplicitlySelected(currentConfig)); 2517 } 2518 2519 /** 2520 * Test that the helper method 2521 * {@link ClientModeImpl#shouldEvaluateWhetherToSendExplicitlySelected(WifiConfiguration)} 2522 * returns false when we connect to the last selected network after expiration of 2523 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 2524 */ 2525 @Test testShouldEvaluateWhetherToSendExplicitlySelected_SameNetworkExpired()2526 public void testShouldEvaluateWhetherToSendExplicitlySelected_SameNetworkExpired() { 2527 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2528 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 2529 assertFalse(mCmi.shouldEvaluateWhetherToSendExplicitlySelected(currentConfig)); 2530 } 2531 2532 /** 2533 * Test that the helper method 2534 * {@link ClientModeImpl#shouldEvaluateWhetherToSendExplicitlySelected(WifiConfiguration)} 2535 * returns false when we connect to a different network to the last selected network. 2536 */ 2537 @Test testShouldEvaluateWhetherToSendExplicitlySelected_DifferentNetwork()2538 public void testShouldEvaluateWhetherToSendExplicitlySelected_DifferentNetwork() { 2539 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2540 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2541 currentConfig.networkId = 4; 2542 assertFalse(mCmi.shouldEvaluateWhetherToSendExplicitlySelected(currentConfig)); 2543 } 2544 expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, Consumer<NetworkCapabilities> networkCapabilitiesChecker)2545 private void expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, 2546 Consumer<NetworkCapabilities> networkCapabilitiesChecker) { 2547 // Expects that the code calls registerNetworkAgent and provides a way for the test to 2548 // verify the messages sent through the NetworkAgent to ConnectivityService. 2549 // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. 2550 // TODO (b/134538181): consider exposing WifiNetworkAgent and using mocks. 2551 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 2552 ArgumentCaptor<NetworkAgentConfig> configCaptor = 2553 ArgumentCaptor.forClass(NetworkAgentConfig.class); 2554 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 2555 ArgumentCaptor.forClass(NetworkCapabilities.class); 2556 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 2557 any(NetworkInfo.class), any(LinkProperties.class), 2558 networkCapabilitiesCaptor.capture(), 2559 anyInt(), configCaptor.capture(), anyInt()); 2560 2561 registerAsyncChannel((x) -> { 2562 mNetworkAgentAsyncChannel = x; 2563 }, messengerCaptor.getValue(), mNetworkAgentHandler); 2564 configChecker.accept(configCaptor.getValue()); 2565 networkCapabilitiesChecker.accept(networkCapabilitiesCaptor.getValue()); 2566 2567 mNetworkAgentAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 2568 mLooper.dispatchAll(); 2569 } 2570 expectUnregisterNetworkAgent()2571 private void expectUnregisterNetworkAgent() { 2572 // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. 2573 // TODO (b/134538181): consider exposing WifiNetworkAgent and using mocks. 2574 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 2575 mLooper.dispatchAll(); 2576 verify(mNetworkAgentHandler).handleMessage(messageCaptor.capture()); 2577 Message message = messageCaptor.getValue(); 2578 assertNotNull(message); 2579 assertEquals(NetworkAgent.EVENT_NETWORK_INFO_CHANGED, message.what); 2580 NetworkInfo networkInfo = (NetworkInfo) message.obj; 2581 assertEquals(NetworkInfo.DetailedState.DISCONNECTED, networkInfo.getDetailedState()); 2582 } 2583 expectNetworkAgentUpdateCapabilities( Consumer<NetworkCapabilities> networkCapabilitiesChecker)2584 private void expectNetworkAgentUpdateCapabilities( 2585 Consumer<NetworkCapabilities> networkCapabilitiesChecker) { 2586 // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. 2587 // TODO (b/134538181): consider exposing WifiNetworkAgent and using mocks. 2588 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 2589 mLooper.dispatchAll(); 2590 verify(mNetworkAgentHandler).handleMessage(messageCaptor.capture()); 2591 Message message = messageCaptor.getValue(); 2592 assertNotNull(message); 2593 assertEquals(NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED, message.what); 2594 networkCapabilitiesChecker.accept((NetworkCapabilities) message.obj); 2595 } 2596 2597 /** 2598 * Verify that when a network is explicitly selected, but noInternetAccessExpected is false, 2599 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2600 * acceptUnvalidated and acceptPartialConnectivity. 2601 */ 2602 @Test testExplicitlySelected_ExplicitInternetExpected()2603 public void testExplicitlySelected_ExplicitInternetExpected() throws Exception { 2604 // Network is explicitly selected. 2605 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2606 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2607 mConnectedNetwork.noInternetAccessExpected = false; 2608 2609 connect(); 2610 expectRegisterNetworkAgent((agentConfig) -> { 2611 assertTrue(agentConfig.explicitlySelected); 2612 assertFalse(agentConfig.acceptUnvalidated); 2613 assertFalse(agentConfig.acceptPartialConnectivity); 2614 }, (cap) -> { }); 2615 } 2616 2617 /** 2618 * Verify that when a network is not explicitly selected, but noInternetAccessExpected is true, 2619 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2620 * acceptUnvalidated and acceptPartialConnectivity. 2621 */ 2622 @Test testExplicitlySelected_NotExplicitNoInternetExpected()2623 public void testExplicitlySelected_NotExplicitNoInternetExpected() throws Exception { 2624 // Network is no longer explicitly selected. 2625 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2626 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 2627 mConnectedNetwork.noInternetAccessExpected = true; 2628 2629 connect(); 2630 expectRegisterNetworkAgent((agentConfig) -> { 2631 assertFalse(agentConfig.explicitlySelected); 2632 assertFalse(agentConfig.acceptUnvalidated); 2633 assertTrue(agentConfig.acceptPartialConnectivity); 2634 }, (cap) -> { }); 2635 } 2636 2637 /** 2638 * Verify that when a network is explicitly selected, and noInternetAccessExpected is true, 2639 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2640 * acceptUnvalidated and acceptPartialConnectivity. 2641 */ 2642 @Test testExplicitlySelected_ExplicitNoInternetExpected()2643 public void testExplicitlySelected_ExplicitNoInternetExpected() throws Exception { 2644 // Network is explicitly selected. 2645 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2646 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2647 mConnectedNetwork.noInternetAccessExpected = true; 2648 2649 connect(); 2650 expectRegisterNetworkAgent((agentConfig) -> { 2651 assertTrue(agentConfig.explicitlySelected); 2652 assertTrue(agentConfig.acceptUnvalidated); 2653 assertTrue(agentConfig.acceptPartialConnectivity); 2654 }, (cap) -> { }); 2655 } 2656 2657 /** 2658 * Verify that CMI dump includes WakeupController. 2659 */ 2660 @Test testDumpShouldDumpWakeupController()2661 public void testDumpShouldDumpWakeupController() { 2662 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 2663 PrintWriter writer = new PrintWriter(stream); 2664 mCmi.dump(null, writer, null); 2665 verify(mWakeupController).dump(null, writer, null); 2666 } 2667 2668 @Test takeBugReportCallsWifiDiagnostics()2669 public void takeBugReportCallsWifiDiagnostics() { 2670 mCmi.takeBugReport(anyString(), anyString()); 2671 verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); 2672 } 2673 2674 /** 2675 * Verify that Rssi Monitoring is started and the callback registered after connecting. 2676 */ 2677 @Test verifyRssiMonitoringCallbackIsRegistered()2678 public void verifyRssiMonitoringCallbackIsRegistered() throws Exception { 2679 // Simulate the first connection. 2680 connect(); 2681 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 2682 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 2683 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 2684 anyInt(), any(NetworkAgentConfig.class), anyInt()); 2685 2686 ArrayList<Integer> thresholdsArray = new ArrayList<>(); 2687 thresholdsArray.add(RSSI_THRESHOLD_MAX); 2688 thresholdsArray.add(RSSI_THRESHOLD_MIN); 2689 Bundle thresholds = new Bundle(); 2690 thresholds.putIntegerArrayList("thresholds", thresholdsArray); 2691 Message message = new Message(); 2692 message.what = NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS; 2693 message.obj = thresholds; 2694 messengerCaptor.getValue().send(message); 2695 mLooper.dispatchAll(); 2696 2697 ArgumentCaptor<WifiNative.WifiRssiEventHandler> rssiEventHandlerCaptor = 2698 ArgumentCaptor.forClass(WifiNative.WifiRssiEventHandler.class); 2699 verify(mWifiNative).startRssiMonitoring(anyString(), anyByte(), anyByte(), 2700 rssiEventHandlerCaptor.capture()); 2701 2702 // breach below min 2703 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MIN); 2704 mLooper.dispatchAll(); 2705 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2706 assertEquals(RSSI_THRESHOLD_BREACH_MIN, wifiInfo.getRssi()); 2707 2708 // breach above max 2709 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MAX); 2710 mLooper.dispatchAll(); 2711 assertEquals(RSSI_THRESHOLD_BREACH_MAX, wifiInfo.getRssi()); 2712 } 2713 2714 /** 2715 * Verify that RSSI and link layer stats polling works in connected mode 2716 */ 2717 @Test verifyConnectedModeRssiPolling()2718 public void verifyConnectedModeRssiPolling() throws Exception { 2719 final long startMillis = 1_500_000_000_100L; 2720 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 2721 llStats.txmpdu_be = 1000; 2722 llStats.rxmpdu_bk = 2000; 2723 WifiNl80211Manager.SignalPollResult signalPollResult = 2724 new WifiNl80211Manager.SignalPollResult(-42, 65, 54, sFreq); 2725 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 2726 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 2727 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 2728 mCmi.enableRssiPolling(true); 2729 connect(); 2730 mLooper.dispatchAll(); 2731 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 2732 mLooper.dispatchAll(); 2733 WifiInfo wifiInfo = mCmi.getWifiInfo(); 2734 assertEquals(llStats.txmpdu_be, wifiInfo.txSuccess); 2735 assertEquals(llStats.rxmpdu_bk, wifiInfo.rxSuccess); 2736 assertEquals(signalPollResult.currentRssiDbm, wifiInfo.getRssi()); 2737 assertEquals(signalPollResult.txBitrateMbps, wifiInfo.getLinkSpeed()); 2738 assertEquals(signalPollResult.txBitrateMbps, wifiInfo.getTxLinkSpeedMbps()); 2739 assertEquals(signalPollResult.rxBitrateMbps, wifiInfo.getRxLinkSpeedMbps()); 2740 assertEquals(sFreq, wifiInfo.getFrequency()); 2741 verify(mWifiDataStall, atLeastOnce()).getTxThroughputKbps(); 2742 verify(mWifiDataStall, atLeastOnce()).getRxThroughputKbps(); 2743 verify(mWifiScoreCard).noteSignalPoll(any()); 2744 } 2745 2746 /** 2747 * Verify RSSI polling with verbose logging 2748 */ 2749 @Test verifyConnectedModeRssiPollingWithVerboseLogging()2750 public void verifyConnectedModeRssiPollingWithVerboseLogging() throws Exception { 2751 mCmi.enableVerboseLogging(1); 2752 verifyConnectedModeRssiPolling(); 2753 } 2754 2755 /** 2756 * Verify that calls to start and stop filtering multicast packets are passed on to the IpClient 2757 * instance. 2758 */ 2759 @Test verifyMcastLockManagerFilterControllerCallsUpdateIpClient()2760 public void verifyMcastLockManagerFilterControllerCallsUpdateIpClient() throws Exception { 2761 loadComponentsInStaMode(); 2762 reset(mIpClient); 2763 WifiMulticastLockManager.FilterController filterController = 2764 mCmi.getMcastLockManagerFilterController(); 2765 filterController.startFilteringMulticastPackets(); 2766 verify(mIpClient).setMulticastFilter(eq(true)); 2767 filterController.stopFilteringMulticastPackets(); 2768 verify(mIpClient).setMulticastFilter(eq(false)); 2769 } 2770 2771 /** 2772 * Verifies that when 2773 * 1. Global feature support flag is set to false 2774 * 2. connected MAC randomization is on and 2775 * 3. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_PERSISTENT and 2776 * 4. randomized MAC for the network to connect to is different from the current MAC. 2777 * 2778 * The factory MAC address is used for the connection, and no attempt is made to change it. 2779 */ 2780 @Test testConnectedMacRandomizationNotSupported()2781 public void testConnectedMacRandomizationNotSupported() throws Exception { 2782 mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, false); 2783 initializeCmi(); 2784 initializeAndAddNetworkAndVerifySuccess(); 2785 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2786 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2787 2788 connect(); 2789 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2790 verify(mWifiNative, never()).setMacAddress(any(), any()); 2791 verify(mWifiNative, never()).getFactoryMacAddress(any()); 2792 } 2793 2794 /** 2795 * Verifies that when 2796 * 1. connected MAC randomization is on and 2797 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_PERSISTENT and 2798 * 3. randomized MAC for the network to connect to is different from the current MAC. 2799 * 2800 * Then the current MAC gets set to the randomized MAC when CMD_START_CONNECT executes. 2801 */ 2802 @Test testConnectedMacRandomizationRandomizationPersistentDifferentMac()2803 public void testConnectedMacRandomizationRandomizationPersistentDifferentMac() 2804 throws Exception { 2805 initializeAndAddNetworkAndVerifySuccess(); 2806 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2807 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2808 2809 connect(); 2810 verify(mWifiNative).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 2811 verify(mWifiMetrics) 2812 .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 2813 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2814 } 2815 2816 /** 2817 * Verifies that when 2818 * 1. connected MAC randomization is on and 2819 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_PERSISTENT and 2820 * 3. randomized MAC for the network to connect to is same as the current MAC. 2821 * 2822 * Then MAC change should not occur when CMD_START_CONNECT executes. 2823 */ 2824 @Test testConnectedMacRandomizationRandomizationPersistentSameMac()2825 public void testConnectedMacRandomizationRandomizationPersistentSameMac() throws Exception { 2826 initializeAndAddNetworkAndVerifySuccess(); 2827 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2828 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2829 2830 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 2831 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 2832 2833 connect(); 2834 verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 2835 verify(mWifiMetrics, never()) 2836 .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 2837 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2838 } 2839 2840 /** 2841 * Verifies that when 2842 * 1. connected MAC randomization is on and 2843 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 2844 * 3. current MAC address is not the factory MAC. 2845 * 2846 * Then the current MAC gets set to the factory MAC when CMD_START_CONNECT executes. 2847 * @throws Exception 2848 */ 2849 @Test testConnectedMacRandomizationRandomizationNoneDifferentMac()2850 public void testConnectedMacRandomizationRandomizationNoneDifferentMac() throws Exception { 2851 initializeAndAddNetworkAndVerifySuccess(); 2852 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2853 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2854 2855 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 2856 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 2857 2858 WifiConfiguration config = new WifiConfiguration(); 2859 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 2860 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 2861 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 2862 2863 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2864 mLooper.dispatchAll(); 2865 2866 verify(mWifiNative).setMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); 2867 verify(mWifiMetrics) 2868 .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 2869 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2870 } 2871 2872 /** 2873 * Verifies that when 2874 * 1. connected MAC randomization is on and 2875 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 2876 * 2877 * Then the factory MAC should be used to connect to the network. 2878 * @throws Exception 2879 */ 2880 @Test testConnectedMacRandomizationRandomizationNoneSameMac()2881 public void testConnectedMacRandomizationRandomizationNoneSameMac() throws Exception { 2882 initializeAndAddNetworkAndVerifySuccess(); 2883 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2884 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2885 2886 WifiConfiguration config = new WifiConfiguration(); 2887 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 2888 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 2889 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 2890 2891 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2892 mLooper.dispatchAll(); 2893 2894 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2895 } 2896 2897 /** 2898 * Verifies that WifiInfo returns DEFAULT_MAC_ADDRESS as mac address when Connected MAC 2899 * Randomization is on and the device is not connected to a wifi network. 2900 */ 2901 @Test testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization()2902 public void testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization() throws Exception { 2903 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 2904 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 2905 2906 connect(); 2907 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 2908 2909 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, sBSSID); 2910 mLooper.dispatchAll(); 2911 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2912 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 2913 mLooper.dispatchAll(); 2914 2915 assertEquals("DisconnectedState", getCurrentState().getName()); 2916 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mCmi.getWifiInfo().getMacAddress()); 2917 assertFalse(mCmi.getWifiInfo().hasRealMacAddress()); 2918 } 2919 2920 /** 2921 * Verifies that we don't set MAC address when config returns an invalid MAC address. 2922 */ 2923 @Test testDoNotSetMacWhenInvalid()2924 public void testDoNotSetMacWhenInvalid() throws Exception { 2925 initializeAndAddNetworkAndVerifySuccess(); 2926 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2927 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2928 2929 WifiConfiguration config = new WifiConfiguration(); 2930 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 2931 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 2932 config.setRandomizedMacAddress(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS)); 2933 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 2934 2935 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 2936 mLooper.dispatchAll(); 2937 2938 // setMacAddress is invoked once when ClientModeImpl starts to prevent leak of factory MAC. 2939 verify(mWifiNative).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class)); 2940 } 2941 2942 /** 2943 * Verify that we don't crash when WifiNative returns null as the current MAC address. 2944 * @throws Exception 2945 */ 2946 @Test testMacRandomizationWifiNativeReturningNull()2947 public void testMacRandomizationWifiNativeReturningNull() throws Exception { 2948 when(mWifiNative.getMacAddress(anyString())).thenReturn(null); 2949 initializeAndAddNetworkAndVerifySuccess(); 2950 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 2951 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 2952 2953 connect(); 2954 verify(mWifiNative).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 2955 } 2956 2957 /** 2958 * Verifies that a notification is posted when a connection failure happens on a network 2959 * in the hotlist. Then verify that tapping on the notification launches an dialog, which 2960 * could be used to set the randomization setting for a network to "Trusted". 2961 */ 2962 @Test testConnectionFailureSendRandomizationSettingsNotification()2963 public void testConnectionFailureSendRandomizationSettingsNotification() throws Exception { 2964 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 2965 // Setup CONNECT_MODE & a WifiConfiguration 2966 initializeAndAddNetworkAndVerifySuccess(); 2967 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, sBSSID); 2968 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2969 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT); 2970 mLooper.dispatchAll(); 2971 2972 WifiConfiguration config = mCmi.getCurrentWifiConfiguration(); 2973 verify(mConnectionFailureNotifier) 2974 .showFailedToConnectDueToNoRandomizedMacSupportNotification(FRAMEWORK_NETWORK_ID); 2975 } 2976 2977 /** 2978 * Verifies that a notification is not posted when a wrong password failure happens on a 2979 * network in the hotlist. 2980 */ 2981 @Test testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword()2982 public void testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword() throws Exception { 2983 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 2984 // Setup CONNECT_MODE & a WifiConfiguration 2985 initializeAndAddNetworkAndVerifySuccess(); 2986 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, sBSSID); 2987 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2988 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 2989 mLooper.dispatchAll(); 2990 2991 verify(mConnectionFailureNotifier, never()) 2992 .showFailedToConnectDueToNoRandomizedMacSupportNotification(anyInt()); 2993 } 2994 2995 /** 2996 * Verifies that CMD_START_CONNECT make WifiDiagnostics report 2997 * CONNECTION_EVENT_STARTED 2998 * @throws Exception 2999 */ 3000 @Test testReportConnectionEventIsCalledAfterCmdStartConnect()3001 public void testReportConnectionEventIsCalledAfterCmdStartConnect() throws Exception { 3002 // Setup CONNECT_MODE & a WifiConfiguration 3003 initializeAndAddNetworkAndVerifySuccess(); 3004 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3005 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3006 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED)); 3007 mLooper.dispatchAll(); 3008 verify(mWifiDiagnostics).reportConnectionEvent( 3009 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED)); 3010 } 3011 3012 /** 3013 * Verifies that CMD_DIAG_CONNECT_TIMEOUT is processed after the timeout threshold if we 3014 * start a connection but do not finish it. 3015 * @throws Exception 3016 */ 3017 @Test testCmdDiagsConnectTimeoutIsGeneratedAfterCmdStartConnect()3018 public void testCmdDiagsConnectTimeoutIsGeneratedAfterCmdStartConnect() throws Exception { 3019 // Setup CONNECT_MODE & a WifiConfiguration 3020 initializeAndAddNetworkAndVerifySuccess(); 3021 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3022 mLooper.dispatchAll(); 3023 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS); 3024 mLooper.dispatchAll(); 3025 verify(mWifiDiagnostics).reportConnectionEvent( 3026 eq(BaseWifiDiagnostics.CONNECTION_EVENT_TIMEOUT)); 3027 } 3028 3029 /** 3030 * Verifies that CMD_DIAG_CONNECT_TIMEOUT does not get processed before the timeout threshold. 3031 * @throws Exception 3032 */ 3033 @Test testCmdDiagsConnectTimeoutIsNotProcessedBeforeTimerExpires()3034 public void testCmdDiagsConnectTimeoutIsNotProcessedBeforeTimerExpires() throws Exception { 3035 // Setup CONNECT_MODE & a WifiConfiguration 3036 initializeAndAddNetworkAndVerifySuccess(); 3037 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3038 mLooper.dispatchAll(); 3039 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS - 1000); 3040 mLooper.dispatchAll(); 3041 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3042 eq(BaseWifiDiagnostics.CONNECTION_EVENT_TIMEOUT)); 3043 } 3044 verifyConnectionEventTimeoutDoesNotOccur()3045 private void verifyConnectionEventTimeoutDoesNotOccur() { 3046 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS); 3047 mLooper.dispatchAll(); 3048 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3049 eq(BaseWifiDiagnostics.CONNECTION_EVENT_TIMEOUT)); 3050 } 3051 3052 /** 3053 * Verifies that association failures make WifiDiagnostics report CONNECTION_EVENT_FAILED 3054 * and then cancel any pending timeouts. 3055 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3056 * @throws Exception 3057 */ 3058 @Test testReportConnectionEventIsCalledAfterAssociationFailure()3059 public void testReportConnectionEventIsCalledAfterAssociationFailure() throws Exception { 3060 mConnectedNetwork.getNetworkSelectionStatus() 3061 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 3062 // Setup CONNECT_MODE & a WifiConfiguration 3063 initializeAndAddNetworkAndVerifySuccess(); 3064 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3065 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 3066 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, sBSSID); 3067 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3068 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED)); 3069 mLooper.dispatchAll(); 3070 verify(mWifiDiagnostics).reportConnectionEvent( 3071 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED)); 3072 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3073 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION, sBSSID, sSSID); 3074 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3075 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 3076 any(WifiConfiguration.class)); 3077 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3078 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 3079 any(WifiConfiguration.class), eq(null)); 3080 verify(mWifiMetrics, never()) 3081 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3082 verifyConnectionEventTimeoutDoesNotOccur(); 3083 } 3084 3085 /** 3086 * Verifies that authentication failures make WifiDiagnostics report 3087 * CONNECTION_EVENT_FAILED and then cancel any pending timeouts. 3088 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3089 * @throws Exception 3090 */ 3091 @Test testReportConnectionEventIsCalledAfterAuthenticationFailure()3092 public void testReportConnectionEventIsCalledAfterAuthenticationFailure() throws Exception { 3093 mConnectedNetwork.getNetworkSelectionStatus() 3094 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 3095 // Setup CONNECT_MODE & a WifiConfiguration 3096 initializeAndAddNetworkAndVerifySuccess(); 3097 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3098 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3099 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 3100 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3101 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED)); 3102 mLooper.dispatchAll(); 3103 verify(mWifiDiagnostics).reportConnectionEvent( 3104 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED)); 3105 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3106 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, sBSSID, sSSID); 3107 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3108 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 3109 any(WifiConfiguration.class)); 3110 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3111 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 3112 any(WifiConfiguration.class), eq(null)); 3113 verify(mWifiMetrics, never()) 3114 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3115 verifyConnectionEventTimeoutDoesNotOccur(); 3116 } 3117 3118 /** 3119 * Verify that if a NETWORK_DISCONNECTION_EVENT is received in ConnectedState, then an 3120 * abnormal disconnect is reported to BssidBlocklistMonitor. 3121 */ 3122 @Test testAbnormalDisconnectNotifiesBssidBlocklistMonitor()3123 public void testAbnormalDisconnectNotifiesBssidBlocklistMonitor() throws Exception { 3124 // trigger RSSI poll to update WifiInfo 3125 mCmi.enableRssiPolling(true); 3126 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 3127 llStats.txmpdu_be = 1000; 3128 llStats.rxmpdu_bk = 2000; 3129 WifiNl80211Manager.SignalPollResult signalPollResult = 3130 new WifiNl80211Manager.SignalPollResult(TEST_RSSI, 65, 54, sFreq); 3131 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 3132 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 3133 3134 connect(); 3135 mLooper.dispatchAll(); 3136 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 3137 mLooper.dispatchAll(); 3138 3139 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3140 BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT, false); 3141 } 3142 3143 /** 3144 * Verify that ClientModeImpl notifies BssidBlocklistMonitor correctly when the RSSI is 3145 * too low. 3146 */ 3147 @Test testNotifiesBssidBlocklistMonitorLowRssi()3148 public void testNotifiesBssidBlocklistMonitorLowRssi() throws Exception { 3149 initializeAndAddNetworkAndVerifySuccess(); 3150 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, 3151 ClientModeImpl.SUPPLICANT_BSSID_ANY); 3152 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 1, 0, sBSSID); 3153 when(mWifiConfigManager.findScanRssi(eq(FRAMEWORK_NETWORK_ID), anyInt())).thenReturn(-80); 3154 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3155 .thenReturn(mScanDetailCache); 3156 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 3157 getGoogleGuestScanDetail(-80, sBSSID, sFreq)); 3158 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 3159 getGoogleGuestScanDetail(-80, sBSSID, sFreq).getScanResult()); 3160 mLooper.dispatchAll(); 3161 3162 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3163 BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, true); 3164 } 3165 3166 /** 3167 * Verifies that the BssidBlocklistMonitor is notified, but the WifiLastResortWatchdog is 3168 * not notified of association rejections of type REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA. 3169 * @throws Exception 3170 */ 3171 @Test testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog()3172 public void testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog() 3173 throws Exception { 3174 initializeAndAddNetworkAndVerifySuccess(); 3175 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3176 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 3177 ClientModeImpl.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA, sBSSID); 3178 mLooper.dispatchAll(); 3179 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3180 anyString(), anyString(), anyInt()); 3181 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3182 BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA, false); 3183 } 3184 3185 /** 3186 * Verifies that WifiLastResortWatchdog and BssidBlocklistMonitor is notified of 3187 * general association rejection failures. 3188 * @throws Exception 3189 */ 3190 @Test testAssociationRejectionUpdatesWatchdog()3191 public void testAssociationRejectionUpdatesWatchdog() throws Exception { 3192 initializeAndAddNetworkAndVerifySuccess(); 3193 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 3194 config.carrierId = CARRIER_ID_1; 3195 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3196 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 0, sBSSID); 3197 mLooper.dispatchAll(); 3198 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 3199 anyString(), anyString(), anyInt()); 3200 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3201 BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION, false); 3202 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionNonAuthFailure(); 3203 } 3204 3205 /** 3206 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 3207 * ERROR_AUTH_FAILURE_WRONG_PSWD. 3208 * @throws Exception 3209 */ 3210 @Test testFailureWrongPassIsIgnoredByWatchdog()3211 public void testFailureWrongPassIsIgnoredByWatchdog() throws Exception { 3212 // Setup CONNECT_MODE & a WifiConfiguration 3213 initializeAndAddNetworkAndVerifySuccess(); 3214 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3215 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3216 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 3217 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3218 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 3219 mLooper.dispatchAll(); 3220 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3221 anyString(), anyString(), anyInt()); 3222 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3223 BssidBlocklistMonitor.REASON_WRONG_PASSWORD, false); 3224 } 3225 3226 /** 3227 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 3228 * ERROR_AUTH_FAILURE_EAP_FAILURE. 3229 * @throws Exception 3230 */ 3231 @Test testEapFailureIsIgnoredByWatchdog()3232 public void testEapFailureIsIgnoredByWatchdog() throws Exception { 3233 // Setup CONNECT_MODE & a WifiConfiguration 3234 initializeAndAddNetworkAndVerifySuccess(); 3235 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3236 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3237 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 3238 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3239 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE); 3240 mLooper.dispatchAll(); 3241 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3242 anyString(), anyString(), anyInt()); 3243 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3244 BssidBlocklistMonitor.REASON_EAP_FAILURE, false); 3245 } 3246 3247 /** 3248 * Verifies that WifiLastResortWatchdog is notified of other types of authentication failures. 3249 * @throws Exception 3250 */ 3251 @Test testAuthenticationFailureUpdatesWatchdog()3252 public void testAuthenticationFailureUpdatesWatchdog() throws Exception { 3253 // Setup CONNECT_MODE & a WifiConfiguration 3254 initializeAndAddNetworkAndVerifySuccess(); 3255 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3256 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3257 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 3258 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3259 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT); 3260 mLooper.dispatchAll(); 3261 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 3262 anyString(), anyString(), anyInt()); 3263 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3264 BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE, false); 3265 } 3266 3267 /** 3268 * Verify that BssidBlocklistMonitor is notified of the SSID pre-connection so that it could 3269 * send down to firmware the list of blocked BSSIDs. 3270 */ 3271 @Test testBssidBlocklistSentToFirmwareAfterCmdStartConnect()3272 public void testBssidBlocklistSentToFirmwareAfterCmdStartConnect() throws Exception { 3273 initializeAndAddNetworkAndVerifySuccess(); 3274 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3275 verify(mBssidBlocklistMonitor, never()).updateFirmwareRoamingConfiguration(sSSID); 3276 mLooper.dispatchAll(); 3277 verify(mBssidBlocklistMonitor).updateFirmwareRoamingConfiguration(sSSID); 3278 // But don't expect to see connection success yet 3279 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 3280 // And certainly not validation success 3281 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 3282 } 3283 3284 /** 3285 * Verifies that dhcp failures make WifiDiagnostics report CONNECTION_EVENT_FAILED and then 3286 * cancel any pending timeouts. 3287 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3288 * @throws Exception 3289 */ 3290 @Test testReportConnectionEventIsCalledAfterDhcpFailure()3291 public void testReportConnectionEventIsCalledAfterDhcpFailure() throws Exception { 3292 mConnectedNetwork.getNetworkSelectionStatus() 3293 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 3294 testDhcpFailure(); 3295 verify(mWifiDiagnostics, atLeastOnce()).reportConnectionEvent( 3296 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED)); 3297 verify(mWifiConnectivityManager, atLeastOnce()).handleConnectionAttemptEnded( 3298 WifiMetrics.ConnectionEvent.FAILURE_DHCP, sBSSID, sSSID); 3299 verify(mWifiNetworkFactory, atLeastOnce()).handleConnectionAttemptEnded( 3300 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class)); 3301 verify(mWifiNetworkSuggestionsManager, atLeastOnce()).handleConnectionAttemptEnded( 3302 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class), 3303 any(String.class)); 3304 verify(mWifiMetrics, never()) 3305 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3306 verifyConnectionEventTimeoutDoesNotOccur(); 3307 } 3308 3309 /** 3310 * Verifies that a successful validation make WifiDiagnostics report CONNECTION_EVENT_SUCCEEDED 3311 * and then cancel any pending timeouts. 3312 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3313 * @throws Exception 3314 */ 3315 @Test testReportConnectionEventIsCalledAfterSuccessfulConnection()3316 public void testReportConnectionEventIsCalledAfterSuccessfulConnection() throws Exception { 3317 mConnectedNetwork.getNetworkSelectionStatus() 3318 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq).getScanResult()); 3319 connect(); 3320 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 3321 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 3322 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 3323 anyInt(), any(NetworkAgentConfig.class), anyInt()); 3324 3325 Message message = new Message(); 3326 message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; 3327 message.arg1 = NetworkAgent.VALID_NETWORK; 3328 message.obj = new Bundle(); 3329 messengerCaptor.getValue().send(message); 3330 mLooper.dispatchAll(); 3331 3332 verify(mWifiDiagnostics).reportConnectionEvent( 3333 eq(WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED)); 3334 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3335 WifiMetrics.ConnectionEvent.FAILURE_NONE, sBSSID, sSSID); 3336 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3337 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), any(WifiConfiguration.class)); 3338 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3339 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), any(WifiConfiguration.class), 3340 any(String.class)); 3341 // BSSID different, record this connection. 3342 verify(mWifiMetrics).incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3343 verifyConnectionEventTimeoutDoesNotOccur(); 3344 } 3345 3346 /** 3347 * Verify that score card is notified of a connection attempt 3348 */ 3349 @Test testScoreCardNoteConnectionAttemptAfterCmdStartConnect()3350 public void testScoreCardNoteConnectionAttemptAfterCmdStartConnect() throws Exception { 3351 initializeAndAddNetworkAndVerifySuccess(); 3352 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 3353 verify(mWifiScoreCard, never()).noteConnectionAttempt(any(), anyInt(), anyString()); 3354 mLooper.dispatchAll(); 3355 verify(mWifiScoreCard).noteConnectionAttempt(any(), anyInt(), anyString()); 3356 verify(mWifiConfigManager).findScanRssi(anyInt(), anyInt()); 3357 // But don't expect to see connection success yet 3358 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 3359 // And certainly not validation success 3360 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 3361 3362 } 3363 3364 /** 3365 * Verify that score card is notified of a successful connection 3366 */ 3367 @Test testScoreCardNoteConnectionComplete()3368 public void testScoreCardNoteConnectionComplete() throws Exception { 3369 Pair<String, String> l2KeyAndCluster = Pair.create("Wad", "Gab"); 3370 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(l2KeyAndCluster); 3371 connect(); 3372 mLooper.dispatchAll(); 3373 verify(mWifiScoreCard).noteIpConfiguration(any()); 3374 ArgumentCaptor<Layer2InformationParcelable> captor = 3375 ArgumentCaptor.forClass(Layer2InformationParcelable.class); 3376 verify(mIpClient, atLeastOnce()).updateLayer2Information(captor.capture()); 3377 final Layer2InformationParcelable info = captor.getValue(); 3378 assertEquals(info.l2Key, "Wad"); 3379 assertEquals(info.cluster, "Gab"); 3380 } 3381 3382 /** 3383 * Verify that score card/health monitor are notified when wifi is disabled while disconnected 3384 */ 3385 @Test testScoreCardNoteWifiDisabledWhileDisconnected()3386 public void testScoreCardNoteWifiDisabledWhileDisconnected() throws Exception { 3387 // connecting and disconnecting shouldn't note wifi disabled 3388 disconnect(); 3389 mLooper.dispatchAll(); 3390 3391 verify(mWifiScoreCard, times(1)).resetConnectionState(); 3392 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 3393 verify(mWifiHealthMonitor, never()).setWifiEnabled(false); 3394 3395 // disabling while disconnected should note wifi disabled 3396 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_DISABLED); 3397 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3398 mLooper.dispatchAll(); 3399 verify(mWifiScoreCard, times(2)).resetConnectionState(); 3400 verify(mWifiHealthMonitor).setWifiEnabled(false); 3401 } 3402 3403 /** 3404 * Verify that score card/health monitor are notified when wifi is disabled while connected 3405 */ 3406 @Test testScoreCardNoteWifiDisabledWhileConnected()3407 public void testScoreCardNoteWifiDisabledWhileConnected() throws Exception { 3408 // Get into connected state 3409 connect(); 3410 mLooper.dispatchAll(); 3411 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 3412 verify(mWifiHealthMonitor, never()).setWifiEnabled(false); 3413 3414 // disabling while connected should note wifi disabled 3415 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_DISABLED); 3416 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3417 mLooper.dispatchAll(); 3418 3419 verify(mWifiScoreCard).noteWifiDisabled(any()); 3420 verify(mWifiScoreCard).resetConnectionState(); 3421 verify(mWifiHealthMonitor).setWifiEnabled(false); 3422 } 3423 3424 /** 3425 * Verify that we do not crash on quick toggling wifi on/off 3426 */ 3427 @Test quickTogglesDoNotCrash()3428 public void quickTogglesDoNotCrash() throws Exception { 3429 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3430 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3431 mLooper.dispatchAll(); 3432 3433 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3434 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3435 mLooper.dispatchAll(); 3436 3437 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3438 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3439 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3440 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3441 mLooper.dispatchAll(); 3442 3443 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3444 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3445 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3446 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3447 mLooper.dispatchAll(); 3448 } 3449 3450 /** 3451 * Verify that valid calls to set the current wifi state are returned when requested. 3452 */ 3453 @Test verifySetAndGetWifiStateCallsWorking()3454 public void verifySetAndGetWifiStateCallsWorking() throws Exception { 3455 // we start off disabled 3456 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 3457 3458 // now check after updating 3459 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_UNKNOWN); 3460 assertEquals(WifiManager.WIFI_STATE_UNKNOWN, mCmi.syncGetWifiState()); 3461 3462 // check after two updates 3463 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_ENABLING); 3464 mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_ENABLED); 3465 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 3466 } 3467 3468 /** 3469 * Verify that invalid states do not change the saved wifi state. 3470 */ 3471 @Test verifyInvalidStatesDoNotChangeSavedWifiState()3472 public void verifyInvalidStatesDoNotChangeSavedWifiState() throws Exception { 3473 int invalidStateNegative = -1; 3474 int invalidStatePositive = 5; 3475 3476 // we start off disabled 3477 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 3478 3479 mCmi.setWifiStateForApiCalls(invalidStateNegative); 3480 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 3481 3482 mCmi.setWifiStateForApiCalls(invalidStatePositive); 3483 assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); 3484 } 3485 3486 /** 3487 * Verify that IPClient instance is shutdown when wifi is disabled. 3488 */ 3489 @Test verifyIpClientShutdownWhenDisabled()3490 public void verifyIpClientShutdownWhenDisabled() throws Exception { 3491 loadComponentsInStaMode(); 3492 3493 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3494 mLooper.dispatchAll(); 3495 verify(mIpClient).shutdown(); 3496 verify(mWifiConfigManager).removeAllEphemeralOrPasspointConfiguredNetworks(); 3497 verify(mWifiConfigManager).clearUserTemporarilyDisabledList(); 3498 } 3499 3500 /** 3501 * Verify that WifiInfo's MAC address is updated when the state machine receives 3502 * NETWORK_CONNECTION_EVENT while in ConnectedState. 3503 */ 3504 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected()3505 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected() throws Exception { 3506 connect(); 3507 assertEquals("ConnectedState", getCurrentState().getName()); 3508 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 3509 3510 // Verify receiving a NETWORK_CONNECTION_EVENT changes the MAC in WifiInfo 3511 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3512 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 3513 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 3514 mLooper.dispatchAll(); 3515 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 3516 } 3517 3518 /** 3519 * Verify that WifiInfo's MAC address is updated when the state machine receives 3520 * NETWORK_CONNECTION_EVENT while in DisconnectedState. 3521 */ 3522 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected()3523 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected() throws Exception { 3524 disconnect(); 3525 assertEquals("DisconnectedState", getCurrentState().getName()); 3526 // Since MAC randomization is enabled, wifiInfo's MAC should be set to default MAC 3527 // when disconnect happens. 3528 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mCmi.getWifiInfo().getMacAddress()); 3529 3530 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3531 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 3532 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 3533 mLooper.dispatchAll(); 3534 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); 3535 } 3536 3537 /** 3538 * Verify that we temporarily disable the network when auto-connected to a network 3539 * with no internet access. 3540 */ 3541 @Test verifyAutoConnectedNetworkWithInternetValidationFailure()3542 public void verifyAutoConnectedNetworkWithInternetValidationFailure() throws Exception { 3543 // Setup RSSI poll to update WifiInfo with low RSSI 3544 mCmi.enableRssiPolling(true); 3545 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 3546 llStats.txmpdu_be = 1000; 3547 llStats.rxmpdu_bk = 2000; 3548 WifiNl80211Manager.SignalPollResult signalPollResult = 3549 new WifiNl80211Manager.SignalPollResult(RSSI_THRESHOLD_BREACH_MIN, 65, 54, sFreq); 3550 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 3551 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 3552 3553 // Simulate the first connection. 3554 connect(); 3555 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 3556 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 3557 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 3558 anyInt(), any(NetworkAgentConfig.class), anyInt()); 3559 3560 WifiConfiguration currentNetwork = new WifiConfiguration(); 3561 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 3562 currentNetwork.SSID = DEFAULT_TEST_SSID; 3563 currentNetwork.noInternetAccessExpected = false; 3564 currentNetwork.numNoInternetAccessReports = 1; 3565 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 3566 .thenReturn(currentNetwork); 3567 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 3568 3569 Message message = new Message(); 3570 message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; 3571 message.arg1 = NetworkAgent.INVALID_NETWORK; 3572 message.obj = new Bundle(); 3573 messengerCaptor.getValue().send(message); 3574 mLooper.dispatchAll(); 3575 3576 verify(mWifiConfigManager) 3577 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 3578 verify(mWifiConfigManager).updateNetworkSelectionStatus( 3579 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 3580 verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID, 3581 BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, true); 3582 verify(mWifiScoreCard).noteValidationFailure(any()); 3583 } 3584 3585 /** 3586 * Verify that we don't temporarily disable the network when user selected to connect to a 3587 * network with no internet access. 3588 */ 3589 @Test verifyLastSelectedNetworkWithInternetValidationFailure()3590 public void verifyLastSelectedNetworkWithInternetValidationFailure() throws Exception { 3591 // Simulate the first connection. 3592 connect(); 3593 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 3594 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 3595 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 3596 anyInt(), any(NetworkAgentConfig.class), anyInt()); 3597 3598 WifiConfiguration currentNetwork = new WifiConfiguration(); 3599 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 3600 currentNetwork.noInternetAccessExpected = false; 3601 currentNetwork.numNoInternetAccessReports = 1; 3602 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 3603 .thenReturn(currentNetwork); 3604 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); 3605 3606 Message message = new Message(); 3607 message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; 3608 message.arg1 = NetworkAgent.INVALID_NETWORK; 3609 message.obj = new Bundle(); 3610 messengerCaptor.getValue().send(message); 3611 mLooper.dispatchAll(); 3612 3613 verify(mWifiConfigManager) 3614 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 3615 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 3616 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 3617 } 3618 3619 /** 3620 * Verify that we temporarily disable the network when auto-connected to a network 3621 * with no internet access. 3622 */ 3623 @Test verifyAutoConnectedNoInternetExpectedNetworkWithInternetValidationFailure()3624 public void verifyAutoConnectedNoInternetExpectedNetworkWithInternetValidationFailure() 3625 throws Exception { 3626 // Simulate the first connection. 3627 connect(); 3628 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 3629 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 3630 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 3631 anyInt(), any(NetworkAgentConfig.class), anyInt()); 3632 3633 WifiConfiguration currentNetwork = new WifiConfiguration(); 3634 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 3635 currentNetwork.noInternetAccessExpected = true; 3636 currentNetwork.numNoInternetAccessReports = 1; 3637 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 3638 .thenReturn(currentNetwork); 3639 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 3640 3641 Message message = new Message(); 3642 message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; 3643 message.arg1 = NetworkAgent.INVALID_NETWORK; 3644 message.obj = new Bundle(); 3645 messengerCaptor.getValue().send(message); 3646 mLooper.dispatchAll(); 3647 3648 verify(mWifiConfigManager) 3649 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 3650 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 3651 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 3652 } 3653 3654 /** 3655 * Verify that we enable the network when we detect validated internet access. 3656 */ 3657 @Test verifyNetworkSelectionEnableOnInternetValidation()3658 public void verifyNetworkSelectionEnableOnInternetValidation() throws Exception { 3659 // Simulate the first connection. 3660 connect(); 3661 verify(mBssidBlocklistMonitor).handleBssidConnectionSuccess(sBSSID, sSSID); 3662 verify(mBssidBlocklistMonitor).handleDhcpProvisioningSuccess(sBSSID, sSSID); 3663 verify(mBssidBlocklistMonitor, never()).handleNetworkValidationSuccess(sBSSID, sSSID); 3664 3665 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 3666 verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(), 3667 any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class), 3668 anyInt(), any(NetworkAgentConfig.class), anyInt()); 3669 3670 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 3671 3672 Message message = new Message(); 3673 message.what = NetworkAgent.CMD_REPORT_NETWORK_STATUS; 3674 message.arg1 = NetworkAgent.VALID_NETWORK; 3675 message.obj = new Bundle(); 3676 messengerCaptor.getValue().send(message); 3677 mLooper.dispatchAll(); 3678 3679 verify(mWifiConfigManager) 3680 .setNetworkValidatedInternetAccess(FRAMEWORK_NETWORK_ID, true); 3681 verify(mWifiConfigManager).updateNetworkSelectionStatus( 3682 FRAMEWORK_NETWORK_ID, DISABLED_NONE); 3683 verify(mWifiScoreCard).noteValidationSuccess(any()); 3684 verify(mBssidBlocklistMonitor).handleNetworkValidationSuccess(sBSSID, sSSID); 3685 } 3686 connectWithValidInitRssi(int initRssiDbm)3687 private void connectWithValidInitRssi(int initRssiDbm) throws Exception { 3688 triggerConnect(); 3689 mCmi.getWifiInfo().setRssi(initRssiDbm); 3690 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3691 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); 3692 mLooper.dispatchAll(); 3693 3694 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 3695 mLooper.dispatchAll(); 3696 3697 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3698 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 3699 mLooper.dispatchAll(); 3700 3701 assertEquals("ObtainingIpState", getCurrentState().getName()); 3702 } 3703 3704 /** 3705 * Verify that we set the INTERNET and bandwidth capability in the network agent when connected 3706 * as a result of auto-join/legacy API's. Also verify up/down stream bandwidth values when 3707 * Rx link speed is unavailable. 3708 */ 3709 @Test verifyNetworkCapabilities()3710 public void verifyNetworkCapabilities() throws Exception { 3711 when(mWifiDataStall.getTxThroughputKbps()).thenReturn(70_000); 3712 when(mWifiDataStall.getRxThroughputKbps()).thenReturn(-1); 3713 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any())) 3714 .thenReturn(Pair.create(Process.INVALID_UID, "")); 3715 // Simulate the first connection. 3716 connectWithValidInitRssi(-42); 3717 3718 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 3719 ArgumentCaptor.forClass(NetworkCapabilities.class); 3720 verify(mConnectivityManager).registerNetworkAgent(any(Messenger.class), 3721 any(NetworkInfo.class), any(LinkProperties.class), 3722 networkCapabilitiesCaptor.capture(), anyInt(), any(NetworkAgentConfig.class), 3723 anyInt()); 3724 3725 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 3726 assertNotNull(networkCapabilities); 3727 3728 // Should have internet capability. 3729 assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 3730 assertNull(networkCapabilities.getNetworkSpecifier()); 3731 3732 assertEquals(mConnectedNetwork.creatorUid, networkCapabilities.getOwnerUid()); 3733 assertArrayEquals( 3734 new int[] {mConnectedNetwork.creatorUid}, 3735 networkCapabilities.getAdministratorUids()); 3736 3737 // Should set bandwidth correctly 3738 assertEquals(-42, mCmi.getWifiInfo().getRssi()); 3739 assertEquals(70_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 3740 assertEquals(70_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 3741 } 3742 3743 /** 3744 * Verify that we don't set the INTERNET capability in the network agent when connected 3745 * as a result of the new network request API. Also verify up/down stream bandwidth values 3746 * when both Tx and Rx link speed are unavailable. 3747 */ 3748 @Test verifyNetworkCapabilitiesForSpecificRequest()3749 public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception { 3750 when(mWifiDataStall.getTxThroughputKbps()).thenReturn(-1); 3751 when(mWifiDataStall.getRxThroughputKbps()).thenReturn(-1); 3752 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any())) 3753 .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME)); 3754 // Simulate the first connection. 3755 connectWithValidInitRssi(-42); 3756 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 3757 ArgumentCaptor.forClass(NetworkCapabilities.class); 3758 verify(mConnectivityManager).registerNetworkAgent(any(Messenger.class), 3759 any(NetworkInfo.class), any(LinkProperties.class), 3760 networkCapabilitiesCaptor.capture(), anyInt(), any(NetworkAgentConfig.class), 3761 anyInt()); 3762 3763 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 3764 assertNotNull(networkCapabilities); 3765 3766 // should not have internet capability. 3767 assertFalse(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 3768 3769 NetworkSpecifier networkSpecifier = networkCapabilities.getNetworkSpecifier(); 3770 assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier); 3771 WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = 3772 (WifiNetworkAgentSpecifier) networkSpecifier; 3773 WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier = 3774 new WifiNetworkAgentSpecifier(mCmi.getCurrentWifiConfiguration()); 3775 assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier); 3776 assertEquals(TEST_UID, networkCapabilities.getRequestorUid()); 3777 assertEquals(OP_PACKAGE_NAME, networkCapabilities.getRequestorPackageName()); 3778 assertEquals(90_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 3779 assertEquals(80_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 3780 } 3781 3782 /** 3783 * Verify that we check for data stall during rssi poll 3784 * and then check that wifi link layer usage data are being updated. 3785 */ 3786 @Test verifyRssiPollChecksDataStall()3787 public void verifyRssiPollChecksDataStall() throws Exception { 3788 mCmi.enableRssiPolling(true); 3789 connect(); 3790 3791 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 3792 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 3793 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 3794 mLooper.dispatchAll(); 3795 WifiLinkLayerStats newLLStats = new WifiLinkLayerStats(); 3796 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(newLLStats); 3797 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 3798 mLooper.dispatchAll(); 3799 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency( 3800 oldLLStats, newLLStats, mCmi.getWifiInfo()); 3801 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(newLLStats); 3802 } 3803 3804 /** 3805 * Verify that we update wifi usability stats entries during rssi poll and that when we get 3806 * a data stall we label and save the current list of usability stats entries. 3807 * @throws Exception 3808 */ 3809 @Test verifyRssiPollUpdatesWifiUsabilityMetrics()3810 public void verifyRssiPollUpdatesWifiUsabilityMetrics() throws Exception { 3811 mCmi.enableRssiPolling(true); 3812 connect(); 3813 3814 WifiLinkLayerStats stats = new WifiLinkLayerStats(); 3815 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(stats); 3816 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), any(), any())) 3817 .thenReturn(WifiIsUnusableEvent.TYPE_UNKNOWN); 3818 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 3819 mLooper.dispatchAll(); 3820 verify(mWifiMetrics).updateWifiUsabilityStatsEntries(any(), eq(stats)); 3821 verify(mWifiMetrics, never()).addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, 3822 eq(anyInt()), eq(-1)); 3823 3824 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), any(), any())) 3825 .thenReturn(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX); 3826 when(mClock.getElapsedSinceBootMillis()).thenReturn(10L); 3827 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 3828 mLooper.dispatchAll(); 3829 verify(mWifiMetrics, times(2)).updateWifiUsabilityStatsEntries(any(), eq(stats)); 3830 when(mClock.getElapsedSinceBootMillis()) 3831 .thenReturn(10L + ClientModeImpl.DURATION_TO_WAIT_ADD_STATS_AFTER_DATA_STALL_MS); 3832 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 3833 mLooper.dispatchAll(); 3834 verify(mWifiMetrics).addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, 3835 WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1); 3836 } 3837 3838 /** 3839 * Verify that when ordered to setPowerSave(true) while Interface is created, 3840 * WifiNative is called with the right powerSave mode. 3841 */ 3842 @Test verifySetPowerSaveTrueSuccess()3843 public void verifySetPowerSaveTrueSuccess() throws Exception { 3844 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3845 assertTrue(mCmi.setPowerSave(true)); 3846 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 3847 } 3848 3849 /** 3850 * Verify that when ordered to setPowerSave(false) while Interface is created, 3851 * WifiNative is called with the right powerSave mode. 3852 */ 3853 @Test verifySetPowerSaveFalseSuccess()3854 public void verifySetPowerSaveFalseSuccess() throws Exception { 3855 mCmi.setOperationalMode(ClientModeImpl.CONNECT_MODE, WIFI_IFACE_NAME); 3856 assertTrue(mCmi.setPowerSave(false)); 3857 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 3858 } 3859 3860 /** 3861 * Verify that when interface is not created yet (InterfaceName is null), 3862 * then setPowerSave() returns with error and no call in WifiNative happens. 3863 */ 3864 @Test verifySetPowerSaveFailure()3865 public void verifySetPowerSaveFailure() throws Exception { 3866 boolean powerSave = true; 3867 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 3868 assertFalse(mCmi.setPowerSave(powerSave)); 3869 verify(mWifiNative, never()).setPowerSave(anyString(), anyBoolean()); 3870 } 3871 3872 /** 3873 * Verify that we call into WifiTrafficPoller during rssi poll 3874 */ 3875 @Test verifyRssiPollCallsWifiTrafficPoller()3876 public void verifyRssiPollCallsWifiTrafficPoller() throws Exception { 3877 mCmi.enableRssiPolling(true); 3878 connect(); 3879 3880 verify(mWifiTrafficPoller).notifyOnDataActivity(anyLong(), anyLong()); 3881 } 3882 3883 /** 3884 * Verify that LinkProbeManager is updated during RSSI poll 3885 */ 3886 @Test verifyRssiPollCallsLinkProbeManager()3887 public void verifyRssiPollCallsLinkProbeManager() throws Exception { 3888 mCmi.enableRssiPolling(true); 3889 3890 connect(); 3891 // reset() should be called when RSSI polling is enabled and entering L2ConnectedState 3892 verify(mLinkProbeManager).resetOnNewConnection(); // called first time here 3893 verify(mLinkProbeManager, never()).resetOnScreenTurnedOn(); // not called 3894 verify(mLinkProbeManager).updateConnectionStats(any(), any()); 3895 3896 mCmi.enableRssiPolling(false); 3897 mLooper.dispatchAll(); 3898 // reset() should be called when in L2ConnectedState (or child states) and RSSI polling 3899 // becomes enabled 3900 mCmi.enableRssiPolling(true); 3901 mLooper.dispatchAll(); 3902 verify(mLinkProbeManager, times(1)).resetOnNewConnection(); // verify not called again 3903 verify(mLinkProbeManager).resetOnScreenTurnedOn(); // verify called here 3904 } 3905 3906 /** 3907 * Verify that when ordered to setLowLatencyMode(true), 3908 * WifiNative is called with the right lowLatency mode. 3909 */ 3910 @Test verifySetLowLatencyTrueSuccess()3911 public void verifySetLowLatencyTrueSuccess() throws Exception { 3912 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 3913 assertTrue(mCmi.setLowLatencyMode(true)); 3914 verify(mWifiNative).setLowLatencyMode(true); 3915 } 3916 3917 /** 3918 * Verify that when ordered to setLowLatencyMode(false), 3919 * WifiNative is called with the right lowLatency mode. 3920 */ 3921 @Test verifySetLowLatencyFalseSuccess()3922 public void verifySetLowLatencyFalseSuccess() throws Exception { 3923 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 3924 assertTrue(mCmi.setLowLatencyMode(false)); 3925 verify(mWifiNative).setLowLatencyMode(false); 3926 } 3927 3928 /** 3929 * Verify that when WifiNative fails to set low latency mode, 3930 * then the call setLowLatencyMode() returns with failure, 3931 */ 3932 @Test verifySetLowLatencyModeFailure()3933 public void verifySetLowLatencyModeFailure() throws Exception { 3934 final boolean lowLatencyMode = true; 3935 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(false); 3936 assertFalse(mCmi.setLowLatencyMode(lowLatencyMode)); 3937 verify(mWifiNative).setLowLatencyMode(eq(lowLatencyMode)); 3938 } 3939 3940 /** 3941 * Verify getting the factory MAC address success case. 3942 */ 3943 @Test testGetFactoryMacAddressSuccess()3944 public void testGetFactoryMacAddressSuccess() throws Exception { 3945 initializeAndAddNetworkAndVerifySuccess(); 3946 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 3947 verify(mWifiNative).getFactoryMacAddress(WIFI_IFACE_NAME); 3948 verify(mWifiNative).getMacAddress(anyString()); // called once when setting up client mode 3949 } 3950 3951 /** 3952 * Verify getting the factory MAC address failure case. 3953 */ 3954 @Test testGetFactoryMacAddressFail()3955 public void testGetFactoryMacAddressFail() throws Exception { 3956 initializeAndAddNetworkAndVerifySuccess(); 3957 when(mWifiNative.getFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 3958 assertNull(mCmi.getFactoryMacAddress()); 3959 verify(mWifiNative).getFactoryMacAddress(WIFI_IFACE_NAME); 3960 verify(mWifiNative).getMacAddress(anyString()); // called once when setting up client mode 3961 } 3962 3963 /** 3964 * Verify that when WifiNative#getFactoryMacAddress fails, if the device does not support 3965 * MAC randomization then the currently programmed MAC address gets returned. 3966 */ 3967 @Test testGetFactoryMacAddressFailWithNoMacRandomizationSupport()3968 public void testGetFactoryMacAddressFailWithNoMacRandomizationSupport() throws Exception { 3969 mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, false); 3970 initializeCmi(); 3971 initializeAndAddNetworkAndVerifySuccess(); 3972 when(mWifiNative.getFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 3973 mCmi.getFactoryMacAddress(); 3974 verify(mWifiNative).getFactoryMacAddress(anyString()); 3975 verify(mWifiNative, times(2)).getMacAddress(WIFI_IFACE_NAME); 3976 } 3977 3978 @Test testSetDeviceMobilityState()3979 public void testSetDeviceMobilityState() { 3980 mCmi.setDeviceMobilityState(WifiManager.DEVICE_MOBILITY_STATE_STATIONARY); 3981 verify(mWifiConnectivityManager).setDeviceMobilityState( 3982 WifiManager.DEVICE_MOBILITY_STATE_STATIONARY); 3983 verify(mWifiHealthMonitor).setDeviceMobilityState( 3984 WifiManager.DEVICE_MOBILITY_STATE_STATIONARY); 3985 verify(mWifiDataStall).setDeviceMobilityState( 3986 WifiManager.DEVICE_MOBILITY_STATE_STATIONARY); 3987 } 3988 3989 /** 3990 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 3991 */ 3992 @Test testRandomizeMacAddressOnStart()3993 public void testRandomizeMacAddressOnStart() throws Exception { 3994 ArgumentCaptor<MacAddress> macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class); 3995 loadComponentsInStaMode(); 3996 verify(mWifiNative).setMacAddress(anyString(), macAddressCaptor.capture()); 3997 MacAddress currentMac = macAddressCaptor.getValue(); 3998 3999 assertNotEquals("The currently programmed MAC address should be different from the factory " 4000 + "MAC address after ClientModeImpl starts", 4001 mCmi.getFactoryMacAddress(), currentMac.toString()); 4002 } 4003 4004 /** 4005 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 4006 */ 4007 @Test testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled()4008 public void testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled() throws Exception { 4009 mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, false); 4010 loadComponentsInStaMode(); 4011 verify(mWifiNative, never()).setMacAddress(anyString(), any()); 4012 } 4013 4014 /** 4015 * Verify bugreport will be taken when get IP_REACHABILITY_LOST 4016 */ 4017 @Test testTakebugreportbyIpReachabilityLost()4018 public void testTakebugreportbyIpReachabilityLost() throws Exception { 4019 connect(); 4020 4021 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 4022 mLooper.dispatchAll(); 4023 verify(mWifiDiagnostics).captureBugReportData( 4024 eq(WifiDiagnostics.REPORT_REASON_REACHABILITY_LOST)); 4025 } 4026 4027 /** 4028 * Verify removing sim will also remove an ephemeral Passpoint Provider. And reset carrier 4029 * privileged suggestor apps. 4030 */ 4031 @Test testResetSimNetworkWhenRemovingSim()4032 public void testResetSimNetworkWhenRemovingSim() throws Exception { 4033 // Switch to connect mode and verify wifi is reported as enabled 4034 startSupplicantAndDispatchMessages(); 4035 4036 // Indicate that sim is removed. 4037 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 4038 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 4039 mLooper.dispatchAll(); 4040 4041 verify(mWifiConfigManager).resetSimNetworks(); 4042 verify(mWifiNetworkSuggestionsManager).resetCarrierPrivilegedApps(); 4043 } 4044 4045 /** 4046 * Verify inserting sim will reset carrier privileged suggestor apps. 4047 * and remove any previous notifications due to sim removal 4048 */ 4049 @Test testResetCarrierPrivilegedAppsWhenInsertingSim()4050 public void testResetCarrierPrivilegedAppsWhenInsertingSim() throws Exception { 4051 // Switch to connect mode and verify wifi is reported as enabled 4052 startSupplicantAndDispatchMessages(); 4053 4054 // Indicate that sim is inserted. 4055 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 4056 ClientModeImpl.RESET_SIM_REASON_SIM_INSERTED); 4057 mLooper.dispatchAll(); 4058 4059 verify(mWifiConfigManager, never()).resetSimNetworks(); 4060 verify(mWifiNetworkSuggestionsManager).resetCarrierPrivilegedApps(); 4061 verify(mSimRequiredNotifier).dismissSimRequiredNotification(); 4062 } 4063 4064 /** 4065 * Verifies that WifiLastResortWatchdog is notified of FOURWAY_HANDSHAKE_TIMEOUT. 4066 */ 4067 @Test testHandshakeTimeoutUpdatesWatchdog()4068 public void testHandshakeTimeoutUpdatesWatchdog() throws Exception { 4069 // Setup CONNECT_MODE & a WifiConfiguration 4070 initializeAndAddNetworkAndVerifySuccess(); 4071 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4072 mLooper.dispatchAll(); 4073 // Verifies that WifiLastResortWatchdog won't be notified 4074 // by other reason code 4075 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 2, sBSSID); 4076 mLooper.dispatchAll(); 4077 4078 assertEquals("DisconnectedState", getCurrentState().getName()); 4079 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 4080 sSSID, sBSSID, WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 4081 4082 // Verifies that WifiLastResortWatchdog be notified 4083 // for FOURWAY_HANDSHAKE_TIMEOUT. 4084 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4085 mLooper.dispatchAll(); 4086 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID); 4087 mLooper.dispatchAll(); 4088 4089 assertEquals("DisconnectedState", getCurrentState().getName()); 4090 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 4091 sSSID, sBSSID, WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 4092 4093 } 4094 4095 /** 4096 * Verify that WifiInfo is correctly populated after connection. 4097 */ 4098 @Test verifyWifiInfoGetNetworkSpecifierPackageName()4099 public void verifyWifiInfoGetNetworkSpecifierPackageName() throws Exception { 4100 mConnectedNetwork.fromWifiNetworkSpecifier = true; 4101 mConnectedNetwork.ephemeral = true; 4102 mConnectedNetwork.trusted = true; 4103 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 4104 connect(); 4105 4106 assertTrue(mCmi.getWifiInfo().isEphemeral()); 4107 assertTrue(mCmi.getWifiInfo().isTrusted()); 4108 assertEquals(OP_PACKAGE_NAME, 4109 mCmi.getWifiInfo().getRequestingPackageName()); 4110 } 4111 4112 /** 4113 * Verify that WifiInfo is correctly populated after connection. 4114 */ 4115 @Test verifyWifiInfoGetNetworkSuggestionPackageName()4116 public void verifyWifiInfoGetNetworkSuggestionPackageName() throws Exception { 4117 mConnectedNetwork.fromWifiNetworkSuggestion = true; 4118 mConnectedNetwork.ephemeral = true; 4119 mConnectedNetwork.trusted = true; 4120 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 4121 connect(); 4122 4123 assertTrue(mCmi.getWifiInfo().isEphemeral()); 4124 assertTrue(mCmi.getWifiInfo().isTrusted()); 4125 assertEquals(OP_PACKAGE_NAME, 4126 mCmi.getWifiInfo().getRequestingPackageName()); 4127 } 4128 4129 /** 4130 * Verify that a WifiIsUnusableEvent is logged and the current list of usability stats entries 4131 * are labeled and saved when receiving an IP reachability lost message. 4132 * @throws Exception 4133 */ 4134 @Test verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics()4135 public void verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics() throws Exception { 4136 connect(); 4137 4138 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 4139 mLooper.dispatchAll(); 4140 verify(mWifiMetrics).logWifiIsUnusableEvent( 4141 WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST); 4142 verify(mWifiMetrics).addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, 4143 WifiUsabilityStats.TYPE_IP_REACHABILITY_LOST, -1); 4144 } 4145 4146 /** 4147 * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds 4148 * to the supplicant with the SIM identity. 4149 */ 4150 @Test testSupRequestIdentity_setsIdentityResponse()4151 public void testSupRequestIdentity_setsIdentityResponse() throws Exception { 4152 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 4153 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 4154 mConnectedNetwork.SSID = DEFAULT_TEST_SSID; 4155 4156 when(mDataTelephonyManager.getSubscriberId()).thenReturn("3214561234567890"); 4157 when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 4158 when(mDataTelephonyManager.getSimOperator()).thenReturn("321456"); 4159 when(mDataTelephonyManager.getCarrierInfoForImsiEncryption(anyInt())).thenReturn(null); 4160 MockitoSession mockSession = ExtendedMockito.mockitoSession() 4161 .mockStatic(SubscriptionManager.class) 4162 .startMocking(); 4163 when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID); 4164 when(SubscriptionManager.isValidSubscriptionId(anyInt())).thenReturn(true); 4165 4166 triggerConnect(); 4167 4168 mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY, 4169 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID); 4170 mLooper.dispatchAll(); 4171 4172 verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME, 4173 "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org", ""); 4174 mockSession.finishMocking(); 4175 } 4176 4177 /** 4178 * Verifies that WifiLastResortWatchdog is notified of DHCP failures when recevied 4179 * NETWORK_DISCONNECTION_EVENT while in ObtainingIpState. 4180 */ 4181 @Test testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr()4182 public void testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr() 4183 throws Exception { 4184 initializeAndAddNetworkAndVerifySuccess(); 4185 4186 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 4187 4188 IActionListener connectActionListener = mock(IActionListener.class); 4189 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 4190 mLooper.dispatchAll(); 4191 verify(connectActionListener).onSuccess(); 4192 4193 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 4194 4195 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 4196 mLooper.dispatchAll(); 4197 4198 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4199 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 4200 mLooper.dispatchAll(); 4201 4202 assertEquals("ObtainingIpState", getCurrentState().getName()); 4203 4204 // Verifies that WifiLastResortWatchdog be notified. 4205 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 4206 mLooper.dispatchAll(); 4207 4208 assertEquals("DisconnectedState", getCurrentState().getName()); 4209 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 4210 sSSID, sBSSID, WifiLastResortWatchdog.FAILURE_CODE_DHCP); 4211 } 4212 4213 /** 4214 * Verifies that we trigger a disconnect when the {@link WifiConfigManager}. 4215 * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked. 4216 */ 4217 @Test testOnNetworkRemoved()4218 public void testOnNetworkRemoved() throws Exception { 4219 connect(); 4220 4221 WifiConfiguration removedNetwork = new WifiConfiguration(); 4222 removedNetwork.networkId = FRAMEWORK_NETWORK_ID; 4223 mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork); 4224 mLooper.dispatchAll(); 4225 4226 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 4227 assertEquals("DisconnectingState", getCurrentState().getName()); 4228 } 4229 4230 /** 4231 * Verifies that we trigger a disconnect when the {@link WifiConfigManager 4232 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 4233 */ 4234 @Test testOnNetworkPermanentlyDisabled()4235 public void testOnNetworkPermanentlyDisabled() throws Exception { 4236 connect(); 4237 4238 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4239 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4240 mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork, 4241 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 4242 mLooper.dispatchAll(); 4243 4244 assertEquals("DisconnectingState", getCurrentState().getName()); 4245 } 4246 4247 /** 4248 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 4249 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 4250 */ 4251 @Test testOnNetworkPermanentlyDisabledWithNoInternet()4252 public void testOnNetworkPermanentlyDisabledWithNoInternet() throws Exception { 4253 connect(); 4254 4255 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4256 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4257 mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork, 4258 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT); 4259 mLooper.dispatchAll(); 4260 4261 assertEquals("ConnectedState", getCurrentState().getName()); 4262 } 4263 4264 /** 4265 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 4266 * .OnNetworkUpdateListener#onNetworkTemporarilyDisabled(WifiConfiguration, int)} is invoked. 4267 */ 4268 @Test testOnNetworkTemporarilyDisabledWithNoInternet()4269 public void testOnNetworkTemporarilyDisabledWithNoInternet() throws Exception { 4270 connect(); 4271 4272 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4273 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4274 mConfigUpdateListenerCaptor.getValue().onNetworkTemporarilyDisabled(disabledNetwork, 4275 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY); 4276 mLooper.dispatchAll(); 4277 4278 assertEquals("ConnectedState", getCurrentState().getName()); 4279 } 4280 4281 /** 4282 * Verify that MboOce/WifiDataStall enable/disable methods are called in ClientMode. 4283 */ 4284 @Test verifyMboOceWifiDataStallSetupInClientMode()4285 public void verifyMboOceWifiDataStallSetupInClientMode() throws Exception { 4286 startSupplicantAndDispatchMessages(); 4287 verify(mMboOceController).enable(); 4288 verify(mWifiDataStall).enablePhoneStateListener(); 4289 mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null); 4290 mLooper.dispatchAll(); 4291 verify(mMboOceController).disable(); 4292 verify(mWifiDataStall).disablePhoneStateListener(); 4293 } 4294 4295 /** 4296 * Verify that Bluetooth active is set correctly with BT state/connection state changes 4297 */ 4298 @Test verifyBluetoothStateAndConnectionStateChanges()4299 public void verifyBluetoothStateAndConnectionStateChanges() throws Exception { 4300 startSupplicantAndDispatchMessages(); 4301 mCmi.sendBluetoothAdapterStateChange(BluetoothAdapter.STATE_ON); 4302 mLooper.dispatchAll(); 4303 verify(mWifiConnectivityManager, times(1)).setBluetoothConnected(false); 4304 4305 mCmi.sendBluetoothAdapterConnectionStateChange(BluetoothAdapter.STATE_CONNECTED); 4306 mLooper.dispatchAll(); 4307 verify(mWifiConnectivityManager, times(1)).setBluetoothConnected(true); 4308 4309 mCmi.sendBluetoothAdapterStateChange(BluetoothAdapter.STATE_OFF); 4310 mLooper.dispatchAll(); 4311 verify(mWifiConnectivityManager, times(2)).setBluetoothConnected(false); 4312 4313 mCmi.sendBluetoothAdapterStateChange(BluetoothAdapter.STATE_ON); 4314 mLooper.dispatchAll(); 4315 verify(mWifiConnectivityManager, times(3)).setBluetoothConnected(false); 4316 4317 mCmi.sendBluetoothAdapterConnectionStateChange(BluetoothAdapter.STATE_CONNECTING); 4318 mLooper.dispatchAll(); 4319 verify(mWifiConnectivityManager, times(2)).setBluetoothConnected(true); 4320 4321 mCmi.sendBluetoothAdapterConnectionStateChange(BluetoothAdapter.STATE_DISCONNECTED); 4322 mLooper.dispatchAll(); 4323 verify(mWifiConnectivityManager, times(4)).setBluetoothConnected(false); 4324 4325 mCmi.sendBluetoothAdapterConnectionStateChange(BluetoothAdapter.STATE_CONNECTED); 4326 mLooper.dispatchAll(); 4327 verify(mWifiConnectivityManager, times(3)).setBluetoothConnected(true); 4328 } 4329 4330 /** 4331 * Test that handleBssTransitionRequest() blacklist the BSS upon 4332 * receiving BTM request frame that contains MBO-OCE IE with an 4333 * association retry delay attribute. 4334 */ 4335 @Test testBtmFrameWithMboAssocretryDelayBlackListTheBssid()4336 public void testBtmFrameWithMboAssocretryDelayBlackListTheBssid() throws Exception { 4337 // Connect to network with |sBSSID|, |sFreq|. 4338 connect(); 4339 4340 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 4341 4342 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 4343 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 4344 | MboOceConstants.BTM_DATA_FLAG_MBO_ASSOC_RETRY_DELAY_INCLUDED; 4345 btmFrmData.mBlackListDurationMs = 60000; 4346 4347 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 4348 mLooper.dispatchAll(); 4349 4350 verify(mWifiMetrics, times(1)).incrementSteeringRequestCountIncludingMboAssocRetryDelay(); 4351 verify(mBssidBlocklistMonitor).blockBssidForDurationMs(sBSSID, sSSID, 4352 btmFrmData.mBlackListDurationMs); 4353 } 4354 4355 /** 4356 * Test that handleBssTransitionRequest() trigger force scan for 4357 * network selection when status code is REJECT. 4358 */ 4359 @Test testBTMRequestRejectTriggerNetworkSelction()4360 public void testBTMRequestRejectTriggerNetworkSelction() throws Exception { 4361 // Connect to network with |sBSSID|, |sFreq|. 4362 connect(); 4363 4364 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 4365 4366 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 4367 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 4368 | MboOceConstants.BTM_DATA_FLAG_BSS_TERMINATION_INCLUDED 4369 | MboOceConstants.BTM_DATA_FLAG_MBO_CELL_DATA_CONNECTION_PREFERENCE_INCLUDED; 4370 btmFrmData.mBlackListDurationMs = 60000; 4371 4372 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 4373 mLooper.dispatchAll(); 4374 4375 verify(mBssidBlocklistMonitor, never()).blockBssidForDurationMs(sBSSID, sSSID, 4376 btmFrmData.mBlackListDurationMs); 4377 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 4378 verify(mWifiMetrics, times(1)).incrementMboCellularSwitchRequestCount(); 4379 verify(mWifiMetrics, times(1)) 4380 .incrementForceScanCountDueToSteeringRequest(); 4381 4382 } 4383 4384 /** 4385 * Test that handleBssTransitionRequest() does not trigger force 4386 * scan when status code is accept. 4387 */ 4388 @Test testBTMRequestAcceptDoNotTriggerNetworkSelction()4389 public void testBTMRequestAcceptDoNotTriggerNetworkSelction() throws Exception { 4390 // Connect to network with |sBSSID|, |sFreq|. 4391 connect(); 4392 4393 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 4394 4395 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT; 4396 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT; 4397 4398 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 4399 mLooper.dispatchAll(); 4400 4401 verify(mWifiConnectivityManager, never()) 4402 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 4403 } 4404 4405 /** 4406 * Test that the interval for poll RSSI is read from config overlay correctly. 4407 */ 4408 @Test testPollRssiIntervalIsSetCorrectly()4409 public void testPollRssiIntervalIsSetCorrectly() throws Exception { 4410 assertEquals(3000, mCmi.getPollRssiIntervalMsecs()); 4411 mResources.setInteger(R.integer.config_wifiPollRssiIntervalMilliseconds, 6000); 4412 assertEquals(6000, mCmi.getPollRssiIntervalMsecs()); 4413 mResources.setInteger(R.integer.config_wifiPollRssiIntervalMilliseconds, 7000); 4414 assertEquals(6000, mCmi.getPollRssiIntervalMsecs()); 4415 } 4416 4417 /** 4418 * Verifies that the logic does not modify PSK key management when WPA3 auto upgrade feature is 4419 * disabled. 4420 * 4421 * @throws Exception 4422 */ 4423 @Test testNoWpa3UpgradeWhenOverlaysAreOff()4424 public void testNoWpa3UpgradeWhenOverlaysAreOff() throws Exception { 4425 initializeAndAddNetworkAndVerifySuccess(); 4426 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4427 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4428 4429 WifiConfiguration config = mock(WifiConfiguration.class); 4430 BitSet allowedKeyManagement = mock(BitSet.class); 4431 config.allowedKeyManagement = allowedKeyManagement; 4432 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))).thenReturn( 4433 true); 4434 when(config.getNetworkSelectionStatus()) 4435 .thenReturn(new WifiConfiguration.NetworkSelectionStatus()); 4436 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4437 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, false); 4438 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, false); 4439 4440 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4441 mLooper.dispatchAll(); 4442 4443 verify(config, never()).setSecurityParams(eq(WifiConfiguration.SECURITY_TYPE_SAE)); 4444 } 4445 4446 /** 4447 * Verifies that the logic always enables SAE key management when WPA3 auto upgrade offload 4448 * feature is enabled. 4449 * 4450 * @throws Exception 4451 */ 4452 @Test testWpa3UpgradeOffload()4453 public void testWpa3UpgradeOffload() throws Exception { 4454 initializeAndAddNetworkAndVerifySuccess(); 4455 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4456 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4457 4458 WifiConfiguration config = mock(WifiConfiguration.class); 4459 BitSet allowedKeyManagement = mock(BitSet.class); 4460 BitSet allowedAuthAlgorithms = mock(BitSet.class); 4461 config.allowedKeyManagement = allowedKeyManagement; 4462 config.allowedAuthAlgorithms = allowedAuthAlgorithms; 4463 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))).thenReturn( 4464 true); 4465 when(config.getNetworkSelectionStatus()) 4466 .thenReturn(new WifiConfiguration.NetworkSelectionStatus()); 4467 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4468 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, true); 4469 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, true); 4470 4471 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4472 mLooper.dispatchAll(); 4473 4474 verify(allowedKeyManagement).set(eq(WifiConfiguration.KeyMgmt.SAE)); 4475 verify(allowedAuthAlgorithms).clear(); 4476 } 4477 4478 /** 4479 * Verifies that the logic does not enable SAE key management when WPA3 auto upgrade feature is 4480 * enabled but no SAE candidate is available. 4481 * 4482 * @throws Exception 4483 */ 4484 @Test testNoWpa3UpgradeWithPskCandidate()4485 public void testNoWpa3UpgradeWithPskCandidate() throws Exception { 4486 initializeAndAddNetworkAndVerifySuccess(); 4487 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4488 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4489 4490 WifiConfiguration config = mock(WifiConfiguration.class); 4491 BitSet allowedKeyManagement = mock(BitSet.class); 4492 config.allowedKeyManagement = allowedKeyManagement; 4493 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))) 4494 .thenReturn(true); 4495 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 4496 mock(WifiConfiguration.NetworkSelectionStatus.class); 4497 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 4498 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4499 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, true); 4500 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, false); 4501 4502 String ssid = "WPA2-Network"; 4503 String caps = "[WPA2-FT/PSK+PSK][ESS][WPS]"; 4504 ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), ssid, 4505 "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0, 4506 0, true); 4507 scanResult.informationElements = new ScanResult.InformationElement[]{ 4508 createIE(ScanResult.InformationElement.EID_SSID, 4509 ssid.getBytes(StandardCharsets.UTF_8)) 4510 }; 4511 when(networkSelectionStatus.getCandidate()).thenReturn(scanResult); 4512 4513 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4514 mLooper.dispatchAll(); 4515 4516 verify(config, never()).setSecurityParams(eq(WifiConfiguration.SECURITY_TYPE_SAE)); 4517 } 4518 4519 /** 4520 * Verifies that the logic enables SAE key management when WPA3 auto upgrade feature is 4521 * enabled and an SAE candidate is available. 4522 * 4523 * @throws Exception 4524 */ 4525 @Test testWpa3UpgradeWithSaeCandidate()4526 public void testWpa3UpgradeWithSaeCandidate() throws Exception { 4527 initializeAndAddNetworkAndVerifySuccess(); 4528 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4529 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4530 4531 WifiConfiguration config = mock(WifiConfiguration.class); 4532 BitSet allowedKeyManagement = mock(BitSet.class); 4533 BitSet allowedAuthAlgorithms = mock(BitSet.class); 4534 BitSet allowedProtocols = mock(BitSet.class); 4535 BitSet allowedPairwiseCiphers = mock(BitSet.class); 4536 BitSet allowedGroupCiphers = mock(BitSet.class); 4537 config.allowedKeyManagement = allowedKeyManagement; 4538 config.allowedAuthAlgorithms = allowedAuthAlgorithms; 4539 config.allowedProtocols = allowedProtocols; 4540 config.allowedPairwiseCiphers = allowedPairwiseCiphers; 4541 config.allowedGroupCiphers = allowedGroupCiphers; 4542 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))) 4543 .thenReturn(true); 4544 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 4545 mock(WifiConfiguration.NetworkSelectionStatus.class); 4546 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 4547 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 4548 when(mWifiConfigManager.getScanDetailCacheForNetwork(anyInt())).thenReturn(null); 4549 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, true); 4550 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, false); 4551 4552 final String ssid = "WPA3-Network"; 4553 String caps = "[WPA2-FT/SAE+SAE][ESS][WPS]"; 4554 ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), ssid, 4555 "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0, 4556 0, true); 4557 scanResult.informationElements = new ScanResult.InformationElement[]{ 4558 createIE(ScanResult.InformationElement.EID_SSID, 4559 ssid.getBytes(StandardCharsets.UTF_8)) 4560 }; 4561 when(networkSelectionStatus.getCandidate()).thenReturn(scanResult); 4562 4563 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4564 mLooper.dispatchAll(); 4565 4566 verify(config).setSecurityParams(eq(WifiConfiguration.SECURITY_TYPE_SAE)); 4567 } 4568 4569 /** 4570 * Verifies that the logic does not enable SAE key management when WPA3 auto upgrade feature is 4571 * enabled and an SAE candidate is available, while another WPA2 AP is in range. 4572 * 4573 * @throws Exception 4574 */ 4575 @Test testWpa3UpgradeWithSaeCandidateAndPskApInRange()4576 public void testWpa3UpgradeWithSaeCandidateAndPskApInRange() throws Exception { 4577 initializeAndAddNetworkAndVerifySuccess(); 4578 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4579 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4580 4581 WifiConfiguration config = mock(WifiConfiguration.class); 4582 BitSet allowedKeyManagement = mock(BitSet.class); 4583 BitSet allowedAuthAlgorithms = mock(BitSet.class); 4584 BitSet allowedProtocols = mock(BitSet.class); 4585 BitSet allowedPairwiseCiphers = mock(BitSet.class); 4586 BitSet allowedGroupCiphers = mock(BitSet.class); 4587 config.allowedKeyManagement = allowedKeyManagement; 4588 config.allowedAuthAlgorithms = allowedAuthAlgorithms; 4589 config.allowedProtocols = allowedProtocols; 4590 config.allowedPairwiseCiphers = allowedPairwiseCiphers; 4591 config.allowedGroupCiphers = allowedGroupCiphers; 4592 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))) 4593 .thenReturn(true); 4594 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 4595 mock(WifiConfiguration.NetworkSelectionStatus.class); 4596 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 4597 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 4598 when(mWifiConfigManager.getScanDetailCacheForNetwork(anyInt())).thenReturn(null); 4599 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, true); 4600 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, false); 4601 4602 final String saeBssid = "ab:cd:01:ef:45:89"; 4603 final String pskBssid = "ab:cd:01:ef:45:9a"; 4604 4605 final String ssidSae = "Mixed-Network"; 4606 config.SSID = ScanResultUtil.createQuotedSSID(ssidSae); 4607 config.networkId = 1; 4608 4609 String capsSae = "[WPA2-FT/SAE+SAE][ESS][WPS]"; 4610 ScanResult scanResultSae = new ScanResult(WifiSsid.createFromAsciiEncoded(ssidSae), ssidSae, 4611 saeBssid, 1245, 0, capsSae, -78, 2412, 1025, 22, 33, 20, 0, 4612 0, true); 4613 ScanResult.InformationElement ieSae = createIE(ScanResult.InformationElement.EID_SSID, 4614 ssidSae.getBytes(StandardCharsets.UTF_8)); 4615 scanResultSae.informationElements = new ScanResult.InformationElement[]{ieSae}; 4616 when(networkSelectionStatus.getCandidate()).thenReturn(scanResultSae); 4617 ScanResult.InformationElement[] ieArr = new ScanResult.InformationElement[1]; 4618 ieArr[0] = ieSae; 4619 4620 final String ssidPsk = "Mixed-Network"; 4621 String capsPsk = "[WPA2-FT/PSK+PSK][ESS][WPS]"; 4622 ScanResult scanResultPsk = new ScanResult(WifiSsid.createFromAsciiEncoded(ssidPsk), ssidPsk, 4623 pskBssid, 1245, 0, capsPsk, -48, 2462, 1025, 22, 33, 20, 0, 4624 0, true); 4625 ScanResult.InformationElement iePsk = createIE(ScanResult.InformationElement.EID_SSID, 4626 ssidPsk.getBytes(StandardCharsets.UTF_8)); 4627 scanResultPsk.informationElements = new ScanResult.InformationElement[]{iePsk}; 4628 ScanResult.InformationElement[] ieArrPsk = new ScanResult.InformationElement[1]; 4629 ieArrPsk[0] = iePsk; 4630 List<ScanResult> scanResults = new ArrayList<>(); 4631 scanResults.add(scanResultPsk); 4632 scanResults.add(scanResultSae); 4633 4634 when(mScanRequestProxy.getScanResults()).thenReturn(scanResults); 4635 4636 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4637 mLooper.dispatchAll(); 4638 4639 verify(config, never()).setSecurityParams(eq(WifiConfiguration.SECURITY_TYPE_SAE)); 4640 } 4641 4642 /** 4643 * Verifies that the logic enables SAE key management when WPA3 auto upgrade feature is 4644 * enabled and no candidate is available (i.e. user selected a WPA2 saved network and the 4645 * network is actually WPA3. 4646 * 4647 * @throws Exception 4648 */ 4649 @Test testWpa3UpgradeWithNoCandidate()4650 public void testWpa3UpgradeWithNoCandidate() throws Exception { 4651 initializeAndAddNetworkAndVerifySuccess(); 4652 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4653 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4654 4655 WifiConfiguration config = mock(WifiConfiguration.class); 4656 BitSet allowedKeyManagement = mock(BitSet.class); 4657 BitSet allowedAuthAlgorithms = mock(BitSet.class); 4658 BitSet allowedProtocols = mock(BitSet.class); 4659 BitSet allowedPairwiseCiphers = mock(BitSet.class); 4660 BitSet allowedGroupCiphers = mock(BitSet.class); 4661 config.allowedKeyManagement = allowedKeyManagement; 4662 config.allowedAuthAlgorithms = allowedAuthAlgorithms; 4663 config.allowedProtocols = allowedProtocols; 4664 config.allowedPairwiseCiphers = allowedPairwiseCiphers; 4665 config.allowedGroupCiphers = allowedGroupCiphers; 4666 when(config.allowedKeyManagement.get(eq(WifiConfiguration.KeyMgmt.WPA_PSK))) 4667 .thenReturn(true); 4668 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 4669 mock(WifiConfiguration.NetworkSelectionStatus.class); 4670 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 4671 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 4672 4673 mResources.setBoolean(R.bool.config_wifiSaeUpgradeEnabled, true); 4674 mResources.setBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled, false); 4675 4676 final String saeBssid = "ab:cd:01:ef:45:89"; 4677 final String ssidSae = "WPA3-Network"; 4678 config.SSID = ScanResultUtil.createQuotedSSID(ssidSae); 4679 config.networkId = 1; 4680 4681 String capsSae = "[WPA2-FT/SAE+SAE][ESS][WPS]"; 4682 ScanResult scanResultSae = new ScanResult(WifiSsid.createFromAsciiEncoded(ssidSae), ssidSae, 4683 saeBssid, 1245, 0, capsSae, -78, 2412, 1025, 22, 33, 20, 0, 4684 0, true); 4685 ScanResult.InformationElement ieSae = createIE(ScanResult.InformationElement.EID_SSID, 4686 ssidSae.getBytes(StandardCharsets.UTF_8)); 4687 scanResultSae.informationElements = new ScanResult.InformationElement[]{ieSae}; 4688 when(networkSelectionStatus.getCandidate()).thenReturn(null); 4689 List<ScanResult> scanResults = new ArrayList<>(); 4690 scanResults.add(scanResultSae); 4691 4692 when(mScanRequestProxy.getScanResults()).thenReturn(scanResults); 4693 4694 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4695 mLooper.dispatchAll(); 4696 4697 verify(config).setSecurityParams(eq(WifiConfiguration.SECURITY_TYPE_SAE)); 4698 } 4699 createIE(int id, byte[] bytes)4700 private static ScanResult.InformationElement createIE(int id, byte[] bytes) { 4701 ScanResult.InformationElement ie = new ScanResult.InformationElement(); 4702 ie.id = id; 4703 ie.bytes = bytes; 4704 return ie; 4705 } 4706 4707 /* 4708 * Verify isWifiBandSupported for 5GHz with an overlay override config 4709 */ 4710 @Test testIsWifiBandSupported5gWithOverride()4711 public void testIsWifiBandSupported5gWithOverride() throws Exception { 4712 mResources.setBoolean(R.bool.config_wifi5ghzSupport, true); 4713 assertTrue(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_5_GHZ)); 4714 verify(mWifiNative, never()).getChannelsForBand(anyInt()); 4715 } 4716 4717 /** 4718 * Verify isWifiBandSupported for 6GHz with an overlay override config 4719 */ 4720 @Test testIsWifiBandSupported6gWithOverride()4721 public void testIsWifiBandSupported6gWithOverride() throws Exception { 4722 mResources.setBoolean(R.bool.config_wifi6ghzSupport, true); 4723 assertTrue(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_6_GHZ)); 4724 verify(mWifiNative, never()).getChannelsForBand(anyInt()); 4725 } 4726 4727 /** 4728 * Verify isWifiBandSupported for 5GHz with no overlay override config no channels 4729 */ 4730 @Test testIsWifiBandSupported5gNoOverrideNoChannels()4731 public void testIsWifiBandSupported5gNoOverrideNoChannels() throws Exception { 4732 final int[] emptyArray = {}; 4733 mResources.setBoolean(R.bool.config_wifi5ghzSupport, false); 4734 when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray); 4735 assertFalse(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_5_GHZ)); 4736 verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ); 4737 } 4738 4739 /** 4740 * Verify isWifiBandSupported for 5GHz with no overlay override config with channels 4741 */ 4742 @Test testIsWifiBandSupported5gNoOverrideWithChannels()4743 public void testIsWifiBandSupported5gNoOverrideWithChannels() throws Exception { 4744 final int[] channelArray = {5170}; 4745 mResources.setBoolean(R.bool.config_wifi5ghzSupport, false); 4746 when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray); 4747 assertTrue(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_5_GHZ)); 4748 verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ); 4749 } 4750 4751 /** 4752 * Verify isWifiBandSupported for 6GHz with no overlay override config no channels 4753 */ 4754 @Test testIsWifiBandSupported6gNoOverrideNoChannels()4755 public void testIsWifiBandSupported6gNoOverrideNoChannels() throws Exception { 4756 final int[] emptyArray = {}; 4757 mResources.setBoolean(R.bool.config_wifi6ghzSupport, false); 4758 when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray); 4759 assertFalse(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_6_GHZ)); 4760 verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ); 4761 } 4762 4763 /** 4764 * Verify isWifiBandSupported for 6GHz with no overlay override config with channels 4765 */ 4766 @Test testIsWifiBandSupported6gNoOverrideWithChannels()4767 public void testIsWifiBandSupported6gNoOverrideWithChannels() throws Exception { 4768 final int[] channelArray = {6420}; 4769 mResources.setBoolean(R.bool.config_wifi6ghzSupport, false); 4770 when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray); 4771 assertTrue(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_6_GHZ)); 4772 verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ); 4773 } 4774 4775 /** 4776 * Helper function for setting up fils test. 4777 * 4778 * @param isDriverSupportFils true if driver support fils. 4779 * @return wifi configuration. 4780 */ setupFilsTest(boolean isDriverSupportFils)4781 private WifiConfiguration setupFilsTest(boolean isDriverSupportFils) { 4782 assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); 4783 assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); 4784 4785 WifiConfiguration config = new WifiConfiguration(); 4786 config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); 4787 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); 4788 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); 4789 config.SSID = ScanResultUtil.createQuotedSSID(sFilsSsid); 4790 config.networkId = 1; 4791 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 4792 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; 4793 4794 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 4795 if (isDriverSupportFils) { 4796 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4797 WifiManager.WIFI_FEATURE_FILS_SHA256 | WifiManager.WIFI_FEATURE_FILS_SHA384); 4798 } else { 4799 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn((long) 0); 4800 } 4801 4802 return config; 4803 } 4804 4805 /** 4806 * Helper function for setting up a scan result with FILS supported AP. 4807 * 4808 */ setupFilsEnabledApInScanResult()4809 private void setupFilsEnabledApInScanResult() { 4810 String caps = "[WPA2-EAP+EAP-SHA256+FILS-SHA256-CCMP]" 4811 + "[RSN-EAP+EAP-SHA256+FILS-SHA256-CCMP][ESS]"; 4812 ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(sFilsSsid), 4813 sFilsSsid, sBSSID, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true); 4814 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 4815 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 4816 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 4817 List<ScanResult> scanResults = new ArrayList<>(); 4818 scanResults.add(scanResult); 4819 4820 when(mScanRequestProxy.getScanResults()).thenReturn(scanResults); 4821 } 4822 4823 4824 /** 4825 * Helper function to send CMD_START_FILS_CONNECTION along with HLP IEs. 4826 * 4827 */ prepareFilsHlpPktAndSendStartConnect()4828 private void prepareFilsHlpPktAndSendStartConnect() { 4829 Layer2PacketParcelable l2Packet = new Layer2PacketParcelable(); 4830 l2Packet.dstMacAddress = TEST_GLOBAL_MAC_ADDRESS; 4831 l2Packet.payload = new byte[] {0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 4832 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x55, 0x66}; 4833 mCmi.sendMessage(ClientModeImpl.CMD_START_FILS_CONNECTION, 0, 0, 4834 Collections.singletonList(l2Packet)); 4835 mLooper.dispatchAll(); 4836 } 4837 4838 /** 4839 * Verifies that while connecting to AP, the logic looks into the scan result and 4840 * looks for AP matching the network type and ssid and update the wificonfig with FILS 4841 * AKM if supported. 4842 * 4843 * @throws Exception 4844 */ 4845 @Test testFilsAKMUpdateBeforeConnect()4846 public void testFilsAKMUpdateBeforeConnect() throws Exception { 4847 initializeAndAddNetworkAndVerifySuccess(); 4848 WifiConfiguration config = setupFilsTest(true); 4849 setupFilsEnabledApInScanResult(); 4850 4851 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4852 mLooper.dispatchAll(); 4853 4854 assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 4855 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 4856 } 4857 4858 /** 4859 * Verifies that while connecting to AP, framework updates the wifi config with 4860 * FILS AKM only if underlying driver support FILS feature. 4861 * 4862 * @throws Exception 4863 */ 4864 @Test testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils()4865 public void testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils() throws Exception { 4866 initializeAndAddNetworkAndVerifySuccess(); 4867 WifiConfiguration config = setupFilsTest(false); 4868 setupFilsEnabledApInScanResult(); 4869 4870 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4871 mLooper.dispatchAll(); 4872 4873 assertFalse(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 4874 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 4875 } 4876 4877 4878 /** 4879 * Verifies that the HLP (DHCP) packets are send to wpa_supplicant 4880 * prior to Fils connection. 4881 * 4882 * @throws Exception 4883 */ 4884 @Test testFilsHlpUpdateBeforeFilsConnection()4885 public void testFilsHlpUpdateBeforeFilsConnection() throws Exception { 4886 initializeAndAddNetworkAndVerifySuccess(); 4887 WifiConfiguration config = setupFilsTest(true); 4888 setupFilsEnabledApInScanResult(); 4889 4890 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4891 mLooper.dispatchAll(); 4892 4893 prepareFilsHlpPktAndSendStartConnect(); 4894 4895 verify(mWifiNative).flushAllHlp(eq(WIFI_IFACE_NAME)); 4896 verify(mWifiNative).addHlpReq(eq(WIFI_IFACE_NAME), any(), any()); 4897 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 4898 } 4899 4900 /** 4901 * Verifies that an association rejection in first FILS connect attempt doesn't block 4902 * the second connection attempt. 4903 * 4904 * @throws Exception 4905 */ 4906 @Test testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject()4907 public void testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject() throws Exception { 4908 initializeAndAddNetworkAndVerifySuccess(); 4909 WifiConfiguration config = setupFilsTest(true); 4910 setupFilsEnabledApInScanResult(); 4911 4912 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4913 mLooper.dispatchAll(); 4914 4915 prepareFilsHlpPktAndSendStartConnect(); 4916 4917 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 4918 4919 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 2, sBSSID); 4920 mLooper.dispatchAll(); 4921 4922 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4923 mLooper.dispatchAll(); 4924 prepareFilsHlpPktAndSendStartConnect(); 4925 4926 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 4927 } 4928 4929 /** 4930 * Verifies Fils connection. 4931 * 4932 * @throws Exception 4933 */ 4934 @Test testFilsConnection()4935 public void testFilsConnection() throws Exception { 4936 initializeAndAddNetworkAndVerifySuccess(); 4937 WifiConfiguration config = setupFilsTest(true); 4938 setupFilsEnabledApInScanResult(); 4939 4940 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 4941 mLooper.dispatchAll(); 4942 4943 prepareFilsHlpPktAndSendStartConnect(); 4944 4945 verify(mWifiMetrics, times(1)).incrementConnectRequestWithFilsAkmCount(); 4946 4947 mCmi.sendMessage(WifiMonitor.FILS_NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 4948 mLooper.dispatchAll(); 4949 4950 verify(mWifiMetrics, times(1)).incrementL2ConnectionThroughFilsAuthCount(); 4951 4952 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4953 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(sFilsSsid), 4954 sBSSID, SupplicantState.COMPLETED)); 4955 mLooper.dispatchAll(); 4956 4957 assertEquals("ObtainingIpState", getCurrentState().getName()); 4958 4959 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 4960 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 4961 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 4962 dhcpResults.baseConfiguration.ipAddress = 4963 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 4964 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 4965 dhcpResults.leaseDuration = 3600; 4966 4967 injectDhcpSuccess(dhcpResults); 4968 mLooper.dispatchAll(); 4969 4970 WifiInfo wifiInfo = mCmi.getWifiInfo(); 4971 assertNotNull(wifiInfo); 4972 assertEquals(sBSSID, wifiInfo.getBSSID()); 4973 assertTrue(WifiSsid.createFromAsciiEncoded(sFilsSsid).equals(wifiInfo.getWifiSsid())); 4974 assertEquals("ConnectedState", getCurrentState().getName()); 4975 } 4976 4977 /** 4978 * Tests the wifi info is updated correctly for connecting network. 4979 */ 4980 @Test testWifiInfoOnConnectingNextNetwork()4981 public void testWifiInfoOnConnectingNextNetwork() throws Exception { 4982 4983 mConnectedNetwork.ephemeral = true; 4984 mConnectedNetwork.trusted = true; 4985 mConnectedNetwork.osu = true; 4986 4987 triggerConnect(); 4988 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 4989 .thenReturn(mScanDetailCache); 4990 4991 when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( 4992 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); 4993 when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( 4994 getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); 4995 4996 // before the fist success connection, there is no valid wifi info. 4997 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, mCmi.getWifiInfo().getNetworkId()); 4998 4999 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5000 new StateChangeResult(FRAMEWORK_NETWORK_ID, 5001 sWifiSsid, sBSSID, SupplicantState.ASSOCIATED)); 5002 mLooper.dispatchAll(); 5003 5004 // retrieve correct wifi info on receiving the supplicant state change event. 5005 assertEquals(FRAMEWORK_NETWORK_ID, mCmi.getWifiInfo().getNetworkId()); 5006 assertEquals(mConnectedNetwork.ephemeral, mCmi.getWifiInfo().isEphemeral()); 5007 assertEquals(mConnectedNetwork.trusted, mCmi.getWifiInfo().isTrusted()); 5008 assertEquals(mConnectedNetwork.osu, mCmi.getWifiInfo().isOsuAp()); 5009 } 5010 5011 /** 5012 * Verify that we disconnect when we mark a previous unmetered network metered. 5013 */ 5014 @Test verifyDisconnectOnMarkingNetworkMetered()5015 public void verifyDisconnectOnMarkingNetworkMetered() throws Exception { 5016 connect(); 5017 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5018 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5019 }); 5020 5021 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5022 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5023 5024 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5025 mLooper.dispatchAll(); 5026 assertEquals("DisconnectingState", getCurrentState().getName()); 5027 } 5028 5029 /** 5030 * Verify that we only update capabilites when we mark a previous unmetered network metered. 5031 */ 5032 @Test verifyUpdateCapabilitiesOnMarkingNetworkUnmetered()5033 public void verifyUpdateCapabilitiesOnMarkingNetworkUnmetered() throws Exception { 5034 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5035 connect(); 5036 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5037 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5038 }); 5039 reset(mNetworkAgentHandler); 5040 5041 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5042 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5043 5044 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5045 mLooper.dispatchAll(); 5046 assertEquals("ConnectedState", getCurrentState().getName()); 5047 5048 expectNetworkAgentUpdateCapabilities((cap) -> { 5049 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5050 }); 5051 } 5052 5053 5054 /** 5055 * Verify that we disconnect when we mark a previous unmetered network metered. 5056 */ 5057 @Test verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint()5058 public void verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 5059 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5060 connect(); 5061 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5062 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5063 }); 5064 reset(mNetworkAgentHandler); 5065 5066 // Mark network metered none. 5067 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5068 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5069 5070 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 5071 WifiInfo wifiInfo = mCmi.getWifiInfo(); 5072 wifiInfo.setMeteredHint(true); 5073 5074 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5075 mLooper.dispatchAll(); 5076 assertEquals("DisconnectingState", getCurrentState().getName()); 5077 } 5078 5079 /** 5080 * Verify that we only update capabilites when we mark a previous unmetered network metered. 5081 */ 5082 @Test verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint()5083 public void verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint() 5084 throws Exception { 5085 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5086 connect(); 5087 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5088 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5089 }); 5090 reset(mNetworkAgentHandler); 5091 5092 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5093 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5094 5095 // Reset metered hint in WifiInfo. 5096 WifiInfo wifiInfo = mCmi.getWifiInfo(); 5097 wifiInfo.setMeteredHint(false); 5098 5099 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5100 mLooper.dispatchAll(); 5101 assertEquals("ConnectedState", getCurrentState().getName()); 5102 5103 expectNetworkAgentUpdateCapabilities((cap) -> { 5104 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5105 }); 5106 } 5107 5108 /** 5109 * Verify that we do nothing on no metered change. 5110 */ 5111 @Test verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint()5112 public void verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 5113 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5114 connect(); 5115 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5116 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5117 }); 5118 reset(mNetworkAgentHandler); 5119 5120 // Mark network metered none. 5121 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5122 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5123 5124 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 5125 WifiInfo wifiInfo = mCmi.getWifiInfo(); 5126 wifiInfo.setMeteredHint(true); 5127 5128 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5129 mLooper.dispatchAll(); 5130 assertEquals("ConnectedState", getCurrentState().getName()); 5131 5132 verifyNoMoreInteractions(mNetworkAgentHandler); 5133 } 5134 5135 /** 5136 * Verify that we do nothing on no metered change. 5137 */ 5138 @Test verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint()5139 public void verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint() throws Exception { 5140 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5141 connect(); 5142 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5143 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5144 }); 5145 reset(mNetworkAgentHandler); 5146 5147 // Mark network metered none. 5148 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5149 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5150 5151 // Reset metered hint in WifiInfo. 5152 WifiInfo wifiInfo = mCmi.getWifiInfo(); 5153 wifiInfo.setMeteredHint(false); 5154 5155 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5156 mLooper.dispatchAll(); 5157 assertEquals("ConnectedState", getCurrentState().getName()); 5158 5159 verifyNoMoreInteractions(mNetworkAgentHandler); 5160 } 5161 5162 /* 5163 * Verify that network cached data is cleared correctly in 5164 * disconnected state. 5165 */ 5166 @Test testNetworkCachedDataIsClearedCorrectlyInDisconnectedState()5167 public void testNetworkCachedDataIsClearedCorrectlyInDisconnectedState() throws Exception { 5168 // Setup CONNECT_MODE & a WifiConfiguration 5169 initializeAndAddNetworkAndVerifySuccess(); 5170 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 5171 mLooper.dispatchAll(); 5172 5173 // got UNSPECIFIED during this connection attempt 5174 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 1, sBSSID); 5175 mLooper.dispatchAll(); 5176 5177 assertEquals("DisconnectedState", getCurrentState().getName()); 5178 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 5179 5180 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 5181 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); 5182 mLooper.dispatchAll(); 5183 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID); 5184 mLooper.dispatchAll(); 5185 5186 assertEquals("DisconnectedState", getCurrentState().getName()); 5187 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 5188 } 5189 5190 /* 5191 * Verify that network cached data is cleared correctly in 5192 * disconnected state. 5193 */ 5194 @Test testNetworkCachedDataIsClearedCorrectlyInObtainingIpState()5195 public void testNetworkCachedDataIsClearedCorrectlyInObtainingIpState() throws Exception { 5196 initializeAndAddNetworkAndVerifySuccess(); 5197 5198 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 5199 5200 IActionListener connectActionListener = mock(IActionListener.class); 5201 mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid()); 5202 mLooper.dispatchAll(); 5203 verify(connectActionListener).onSuccess(); 5204 5205 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any()); 5206 5207 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 5208 mLooper.dispatchAll(); 5209 5210 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5211 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 5212 mLooper.dispatchAll(); 5213 5214 assertEquals("ObtainingIpState", getCurrentState().getName()); 5215 5216 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 5217 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID); 5218 mLooper.dispatchAll(); 5219 5220 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 5221 } 5222 5223 /* 5224 * Verify that network cached data is NOT cleared in ConnectedState. 5225 */ 5226 @Test testNetworkCachedDataIsClearedIf4WayHandshakeFailure()5227 public void testNetworkCachedDataIsClearedIf4WayHandshakeFailure() throws Exception { 5228 when(mWifiScoreCard.detectAbnormalDisconnection()) 5229 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 5230 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 5231 connect(); 5232 inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(true); 5233 5234 // got 4WAY_HANDSHAKE_TIMEOUT 5235 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 15, sBSSID); 5236 mLooper.dispatchAll(); 5237 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 5238 } 5239 5240 /** 5241 * Verify that network cached data is cleared on updating a network. 5242 */ 5243 @Test testNetworkCachedDataIsClearedOnUpdatingNetwork()5244 public void testNetworkCachedDataIsClearedOnUpdatingNetwork() throws Exception { 5245 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5246 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5247 5248 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5249 mLooper.dispatchAll(); 5250 verify(mWifiNative).removeNetworkCachedData(eq(oldConfig.networkId)); 5251 } 5252 5253 5254 @Test testIpReachabilityLostAndRoamEventsRace()5255 public void testIpReachabilityLostAndRoamEventsRace() throws Exception { 5256 connect(); 5257 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 5258 reset(mNetworkAgentHandler); 5259 5260 // Trigger ip reachibility loss and ensure we trigger a disconnect & we're in 5261 // "DisconnectingState" 5262 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 5263 mLooper.dispatchAll(); 5264 verify(mWifiNative).disconnect(any()); 5265 assertEquals("DisconnectingState", getCurrentState().getName()); 5266 5267 // Now send a network connection (indicating a roam) event before we get the disconnect 5268 // event. 5269 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 5270 mLooper.dispatchAll(); 5271 // ensure that we ignored the transient roam while we're disconnecting. 5272 assertEquals("DisconnectingState", getCurrentState().getName()); 5273 verifyNoMoreInteractions(mNetworkAgentHandler); 5274 5275 // Now send the disconnect event and ensure that we transition to "DisconnectedState". 5276 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 5277 mLooper.dispatchAll(); 5278 assertEquals("DisconnectedState", getCurrentState().getName()); 5279 expectUnregisterNetworkAgent(); 5280 5281 verifyNoMoreInteractions(mNetworkAgentHandler); 5282 } 5283 5284 @Test testSyncGetCurrentNetwork()5285 public void testSyncGetCurrentNetwork() throws Exception { 5286 // syncGetCurrentNetwork() returns null when disconnected 5287 mLooper.startAutoDispatch(); 5288 assertNull(mCmi.syncGetCurrentNetwork(mCmiAsyncChannel)); 5289 mLooper.stopAutoDispatch(); 5290 5291 connect(); 5292 5293 // syncGetCurrentNetwork() returns non-null Network when connected 5294 mLooper.startAutoDispatch(); 5295 assertEquals(mNetwork, mCmi.syncGetCurrentNetwork(mCmiAsyncChannel)); 5296 mLooper.stopAutoDispatch(); 5297 } 5298 } 5299