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.content.Intent.ACTION_SCREEN_OFF; 20 import static android.content.Intent.ACTION_SCREEN_ON; 21 import static android.net.NetworkInfo.DetailedState.CONNECTED; 22 import static android.net.NetworkInfo.DetailedState.CONNECTING; 23 import static android.net.NetworkInfo.DetailedState.OBTAINING_IPADDR; 24 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; 25 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; 26 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED; 27 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE; 28 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY; 29 30 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY; 31 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT; 32 import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION; 33 import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE; 34 import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS; 35 36 import static org.junit.Assert.assertArrayEquals; 37 import static org.junit.Assert.assertEquals; 38 import static org.junit.Assert.assertFalse; 39 import static org.junit.Assert.assertNotEquals; 40 import static org.junit.Assert.assertNotNull; 41 import static org.junit.Assert.assertNull; 42 import static org.junit.Assert.assertTrue; 43 import static org.junit.Assume.assumeTrue; 44 import static org.mockito.Mockito.any; 45 import static org.mockito.Mockito.anyBoolean; 46 import static org.mockito.Mockito.anyByte; 47 import static org.mockito.Mockito.anyInt; 48 import static org.mockito.Mockito.anyLong; 49 import static org.mockito.Mockito.anyObject; 50 import static org.mockito.Mockito.anyString; 51 import static org.mockito.Mockito.argThat; 52 import static org.mockito.Mockito.atLeastOnce; 53 import static org.mockito.Mockito.clearInvocations; 54 import static org.mockito.Mockito.doAnswer; 55 import static org.mockito.Mockito.doReturn; 56 import static org.mockito.Mockito.eq; 57 import static org.mockito.Mockito.inOrder; 58 import static org.mockito.Mockito.mock; 59 import static org.mockito.Mockito.never; 60 import static org.mockito.Mockito.reset; 61 import static org.mockito.Mockito.spy; 62 import static org.mockito.Mockito.times; 63 import static org.mockito.Mockito.verify; 64 import static org.mockito.Mockito.verifyNoMoreInteractions; 65 import static org.mockito.Mockito.when; 66 import static org.mockito.Mockito.withSettings; 67 68 import android.annotation.NonNull; 69 import android.annotation.Nullable; 70 import android.app.ActivityManager; 71 import android.app.test.MockAnswerUtil.AnswerWithArguments; 72 import android.app.test.TestAlarmManager; 73 import android.content.BroadcastReceiver; 74 import android.content.Context; 75 import android.content.Intent; 76 import android.content.pm.PackageManager; 77 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 78 import android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.AssociationRejectionData; 79 import android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.MboAssocDisallowedReasonCode; 80 import android.net.CaptivePortalData; 81 import android.net.DhcpResultsParcelable; 82 import android.net.InetAddresses; 83 import android.net.Layer2InformationParcelable; 84 import android.net.Layer2PacketParcelable; 85 import android.net.LinkAddress; 86 import android.net.LinkProperties; 87 import android.net.MacAddress; 88 import android.net.Network; 89 import android.net.NetworkAgent; 90 import android.net.NetworkAgentConfig; 91 import android.net.NetworkCapabilities; 92 import android.net.NetworkInfo; 93 import android.net.NetworkProvider; 94 import android.net.NetworkSpecifier; 95 import android.net.StaticIpConfiguration; 96 import android.net.Uri; 97 import android.net.ip.IIpClient; 98 import android.net.ip.IpClientCallbacks; 99 import android.net.vcn.VcnManager; 100 import android.net.vcn.VcnNetworkPolicyResult; 101 import android.net.wifi.IActionListener; 102 import android.net.wifi.ScanResult; 103 import android.net.wifi.SupplicantState; 104 import android.net.wifi.WifiConfiguration; 105 import android.net.wifi.WifiConfiguration.KeyMgmt; 106 import android.net.wifi.WifiEnterpriseConfig; 107 import android.net.wifi.WifiInfo; 108 import android.net.wifi.WifiManager; 109 import android.net.wifi.WifiNetworkAgentSpecifier; 110 import android.net.wifi.WifiNetworkSpecifier; 111 import android.net.wifi.WifiSsid; 112 import android.net.wifi.hotspot2.IProvisioningCallback; 113 import android.net.wifi.hotspot2.OsuProvider; 114 import android.net.wifi.nl80211.WifiNl80211Manager; 115 import android.net.wifi.p2p.WifiP2pManager; 116 import android.os.BatteryStatsManager; 117 import android.os.Binder; 118 import android.os.Bundle; 119 import android.os.Handler; 120 import android.os.HandlerThread; 121 import android.os.Looper; 122 import android.os.Message; 123 import android.os.Messenger; 124 import android.os.PowerManager; 125 import android.os.Process; 126 import android.os.test.TestLooper; 127 import android.provider.Settings; 128 import android.telephony.TelephonyManager; 129 import android.test.mock.MockContentProvider; 130 import android.test.mock.MockContentResolver; 131 import android.util.Log; 132 import android.util.Pair; 133 134 import androidx.test.filters.SmallTest; 135 136 import com.android.dx.mockito.inline.extended.ExtendedMockito; 137 import com.android.internal.util.AsyncChannel; 138 import com.android.internal.util.IState; 139 import com.android.internal.util.StateMachine; 140 import com.android.modules.utils.build.SdkLevel; 141 import com.android.server.wifi.ClientMode.LinkProbeCallback; 142 import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast; 143 import com.android.server.wifi.WifiNative.ConnectionCapabilities; 144 import com.android.server.wifi.WifiScoreCard.PerNetwork; 145 import com.android.server.wifi.hotspot2.NetworkDetail; 146 import com.android.server.wifi.hotspot2.PasspointManager; 147 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil; 148 import com.android.server.wifi.hotspot2.WnmData; 149 import com.android.server.wifi.proto.nano.WifiMetricsProto; 150 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent; 151 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent; 152 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStats; 153 import com.android.server.wifi.util.ActionListenerWrapper; 154 import com.android.server.wifi.util.NativeUtil; 155 import com.android.server.wifi.util.RssiUtilTest; 156 import com.android.server.wifi.util.ScanResultUtil; 157 import com.android.server.wifi.util.WifiPermissionsUtil; 158 import com.android.wifi.resources.R; 159 160 import org.junit.After; 161 import org.junit.Before; 162 import org.junit.Test; 163 import org.mockito.ArgumentCaptor; 164 import org.mockito.ArgumentMatcher; 165 import org.mockito.Captor; 166 import org.mockito.InOrder; 167 import org.mockito.Mock; 168 import org.mockito.MockitoAnnotations; 169 import org.mockito.MockitoSession; 170 import org.mockito.quality.Strictness; 171 172 import java.io.ByteArrayOutputStream; 173 import java.io.FileDescriptor; 174 import java.io.PrintWriter; 175 import java.io.StringWriter; 176 import java.lang.reflect.Field; 177 import java.lang.reflect.InvocationTargetException; 178 import java.lang.reflect.Method; 179 import java.net.URL; 180 import java.nio.charset.StandardCharsets; 181 import java.util.ArrayList; 182 import java.util.Arrays; 183 import java.util.Collections; 184 import java.util.Random; 185 import java.util.Set; 186 import java.util.concurrent.CountDownLatch; 187 import java.util.function.Consumer; 188 189 /** 190 * Unit tests for {@link com.android.server.wifi.ClientModeImpl}. 191 */ 192 @SmallTest 193 public class ClientModeImplTest extends WifiBaseTest { 194 public static final String TAG = "ClientModeImplTest"; 195 196 private static final int MANAGED_PROFILE_UID = 1100000; 197 private static final int OTHER_USER_UID = 1200000; 198 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE = 199 (ActivityManager.isLowRamDeviceStatic() 200 ? ClientModeImpl.NUM_LOG_RECS_VERBOSE_LOW_MEMORY 201 : ClientModeImpl.NUM_LOG_RECS_VERBOSE); 202 private static final int FRAMEWORK_NETWORK_ID = 0; 203 private static final int PASSPOINT_NETWORK_ID = 1; 204 private static final int OTHER_NETWORK_ID = 47; 205 private static final int TEST_RSSI = -54; 206 private static final int TEST_NETWORK_ID = 54; 207 private static final int WPS_SUPPLICANT_NETWORK_ID = 5; 208 private static final int WPS_FRAMEWORK_NETWORK_ID = 10; 209 private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; 210 private static final String OP_PACKAGE_NAME = "com.xxx"; 211 private static final int TEST_UID = Process.SYSTEM_UID + 1000; 212 private static final MacAddress TEST_GLOBAL_MAC_ADDRESS = 213 MacAddress.fromString("10:22:34:56:78:92"); 214 private static final MacAddress TEST_LOCAL_MAC_ADDRESS = 215 MacAddress.fromString("2a:53:43:c3:56:21"); 216 private static final MacAddress TEST_DEFAULT_MAC_ADDRESS = 217 MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 218 219 // NetworkAgent creates threshold ranges with Integers 220 private static final int RSSI_THRESHOLD_MAX = -30; 221 private static final int RSSI_THRESHOLD_MIN = -76; 222 // Threshold breach callbacks are called with bytes 223 private static final byte RSSI_THRESHOLD_BREACH_MIN = -80; 224 private static final byte RSSI_THRESHOLD_BREACH_MAX = -20; 225 226 private static final int DATA_SUBID = 1; 227 private static final int CARRIER_ID_1 = 100; 228 229 private static final long TEST_BSSID = 0x112233445566L; 230 private static final int TEST_DELAY_IN_SECONDS = 300; 231 232 private static final int DEFINED_ERROR_CODE = 32764; 233 private static final String TEST_TERMS_AND_CONDITIONS_URL = 234 "https://policies.google.com/terms?hl=en-US"; 235 private static final String VENUE_URL = 236 "https://www.android.com/android-11/"; 237 238 private long mBinderToken; 239 private MockitoSession mSession; 240 private TestNetworkParams mTestNetworkParams = new TestNetworkParams(); 241 242 /** 243 * Helper class for setting the default parameters of the WifiConfiguration that gets used 244 * in connect(). 245 */ 246 class TestNetworkParams { 247 public boolean hasEverConnected = false; 248 } 249 mockWithInterfaces(Class<T> class1, Class<?>... interfaces)250 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 251 return mock(class1, withSettings().extraInterfaces(interfaces)); 252 } 253 enableDebugLogs()254 private void enableDebugLogs() { 255 mCmi.enableVerboseLogging(true); 256 } 257 getFrameworkFacade()258 private FrameworkFacade getFrameworkFacade() throws Exception { 259 FrameworkFacade facade = mock(FrameworkFacade.class); 260 261 doAnswer(new AnswerWithArguments() { 262 public void answer( 263 Context context, String ifname, IpClientCallbacks callback) { 264 mIpClientCallback = callback; 265 callback.onIpClientCreated(mIpClient); 266 } 267 }).when(facade).makeIpClient(any(), anyString(), any()); 268 269 return facade; 270 } 271 getContext()272 private Context getContext() throws Exception { 273 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 274 275 Context context = mock(Context.class); 276 when(context.getPackageManager()).thenReturn(mPackageManager); 277 278 MockContentResolver mockContentResolver = new MockContentResolver(); 279 mockContentResolver.addProvider(Settings.AUTHORITY, 280 new MockContentProvider(context) { 281 @Override 282 public Bundle call(String method, String arg, Bundle extras) { 283 return new Bundle(); 284 } 285 }); 286 when(context.getContentResolver()).thenReturn(mockContentResolver); 287 288 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager); 289 when(context.getSystemService(PowerManager.class)).thenReturn(mPowerManager); 290 when(mPowerManager.isInteractive()).thenReturn(true); 291 when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn( 292 mock(PowerManager.WakeLock.class)); 293 294 mAlarmManager = new TestAlarmManager(); 295 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 296 mAlarmManager.getAlarmManager()); 297 298 when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME); 299 300 when(context.getSystemService(ActivityManager.class)).thenReturn( 301 mock(ActivityManager.class)); 302 303 WifiP2pManager p2pm = mock(WifiP2pManager.class); 304 when(context.getSystemService(WifiP2pManager.class)).thenReturn(p2pm); 305 final CountDownLatch untilDone = new CountDownLatch(1); 306 mP2pThread = new HandlerThread("WifiP2pMockThread") { 307 @Override 308 protected void onLooperPrepared() { 309 untilDone.countDown(); 310 } 311 }; 312 mP2pThread.start(); 313 untilDone.await(); 314 Handler handler = new Handler(mP2pThread.getLooper()); 315 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 316 317 return context; 318 } 319 getMockResources()320 private MockResources getMockResources() { 321 MockResources resources = new MockResources(); 322 return resources; 323 } 324 getCurrentState()325 private IState getCurrentState() throws 326 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 327 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 328 method.setAccessible(true); 329 return (IState) method.invoke(mCmi); 330 } 331 getCmiHandlerThread(ClientModeImpl cmi)332 private static HandlerThread getCmiHandlerThread(ClientModeImpl cmi) throws 333 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 334 Field field = StateMachine.class.getDeclaredField("mSmThread"); 335 field.setAccessible(true); 336 return (HandlerThread) field.get(cmi); 337 } 338 stopLooper(final Looper looper)339 private static void stopLooper(final Looper looper) throws Exception { 340 new Handler(looper).post(new Runnable() { 341 @Override 342 public void run() { 343 looper.quitSafely(); 344 } 345 }); 346 } 347 dumpState()348 private void dumpState() { 349 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 350 PrintWriter writer = new PrintWriter(stream); 351 mCmi.dump(null, writer, null); 352 writer.flush(); 353 Log.d(TAG, "ClientModeImpl state -" + stream.toString()); 354 } 355 getGoogleGuestScanDetail(int rssi, String bssid, int freq)356 private static ScanDetail getGoogleGuestScanDetail(int rssi, String bssid, int freq) { 357 ScanResult.InformationElement[] ie = new ScanResult.InformationElement[1]; 358 ie[0] = ScanResults.generateSsidIe(TEST_SSID); 359 NetworkDetail nd = new NetworkDetail(TEST_BSSID_STR, ie, new ArrayList<String>(), sFreq); 360 ScanDetail detail = new ScanDetail(nd, TEST_WIFI_SSID, bssid, "", rssi, freq, 361 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 362 there older than scan start */ 363 ie, new ArrayList<String>(), ScanResults.generateIERawDatafromScanResultIE(ie)); 364 365 return detail; 366 } 367 getMockScanResults()368 private ArrayList<ScanDetail> getMockScanResults() { 369 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 370 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 371 372 list.add(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 373 return list; 374 } 375 injectDhcpSuccess(DhcpResultsParcelable dhcpResults)376 private void injectDhcpSuccess(DhcpResultsParcelable dhcpResults) { 377 mIpClientCallback.onNewDhcpResults(dhcpResults); 378 mIpClientCallback.onProvisioningSuccess(new LinkProperties()); 379 } 380 injectDhcpFailure()381 private void injectDhcpFailure() { 382 mIpClientCallback.onNewDhcpResults((DhcpResultsParcelable) null); 383 mIpClientCallback.onProvisioningFailure(new LinkProperties()); 384 } 385 386 static final String TEST_SSID = "\"GoogleGuest\""; 387 static final String SSID_NO_QUOTE = TEST_SSID.replace("\"", ""); 388 static final WifiSsid TEST_WIFI_SSID = WifiSsid.createFromAsciiEncoded(SSID_NO_QUOTE); 389 static final String TEST_SSID1 = "\"RandomSsid1\""; 390 static final String SSID_NO_QUOTE1 = TEST_SSID1.replace("\"", ""); 391 static final WifiSsid TEST_WIFI_SSID1 = WifiSsid.createFromAsciiEncoded(SSID_NO_QUOTE1); 392 static final String TEST_BSSID_STR = "01:02:03:04:05:06"; 393 static final String TEST_BSSID_STR1 = "02:01:04:03:06:05"; 394 static final int sFreq = 2437; 395 static final int sFreq1 = 5240; 396 static final String WIFI_IFACE_NAME = "mockWlan"; 397 static final String sFilsSsid = "FILS-AP"; 398 399 ClientModeImpl mCmi; 400 HandlerThread mWifiCoreThread; 401 HandlerThread mP2pThread; 402 HandlerThread mSyncThread; 403 TestAlarmManager mAlarmManager; 404 MockWifiMonitor mWifiMonitor; 405 TestLooper mLooper; 406 Context mContext; 407 MockResources mResources; 408 FrameworkFacade mFrameworkFacade; 409 IpClientCallbacks mIpClientCallback; 410 OsuProvider mOsuProvider; 411 WifiConfiguration mConnectedNetwork; 412 ExtendedWifiInfo mWifiInfo; 413 ConnectionCapabilities mConnectionCapabilities = new ConnectionCapabilities(); 414 415 @Mock WifiNetworkAgent mWifiNetworkAgent; 416 @Mock SupplicantStateTracker mSupplicantStateTracker; 417 @Mock WifiMetrics mWifiMetrics; 418 @Mock WifiInjector mWifiInjector; 419 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 420 @Mock WifiBlocklistMonitor mWifiBlocklistMonitor; 421 @Mock WifiConfigManager mWifiConfigManager; 422 @Mock WifiNative mWifiNative; 423 @Mock WifiScoreCard mWifiScoreCard; 424 @Mock PerNetwork mPerNetwork; 425 @Mock WifiScoreCard.NetworkConnectionStats mPerNetworkRecentStats; 426 @Mock WifiHealthMonitor mWifiHealthMonitor; 427 @Mock WifiTrafficPoller mWifiTrafficPoller; 428 @Mock WifiConnectivityManager mWifiConnectivityManager; 429 @Mock WifiStateTracker mWifiStateTracker; 430 @Mock PasspointManager mPasspointManager; 431 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 432 @Mock IIpClient mIpClient; 433 @Mock TelephonyManager mTelephonyManager; 434 @Mock TelephonyManager mDataTelephonyManager; 435 @Mock WrongPasswordNotifier mWrongPasswordNotifier; 436 @Mock Clock mClock; 437 @Mock ScanDetailCache mScanDetailCache; 438 @Mock WifiDiagnostics mWifiDiagnostics; 439 @Mock IProvisioningCallback mProvisioningCallback; 440 @Mock WakeupController mWakeupController; 441 @Mock WifiDataStall mWifiDataStall; 442 @Mock WifiNetworkFactory mWifiNetworkFactory; 443 @Mock UntrustedWifiNetworkFactory mUntrustedWifiNetworkFactory; 444 @Mock OemWifiNetworkFactory mOemWifiNetworkFactory; 445 @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; 446 @Mock LinkProbeManager mLinkProbeManager; 447 @Mock PackageManager mPackageManager; 448 @Mock WifiLockManager mWifiLockManager; 449 @Mock AsyncChannel mNullAsyncChannel; 450 @Mock BatteryStatsManager mBatteryStatsManager; 451 @Mock MboOceController mMboOceController; 452 @Mock ConnectionFailureNotifier mConnectionFailureNotifier; 453 @Mock EapFailureNotifier mEapFailureNotifier; 454 @Mock SimRequiredNotifier mSimRequiredNotifier; 455 @Mock ThroughputPredictor mThroughputPredictor; 456 @Mock ScanRequestProxy mScanRequestProxy; 457 @Mock DeviceConfigFacade mDeviceConfigFacade; 458 @Mock Network mNetwork; 459 @Mock ConcreteClientModeManager mClientModeManager; 460 @Mock WifiScoreReport mWifiScoreReport; 461 @Mock PowerManager mPowerManager; 462 @Mock WifiP2pConnection mWifiP2pConnection; 463 @Mock WifiGlobals mWifiGlobals; 464 @Mock LinkProbeCallback mLinkProbeCallback; 465 @Mock ClientModeImplMonitor mCmiMonitor; 466 @Mock ClientModeManagerBroadcastQueue mBroadcastQueue; 467 @Mock WifiNetworkSelector mWifiNetworkSelector; 468 @Mock ActiveModeWarden mActiveModeWarden; 469 @Mock ClientModeManager mPrimaryClientModeManager; 470 @Mock WifiSettingsConfigStore mSettingsConfigStore; 471 @Mock Uri mMockUri; 472 @Mock WifiCarrierInfoManager mWifiCarrierInfoManager; 473 474 @Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor; 475 @Captor ArgumentCaptor<WifiNetworkAgent.Callback> mWifiNetworkAgentCallbackCaptor; 476 @Captor ArgumentCaptor<WifiCarrierInfoManager.OnCarrierOffloadDisabledListener> 477 mOffloadDisabledListenerArgumentCaptor = ArgumentCaptor.forClass( 478 WifiCarrierInfoManager.OnCarrierOffloadDisabledListener.class); 479 @Captor ArgumentCaptor<BroadcastReceiver> mScreenStateBroadcastReceiverCaptor; 480 setUpWifiNative()481 private void setUpWifiNative() throws Exception { 482 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn( 483 TEST_GLOBAL_MAC_ADDRESS); 484 doAnswer(new AnswerWithArguments() { 485 public void answer(WifiSettingsConfigStore.Key<String> key, Object macAddress) { 486 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)) 487 .thenReturn((String) macAddress); 488 } 489 }).when(mSettingsConfigStore).put(eq(WIFI_STA_FACTORY_MAC_ADDRESS), any(String.class)); 490 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 491 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 492 ConnectionCapabilities cap = new ConnectionCapabilities(); 493 cap.wifiStandard = ScanResult.WIFI_STANDARD_11AC; 494 when(mWifiNative.getConnectionCapabilities(WIFI_IFACE_NAME)) 495 .thenReturn(mConnectionCapabilities); 496 when(mWifiNative.setStaMacAddress(eq(WIFI_IFACE_NAME), anyObject())) 497 .then(new AnswerWithArguments() { 498 public boolean answer(String iface, MacAddress mac) { 499 when(mWifiNative.getMacAddress(iface)).thenReturn(mac.toString()); 500 return true; 501 } 502 }); 503 when(mWifiNative.connectToNetwork(any(), any())).thenReturn(true); 504 } 505 506 /** Reset verify() counters on WifiNative, and restore when() mocks on mWifiNative */ resetWifiNative()507 private void resetWifiNative() throws Exception { 508 reset(mWifiNative); 509 setUpWifiNative(); 510 } 511 512 @Before setUp()513 public void setUp() throws Exception { 514 Log.d(TAG, "Setting up ..."); 515 516 // Ensure looper exists 517 mLooper = new TestLooper(); 518 519 MockitoAnnotations.initMocks(this); 520 521 /** uncomment this to enable logs from ClientModeImpls */ 522 // enableDebugLogs(); 523 mWifiMonitor = spy(new MockWifiMonitor()); 524 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 525 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 526 .thenReturn(Pair.create(Process.INVALID_UID, "")); 527 setUpWifiNative(); 528 doAnswer(new AnswerWithArguments() { 529 public MacAddress answer( 530 WifiConfiguration config) { 531 return config.getRandomizedMacAddress(); 532 } 533 }).when(mWifiConfigManager).getRandomizedMacAndUpdateIfNeeded(any()); 534 535 mTestNetworkParams = new TestNetworkParams(); 536 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 537 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 538 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 539 540 mFrameworkFacade = getFrameworkFacade(); 541 mContext = getContext(); 542 mWifiInfo = new ExtendedWifiInfo(mWifiGlobals, WIFI_IFACE_NAME); 543 544 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true); 545 mResources = getMockResources(); 546 mResources.setIntArray(R.array.config_wifiRssiLevelThresholds, 547 RssiUtilTest.RSSI_THRESHOLDS); 548 mResources.setInteger(R.integer.config_wifiLinkBandwidthUpdateThresholdPercent, 25); 549 mResources.setInteger(R.integer.config_wifiClientModeImplNumLogRecs, 100); 550 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 551 when(mContext.getResources()).thenReturn(mResources); 552 553 when(mWifiGlobals.getPollRssiIntervalMillis()).thenReturn(3000); 554 when(mWifiGlobals.getIpReachabilityDisconnectEnabled()).thenReturn(true); 555 556 when(mFrameworkFacade.getIntegerSetting(mContext, 557 Settings.Global.WIFI_FREQUENCY_BAND, 558 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 559 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 560 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 561 doAnswer(inv -> { 562 mIpClientCallback.onQuit(); 563 return null; 564 }).when(mIpClient).shutdown(); 565 when(mWifiNetworkAgent.getNetwork()).thenReturn(mNetwork); 566 567 // static mocking 568 mSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT) 569 .mockStatic(WifiInjector.class, withSettings().lenient()) 570 .spyStatic(MacAddress.class) 571 .startMocking(); 572 when(WifiInjector.getInstance()).thenReturn(mWifiInjector); 573 574 when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden); 575 when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager); 576 when(mPrimaryClientModeManager.getSupportedFeatures()).thenReturn( 577 WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE); 578 when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals); 579 when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true); 580 when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true); 581 when(mWifiGlobals.getClientModeImplNumLogRecs()).thenReturn(100); 582 when(mWifiInjector.makeWifiNetworkAgent(any(), any(), any(), any(), any())) 583 .thenAnswer(new AnswerWithArguments() { 584 public WifiNetworkAgent answer( 585 @NonNull NetworkCapabilities nc, 586 @NonNull LinkProperties linkProperties, 587 @NonNull NetworkAgentConfig naConfig, 588 @Nullable NetworkProvider provider, 589 @NonNull WifiNetworkAgent.Callback callback) { 590 when(mWifiNetworkAgent.getCallback()).thenReturn(callback); 591 return mWifiNetworkAgent; 592 } 593 }); 594 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 595 596 initializeCmi(); 597 // Retrieve factory MAC address on first bootup. 598 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 599 600 mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 601 mConnectedNetwork = spy(WifiConfigurationTestUtil.createOpenNetwork()); 602 when(mNullAsyncChannel.sendMessageSynchronously(any())).thenReturn(null); 603 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null)); 604 when(mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()).thenReturn(true); 605 when(mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled()).thenReturn(true); 606 when(mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()).thenReturn(true); 607 when(mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()).thenReturn( 608 DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS); 609 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 610 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 611 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 612 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 613 when(mPerNetwork.getRecentStats()).thenReturn(mPerNetworkRecentStats); 614 when(mWifiScoreCard.lookupNetwork(any())).thenReturn(mPerNetwork); 615 when(mThroughputPredictor.predictMaxTxThroughput(any())).thenReturn(90); 616 when(mThroughputPredictor.predictMaxRxThroughput(any())).thenReturn(80); 617 618 doAnswer(new AnswerWithArguments() { 619 public void answer(boolean shouldReduceNetworkScore) { 620 mCmi.setShouldReduceNetworkScore(shouldReduceNetworkScore); 621 } 622 }).when(mClientModeManager).setShouldReduceNetworkScore(anyBoolean()); 623 doAnswer(new AnswerWithArguments() { 624 public void answer(ClientModeManager manager, QueuedBroadcast broadcast) { 625 broadcast.send(); 626 } 627 }).when(mBroadcastQueue).queueOrSendBroadcast(any(), any()); 628 } 629 registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger, Handler wrappedHandler)630 private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger, 631 Handler wrappedHandler) { 632 final AsyncChannel channel = new AsyncChannel(); 633 Handler handler = new Handler(mLooper.getLooper()) { 634 @Override 635 public void handleMessage(Message msg) { 636 switch (msg.what) { 637 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 638 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 639 consumer.accept(channel); 640 } else { 641 Log.d(TAG, "Failed to connect Command channel " + this); 642 } 643 break; 644 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 645 Log.d(TAG, "Command channel disconnected " + this); 646 break; 647 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 648 Log.d(TAG, "Command channel fully connected " + this); 649 break; 650 default: 651 if (wrappedHandler != null) { 652 wrappedHandler.handleMessage(msg); 653 } 654 break; 655 } 656 } 657 }; 658 659 channel.connect(mContext, handler, messenger); 660 mLooper.dispatchAll(); 661 } 662 registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger)663 private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger) { 664 registerAsyncChannel(consumer, messenger, null /* wrappedHandler */); 665 } 666 initializeCmi()667 private void initializeCmi() throws Exception { 668 mCmi = new ClientModeImpl(mContext, mWifiMetrics, mClock, mWifiScoreCard, mWifiStateTracker, 669 mWifiPermissionsUtil, mWifiConfigManager, mPasspointManager, 670 mWifiMonitor, mWifiDiagnostics, mWifiDataStall, 671 new ScoringParams(), new WifiThreadRunner(new Handler(mLooper.getLooper())), 672 mWifiNetworkSuggestionsManager, mWifiHealthMonitor, mThroughputPredictor, 673 mDeviceConfigFacade, mScanRequestProxy, mWifiInfo, mWifiConnectivityManager, 674 mWifiBlocklistMonitor, mConnectionFailureNotifier, 675 WifiInjector.REGULAR_NETWORK_CAPABILITIES_FILTER, mWifiNetworkFactory, 676 mUntrustedWifiNetworkFactory, mOemWifiNetworkFactory, 677 mWifiLastResortWatchdog, mWakeupController, 678 mWifiLockManager, mFrameworkFacade, mLooper.getLooper(), 679 mWifiNative, mWrongPasswordNotifier, mWifiTrafficPoller, mLinkProbeManager, 680 1, mBatteryStatsManager, mSupplicantStateTracker, mMboOceController, 681 mWifiCarrierInfoManager, mEapFailureNotifier, mSimRequiredNotifier, 682 mWifiScoreReport, mWifiP2pConnection, mWifiGlobals, 683 WIFI_IFACE_NAME, mClientModeManager, mCmiMonitor, mBroadcastQueue, 684 mWifiNetworkSelector, mTelephonyManager, mWifiInjector, mSettingsConfigStore, 685 false); 686 687 mWifiCoreThread = getCmiHandlerThread(mCmi); 688 689 mBinderToken = Binder.clearCallingIdentity(); 690 691 verify(mWifiConfigManager, atLeastOnce()).addOnNetworkUpdateListener( 692 mConfigUpdateListenerCaptor.capture()); 693 assertNotNull(mConfigUpdateListenerCaptor.getValue()); 694 695 verify(mWifiCarrierInfoManager, atLeastOnce()).addOnCarrierOffloadDisabledListener( 696 mOffloadDisabledListenerArgumentCaptor.capture()); 697 assertNotNull(mOffloadDisabledListenerArgumentCaptor.getValue()); 698 699 mCmi.enableVerboseLogging(true); 700 mLooper.dispatchAll(); 701 702 verify(mWifiLastResortWatchdog, atLeastOnce()).clearAllFailureCounts(); 703 assertEquals("DisconnectedState", getCurrentState().getName()); 704 705 verify(mContext, atLeastOnce()).registerReceiver( 706 mScreenStateBroadcastReceiverCaptor.capture(), 707 argThat(f -> f.hasAction(ACTION_SCREEN_ON) && f.hasAction(ACTION_SCREEN_OFF))); 708 } 709 710 @After cleanUp()711 public void cleanUp() throws Exception { 712 Binder.restoreCallingIdentity(mBinderToken); 713 714 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 715 if (mWifiCoreThread != null) stopLooper(mWifiCoreThread.getLooper()); 716 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 717 718 mWifiCoreThread = null; 719 mP2pThread = null; 720 mSyncThread = null; 721 mCmi = null; 722 if (mSession != null) { 723 mSession.finishMocking(); 724 } 725 } 726 727 /** 728 * Test that mode changes accurately reflect the value for isWifiEnabled. 729 */ 730 @Test checkIsWifiEnabledForModeChanges()731 public void checkIsWifiEnabledForModeChanges() throws Exception { 732 // now disable client mode and verify the reported wifi state 733 mCmi.stop(); 734 mLooper.dispatchAll(); 735 verify(mContext, never()) 736 .sendStickyBroadcastAsUser(argThat(new WifiEnablingStateIntentMatcher()), any()); 737 } 738 739 private static class WifiEnablingStateIntentMatcher implements ArgumentMatcher<Intent> { 740 @Override matches(Intent intent)741 public boolean matches(Intent intent) { 742 return WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction()) 743 && WifiManager.WIFI_STATE_ENABLING 744 == intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 745 WifiManager.WIFI_STATE_DISABLED); 746 } 747 } 748 749 private class NetworkStateChangedIntentMatcher implements ArgumentMatcher<Intent> { 750 private final NetworkInfo.DetailedState mState; NetworkStateChangedIntentMatcher(NetworkInfo.DetailedState state)751 NetworkStateChangedIntentMatcher(NetworkInfo.DetailedState state) { 752 mState = state; 753 } 754 @Override matches(Intent intent)755 public boolean matches(Intent intent) { 756 if (WifiManager.NETWORK_STATE_CHANGED_ACTION != intent.getAction()) { 757 // not the correct type 758 return false; 759 } 760 NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 761 return networkInfo.getDetailedState() == mState; 762 } 763 } 764 canSaveNetworkConfig()765 private void canSaveNetworkConfig() throws Exception { 766 IActionListener connectActionListener = mock(IActionListener.class); 767 mCmi.saveNetwork( 768 new NetworkUpdateResult(TEST_NETWORK_ID), 769 new ActionListenerWrapper(connectActionListener), 770 Binder.getCallingUid()); 771 mLooper.dispatchAll(); 772 verify(connectActionListener).onSuccess(); 773 } 774 775 /** 776 * Verifies that configs can be saved when in client mode. 777 */ 778 @Test canSaveNetworkConfigInClientMode()779 public void canSaveNetworkConfigInClientMode() throws Exception { 780 canSaveNetworkConfig(); 781 } 782 createTestNetwork(boolean isHidden)783 private WifiConfiguration createTestNetwork(boolean isHidden) { 784 WifiConfiguration config = new WifiConfiguration(); 785 config.networkId = FRAMEWORK_NETWORK_ID; 786 config.SSID = TEST_SSID; 787 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 788 config.hiddenSSID = isHidden; 789 return config; 790 } 791 initializeMocksForAddedNetwork(boolean isHidden)792 private void initializeMocksForAddedNetwork(boolean isHidden) throws Exception { 793 WifiConfiguration config = createTestNetwork(isHidden); 794 795 when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(config)); 796 when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config); 797 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 798 } 799 initializeAndAddNetworkAndVerifySuccess()800 private void initializeAndAddNetworkAndVerifySuccess() throws Exception { 801 initializeAndAddNetworkAndVerifySuccess(false); 802 } 803 initializeAndAddNetworkAndVerifySuccess(boolean isHidden)804 private void initializeAndAddNetworkAndVerifySuccess(boolean isHidden) throws Exception { 805 initializeMocksForAddedNetwork(isHidden); 806 } 807 setupAndStartConnectSequence(WifiConfiguration config)808 private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception { 809 when(mWifiConfigManager.getConfiguredNetwork(eq(config.networkId))) 810 .thenReturn(config); 811 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking( 812 eq(config.networkId))).thenReturn(config); 813 814 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 815 816 IActionListener connectActionListener = mock(IActionListener.class); 817 mCmi.connectNetwork( 818 new NetworkUpdateResult(config.networkId), 819 new ActionListenerWrapper(connectActionListener), 820 Binder.getCallingUid()); 821 mLooper.dispatchAll(); 822 verify(connectActionListener).onSuccess(); 823 } 824 validateSuccessfulConnectSequence(WifiConfiguration config)825 private void validateSuccessfulConnectSequence(WifiConfiguration config) { 826 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 827 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 828 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 829 verify(mCmiMonitor).onConnectionStart(mClientModeManager); 830 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 831 } 832 validateFailureConnectSequence(WifiConfiguration config)833 private void validateFailureConnectSequence(WifiConfiguration config) { 834 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 835 verify(mWifiConfigManager, never()) 836 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 837 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 838 } 839 840 /** 841 * Tests the network connection initiation sequence with the default network request pending 842 * from WifiNetworkFactory. 843 * This simulates the connect sequence using the public 844 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 845 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 846 */ 847 @Test triggerConnect()848 public void triggerConnect() throws Exception { 849 WifiConfiguration config = mConnectedNetwork; 850 config.networkId = FRAMEWORK_NETWORK_ID; 851 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 852 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 853 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 854 assertEquals(null, config.getNetworkSelectionStatus().getCandidateSecurityParams()); 855 setupAndStartConnectSequence(config); 856 validateSuccessfulConnectSequence(config); 857 assertEquals(config.getSecurityParamsList().stream() 858 .filter(WifiConfigurationUtil::isSecurityParamsValid) 859 .findFirst().orElse(null), 860 config.getNetworkSelectionStatus().getCandidateSecurityParams()); 861 } 862 863 /** 864 * Tests the network connection initiation sequence with the default network request pending 865 * from WifiNetworkFactory. 866 * This simulates the connect sequence using the public 867 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 868 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 869 */ 870 @Test triggerConnectFromNonSettingsApp()871 public void triggerConnectFromNonSettingsApp() throws Exception { 872 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 873 config.networkId = FRAMEWORK_NETWORK_ID; 874 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(Process.myUid())) 875 .thenReturn(false); 876 setupAndStartConnectSequence(config); 877 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 878 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 879 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 880 } 881 882 /** 883 * Tests the network connection initiation sequence with no network request pending from 884 * from WifiNetworkFactory. 885 * This simulates the connect sequence using the public 886 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 887 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 888 */ 889 @Test triggerConnectWithNoNetworkRequest()890 public void triggerConnectWithNoNetworkRequest() throws Exception { 891 // Remove the network requests. 892 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 893 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 894 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 895 896 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 897 config.networkId = FRAMEWORK_NETWORK_ID; 898 setupAndStartConnectSequence(config); 899 validateFailureConnectSequence(config); 900 } 901 902 /** 903 * Tests the entire successful network connection flow. 904 */ 905 @Test testConnect()906 public void testConnect() throws Exception { 907 connect(null); 908 } 909 connect()910 private void connect() throws Exception { 911 connect(null); 912 } 913 914 /** 915 * Simulate a connect 916 * 917 * @param wnmDataForTermsAndConditions Use null unless it is required to simulate a terms and 918 * conditions acceptance notification from Passpoint 919 * @throws Exception 920 */ connect(WnmData wnmDataForTermsAndConditions)921 private void connect(WnmData wnmDataForTermsAndConditions) throws Exception { 922 assertNull(mCmi.getConnectingWifiConfiguration()); 923 assertNull(mCmi.getConnectedWifiConfiguration()); 924 925 triggerConnect(); 926 927 assertNotNull(mCmi.getConnectingWifiConfiguration()); 928 assertNull(mCmi.getConnectedWifiConfiguration()); 929 930 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 931 config.carrierId = CARRIER_ID_1; 932 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 933 .thenReturn(mScanDetailCache); 934 935 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 936 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 937 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 938 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 939 ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(sFilsSsid), 940 sFilsSsid, TEST_BSSID_STR, 1245, 0, "", -78, 2412, 1025, 22, 33, 20, 0, 0, true); 941 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 942 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 943 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 944 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 945 946 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 947 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 948 SupplicantState.ASSOCIATED)); 949 mLooper.dispatchAll(); 950 951 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 952 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 953 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 954 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 955 mLooper.dispatchAll(); 956 957 verify(mWifiMetrics).noteFirstL2ConnectionAfterBoot(true); 958 959 // L2 connected, but not L3 connected yet. So, still "Connecting"... 960 assertNotNull(mCmi.getConnectingWifiConfiguration()); 961 assertNull(mCmi.getConnectedWifiConfiguration()); 962 963 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 964 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 965 SupplicantState.COMPLETED)); 966 mLooper.dispatchAll(); 967 968 assertEquals("L3ProvisioningState", getCurrentState().getName()); 969 verify(mContext).sendStickyBroadcastAsUser( 970 argThat(new NetworkStateChangedIntentMatcher(CONNECTING)), any()); 971 verify(mContext).sendStickyBroadcastAsUser( 972 argThat(new NetworkStateChangedIntentMatcher(OBTAINING_IPADDR)), any()); 973 974 if (wnmDataForTermsAndConditions != null) { 975 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 976 0, 0, wnmDataForTermsAndConditions); 977 mLooper.dispatchAll(); 978 } 979 980 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 981 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 982 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 983 dhcpResults.baseConfiguration.ipAddress = 984 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 985 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 986 dhcpResults.leaseDuration = 3600; 987 988 injectDhcpSuccess(dhcpResults); 989 mLooper.dispatchAll(); 990 991 assertNull(mCmi.getConnectingWifiConfiguration()); 992 assertNotNull(mCmi.getConnectedWifiConfiguration()); 993 994 // Verify WifiMetrics logging for metered metrics based on DHCP results 995 verify(mWifiMetrics).addMeteredStat(any(), anyBoolean()); 996 WifiInfo wifiInfo = mWifiInfo; 997 assertNotNull(wifiInfo); 998 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 999 assertEquals(sFreq, wifiInfo.getFrequency()); 1000 assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid()); 1001 assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, wifiInfo.getMacAddress()); 1002 assertEquals(mConnectedNetwork.getDefaultSecurityParams().getSecurityType(), 1003 mWifiInfo.getCurrentSecurityType()); 1004 if (wifiInfo.isPasspointAp()) { 1005 assertEquals(wifiInfo.getPasspointProviderFriendlyName(), 1006 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1007 } else { 1008 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1009 } 1010 assertEquals(Arrays.asList(scanResult.informationElements), 1011 wifiInfo.getInformationElements()); 1012 expectRegisterNetworkAgent((na) -> { 1013 if (!mConnectedNetwork.carrierMerged) { 1014 assertNull(na.subscriberId); 1015 } 1016 }, (nc) -> { 1017 if (SdkLevel.isAtLeastS()) { 1018 WifiInfo wifiInfoFromTi = (WifiInfo) nc.getTransportInfo(); 1019 assertEquals(TEST_BSSID_STR, wifiInfoFromTi.getBSSID()); 1020 assertEquals(sFreq, wifiInfoFromTi.getFrequency()); 1021 assertEquals(TEST_WIFI_SSID, wifiInfoFromTi.getWifiSsid()); 1022 if (wifiInfo.isPasspointAp()) { 1023 assertEquals(wifiInfoFromTi.getPasspointProviderFriendlyName(), 1024 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1025 } else { 1026 assertNull(wifiInfoFromTi.getPasspointProviderFriendlyName()); 1027 } 1028 } 1029 }); 1030 // Ensure the connection stats for the network is updated. 1031 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 1032 anyBoolean(), anyInt()); 1033 verify(mWifiConfigManager).updateRandomizedMacExpireTime(any(), anyLong()); 1034 verify(mContext).sendStickyBroadcastAsUser( 1035 argThat(new NetworkStateChangedIntentMatcher(CONNECTED)), any()); 1036 1037 // Anonymous Identity is not set. 1038 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1039 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.CONNECTED); 1040 assertEquals("L3ConnectedState", getCurrentState().getName()); 1041 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionSuccess(); 1042 verify(mWifiLockManager).updateWifiClientConnected(mClientModeManager, true); 1043 verify(mWifiNative).getConnectionCapabilities(any()); 1044 verify(mThroughputPredictor).predictMaxTxThroughput(any()); 1045 verify(mWifiMetrics).setConnectionMaxSupportedLinkSpeedMbps(WIFI_IFACE_NAME, 90, 80); 1046 assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); 1047 verify(mWifiMetrics).noteFirstL3ConnectionAfterBoot(true); 1048 } 1049 setupEapSimConnection()1050 private void setupEapSimConnection() throws Exception { 1051 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1052 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1053 mConnectedNetwork.carrierId = CARRIER_ID_1; 1054 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1055 .thenReturn(DATA_SUBID); 1056 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1057 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1058 1059 triggerConnect(); 1060 1061 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1062 .thenReturn(mScanDetailCache); 1063 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1064 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1065 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1066 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1067 1068 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1069 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1070 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1071 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1072 mLooper.dispatchAll(); 1073 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1074 } 1075 1076 /** 1077 * Test when a roam occurs simultaneously with another connection attempt. 1078 * The roam's NETWORK_CONNECTION_EVENT should be ignored, only the new network's 1079 * NETWORK_CONNECTION_EVENT should be acted upon. 1080 */ 1081 @Test roamRaceWithConnect()1082 public void roamRaceWithConnect() throws Exception { 1083 connect(); 1084 1085 initializeAndAddNetworkAndVerifySuccess(); 1086 1087 // connect to new network 1088 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1089 config.networkId = OTHER_NETWORK_ID; 1090 setupAndStartConnectSequence(config); 1091 1092 // in L2ConnectingState 1093 assertEquals("L2ConnectingState", getCurrentState().getName()); 1094 1095 // send NETWORK_CONNECTION_EVENT for previous network ID 1096 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1097 new NetworkConnectionEventInfo( 1098 FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 1099 mLooper.dispatchAll(); 1100 1101 // should ignore it, stay in L2ConnectingState 1102 assertEquals("L2ConnectingState", getCurrentState().getName()); 1103 1104 // send expected new network SSID 1105 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1106 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(config.SSID))); 1107 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1108 new NetworkConnectionEventInfo( 1109 OTHER_NETWORK_ID, wifiSsid, TEST_BSSID_STR1, false)); 1110 mLooper.dispatchAll(); 1111 1112 // then move to next state 1113 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1114 } 1115 1116 /** 1117 * When the SIM card was removed, if the current wifi connection is not using it, the connection 1118 * should be kept. 1119 */ 1120 @Test testResetSimWhenNonConnectedSimRemoved()1121 public void testResetSimWhenNonConnectedSimRemoved() throws Exception { 1122 setupEapSimConnection(); 1123 doReturn(true).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1124 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1125 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1126 mLooper.dispatchAll(); 1127 1128 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); 1129 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1130 } 1131 1132 /** 1133 * When the SIM card was removed, if the current wifi connection is using it, the connection 1134 * should be disconnected, otherwise, the connection shouldn't be impacted. 1135 */ 1136 @Test testResetSimWhenConnectedSimRemoved()1137 public void testResetSimWhenConnectedSimRemoved() throws Exception { 1138 setupEapSimConnection(); 1139 doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1140 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1141 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1142 mLooper.dispatchAll(); 1143 1144 verify(mSimRequiredNotifier).showSimRequiredNotification(any(), any()); 1145 verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME); 1146 } 1147 1148 /** 1149 * When the SIM card was removed, if the current wifi connection is using it, the connection 1150 * should be disconnected, otherwise, the connection shouldn't be impacted. 1151 */ 1152 @Test testResetSimWhenConnectedSimRemovedAfterNetworkRemoval()1153 public void testResetSimWhenConnectedSimRemovedAfterNetworkRemoval() throws Exception { 1154 setupEapSimConnection(); 1155 doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1156 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 1157 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1158 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1159 mLooper.dispatchAll(); 1160 1161 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); 1162 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1163 } 1164 1165 /** 1166 * When the default data SIM is changed, if the current wifi connection is carrier wifi, 1167 * the connection should be disconnected. 1168 */ 1169 @Test testResetSimWhenDefaultDataSimChanged()1170 public void testResetSimWhenDefaultDataSimChanged() throws Exception { 1171 setupEapSimConnection(); 1172 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1173 ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); 1174 mLooper.dispatchAll(); 1175 1176 verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME); 1177 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 1178 eq(StaEvent.DISCONNECT_RESET_SIM_NETWORKS)); 1179 } 1180 1181 /** 1182 * Tests anonymous identity is set again whenever a connection is established for the carrier 1183 * that supports encrypted IMSI and anonymous identity and no real pseudonym was provided. 1184 */ 1185 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym()1186 public void testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym() throws Exception { 1187 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1188 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1189 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1190 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1191 1192 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1193 .thenReturn(DATA_SUBID); 1194 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1195 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1196 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1197 .thenReturn(expectedAnonymousIdentity); 1198 1199 // Initial value should be "not set" 1200 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1201 1202 triggerConnect(); 1203 1204 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1205 assertEquals(expectedAnonymousIdentity, 1206 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1207 1208 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1209 .thenReturn(mScanDetailCache); 1210 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1211 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1212 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1213 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1214 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1215 .thenReturn(expectedAnonymousIdentity); 1216 1217 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1218 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1219 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1220 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1221 mLooper.dispatchAll(); 1222 1223 verify(mWifiNative).getEapAnonymousIdentity(any()); 1224 1225 // Post connection value should remain "not set" 1226 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1227 // verify that WifiConfigManager#addOrUpdateNetwork() was called to clear any previously 1228 // stored pseudonym. i.e. to enable Encrypted IMSI for 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 } 1234 1235 /** 1236 * Tests anonymous identity is set again whenever a connection is established for the carrier 1237 * that supports encrypted IMSI and anonymous identity but real pseudonym was provided for 1238 * subsequent connections. 1239 */ 1240 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym()1241 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym() 1242 throws Exception { 1243 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1244 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1245 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1246 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1247 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 1248 1249 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1250 .thenReturn(DATA_SUBID); 1251 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1252 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1253 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1254 .thenReturn(expectedAnonymousIdentity); 1255 1256 triggerConnect(); 1257 1258 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1259 assertEquals(expectedAnonymousIdentity, 1260 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1261 1262 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1263 .thenReturn(mScanDetailCache); 1264 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1265 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1266 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1267 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1268 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1269 .thenReturn(pseudonym); 1270 1271 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1272 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1273 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1274 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1275 mLooper.dispatchAll(); 1276 1277 verify(mWifiNative).getEapAnonymousIdentity(any()); 1278 assertEquals(pseudonym, 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 } 1288 1289 /** 1290 * Tests anonymous identity is set again whenever a connection is established for the carrier 1291 * that supports encrypted IMSI and anonymous identity but real but not decorated pseudonym was 1292 * provided for subsequent connections. 1293 */ 1294 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym()1295 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym() 1296 throws Exception { 1297 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1298 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1299 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1300 String pseudonym = "83bcca9384fca"; 1301 String realm = "wlan.mnc456.mcc123.3gppnetwork.org"; 1302 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1303 1304 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1305 .thenReturn(DATA_SUBID); 1306 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1307 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1308 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1309 .thenReturn(expectedAnonymousIdentity); 1310 doAnswer(invocation -> { return invocation.getArgument(1) + "@" + realm; }) 1311 .when(mWifiCarrierInfoManager).decoratePseudonymWith3GppRealm(any(), anyString()); 1312 triggerConnect(); 1313 1314 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1315 assertEquals(expectedAnonymousIdentity, 1316 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1317 1318 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1319 .thenReturn(mScanDetailCache); 1320 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1321 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1322 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1323 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1324 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1325 .thenReturn(pseudonym); 1326 1327 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1328 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1329 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1330 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1331 mLooper.dispatchAll(); 1332 1333 verify(mWifiNative).getEapAnonymousIdentity(any()); 1334 assertEquals(pseudonym + "@" + realm, 1335 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1336 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1337 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1338 // pseudonym usage in all subsequent connections. 1339 // Note: This test will fail if future logic will have additional conditions that would 1340 // trigger "add or update network" operation. The test needs to be updated to account for 1341 // this change. 1342 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1343 } 1344 1345 /** 1346 * Tests anonymous identity will be set to suggestion network. 1347 */ 1348 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForSuggestion()1349 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForSuggestion() 1350 throws Exception { 1351 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1352 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1353 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1354 mConnectedNetwork.fromWifiNetworkSuggestion = true; 1355 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1356 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 1357 1358 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1359 .thenReturn(DATA_SUBID); 1360 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1361 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1362 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1363 .thenReturn(expectedAnonymousIdentity); 1364 1365 triggerConnect(); 1366 1367 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1368 assertEquals(expectedAnonymousIdentity, 1369 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1370 1371 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1372 .thenReturn(mScanDetailCache); 1373 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1374 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1375 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1376 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1377 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1378 .thenReturn(pseudonym); 1379 1380 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1381 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1382 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1383 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1384 mLooper.dispatchAll(); 1385 1386 verify(mWifiNative).getEapAnonymousIdentity(any()); 1387 assertEquals(pseudonym, 1388 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1389 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1390 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1391 // pseudonym usage in all subsequent connections. 1392 // Note: This test will fail if future logic will have additional conditions that would 1393 // trigger "add or update network" operation. The test needs to be updated to account for 1394 // this change. 1395 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1396 verify(mWifiNetworkSuggestionsManager).setAnonymousIdentity(any()); 1397 } 1398 1399 /** 1400 * Tests anonymous identity will be set to passpoint network. 1401 */ 1402 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForPasspoint()1403 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForPasspoint() 1404 throws Exception { 1405 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1406 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1407 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1408 mConnectedNetwork.FQDN = WifiConfigurationTestUtil.TEST_FQDN; 1409 mConnectedNetwork.providerFriendlyName = 1410 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 1411 mConnectedNetwork.setPasspointUniqueId(WifiConfigurationTestUtil.TEST_FQDN + "_" 1412 + WifiConfigurationTestUtil.TEST_FQDN.hashCode()); 1413 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1414 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 1415 1416 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1417 .thenReturn(DATA_SUBID); 1418 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1419 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1420 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1421 .thenReturn(expectedAnonymousIdentity); 1422 1423 triggerConnect(); 1424 1425 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1426 assertEquals(expectedAnonymousIdentity, 1427 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1428 1429 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1430 .thenReturn(mScanDetailCache); 1431 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1432 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1433 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1434 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1435 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1436 .thenReturn(pseudonym); 1437 1438 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 1439 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1440 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1441 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 1442 mLooper.dispatchAll(); 1443 1444 verify(mWifiNative).getEapAnonymousIdentity(any()); 1445 assertEquals(pseudonym, 1446 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1447 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1448 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1449 // pseudonym usage in all subsequent connections. 1450 // Note: This test will fail if future logic will have additional conditions that would 1451 // trigger "add or update network" operation. The test needs to be updated to account for 1452 // this change. 1453 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1454 verify(mPasspointManager).setAnonymousIdentity(any()); 1455 } 1456 /** 1457 * Tests the Passpoint information is set in WifiInfo for Passpoint AP connection. 1458 */ 1459 @Test connectPasspointAp()1460 public void connectPasspointAp() throws Exception { 1461 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 1462 config.SSID = TEST_WIFI_SSID.toString(); 1463 config.BSSID = TEST_BSSID_STR; 1464 config.networkId = FRAMEWORK_NETWORK_ID; 1465 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1466 setupAndStartConnectSequence(config); 1467 validateSuccessfulConnectSequence(config); 1468 1469 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1470 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1471 SupplicantState.ASSOCIATING)); 1472 mLooper.dispatchAll(); 1473 1474 WifiInfo wifiInfo = mWifiInfo; 1475 assertNotNull(wifiInfo); 1476 assertEquals(WifiConfigurationTestUtil.TEST_FQDN, wifiInfo.getPasspointFqdn()); 1477 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 1478 wifiInfo.getPasspointProviderFriendlyName()); 1479 } 1480 1481 /** 1482 * Tests that Passpoint fields in WifiInfo are reset when connecting to a non-Passpoint network 1483 * during DisconnectedState. 1484 * @throws Exception 1485 */ 1486 @Test testResetWifiInfoPasspointFields()1487 public void testResetWifiInfoPasspointFields() throws Exception { 1488 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 1489 config.SSID = TEST_WIFI_SSID.toString(); 1490 config.BSSID = TEST_BSSID_STR; 1491 config.networkId = PASSPOINT_NETWORK_ID; 1492 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1493 setupAndStartConnectSequence(config); 1494 validateSuccessfulConnectSequence(config); 1495 1496 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1497 new StateChangeResult(PASSPOINT_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1498 SupplicantState.ASSOCIATING)); 1499 mLooper.dispatchAll(); 1500 1501 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1502 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1503 SupplicantState.ASSOCIATING)); 1504 mLooper.dispatchAll(); 1505 1506 WifiInfo wifiInfo = mWifiInfo; 1507 assertNotNull(wifiInfo); 1508 assertNull(wifiInfo.getPasspointFqdn()); 1509 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1510 } 1511 1512 /** 1513 * Tests the OSU information is set in WifiInfo for OSU AP connection. 1514 */ 1515 @Test connectOsuAp()1516 public void connectOsuAp() throws Exception { 1517 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 1518 osuConfig.SSID = TEST_WIFI_SSID.toString(); 1519 osuConfig.BSSID = TEST_BSSID_STR; 1520 osuConfig.osu = true; 1521 osuConfig.networkId = FRAMEWORK_NETWORK_ID; 1522 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 1523 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1524 setupAndStartConnectSequence(osuConfig); 1525 validateSuccessfulConnectSequence(osuConfig); 1526 1527 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1528 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1529 SupplicantState.ASSOCIATING)); 1530 mLooper.dispatchAll(); 1531 1532 WifiInfo wifiInfo = mWifiInfo; 1533 assertNotNull(wifiInfo); 1534 assertTrue(wifiInfo.isOsuAp()); 1535 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 1536 wifiInfo.getPasspointProviderFriendlyName()); 1537 } 1538 1539 /** 1540 * Tests that OSU fields in WifiInfo are reset when connecting to a non-OSU network during 1541 * DisconnectedState. 1542 * @throws Exception 1543 */ 1544 @Test testResetWifiInfoOsuFields()1545 public void testResetWifiInfoOsuFields() throws Exception { 1546 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 1547 osuConfig.SSID = TEST_WIFI_SSID.toString(); 1548 osuConfig.BSSID = TEST_BSSID_STR; 1549 osuConfig.osu = true; 1550 osuConfig.networkId = PASSPOINT_NETWORK_ID; 1551 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 1552 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1553 setupAndStartConnectSequence(osuConfig); 1554 validateSuccessfulConnectSequence(osuConfig); 1555 1556 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1557 new StateChangeResult(PASSPOINT_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1558 SupplicantState.ASSOCIATING)); 1559 mLooper.dispatchAll(); 1560 1561 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1562 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 1563 SupplicantState.ASSOCIATING)); 1564 mLooper.dispatchAll(); 1565 1566 WifiInfo wifiInfo = mWifiInfo; 1567 assertNotNull(wifiInfo); 1568 assertFalse(wifiInfo.isOsuAp()); 1569 } 1570 1571 /** 1572 * Verify that WifiStateTracker is called if wifi is disabled while connected. 1573 */ 1574 @Test verifyWifiStateTrackerUpdatedWhenDisabled()1575 public void verifyWifiStateTrackerUpdatedWhenDisabled() throws Exception { 1576 connect(); 1577 1578 mCmi.stop(); 1579 mLooper.dispatchAll(); 1580 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.DISCONNECTED); 1581 } 1582 1583 /** 1584 * Tests the network connection initiation sequence with no network request pending from 1585 * from WifiNetworkFactory when we're already connected to a different network. 1586 * This simulates the connect sequence using the public 1587 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 1588 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1589 */ 1590 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnected()1591 public void triggerConnectWithNoNetworkRequestAndAlreadyConnected() throws Exception { 1592 // Simulate the first connection. 1593 connect(); 1594 1595 // Remove the network requests. 1596 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1597 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1598 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1599 1600 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1601 config.networkId = FRAMEWORK_NETWORK_ID + 1; 1602 setupAndStartConnectSequence(config); 1603 validateSuccessfulConnectSequence(config); 1604 verify(mWifiPermissionsUtil, atLeastOnce()).checkNetworkSettingsPermission(anyInt()); 1605 } 1606 1607 /** 1608 * Tests the network connection initiation sequence from a non-privileged app with no network 1609 * request pending from from WifiNetworkFactory when we're already connected to a different 1610 * network. 1611 * This simulates the connect sequence using the public 1612 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 1613 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1614 */ 1615 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp()1616 public void triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp() 1617 throws Exception { 1618 // Simulate the first connection. 1619 connect(); 1620 1621 // Remove the network requests. 1622 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1623 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1624 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1625 1626 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 1627 1628 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1629 config.networkId = FRAMEWORK_NETWORK_ID + 1; 1630 setupAndStartConnectSequence(config); 1631 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1632 verify(mWifiConfigManager, never()) 1633 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 1634 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 1635 verify(mWifiPermissionsUtil, times(2)).checkNetworkSettingsPermission(anyInt()); 1636 } 1637 1638 /** 1639 * If caller tries to connect to a network that is already connected, the connection request 1640 * should succeed. 1641 * 1642 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 1643 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 1644 */ 1645 @Test reconnectToConnectedNetworkWithNetworkId()1646 public void reconnectToConnectedNetworkWithNetworkId() throws Exception { 1647 connect(); 1648 1649 // try to reconnect 1650 IActionListener connectActionListener = mock(IActionListener.class); 1651 mCmi.connectNetwork( 1652 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 1653 new ActionListenerWrapper(connectActionListener), 1654 Binder.getCallingUid()); 1655 mLooper.dispatchAll(); 1656 verify(connectActionListener).onSuccess(); 1657 1658 // Verify that we didn't trigger a second connection. 1659 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1660 } 1661 1662 /** 1663 * If caller tries to connect to a network that is already connected, the connection request 1664 * should succeed. 1665 * 1666 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 1667 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 1668 */ 1669 @Test reconnectToConnectedNetworkWithConfig()1670 public void reconnectToConnectedNetworkWithConfig() throws Exception { 1671 connect(); 1672 1673 // try to reconnect 1674 IActionListener connectActionListener = mock(IActionListener.class); 1675 int callingUid = Binder.getCallingUid(); 1676 mCmi.connectNetwork( 1677 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 1678 new ActionListenerWrapper(connectActionListener), 1679 callingUid); 1680 mLooper.dispatchAll(); 1681 verify(connectActionListener).onSuccess(); 1682 1683 // Verify that we didn't trigger a second connection. 1684 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1685 } 1686 1687 /** 1688 * If caller tries to connect to a network that is already connecting, the connection request 1689 * should succeed. 1690 * 1691 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 1692 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did not trigger a 1693 * new connection. 1694 */ 1695 @Test reconnectToConnectingNetwork()1696 public void reconnectToConnectingNetwork() throws Exception { 1697 triggerConnect(); 1698 1699 // try to reconnect to the same network (before connection is established). 1700 IActionListener connectActionListener = mock(IActionListener.class); 1701 mCmi.connectNetwork( 1702 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 1703 new ActionListenerWrapper(connectActionListener), 1704 Binder.getCallingUid()); 1705 mLooper.dispatchAll(); 1706 verify(connectActionListener).onSuccess(); 1707 1708 // Verify that we didn't trigger a second connection. 1709 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1710 } 1711 1712 /** 1713 * If caller tries to connect to a network that is already connecting, the connection request 1714 * should succeed. 1715 * 1716 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 1717 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did trigger a new 1718 * connection. 1719 */ 1720 @Test reconnectToConnectingNetworkWithCredentialChange()1721 public void reconnectToConnectingNetworkWithCredentialChange() throws Exception { 1722 triggerConnect(); 1723 1724 // try to reconnect to the same network with a credential changed (before connection is 1725 // established). 1726 NetworkUpdateResult networkUpdateResult = new NetworkUpdateResult( 1727 FRAMEWORK_NETWORK_ID, 1728 false /* ip */, 1729 false /* proxy */, 1730 true /* credential */, 1731 false /* isNewNetwork */); 1732 IActionListener connectActionListener = mock(IActionListener.class); 1733 mCmi.connectNetwork( 1734 networkUpdateResult, 1735 new ActionListenerWrapper(connectActionListener), 1736 Binder.getCallingUid()); 1737 mLooper.dispatchAll(); 1738 verify(connectActionListener).onSuccess(); 1739 1740 // Verify that we triggered a second connection. 1741 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1742 } 1743 1744 /** 1745 * If caller tries to connect to a network that previously failed connection, the connection 1746 * request should succeed. 1747 * 1748 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 1749 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 1750 * and did trigger a new * connection. 1751 */ 1752 @Test connectAfterAssociationRejection()1753 public void connectAfterAssociationRejection() throws Exception { 1754 triggerConnect(); 1755 1756 // fail the connection. 1757 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 1758 new AssocRejectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 1759 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 1760 mLooper.dispatchAll(); 1761 1762 IActionListener connectActionListener = mock(IActionListener.class); 1763 mCmi.connectNetwork( 1764 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 1765 new ActionListenerWrapper(connectActionListener), 1766 Binder.getCallingUid()); 1767 mLooper.dispatchAll(); 1768 verify(connectActionListener).onSuccess(); 1769 1770 // Verify that we triggered a second connection. 1771 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1772 } 1773 1774 /** 1775 * If caller tries to connect to a network that previously failed connection, the connection 1776 * request should succeed. 1777 * 1778 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 1779 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 1780 * and did trigger a new * connection. 1781 */ 1782 @Test connectAfterConnectionFailure()1783 public void connectAfterConnectionFailure() throws Exception { 1784 triggerConnect(); 1785 1786 // fail the connection. 1787 DisconnectEventInfo disconnectEventInfo = 1788 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 1789 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 1790 mLooper.dispatchAll(); 1791 1792 IActionListener connectActionListener = mock(IActionListener.class); 1793 mCmi.connectNetwork( 1794 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 1795 new ActionListenerWrapper(connectActionListener), 1796 Binder.getCallingUid()); 1797 mLooper.dispatchAll(); 1798 verify(connectActionListener).onSuccess(); 1799 1800 // Verify that we triggered a second connection. 1801 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 1802 } 1803 1804 /** 1805 * If caller tries to connect to a new network while still provisioning the current one, 1806 * the connection attempt should succeed. 1807 */ 1808 @Test connectWhileObtainingIp()1809 public void connectWhileObtainingIp() throws Exception { 1810 initializeAndAddNetworkAndVerifySuccess(); 1811 1812 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 1813 1814 startConnectSuccess(); 1815 1816 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1817 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 1818 mLooper.dispatchAll(); 1819 1820 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1821 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 1822 SupplicantState.COMPLETED)); 1823 mLooper.dispatchAll(); 1824 1825 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1826 1827 // Connect to a different network 1828 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1829 config.networkId = FRAMEWORK_NETWORK_ID + 1; 1830 setupAndStartConnectSequence(config); 1831 validateSuccessfulConnectSequence(config); 1832 1833 // Disconnection from previous network. 1834 DisconnectEventInfo disconnectEventInfo = 1835 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 1836 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 1837 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1838 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 1839 SupplicantState.DISCONNECTED)); 1840 mLooper.dispatchAll(); 1841 1842 // Ensure we don't end the new connection event. 1843 verify(mWifiMetrics, never()).endConnectionEvent( 1844 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 1845 anyInt(), anyInt(), anyInt()); 1846 verify(mWifiConnectivityManager).prepareForForcedConnection(FRAMEWORK_NETWORK_ID + 1); 1847 } 1848 1849 /** 1850 * If there is a network removal while still connecting to it, the connection 1851 * should be aborted. 1852 */ 1853 @Test networkRemovalWhileObtainingIp()1854 public void networkRemovalWhileObtainingIp() throws Exception { 1855 initializeAndAddNetworkAndVerifySuccess(); 1856 1857 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 1858 1859 startConnectSuccess(); 1860 1861 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1862 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 1863 mLooper.dispatchAll(); 1864 1865 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1866 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 1867 SupplicantState.COMPLETED)); 1868 mLooper.dispatchAll(); 1869 1870 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1871 reset(mWifiNative); 1872 1873 // Simulate the target network removal & the disconnect trigger. 1874 WifiConfiguration removedNetwork = new WifiConfiguration(); 1875 removedNetwork.networkId = FRAMEWORK_NETWORK_ID; 1876 mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork); 1877 mLooper.dispatchAll(); 1878 1879 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 1880 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 1881 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 1882 eq(StaEvent.DISCONNECT_NETWORK_REMOVED)); 1883 1884 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)).thenReturn(null); 1885 DisconnectEventInfo disconnectEventInfo = 1886 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 1887 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 1888 mLooper.dispatchAll(); 1889 1890 assertEquals("DisconnectedState", getCurrentState().getName()); 1891 } 1892 1893 /** 1894 * Tests that manual connection to a network (from settings app) logs the correct nominator ID. 1895 */ 1896 @Test testManualConnectNominator()1897 public void testManualConnectNominator() throws Exception { 1898 initializeAndAddNetworkAndVerifySuccess(); 1899 1900 WifiConfiguration config = new WifiConfiguration(); 1901 config.networkId = TEST_NETWORK_ID; 1902 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 1903 1904 IActionListener connectActionListener = mock(IActionListener.class); 1905 mCmi.connectNetwork( 1906 new NetworkUpdateResult(TEST_NETWORK_ID), 1907 new ActionListenerWrapper(connectActionListener), 1908 Process.SYSTEM_UID); 1909 mLooper.dispatchAll(); 1910 verify(connectActionListener).onSuccess(); 1911 1912 verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, 1913 WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); 1914 } 1915 startConnectSuccess()1916 private void startConnectSuccess() throws Exception { 1917 startConnectSuccess(FRAMEWORK_NETWORK_ID); 1918 } 1919 startConnectSuccess(int networkId)1920 private void startConnectSuccess(int networkId) throws Exception { 1921 IActionListener connectActionListener = mock(IActionListener.class); 1922 mCmi.connectNetwork( 1923 new NetworkUpdateResult(networkId), 1924 new ActionListenerWrapper(connectActionListener), 1925 Binder.getCallingUid()); 1926 mLooper.dispatchAll(); 1927 verify(connectActionListener).onSuccess(); 1928 } 1929 1930 @Test testDhcpFailure()1931 public void testDhcpFailure() throws Exception { 1932 initializeAndAddNetworkAndVerifySuccess(); 1933 1934 startConnectSuccess(); 1935 1936 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1937 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 1938 SupplicantState.ASSOCIATED)); 1939 mLooper.dispatchAll(); 1940 1941 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1942 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 1943 mLooper.dispatchAll(); 1944 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 1945 1946 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1947 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 1948 SupplicantState.COMPLETED)); 1949 mLooper.dispatchAll(); 1950 1951 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1952 injectDhcpFailure(); 1953 mLooper.dispatchAll(); 1954 1955 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 1956 // Verify this is not counted as a IP renewal failure 1957 verify(mWifiMetrics, never()).incrementIpRenewalFailure(); 1958 // Verifies that WifiLastResortWatchdog be notified 1959 // by DHCP failure 1960 verify(mWifiLastResortWatchdog, times(2)).noteConnectionFailureAndTriggerIfNeeded( 1961 eq(TEST_SSID), eq(TEST_BSSID_STR), 1962 eq(WifiLastResortWatchdog.FAILURE_CODE_DHCP), anyBoolean()); 1963 verify(mWifiBlocklistMonitor, times(2)).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 1964 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_DHCP_FAILURE), anyInt()); 1965 verify(mWifiBlocklistMonitor, times(2)).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 1966 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_DHCP_FAILURE), anyInt()); 1967 verify(mWifiBlocklistMonitor, never()).handleDhcpProvisioningSuccess( 1968 TEST_BSSID_STR, TEST_SSID); 1969 verify(mWifiBlocklistMonitor, never()).handleNetworkValidationSuccess( 1970 TEST_BSSID_STR, TEST_SSID); 1971 } 1972 1973 /** 1974 * Verify that a IP renewal failure is logged when IP provisioning fail in the 1975 * L3ConnectedState. 1976 */ 1977 @Test testDhcpRenewalMetrics()1978 public void testDhcpRenewalMetrics() throws Exception { 1979 connect(); 1980 injectDhcpFailure(); 1981 mLooper.dispatchAll(); 1982 1983 verify(mWifiMetrics).incrementIpRenewalFailure(); 1984 } 1985 1986 /** 1987 * Verify that the network selection status will be updated with DISABLED_AUTHENTICATION_FAILURE 1988 * when wrong password authentication failure is detected and the network had been 1989 * connected previously. 1990 */ 1991 @Test testWrongPasswordWithPreviouslyConnected()1992 public void testWrongPasswordWithPreviouslyConnected() throws Exception { 1993 initializeAndAddNetworkAndVerifySuccess(); 1994 1995 startConnectSuccess(); 1996 1997 WifiConfiguration config = createTestNetwork(false); 1998 config.getNetworkSelectionStatus().setHasEverConnected(true); 1999 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2000 2001 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2002 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 2003 DisconnectEventInfo disconnectEventInfo = 2004 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2005 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2006 mLooper.dispatchAll(); 2007 2008 verify(mWrongPasswordNotifier, never()).onWrongPasswordError(anyString()); 2009 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 2010 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE)); 2011 2012 assertEquals("DisconnectedState", getCurrentState().getName()); 2013 } 2014 2015 /** 2016 * It is observed sometimes the WifiMonitor.NETWORK_DISCONNECTION_EVENT is observed before the 2017 * actual connection failure messages while making a connection. 2018 * The test make sure that make sure that the connection event is ended properly in the above 2019 * case. 2020 */ 2021 @Test testDisconnectionEventInL2ConnectingStateEndsConnectionEvent()2022 public void testDisconnectionEventInL2ConnectingStateEndsConnectionEvent() throws Exception { 2023 initializeAndAddNetworkAndVerifySuccess(); 2024 2025 startConnectSuccess(); 2026 2027 WifiConfiguration config = createTestNetwork(false); 2028 config.getNetworkSelectionStatus().setHasEverConnected(true); 2029 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2030 2031 DisconnectEventInfo disconnectEventInfo = 2032 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2033 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2034 mLooper.dispatchAll(); 2035 2036 verify(mWifiMetrics).endConnectionEvent( 2037 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 2038 anyInt(), anyInt(), anyInt()); 2039 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 2040 any(), anyInt(), any(), any()); 2041 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, mWifiInfo.getCurrentSecurityType()); 2042 assertEquals("DisconnectedState", getCurrentState().getName()); 2043 } 2044 2045 /** 2046 * Verify that the network selection status will be updated with DISABLED_BY_WRONG_PASSWORD 2047 * when wrong password authentication failure is detected and the network has never been 2048 * connected. 2049 */ 2050 @Test testWrongPasswordWithNeverConnected()2051 public void testWrongPasswordWithNeverConnected() throws Exception { 2052 initializeAndAddNetworkAndVerifySuccess(); 2053 2054 startConnectSuccess(); 2055 2056 WifiConfiguration config = new WifiConfiguration(); 2057 config.SSID = TEST_SSID; 2058 config.getNetworkSelectionStatus().setHasEverConnected(false); 2059 config.carrierId = CARRIER_ID_1; 2060 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2061 2062 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2063 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 2064 DisconnectEventInfo disconnectEventInfo = 2065 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2066 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2067 mLooper.dispatchAll(); 2068 2069 verify(mWrongPasswordNotifier).onWrongPasswordError(eq(TEST_SSID)); 2070 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 2071 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)); 2072 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionAuthFailure(); 2073 assertEquals("DisconnectedState", getCurrentState().getName()); 2074 } 2075 2076 /** 2077 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 2078 * is called when a Authentication failure is detected with a vendor specific EAP Error 2079 * of certification expired while using EAP-SIM 2080 * In this test case, it is assumed that the network had been connected previously. 2081 */ 2082 @Test testEapSimErrorVendorSpecific()2083 public void testEapSimErrorVendorSpecific() throws Exception { 2084 when(mWifiMetrics.startConnectionEvent(any(), any(), anyString(), anyInt())) 2085 .thenReturn(80000); 2086 initializeAndAddNetworkAndVerifySuccess(); 2087 2088 startConnectSuccess(); 2089 2090 WifiConfiguration config = new WifiConfiguration(); 2091 config.SSID = TEST_SSID; 2092 config.getNetworkSelectionStatus().setHasEverConnected(true); 2093 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 2094 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 2095 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2096 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 2097 .thenReturn(WifiHealthMonitor.REASON_AUTH_FAILURE); 2098 2099 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2100 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 2101 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED); 2102 mLooper.dispatchAll(); 2103 2104 verify(mEapFailureNotifier).onEapFailure( 2105 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED, config, true); 2106 verify(mWifiCarrierInfoManager).resetCarrierKeysForImsiEncryption(any()); 2107 verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled(); 2108 verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString()); 2109 verify(mWifiDiagnostics, times(2)).takeBugReport(anyString(), anyString()); 2110 } 2111 2112 /** 2113 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 2114 * is not called when a Authentication failure is detected with a vendor specific EAP Error 2115 * of certification expired while using other methods than EAP-SIM, EAP-AKA, or EAP-AKA'. 2116 */ 2117 @Test testEapTlsErrorVendorSpecific()2118 public void testEapTlsErrorVendorSpecific() throws Exception { 2119 initializeAndAddNetworkAndVerifySuccess(); 2120 2121 startConnectSuccess(); 2122 2123 WifiConfiguration config = new WifiConfiguration(); 2124 config.getNetworkSelectionStatus().setHasEverConnected(true); 2125 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 2126 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 2127 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2128 2129 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2130 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 2131 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED); 2132 mLooper.dispatchAll(); 2133 2134 verify(mWifiCarrierInfoManager, never()).resetCarrierKeysForImsiEncryption(any()); 2135 } 2136 2137 /** 2138 * Verify that the network selection status will be updated with 2139 * DISABLED_AUTHENTICATION_NO_SUBSCRIBED when service is not subscribed. 2140 */ 2141 @Test testEapSimNoSubscribedError()2142 public void testEapSimNoSubscribedError() throws Exception { 2143 initializeAndAddNetworkAndVerifySuccess(); 2144 2145 startConnectSuccess(); 2146 2147 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 2148 2149 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2150 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 2151 WifiNative.EAP_SIM_NOT_SUBSCRIBED); 2152 mLooper.dispatchAll(); 2153 2154 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 2155 eq(WifiConfiguration.NetworkSelectionStatus 2156 .DISABLED_AUTHENTICATION_NO_SUBSCRIPTION)); 2157 } 2158 2159 @Test testBadNetworkEvent()2160 public void testBadNetworkEvent() throws Exception { 2161 initializeAndAddNetworkAndVerifySuccess(); 2162 2163 startConnectSuccess(); 2164 2165 DisconnectEventInfo disconnectEventInfo = 2166 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2167 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2168 mLooper.dispatchAll(); 2169 2170 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2171 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 2172 SupplicantState.COMPLETED)); 2173 mLooper.dispatchAll(); 2174 2175 assertEquals("DisconnectedState", getCurrentState().getName()); 2176 verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString()); 2177 } 2178 2179 2180 @Test getWhatToString()2181 public void getWhatToString() throws Exception { 2182 assertEquals("CMD_PRE_DHCP_ACTION", mCmi.getWhatToString(CMD_PRE_DHCP_ACTION)); 2183 assertEquals("CMD_IP_REACHABILITY_LOST", mCmi.getWhatToString( 2184 ClientModeImpl.CMD_IP_REACHABILITY_LOST)); 2185 } 2186 2187 @Test disconnect()2188 public void disconnect() throws Exception { 2189 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 2190 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 2191 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 2192 connect(); 2193 inOrderWifiLockManager.verify(mWifiLockManager) 2194 .updateWifiClientConnected(mClientModeManager, true); 2195 2196 DisconnectEventInfo disconnectEventInfo = 2197 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 2198 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2199 mLooper.dispatchAll(); 2200 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2201 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 2202 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 2203 mLooper.dispatchAll(); 2204 2205 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.DISCONNECTED); 2206 assertEquals("DisconnectedState", getCurrentState().getName()); 2207 verify(mCmiMonitor).onConnectionEnd(mClientModeManager); 2208 inOrderWifiLockManager.verify(mWifiLockManager) 2209 .updateWifiClientConnected(mClientModeManager, false); 2210 verify(mWifiScoreCard).detectAbnormalDisconnection(WIFI_IFACE_NAME); 2211 verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); 2212 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 2213 // Set MAC address thrice - once at bootup, once for new connection, once for disconnect. 2214 verify(mWifiNative, times(3)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 2215 // ClientModeManager should only be stopped when in lingering mode 2216 verify(mClientModeManager, never()).stop(); 2217 } 2218 2219 @Test secondaryRoleCmmDisconnected_stopsClientModeManager()2220 public void secondaryRoleCmmDisconnected_stopsClientModeManager() throws Exception { 2221 // Owning ClientModeManager has role SECONDARY_TRANSIENT 2222 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 2223 2224 connect(); 2225 2226 // ClientModeManager never stopped 2227 verify(mClientModeManager, never()).stop(); 2228 2229 // Disconnected from network 2230 DisconnectEventInfo disconnectEventInfo = 2231 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 2232 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2233 mLooper.dispatchAll(); 2234 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2235 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 2236 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 2237 mLooper.dispatchAll(); 2238 2239 assertEquals("DisconnectedState", getCurrentState().getName()); 2240 2241 // Since in lingering mode, disconnect => stop ClientModeManager 2242 verify(mClientModeManager).stop(); 2243 } 2244 2245 @Test primaryCmmDisconnected_doesntStopsClientModeManager()2246 public void primaryCmmDisconnected_doesntStopsClientModeManager() throws Exception { 2247 // Owning ClientModeManager is primary 2248 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 2249 2250 connect(); 2251 2252 // ClientModeManager never stopped 2253 verify(mClientModeManager, never()).stop(); 2254 2255 // Disconnected from network 2256 DisconnectEventInfo disconnectEventInfo = 2257 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 2258 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2259 mLooper.dispatchAll(); 2260 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2261 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 2262 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 2263 mLooper.dispatchAll(); 2264 2265 assertEquals("DisconnectedState", getCurrentState().getName()); 2266 2267 // Since primary => don't stop ClientModeManager 2268 verify(mClientModeManager, never()).stop(); 2269 } 2270 2271 /** 2272 * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected 2273 * to true. 2274 * 2275 * Test: Successfully create and connect to a network. Check the config and verify 2276 * WifiConfiguration.getHasEverConnected() is true. 2277 */ 2278 @Test setHasEverConnectedTrueOnConnect()2279 public void setHasEverConnectedTrueOnConnect() throws Exception { 2280 connect(); 2281 verify(mWifiConfigManager, atLeastOnce()).updateNetworkAfterConnect(eq(0), eq(false), 2282 anyInt()); 2283 } 2284 2285 /** 2286 * Fail network connection attempt and verify HasEverConnected remains false. 2287 * 2288 * Test: Successfully create a network but fail when connecting. Check the config and verify 2289 * WifiConfiguration.getHasEverConnected() is false. 2290 */ 2291 @Test connectionFailureDoesNotSetHasEverConnectedTrue()2292 public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception { 2293 testDhcpFailure(); 2294 verify(mWifiConfigManager, never()).updateNetworkAfterConnect(eq(0), eq(false), anyInt()); 2295 } 2296 2297 @Test iconQueryTest()2298 public void iconQueryTest() throws Exception { 2299 // TODO(b/31065385): Passpoint config management. 2300 } 2301 2302 @Test verboseLogRecSizeIsGreaterThanNormalSize()2303 public void verboseLogRecSizeIsGreaterThanNormalSize() { 2304 assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > mWifiGlobals.getClientModeImplNumLogRecs()); 2305 } 2306 2307 /** 2308 * Verifies that, by default, we allow only the "normal" number of log records. 2309 */ 2310 @Test normalLogRecSizeIsUsedByDefault()2311 public void normalLogRecSizeIsUsedByDefault() { 2312 mCmi.enableVerboseLogging(false); 2313 assertEquals(mWifiGlobals.getClientModeImplNumLogRecs(), mCmi.getLogRecMaxSize()); 2314 } 2315 2316 /** 2317 * Verifies that, in verbose mode, we allow a larger number of log records. 2318 */ 2319 @Test enablingVerboseLoggingUpdatesLogRecSize()2320 public void enablingVerboseLoggingUpdatesLogRecSize() { 2321 mCmi.enableVerboseLogging(true); 2322 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mCmi.getLogRecMaxSize()); 2323 } 2324 2325 @Test disablingVerboseLoggingClearsRecords()2326 public void disablingVerboseLoggingClearsRecords() { 2327 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 2328 mLooper.dispatchAll(); 2329 assertTrue(mCmi.getLogRecSize() >= 1); 2330 2331 mCmi.enableVerboseLogging(false); 2332 assertEquals(0, mCmi.getLogRecSize()); 2333 } 2334 2335 @Test disablingVerboseLoggingUpdatesLogRecSize()2336 public void disablingVerboseLoggingUpdatesLogRecSize() { 2337 mCmi.enableVerboseLogging(true); 2338 mCmi.enableVerboseLogging(false); 2339 assertEquals(mWifiGlobals.getClientModeImplNumLogRecs(), mCmi.getLogRecMaxSize()); 2340 } 2341 2342 @Test logRecsIncludeDisconnectCommand()2343 public void logRecsIncludeDisconnectCommand() { 2344 // There's nothing special about the DISCONNECT command. It's just representative of 2345 // "normal" commands. 2346 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 2347 mLooper.dispatchAll(); 2348 assertEquals(1, mCmi.copyLogRecs() 2349 .stream() 2350 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_DISCONNECT) 2351 .count()); 2352 } 2353 2354 @Test logRecsExcludeRssiPollCommandByDefault()2355 public void logRecsExcludeRssiPollCommandByDefault() { 2356 mCmi.enableVerboseLogging(false); 2357 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 2358 mLooper.dispatchAll(); 2359 assertEquals(0, mCmi.copyLogRecs() 2360 .stream() 2361 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 2362 .count()); 2363 } 2364 2365 @Test logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled()2366 public void logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled() { 2367 mCmi.enableVerboseLogging(true); 2368 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 2369 mLooper.dispatchAll(); 2370 assertEquals(1, mCmi.copyLogRecs() 2371 .stream() 2372 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 2373 .count()); 2374 } 2375 2376 /** 2377 * Verify that syncStartSubscriptionProvisioning will redirect calls with right parameters 2378 * to {@link PasspointManager} with expected true being returned when in client mode. 2379 */ 2380 @Test syncStartSubscriptionProvisioningInClientMode()2381 public void syncStartSubscriptionProvisioningInClientMode() throws Exception { 2382 when(mPasspointManager.startSubscriptionProvisioning(anyInt(), 2383 any(OsuProvider.class), any(IProvisioningCallback.class))).thenReturn(true); 2384 mLooper.startAutoDispatch(); 2385 assertTrue(mCmi.syncStartSubscriptionProvisioning( 2386 OTHER_USER_UID, mOsuProvider, mProvisioningCallback)); 2387 verify(mPasspointManager).startSubscriptionProvisioning(OTHER_USER_UID, mOsuProvider, 2388 mProvisioningCallback); 2389 mLooper.stopAutoDispatch(); 2390 } 2391 2392 @Test testSyncGetCurrentNetwork()2393 public void testSyncGetCurrentNetwork() throws Exception { 2394 // syncGetCurrentNetwork() returns null when disconnected 2395 mLooper.startAutoDispatch(); 2396 assertNull(mCmi.syncGetCurrentNetwork()); 2397 mLooper.stopAutoDispatch(); 2398 2399 connect(); 2400 2401 // syncGetCurrentNetwork() returns non-null Network when connected 2402 mLooper.startAutoDispatch(); 2403 assertEquals(mNetwork, mCmi.syncGetCurrentNetwork()); 2404 mLooper.stopAutoDispatch(); 2405 } 2406 2407 /** 2408 * Test that we disconnect from a network if it was removed while we are in the 2409 * L3ProvisioningState. 2410 */ 2411 @Test disconnectFromNetworkWhenRemovedWhileObtainingIpAddr()2412 public void disconnectFromNetworkWhenRemovedWhileObtainingIpAddr() throws Exception { 2413 initializeAndAddNetworkAndVerifySuccess(); 2414 2415 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 2416 2417 startConnectSuccess(); 2418 2419 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2420 .thenReturn(mScanDetailCache); 2421 2422 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 2423 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 2424 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 2425 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 2426 2427 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2428 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 2429 mLooper.dispatchAll(); 2430 2431 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2432 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 2433 SupplicantState.COMPLETED)); 2434 mLooper.dispatchAll(); 2435 2436 assertEquals("L3ProvisioningState", getCurrentState().getName()); 2437 2438 // trigger removal callback to trigger disconnect. 2439 WifiConfiguration removedConfig = new WifiConfiguration(); 2440 removedConfig.networkId = FRAMEWORK_NETWORK_ID; 2441 mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedConfig); 2442 2443 reset(mWifiConfigManager); 2444 2445 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)).thenReturn(null); 2446 2447 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 2448 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 2449 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 2450 dhcpResults.baseConfiguration.ipAddress = 2451 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 2452 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 2453 dhcpResults.leaseDuration = 3600; 2454 2455 injectDhcpSuccess(dhcpResults); 2456 mLooper.dispatchAll(); 2457 2458 verify(mWifiNative, times(2)).disconnect(WIFI_IFACE_NAME); 2459 } 2460 2461 /** 2462 * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. 2463 */ 2464 @Test testWifiInfoUpdatedUponSupplicantStateChangedEvent()2465 public void testWifiInfoUpdatedUponSupplicantStateChangedEvent() throws Exception { 2466 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 2467 connect(); 2468 2469 // Set the scan detail cache for roaming target. 2470 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2471 .thenReturn(mScanDetailCache); 2472 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 2473 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 2474 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 2475 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 2476 2477 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 2478 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. 2479 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2480 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, 2481 SupplicantState.COMPLETED)); 2482 mLooper.dispatchAll(); 2483 2484 WifiInfo wifiInfo = mWifiInfo; 2485 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 2486 assertEquals(sFreq1, wifiInfo.getFrequency()); 2487 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2488 2489 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2490 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, 2491 SupplicantState.DISCONNECTED)); 2492 mLooper.dispatchAll(); 2493 2494 wifiInfo = mWifiInfo; 2495 assertNull(wifiInfo.getBSSID()); 2496 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 2497 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, wifiInfo.getNetworkId()); 2498 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2499 assertEquals("DisconnectedState", getCurrentState().getName()); 2500 } 2501 2502 2503 /** 2504 * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. 2505 */ 2506 @Test testWifiInfoUpdatedUponSupplicantStateChangedEventWithWrongSsid()2507 public void testWifiInfoUpdatedUponSupplicantStateChangedEventWithWrongSsid() throws Exception { 2508 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 2509 connect(); 2510 2511 // Set the scan detail cache for roaming target. 2512 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2513 .thenReturn(mScanDetailCache); 2514 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 2515 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 2516 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 2517 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 2518 2519 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 2520 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. 2521 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2522 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, 2523 SupplicantState.COMPLETED)); 2524 mLooper.dispatchAll(); 2525 2526 WifiInfo wifiInfo = mWifiInfo; 2527 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 2528 assertEquals(sFreq1, wifiInfo.getFrequency()); 2529 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2530 2531 // Send state change event with wrong ssid. 2532 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2533 new StateChangeResult(0, TEST_WIFI_SSID1, TEST_BSSID_STR, 2534 SupplicantState.DISCONNECTED)); 2535 mLooper.dispatchAll(); 2536 2537 wifiInfo = mWifiInfo; 2538 assertNull(wifiInfo.getBSSID()); 2539 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 2540 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, wifiInfo.getNetworkId()); 2541 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2542 assertEquals("DisconnectedState", getCurrentState().getName()); 2543 } 2544 2545 /** 2546 * Verifies that WifiInfo is updated upon CMD_ASSOCIATED_BSSID event. 2547 */ 2548 @Test testWifiInfoUpdatedUponAssociatedBSSIDEvent()2549 public void testWifiInfoUpdatedUponAssociatedBSSIDEvent() throws Exception { 2550 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 2551 connect(); 2552 2553 // Set the scan detail cache for roaming target. 2554 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2555 .thenReturn(mScanDetailCache); 2556 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 2557 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 2558 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 2559 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 2560 2561 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 2562 // Send a CMD_ASSOCIATED_BSSID, verify WifiInfo is updated. 2563 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR1); 2564 mLooper.dispatchAll(); 2565 2566 WifiInfo wifiInfo = mWifiInfo; 2567 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 2568 assertEquals(sFreq1, wifiInfo.getFrequency()); 2569 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2570 verify(mContext, times(2)).sendStickyBroadcastAsUser( 2571 argThat(new NetworkStateChangedIntentMatcher(CONNECTED)), any()); 2572 } 2573 2574 /** 2575 * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not 2576 * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState. 2577 * This protects ClientModeImpl from getting into a bad state where WifiInfo says wifi is 2578 * already Connected or Connecting, (when it is in-fact Disconnected), so 2579 * WifiConnectivityManager does not attempt any new Connections, freezing wifi. 2580 */ 2581 @Test testWifiInfoCleanedUpEnteringExitingConnectableState()2582 public void testWifiInfoCleanedUpEnteringExitingConnectableState() throws Exception { 2583 InOrder inOrderMetrics = inOrder(mWifiMetrics); 2584 Log.i(TAG, mCmi.getCurrentState().getName()); 2585 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 2586 WifiInfo wifiInfo = mWifiInfo; 2587 wifiInfo.setBSSID(initialBSSID); 2588 2589 // reset mWifiNative since initializeCmi() was called in setup() 2590 resetWifiNative(); 2591 2592 // Set CMI to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager 2593 initializeCmi(); 2594 inOrderMetrics.verify(mWifiMetrics) 2595 .setWifiState(WIFI_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 2596 inOrderMetrics.verify(mWifiMetrics) 2597 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_ENABLED); 2598 assertNull(wifiInfo.getBSSID()); 2599 2600 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated 2601 connect(); 2602 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 2603 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 2604 2605 // Set CMI to DISABLED_MODE, verify state and wifi disabled in ConnectivityManager, and 2606 // WifiInfo is reset() and state set to DISCONNECTED 2607 mCmi.stop(); 2608 mLooper.dispatchAll(); 2609 2610 inOrderMetrics.verify(mWifiMetrics).setWifiState(WIFI_IFACE_NAME, 2611 WifiMetricsProto.WifiLog.WIFI_DISABLED); 2612 inOrderMetrics.verify(mWifiMetrics) 2613 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_DISABLED); 2614 assertNull(wifiInfo.getBSSID()); 2615 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 2616 } 2617 2618 @Test testWifiInfoCleanedUpEnteringExitingConnectableState2()2619 public void testWifiInfoCleanedUpEnteringExitingConnectableState2() throws Exception { 2620 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 2621 InOrder inOrderMetrics = inOrder(mWifiMetrics); 2622 2623 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated 2624 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2625 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 2626 SupplicantState.COMPLETED)); 2627 mLooper.dispatchAll(); 2628 assertNull(mWifiInfo.getBSSID()); 2629 assertEquals(SupplicantState.DISCONNECTED, mWifiInfo.getSupplicantState()); 2630 } 2631 2632 @Test testWifiInfoCleanedUpEnteringExitingConnectableState3()2633 public void testWifiInfoCleanedUpEnteringExitingConnectableState3() throws Exception { 2634 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 2635 InOrder inOrderMetrics = inOrder(mWifiMetrics); 2636 2637 // Set the bssid to something, so we can verify it is cleared (just in case) 2638 mWifiInfo.setBSSID(initialBSSID); 2639 2640 initializeCmi(); 2641 2642 inOrderMetrics.verify(mWifiMetrics) 2643 .setWifiState(WIFI_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 2644 inOrderMetrics.verify(mWifiMetrics) 2645 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_ENABLED); 2646 assertEquals("DisconnectedState", getCurrentState().getName()); 2647 assertEquals(SupplicantState.DISCONNECTED, mWifiInfo.getSupplicantState()); 2648 assertNull(mWifiInfo.getBSSID()); 2649 } 2650 2651 /** 2652 * Test that connected SSID and BSSID are exposed to system server. 2653 * Also tests that {@link ClientModeImpl#syncRequestConnectionInfo()} always 2654 * returns a copy of WifiInfo. 2655 */ 2656 @Test testConnectedIdsAreVisibleFromSystemServer()2657 public void testConnectedIdsAreVisibleFromSystemServer() throws Exception { 2658 WifiInfo wifiInfo = mWifiInfo; 2659 // Get into a connected state, with known BSSID and SSID 2660 connect(); 2661 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 2662 assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid()); 2663 2664 mLooper.startAutoDispatch(); 2665 WifiInfo connectionInfo = mCmi.syncRequestConnectionInfo(); 2666 mLooper.stopAutoDispatch(); 2667 2668 assertEquals(wifiInfo.getSSID(), connectionInfo.getSSID()); 2669 assertEquals(wifiInfo.getBSSID(), connectionInfo.getBSSID()); 2670 assertEquals(wifiInfo.getMacAddress(), connectionInfo.getMacAddress()); 2671 } 2672 2673 /** 2674 * Test that reconnectCommand() triggers connectivity scan when ClientModeImpl 2675 * is in DisconnectedMode. 2676 */ 2677 @Test testReconnectCommandWhenDisconnected()2678 public void testReconnectCommandWhenDisconnected() throws Exception { 2679 // Connect to network with |TEST_BSSID_STR|, |sFreq|, and then disconnect. 2680 disconnect(); 2681 2682 mCmi.reconnect(ClientModeImpl.WIFI_WORK_SOURCE); 2683 mLooper.dispatchAll(); 2684 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 2685 } 2686 2687 /** 2688 * Test that reconnectCommand() doesn't trigger connectivity scan when ClientModeImpl 2689 * is in ConnectedMode. 2690 */ 2691 @Test testReconnectCommandWhenConnected()2692 public void testReconnectCommandWhenConnected() throws Exception { 2693 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 2694 connect(); 2695 2696 mCmi.reconnect(ClientModeImpl.WIFI_WORK_SOURCE); 2697 mLooper.dispatchAll(); 2698 verify(mWifiConnectivityManager, never()) 2699 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 2700 } 2701 2702 /** 2703 * Verifies that ClientModeImpl sets and unsets appropriate 'RecentFailureReason' values 2704 * on a WifiConfiguration when it fails association, authentication, or successfully connects 2705 */ 2706 @Test testExtraFailureReason_ApIsBusy()2707 public void testExtraFailureReason_ApIsBusy() throws Exception { 2708 // Setup CONNECT_MODE & a WifiConfiguration 2709 initializeAndAddNetworkAndVerifySuccess(); 2710 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 2711 // targetNetworkId state) 2712 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 2713 mLooper.dispatchAll(); 2714 // Simulate an ASSOCIATION_REJECTION_EVENT, due to the AP being busy 2715 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 2716 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 2717 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, 2718 false)); 2719 mLooper.dispatchAll(); 2720 verify(mWifiConfigManager).setRecentFailureAssociationStatus(eq(0), 2721 eq(WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA)); 2722 assertEquals("DisconnectedState", getCurrentState().getName()); 2723 2724 // Simulate an AUTHENTICATION_FAILURE_EVENT, which should clear the ExtraFailureReason 2725 reset(mWifiConfigManager); 2726 initializeAndAddNetworkAndVerifySuccess(); 2727 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 2728 // targetNetworkId state) 2729 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 2730 mLooper.dispatchAll(); 2731 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 0, 0, null); 2732 DisconnectEventInfo disconnectEventInfo = 2733 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2734 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2735 mLooper.dispatchAll(); 2736 verify(mWifiConfigManager).clearRecentFailureReason(eq(0)); 2737 verify(mWifiConfigManager, never()).setRecentFailureAssociationStatus(anyInt(), anyInt()); 2738 2739 // Simulate a NETWORK_CONNECTION_EVENT which should clear the ExtraFailureReason 2740 reset(mWifiConfigManager); 2741 initializeAndAddNetworkAndVerifySuccess(); 2742 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 2743 // targetNetworkId state) 2744 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 2745 mLooper.dispatchAll(); 2746 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2747 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, null, false)); 2748 mLooper.dispatchAll(); 2749 verify(mWifiConfigManager).clearRecentFailureReason(eq(0)); 2750 verify(mWifiConfigManager, never()).setRecentFailureAssociationStatus(anyInt(), anyInt()); 2751 } 2752 makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, long timeSinceLastSelected)2753 private WifiConfiguration makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, 2754 long timeSinceLastSelected) { 2755 long lastSelectedTimestamp = 45666743454L; 2756 2757 when(mClock.getElapsedSinceBootMillis()).thenReturn( 2758 lastSelectedTimestamp + timeSinceLastSelected); 2759 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(lastSelectedTimestamp); 2760 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(lastSelectedNetworkId); 2761 2762 WifiConfiguration currentConfig = new WifiConfiguration(); 2763 currentConfig.networkId = lastSelectedNetworkId; 2764 return currentConfig; 2765 } 2766 2767 /** 2768 * Test that the helper method 2769 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 2770 * returns true when we connect to the last selected network before expiration of 2771 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 2772 */ 2773 @Test testIsRecentlySelectedByTheUser_SameNetworkNotExpired()2774 public void testIsRecentlySelectedByTheUser_SameNetworkNotExpired() { 2775 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2776 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2777 assertTrue(mCmi.isRecentlySelectedByTheUser(currentConfig)); 2778 } 2779 2780 /** 2781 * Test that the helper method 2782 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 2783 * returns false when we connect to the last selected network after expiration of 2784 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 2785 */ 2786 @Test testIsRecentlySelectedByTheUser_SameNetworkExpired()2787 public void testIsRecentlySelectedByTheUser_SameNetworkExpired() { 2788 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2789 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 2790 assertFalse(mCmi.isRecentlySelectedByTheUser(currentConfig)); 2791 } 2792 2793 /** 2794 * Test that the helper method 2795 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 2796 * returns false when we connect to a different network to the last selected network. 2797 */ 2798 @Test testIsRecentlySelectedByTheUser_DifferentNetwork()2799 public void testIsRecentlySelectedByTheUser_DifferentNetwork() { 2800 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 2801 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2802 currentConfig.networkId = 4; 2803 assertFalse(mCmi.isRecentlySelectedByTheUser(currentConfig)); 2804 } 2805 expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, Consumer<NetworkCapabilities> networkCapabilitiesChecker)2806 private void expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, 2807 Consumer<NetworkCapabilities> networkCapabilitiesChecker) { 2808 // Expects that the code calls registerNetworkAgent and provides a way for the test to 2809 // verify the messages sent through the NetworkAgent to ConnectivityService. 2810 // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. 2811 ArgumentCaptor<NetworkAgentConfig> configCaptor = 2812 ArgumentCaptor.forClass(NetworkAgentConfig.class); 2813 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 2814 ArgumentCaptor.forClass(NetworkCapabilities.class); 2815 2816 verify(mWifiInjector).makeWifiNetworkAgent( 2817 networkCapabilitiesCaptor.capture(), 2818 any(), 2819 configCaptor.capture(), 2820 any(), 2821 mWifiNetworkAgentCallbackCaptor.capture()); 2822 2823 configChecker.accept(configCaptor.getValue()); 2824 networkCapabilitiesChecker.accept(networkCapabilitiesCaptor.getValue()); 2825 } 2826 expectNetworkAgentUpdateCapabilities( Consumer<NetworkCapabilities> networkCapabilitiesChecker)2827 private void expectNetworkAgentUpdateCapabilities( 2828 Consumer<NetworkCapabilities> networkCapabilitiesChecker) throws Exception { 2829 ArgumentCaptor<NetworkCapabilities> captor = ArgumentCaptor.forClass( 2830 NetworkCapabilities.class); 2831 mLooper.dispatchAll(); 2832 verify(mWifiNetworkAgent).sendNetworkCapabilitiesAndCache(captor.capture()); 2833 networkCapabilitiesChecker.accept(captor.getValue()); 2834 } 2835 2836 /** 2837 * Verify that when a network is explicitly selected, but noInternetAccessExpected is false, 2838 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2839 * acceptUnvalidated and acceptPartialConnectivity. 2840 */ 2841 @Test testExplicitlySelected_ExplicitInternetExpected()2842 public void testExplicitlySelected_ExplicitInternetExpected() throws Exception { 2843 // Network is explicitly selected. 2844 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2845 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2846 mConnectedNetwork.noInternetAccessExpected = false; 2847 2848 connect(); 2849 expectRegisterNetworkAgent((agentConfig) -> { 2850 assertTrue(agentConfig.explicitlySelected); 2851 assertFalse(agentConfig.acceptUnvalidated); 2852 assertFalse(agentConfig.acceptPartialConnectivity); 2853 }, (cap) -> { }); 2854 } 2855 2856 /** 2857 * Verify that when a network is explicitly selected, has role SECONDARY_TRANSIENT, but 2858 * noInternetAccessExpected is false, the {@link NetworkAgentConfig} contains the right values 2859 * of explicitlySelected, acceptUnvalidated and acceptPartialConnectivity. 2860 */ 2861 @Test testExplicitlySelected_secondaryTransient_expectNotExplicitlySelected()2862 public void testExplicitlySelected_secondaryTransient_expectNotExplicitlySelected() 2863 throws Exception { 2864 // Network is explicitly selected. 2865 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2866 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2867 mConnectedNetwork.noInternetAccessExpected = false; 2868 2869 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 2870 2871 connect(); 2872 expectRegisterNetworkAgent((agentConfig) -> { 2873 assertFalse(agentConfig.explicitlySelected); 2874 assertFalse(agentConfig.acceptUnvalidated); 2875 assertFalse(agentConfig.acceptPartialConnectivity); 2876 }, (cap) -> { }); 2877 } 2878 2879 /** 2880 * Verify that when a network is not explicitly selected, but noInternetAccessExpected is true, 2881 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2882 * acceptUnvalidated and acceptPartialConnectivity. 2883 */ 2884 @Test testExplicitlySelected_NotExplicitNoInternetExpected()2885 public void testExplicitlySelected_NotExplicitNoInternetExpected() throws Exception { 2886 // Network is no longer explicitly selected. 2887 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2888 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 2889 mConnectedNetwork.noInternetAccessExpected = true; 2890 2891 connect(); 2892 expectRegisterNetworkAgent((agentConfig) -> { 2893 assertFalse(agentConfig.explicitlySelected); 2894 assertFalse(agentConfig.acceptUnvalidated); 2895 assertTrue(agentConfig.acceptPartialConnectivity); 2896 }, (cap) -> { }); 2897 } 2898 2899 /** 2900 * Verify that when a network is explicitly selected, and noInternetAccessExpected is true, 2901 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 2902 * acceptUnvalidated and acceptPartialConnectivity. 2903 */ 2904 @Test testExplicitlySelected_ExplicitNoInternetExpected()2905 public void testExplicitlySelected_ExplicitNoInternetExpected() throws Exception { 2906 // Network is explicitly selected. 2907 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 2908 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 2909 mConnectedNetwork.noInternetAccessExpected = true; 2910 2911 connect(); 2912 expectRegisterNetworkAgent((agentConfig) -> { 2913 assertTrue(agentConfig.explicitlySelected); 2914 assertTrue(agentConfig.acceptUnvalidated); 2915 assertTrue(agentConfig.acceptPartialConnectivity); 2916 }, (cap) -> { }); 2917 } 2918 2919 /** 2920 * Verify that Rssi Monitoring is started and the callback registered after connecting. 2921 */ 2922 @Test verifyRssiMonitoringCallbackIsRegistered()2923 public void verifyRssiMonitoringCallbackIsRegistered() throws Exception { 2924 // Simulate the first connection. 2925 connect(); 2926 2927 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 2928 mWifiNetworkAgentCallbackCaptor.capture()); 2929 2930 ArrayList<Integer> thresholdsArray = new ArrayList<>(); 2931 thresholdsArray.add(RSSI_THRESHOLD_MAX); 2932 thresholdsArray.add(RSSI_THRESHOLD_MIN); 2933 mWifiNetworkAgentCallbackCaptor.getValue().onSignalStrengthThresholdsUpdated( 2934 thresholdsArray.stream().mapToInt(Integer::intValue).toArray()); 2935 mLooper.dispatchAll(); 2936 2937 ArgumentCaptor<WifiNative.WifiRssiEventHandler> rssiEventHandlerCaptor = 2938 ArgumentCaptor.forClass(WifiNative.WifiRssiEventHandler.class); 2939 verify(mWifiNative).startRssiMonitoring(anyString(), anyByte(), anyByte(), 2940 rssiEventHandlerCaptor.capture()); 2941 2942 // breach below min 2943 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MIN); 2944 mLooper.dispatchAll(); 2945 WifiInfo wifiInfo = mWifiInfo; 2946 assertEquals(RSSI_THRESHOLD_BREACH_MIN, wifiInfo.getRssi()); 2947 2948 // breach above max 2949 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MAX); 2950 mLooper.dispatchAll(); 2951 assertEquals(RSSI_THRESHOLD_BREACH_MAX, wifiInfo.getRssi()); 2952 } 2953 2954 /** 2955 * Verify that RSSI and link layer stats polling works in connected mode 2956 */ 2957 @Test verifyConnectedModeRssiPolling()2958 public void verifyConnectedModeRssiPolling() throws Exception { 2959 final long startMillis = 1_500_000_000_100L; 2960 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 2961 llStats.txmpdu_be = 1000; 2962 llStats.rxmpdu_bk = 2000; 2963 WifiNl80211Manager.SignalPollResult signalPollResult = 2964 new WifiNl80211Manager.SignalPollResult(-42, 65, 54, sFreq); 2965 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 2966 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 2967 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 2968 mCmi.enableRssiPolling(true); 2969 connect(); 2970 mLooper.dispatchAll(); 2971 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 2972 mLooper.dispatchAll(); 2973 WifiInfo wifiInfo = mWifiInfo; 2974 assertEquals(llStats.txmpdu_be, wifiInfo.txSuccess); 2975 assertEquals(llStats.rxmpdu_bk, wifiInfo.rxSuccess); 2976 assertEquals(signalPollResult.currentRssiDbm, wifiInfo.getRssi()); 2977 assertEquals(signalPollResult.txBitrateMbps, wifiInfo.getLinkSpeed()); 2978 assertEquals(signalPollResult.txBitrateMbps, wifiInfo.getTxLinkSpeedMbps()); 2979 assertEquals(signalPollResult.rxBitrateMbps, wifiInfo.getRxLinkSpeedMbps()); 2980 assertEquals(sFreq, wifiInfo.getFrequency()); 2981 verify(mPerNetwork, atLeastOnce()).getTxLinkBandwidthKbps(); 2982 verify(mPerNetwork, atLeastOnce()).getRxLinkBandwidthKbps(); 2983 verify(mWifiScoreCard).noteSignalPoll(any()); 2984 } 2985 2986 /** 2987 * Verify link bandwidth update in connected mode 2988 */ 2989 @Test verifyConnectedModeNetworkCapabilitiesBandwidthUpdate()2990 public void verifyConnectedModeNetworkCapabilitiesBandwidthUpdate() throws Exception { 2991 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(40_000); 2992 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(50_000); 2993 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 2994 .thenReturn(Pair.create(Process.INVALID_UID, "")); 2995 // Simulate the first connection. 2996 connectWithValidInitRssi(-42); 2997 2998 // NetworkCapabilities should be always updated after the connection 2999 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 3000 ArgumentCaptor.forClass(NetworkCapabilities.class); 3001 verify(mWifiInjector).makeWifiNetworkAgent( 3002 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 3003 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 3004 assertNotNull(networkCapabilities); 3005 assertEquals(-42, mWifiInfo.getRssi()); 3006 assertEquals(40_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 3007 assertEquals(50_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 3008 verify(mCmi.mNetworkAgent, times(2)) 3009 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 3010 3011 // Enable RSSI polling 3012 final long startMillis = 1_500_000_000_100L; 3013 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 3014 WifiNl80211Manager.SignalPollResult signalPollResult = 3015 new WifiNl80211Manager.SignalPollResult(-42, 65, 54, sFreq); 3016 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 3017 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 3018 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 3019 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(82_000); 3020 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(92_000); 3021 mCmi.enableRssiPolling(true); 3022 mLooper.dispatchAll(); 3023 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 3024 mLooper.dispatchAll(); 3025 3026 // NetworkCapabilities should be updated after a big change of bandwidth 3027 verify(mCmi.mNetworkAgent, times(3)) 3028 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 3029 networkCapabilities = networkCapabilitiesCaptor.getValue(); 3030 assertEquals(82_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 3031 assertEquals(92_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 3032 3033 // No update after a small change of bandwidth 3034 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(72_000); 3035 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(82_000); 3036 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 3037 mLooper.dispatchAll(); 3038 verify(mCmi.mNetworkAgent, times(3)) 3039 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 3040 networkCapabilities = networkCapabilitiesCaptor.getValue(); 3041 assertEquals(82_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 3042 assertEquals(92_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 3043 } 3044 3045 /** 3046 * Verify RSSI polling with verbose logging 3047 */ 3048 @Test verifyConnectedModeRssiPollingWithVerboseLogging()3049 public void verifyConnectedModeRssiPollingWithVerboseLogging() throws Exception { 3050 mCmi.enableVerboseLogging(true); 3051 verifyConnectedModeRssiPolling(); 3052 } 3053 3054 /** 3055 * Verify that calls to start and stop filtering multicast packets are passed on to the IpClient 3056 * instance. 3057 */ 3058 @Test verifyMcastLockManagerFilterControllerCallsUpdateIpClient()3059 public void verifyMcastLockManagerFilterControllerCallsUpdateIpClient() throws Exception { 3060 reset(mIpClient); 3061 WifiMulticastLockManager.FilterController filterController = 3062 mCmi.getMcastLockManagerFilterController(); 3063 filterController.startFilteringMulticastPackets(); 3064 verify(mIpClient).setMulticastFilter(eq(true)); 3065 filterController.stopFilteringMulticastPackets(); 3066 verify(mIpClient).setMulticastFilter(eq(false)); 3067 } 3068 3069 /** 3070 * Verifies that when 3071 * 1. Global feature support flag is set to false 3072 * 2. connected MAC randomization is on and 3073 * 3. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 3074 * 4. randomized MAC for the network to connect to is different from the current MAC. 3075 * 3076 * The factory MAC address is used for the connection, and no attempt is made to change it. 3077 */ 3078 @Test testConnectedMacRandomizationNotSupported()3079 public void testConnectedMacRandomizationNotSupported() throws Exception { 3080 // reset mWifiNative since initializeCmi() was called in setup() 3081 resetWifiNative(); 3082 3083 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 3084 initializeCmi(); 3085 initializeAndAddNetworkAndVerifySuccess(); 3086 3087 connect(); 3088 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3089 verify(mWifiNative, never()).setStaMacAddress(any(), any()); 3090 // try to retrieve factory MAC address (once at bootup, once for this connection) 3091 verify(mSettingsConfigStore, times(2)).get(any()); 3092 } 3093 3094 /** 3095 * Verifies that when 3096 * 1. connected MAC randomization is on and 3097 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 3098 * 3. randomized MAC for the network to connect to is different from the current MAC. 3099 * 3100 * Then the current MAC gets set to the randomized MAC when CMD_START_CONNECT executes. 3101 */ 3102 @Test testConnectedMacRandomizationRandomizationPersistentDifferentMac()3103 public void testConnectedMacRandomizationRandomizationPersistentDifferentMac() 3104 throws Exception { 3105 initializeAndAddNetworkAndVerifySuccess(); 3106 3107 connect(); 3108 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 3109 verify(mWifiMetrics).logStaEvent( 3110 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 3111 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3112 } 3113 3114 /** 3115 * Verifies that when 3116 * 1. connected MAC randomization is on and 3117 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 3118 * 3. randomized MAC for the network to connect to is same as the current MAC. 3119 * 3120 * Then MAC change should not occur when CMD_START_CONNECT executes. 3121 */ 3122 @Test testConnectedMacRandomizationRandomizationPersistentSameMac()3123 public void testConnectedMacRandomizationRandomizationPersistentSameMac() throws Exception { 3124 initializeAndAddNetworkAndVerifySuccess(); 3125 3126 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3127 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 3128 3129 connect(); 3130 verify(mWifiNative, never()).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 3131 verify(mWifiMetrics, never()).logStaEvent( 3132 any(), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 3133 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3134 } 3135 3136 /** 3137 * Verifies that when 3138 * 1. connected MAC randomization is on and 3139 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 3140 * 3. current MAC address is not the factory MAC. 3141 * 3142 * Then the current MAC gets set to the factory MAC when CMD_START_CONNECT executes. 3143 * @throws Exception 3144 */ 3145 @Test testConnectedMacRandomizationRandomizationNoneDifferentMac()3146 public void testConnectedMacRandomizationRandomizationNoneDifferentMac() throws Exception { 3147 initializeAndAddNetworkAndVerifySuccess(); 3148 3149 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3150 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 3151 3152 WifiConfiguration config = new WifiConfiguration(); 3153 config.SSID = TEST_SSID; 3154 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 3155 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 3156 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 3157 3158 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3159 mLooper.dispatchAll(); 3160 3161 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); 3162 verify(mWifiMetrics).logStaEvent( 3163 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 3164 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3165 } 3166 3167 /** 3168 * Verifies that when 3169 * 1. connected MAC randomization is on and 3170 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 3171 * 3172 * Then the factory MAC should be used to connect to the network. 3173 * @throws Exception 3174 */ 3175 @Test testConnectedMacRandomizationRandomizationNoneSameMac()3176 public void testConnectedMacRandomizationRandomizationNoneSameMac() throws Exception { 3177 initializeAndAddNetworkAndVerifySuccess(); 3178 3179 clearInvocations(mWifiNative, mSettingsConfigStore); 3180 3181 WifiConfiguration config = new WifiConfiguration(); 3182 config.SSID = TEST_SSID; 3183 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 3184 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 3185 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 3186 3187 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3188 mLooper.dispatchAll(); 3189 3190 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 3191 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); 3192 verify(mSettingsConfigStore, never()).put( 3193 WIFI_STA_FACTORY_MAC_ADDRESS, TEST_GLOBAL_MAC_ADDRESS.toString()); 3194 3195 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3196 3197 // Now disconnect & reconnect - should use the cached factory MAC address. 3198 mCmi.disconnect(); 3199 mLooper.dispatchAll(); 3200 3201 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3202 mLooper.dispatchAll(); 3203 3204 verify(mSettingsConfigStore, times(2)).get(WIFI_STA_FACTORY_MAC_ADDRESS); 3205 // No new call to retrieve & store factory MAC address. 3206 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); 3207 verify(mSettingsConfigStore, never()).put( 3208 WIFI_STA_FACTORY_MAC_ADDRESS, TEST_GLOBAL_MAC_ADDRESS.toString()); 3209 } 3210 3211 /** 3212 * Verifies that WifiInfo returns DEFAULT_MAC_ADDRESS as mac address when Connected MAC 3213 * Randomization is on and the device is not connected to a wifi network. 3214 */ 3215 @Test testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization()3216 public void testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization() throws Exception { 3217 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3218 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 3219 3220 connect(); 3221 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3222 3223 DisconnectEventInfo disconnectEventInfo = 3224 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 3225 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3226 mLooper.dispatchAll(); 3227 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3228 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 3229 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 3230 mLooper.dispatchAll(); 3231 3232 assertEquals("DisconnectedState", getCurrentState().getName()); 3233 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mWifiInfo.getMacAddress()); 3234 assertFalse(mWifiInfo.hasRealMacAddress()); 3235 } 3236 3237 /** 3238 * Verifies that we don't set MAC address when config returns an invalid MAC address. 3239 */ 3240 @Test testDoNotSetMacWhenInvalid()3241 public void testDoNotSetMacWhenInvalid() throws Exception { 3242 initializeAndAddNetworkAndVerifySuccess(); 3243 3244 WifiConfiguration config = new WifiConfiguration(); 3245 config.SSID = TEST_SSID; 3246 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 3247 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 3248 config.setRandomizedMacAddress(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS)); 3249 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 3250 3251 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3252 mLooper.dispatchAll(); 3253 3254 // setStaMacAddress is invoked once when ClientModeImpl starts to prevent leak of factory 3255 // MAC. 3256 verify(mWifiNative).setStaMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class)); 3257 } 3258 3259 /** 3260 * Verify that we don't crash when WifiNative returns null as the current MAC address. 3261 * @throws Exception 3262 */ 3263 @Test testMacRandomizationWifiNativeReturningNull()3264 public void testMacRandomizationWifiNativeReturningNull() throws Exception { 3265 when(mWifiNative.getMacAddress(anyString())).thenReturn(null); 3266 initializeAndAddNetworkAndVerifySuccess(); 3267 3268 connect(); 3269 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 3270 } 3271 3272 /** 3273 * Verifies that a notification is posted when a connection failure happens on a network 3274 * in the hotlist. Then verify that tapping on the notification launches an dialog, which 3275 * could be used to set the randomization setting for a network to "Trusted". 3276 */ 3277 @Test testConnectionFailureSendRandomizationSettingsNotification()3278 public void testConnectionFailureSendRandomizationSettingsNotification() throws Exception { 3279 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 3280 // Setup CONNECT_MODE & a WifiConfiguration 3281 initializeAndAddNetworkAndVerifySuccess(); 3282 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 3283 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3284 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT); 3285 mLooper.dispatchAll(); 3286 3287 WifiConfiguration config = mCmi.getConnectedWifiConfiguration(); 3288 verify(mConnectionFailureNotifier) 3289 .showFailedToConnectDueToNoRandomizedMacSupportNotification(FRAMEWORK_NETWORK_ID); 3290 } 3291 3292 /** 3293 * Verifies that a notification is not posted when a wrong password failure happens on a 3294 * network in the hotlist. 3295 */ 3296 @Test testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword()3297 public void testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword() throws Exception { 3298 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 3299 // Setup CONNECT_MODE & a WifiConfiguration 3300 initializeAndAddNetworkAndVerifySuccess(); 3301 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 3302 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3303 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 3304 mLooper.dispatchAll(); 3305 3306 verify(mConnectionFailureNotifier, never()) 3307 .showFailedToConnectDueToNoRandomizedMacSupportNotification(anyInt()); 3308 } 3309 3310 /** 3311 * Verifies that CMD_START_CONNECT make WifiDiagnostics report 3312 * CONNECTION_EVENT_STARTED 3313 * @throws Exception 3314 */ 3315 @Test testReportConnectionEventIsCalledAfterCmdStartConnect()3316 public void testReportConnectionEventIsCalledAfterCmdStartConnect() throws Exception { 3317 // Setup CONNECT_MODE & a WifiConfiguration 3318 initializeAndAddNetworkAndVerifySuccess(); 3319 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3320 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3321 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED), any()); 3322 mLooper.dispatchAll(); 3323 verify(mWifiDiagnostics).reportConnectionEvent( 3324 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED), any()); 3325 } 3326 3327 /** 3328 * Verifies that CMD_DIAG_CONNECT_TIMEOUT is processed after the timeout threshold if we 3329 * start a connection but do not finish it. 3330 * @throws Exception 3331 */ 3332 @Test testCmdDiagsConnectTimeoutIsGeneratedAfterCmdStartConnect()3333 public void testCmdDiagsConnectTimeoutIsGeneratedAfterCmdStartConnect() throws Exception { 3334 // Setup CONNECT_MODE & a WifiConfiguration 3335 initializeAndAddNetworkAndVerifySuccess(); 3336 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3337 mLooper.dispatchAll(); 3338 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS); 3339 mLooper.dispatchAll(); 3340 verify(mWifiDiagnostics).reportConnectionEvent( 3341 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 3342 } 3343 3344 /** 3345 * Verifies that CMD_DIAG_CONNECT_TIMEOUT does not get processed before the timeout threshold. 3346 * @throws Exception 3347 */ 3348 @Test testCmdDiagsConnectTimeoutIsNotProcessedBeforeTimerExpires()3349 public void testCmdDiagsConnectTimeoutIsNotProcessedBeforeTimerExpires() throws Exception { 3350 // Setup CONNECT_MODE & a WifiConfiguration 3351 initializeAndAddNetworkAndVerifySuccess(); 3352 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3353 mLooper.dispatchAll(); 3354 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS - 1000); 3355 mLooper.dispatchAll(); 3356 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3357 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 3358 } 3359 verifyConnectionEventTimeoutDoesNotOccur()3360 private void verifyConnectionEventTimeoutDoesNotOccur() { 3361 mLooper.moveTimeForward(ClientModeImpl.DIAGS_CONNECT_TIMEOUT_MILLIS); 3362 mLooper.dispatchAll(); 3363 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3364 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 3365 } 3366 3367 /** 3368 * Verifies that association failures make WifiDiagnostics report CONNECTION_EVENT_FAILED 3369 * and then cancel any pending timeouts. 3370 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3371 * @throws Exception 3372 */ 3373 @Test testReportConnectionEventIsCalledAfterAssociationFailure()3374 public void testReportConnectionEventIsCalledAfterAssociationFailure() throws Exception { 3375 mConnectedNetwork.getNetworkSelectionStatus() 3376 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 3377 .getScanResult()); 3378 // Setup CONNECT_MODE & a WifiConfiguration 3379 initializeAndAddNetworkAndVerifySuccess(); 3380 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3381 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3382 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 3383 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 3384 verify(mWifiDiagnostics, never()).reportConnectionEvent( 3385 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 3386 mLooper.dispatchAll(); 3387 verify(mWifiDiagnostics).reportConnectionEvent( 3388 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 3389 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3390 mClientModeManager, 3391 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION, TEST_BSSID_STR, 3392 TEST_SSID); 3393 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3394 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 3395 any(WifiConfiguration.class), eq(TEST_BSSID_STR)); 3396 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3397 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 3398 any(WifiConfiguration.class), eq(null)); 3399 verify(mWifiMetrics, never()) 3400 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3401 verifyConnectionEventTimeoutDoesNotOccur(); 3402 3403 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 3404 mWifiNetworkSuggestionsManager); 3405 3406 // Now trigger a disconnect event from supplicant, this should be ignored since the 3407 // connection tracking should have already ended. 3408 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 3409 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 3410 mLooper.dispatchAll(); 3411 3412 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 3413 mWifiNetworkSuggestionsManager); 3414 } 3415 3416 /** 3417 * Verifies that authentication failures make WifiDiagnostics report 3418 * CONNECTION_EVENT_FAILED and then cancel any pending timeouts. 3419 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3420 * @throws Exception 3421 */ 3422 @Test testReportConnectionEventIsCalledAfterAuthenticationFailure()3423 public void testReportConnectionEventIsCalledAfterAuthenticationFailure() throws Exception { 3424 mConnectedNetwork.getNetworkSelectionStatus() 3425 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 3426 .getScanResult()); 3427 // Setup CONNECT_MODE & a WifiConfiguration 3428 initializeAndAddNetworkAndVerifySuccess(); 3429 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3430 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3431 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 3432 mLooper.dispatchAll(); 3433 verify(mWifiDiagnostics).reportConnectionEvent( 3434 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 3435 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3436 mClientModeManager, 3437 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, TEST_BSSID_STR, 3438 TEST_SSID); 3439 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3440 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 3441 any(WifiConfiguration.class), eq(TEST_BSSID_STR)); 3442 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3443 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 3444 any(WifiConfiguration.class), eq(null)); 3445 verify(mWifiMetrics, never()) 3446 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3447 verifyConnectionEventTimeoutDoesNotOccur(); 3448 3449 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 3450 mWifiNetworkSuggestionsManager); 3451 3452 // Now trigger a disconnect event from supplicant, this should be ignored since the 3453 // connection tracking should have already ended. 3454 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 3455 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 3456 mLooper.dispatchAll(); 3457 3458 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 3459 mWifiNetworkSuggestionsManager); 3460 } 3461 3462 /** 3463 * Verify that if a NETWORK_DISCONNECTION_EVENT is received in L3ConnectedState, then an 3464 * abnormal disconnect is reported to WifiBlocklistMonitor. 3465 */ 3466 @Test testAbnormalDisconnectNotifiesWifiBlocklistMonitor()3467 public void testAbnormalDisconnectNotifiesWifiBlocklistMonitor() throws Exception { 3468 // trigger RSSI poll to update WifiInfo 3469 mCmi.enableRssiPolling(true); 3470 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 3471 llStats.txmpdu_be = 1000; 3472 llStats.rxmpdu_bk = 2000; 3473 WifiNl80211Manager.SignalPollResult signalPollResult = 3474 new WifiNl80211Manager.SignalPollResult(TEST_RSSI, 65, 54, sFreq); 3475 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 3476 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 3477 3478 connect(); 3479 mLooper.dispatchAll(); 3480 DisconnectEventInfo disconnectEventInfo = 3481 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 3482 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3483 mLooper.dispatchAll(); 3484 3485 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3486 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_ABNORMAL_DISCONNECT), anyInt()); 3487 } 3488 3489 /** 3490 * Verify that ClientModeImpl notifies WifiBlocklistMonitor correctly when the RSSI is 3491 * too low. 3492 */ 3493 @Test testNotifiesWifiBlocklistMonitorLowRssi()3494 public void testNotifiesWifiBlocklistMonitorLowRssi() throws Exception { 3495 int testLowRssi = -80; 3496 initializeAndAddNetworkAndVerifySuccess(); 3497 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, 3498 ClientModeImpl.SUPPLICANT_BSSID_ANY); 3499 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3500 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, true)); 3501 when(mWifiConfigManager.findScanRssi(eq(FRAMEWORK_NETWORK_ID), anyInt())) 3502 .thenReturn(testLowRssi); 3503 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3504 .thenReturn(mScanDetailCache); 3505 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 3506 getGoogleGuestScanDetail(testLowRssi, TEST_BSSID_STR, sFreq)); 3507 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 3508 getGoogleGuestScanDetail(testLowRssi, TEST_BSSID_STR, sFreq).getScanResult()); 3509 mLooper.dispatchAll(); 3510 3511 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(TEST_BSSID_STR, TEST_SSID, 3512 WifiBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, testLowRssi); 3513 } 3514 3515 /** 3516 * Verify that the recent failure association status is updated properly when 3517 * ASSOC_REJECTED_TEMPORARILY occurs. 3518 */ 3519 @Test testAssocRejectedTemporarilyUpdatesRecentAssociationFailureStatus()3520 public void testAssocRejectedTemporarilyUpdatesRecentAssociationFailureStatus() 3521 throws Exception { 3522 initializeAndAddNetworkAndVerifySuccess(); 3523 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3524 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3525 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 3526 ISupplicantStaIfaceCallback.StatusCode.ASSOC_REJECTED_TEMPORARILY, 3527 false)); 3528 mLooper.dispatchAll(); 3529 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3530 eq(WifiConfiguration.RECENT_FAILURE_REFUSED_TEMPORARILY)); 3531 } 3532 3533 /** 3534 * Verify that WifiScoreCard and WifiBlocklistMonitor are notified properly when 3535 * disconnection occurs in middle of connection states. 3536 */ 3537 @Test testDisconnectConnecting()3538 public void testDisconnectConnecting() throws Exception { 3539 initializeAndAddNetworkAndVerifySuccess(); 3540 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3541 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 3542 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 3543 ISupplicantStaIfaceCallback.ReasonCode.FOURWAY_HANDSHAKE_TIMEOUT, 3544 false)); 3545 mLooper.dispatchAll(); 3546 verify(mWifiScoreCard).noteConnectionFailure(any(), anyInt(), anyString(), anyInt()); 3547 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 3548 // Verify that the WifiBlocklistMonitor is notified of a non-locally generated disconnect 3549 // that occurred mid connection attempt. 3550 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(anyString(), anyString(), 3551 eq(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING), anyInt()); 3552 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(), 3553 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES)); 3554 } 3555 3556 /** 3557 * Verify that the WifiConfigManager is notified when a network experiences consecutive 3558 * connection failures. 3559 */ 3560 @Test testDisableNetworkConsecutiveFailures()3561 public void testDisableNetworkConsecutiveFailures() throws Exception { 3562 initializeAndAddNetworkAndVerifySuccess(); 3563 when(mPerNetworkRecentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE)) 3564 .thenReturn(WifiBlocklistMonitor.NUM_CONSECUTIVE_FAILURES_PER_NETWORK_EXP_BACKOFF); 3565 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 3566 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 3567 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 3568 ISupplicantStaIfaceCallback.ReasonCode.FOURWAY_HANDSHAKE_TIMEOUT, 3569 false)); 3570 mLooper.dispatchAll(); 3571 verify(mWifiScoreCard).noteConnectionFailure(any(), anyInt(), anyString(), anyInt()); 3572 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 3573 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(anyString(), anyString(), 3574 eq(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING), anyInt()); 3575 verify(mWifiConfigManager).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 3576 WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES); 3577 } 3578 3579 /** 3580 * Verify that the recent failure association status is updated properly when 3581 * DENIED_POOR_CHANNEL_CONDITIONS occurs. 3582 */ 3583 @Test testAssocRejectedPoorChannelConditionsUpdatesRecentAssociationFailureStatus()3584 public void testAssocRejectedPoorChannelConditionsUpdatesRecentAssociationFailureStatus() 3585 throws Exception { 3586 initializeAndAddNetworkAndVerifySuccess(); 3587 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3588 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3589 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 3590 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS, 3591 false)); 3592 mLooper.dispatchAll(); 3593 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3594 eq(WifiConfiguration.RECENT_FAILURE_POOR_CHANNEL_CONDITIONS)); 3595 } 3596 3597 /** 3598 * Verify that the recent failure association status is updated properly when a disconnection 3599 * with reason code DISASSOC_AP_BUSY occurs. 3600 */ 3601 @Test testNetworkDisconnectionApBusyUpdatesRecentAssociationFailureStatus()3602 public void testNetworkDisconnectionApBusyUpdatesRecentAssociationFailureStatus() 3603 throws Exception { 3604 connect(); 3605 // Disconnection with reason = DISASSOC_AP_BUSY 3606 DisconnectEventInfo disconnectEventInfo = 3607 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 5, false); 3608 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3609 mLooper.dispatchAll(); 3610 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3611 eq(WifiConfiguration.RECENT_FAILURE_DISCONNECTION_AP_BUSY)); 3612 } 3613 3614 /** 3615 * Verify that the recent failure association status is updated properly when a disconnection 3616 * with reason code DISASSOC_AP_BUSY occurs. 3617 */ 3618 @Test testMidConnectionDisconnectionApBusyUpdatesRecentAssociationFailureStatus()3619 public void testMidConnectionDisconnectionApBusyUpdatesRecentAssociationFailureStatus() 3620 throws Exception { 3621 initializeAndAddNetworkAndVerifySuccess(); 3622 startConnectSuccess(); 3623 assertEquals("L2ConnectingState", getCurrentState().getName()); 3624 3625 // Disconnection with reason = DISASSOC_AP_BUSY 3626 DisconnectEventInfo disconnectEventInfo = 3627 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 5, false); 3628 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3629 mLooper.dispatchAll(); 3630 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3631 eq(WifiConfiguration.RECENT_FAILURE_DISCONNECTION_AP_BUSY)); 3632 } 3633 3634 /** 3635 * Verify that the recent failure association status is updated properly when 3636 * ASSOCIATION_REJECTION_EVENT with OCE RSSI based association rejection attribute is received. 3637 */ 3638 @Test testOceRssiBasedAssociationRejectionUpdatesRecentAssociationFailureStatus()3639 public void testOceRssiBasedAssociationRejectionUpdatesRecentAssociationFailureStatus() 3640 throws Exception { 3641 assumeTrue(SdkLevel.isAtLeastS()); 3642 initializeAndAddNetworkAndVerifySuccess(); 3643 AssociationRejectionData assocRejectData = new AssociationRejectionData(); 3644 assocRejectData.ssid = NativeUtil.decodeSsid(TEST_SSID); 3645 assocRejectData.bssid = NativeUtil.macAddressToByteArray(TEST_BSSID_STR); 3646 assocRejectData.statusCode = 3647 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS; 3648 assocRejectData.isOceRssiBasedAssocRejectAttrPresent = true; 3649 assocRejectData.oceRssiBasedAssocRejectData.retryDelayS = 10; 3650 assocRejectData.oceRssiBasedAssocRejectData.deltaRssi = 20; 3651 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3652 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3653 new AssocRejectEventInfo(assocRejectData)); 3654 mLooper.dispatchAll(); 3655 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3656 eq(WifiConfiguration.RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION)); 3657 } 3658 3659 /** 3660 * Verify that the recent failure association status is updated properly when 3661 * ASSOCIATION_REJECTION_EVENT with MBO association disallowed attribute is received. 3662 */ 3663 @Test testMboAssocDisallowedIndInAssocRejectUpdatesRecentAssociationFailureStatus()3664 public void testMboAssocDisallowedIndInAssocRejectUpdatesRecentAssociationFailureStatus() 3665 throws Exception { 3666 assumeTrue(SdkLevel.isAtLeastS()); 3667 initializeAndAddNetworkAndVerifySuccess(); 3668 AssociationRejectionData assocRejectData = new AssociationRejectionData(); 3669 assocRejectData.ssid = NativeUtil.decodeSsid(TEST_SSID); 3670 assocRejectData.bssid = NativeUtil.macAddressToByteArray(TEST_BSSID_STR); 3671 assocRejectData.statusCode = 3672 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS; 3673 assocRejectData.isMboAssocDisallowedReasonCodePresent = true; 3674 assocRejectData.mboAssocDisallowedReason = MboAssocDisallowedReasonCode 3675 .MAX_NUM_STA_ASSOCIATED; 3676 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3677 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3678 new AssocRejectEventInfo(assocRejectData)); 3679 mLooper.dispatchAll(); 3680 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 3681 eq(WifiConfiguration.RECENT_FAILURE_MBO_ASSOC_DISALLOWED_MAX_NUM_STA_ASSOCIATED)); 3682 } 3683 3684 /** 3685 * Verifies that the WifiBlocklistMonitor is notified, but the WifiLastResortWatchdog is 3686 * not notified of association rejections of type REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA. 3687 * @throws Exception 3688 */ 3689 @Test testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog()3690 public void testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog() 3691 throws Exception { 3692 initializeAndAddNetworkAndVerifySuccess(); 3693 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3694 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3695 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 3696 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 3697 mLooper.dispatchAll(); 3698 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3699 anyString(), anyString(), anyInt(), anyBoolean()); 3700 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3701 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA), 3702 anyInt()); 3703 } 3704 3705 /** 3706 * Verifies that the WifiBlocklistMonitor is notified, but the WifiLastResortWatchdog is 3707 * not notified of association rejections of type DENIED_INSUFFICIENT_BANDWIDTH. 3708 * @throws Exception 3709 */ 3710 @Test testAssociationRejectionWithReasonDeniedInsufficientBandwidth()3711 public void testAssociationRejectionWithReasonDeniedInsufficientBandwidth() 3712 throws Exception { 3713 initializeAndAddNetworkAndVerifySuccess(); 3714 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3715 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3716 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, ISupplicantStaIfaceCallback 3717 .StatusCode.DENIED_INSUFFICIENT_BANDWIDTH, false)); 3718 mLooper.dispatchAll(); 3719 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3720 anyString(), anyString(), anyInt(), anyBoolean()); 3721 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3722 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA), 3723 anyInt()); 3724 } 3725 3726 /** 3727 * Verifies that WifiLastResortWatchdog and WifiBlocklistMonitor is notified of 3728 * general association rejection failures. 3729 * @throws Exception 3730 */ 3731 @Test testAssociationRejectionUpdatesWatchdog()3732 public void testAssociationRejectionUpdatesWatchdog() throws Exception { 3733 initializeAndAddNetworkAndVerifySuccess(); 3734 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 3735 config.carrierId = CARRIER_ID_1; 3736 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3737 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3738 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 3739 mLooper.dispatchAll(); 3740 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 3741 anyString(), anyString(), anyInt(), anyBoolean()); 3742 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3743 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_ASSOCIATION_REJECTION), anyInt()); 3744 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionNonAuthFailure(); 3745 } 3746 3747 /** 3748 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 3749 * ERROR_AUTH_FAILURE_WRONG_PSWD. 3750 * @throws Exception 3751 */ 3752 @Test testFailureWrongPassIsIgnoredByWatchdog()3753 public void testFailureWrongPassIsIgnoredByWatchdog() throws Exception { 3754 // Setup CONNECT_MODE & a WifiConfiguration 3755 initializeAndAddNetworkAndVerifySuccess(); 3756 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3757 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3758 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 3759 SupplicantState.COMPLETED)); 3760 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3761 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD); 3762 mLooper.dispatchAll(); 3763 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3764 anyString(), anyString(), anyInt(), anyBoolean()); 3765 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3766 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_WRONG_PASSWORD), anyInt()); 3767 } 3768 3769 /** 3770 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 3771 * ERROR_AUTH_FAILURE_EAP_FAILURE. 3772 * @throws Exception 3773 */ 3774 @Test testEapFailureIsIgnoredByWatchdog()3775 public void testEapFailureIsIgnoredByWatchdog() throws Exception { 3776 // Setup CONNECT_MODE & a WifiConfiguration 3777 initializeAndAddNetworkAndVerifySuccess(); 3778 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3779 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3780 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 3781 SupplicantState.COMPLETED)); 3782 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3783 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE); 3784 mLooper.dispatchAll(); 3785 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 3786 anyString(), anyString(), anyInt(), anyBoolean()); 3787 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3788 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_EAP_FAILURE), anyInt()); 3789 } 3790 3791 /** 3792 * Verifies that WifiLastResortWatchdog is notified of other types of authentication failures. 3793 * @throws Exception 3794 */ 3795 @Test testAuthenticationFailureUpdatesWatchdog()3796 public void testAuthenticationFailureUpdatesWatchdog() throws Exception { 3797 // Setup CONNECT_MODE & a WifiConfiguration 3798 initializeAndAddNetworkAndVerifySuccess(); 3799 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3800 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3801 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 3802 SupplicantState.COMPLETED)); 3803 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3804 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT); 3805 mLooper.dispatchAll(); 3806 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 3807 anyString(), anyString(), anyInt(), anyBoolean()); 3808 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 3809 eq(TEST_SSID), eq(WifiBlocklistMonitor.REASON_AUTHENTICATION_FAILURE), anyInt()); 3810 } 3811 3812 /** 3813 * Verify that WifiBlocklistMonitor is notified of the SSID pre-connection so that it could 3814 * send down to firmware the list of blocked BSSIDs. 3815 */ 3816 @Test testBssidBlocklistSentToFirmwareAfterCmdStartConnect()3817 public void testBssidBlocklistSentToFirmwareAfterCmdStartConnect() throws Exception { 3818 initializeAndAddNetworkAndVerifySuccess(); 3819 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3820 verify(mWifiBlocklistMonitor, never()).updateFirmwareRoamingConfiguration( 3821 Set.of(TEST_SSID)); 3822 mLooper.dispatchAll(); 3823 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration(Set.of(TEST_SSID)); 3824 // But don't expect to see connection success yet 3825 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 3826 // And certainly not validation success 3827 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 3828 } 3829 3830 /** 3831 * Verifies that dhcp failures make WifiDiagnostics report CONNECTION_EVENT_FAILED and then 3832 * cancel any pending timeouts. 3833 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3834 * @throws Exception 3835 */ 3836 @Test testReportConnectionEventIsCalledAfterDhcpFailure()3837 public void testReportConnectionEventIsCalledAfterDhcpFailure() throws Exception { 3838 mConnectedNetwork.getNetworkSelectionStatus() 3839 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 3840 .getScanResult()); 3841 testDhcpFailure(); 3842 verify(mWifiDiagnostics, atLeastOnce()).reportConnectionEvent( 3843 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 3844 verify(mWifiConnectivityManager, atLeastOnce()).handleConnectionAttemptEnded( 3845 mClientModeManager, 3846 WifiMetrics.ConnectionEvent.FAILURE_DHCP, TEST_BSSID_STR, TEST_SSID); 3847 verify(mWifiNetworkFactory, atLeastOnce()).handleConnectionAttemptEnded( 3848 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class), 3849 eq(TEST_BSSID_STR)); 3850 verify(mWifiNetworkSuggestionsManager, atLeastOnce()).handleConnectionAttemptEnded( 3851 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class), 3852 any(String.class)); 3853 verify(mWifiMetrics, never()) 3854 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3855 verifyConnectionEventTimeoutDoesNotOccur(); 3856 } 3857 3858 /** 3859 * Verifies that a successful validation make WifiDiagnostics report CONNECTION_EVENT_SUCCEEDED 3860 * and then cancel any pending timeouts. 3861 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 3862 */ 3863 @Test testReportConnectionEventIsCalledAfterSuccessfulConnection()3864 public void testReportConnectionEventIsCalledAfterSuccessfulConnection() throws Exception { 3865 mConnectedNetwork.getNetworkSelectionStatus() 3866 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq) 3867 .getScanResult()); 3868 connect(); 3869 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 3870 mWifiNetworkAgentCallbackCaptor.capture()); 3871 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 3872 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 3873 mLooper.dispatchAll(); 3874 3875 verify(mWifiDiagnostics).reportConnectionEvent( 3876 eq(WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED), any()); 3877 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 3878 mClientModeManager, 3879 WifiMetrics.ConnectionEvent.FAILURE_NONE, TEST_BSSID_STR, TEST_SSID); 3880 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 3881 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), any(WifiConfiguration.class), 3882 eq(TEST_BSSID_STR)); 3883 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 3884 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), any(WifiConfiguration.class), 3885 any(String.class)); 3886 verify(mCmiMonitor).onInternetValidated(mClientModeManager); 3887 // BSSID different, record this connection. 3888 verify(mWifiMetrics).incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 3889 verifyConnectionEventTimeoutDoesNotOccur(); 3890 } 3891 3892 /** 3893 * Verify that score card is notified of a connection attempt 3894 */ 3895 @Test testScoreCardNoteConnectionAttemptAfterCmdStartConnect()3896 public void testScoreCardNoteConnectionAttemptAfterCmdStartConnect() throws Exception { 3897 initializeAndAddNetworkAndVerifySuccess(); 3898 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3899 verify(mWifiScoreCard, never()).noteConnectionAttempt(any(), anyInt(), anyString()); 3900 mLooper.dispatchAll(); 3901 verify(mWifiScoreCard).noteConnectionAttempt(any(), anyInt(), anyString()); 3902 verify(mWifiConfigManager).findScanRssi(anyInt(), anyInt()); 3903 // But don't expect to see connection success yet 3904 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 3905 // And certainly not validation success 3906 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 3907 3908 } 3909 3910 /** 3911 * Verify that score card is notified of a successful connection 3912 */ 3913 @Test testScoreCardNoteConnectionComplete()3914 public void testScoreCardNoteConnectionComplete() throws Exception { 3915 Pair<String, String> l2KeyAndCluster = Pair.create("Wad", "Gab"); 3916 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(l2KeyAndCluster); 3917 connect(); 3918 mLooper.dispatchAll(); 3919 verify(mWifiScoreCard).noteIpConfiguration(any()); 3920 ArgumentCaptor<Layer2InformationParcelable> captor = 3921 ArgumentCaptor.forClass(Layer2InformationParcelable.class); 3922 verify(mIpClient, atLeastOnce()).updateLayer2Information(captor.capture()); 3923 final Layer2InformationParcelable info = captor.getValue(); 3924 assertEquals(info.l2Key, "Wad"); 3925 assertEquals(info.cluster, "Gab"); 3926 } 3927 3928 /** 3929 * Verify that score card/health monitor are notified when wifi is disabled while disconnected 3930 */ 3931 @Test testScoreCardNoteWifiDisabledWhileDisconnected()3932 public void testScoreCardNoteWifiDisabledWhileDisconnected() throws Exception { 3933 // connecting and disconnecting shouldn't note wifi disabled 3934 disconnect(); 3935 mLooper.dispatchAll(); 3936 3937 verify(mWifiScoreCard, times(1)).resetConnectionState(WIFI_IFACE_NAME); 3938 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 3939 3940 // disabling while disconnected should note wifi disabled 3941 mCmi.stop(); 3942 mLooper.dispatchAll(); 3943 verify(mWifiScoreCard, times(2)).resetConnectionState(WIFI_IFACE_NAME); 3944 } 3945 3946 /** 3947 * Verify that score card/health monitor are notified when wifi is disabled while connected 3948 */ 3949 @Test testScoreCardNoteWifiDisabledWhileConnected()3950 public void testScoreCardNoteWifiDisabledWhileConnected() throws Exception { 3951 // Get into connected state 3952 connect(); 3953 mLooper.dispatchAll(); 3954 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 3955 3956 // disabling while connected should note wifi disabled 3957 mCmi.stop(); 3958 mLooper.dispatchAll(); 3959 3960 verify(mWifiScoreCard).noteWifiDisabled(any()); 3961 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 3962 } 3963 3964 /** 3965 * Verify that IPClient instance is shutdown when wifi is disabled. 3966 */ 3967 @Test verifyIpClientShutdownWhenDisabled()3968 public void verifyIpClientShutdownWhenDisabled() throws Exception { 3969 mCmi.stop(); 3970 mLooper.dispatchAll(); 3971 verify(mIpClient).shutdown(); 3972 } 3973 3974 /** 3975 * Verify that WifiInfo's MAC address is updated when the state machine receives 3976 * NETWORK_CONNECTION_EVENT while in L3ConnectedState. 3977 */ 3978 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected()3979 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected() throws Exception { 3980 connect(); 3981 assertEquals("L3ConnectedState", getCurrentState().getName()); 3982 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3983 3984 // Verify receiving a NETWORK_CONNECTION_EVENT changes the MAC in WifiInfo 3985 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 3986 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 3987 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 3988 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 3989 mLooper.dispatchAll(); 3990 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 3991 } 3992 3993 /** 3994 * Verify that WifiInfo's MAC address is updated when the state machine receives 3995 * NETWORK_CONNECTION_EVENT while in DisconnectedState. 3996 */ 3997 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected()3998 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected() throws Exception { 3999 disconnect(); 4000 assertEquals("DisconnectedState", getCurrentState().getName()); 4001 // Since MAC randomization is enabled, wifiInfo's MAC should be set to default MAC 4002 // when disconnect happens. 4003 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mWifiInfo.getMacAddress()); 4004 4005 setupAndStartConnectSequence(mConnectedNetwork); 4006 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4007 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4008 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 4009 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 4010 mLooper.dispatchAll(); 4011 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4012 } 4013 4014 @Test internetValidationFailure_notUserSelected_expectTemporarilyDisabled()4015 public void internetValidationFailure_notUserSelected_expectTemporarilyDisabled() 4016 throws Exception { 4017 // Setup RSSI poll to update WifiInfo with low RSSI 4018 mCmi.enableRssiPolling(true); 4019 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4020 llStats.txmpdu_be = 1000; 4021 llStats.rxmpdu_bk = 2000; 4022 WifiNl80211Manager.SignalPollResult signalPollResult = 4023 new WifiNl80211Manager.SignalPollResult(RSSI_THRESHOLD_BREACH_MIN, 65, 54, sFreq); 4024 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4025 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); 4026 4027 connect(); 4028 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4029 mWifiNetworkAgentCallbackCaptor.capture()); 4030 4031 WifiConfiguration currentNetwork = new WifiConfiguration(); 4032 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 4033 currentNetwork.SSID = DEFAULT_TEST_SSID; 4034 currentNetwork.noInternetAccessExpected = false; 4035 currentNetwork.numNoInternetAccessReports = 1; 4036 4037 // not user selected 4038 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 4039 .thenReturn(currentNetwork); 4040 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 4041 4042 // internet validation failure 4043 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4044 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUr; */); 4045 mLooper.dispatchAll(); 4046 4047 verify(mWifiConfigManager) 4048 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 4049 // expect temporarily disabled 4050 verify(mWifiConfigManager).updateNetworkSelectionStatus( 4051 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 4052 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(TEST_BSSID_STR, TEST_SSID, 4053 WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, RSSI_THRESHOLD_BREACH_MIN); 4054 verify(mWifiScoreCard).noteValidationFailure(any()); 4055 } 4056 4057 @Test mbb_internetValidationError_expectDisconnect()4058 public void mbb_internetValidationError_expectDisconnect() throws Exception { 4059 connect(); 4060 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4061 mWifiNetworkAgentCallbackCaptor.capture()); 4062 4063 // Make Before Break CMM 4064 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4065 4066 // internet validation failure 4067 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4068 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUr; */); 4069 mLooper.dispatchAll(); 4070 4071 // expect disconnection 4072 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 4073 } 4074 4075 @Test captivePortalDetected_notifiesCmiMonitor()4076 public void captivePortalDetected_notifiesCmiMonitor() throws Exception { 4077 connect(); 4078 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4079 mWifiNetworkAgentCallbackCaptor.capture()); 4080 4081 // captive portal detected 4082 when(mMockUri.toString()).thenReturn("TEST_URI"); 4083 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4084 NetworkAgent.VALIDATION_STATUS_NOT_VALID, mMockUri); 4085 mLooper.dispatchAll(); 4086 4087 verify(mWifiConfigManager).noteCaptivePortalDetected(anyInt()); 4088 verify(mCmiMonitor).onCaptivePortalDetected(mClientModeManager); 4089 } 4090 4091 @Test internetValidationFailure_userSelectedRecently_expectNotDisabled()4092 public void internetValidationFailure_userSelectedRecently_expectNotDisabled() 4093 throws Exception { 4094 connect(); 4095 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4096 mWifiNetworkAgentCallbackCaptor.capture()); 4097 4098 WifiConfiguration currentNetwork = new WifiConfiguration(); 4099 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 4100 currentNetwork.noInternetAccessExpected = false; 4101 currentNetwork.numNoInternetAccessReports = 1; 4102 4103 // user last picked this network 4104 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 4105 .thenReturn(currentNetwork); 4106 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); 4107 4108 // user recently picked this network 4109 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(1234L); 4110 when(mClock.getElapsedSinceBootMillis()).thenReturn(1235L); 4111 4112 // internet validation failure 4113 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4114 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 4115 mLooper.dispatchAll(); 4116 4117 verify(mWifiConfigManager) 4118 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 4119 // expect not disabled 4120 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 4121 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 4122 } 4123 4124 @Test internetValidationFailure_userSelectedTooLongAgo_expectTemporarilyDisabled()4125 public void internetValidationFailure_userSelectedTooLongAgo_expectTemporarilyDisabled() 4126 throws Exception { 4127 connect(); 4128 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4129 mWifiNetworkAgentCallbackCaptor.capture()); 4130 4131 WifiConfiguration currentNetwork = new WifiConfiguration(); 4132 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 4133 currentNetwork.noInternetAccessExpected = false; 4134 currentNetwork.numNoInternetAccessReports = 1; 4135 4136 // user last picked this network 4137 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 4138 .thenReturn(currentNetwork); 4139 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); 4140 4141 // user picked this network a long time ago 4142 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(1234L); 4143 when(mClock.getElapsedSinceBootMillis()) 4144 .thenReturn(1235L + ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS); 4145 4146 // internet validation failure 4147 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4148 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 4149 mLooper.dispatchAll(); 4150 4151 verify(mWifiConfigManager) 4152 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 4153 // expect temporarily disabled 4154 verify(mWifiConfigManager).updateNetworkSelectionStatus( 4155 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 4156 } 4157 4158 @Test noInternetExpectedNetwork_internetValidationFailure_notUserSelected_expectNotDisabled()4159 public void noInternetExpectedNetwork_internetValidationFailure_notUserSelected_expectNotDisabled() 4160 throws Exception { 4161 connect(); 4162 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4163 mWifiNetworkAgentCallbackCaptor.capture()); 4164 4165 WifiConfiguration currentNetwork = new WifiConfiguration(); 4166 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 4167 // no internet expected 4168 currentNetwork.noInternetAccessExpected = true; 4169 currentNetwork.numNoInternetAccessReports = 1; 4170 4171 // user didn't pick this network 4172 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 4173 .thenReturn(currentNetwork); 4174 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 4175 4176 // internet validation failure 4177 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4178 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 4179 mLooper.dispatchAll(); 4180 4181 verify(mWifiConfigManager) 4182 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 4183 // expect not disabled 4184 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 4185 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 4186 } 4187 4188 /** 4189 * Verify that we do not set the user connect choice after a successful connection if the 4190 * connection is not made by the user. 4191 */ 4192 @Test testNonSettingsConnectionNotSetUserConnectChoice()4193 public void testNonSettingsConnectionNotSetUserConnectChoice() throws Exception { 4194 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 4195 connect(); 4196 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 4197 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), eq(false), 4198 anyInt()); 4199 } 4200 4201 /** 4202 * Verify that we do not set the user connect choice after connecting to a newly added network. 4203 */ 4204 @Test testNoSetUserConnectChoiceOnFirstConnection()4205 public void testNoSetUserConnectChoiceOnFirstConnection() throws Exception { 4206 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 4207 connect(); 4208 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 4209 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), eq(false), 4210 anyInt()); 4211 } 4212 4213 /** 4214 * Verify that on the second successful connection to a network we set the user connect choice. 4215 */ 4216 @Test testConnectionSetUserConnectChoiceOnSecondConnection()4217 public void testConnectionSetUserConnectChoiceOnSecondConnection() throws Exception { 4218 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 4219 mTestNetworkParams.hasEverConnected = true; 4220 connect(); 4221 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 4222 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), eq(true), 4223 anyInt()); 4224 } 4225 4226 /** 4227 * Verify that we enable the network when we detect validated internet access. 4228 */ 4229 @Test verifyNetworkSelectionEnableOnInternetValidation()4230 public void verifyNetworkSelectionEnableOnInternetValidation() throws Exception { 4231 // Simulate the first connection. 4232 connect(); 4233 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 4234 verify(mWifiBlocklistMonitor).handleDhcpProvisioningSuccess(TEST_BSSID_STR, TEST_SSID); 4235 verify(mWifiBlocklistMonitor, never()).handleNetworkValidationSuccess( 4236 TEST_BSSID_STR, TEST_SSID); 4237 4238 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4239 mWifiNetworkAgentCallbackCaptor.capture()); 4240 4241 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 4242 4243 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4244 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 4245 mLooper.dispatchAll(); 4246 4247 verify(mWifiConfigManager) 4248 .setNetworkValidatedInternetAccess(FRAMEWORK_NETWORK_ID, true); 4249 verify(mWifiConfigManager).updateNetworkSelectionStatus( 4250 FRAMEWORK_NETWORK_ID, DISABLED_NONE); 4251 verify(mWifiScoreCard).noteValidationSuccess(any()); 4252 verify(mWifiBlocklistMonitor).handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 4253 } 4254 4255 /** 4256 * Verify that the logic clears the terms and conditions URL after we got a notification that 4257 * the network was validated (i.e. the user accepted and internt access is available). 4258 */ 4259 @Test testTermsAndConditionsClearUrlAfterNetworkValidation()4260 public void testTermsAndConditionsClearUrlAfterNetworkValidation() throws Exception { 4261 assumeTrue(SdkLevel.isAtLeastS()); 4262 InOrder inOrder = inOrder(mWifiNetworkAgent); 4263 4264 // Simulate the first connection. 4265 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 4266 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 4267 TEST_TERMS_AND_CONDITIONS_URL); 4268 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 4269 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 4270 connect(wnmData); 4271 // Verify that link properties contains the T&C URL and captive is set to true 4272 inOrder.verify(mWifiNetworkAgent) 4273 .sendLinkProperties(argThat(linkProperties -> TEST_TERMS_AND_CONDITIONS_URL.equals( 4274 linkProperties.getCaptivePortalData().getUserPortalUrl().toString()) 4275 && linkProperties.getCaptivePortalData().isCaptive())); 4276 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 4277 verify(mWifiBlocklistMonitor).handleDhcpProvisioningSuccess(TEST_BSSID_STR, TEST_SSID); 4278 verify(mWifiBlocklistMonitor, never()) 4279 .handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 4280 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4281 mWifiNetworkAgentCallbackCaptor.capture()); 4282 4283 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 4284 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 4285 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 4286 mLooper.dispatchAll(); 4287 4288 verify(mWifiConfigManager) 4289 .setNetworkValidatedInternetAccess(FRAMEWORK_NETWORK_ID, true); 4290 verify(mWifiConfigManager).updateNetworkSelectionStatus( 4291 FRAMEWORK_NETWORK_ID, DISABLED_NONE); 4292 verify(mWifiScoreCard).noteValidationSuccess(any()); 4293 verify(mWifiBlocklistMonitor).handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 4294 4295 // Now that the network has been validated, link properties must not have a T&C URL anymore 4296 // and captive is set to false 4297 inOrder.verify(mWifiNetworkAgent) 4298 .sendLinkProperties(argThat(linkProperties -> 4299 linkProperties.getCaptivePortalData().getUserPortalUrl() == null 4300 && !linkProperties.getCaptivePortalData().isCaptive())); 4301 } 4302 connectWithValidInitRssi(int initRssiDbm)4303 private void connectWithValidInitRssi(int initRssiDbm) throws Exception { 4304 triggerConnect(); 4305 mWifiInfo.setRssi(initRssiDbm); 4306 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4307 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 4308 SupplicantState.ASSOCIATED)); 4309 mLooper.dispatchAll(); 4310 4311 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 4312 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 4313 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 4314 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 4315 mLooper.dispatchAll(); 4316 4317 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4318 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 4319 SupplicantState.COMPLETED)); 4320 mLooper.dispatchAll(); 4321 4322 assertEquals("L3ProvisioningState", getCurrentState().getName()); 4323 4324 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 4325 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 4326 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 4327 dhcpResults.baseConfiguration.ipAddress = 4328 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 4329 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 4330 dhcpResults.leaseDuration = 3600; 4331 4332 injectDhcpSuccess(dhcpResults); 4333 mLooper.dispatchAll(); 4334 4335 } 4336 4337 /** 4338 * Verify that we set the INTERNET and bandwidth capability in the network agent when connected 4339 * as a result of auto-join/legacy API's. Also verify up/down stream bandwidth values when 4340 * Rx link speed is unavailable. 4341 */ 4342 @Test verifyNetworkCapabilities()4343 public void verifyNetworkCapabilities() throws Exception { 4344 mWifiInfo.setFrequency(5825); 4345 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(40_000); 4346 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(50_000); 4347 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 4348 .thenReturn(Pair.create(Process.INVALID_UID, "")); 4349 // Simulate the first connection. 4350 connectWithValidInitRssi(-42); 4351 4352 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 4353 ArgumentCaptor.forClass(NetworkCapabilities.class); 4354 verify(mWifiInjector).makeWifiNetworkAgent( 4355 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 4356 4357 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 4358 assertNotNull(networkCapabilities); 4359 4360 // Should have internet capability. 4361 assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 4362 4363 assertEquals(mConnectedNetwork.creatorUid, networkCapabilities.getOwnerUid()); 4364 assertArrayEquals( 4365 new int[] {mConnectedNetwork.creatorUid}, 4366 networkCapabilities.getAdministratorUids()); 4367 4368 // Should set bandwidth correctly 4369 assertEquals(-42, mWifiInfo.getRssi()); 4370 assertEquals(40_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 4371 assertEquals(50_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 4372 4373 // Should set band correctly. 4374 // There is no accessor to get the band from the WifiNetworkAgentSpecifier, so match against 4375 // a WifiNetworkSpecifier. 4376 // TODO: should there be? 4377 final NetworkSpecifier spec = networkCapabilities.getNetworkSpecifier(); 4378 assertTrue(spec instanceof WifiNetworkAgentSpecifier); 4379 final WifiNetworkAgentSpecifier wnas = (WifiNetworkAgentSpecifier) spec; 4380 assertTrue(wnas.satisfiesNetworkSpecifier( 4381 new WifiNetworkSpecifier.Builder().setBand(ScanResult.WIFI_BAND_5_GHZ).build())); 4382 } 4383 4384 /** 4385 * Verify that we don't set the INTERNET capability in the network agent when connected 4386 * as a result of the new network request API. Also verify up/down stream bandwidth values 4387 * when both Tx and Rx link speed are unavailable. 4388 */ 4389 @Test verifyNetworkCapabilitiesForSpecificRequest()4390 public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception { 4391 mWifiInfo.setFrequency(2437); 4392 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000); 4393 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000); 4394 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 4395 .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME)); 4396 // Simulate the first connection. 4397 connectWithValidInitRssi(-42); 4398 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 4399 ArgumentCaptor.forClass(NetworkCapabilities.class); 4400 4401 verify(mWifiInjector).makeWifiNetworkAgent( 4402 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 4403 4404 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 4405 assertNotNull(networkCapabilities); 4406 4407 // should not have internet capability. 4408 assertFalse(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 4409 4410 NetworkSpecifier networkSpecifier = networkCapabilities.getNetworkSpecifier(); 4411 assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier); 4412 WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = 4413 (WifiNetworkAgentSpecifier) networkSpecifier; 4414 4415 // createNetworkAgentSpecifier does not write the BSSID to the current wifi configuration. 4416 WifiConfiguration expectedConfig = new WifiConfiguration( 4417 mCmi.getConnectedWifiConfiguration()); 4418 expectedConfig.BSSID = TEST_BSSID_STR; 4419 WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier = 4420 new WifiNetworkAgentSpecifier(expectedConfig, ScanResult.WIFI_BAND_24_GHZ, 4421 true /* matchLocalOnlySpecifiers */); 4422 assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier); 4423 assertEquals(TEST_UID, networkCapabilities.getRequestorUid()); 4424 assertEquals(OP_PACKAGE_NAME, networkCapabilities.getRequestorPackageName()); 4425 assertEquals(30_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 4426 assertEquals(40_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 4427 } 4428 4429 /** 4430 * Verify that we check for data stall during rssi poll 4431 * and then check that wifi link layer usage data are being updated. 4432 */ 4433 @Test verifyRssiPollChecksDataStall()4434 public void verifyRssiPollChecksDataStall() throws Exception { 4435 mCmi.enableRssiPolling(true); 4436 connect(); 4437 4438 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 4439 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 4440 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4441 mLooper.dispatchAll(); 4442 WifiLinkLayerStats newLLStats = new WifiLinkLayerStats(); 4443 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(newLLStats); 4444 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4445 mLooper.dispatchAll(); 4446 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 4447 mConnectionCapabilities, oldLLStats, newLLStats, mWifiInfo); 4448 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, newLLStats); 4449 } 4450 4451 /** 4452 * Verify that we update wifi usability stats entries during rssi poll and that when we get 4453 * a data stall we label and save the current list of usability stats entries. 4454 * @throws Exception 4455 */ 4456 @Test verifyRssiPollUpdatesWifiUsabilityMetrics()4457 public void verifyRssiPollUpdatesWifiUsabilityMetrics() throws Exception { 4458 mCmi.enableRssiPolling(true); 4459 connect(); 4460 4461 WifiLinkLayerStats stats = new WifiLinkLayerStats(); 4462 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(stats); 4463 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), 4464 any(), any(), any(), any())) 4465 .thenReturn(WifiIsUnusableEvent.TYPE_UNKNOWN); 4466 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4467 mLooper.dispatchAll(); 4468 verify(mWifiMetrics).updateWifiUsabilityStatsEntries(any(), any(), eq(stats)); 4469 verify(mWifiMetrics, never()).addToWifiUsabilityStatsList(any(), 4470 WifiUsabilityStats.LABEL_BAD, eq(anyInt()), eq(-1)); 4471 4472 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), any(), any(), any(), 4473 any())) 4474 .thenReturn(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX); 4475 when(mClock.getElapsedSinceBootMillis()).thenReturn(10L); 4476 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4477 mLooper.dispatchAll(); 4478 verify(mWifiMetrics, times(2)).updateWifiUsabilityStatsEntries(any(), any(), eq(stats)); 4479 when(mClock.getElapsedSinceBootMillis()) 4480 .thenReturn(10L + ClientModeImpl.DURATION_TO_WAIT_ADD_STATS_AFTER_DATA_STALL_MS); 4481 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4482 mLooper.dispatchAll(); 4483 verify(mWifiMetrics).addToWifiUsabilityStatsList(WIFI_IFACE_NAME, 4484 WifiUsabilityStats.LABEL_BAD, WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1); 4485 } 4486 4487 /** 4488 * Verify that when ordered to setPowerSave(true) while Interface is created, 4489 * WifiNative is called with the right powerSave mode. 4490 */ 4491 @Test verifySetPowerSaveTrueSuccess()4492 public void verifySetPowerSaveTrueSuccess() throws Exception { 4493 // called once during setup() 4494 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 4495 4496 assertTrue(mCmi.setPowerSave(true)); 4497 verify(mWifiNative, times(2)).setPowerSave(WIFI_IFACE_NAME, true); 4498 } 4499 4500 /** 4501 * Verify that when ordered to setPowerSave(false) while Interface is created, 4502 * WifiNative is called with the right powerSave mode. 4503 */ 4504 @Test verifySetPowerSaveFalseSuccess()4505 public void verifySetPowerSaveFalseSuccess() throws Exception { 4506 assertTrue(mCmi.setPowerSave(false)); 4507 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 4508 } 4509 4510 /** 4511 * Verify that we call into WifiTrafficPoller during rssi poll 4512 */ 4513 @Test verifyRssiPollCallsWifiTrafficPoller()4514 public void verifyRssiPollCallsWifiTrafficPoller() throws Exception { 4515 mCmi.enableRssiPolling(true); 4516 connect(); 4517 4518 verify(mWifiTrafficPoller).notifyOnDataActivity(anyLong(), anyLong()); 4519 } 4520 4521 /** 4522 * Verify that LinkProbeManager is updated during RSSI poll 4523 */ 4524 @Test verifyRssiPollCallsLinkProbeManager()4525 public void verifyRssiPollCallsLinkProbeManager() throws Exception { 4526 mCmi.enableRssiPolling(true); 4527 4528 connect(); 4529 // reset() should be called when RSSI polling is enabled and entering L2L3ConnectedState 4530 verify(mLinkProbeManager).resetOnNewConnection(); // called first time here 4531 verify(mLinkProbeManager, never()).resetOnScreenTurnedOn(); // not called 4532 verify(mLinkProbeManager).updateConnectionStats(any(), any()); 4533 4534 mCmi.enableRssiPolling(false); 4535 mLooper.dispatchAll(); 4536 // reset() should be called when in L2L3ConnectedState (or child states) and RSSI polling 4537 // becomes enabled 4538 mCmi.enableRssiPolling(true); 4539 mLooper.dispatchAll(); 4540 verify(mLinkProbeManager, times(1)).resetOnNewConnection(); // verify not called again 4541 verify(mLinkProbeManager).resetOnScreenTurnedOn(); // verify called here 4542 } 4543 4544 /** 4545 * Verify that when ordered to setLowLatencyMode(true), 4546 * WifiNative is called with the right lowLatency mode. 4547 */ 4548 @Test verifySetLowLatencyTrueSuccess()4549 public void verifySetLowLatencyTrueSuccess() throws Exception { 4550 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 4551 assertTrue(mCmi.setLowLatencyMode(true)); 4552 verify(mWifiNative).setLowLatencyMode(true); 4553 } 4554 4555 /** 4556 * Verify that when ordered to setLowLatencyMode(false), 4557 * WifiNative is called with the right lowLatency mode. 4558 */ 4559 @Test verifySetLowLatencyFalseSuccess()4560 public void verifySetLowLatencyFalseSuccess() throws Exception { 4561 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 4562 assertTrue(mCmi.setLowLatencyMode(false)); 4563 verify(mWifiNative).setLowLatencyMode(false); 4564 } 4565 4566 /** 4567 * Verify that when WifiNative fails to set low latency mode, 4568 * then the call setLowLatencyMode() returns with failure, 4569 */ 4570 @Test verifySetLowLatencyModeFailure()4571 public void verifySetLowLatencyModeFailure() throws Exception { 4572 final boolean lowLatencyMode = true; 4573 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(false); 4574 assertFalse(mCmi.setLowLatencyMode(lowLatencyMode)); 4575 verify(mWifiNative).setLowLatencyMode(eq(lowLatencyMode)); 4576 } 4577 4578 /** 4579 * Verify getting the factory MAC address success case. 4580 */ 4581 @Test testGetFactoryMacAddressSuccess()4582 public void testGetFactoryMacAddressSuccess() throws Exception { 4583 initializeAndAddNetworkAndVerifySuccess(); 4584 4585 clearInvocations(mWifiNative, mSettingsConfigStore); 4586 4587 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 4588 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); // try config store. 4589 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); // not native 4590 verify(mSettingsConfigStore, never()).put(eq(WIFI_STA_FACTORY_MAC_ADDRESS), any()); 4591 4592 clearInvocations(mWifiNative, mSettingsConfigStore); 4593 4594 // get it again, should now use the config store MAC address, not native. 4595 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 4596 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 4597 4598 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 4599 } 4600 4601 /** 4602 * Verify getting the factory MAC address failure case. 4603 */ 4604 @Test testGetFactoryMacAddressFail()4605 public void testGetFactoryMacAddressFail() throws Exception { 4606 initializeAndAddNetworkAndVerifySuccess(); 4607 4608 clearInvocations(mWifiNative, mSettingsConfigStore); 4609 4610 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)).thenReturn(null); 4611 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 4612 assertNull(mCmi.getFactoryMacAddress()); 4613 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 4614 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 4615 4616 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 4617 } 4618 4619 /** 4620 * Verify that when WifiNative#getStaFactoryMacAddress fails, if the device does not support 4621 * MAC randomization then the currently programmed MAC address gets returned. 4622 */ 4623 @Test testGetFactoryMacAddressFailWithNoMacRandomizationSupport()4624 public void testGetFactoryMacAddressFailWithNoMacRandomizationSupport() throws Exception { 4625 // reset mWifiNative since initializeCmi() was called in setup() 4626 resetWifiNative(); 4627 4628 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 4629 initializeCmi(); 4630 initializeAndAddNetworkAndVerifySuccess(); 4631 4632 clearInvocations(mWifiNative, mSettingsConfigStore); 4633 4634 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)).thenReturn(null); 4635 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 4636 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4637 .thenReturn(TEST_DEFAULT_MAC_ADDRESS.toString()); 4638 assertEquals(TEST_DEFAULT_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 4639 4640 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 4641 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 4642 verify(mWifiNative).getMacAddress(WIFI_IFACE_NAME); 4643 4644 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 4645 } 4646 4647 /** 4648 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 4649 */ 4650 @Test testRandomizeMacAddressOnStart()4651 public void testRandomizeMacAddressOnStart() throws Exception { 4652 ArgumentCaptor<MacAddress> macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class); 4653 verify(mWifiNative).setStaMacAddress(anyString(), macAddressCaptor.capture()); 4654 MacAddress currentMac = macAddressCaptor.getValue(); 4655 4656 assertNotEquals("The currently programmed MAC address should be different from the factory " 4657 + "MAC address after ClientModeImpl starts", 4658 mCmi.getFactoryMacAddress(), currentMac.toString()); 4659 } 4660 4661 /** 4662 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 4663 */ 4664 @Test testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled()4665 public void testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled() throws Exception { 4666 // reset mWifiNative since initializeCmi() was called in setup() 4667 resetWifiNative(); 4668 4669 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 4670 initializeCmi(); 4671 verify(mWifiNative, never()).setStaMacAddress(anyString(), any()); 4672 } 4673 4674 /** 4675 * Verify bugreport will be taken when get IP_REACHABILITY_LOST 4676 */ 4677 @Test testTakebugreportbyIpReachabilityLost()4678 public void testTakebugreportbyIpReachabilityLost() throws Exception { 4679 connect(); 4680 4681 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 4682 mLooper.dispatchAll(); 4683 verify(mWifiDiagnostics).triggerBugReportDataCapture( 4684 eq(WifiDiagnostics.REPORT_REASON_REACHABILITY_LOST)); 4685 } 4686 4687 /** 4688 * Verifies that WifiLastResortWatchdog is notified of FOURWAY_HANDSHAKE_TIMEOUT. 4689 */ 4690 @Test testHandshakeTimeoutUpdatesWatchdog()4691 public void testHandshakeTimeoutUpdatesWatchdog() throws Exception { 4692 // Setup CONNECT_MODE & a WifiConfiguration 4693 initializeAndAddNetworkAndVerifySuccess(); 4694 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4695 mLooper.dispatchAll(); 4696 // Verifies that WifiLastResortWatchdog won't be notified 4697 // by other reason code 4698 DisconnectEventInfo disconnectEventInfo = 4699 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 2, false); 4700 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4701 mLooper.dispatchAll(); 4702 4703 assertEquals("DisconnectedState", getCurrentState().getName()); 4704 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 4705 eq(TEST_SSID), eq(TEST_BSSID_STR), 4706 eq(WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION), anyBoolean()); 4707 4708 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4709 mLooper.dispatchAll(); 4710 // Verifies that WifiLastResortWatchdog be notified 4711 // for FOURWAY_HANDSHAKE_TIMEOUT. 4712 disconnectEventInfo = new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 4713 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4714 mLooper.dispatchAll(); 4715 4716 assertEquals("DisconnectedState", getCurrentState().getName()); 4717 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 4718 eq(TEST_SSID), eq(TEST_BSSID_STR), 4719 eq(WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION), anyBoolean()); 4720 4721 } 4722 4723 /** 4724 * Verify that WifiInfo is correctly populated after connection. 4725 */ 4726 @Test verifyWifiInfoGetNetworkSpecifierPackageName()4727 public void verifyWifiInfoGetNetworkSpecifierPackageName() throws Exception { 4728 mConnectedNetwork.fromWifiNetworkSpecifier = true; 4729 mConnectedNetwork.ephemeral = true; 4730 mConnectedNetwork.trusted = true; 4731 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 4732 connect(); 4733 4734 assertTrue(mWifiInfo.isEphemeral()); 4735 assertTrue(mWifiInfo.isTrusted()); 4736 assertEquals(OP_PACKAGE_NAME, 4737 mWifiInfo.getRequestingPackageName()); 4738 } 4739 4740 /** 4741 * Verify that WifiInfo is correctly populated after connection. 4742 */ 4743 @Test verifyWifiInfoGetNetworkSuggestionPackageName()4744 public void verifyWifiInfoGetNetworkSuggestionPackageName() throws Exception { 4745 mConnectedNetwork.fromWifiNetworkSuggestion = true; 4746 mConnectedNetwork.ephemeral = true; 4747 mConnectedNetwork.trusted = true; 4748 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 4749 connect(); 4750 4751 assertTrue(mWifiInfo.isEphemeral()); 4752 assertTrue(mWifiInfo.isTrusted()); 4753 assertEquals(OP_PACKAGE_NAME, 4754 mWifiInfo.getRequestingPackageName()); 4755 } 4756 4757 /** 4758 * Verify that a WifiIsUnusableEvent is logged and the current list of usability stats entries 4759 * are labeled and saved when receiving an IP reachability lost message. 4760 * @throws Exception 4761 */ 4762 @Test verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics()4763 public void verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics() throws Exception { 4764 connect(); 4765 4766 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 4767 mLooper.dispatchAll(); 4768 verify(mWifiMetrics).logWifiIsUnusableEvent(WIFI_IFACE_NAME, 4769 WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST); 4770 verify(mWifiMetrics).addToWifiUsabilityStatsList(WIFI_IFACE_NAME, 4771 WifiUsabilityStats.LABEL_BAD, 4772 WifiUsabilityStats.TYPE_IP_REACHABILITY_LOST, -1); 4773 } 4774 4775 /** 4776 * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds 4777 * to the supplicant with the SIM identity. 4778 */ 4779 @Test testSupRequestIdentity_setsIdentityResponse()4780 public void testSupRequestIdentity_setsIdentityResponse() throws Exception { 4781 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 4782 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 4783 mConnectedNetwork.SSID = DEFAULT_TEST_SSID; 4784 String expectetIdentity = "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org"; 4785 4786 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 4787 .thenReturn(DATA_SUBID); 4788 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 4789 when(mWifiCarrierInfoManager.getSimIdentity(any())) 4790 .thenReturn(Pair.create(expectetIdentity, "")); 4791 4792 triggerConnect(); 4793 4794 mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY, 4795 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID); 4796 mLooper.dispatchAll(); 4797 4798 verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME, 4799 expectetIdentity, ""); 4800 } 4801 4802 /** 4803 * Verifies that WifiLastResortWatchdog is notified of DHCP failures when recevied 4804 * NETWORK_DISCONNECTION_EVENT while in L3ProvisioningState. 4805 */ 4806 @Test testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr()4807 public void testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr() 4808 throws Exception { 4809 initializeAndAddNetworkAndVerifySuccess(); 4810 4811 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 4812 4813 startConnectSuccess(); 4814 4815 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 4816 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 4817 mLooper.dispatchAll(); 4818 4819 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4820 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 4821 SupplicantState.COMPLETED)); 4822 mLooper.dispatchAll(); 4823 4824 assertEquals("L3ProvisioningState", getCurrentState().getName()); 4825 4826 // Verifies that WifiLastResortWatchdog be notified. 4827 DisconnectEventInfo disconnectEventInfo = 4828 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 4829 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4830 mLooper.dispatchAll(); 4831 4832 assertEquals("DisconnectedState", getCurrentState().getName()); 4833 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 4834 eq(TEST_SSID), eq(TEST_BSSID_STR), 4835 eq(WifiLastResortWatchdog.FAILURE_CODE_DHCP), anyBoolean()); 4836 } 4837 4838 /** 4839 * Verifies that we trigger a disconnect when the {@link WifiConfigManager}. 4840 * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked. 4841 */ 4842 @Test testOnNetworkRemoved()4843 public void testOnNetworkRemoved() throws Exception { 4844 connect(); 4845 4846 WifiConfiguration removedNetwork = new WifiConfiguration(); 4847 removedNetwork.networkId = FRAMEWORK_NETWORK_ID; 4848 mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork); 4849 mLooper.dispatchAll(); 4850 4851 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 4852 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 4853 } 4854 4855 /** 4856 * Verifies that we trigger a disconnect when the {@link WifiConfigManager 4857 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 4858 */ 4859 @Test testOnNetworkPermanentlyDisabled()4860 public void testOnNetworkPermanentlyDisabled() throws Exception { 4861 connect(); 4862 4863 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4864 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4865 mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork, 4866 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 4867 mLooper.dispatchAll(); 4868 4869 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 4870 } 4871 4872 /** 4873 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 4874 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 4875 */ 4876 @Test testOnNetworkPermanentlyDisabledWithNoInternet()4877 public void testOnNetworkPermanentlyDisabledWithNoInternet() throws Exception { 4878 connect(); 4879 4880 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4881 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4882 mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork, 4883 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT); 4884 mLooper.dispatchAll(); 4885 4886 assertEquals("L3ConnectedState", getCurrentState().getName()); 4887 } 4888 4889 /** 4890 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 4891 * .OnNetworkUpdateListener#onNetworkTemporarilyDisabled(WifiConfiguration, int)} is invoked. 4892 */ 4893 @Test testOnNetworkTemporarilyDisabledWithNoInternet()4894 public void testOnNetworkTemporarilyDisabledWithNoInternet() throws Exception { 4895 connect(); 4896 4897 WifiConfiguration disabledNetwork = new WifiConfiguration(); 4898 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 4899 mConfigUpdateListenerCaptor.getValue().onNetworkTemporarilyDisabled(disabledNetwork, 4900 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY); 4901 mLooper.dispatchAll(); 4902 4903 assertEquals("L3ConnectedState", getCurrentState().getName()); 4904 } 4905 4906 /** 4907 * Verify that MboOce/WifiDataStall enable/disable methods are called in ClientMode. 4908 */ 4909 @Test verifyMboOceWifiDataStallSetupInClientMode()4910 public void verifyMboOceWifiDataStallSetupInClientMode() throws Exception { 4911 verify(mMboOceController).enable(); 4912 mCmi.stop(); 4913 mLooper.dispatchAll(); 4914 verify(mMboOceController).disable(); 4915 } 4916 4917 @Test verifyWifiMonitorHandlersDeregisteredOnStop()4918 public void verifyWifiMonitorHandlersDeregisteredOnStop() throws Exception { 4919 verify(mWifiMonitor, atLeastOnce()) 4920 .registerHandler(eq(WIFI_IFACE_NAME), anyInt(), any()); 4921 verify(mWifiMetrics).registerForWifiMonitorEvents(WIFI_IFACE_NAME); 4922 verify(mWifiLastResortWatchdog).registerForWifiMonitorEvents(WIFI_IFACE_NAME); 4923 4924 mCmi.stop(); 4925 mLooper.dispatchAll(); 4926 4927 verify(mWifiMonitor, atLeastOnce()) 4928 .deregisterHandler(eq(WIFI_IFACE_NAME), anyInt(), any()); 4929 verify(mWifiMetrics).deregisterForWifiMonitorEvents(WIFI_IFACE_NAME); 4930 verify(mWifiLastResortWatchdog).deregisterForWifiMonitorEvents(WIFI_IFACE_NAME); 4931 } 4932 4933 @Test onBluetoothConnectionStateChanged()4934 public void onBluetoothConnectionStateChanged() throws Exception { 4935 // reset mWifiNative since initializeCmi() was called in setup() 4936 resetWifiNative(); 4937 4938 when(mWifiGlobals.isBluetoothConnected()).thenReturn(false); 4939 initializeCmi(); 4940 verify(mWifiNative).setBluetoothCoexistenceScanMode(any(), eq(false)); 4941 4942 when(mWifiGlobals.isBluetoothConnected()).thenReturn(true); 4943 mCmi.onBluetoothConnectionStateChanged(); 4944 mLooper.dispatchAll(); 4945 verify(mWifiNative).setBluetoothCoexistenceScanMode(any(), eq(true)); 4946 4947 when(mWifiGlobals.isBluetoothConnected()).thenReturn(false); 4948 mCmi.onBluetoothConnectionStateChanged(); 4949 mLooper.dispatchAll(); 4950 verify(mWifiNative, times(2)).setBluetoothCoexistenceScanMode(any(), eq(false)); 4951 } 4952 4953 /** 4954 * Test that handleBssTransitionRequest() blocklist the BSS upon 4955 * receiving BTM request frame that contains MBO-OCE IE with an 4956 * association retry delay attribute. 4957 */ 4958 @Test testBtmFrameWithMboAssocretryDelayBlockListTheBssid()4959 public void testBtmFrameWithMboAssocretryDelayBlockListTheBssid() throws Exception { 4960 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 4961 connect(); 4962 4963 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 4964 4965 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 4966 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 4967 | MboOceConstants.BTM_DATA_FLAG_MBO_ASSOC_RETRY_DELAY_INCLUDED; 4968 btmFrmData.mBlockListDurationMs = 60000; 4969 4970 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 4971 mLooper.dispatchAll(); 4972 4973 verify(mWifiMetrics, times(1)).incrementSteeringRequestCountIncludingMboAssocRetryDelay(); 4974 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), eq(TEST_SSID), 4975 eq(btmFrmData.mBlockListDurationMs), anyInt(), anyInt()); 4976 } 4977 4978 /** 4979 * Test that handleBssTransitionRequest() blocklist the BSS upon 4980 * receiving BTM request frame that contains disassociation imminent bit 4981 * set to 1. 4982 */ 4983 @Test testBtmFrameWithDisassocImminentBitBlockListTheBssid()4984 public void testBtmFrameWithDisassocImminentBitBlockListTheBssid() throws Exception { 4985 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 4986 connect(); 4987 4988 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 4989 4990 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT; 4991 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT; 4992 4993 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 4994 mLooper.dispatchAll(); 4995 4996 verify(mWifiMetrics, never()).incrementSteeringRequestCountIncludingMboAssocRetryDelay(); 4997 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), eq(TEST_SSID), 4998 eq(MboOceConstants.DEFAULT_BLOCKLIST_DURATION_MS), anyInt(), anyInt()); 4999 } 5000 5001 /** 5002 * Test that handleBssTransitionRequest() trigger force scan for 5003 * network selection when status code is REJECT. 5004 */ 5005 @Test testBTMRequestRejectTriggerNetworkSelction()5006 public void testBTMRequestRejectTriggerNetworkSelction() throws Exception { 5007 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 5008 connect(); 5009 5010 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 5011 5012 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 5013 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 5014 | MboOceConstants.BTM_DATA_FLAG_BSS_TERMINATION_INCLUDED 5015 | MboOceConstants.BTM_DATA_FLAG_MBO_CELL_DATA_CONNECTION_PREFERENCE_INCLUDED; 5016 btmFrmData.mBlockListDurationMs = 60000; 5017 5018 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 5019 mLooper.dispatchAll(); 5020 5021 verify(mWifiBlocklistMonitor, never()).blockBssidForDurationMs(eq(TEST_BSSID_STR), 5022 eq(TEST_SSID), eq(btmFrmData.mBlockListDurationMs), anyInt(), anyInt()); 5023 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 5024 verify(mWifiMetrics, times(1)).incrementMboCellularSwitchRequestCount(); 5025 verify(mWifiMetrics, times(1)) 5026 .incrementForceScanCountDueToSteeringRequest(); 5027 5028 } 5029 5030 /** 5031 * Test that handleBssTransitionRequest() does not trigger force 5032 * scan when status code is accept. 5033 */ 5034 @Test testBTMRequestAcceptDoNotTriggerNetworkSelction()5035 public void testBTMRequestAcceptDoNotTriggerNetworkSelction() throws Exception { 5036 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 5037 connect(); 5038 5039 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 5040 5041 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT; 5042 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT; 5043 5044 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 5045 mLooper.dispatchAll(); 5046 5047 verify(mWifiConnectivityManager, never()) 5048 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 5049 } 5050 createIE(int id, byte[] bytes)5051 private static ScanResult.InformationElement createIE(int id, byte[] bytes) { 5052 ScanResult.InformationElement ie = new ScanResult.InformationElement(); 5053 ie.id = id; 5054 ie.bytes = bytes; 5055 return ie; 5056 } 5057 5058 /** 5059 * Helper function for setting up fils test. 5060 * 5061 * @param isDriverSupportFils true if driver support fils. 5062 * @return wifi configuration. 5063 */ setupFilsTest(boolean isDriverSupportFils)5064 private WifiConfiguration setupFilsTest(boolean isDriverSupportFils) { 5065 WifiConfiguration config = new WifiConfiguration(); 5066 config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); 5067 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); 5068 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); 5069 config.SSID = ScanResultUtil.createQuotedSSID(sFilsSsid); 5070 config.networkId = 1; 5071 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 5072 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 5073 5074 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 5075 if (isDriverSupportFils) { 5076 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 5077 WifiManager.WIFI_FEATURE_FILS_SHA256 | WifiManager.WIFI_FEATURE_FILS_SHA384); 5078 } else { 5079 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn((long) 0); 5080 } 5081 5082 return config; 5083 } 5084 5085 /** 5086 * Helper function for setting up a scan result with FILS supported AP. 5087 * 5088 */ setupFilsEnabledApInScanResult()5089 private void setupFilsEnabledApInScanResult() { 5090 String caps = "[WPA2-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]" 5091 + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP][ESS]"; 5092 ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(sFilsSsid), 5093 sFilsSsid, TEST_BSSID_STR, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true); 5094 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 5095 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 5096 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 5097 when(mScanRequestProxy.getScanResults()).thenReturn(Arrays.asList(scanResult)); 5098 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 5099 } 5100 5101 5102 /** 5103 * Helper function to send CMD_START_FILS_CONNECTION along with HLP IEs. 5104 * 5105 */ prepareFilsHlpPktAndSendStartConnect()5106 private void prepareFilsHlpPktAndSendStartConnect() { 5107 Layer2PacketParcelable l2Packet = new Layer2PacketParcelable(); 5108 l2Packet.dstMacAddress = TEST_GLOBAL_MAC_ADDRESS; 5109 l2Packet.payload = new byte[] {0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 5110 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x55, 0x66}; 5111 mCmi.sendMessage(ClientModeImpl.CMD_START_FILS_CONNECTION, 0, 0, 5112 Collections.singletonList(l2Packet)); 5113 mLooper.dispatchAll(); 5114 } 5115 5116 /** 5117 * Verifies that while connecting to AP, the logic looks into the scan result and 5118 * looks for AP matching the network type and ssid and update the wificonfig with FILS 5119 * AKM if supported. 5120 * 5121 * @throws Exception 5122 */ 5123 @Test testFilsAKMUpdateBeforeConnect()5124 public void testFilsAKMUpdateBeforeConnect() throws Exception { 5125 initializeAndAddNetworkAndVerifySuccess(); 5126 WifiConfiguration config = setupFilsTest(true); 5127 setupFilsEnabledApInScanResult(); 5128 5129 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5130 mLooper.dispatchAll(); 5131 5132 assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 5133 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 5134 } 5135 5136 /** 5137 * Verifies that while connecting to AP, framework updates the wifi config with 5138 * FILS AKM only if underlying driver support FILS feature. 5139 * 5140 * @throws Exception 5141 */ 5142 @Test testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils()5143 public void testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils() throws Exception { 5144 initializeAndAddNetworkAndVerifySuccess(); 5145 WifiConfiguration config = setupFilsTest(false); 5146 setupFilsEnabledApInScanResult(); 5147 5148 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5149 mLooper.dispatchAll(); 5150 5151 assertFalse(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 5152 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 5153 } 5154 5155 5156 /** 5157 * Verifies that the HLP (DHCP) packets are send to wpa_supplicant 5158 * prior to Fils connection. 5159 * 5160 * @throws Exception 5161 */ 5162 @Test testFilsHlpUpdateBeforeFilsConnection()5163 public void testFilsHlpUpdateBeforeFilsConnection() throws Exception { 5164 initializeAndAddNetworkAndVerifySuccess(); 5165 WifiConfiguration config = setupFilsTest(true); 5166 setupFilsEnabledApInScanResult(); 5167 5168 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5169 mLooper.dispatchAll(); 5170 5171 prepareFilsHlpPktAndSendStartConnect(); 5172 5173 verify(mWifiNative).flushAllHlp(eq(WIFI_IFACE_NAME)); 5174 verify(mWifiNative).addHlpReq(eq(WIFI_IFACE_NAME), any(), any()); 5175 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 5176 } 5177 5178 /** 5179 * Verifies that an association rejection in first FILS connect attempt doesn't block 5180 * the second connection attempt. 5181 * 5182 * @throws Exception 5183 */ 5184 @Test testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject()5185 public void testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject() throws Exception { 5186 initializeAndAddNetworkAndVerifySuccess(); 5187 WifiConfiguration config = setupFilsTest(true); 5188 setupFilsEnabledApInScanResult(); 5189 5190 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5191 mLooper.dispatchAll(); 5192 5193 prepareFilsHlpPktAndSendStartConnect(); 5194 5195 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 5196 5197 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5198 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 2, false)); 5199 mLooper.dispatchAll(); 5200 5201 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5202 mLooper.dispatchAll(); 5203 prepareFilsHlpPktAndSendStartConnect(); 5204 5205 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 5206 } 5207 5208 /** 5209 * Verifies Fils connection. 5210 * 5211 * @throws Exception 5212 */ 5213 @Test testFilsConnection()5214 public void testFilsConnection() throws Exception { 5215 initializeAndAddNetworkAndVerifySuccess(); 5216 WifiConfiguration config = setupFilsTest(true); 5217 setupFilsEnabledApInScanResult(); 5218 5219 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5220 mLooper.dispatchAll(); 5221 5222 prepareFilsHlpPktAndSendStartConnect(); 5223 5224 verify(mWifiMetrics, times(1)).incrementConnectRequestWithFilsAkmCount(); 5225 5226 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5227 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, true)); 5228 mLooper.dispatchAll(); 5229 5230 verify(mWifiMetrics, times(1)).incrementL2ConnectionThroughFilsAuthCount(); 5231 5232 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5233 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(sFilsSsid), 5234 TEST_BSSID_STR, SupplicantState.COMPLETED)); 5235 mLooper.dispatchAll(); 5236 5237 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5238 5239 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 5240 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 5241 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 5242 dhcpResults.baseConfiguration.ipAddress = 5243 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 5244 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 5245 dhcpResults.leaseDuration = 3600; 5246 5247 injectDhcpSuccess(dhcpResults); 5248 mLooper.dispatchAll(); 5249 5250 WifiInfo wifiInfo = mWifiInfo; 5251 assertNotNull(wifiInfo); 5252 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 5253 assertTrue(WifiSsid.createFromAsciiEncoded(sFilsSsid).equals(wifiInfo.getWifiSsid())); 5254 assertEquals("L3ConnectedState", getCurrentState().getName()); 5255 } 5256 5257 /** 5258 * Tests the wifi info is updated correctly for connecting network. 5259 */ 5260 @Test testWifiInfoOnConnectingNextNetwork()5261 public void testWifiInfoOnConnectingNextNetwork() throws Exception { 5262 mConnectedNetwork.ephemeral = true; 5263 mConnectedNetwork.trusted = true; 5264 mConnectedNetwork.oemPaid = true; 5265 mConnectedNetwork.oemPrivate = true; 5266 mConnectedNetwork.carrierMerged = true; 5267 mConnectedNetwork.osu = true; 5268 mConnectedNetwork.subscriptionId = DATA_SUBID; 5269 5270 triggerConnect(); 5271 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 5272 .thenReturn(mScanDetailCache); 5273 5274 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 5275 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 5276 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 5277 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 5278 5279 // before the fist success connection, there is no valid wifi info. 5280 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, mWifiInfo.getNetworkId()); 5281 5282 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5283 new StateChangeResult(FRAMEWORK_NETWORK_ID, 5284 TEST_WIFI_SSID, TEST_BSSID_STR, SupplicantState.ASSOCIATED)); 5285 mLooper.dispatchAll(); 5286 5287 // retrieve correct wifi info on receiving the supplicant state change event. 5288 assertEquals(FRAMEWORK_NETWORK_ID, mWifiInfo.getNetworkId()); 5289 assertEquals(mConnectedNetwork.ephemeral, mWifiInfo.isEphemeral()); 5290 assertEquals(mConnectedNetwork.trusted, mWifiInfo.isTrusted()); 5291 assertEquals(mConnectedNetwork.osu, mWifiInfo.isOsuAp()); 5292 if (SdkLevel.isAtLeastS()) { 5293 assertEquals(mConnectedNetwork.oemPaid, mWifiInfo.isOemPaid()); 5294 assertEquals(mConnectedNetwork.oemPrivate, mWifiInfo.isOemPrivate()); 5295 assertEquals(mConnectedNetwork.carrierMerged, mWifiInfo.isCarrierMerged()); 5296 assertEquals(DATA_SUBID, mWifiInfo.getSubscriptionId()); 5297 } 5298 } 5299 5300 /** 5301 * Verify that we disconnect when we mark a previous unmetered network metered. 5302 */ 5303 @Test verifyDisconnectOnMarkingNetworkMetered()5304 public void verifyDisconnectOnMarkingNetworkMetered() throws Exception { 5305 connect(); 5306 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5307 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5308 }); 5309 5310 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5311 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5312 5313 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5314 mLooper.dispatchAll(); 5315 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 5316 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 5317 eq(StaEvent.DISCONNECT_NETWORK_METERED)); 5318 } 5319 5320 /** 5321 * Verify that we only update capabilites when we mark a previous unmetered network metered. 5322 */ 5323 @Test verifyUpdateCapabilitiesOnMarkingNetworkUnmetered()5324 public void verifyUpdateCapabilitiesOnMarkingNetworkUnmetered() throws Exception { 5325 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5326 connect(); 5327 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5328 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5329 }); 5330 reset(mWifiNetworkAgent); 5331 5332 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5333 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5334 5335 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5336 mLooper.dispatchAll(); 5337 assertEquals("L3ConnectedState", getCurrentState().getName()); 5338 5339 expectNetworkAgentUpdateCapabilities((cap) -> { 5340 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5341 }); 5342 } 5343 5344 5345 /** 5346 * Verify that we disconnect when we mark a previous unmetered network metered. 5347 */ 5348 @Test verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint()5349 public void verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 5350 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5351 connect(); 5352 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5353 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5354 }); 5355 reset(mWifiNetworkAgent); 5356 5357 // Mark network metered none. 5358 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5359 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5360 5361 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 5362 WifiInfo wifiInfo = mWifiInfo; 5363 wifiInfo.setMeteredHint(true); 5364 5365 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5366 mLooper.dispatchAll(); 5367 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 5368 } 5369 5370 /** 5371 * Verify that we only update capabilites when we mark a previous unmetered network metered. 5372 */ 5373 @Test verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint()5374 public void verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint() 5375 throws Exception { 5376 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5377 connect(); 5378 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5379 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5380 }); 5381 reset(mWifiNetworkAgent); 5382 5383 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5384 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5385 5386 // Reset metered hint in WifiInfo. 5387 WifiInfo wifiInfo = mWifiInfo; 5388 wifiInfo.setMeteredHint(false); 5389 5390 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5391 mLooper.dispatchAll(); 5392 assertEquals("L3ConnectedState", getCurrentState().getName()); 5393 5394 expectNetworkAgentUpdateCapabilities((cap) -> { 5395 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5396 }); 5397 } 5398 5399 /** 5400 * Verify that we do nothing on no metered change. 5401 */ 5402 @Test verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint()5403 public void verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 5404 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5405 connect(); 5406 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5407 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5408 }); 5409 reset(mWifiNetworkAgent); 5410 5411 // Mark network metered none. 5412 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5413 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5414 5415 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 5416 WifiInfo wifiInfo = mWifiInfo; 5417 wifiInfo.setMeteredHint(true); 5418 5419 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5420 mLooper.dispatchAll(); 5421 assertEquals("L3ConnectedState", getCurrentState().getName()); 5422 5423 verifyNoMoreInteractions(mWifiNetworkAgent); 5424 } 5425 5426 /** 5427 * Verify that we do nothing on no metered change. 5428 */ 5429 @Test verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint()5430 public void verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint() throws Exception { 5431 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 5432 connect(); 5433 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 5434 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 5435 }); 5436 reset(mWifiNetworkAgent); 5437 5438 // Mark network metered none. 5439 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5440 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 5441 5442 // Reset metered hint in WifiInfo. 5443 WifiInfo wifiInfo = mWifiInfo; 5444 wifiInfo.setMeteredHint(false); 5445 5446 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5447 mLooper.dispatchAll(); 5448 assertEquals("L3ConnectedState", getCurrentState().getName()); 5449 5450 verifyNoMoreInteractions(mWifiNetworkAgent); 5451 } 5452 5453 /* 5454 * Verify that network cached data is cleared correctly in 5455 * disconnected state. 5456 */ 5457 @Test testNetworkCachedDataIsClearedCorrectlyInDisconnectedState()5458 public void testNetworkCachedDataIsClearedCorrectlyInDisconnectedState() throws Exception { 5459 // Setup CONNECT_MODE & a WifiConfiguration 5460 initializeAndAddNetworkAndVerifySuccess(); 5461 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5462 mLooper.dispatchAll(); 5463 5464 // got UNSPECIFIED during this connection attempt 5465 DisconnectEventInfo disconnectEventInfo = 5466 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 1, false); 5467 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5468 mLooper.dispatchAll(); 5469 5470 assertEquals("DisconnectedState", getCurrentState().getName()); 5471 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 5472 5473 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5474 mLooper.dispatchAll(); 5475 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 5476 disconnectEventInfo = new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 5477 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5478 mLooper.dispatchAll(); 5479 5480 assertEquals("DisconnectedState", getCurrentState().getName()); 5481 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 5482 } 5483 5484 /* 5485 * Verify that network cached data is cleared correctly in 5486 * disconnected state. 5487 */ 5488 @Test testNetworkCachedDataIsClearedCorrectlyInL3ProvisioningState()5489 public void testNetworkCachedDataIsClearedCorrectlyInL3ProvisioningState() throws Exception { 5490 initializeAndAddNetworkAndVerifySuccess(); 5491 5492 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 5493 5494 startConnectSuccess(); 5495 5496 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5497 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 5498 mLooper.dispatchAll(); 5499 5500 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5501 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 5502 SupplicantState.COMPLETED)); 5503 mLooper.dispatchAll(); 5504 5505 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5506 5507 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 5508 DisconnectEventInfo disconnectEventInfo = 5509 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 5510 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5511 mLooper.dispatchAll(); 5512 5513 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 5514 } 5515 5516 /* 5517 * Verify that network cached data is NOT cleared in L3ConnectedState. 5518 */ 5519 @Test testNetworkCachedDataIsClearedIf4WayHandshakeFailure()5520 public void testNetworkCachedDataIsClearedIf4WayHandshakeFailure() throws Exception { 5521 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 5522 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 5523 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 5524 connect(); 5525 inOrderWifiLockManager.verify(mWifiLockManager) 5526 .updateWifiClientConnected(mClientModeManager, true); 5527 5528 // got 4WAY_HANDSHAKE_TIMEOUT 5529 DisconnectEventInfo disconnectEventInfo = 5530 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 5531 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5532 mLooper.dispatchAll(); 5533 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 5534 } 5535 5536 /** 5537 * Verify that network cached data is cleared on updating a network. 5538 */ 5539 @Test testNetworkCachedDataIsClearedOnUpdatingNetwork()5540 public void testNetworkCachedDataIsClearedOnUpdatingNetwork() throws Exception { 5541 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 5542 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 5543 5544 mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig); 5545 mLooper.dispatchAll(); 5546 verify(mWifiNative).removeNetworkCachedData(eq(oldConfig.networkId)); 5547 } 5548 5549 5550 @Test testVerifyWifiInfoStateOnFrameworkDisconnect()5551 public void testVerifyWifiInfoStateOnFrameworkDisconnect() throws Exception { 5552 connect(); 5553 5554 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.COMPLETED); 5555 5556 // Now trigger disconnect 5557 mCmi.disconnect(); 5558 mLooper.dispatchAll(); 5559 5560 // get disconnect event 5561 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5562 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 5563 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 5564 mLooper.dispatchAll(); 5565 5566 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.DISCONNECTED); 5567 } 5568 5569 @Test testVerifyWifiInfoStateOnFrameworkDisconnectButMissingDisconnectEvent()5570 public void testVerifyWifiInfoStateOnFrameworkDisconnectButMissingDisconnectEvent() 5571 throws Exception { 5572 connect(); 5573 5574 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.COMPLETED); 5575 5576 // Now trigger disconnect 5577 mCmi.disconnect(); 5578 mLooper.dispatchAll(); 5579 5580 // missing disconnect event, but got supplicant state change with disconnect state instead. 5581 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5582 new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(mConnectedNetwork.SSID), 5583 TEST_BSSID_STR, SupplicantState.DISCONNECTED)); 5584 mLooper.dispatchAll(); 5585 5586 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.DISCONNECTED); 5587 } 5588 5589 /** 5590 * Ensures that we only disable the current network & set MAC address only when we exit 5591 * ConnectingState. 5592 * @throws Exception 5593 */ 5594 @Test testDisableNetworkOnExitingConnectingOrConnectedState()5595 public void testDisableNetworkOnExitingConnectingOrConnectedState() throws Exception { 5596 connect(); 5597 String oldSsid = mConnectedNetwork.SSID; 5598 5599 // Trigger connection to a different network 5600 mConnectedNetwork.SSID = oldSsid.concat("blah"); 5601 mConnectedNetwork.networkId++; 5602 mConnectedNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 5603 setupAndStartConnectSequence(mConnectedNetwork); 5604 5605 // Send disconnect event for the old network. 5606 DisconnectEventInfo disconnectEventInfo = 5607 new DisconnectEventInfo(oldSsid, TEST_BSSID_STR, 0, false); 5608 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5609 mLooper.dispatchAll(); 5610 5611 assertEquals("L2ConnectingState", getCurrentState().getName()); 5612 // Since we remain in connecting state, we should not disable the network or set random MAC 5613 // address on disconnect. 5614 verify(mWifiNative, never()).disableNetwork(WIFI_IFACE_NAME); 5615 // Set MAC address thrice - once at bootup, twice for the 2 connections. 5616 verify(mWifiNative, times(3)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 5617 5618 // Send disconnect event for the new network. 5619 disconnectEventInfo = 5620 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 5621 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5622 mLooper.dispatchAll(); 5623 5624 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 5625 // Set MAC address thrice - once at bootup, twice for the connections, 5626 // once for the disconnect. 5627 verify(mWifiNative, times(4)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 5628 } 5629 5630 @Test testIpReachabilityLostAndRoamEventsRace()5631 public void testIpReachabilityLostAndRoamEventsRace() throws Exception { 5632 connect(); 5633 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 5634 reset(mWifiNetworkAgent); 5635 5636 // Trigger ip reachability loss and ensure we trigger a disconnect. 5637 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_LOST); 5638 mLooper.dispatchAll(); 5639 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 5640 5641 // Now send a network connection (indicating a roam) event before we get the disconnect 5642 // event. 5643 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5644 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false)); 5645 mLooper.dispatchAll(); 5646 // ensure that we ignored the transient roam while we're disconnecting. 5647 verifyNoMoreInteractions(mWifiNetworkAgent); 5648 5649 // Now send the disconnect event and ensure that we transition to "DisconnectedState". 5650 DisconnectEventInfo disconnectEventInfo = 5651 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 5652 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5653 mLooper.dispatchAll(); 5654 assertEquals("DisconnectedState", getCurrentState().getName()); 5655 verify(mWifiNetworkAgent).unregister(); 5656 5657 verifyNoMoreInteractions(mWifiNetworkAgent); 5658 } 5659 5660 @Test testConnectionWhileDisconnecting()5661 public void testConnectionWhileDisconnecting() throws Exception { 5662 connect(); 5663 5664 // Trigger a disconnect event. 5665 mCmi.disconnect(); 5666 mLooper.dispatchAll(); 5667 assertEquals("L3ConnectedState", getCurrentState().getName()); 5668 5669 // Trigger a new connection before the NETWORK_DISCONNECTION_EVENT comes in. 5670 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 5671 config.networkId = FRAMEWORK_NETWORK_ID + 1; 5672 setupAndStartConnectSequence(config); 5673 // Ensure that we triggered the connection attempt. 5674 validateSuccessfulConnectSequence(config); 5675 5676 // Now trigger the disconnect event for the previous disconnect and ensure we handle it 5677 // correctly and remain in ConnectingState. 5678 DisconnectEventInfo disconnectEventInfo = 5679 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 5680 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5681 mLooper.dispatchAll(); 5682 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 5683 } 5684 5685 @Test testConnectionWatchdog()5686 public void testConnectionWatchdog() throws Exception { 5687 triggerConnect(); 5688 Log.i(TAG, "Triggering Connect done"); 5689 5690 // Simulate watchdog timeout and ensure we retuned to disconnected state. 5691 mLooper.moveTimeForward(ClientModeImpl.CONNECTING_WATCHDOG_TIMEOUT_MS + 5L); 5692 mLooper.dispatchAll(); 5693 5694 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 5695 assertEquals("DisconnectedState", mCmi.getCurrentState().getName()); 5696 } 5697 5698 @Test testRoamAfterConnectDoesNotChangeNetworkInfoInNetworkStateChangeBroadcast()5699 public void testRoamAfterConnectDoesNotChangeNetworkInfoInNetworkStateChangeBroadcast() 5700 throws Exception { 5701 connect(); 5702 5703 // The last NETWORK_STATE_CHANGED_ACTION should be to mark the network connected. 5704 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 5705 verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), any()); 5706 Intent intent = intentCaptor.getValue(); 5707 assertNotNull(intent); 5708 assertEquals(WifiManager.NETWORK_STATE_CHANGED_ACTION, intent.getAction()); 5709 NetworkInfo networkInfo = (NetworkInfo) intent.getExtra(WifiManager.EXTRA_NETWORK_INFO); 5710 assertTrue(networkInfo.isConnected()); 5711 5712 reset(mContext); 5713 when(mContext.getResources()).thenReturn(mResources); 5714 5715 // send roam event 5716 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR1); 5717 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5718 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, 5719 SupplicantState.COMPLETED)); 5720 mLooper.dispatchAll(); 5721 5722 verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), any()); 5723 intent = intentCaptor.getValue(); 5724 assertNotNull(intent); 5725 assertEquals(WifiManager.NETWORK_STATE_CHANGED_ACTION, intent.getAction()); 5726 networkInfo = (NetworkInfo) intent.getExtra(WifiManager.EXTRA_NETWORK_INFO); 5727 assertTrue(networkInfo.isConnected()); 5728 } 5729 5730 5731 /** 5732 * Ensure that {@link ClientModeImpl#dump(FileDescriptor, PrintWriter, String[])} 5733 * {@link WifiNative#getWifiLinkLayerStats(String)}, at least once before calling 5734 * {@link WifiScoreReport#dump(FileDescriptor, PrintWriter, String[])}. 5735 * 5736 * This ensures that WifiScoreReport will always get updated RSSI and link layer stats before 5737 * dumping during a bug report, no matter if the screen is on or not. 5738 */ 5739 @Test testWifiScoreReportDump()5740 public void testWifiScoreReportDump() throws Exception { 5741 connect(); 5742 5743 mLooper.startAutoDispatch(); 5744 mCmi.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); 5745 mLooper.stopAutoDispatchAndIgnoreExceptions(); 5746 5747 InOrder inOrder = inOrder(mWifiNative, mWifiScoreReport); 5748 5749 inOrder.verify(mWifiNative).getWifiLinkLayerStats(any()); 5750 inOrder.verify(mWifiScoreReport).dump(any(), any(), any()); 5751 } 5752 5753 @Test clearRequestingPackageNameInWifiInfoOnConnectionFailure()5754 public void clearRequestingPackageNameInWifiInfoOnConnectionFailure() throws Exception { 5755 mConnectedNetwork.fromWifiNetworkSpecifier = true; 5756 mConnectedNetwork.ephemeral = true; 5757 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 5758 5759 triggerConnect(); 5760 5761 // association completed 5762 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5763 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 5764 SupplicantState.ASSOCIATED)); 5765 mLooper.dispatchAll(); 5766 5767 assertTrue(mWifiInfo.isEphemeral()); 5768 assertEquals(OP_PACKAGE_NAME, mWifiInfo.getRequestingPackageName()); 5769 5770 // fail the connection. 5771 DisconnectEventInfo disconnectEventInfo = 5772 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 5773 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5774 mLooper.dispatchAll(); 5775 5776 assertFalse(mWifiInfo.isEphemeral()); 5777 assertNull(mWifiInfo.getRequestingPackageName()); 5778 } 5779 5780 @Test handleAssociationRejectionWhenRoaming()5781 public void handleAssociationRejectionWhenRoaming() throws Exception { 5782 connect(); 5783 5784 assertTrue(SupplicantState.isConnecting(mWifiInfo.getSupplicantState())); 5785 5786 when(mWifiNative.roamToNetwork(any(), any())).thenReturn(true); 5787 5788 // Trigger roam to a BSSID. 5789 mCmi.startRoamToNetwork(FRAMEWORK_NETWORK_ID, TEST_BSSID_STR1); 5790 mLooper.dispatchAll(); 5791 5792 5793 assertEquals(TEST_BSSID_STR1, mCmi.getConnectingBssid()); 5794 assertEquals(FRAMEWORK_NETWORK_ID, mCmi.getConnectingWifiConfiguration().networkId); 5795 5796 verify(mWifiNative).roamToNetwork(any(), any()); 5797 assertEquals("RoamingState", getCurrentState().getName()); 5798 5799 // fail the connection. 5800 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5801 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 5802 SupplicantState.DISCONNECTED)); 5803 mLooper.dispatchAll(); 5804 5805 // Ensure we reset WifiInfo fields. 5806 assertFalse(SupplicantState.isConnecting(mWifiInfo.getSupplicantState())); 5807 } 5808 5809 @Test testOemPaidNetworkCapability()5810 public void testOemPaidNetworkCapability() throws Exception { 5811 // oemPaid introduced in S, not applicable to R 5812 assumeTrue(SdkLevel.isAtLeastS()); 5813 mConnectedNetwork.oemPaid = true; 5814 connect(); 5815 expectRegisterNetworkAgent((agentConfig) -> { }, 5816 (cap) -> { 5817 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)); 5818 assertFalse(cap.hasCapability(NetworkCapabilities 5819 .NET_CAPABILITY_NOT_RESTRICTED)); 5820 }); 5821 } 5822 @Test testNotOemPaidNetworkCapability()5823 public void testNotOemPaidNetworkCapability() throws Exception { 5824 // oemPaid introduced in S, not applicable to R 5825 assumeTrue(SdkLevel.isAtLeastS()); 5826 mConnectedNetwork.oemPaid = false; 5827 connect(); 5828 expectRegisterNetworkAgent((agentConfig) -> { }, 5829 (cap) -> { 5830 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)); 5831 assertTrue(cap.hasCapability(NetworkCapabilities 5832 .NET_CAPABILITY_NOT_RESTRICTED)); 5833 }); 5834 } 5835 5836 @Test testOemPrivateNetworkCapability()5837 public void testOemPrivateNetworkCapability() throws Exception { 5838 // oemPrivate introduced in S, not applicable to R 5839 assumeTrue(SdkLevel.isAtLeastS()); 5840 mConnectedNetwork.oemPrivate = true; 5841 connect(); 5842 expectRegisterNetworkAgent((agentConfig) -> { }, 5843 (cap) -> { 5844 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)); 5845 assertFalse(cap.hasCapability(NetworkCapabilities 5846 .NET_CAPABILITY_NOT_RESTRICTED)); 5847 }); 5848 } 5849 5850 @Test testNotOemPrivateNetworkCapability()5851 public void testNotOemPrivateNetworkCapability() throws Exception { 5852 // oemPrivate introduced in S, not applicable to R 5853 assumeTrue(SdkLevel.isAtLeastS()); 5854 mConnectedNetwork.oemPrivate = false; 5855 connect(); 5856 expectRegisterNetworkAgent((agentConfig) -> { }, 5857 (cap) -> { 5858 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)); 5859 assertTrue(cap.hasCapability(NetworkCapabilities 5860 .NET_CAPABILITY_NOT_RESTRICTED)); 5861 }); 5862 } 5863 5864 @Test testSendLinkProbeFailure()5865 public void testSendLinkProbeFailure() throws Exception { 5866 mCmi.probeLink(mLinkProbeCallback, -1); 5867 5868 verify(mLinkProbeCallback).onFailure(LinkProbeCallback.LINK_PROBE_ERROR_NOT_CONNECTED); 5869 verify(mLinkProbeCallback, never()).onAck(anyInt()); 5870 verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt()); 5871 } 5872 5873 @Test testSendLinkProbeSuccess()5874 public void testSendLinkProbeSuccess() throws Exception { 5875 connect(); 5876 5877 mCmi.probeLink(mLinkProbeCallback, -1); 5878 5879 verify(mWifiNative).probeLink(any(), any(), eq(mLinkProbeCallback), eq(-1)); 5880 verify(mLinkProbeCallback, never()).onFailure(anyInt()); 5881 verify(mLinkProbeCallback, never()).onAck(anyInt()); 5882 } 5883 setupPasspointConnection()5884 private void setupPasspointConnection() throws Exception { 5885 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 5886 mConnectedNetwork.carrierId = CARRIER_ID_1; 5887 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 5888 .thenReturn(DATA_SUBID); 5889 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 5890 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 5891 triggerConnect(); 5892 5893 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(mConnectedNetwork); 5894 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 5895 .thenReturn(mScanDetailCache); 5896 when(mScanRequestProxy.getScanResult(TEST_BSSID_STR)).thenReturn( 5897 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 5898 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 5899 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 5900 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 5901 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 5902 5903 WifiSsid wifiSsid = WifiSsid.createFromByteArray( 5904 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 5905 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5906 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false)); 5907 mLooper.dispatchAll(); 5908 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5909 } 5910 5911 /** 5912 * When connecting to a Passpoint network, verify that the Venue URL ANQP request is sent. 5913 */ 5914 @Test testVenueUrlRequestForPasspointNetworks()5915 public void testVenueUrlRequestForPasspointNetworks() throws Exception { 5916 setupPasspointConnection(); 5917 verify(mPasspointManager).requestVenueUrlAnqpElement(any(ScanResult.class)); 5918 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5919 } 5920 5921 /** 5922 * Verify that the Venue URL ANQP request is not sent for non-Passpoint EAP networks 5923 */ 5924 @Test testVenueUrlNotRequestedForNonPasspointNetworks()5925 public void testVenueUrlNotRequestedForNonPasspointNetworks() throws Exception { 5926 setupEapSimConnection(); 5927 verify(mPasspointManager, never()).requestVenueUrlAnqpElement(any(ScanResult.class)); 5928 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5929 } 5930 5931 @Test testFirmwareRoam()5932 public void testFirmwareRoam() throws Exception { 5933 connect(); 5934 5935 // Now send a network connection (indicating a roam) event 5936 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5937 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false)); 5938 mLooper.dispatchAll(); 5939 5940 verify(mContext, times(2)).sendStickyBroadcastAsUser( 5941 argThat(new NetworkStateChangedIntentMatcher(CONNECTED)), any()); 5942 } 5943 5944 @Test testProvisioningUpdateAfterConnect()5945 public void testProvisioningUpdateAfterConnect() throws Exception { 5946 connect(); 5947 5948 // Trigger a IP params update (maybe a dhcp lease renewal). 5949 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 5950 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 5951 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 5952 dhcpResults.baseConfiguration.ipAddress = 5953 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 5954 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 5955 dhcpResults.leaseDuration = 3600; 5956 5957 injectDhcpSuccess(dhcpResults); 5958 mLooper.dispatchAll(); 5959 5960 verify(mContext, times(2)).sendStickyBroadcastAsUser( 5961 argThat(new NetworkStateChangedIntentMatcher(CONNECTED)), any()); 5962 } 5963 5964 /** 5965 * Verify that the Deauth-Imminent WNM-Notification is handled by relaying to the Passpoint 5966 * Manager. 5967 */ 5968 @Test testHandlePasspointDeauthImminentWnmNotification()5969 public void testHandlePasspointDeauthImminentWnmNotification() throws Exception { 5970 setupEapSimConnection(); 5971 WnmData wnmData = WnmData.createDeauthImminentEvent(TEST_BSSID, "", false, 5972 TEST_DELAY_IN_SECONDS); 5973 mCmi.sendMessage(WifiMonitor.HS20_DEAUTH_IMMINENT_EVENT, 0, 0, wnmData); 5974 mLooper.dispatchAll(); 5975 verify(mPasspointManager).handleDeauthImminentEvent(eq(wnmData), 5976 any(WifiConfiguration.class)); 5977 } 5978 5979 /** 5980 * Verify that the network selection status will be updated and the function onEapFailure() 5981 * in EapFailureNotifier is called when a EAP Authentication failure is detected 5982 * with carrier erroe code. 5983 */ 5984 @Test testCarrierEapFailure()5985 public void testCarrierEapFailure() throws Exception { 5986 initializeAndAddNetworkAndVerifySuccess(); 5987 5988 startConnectSuccess(); 5989 5990 WifiConfiguration config = new WifiConfiguration(); 5991 config.SSID = TEST_SSID; 5992 config.getNetworkSelectionStatus().setHasEverConnected(true); 5993 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 5994 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 5995 when(mEapFailureNotifier.onEapFailure(anyInt(), eq(config), anyBoolean())).thenReturn(true); 5996 5997 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 5998 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 5999 DEFINED_ERROR_CODE 6000 ); 6001 mLooper.dispatchAll(); 6002 6003 verify(mEapFailureNotifier).onEapFailure(DEFINED_ERROR_CODE, config, true); 6004 verify(mWifiBlocklistMonitor).loadCarrierConfigsForDisableReasonInfos(); 6005 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 6006 eq(WifiConfiguration.NetworkSelectionStatus 6007 .DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR)); 6008 } 6009 6010 /** 6011 * When connected to a Passpoint network, verify that the Venue URL and T&C URL are updated in 6012 * the {@link LinkProperties} object when provisioning complete and when link properties change 6013 * events are received. 6014 */ 6015 @Test testVenueAndTCUrlsUpdateForPasspointNetworks()6016 public void testVenueAndTCUrlsUpdateForPasspointNetworks() throws Exception { 6017 // This tests new S functionality/APIs, not applicable to R. 6018 assumeTrue(SdkLevel.isAtLeastS()); 6019 setupPasspointConnection(); 6020 when(mPasspointManager.getVenueUrl(any(ScanResult.class))).thenReturn(new URL(VENUE_URL)); 6021 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 6022 TEST_TERMS_AND_CONDITIONS_URL); 6023 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 6024 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 6025 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 6026 0, 0, wnmData); 6027 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 6028 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 6029 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 6030 dhcpResults.baseConfiguration.ipAddress = 6031 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 6032 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 6033 dhcpResults.leaseDuration = 3600; 6034 injectDhcpSuccess(dhcpResults); 6035 mCmi.mNetworkAgent = null; 6036 mLooper.dispatchAll(); 6037 LinkProperties linkProperties = mock(LinkProperties.class); 6038 mIpClientCallback.onLinkPropertiesChange(linkProperties); 6039 mLooper.dispatchAll(); 6040 verify(mPasspointManager, times(2)).getVenueUrl(any(ScanResult.class)); 6041 final ArgumentCaptor<CaptivePortalData> captivePortalDataCaptor = 6042 ArgumentCaptor.forClass(CaptivePortalData.class); 6043 verify(linkProperties).setCaptivePortalData(captivePortalDataCaptor.capture()); 6044 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 6045 captivePortalDataCaptor.getValue().getVenueFriendlyName()); 6046 assertEquals(VENUE_URL, captivePortalDataCaptor.getValue().getVenueInfoUrl().toString()); 6047 assertEquals(TEST_TERMS_AND_CONDITIONS_URL, captivePortalDataCaptor.getValue() 6048 .getUserPortalUrl().toString()); 6049 } 6050 6051 /** 6052 * Verify that the T&C WNM-Notification is handled by relaying to the Passpoint 6053 * Manager. 6054 */ 6055 @Test testHandlePasspointTermsAndConditionsWnmNotification()6056 public void testHandlePasspointTermsAndConditionsWnmNotification() throws Exception { 6057 setupEapSimConnection(); 6058 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 6059 TEST_TERMS_AND_CONDITIONS_URL); 6060 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 6061 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 6062 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 6063 0, 0, wnmData); 6064 mLooper.dispatchAll(); 6065 verify(mPasspointManager).handleTermsAndConditionsEvent(eq(wnmData), 6066 any(WifiConfiguration.class)); 6067 verify(mWifiNative, never()).disconnect(anyString()); 6068 } 6069 6070 /** 6071 * Verify that when a bad URL is received in the T&C WNM-Notification, the connection is 6072 * disconnected. 6073 */ 6074 @Test testHandlePasspointTermsAndConditionsWnmNotificationWithBadUrl()6075 public void testHandlePasspointTermsAndConditionsWnmNotificationWithBadUrl() throws Exception { 6076 setupEapSimConnection(); 6077 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 6078 TEST_TERMS_AND_CONDITIONS_URL); 6079 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 6080 any(WifiConfiguration.class))).thenReturn(null); 6081 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 6082 0, 0, wnmData); 6083 mLooper.dispatchAll(); 6084 verify(mPasspointManager).handleTermsAndConditionsEvent(eq(wnmData), 6085 any(WifiConfiguration.class)); 6086 verify(mWifiNative).disconnect(eq(WIFI_IFACE_NAME)); 6087 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 6088 eq(StaEvent.DISCONNECT_PASSPOINT_TAC)); 6089 } 6090 6091 /** 6092 * Verify that the Transition Disable event is routed correctly. 6093 */ 6094 @Test testTransitionDisableEvent()6095 public void testTransitionDisableEvent() throws Exception { 6096 final int networkId = FRAMEWORK_NETWORK_ID; 6097 final int indication = WifiMonitor.TDI_USE_WPA3_PERSONAL 6098 | WifiMonitor.TDI_USE_WPA3_ENTERPRISE; 6099 6100 initializeAndAddNetworkAndVerifySuccess(); 6101 6102 startConnectSuccess(); 6103 6104 mCmi.sendMessage(WifiMonitor.TRANSITION_DISABLE_INDICATION, 6105 networkId, indication); 6106 mLooper.dispatchAll(); 6107 6108 verify(mWifiConfigManager).updateNetworkTransitionDisable( 6109 eq(networkId), eq(indication)); 6110 } 6111 6112 /** 6113 * Verify that the network selection status will be updated with DISABLED_NETWORK_NOT_FOUND 6114 * when number of NETWORK_NOT_FOUND_EVENT event reaches the threshold. 6115 */ 6116 @Test testNetworkNotFoundEventUpdatesAssociationFailureStatus()6117 public void testNetworkNotFoundEventUpdatesAssociationFailureStatus() 6118 throws Exception { 6119 assumeTrue(SdkLevel.isAtLeastS()); 6120 initializeAndAddNetworkAndVerifySuccess(); 6121 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 6122 for (int i = 0; i < ClientModeImpl.NETWORK_NOT_FOUND_EVENT_THRESHOLD; i++) { 6123 mCmi.sendMessage(WifiMonitor.NETWORK_NOT_FOUND_EVENT, DEFAULT_TEST_SSID); 6124 } 6125 mLooper.dispatchAll(); 6126 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 6127 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_NETWORK_NOT_FOUND)); 6128 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 6129 eq(WifiConfiguration.RECENT_FAILURE_NETWORK_NOT_FOUND)); 6130 6131 verify(mWifiDiagnostics).reportConnectionEvent( 6132 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 6133 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 6134 mClientModeManager, 6135 WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND, TEST_BSSID_STR, TEST_SSID); 6136 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 6137 eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND), 6138 any(WifiConfiguration.class), eq(TEST_BSSID_STR)); 6139 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 6140 eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND), 6141 any(WifiConfiguration.class), eq(null)); 6142 verify(mWifiMetrics, never()) 6143 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 6144 verifyConnectionEventTimeoutDoesNotOccur(); 6145 6146 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 6147 mWifiNetworkSuggestionsManager); 6148 6149 // Now trigger a disconnect event from supplicant, this should be ignored since the 6150 // connection tracking should have already ended. 6151 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 6152 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 6153 mLooper.dispatchAll(); 6154 6155 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 6156 mWifiNetworkSuggestionsManager); 6157 } 6158 6159 /** 6160 * Verify that the subscriberId will be filled in NetworkAgentConfig 6161 * after connecting to a merged network. And also VCN policy will be checked. 6162 */ 6163 @Test triggerConnectToMergedNetwork()6164 public void triggerConnectToMergedNetwork() throws Exception { 6165 assumeTrue(SdkLevel.isAtLeastS()); 6166 VcnManager vcnManager = mock(VcnManager.class); 6167 VcnNetworkPolicyResult vcnUnderlyingNetworkPolicy = mock(VcnNetworkPolicyResult.class); 6168 when(mContext.getSystemService(VcnManager.class)).thenReturn(vcnManager); 6169 ArgumentCaptor<VcnManager.VcnNetworkPolicyChangeListener> policyChangeListenerCaptor = 6170 ArgumentCaptor.forClass(VcnManager.VcnNetworkPolicyChangeListener.class); 6171 InOrder inOrder = inOrder(vcnManager, vcnUnderlyingNetworkPolicy); 6172 doAnswer(new AnswerWithArguments() { 6173 public VcnNetworkPolicyResult answer(NetworkCapabilities networkCapabilities, 6174 LinkProperties linkProperties) throws Exception { 6175 networkCapabilities.removeCapability( 6176 NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 6177 when(vcnUnderlyingNetworkPolicy.getNetworkCapabilities()) 6178 .thenReturn(networkCapabilities); 6179 return vcnUnderlyingNetworkPolicy; 6180 } 6181 }).when(vcnManager).applyVcnNetworkPolicy(any(), any()); 6182 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(false); 6183 6184 String testSubscriberId = "TestSubscriberId"; 6185 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 6186 when(mDataTelephonyManager.getSubscriberId()).thenReturn(testSubscriberId); 6187 mConnectedNetwork.carrierMerged = true; 6188 mConnectedNetwork.subscriptionId = DATA_SUBID; 6189 connect(); 6190 expectRegisterNetworkAgent((agentConfig) -> { 6191 assertEquals(testSubscriberId, agentConfig.subscriberId); 6192 }, (cap) -> { 6193 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)); 6194 assertEquals(Collections.singleton(DATA_SUBID), cap.getSubscriptionIds()); 6195 }); 6196 // Verify VCN policy listener is registered 6197 inOrder.verify(vcnManager).addVcnNetworkPolicyChangeListener(any(), 6198 policyChangeListenerCaptor.capture()); 6199 assertNotNull(policyChangeListenerCaptor.getValue()); 6200 6201 // Verify getting new capability from VcnManager 6202 inOrder.verify(vcnManager).applyVcnNetworkPolicy(any(NetworkCapabilities.class), 6203 any(LinkProperties.class)); 6204 inOrder.verify(vcnUnderlyingNetworkPolicy).isTeardownRequested(); 6205 inOrder.verify(vcnUnderlyingNetworkPolicy).getNetworkCapabilities(); 6206 6207 // Update policy with tear down request. 6208 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(true); 6209 policyChangeListenerCaptor.getValue().onPolicyChanged(); 6210 mLooper.dispatchAll(); 6211 6212 // The merged carrier network should be disconnected. 6213 inOrder.verify(vcnManager).applyVcnNetworkPolicy(any(NetworkCapabilities.class), 6214 any(LinkProperties.class)); 6215 inOrder.verify(vcnUnderlyingNetworkPolicy).isTeardownRequested(); 6216 inOrder.verify(vcnUnderlyingNetworkPolicy).getNetworkCapabilities(); 6217 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 6218 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 6219 eq(StaEvent.DISCONNECT_VCN_REQUEST)); 6220 DisconnectEventInfo disconnectEventInfo = 6221 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 6222 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 6223 mLooper.dispatchAll(); 6224 assertEquals("DisconnectedState", getCurrentState().getName()); 6225 6226 // In DisconnectedState, policy update should result no capability update. 6227 reset(mWifiConfigManager, vcnManager); 6228 policyChangeListenerCaptor.getValue().onPolicyChanged(); 6229 verifyNoMoreInteractions(mWifiConfigManager, vcnManager); 6230 } 6231 6232 /** 6233 * Verify when connect to a unmerged network, will not mark it as a VCN network. 6234 */ 6235 @Test triggerConnectToUnmergedNetwork()6236 public void triggerConnectToUnmergedNetwork() throws Exception { 6237 assumeTrue(SdkLevel.isAtLeastS()); 6238 VcnManager vcnManager = mock(VcnManager.class); 6239 when(mContext.getSystemService(VcnManager.class)).thenReturn(vcnManager); 6240 VcnNetworkPolicyResult vcnUnderlyingNetworkPolicy = mock(VcnNetworkPolicyResult.class); 6241 ArgumentCaptor<VcnManager.VcnNetworkPolicyChangeListener> policyChangeListenerCaptor = 6242 ArgumentCaptor.forClass(VcnManager.VcnNetworkPolicyChangeListener.class); 6243 doAnswer(new AnswerWithArguments() { 6244 public VcnNetworkPolicyResult answer(NetworkCapabilities networkCapabilities, 6245 LinkProperties linkProperties) throws Exception { 6246 networkCapabilities.removeCapability( 6247 NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 6248 when(vcnUnderlyingNetworkPolicy.getNetworkCapabilities()) 6249 .thenReturn(networkCapabilities); 6250 return vcnUnderlyingNetworkPolicy; 6251 } 6252 }).when(vcnManager).applyVcnNetworkPolicy(any(), any()); 6253 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(false); 6254 6255 String testSubscriberId = "TestSubscriberId"; 6256 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 6257 when(mDataTelephonyManager.getSubscriberId()).thenReturn(testSubscriberId); 6258 connect(); 6259 expectRegisterNetworkAgent((agentConfig) -> { 6260 assertEquals(null, agentConfig.subscriberId); 6261 }, (cap) -> { 6262 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)); 6263 assertTrue(cap.getSubscriptionIds().isEmpty()); 6264 }); 6265 6266 // Verify VCN policy listener is registered 6267 verify(vcnManager, atLeastOnce()).addVcnNetworkPolicyChangeListener(any(), 6268 policyChangeListenerCaptor.capture()); 6269 assertNotNull(policyChangeListenerCaptor.getValue()); 6270 6271 policyChangeListenerCaptor.getValue().onPolicyChanged(); 6272 mLooper.dispatchAll(); 6273 6274 verifyNoMoreInteractions(vcnManager, vcnUnderlyingNetworkPolicy); 6275 } 6276 6277 /** 6278 * Verifies that we trigger a disconnect when the {@link WifiConfigManager}. 6279 * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked. 6280 */ 6281 @Test testOnCarrierOffloadDisabled()6282 public void testOnCarrierOffloadDisabled() throws Exception { 6283 mConnectedNetwork.subscriptionId = DATA_SUBID; 6284 connect(); 6285 6286 mOffloadDisabledListenerArgumentCaptor.getValue() 6287 .onCarrierOffloadDisabled(DATA_SUBID, false); 6288 mLooper.dispatchAll(); 6289 6290 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 6291 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 6292 eq(StaEvent.DISCONNECT_CARRIER_OFFLOAD_DISABLED)); 6293 } 6294 6295 @Test testPacketFilter()6296 public void testPacketFilter() throws Exception { 6297 connect(); 6298 6299 byte[] filter = new byte[20]; 6300 new Random().nextBytes(filter); 6301 mIpClientCallback.installPacketFilter(filter); 6302 mLooper.dispatchAll(); 6303 6304 verify(mWifiNative).installPacketFilter(WIFI_IFACE_NAME, filter); 6305 6306 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 6307 mIpClientCallback.startReadPacketFilter(); 6308 mLooper.dispatchAll(); 6309 verify(mIpClient).readPacketFilterComplete(filter); 6310 verify(mWifiNative).readPacketFilter(WIFI_IFACE_NAME); 6311 } 6312 6313 @Test testPacketFilterOnRoleChangeOnSecondaryCmm()6314 public void testPacketFilterOnRoleChangeOnSecondaryCmm() throws Exception { 6315 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6316 connect(); 6317 6318 verify(mWifiScoreReport).onRoleChanged(ROLE_CLIENT_PRIMARY); 6319 6320 byte[] filter = new byte[20]; 6321 new Random().nextBytes(filter); 6322 mIpClientCallback.installPacketFilter(filter); 6323 mLooper.dispatchAll(); 6324 6325 // just cache the data. 6326 verify(mWifiNative, never()).installPacketFilter(WIFI_IFACE_NAME, filter); 6327 6328 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 6329 mIpClientCallback.startReadPacketFilter(); 6330 mLooper.dispatchAll(); 6331 verify(mIpClient).readPacketFilterComplete(filter); 6332 // return the cached the data. 6333 verify(mWifiNative, never()).readPacketFilter(WIFI_IFACE_NAME); 6334 6335 // Now invoke role change, that should apply the APF 6336 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 6337 mCmi.onRoleChanged(); 6338 verify(mWifiNative).installPacketFilter(WIFI_IFACE_NAME, filter); 6339 verify(mWifiScoreReport, times(2)).onRoleChanged(ROLE_CLIENT_PRIMARY); 6340 } 6341 6342 6343 @Test testPacketFilterOnRoleChangeOnSecondaryCmmWithSupportForNonPrimaryApf()6344 public void testPacketFilterOnRoleChangeOnSecondaryCmmWithSupportForNonPrimaryApf() 6345 throws Exception { 6346 mResources.setBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta, true); 6347 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6348 connect(); 6349 6350 byte[] filter = new byte[20]; 6351 new Random().nextBytes(filter); 6352 mIpClientCallback.installPacketFilter(filter); 6353 mLooper.dispatchAll(); 6354 6355 // apply the data. 6356 verify(mWifiNative).installPacketFilter(WIFI_IFACE_NAME, filter); 6357 6358 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 6359 mIpClientCallback.startReadPacketFilter(); 6360 mLooper.dispatchAll(); 6361 verify(mIpClient).readPacketFilterComplete(filter); 6362 // return the applied data. 6363 verify(mWifiNative).readPacketFilter(WIFI_IFACE_NAME); 6364 6365 // Now invoke role change, that should not apply the APF 6366 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 6367 mCmi.onRoleChanged(); 6368 // ignore (since it was already applied) 6369 verify(mWifiNative, times(1)).installPacketFilter(WIFI_IFACE_NAME, filter); 6370 } 6371 6372 @Test testWifiInfoUpdateOnRoleChange()6373 public void testWifiInfoUpdateOnRoleChange() throws Exception { 6374 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6375 connect(); 6376 // Should not set WifiInfo.isPrimary 6377 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 6378 if (SdkLevel.isAtLeastS()) { 6379 WifiInfo wifiInfoFromTi = (WifiInfo) cap.getTransportInfo(); 6380 assertFalse(wifiInfoFromTi.isPrimary()); 6381 } 6382 }); 6383 reset(mWifiNetworkAgent); 6384 6385 // Now invoke role change, that should set WifiInfo.isPrimary 6386 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 6387 mCmi.onRoleChanged(); 6388 expectNetworkAgentUpdateCapabilities((cap) -> { 6389 if (SdkLevel.isAtLeastS()) { 6390 WifiInfo wifiInfoFromTi = (WifiInfo) cap.getTransportInfo(); 6391 assertTrue(wifiInfoFromTi.isPrimary()); 6392 } 6393 }); 6394 } 6395 6396 /** 6397 * Verify onCellularConnectivityChanged plumbs the information to the right locations. 6398 */ 6399 @Test testOnCellularConnectivityChanged()6400 public void testOnCellularConnectivityChanged() { 6401 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_AVAILABLE); 6402 verify(mWifiConfigManager).onCellularConnectivityChanged( 6403 WifiDataStall.CELLULAR_DATA_AVAILABLE); 6404 6405 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 6406 verify(mWifiConfigManager).onCellularConnectivityChanged( 6407 WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 6408 } 6409 6410 /** 6411 * Verify that when cellular data is lost and wifi is not connected, we force a connectivity 6412 * scan. 6413 */ 6414 @Test testOnCellularConnectivityChangedForceConnectivityScan()6415 public void testOnCellularConnectivityChangedForceConnectivityScan() throws Exception { 6416 mResources.setBoolean(R.bool.config_wifiScanOnCellularDataLossEnabled, true); 6417 // verify a connectivity scan is forced since wifi is not connected 6418 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 6419 verify(mWifiConnectivityManager).forceConnectivityScan(WIFI_WORK_SOURCE); 6420 6421 // verify that after wifi is connected, loss of cellular data will not trigger scans. 6422 connect(); 6423 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 6424 verify(mWifiConnectivityManager).forceConnectivityScan(WIFI_WORK_SOURCE); 6425 } 6426 setScreenState(boolean screenOn)6427 private void setScreenState(boolean screenOn) { 6428 BroadcastReceiver broadcastReceiver = mScreenStateBroadcastReceiverCaptor.getValue(); 6429 assertNotNull(broadcastReceiver); 6430 Intent intent = new Intent(screenOn ? ACTION_SCREEN_ON : ACTION_SCREEN_OFF); 6431 broadcastReceiver.onReceive(mContext, intent); 6432 } 6433 6434 @Test verifyRssiPollOnScreenStateChange()6435 public void verifyRssiPollOnScreenStateChange() throws Exception { 6436 setScreenState(true); 6437 connect(); 6438 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6439 6440 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 6441 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 6442 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6443 mLooper.dispatchAll(); 6444 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 6445 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 6446 mConnectionCapabilities, null, oldLLStats, mWifiInfo); 6447 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 6448 6449 WifiLinkLayerStats newLLStats = new WifiLinkLayerStats(); 6450 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(newLLStats); 6451 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6452 mLooper.dispatchAll(); 6453 verify(mWifiNative, times(2)).getWifiLinkLayerStats(WIFI_IFACE_NAME); 6454 6455 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 6456 mConnectionCapabilities, oldLLStats, newLLStats, mWifiInfo); 6457 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, newLLStats); 6458 6459 // Now set the screen state to false & move time forward, ensure no more link layer stats 6460 // collection. 6461 setScreenState(false); 6462 mLooper.dispatchAll(); 6463 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6464 6465 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6466 mLooper.dispatchAll(); 6467 6468 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 6469 } 6470 6471 @Test verifyRssiPollOnSecondaryCmm()6472 public void verifyRssiPollOnSecondaryCmm() throws Exception { 6473 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6474 mCmi.onRoleChanged(); 6475 setScreenState(true); 6476 connect(); 6477 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6478 6479 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 6480 6481 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(new WifiLinkLayerStats()); 6482 6483 // No link layer stats collection on secondary CMM. 6484 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6485 mLooper.dispatchAll(); 6486 6487 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 6488 } 6489 6490 @Test verifyRssiPollOnOnRoleChangeToPrimary()6491 public void verifyRssiPollOnOnRoleChangeToPrimary() throws Exception { 6492 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6493 mCmi.onRoleChanged(); 6494 setScreenState(true); 6495 connect(); 6496 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6497 6498 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(new WifiLinkLayerStats()); 6499 6500 // No link layer stats collection on secondary CMM. 6501 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6502 mLooper.dispatchAll(); 6503 6504 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 6505 6506 // Now invoke role change, that should start rssi polling on the new primary. 6507 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 6508 mCmi.onRoleChanged(); 6509 mLooper.dispatchAll(); 6510 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6511 6512 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 6513 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 6514 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6515 mLooper.dispatchAll(); 6516 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 6517 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 6518 mConnectionCapabilities, null, oldLLStats, mWifiInfo); 6519 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 6520 } 6521 6522 @Test verifyRssiPollOnOnRoleChangeToSecondary()6523 public void verifyRssiPollOnOnRoleChangeToSecondary() throws Exception { 6524 setScreenState(true); 6525 connect(); 6526 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6527 6528 // RSSI polling is enabled on primary. 6529 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 6530 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 6531 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6532 mLooper.dispatchAll(); 6533 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 6534 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 6535 mConnectionCapabilities, null, oldLLStats, mWifiInfo); 6536 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 6537 6538 // Now invoke role change, that should stop rssi polling on the secondary. 6539 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 6540 mCmi.onRoleChanged(); 6541 mLooper.dispatchAll(); 6542 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 6543 6544 // No link layer stats collection on secondary CMM. 6545 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 6546 mLooper.dispatchAll(); 6547 6548 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 6549 } 6550 6551 @Test testClientModeImplWhenIpClientIsNotReady()6552 public void testClientModeImplWhenIpClientIsNotReady() throws Exception { 6553 WifiConfiguration config = mConnectedNetwork; 6554 config.networkId = FRAMEWORK_NETWORK_ID; 6555 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 6556 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 6557 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 6558 assertNull(config.getNetworkSelectionStatus().getCandidateSecurityParams()); 6559 6560 mFrameworkFacade = mock(FrameworkFacade.class); 6561 ArgumentCaptor<IpClientCallbacks> captor = ArgumentCaptor.forClass(IpClientCallbacks.class); 6562 // reset mWifiNative since initializeCmi() was called in setup() 6563 resetWifiNative(); 6564 6565 // reinitialize ClientModeImpl with IpClient is not ready. 6566 initializeCmi(); 6567 verify(mFrameworkFacade).makeIpClient(any(), anyString(), captor.capture()); 6568 6569 // Manually connect should fail. 6570 IActionListener connectActionListener = mock(IActionListener.class); 6571 mCmi.connectNetwork( 6572 new NetworkUpdateResult(config.networkId), 6573 new ActionListenerWrapper(connectActionListener), 6574 Binder.getCallingUid()); 6575 mLooper.dispatchAll(); 6576 verify(connectActionListener).onFailure(WifiManager.ERROR); 6577 verify(mWifiConfigManager, never()) 6578 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 6579 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 6580 6581 // Auto connect should also fail 6582 mCmi.startConnectToNetwork(config.networkId, MANAGED_PROFILE_UID, config.BSSID); 6583 mLooper.dispatchAll(); 6584 verify(mWifiConfigManager, never()) 6585 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 6586 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 6587 6588 // Make IpClient ready connection should succeed. 6589 captor.getValue().onIpClientCreated(mIpClient); 6590 mLooper.dispatchAll(); 6591 6592 triggerConnect(); 6593 } 6594 } 6595