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