1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import static android.net.NetworkInfo.DetailedState.AUTHENTICATING; 20 import static android.net.NetworkInfo.DetailedState.CONNECTED; 21 import static android.net.NetworkInfo.DetailedState.CONNECTING; 22 import static android.net.NetworkInfo.DetailedState.DISCONNECTED; 23 import static android.net.NetworkInfo.DetailedState.OBTAINING_IPADDR; 24 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; 25 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; 26 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NOT_METERED; 27 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE; 28 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT; 29 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY; 30 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_UNWANTED_LOW_RSSI; 31 import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED; 32 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE; 33 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN; 34 import static android.net.wifi.WifiInfo.SECURITY_TYPE_OWE; 35 import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK; 36 import static android.net.wifi.WifiManager.AddNetworkResult.STATUS_SUCCESS; 37 38 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY; 39 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY; 40 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED; 41 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT; 42 import static com.android.server.wifi.ClientModeImpl.ARP_TABLE_PATH; 43 import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION; 44 import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION_COMPLETE; 45 import static com.android.server.wifi.ClientModeImpl.CMD_UNWANTED_NETWORK; 46 import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE; 47 import static com.android.server.wifi.WifiBlocklistMonitor.REASON_APP_DISALLOW; 48 import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS; 49 import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS; 50 import static com.android.server.wifi.TestUtil.createCapabilityBitset; 51 52 import static org.junit.Assert.assertArrayEquals; 53 import static org.junit.Assert.assertEquals; 54 import static org.junit.Assert.assertFalse; 55 import static org.junit.Assert.assertNotEquals; 56 import static org.junit.Assert.assertNotNull; 57 import static org.junit.Assert.assertNull; 58 import static org.junit.Assert.assertTrue; 59 import static org.junit.Assert.fail; 60 import static org.junit.Assume.assumeFalse; 61 import static org.junit.Assume.assumeTrue; 62 import static org.mockito.Mockito.any; 63 import static org.mockito.Mockito.anyBoolean; 64 import static org.mockito.Mockito.anyByte; 65 import static org.mockito.Mockito.anyInt; 66 import static org.mockito.Mockito.anyLong; 67 import static org.mockito.Mockito.anyString; 68 import static org.mockito.Mockito.argThat; 69 import static org.mockito.Mockito.atLeast; 70 import static org.mockito.Mockito.atLeastOnce; 71 import static org.mockito.Mockito.clearInvocations; 72 import static org.mockito.Mockito.doAnswer; 73 import static org.mockito.Mockito.doReturn; 74 import static org.mockito.Mockito.eq; 75 import static org.mockito.Mockito.inOrder; 76 import static org.mockito.Mockito.mock; 77 import static org.mockito.Mockito.never; 78 import static org.mockito.Mockito.reset; 79 import static org.mockito.Mockito.spy; 80 import static org.mockito.Mockito.times; 81 import static org.mockito.Mockito.verify; 82 import static org.mockito.Mockito.verifyNoMoreInteractions; 83 import static org.mockito.Mockito.when; 84 import static org.mockito.Mockito.withSettings; 85 86 import android.Manifest; 87 import android.annotation.NonNull; 88 import android.annotation.Nullable; 89 import android.app.ActivityManager; 90 import android.app.test.MockAnswerUtil.AnswerWithArguments; 91 import android.app.test.TestAlarmManager; 92 import android.content.BroadcastReceiver; 93 import android.content.Context; 94 import android.content.Intent; 95 import android.content.pm.PackageManager; 96 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 97 import android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.AssociationRejectionData; 98 import android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.MboAssocDisallowedReasonCode; 99 import android.net.CaptivePortalData; 100 import android.net.DhcpResultsParcelable; 101 import android.net.InetAddresses; 102 import android.net.IpConfiguration; 103 import android.net.IpPrefix; 104 import android.net.Layer2InformationParcelable; 105 import android.net.Layer2PacketParcelable; 106 import android.net.LinkAddress; 107 import android.net.LinkProperties; 108 import android.net.MacAddress; 109 import android.net.Network; 110 import android.net.NetworkAgent; 111 import android.net.NetworkAgentConfig; 112 import android.net.NetworkCapabilities; 113 import android.net.NetworkInfo; 114 import android.net.NetworkProvider; 115 import android.net.NetworkSpecifier; 116 import android.net.ProvisioningConfigurationParcelable; 117 import android.net.RouteInfo; 118 import android.net.StaticIpConfiguration; 119 import android.net.Uri; 120 import android.net.apf.ApfCapabilities; 121 import android.net.ip.IIpClient; 122 import android.net.ip.IpClientCallbacks; 123 import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable; 124 import android.net.networkstack.aidl.ip.ReachabilityLossReason; 125 import android.net.vcn.VcnManager; 126 import android.net.vcn.VcnNetworkPolicyResult; 127 import android.net.wifi.BlockingOption; 128 import android.net.wifi.IActionListener; 129 import android.net.wifi.MloLink; 130 import android.net.wifi.ScanResult; 131 import android.net.wifi.SecurityParams; 132 import android.net.wifi.SupplicantState; 133 import android.net.wifi.WifiConfiguration; 134 import android.net.wifi.WifiConfiguration.KeyMgmt; 135 import android.net.wifi.WifiContext; 136 import android.net.wifi.WifiEnterpriseConfig; 137 import android.net.wifi.WifiInfo; 138 import android.net.wifi.WifiManager; 139 import android.net.wifi.WifiNetworkAgentSpecifier; 140 import android.net.wifi.WifiNetworkSpecifier; 141 import android.net.wifi.WifiScanner; 142 import android.net.wifi.WifiSsid; 143 import android.net.wifi.flags.Flags; 144 import android.net.wifi.hotspot2.IProvisioningCallback; 145 import android.net.wifi.hotspot2.OsuProvider; 146 import android.net.wifi.nl80211.DeviceWiphyCapabilities; 147 import android.net.wifi.p2p.WifiP2pManager; 148 import android.net.wifi.util.ScanResultUtil; 149 import android.os.BatteryStatsManager; 150 import android.os.Binder; 151 import android.os.Bundle; 152 import android.os.Handler; 153 import android.os.HandlerThread; 154 import android.os.Looper; 155 import android.os.Messenger; 156 import android.os.PowerManager; 157 import android.os.Process; 158 import android.os.UserHandle; 159 import android.os.test.TestLooper; 160 import android.provider.Settings; 161 import android.telephony.TelephonyManager; 162 import android.test.mock.MockContentProvider; 163 import android.test.mock.MockContentResolver; 164 import android.util.ArraySet; 165 import android.util.LocalLog; 166 import android.util.Log; 167 import android.util.Pair; 168 import android.util.Range; 169 170 import androidx.test.filters.SmallTest; 171 172 import com.android.dx.mockito.inline.extended.ExtendedMockito; 173 import com.android.internal.util.AsyncChannel; 174 import com.android.internal.util.IState; 175 import com.android.internal.util.StateMachine; 176 import com.android.modules.utils.build.SdkLevel; 177 import com.android.server.wifi.ClientMode.LinkProbeCallback; 178 import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast; 179 import com.android.server.wifi.WifiNative.ConnectionCapabilities; 180 import com.android.server.wifi.WifiScoreCard.PerBssid; 181 import com.android.server.wifi.WifiScoreCard.PerNetwork; 182 import com.android.server.wifi.b2b.WifiRoamingModeManager; 183 import com.android.server.wifi.hotspot2.NetworkDetail; 184 import com.android.server.wifi.hotspot2.PasspointManager; 185 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil; 186 import com.android.server.wifi.hotspot2.WnmData; 187 import com.android.server.wifi.p2p.WifiP2pServiceImpl; 188 import com.android.server.wifi.proto.nano.WifiMetricsProto; 189 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent; 190 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent; 191 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStatsEntry; 192 import com.android.server.wifi.util.ActionListenerWrapper; 193 import com.android.server.wifi.util.NativeUtil; 194 import com.android.server.wifi.util.RssiUtilTest; 195 import com.android.server.wifi.util.WifiPermissionsUtil; 196 import com.android.wifi.resources.R; 197 198 import org.junit.After; 199 import org.junit.Before; 200 import org.junit.Test; 201 import org.mockito.ArgumentCaptor; 202 import org.mockito.ArgumentMatcher; 203 import org.mockito.Captor; 204 import org.mockito.InOrder; 205 import org.mockito.Mock; 206 import org.mockito.MockitoAnnotations; 207 import org.mockito.MockitoSession; 208 import org.mockito.quality.Strictness; 209 import org.mockito.verification.VerificationMode; 210 211 import java.io.BufferedReader; 212 import java.io.ByteArrayOutputStream; 213 import java.io.FileDescriptor; 214 import java.io.PrintWriter; 215 import java.io.StringWriter; 216 import java.lang.reflect.Field; 217 import java.lang.reflect.InvocationTargetException; 218 import java.lang.reflect.Method; 219 import java.net.Inet4Address; 220 import java.net.InetAddress; 221 import java.net.URL; 222 import java.nio.charset.StandardCharsets; 223 import java.util.ArrayList; 224 import java.util.Arrays; 225 import java.util.BitSet; 226 import java.util.Collections; 227 import java.util.HashMap; 228 import java.util.List; 229 import java.util.Map; 230 import java.util.Random; 231 import java.util.Set; 232 import java.util.StringJoiner; 233 import java.util.concurrent.CountDownLatch; 234 import java.util.function.Consumer; 235 236 /** 237 * Unit tests for {@link com.android.server.wifi.ClientModeImpl}. 238 */ 239 @SmallTest 240 public class ClientModeImplTest extends WifiBaseTest { 241 public static final String TAG = "ClientModeImplTest"; 242 243 private static final int MANAGED_PROFILE_UID = 1100000; 244 private static final int OTHER_USER_UID = 1200000; 245 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE = ClientModeImpl.NUM_LOG_RECS_VERBOSE; 246 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE_LOW_RAM = 247 ClientModeImpl.NUM_LOG_RECS_VERBOSE_LOW_MEMORY; 248 private static final int FRAMEWORK_NETWORK_ID = 0; 249 private static final int PASSPOINT_NETWORK_ID = 1; 250 private static final int OTHER_NETWORK_ID = 47; 251 private static final int TEST_RSSI = -54; 252 private static final int TEST_NETWORK_ID = 54; 253 private static final int WPS_SUPPLICANT_NETWORK_ID = 5; 254 private static final int WPS_FRAMEWORK_NETWORK_ID = 10; 255 private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; 256 private static final String OP_PACKAGE_NAME = "com.xxx"; 257 private static final int TEST_UID = Process.SYSTEM_UID + 1000; 258 private static final MacAddress TEST_GLOBAL_MAC_ADDRESS = 259 MacAddress.fromString("10:22:34:56:78:92"); 260 private static final MacAddress TEST_LOCAL_MAC_ADDRESS = 261 MacAddress.fromString("2a:53:43:c3:56:21"); 262 private static final MacAddress TEST_LOCAL_MAC_ADDRESS_SECONDARY_DBS = 263 MacAddress.fromString("2a:53:43:c3:56:22"); 264 private static final MacAddress TEST_DEFAULT_MAC_ADDRESS = 265 MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 266 // NetworkAgent creates threshold ranges with Integers 267 private static final int RSSI_THRESHOLD_MAX = -30; 268 private static final int RSSI_THRESHOLD_MIN = -76; 269 // Threshold breach callbacks are called with bytes 270 private static final byte RSSI_THRESHOLD_BREACH_MIN = -80; 271 private static final byte RSSI_THRESHOLD_BREACH_MAX = -20; 272 273 private static final int DATA_SUBID = 1; 274 private static final int CARRIER_ID_1 = 100; 275 276 private static final long TEST_BSSID = 0x112233445566L; 277 private static final int TEST_DELAY_IN_SECONDS = 300; 278 private static final String TEST_ATTRIBUTION_TAG = "TEST_ATTRIBUTION_TAG"; 279 280 private static final int DEFINED_ERROR_CODE = 32764; 281 private static final String TEST_TERMS_AND_CONDITIONS_URL = 282 "https://policies.google.com/terms?hl=en-US"; 283 private static final String VENUE_URL = 284 "https://www.android.com/android-11/"; 285 private static final long[] TEST_RCOI_ARRAY = {0xcafeL, 0xbabaL}; 286 private static final long TEST_MATCHED_RCOI = TEST_RCOI_ARRAY[0]; 287 288 private static final String TEST_AP_MLD_MAC_ADDRESS_STR = "02:03:04:05:06:07"; 289 private static final MacAddress TEST_AP_MLD_MAC_ADDRESS = 290 MacAddress.fromString(TEST_AP_MLD_MAC_ADDRESS_STR); 291 292 private static final String TEST_MLO_LINK_ADDR_STR = "02:03:04:05:06:0A"; 293 private static final MacAddress TEST_MLO_LINK_ADDR = 294 MacAddress.fromString(TEST_MLO_LINK_ADDR_STR); 295 296 private static final String TEST_MLO_LINK_ADDR_1_STR = "02:03:04:05:06:0B"; 297 private static final MacAddress TEST_MLO_LINK_ADDR_1 = 298 MacAddress.fromString(TEST_MLO_LINK_ADDR_1_STR); 299 300 private static final int TEST_MLO_LINK_ID = 1; 301 private static final int TEST_MLO_LINK_ID_1 = 2; 302 303 private static final int TEST_MLO_LINK_FREQ = 5160; 304 private static final int TEST_MLO_LINK_FREQ_1 = 2437; 305 306 private static final String TEST_TDLS_PEER_ADDR_STR = "02:55:11:02:36:4C"; 307 308 private long mBinderToken; 309 private MockitoSession mSession; 310 private TestNetworkParams mTestNetworkParams = new TestNetworkParams(); 311 312 // Attribution tag to be used in the mocked connect sequence 313 private String mAttributionTagForConnect = TEST_ATTRIBUTION_TAG; 314 315 /** 316 * Helper class for setting the default parameters of the WifiConfiguration that gets used 317 * in connect(). 318 */ 319 class TestNetworkParams { 320 public boolean hasEverConnected = false; 321 } 322 mockWithInterfaces(Class<T> class1, Class<?>... interfaces)323 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 324 return mock(class1, withSettings().extraInterfaces(interfaces)); 325 } 326 enableDebugLogs()327 private void enableDebugLogs() { 328 mCmi.enableVerboseLogging(true); 329 } 330 getFrameworkFacade()331 private FrameworkFacade getFrameworkFacade() throws Exception { 332 FrameworkFacade facade = mock(FrameworkFacade.class); 333 334 doAnswer(new AnswerWithArguments() { 335 public void answer( 336 Context context, String ifname, IpClientCallbacks callback) { 337 mIpClientCallback = callback; 338 callback.onIpClientCreated(mIpClient); 339 } 340 }).when(facade).makeIpClient(any(), anyString(), any()); 341 342 return facade; 343 } 344 getContext()345 private WifiContext getContext() throws Exception { 346 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 347 348 WifiContext context = mock(WifiContext.class); 349 when(context.getPackageManager()).thenReturn(mPackageManager); 350 351 MockContentResolver mockContentResolver = new MockContentResolver(); 352 mockContentResolver.addProvider(Settings.AUTHORITY, 353 new MockContentProvider(context) { 354 @Override 355 public Bundle call(String method, String arg, Bundle extras) { 356 return new Bundle(); 357 } 358 }); 359 when(context.getContentResolver()).thenReturn(mockContentResolver); 360 361 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager); 362 when(context.getSystemService(PowerManager.class)).thenReturn(mPowerManager); 363 when(mPowerManager.isInteractive()).thenReturn(true); 364 when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn( 365 mock(PowerManager.WakeLock.class)); 366 367 mAlarmManager = new TestAlarmManager(); 368 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 369 mAlarmManager.getAlarmManager()); 370 371 when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME); 372 373 when(context.getSystemService(ActivityManager.class)).thenReturn(mActivityManager); 374 375 WifiP2pManager p2pm = mock(WifiP2pManager.class); 376 when(context.getSystemService(WifiP2pManager.class)).thenReturn(p2pm); 377 final CountDownLatch untilDone = new CountDownLatch(1); 378 mP2pThread = new HandlerThread("WifiP2pMockThread") { 379 @Override 380 protected void onLooperPrepared() { 381 untilDone.countDown(); 382 } 383 }; 384 mP2pThread.start(); 385 untilDone.await(); 386 Handler handler = new Handler(mP2pThread.getLooper()); 387 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 388 389 mUserAllContext = mock(Context.class); 390 when(context.createContextAsUser(UserHandle.ALL, 0)).thenReturn(mUserAllContext); 391 392 return context; 393 } 394 getMockResources()395 private MockResources getMockResources() { 396 MockResources resources = new MockResources(); 397 return resources; 398 } 399 getCurrentState()400 private IState getCurrentState() throws 401 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 402 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 403 method.setAccessible(true); 404 return (IState) method.invoke(mCmi); 405 } 406 getCmiHandlerThread(ClientModeImpl cmi)407 private static HandlerThread getCmiHandlerThread(ClientModeImpl cmi) throws 408 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 409 Field field = StateMachine.class.getDeclaredField("mSmThread"); 410 field.setAccessible(true); 411 return (HandlerThread) field.get(cmi); 412 } 413 stopLooper(final Looper looper)414 private static void stopLooper(final Looper looper) throws Exception { 415 new Handler(looper).post(new Runnable() { 416 @Override 417 public void run() { 418 looper.quitSafely(); 419 } 420 }); 421 } 422 dumpState()423 private void dumpState() { 424 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 425 PrintWriter writer = new PrintWriter(stream); 426 mCmi.dump(null, writer, null); 427 writer.flush(); 428 Log.d(TAG, "ClientModeImpl state -" + stream.toString()); 429 } 430 getGoogleGuestScanDetail(int rssi, String bssid, int freq)431 private static ScanDetail getGoogleGuestScanDetail(int rssi, String bssid, int freq) { 432 ScanResult.InformationElement[] ie = new ScanResult.InformationElement[1]; 433 ie[0] = ScanResults.generateSsidIe(TEST_SSID); 434 NetworkDetail nd = new NetworkDetail(TEST_BSSID_STR, ie, new ArrayList<String>(), sFreq); 435 ScanDetail detail = new ScanDetail(nd, TEST_WIFI_SSID, bssid, "", rssi, freq, 436 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 437 there older than scan start */ 438 ie, new ArrayList<String>(), ScanResults.generateIERawDatafromScanResultIE(ie)); 439 440 return detail; 441 } 442 getHiddenScanDetail(int rssi, String bssid, int freq)443 private static ScanDetail getHiddenScanDetail(int rssi, String bssid, int freq) { 444 ScanResult.InformationElement ie = new ScanResult.InformationElement(); 445 WifiSsid ssid = WifiSsid.fromBytes(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); 446 ie.id = ScanResult.InformationElement.EID_SSID; 447 ie.bytes = ssid.getBytes(); 448 ScanResult.InformationElement[] ies = new ScanResult.InformationElement[1]; 449 ies[0] = ie; 450 NetworkDetail nd = new NetworkDetail(TEST_BSSID_STR, ies, new ArrayList<String>(), sFreq); 451 ScanDetail detail = new ScanDetail(nd, ssid, bssid, "", rssi, freq, 452 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 453 there older than scan start */ 454 ies, new ArrayList<String>(), ScanResults.generateIERawDatafromScanResultIE(ies)); 455 456 return detail; 457 } 458 getMockScanResults()459 private ArrayList<ScanDetail> getMockScanResults() { 460 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 461 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 462 463 list.add(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 464 return list; 465 } 466 injectDhcpSuccess(DhcpResultsParcelable dhcpResults)467 private void injectDhcpSuccess(DhcpResultsParcelable dhcpResults) { 468 mIpClientCallback.onNewDhcpResults(dhcpResults); 469 mIpClientCallback.onProvisioningSuccess(new LinkProperties()); 470 } 471 injectDhcpSuccess()472 private void injectDhcpSuccess() { 473 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 474 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 475 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 476 dhcpResults.baseConfiguration.ipAddress = 477 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 478 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 479 dhcpResults.leaseDuration = 3600; 480 injectDhcpSuccess(dhcpResults); 481 } 482 injectDhcpFailure()483 private void injectDhcpFailure() { 484 mIpClientCallback.onNewDhcpResults((DhcpResultsParcelable) null); 485 mIpClientCallback.onProvisioningFailure(new LinkProperties()); 486 } 487 488 static final String TEST_SSID = "\"GoogleGuest\""; 489 static final String SSID_NO_QUOTE = TEST_SSID.replace("\"", ""); 490 static final WifiSsid TEST_WIFI_SSID = WifiSsid.fromUtf8Text(SSID_NO_QUOTE); 491 static final String TEST_SSID1 = "\"RandomSsid1\""; 492 static final String SSID_NO_QUOTE1 = TEST_SSID1.replace("\"", ""); 493 static final WifiSsid TEST_WIFI_SSID1 = WifiSsid.fromUtf8Text(SSID_NO_QUOTE1); 494 static final String TEST_BSSID_STR = "01:02:03:04:05:06"; 495 static final String TEST_BSSID_STR1 = "02:01:04:03:06:05"; 496 static final String TEST_BSSID_STR2 = "02:01:04:03:06:04"; 497 static final int sFreq = 2437; 498 static final int sFreq1 = 5240; 499 static final String WIFI_IFACE_NAME = "mockWlan"; 500 static final String sFilsSsid = "FILS-AP"; 501 static final ApfCapabilities APF_CAP = new ApfCapabilities(1, 2, 3); 502 static final long TEST_TX_BYTES = 6666; 503 static final long TEST_RX_BYTES = 8888; 504 static final int TEST_MULTICAST_LOCK_MAX_DTIM_MULTIPLIER = 1; 505 static final int TEST_IPV6_ONLY_NETWORK_MAX_DTIM_MULTIPLIER = 2; 506 static final int TEST_IPV4_ONLY_NETWORK_MAX_DTIM_MULTIPLIER = 9; 507 static final int TEST_DUAL_STACK_NETWORK_MAX_DTIM_MULTIPLIER = 2; 508 static final int TEST_CHANNEL = 6; 509 static final int TEST_CHANNEL_1 = 44; 510 511 ClientModeImpl mCmi; 512 HandlerThread mWifiCoreThread; 513 HandlerThread mP2pThread; 514 HandlerThread mSyncThread; 515 TestAlarmManager mAlarmManager; 516 MockWifiMonitor mWifiMonitor; 517 TestLooper mLooper; 518 WifiContext mContext; 519 Context mUserAllContext; 520 MockResources mResources; 521 FrameworkFacade mFrameworkFacade; 522 IpClientCallbacks mIpClientCallback; 523 OsuProvider mOsuProvider; 524 WifiConfiguration mConnectedNetwork; 525 WifiConfiguration mTestConfig; 526 ExtendedWifiInfo mWifiInfo; 527 WifiRoamingModeManager mWifiRoamingModeManager; 528 ConnectionCapabilities mConnectionCapabilities = new ConnectionCapabilities(); 529 530 @Mock ActivityManager mActivityManager; 531 @Mock WifiNetworkAgent mWifiNetworkAgent; 532 @Mock SupplicantStateTracker mSupplicantStateTracker; 533 @Mock WifiMetrics mWifiMetrics; 534 @Mock WifiInjector mWifiInjector; 535 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 536 @Mock WifiBlocklistMonitor mWifiBlocklistMonitor; 537 @Mock WifiConfigManager mWifiConfigManager; 538 @Mock WifiNative mWifiNative; 539 @Mock WifiScoreCard mWifiScoreCard; 540 @Mock PerNetwork mPerNetwork; 541 @Mock PerBssid mPerBssid; 542 @Mock WifiScoreCard.NetworkConnectionStats mPerNetworkRecentStats; 543 @Mock WifiHealthMonitor mWifiHealthMonitor; 544 @Mock WifiTrafficPoller mWifiTrafficPoller; 545 @Mock WifiConnectivityManager mWifiConnectivityManager; 546 @Mock WifiStateTracker mWifiStateTracker; 547 @Mock PasspointManager mPasspointManager; 548 @Mock WifiPermissionsUtil mWifiPermissionsUtil; 549 @Mock IIpClient mIpClient; 550 @Mock TelephonyManager mTelephonyManager; 551 @Mock TelephonyManager mDataTelephonyManager; 552 @Mock WrongPasswordNotifier mWrongPasswordNotifier; 553 @Mock Clock mClock; 554 @Mock ScanDetailCache mScanDetailCache; 555 @Mock WifiDiagnostics mWifiDiagnostics; 556 @Mock IProvisioningCallback mProvisioningCallback; 557 @Mock WakeupController mWakeupController; 558 @Mock WifiDataStall mWifiDataStall; 559 @Mock WifiNetworkFactory mWifiNetworkFactory; 560 @Mock UntrustedWifiNetworkFactory mUntrustedWifiNetworkFactory; 561 @Mock OemWifiNetworkFactory mOemWifiNetworkFactory; 562 @Mock RestrictedWifiNetworkFactory mRestrictedWifiNetworkFactory; 563 @Mock MultiInternetManager mMultiInternetManager; 564 @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; 565 @Mock PackageManager mPackageManager; 566 @Mock WifiLockManager mWifiLockManager; 567 @Mock AsyncChannel mNullAsyncChannel; 568 @Mock BatteryStatsManager mBatteryStatsManager; 569 @Mock MboOceController mMboOceController; 570 @Mock ConnectionFailureNotifier mConnectionFailureNotifier; 571 @Mock EapFailureNotifier mEapFailureNotifier; 572 @Mock SimRequiredNotifier mSimRequiredNotifier; 573 @Mock ThroughputPredictor mThroughputPredictor; 574 @Mock ScanRequestProxy mScanRequestProxy; 575 @Mock DeviceConfigFacade mDeviceConfigFacade; 576 @Mock Network mNetwork; 577 @Mock ConcreteClientModeManager mClientModeManager; 578 @Mock WifiScoreReport mWifiScoreReport; 579 @Mock PowerManager mPowerManager; 580 @Mock WifiP2pConnection mWifiP2pConnection; 581 @Mock WifiGlobals mWifiGlobals; 582 @Mock LinkProbeCallback mLinkProbeCallback; 583 @Mock ClientModeImplMonitor mCmiMonitor; 584 @Mock ClientModeManagerBroadcastQueue mBroadcastQueue; 585 @Mock WifiNetworkSelector mWifiNetworkSelector; 586 @Mock ActiveModeWarden mActiveModeWarden; 587 @Mock ClientModeManager mPrimaryClientModeManager; 588 @Mock WifiSettingsConfigStore mSettingsConfigStore; 589 @Mock Uri mMockUri; 590 @Mock WifiCarrierInfoManager mWifiCarrierInfoManager; 591 @Mock WifiPseudonymManager mWifiPseudonymManager; 592 @Mock WifiNotificationManager mWifiNotificationManager; 593 594 @Mock WifiConnectivityHelper mWifiConnectivityHelper; 595 @Mock InsecureEapNetworkHandler mInsecureEapNetworkHandler; 596 @Mock ScanResult mScanResult; 597 @Mock HandlerThread mWifiHandlerThread; 598 @Mock SsidTranslator mSsidTranslator; 599 @Mock ApplicationQosPolicyRequestHandler mApplicationQosPolicyRequestHandler; 600 @Mock LocalLog mLocalLog; 601 @Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager; 602 @Mock WifiCountryCode mWifiCountryCode; 603 @Mock WifiRoamingConfigStore mWifiRoamingConfigStore; 604 605 @Mock DeviceWiphyCapabilities mDeviceWiphyCapabilities; 606 607 @Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor; 608 @Captor ArgumentCaptor<WifiNetworkAgent.Callback> mWifiNetworkAgentCallbackCaptor; 609 @Captor ArgumentCaptor<WifiCarrierInfoManager.OnCarrierOffloadDisabledListener> 610 mOffloadDisabledListenerArgumentCaptor = ArgumentCaptor.forClass( 611 WifiCarrierInfoManager.OnCarrierOffloadDisabledListener.class); 612 @Captor ArgumentCaptor<BroadcastReceiver> mScreenStateBroadcastReceiverCaptor; 613 614 @Captor 615 ArgumentCaptor<WifiDeviceStateChangeManager.StateChangeCallback> 616 mStateChangeCallbackArgumentCaptor; 617 618 @Captor ArgumentCaptor<ProvisioningConfigurationParcelable> mProvisioningConfigurationCaptor; 619 WifiInfo mPrimaryWifiInfo; 620 setUpWifiNative()621 private void setUpWifiNative() throws Exception { 622 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn( 623 TEST_GLOBAL_MAC_ADDRESS); 624 doAnswer(new AnswerWithArguments() { 625 public void answer(WifiSettingsConfigStore.Key<String> key, Object macAddress) { 626 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)) 627 .thenReturn((String) macAddress); 628 } 629 }).when(mSettingsConfigStore).put(eq(WIFI_STA_FACTORY_MAC_ADDRESS), any(String.class)); 630 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 631 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 632 ConnectionCapabilities cap = new ConnectionCapabilities(); 633 cap.wifiStandard = ScanResult.WIFI_STANDARD_11AC; 634 when(mWifiNative.getConnectionCapabilities(WIFI_IFACE_NAME)) 635 .thenReturn(mConnectionCapabilities); 636 when(mWifiNative.setStaMacAddress(eq(WIFI_IFACE_NAME), any())) 637 .then(new AnswerWithArguments() { 638 public boolean answer(String iface, MacAddress mac) { 639 when(mWifiNative.getMacAddress(iface)).thenReturn(mac.toString()); 640 return true; 641 } 642 }); 643 when(mWifiNative.connectToNetwork(any(), any())).thenReturn(true); 644 when(mWifiNative.getApfCapabilities(anyString())).thenReturn(APF_CAP); 645 when(mWifiNative.isQosPolicyFeatureEnabled()).thenReturn(true); 646 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(new BitSet()); 647 } 648 649 /** Reset verify() counters on WifiNative, and restore when() mocks on mWifiNative */ resetWifiNative()650 private void resetWifiNative() throws Exception { 651 reset(mWifiNative); 652 setUpWifiNative(); 653 } 654 655 @Before setUp()656 public void setUp() throws Exception { 657 Log.d(TAG, "Setting up ..."); 658 659 // Ensure looper exists 660 mLooper = new TestLooper(); 661 662 MockitoAnnotations.initMocks(this); 663 664 /** uncomment this to enable logs from ClientModeImpls */ 665 // enableDebugLogs(); 666 mWifiMonitor = spy(new MockWifiMonitor()); 667 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 668 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 669 .thenReturn(Collections.emptySet()); 670 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 671 .thenReturn(Pair.create(Process.INVALID_UID, "")); 672 setUpWifiNative(); 673 doAnswer(new AnswerWithArguments() { 674 public MacAddress answer( 675 WifiConfiguration config, boolean isForSecondaryDbs) { 676 MacAddress mac = config.getRandomizedMacAddress(); 677 if (isForSecondaryDbs) { 678 mac = MacAddressUtil.nextMacAddress(mac); 679 } 680 return mac; 681 } 682 }).when(mWifiConfigManager).getRandomizedMacAndUpdateIfNeeded(any(), anyBoolean()); 683 684 mTestNetworkParams = new TestNetworkParams(); 685 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 686 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 687 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(true); 688 when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(true); 689 when(mApplicationQosPolicyRequestHandler.isFeatureEnabled()).thenReturn(true); 690 when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog); 691 when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode); 692 when(mWifiInjector.getApplicationQosPolicyRequestHandler()) 693 .thenReturn(mApplicationQosPolicyRequestHandler); 694 695 mFrameworkFacade = getFrameworkFacade(); 696 mContext = getContext(); 697 mWifiInfo = new ExtendedWifiInfo(mWifiGlobals, WIFI_IFACE_NAME); 698 mWifiRoamingModeManager = new WifiRoamingModeManager(mWifiNative, 699 mActiveModeWarden, mWifiRoamingConfigStore); 700 701 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true); 702 mResources = getMockResources(); 703 mResources.setIntArray(R.array.config_wifiRssiLevelThresholds, 704 RssiUtilTest.RSSI_THRESHOLDS); 705 mResources.setInteger(R.integer.config_wifiLinkBandwidthUpdateThresholdPercent, 25); 706 mResources.setInteger(R.integer.config_wifiClientModeImplNumLogRecs, 100); 707 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 708 when(mContext.getResources()).thenReturn(mResources); 709 710 when(mWifiGlobals.getPollRssiIntervalMillis()).thenReturn(3000); 711 when(mWifiGlobals.getIpReachabilityDisconnectEnabled()).thenReturn(true); 712 when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(Integer.MAX_VALUE); 713 714 when(mFrameworkFacade.getIntegerSetting(mContext, 715 Settings.Global.WIFI_FREQUENCY_BAND, 716 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 717 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 718 when(mFrameworkFacade.getTxBytes(eq(WIFI_IFACE_NAME))).thenReturn(TEST_TX_BYTES); 719 when(mFrameworkFacade.getRxBytes(eq(WIFI_IFACE_NAME))).thenReturn(TEST_RX_BYTES); 720 when(mFrameworkFacade.getTotalTxBytes()).thenReturn(TEST_TX_BYTES); 721 when(mFrameworkFacade.getTotalRxBytes()).thenReturn(TEST_RX_BYTES); 722 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 723 doAnswer(inv -> { 724 mIpClientCallback.onQuit(); 725 return null; 726 }).when(mIpClient).shutdown(); 727 when(mWifiNetworkAgent.getNetwork()).thenReturn(mNetwork); 728 729 // static mocking 730 mSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT) 731 .mockStatic(WifiInjector.class, withSettings().lenient()) 732 .spyStatic(MacAddress.class) 733 .startMocking(); 734 when(WifiInjector.getInstance()).thenReturn(mWifiInjector); 735 736 when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden); 737 when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager); 738 when(mPrimaryClientModeManager.getSupportedFeaturesBitSet()).thenReturn( 739 createCapabilityBitset( 740 WifiManager.WIFI_FEATURE_WPA3_SAE, WifiManager.WIFI_FEATURE_OWE)); 741 when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals); 742 when(mWifiInjector.getWifiHandlerThread()).thenReturn(mWifiHandlerThread); 743 when(mWifiInjector.getSsidTranslator()).thenReturn(mSsidTranslator); 744 when(mWifiInjector.getWifiDeviceStateChangeManager()) 745 .thenReturn(mWifiDeviceStateChangeManager); 746 when(mWifiHandlerThread.getLooper()).thenReturn(mLooper.getLooper()); 747 when(mWifiNative.getDeviceWiphyCapabilities(any())).thenReturn(mDeviceWiphyCapabilities); 748 if (Flags.getDeviceCrossAkmRoamingSupport() && SdkLevel.isAtLeastV()) { 749 when(mDeviceWiphyCapabilities.getMaxNumberAkms()).thenReturn(3); 750 } 751 when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true); 752 when(mWifiGlobals.getClientModeImplNumLogRecs()).thenReturn(100); 753 when(mWifiGlobals.isSaveFactoryMacToConfigStoreEnabled()).thenReturn(true); 754 when(mWifiGlobals.getNetworkNotFoundEventThreshold()).thenReturn(3); 755 when(mWifiGlobals.getMacRandomizationUnsupportedSsidPrefixes()).thenReturn( 756 Collections.EMPTY_SET); 757 when(mWifiInjector.makeWifiNetworkAgent(any(), any(), any(), any(), any())) 758 .thenAnswer(new AnswerWithArguments() { 759 public WifiNetworkAgent answer( 760 @NonNull NetworkCapabilities nc, 761 @NonNull LinkProperties linkProperties, 762 @NonNull NetworkAgentConfig naConfig, 763 @Nullable NetworkProvider provider, 764 @NonNull WifiNetworkAgent.Callback callback) { 765 when(mWifiNetworkAgent.getCallback()).thenReturn(callback); 766 return mWifiNetworkAgent; 767 } 768 }); 769 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 770 // Update the WifiInfo in WifiActiveModeWarden 771 doAnswer(inv -> { 772 if (mCmi != null) { 773 mPrimaryWifiInfo = mCmi.getConnectionInfo(); 774 } 775 return null; 776 }).when(mActiveModeWarden).updateCurrentConnectionInfo(); 777 initializeCmi(); 778 // Retrieve factory MAC address on first bootup. 779 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 780 if (Flags.getDeviceCrossAkmRoamingSupport() && SdkLevel.isAtLeastV()) { 781 verify(mWifiGlobals).setWpa3SaeUpgradeOffloadEnabled(); 782 } 783 784 mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true); 785 mConnectedNetwork = spy(WifiConfigurationTestUtil.createOpenNetwork()); 786 when(mNullAsyncChannel.sendMessageSynchronously(any())).thenReturn(null); 787 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null)); 788 when(mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()).thenReturn(true); 789 when(mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled()).thenReturn(true); 790 when(mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()).thenReturn(true); 791 when(mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()).thenReturn( 792 DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS); 793 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 794 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 795 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 796 .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); 797 when(mPerNetwork.getRecentStats()).thenReturn(mPerNetworkRecentStats); 798 when(mWifiScoreCard.lookupNetwork(any())).thenReturn(mPerNetwork); 799 when(mWifiScoreCard.lookupBssid(any(), any())).thenReturn(mPerBssid); 800 when(mThroughputPredictor.predictMaxTxThroughput(any())).thenReturn(90); 801 when(mThroughputPredictor.predictMaxRxThroughput(any())).thenReturn(80); 802 when(mWifiInjector.getWifiRoamingModeManager()).thenReturn(mWifiRoamingModeManager); 803 804 doAnswer(new AnswerWithArguments() { 805 public void answer(boolean shouldReduceNetworkScore) { 806 mCmi.setShouldReduceNetworkScore(shouldReduceNetworkScore); 807 } 808 }).when(mClientModeManager).setShouldReduceNetworkScore(anyBoolean()); 809 doAnswer(new AnswerWithArguments() { 810 public void answer(ClientModeManager manager, QueuedBroadcast broadcast) { 811 broadcast.send(); 812 } 813 }).when(mBroadcastQueue).queueOrSendBroadcast(any(), any()); 814 } 815 validateConnectionInfo()816 private void validateConnectionInfo() { 817 // The WifiInfo#equals returns false for pre-S, don't enforce the check. 818 if (!SdkLevel.isAtLeastS()) return; 819 if (mClientModeManager.getRole() == ROLE_CLIENT_PRIMARY) { 820 assertEquals(mCmi.getConnectionInfo(), mPrimaryWifiInfo); 821 } 822 } 823 initializeCmi()824 private void initializeCmi() throws Exception { 825 mCmi = new ClientModeImpl(mContext, mWifiMetrics, mClock, mWifiScoreCard, mWifiStateTracker, 826 mWifiPermissionsUtil, mWifiConfigManager, mPasspointManager, 827 mWifiMonitor, mWifiDiagnostics, mWifiDataStall, 828 new ScoringParams(), new WifiThreadRunner(new Handler(mLooper.getLooper())), 829 mWifiNetworkSuggestionsManager, mWifiHealthMonitor, mThroughputPredictor, 830 mDeviceConfigFacade, mScanRequestProxy, mWifiInfo, mWifiConnectivityManager, 831 mWifiBlocklistMonitor, mConnectionFailureNotifier, 832 WifiInjector.REGULAR_NETWORK_CAPABILITIES_FILTER, mWifiNetworkFactory, 833 mUntrustedWifiNetworkFactory, mOemWifiNetworkFactory, mRestrictedWifiNetworkFactory, 834 mMultiInternetManager, mWifiLastResortWatchdog, mWakeupController, 835 mWifiLockManager, mFrameworkFacade, mLooper.getLooper(), 836 mWifiNative, mWrongPasswordNotifier, mWifiTrafficPoller, 837 1, mBatteryStatsManager, mSupplicantStateTracker, mMboOceController, 838 mWifiCarrierInfoManager, mWifiPseudonymManager, mEapFailureNotifier, 839 mSimRequiredNotifier, mWifiScoreReport, mWifiP2pConnection, mWifiGlobals, 840 WIFI_IFACE_NAME, mClientModeManager, mCmiMonitor, 841 mBroadcastQueue, mWifiNetworkSelector, mTelephonyManager, mWifiInjector, 842 mSettingsConfigStore, false, mWifiNotificationManager, 843 mWifiConnectivityHelper); 844 mCmi.mInsecureEapNetworkHandler = mInsecureEapNetworkHandler; 845 846 mWifiCoreThread = getCmiHandlerThread(mCmi); 847 848 mBinderToken = Binder.clearCallingIdentity(); 849 850 verify(mWifiConfigManager, atLeastOnce()).addOnNetworkUpdateListener( 851 mConfigUpdateListenerCaptor.capture()); 852 assertNotNull(mConfigUpdateListenerCaptor.getValue()); 853 854 verify(mWifiCarrierInfoManager, atLeastOnce()).addOnCarrierOffloadDisabledListener( 855 mOffloadDisabledListenerArgumentCaptor.capture()); 856 assertNotNull(mOffloadDisabledListenerArgumentCaptor.getValue()); 857 858 mCmi.enableVerboseLogging(true); 859 mCmi.disconnect(); 860 mLooper.dispatchAll(); 861 862 verify(mWifiLastResortWatchdog, atLeastOnce()).clearAllFailureCounts(); 863 assertEquals("DisconnectedState", getCurrentState().getName()); 864 validateConnectionInfo(); 865 866 verify(mWifiDeviceStateChangeManager, atLeastOnce()) 867 .registerStateChangeCallback(mStateChangeCallbackArgumentCaptor.capture()); 868 } 869 870 @After cleanUp()871 public void cleanUp() throws Exception { 872 Binder.restoreCallingIdentity(mBinderToken); 873 874 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 875 if (mWifiCoreThread != null) stopLooper(mWifiCoreThread.getLooper()); 876 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 877 878 mWifiCoreThread = null; 879 mP2pThread = null; 880 mSyncThread = null; 881 mCmi = null; 882 if (mSession != null) { 883 mSession.finishMocking(); 884 } 885 } 886 887 /** 888 * Test that mode changes accurately reflect the value for isWifiEnabled. 889 */ 890 @Test checkIsWifiEnabledForModeChanges()891 public void checkIsWifiEnabledForModeChanges() throws Exception { 892 // now disable client mode and verify the reported wifi state 893 mCmi.stop(); 894 mLooper.dispatchAll(); 895 verify(mContext, never()) 896 .sendStickyBroadcastAsUser(argThat(new WifiEnablingStateIntentMatcher()), any()); 897 } 898 899 private static class WifiEnablingStateIntentMatcher implements ArgumentMatcher<Intent> { 900 @Override matches(Intent intent)901 public boolean matches(Intent intent) { 902 return WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction()) 903 && WifiManager.WIFI_STATE_ENABLING 904 == intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 905 WifiManager.WIFI_STATE_DISABLED); 906 } 907 } 908 909 private class NetworkStateChangedIntentMatcher implements ArgumentMatcher<Intent> { 910 private final NetworkInfo.DetailedState mState; NetworkStateChangedIntentMatcher(NetworkInfo.DetailedState state)911 NetworkStateChangedIntentMatcher(NetworkInfo.DetailedState state) { 912 mState = state; 913 } 914 @Override matches(Intent intent)915 public boolean matches(Intent intent) { 916 if (WifiManager.NETWORK_STATE_CHANGED_ACTION != intent.getAction()) { 917 // not the correct type 918 return false; 919 } 920 NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 921 return networkInfo.getDetailedState() == mState; 922 } 923 } 924 canSaveNetworkConfig()925 private void canSaveNetworkConfig() throws Exception { 926 IActionListener connectActionListener = mock(IActionListener.class); 927 mCmi.saveNetwork( 928 new NetworkUpdateResult(TEST_NETWORK_ID), 929 new ActionListenerWrapper(connectActionListener), 930 Binder.getCallingUid(), OP_PACKAGE_NAME); 931 mLooper.dispatchAll(); 932 verify(connectActionListener).onSuccess(); 933 } 934 935 /** 936 * Verifies that configs can be saved when in client mode. 937 */ 938 @Test canSaveNetworkConfigInClientMode()939 public void canSaveNetworkConfigInClientMode() throws Exception { 940 canSaveNetworkConfig(); 941 } 942 943 /** 944 * Verifies that admin restricted configs can be saved without triggering a connection. 945 */ 946 @Test canSaveAdminRestrictedNetworkWithoutConnecting()947 public void canSaveAdminRestrictedNetworkWithoutConnecting() throws Exception { 948 assumeTrue(SdkLevel.isAtLeastT()); 949 950 mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID); 951 IActionListener connectActionListener = mock(IActionListener.class); 952 when(mWifiPermissionsUtil.isAdminRestrictedNetwork(any())).thenReturn(true); 953 mCmi.saveNetwork( 954 new NetworkUpdateResult(TEST_NETWORK_ID, STATUS_SUCCESS, false, false, true, false), 955 new ActionListenerWrapper(connectActionListener), 956 Binder.getCallingUid(), OP_PACKAGE_NAME); 957 mLooper.dispatchAll(); 958 959 verify(connectActionListener).onSuccess(); 960 verify(mWifiPermissionsUtil).isAdminRestrictedNetwork(any()); 961 verify(mClientModeManager, never()) 962 .setShouldReduceNetworkScore(false); 963 } 964 965 /** 966 * Verifies that deprecated security type configs can be saved without triggering a connection. 967 */ 968 @Test canSaveDeprecatedSecurityTypeNetworkWithoutConnecting()969 public void canSaveDeprecatedSecurityTypeNetworkWithoutConnecting() throws Exception { 970 mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID); 971 IActionListener connectActionListener = mock(IActionListener.class); 972 when(mWifiGlobals.isDeprecatedSecurityTypeNetwork(any())).thenReturn(true); 973 mCmi.saveNetwork( 974 new NetworkUpdateResult(TEST_NETWORK_ID, STATUS_SUCCESS, false, false, true, false), 975 new ActionListenerWrapper(connectActionListener), 976 Binder.getCallingUid(), OP_PACKAGE_NAME); 977 mLooper.dispatchAll(); 978 979 verify(connectActionListener).onSuccess(); 980 verify(mClientModeManager, never()) 981 .setShouldReduceNetworkScore(false); 982 } 983 createTestNetwork(boolean isHidden)984 private WifiConfiguration createTestNetwork(boolean isHidden) { 985 WifiConfiguration config = new WifiConfiguration(); 986 config.networkId = FRAMEWORK_NETWORK_ID; 987 config.SSID = TEST_SSID; 988 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 989 config.hiddenSSID = isHidden; 990 return config; 991 } 992 initializeMocksForAddedNetwork(WifiConfiguration config)993 private void initializeMocksForAddedNetwork(WifiConfiguration config) throws Exception { 994 when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(config)); 995 when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config); 996 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 997 } 998 initializeMocksForAddedNetwork(boolean isHidden)999 private void initializeMocksForAddedNetwork(boolean isHidden) throws Exception { 1000 mTestConfig = createTestNetwork(isHidden); 1001 initializeMocksForAddedNetwork(mTestConfig); 1002 } 1003 initializeAndAddNetworkAndVerifySuccess(WifiConfiguration config)1004 private void initializeAndAddNetworkAndVerifySuccess(WifiConfiguration config) 1005 throws Exception { 1006 initializeMocksForAddedNetwork(config); 1007 } 1008 initializeAndAddNetworkAndVerifySuccess()1009 private void initializeAndAddNetworkAndVerifySuccess() throws Exception { 1010 initializeAndAddNetworkAndVerifySuccess(false); 1011 } 1012 initializeAndAddNetworkAndVerifySuccess(boolean isHidden)1013 private void initializeAndAddNetworkAndVerifySuccess(boolean isHidden) throws Exception { 1014 initializeMocksForAddedNetwork(isHidden); 1015 } 1016 setupAndStartConnectSequence(WifiConfiguration config)1017 private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception { 1018 when(mWifiConfigManager.getConfiguredNetwork(eq(config.networkId))) 1019 .thenReturn(config); 1020 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking( 1021 eq(config.networkId))).thenReturn(config); 1022 1023 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 1024 1025 IActionListener connectActionListener = mock(IActionListener.class); 1026 mCmi.connectNetwork( 1027 new NetworkUpdateResult(config.networkId), 1028 new ActionListenerWrapper(connectActionListener), 1029 Binder.getCallingUid(), OP_PACKAGE_NAME, mAttributionTagForConnect); 1030 mLooper.dispatchAll(); 1031 verify(connectActionListener).onSuccess(); 1032 } 1033 validateSuccessfulConnectSequence(WifiConfiguration config)1034 private void validateSuccessfulConnectSequence(WifiConfiguration config) { 1035 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1036 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 1037 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 1038 verify(mCmiMonitor).onConnectionStart(mClientModeManager); 1039 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 1040 } 1041 validateFailureConnectSequence(WifiConfiguration config)1042 private void validateFailureConnectSequence(WifiConfiguration config) { 1043 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1044 verify(mWifiConfigManager, never()) 1045 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 1046 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 1047 } 1048 1049 /** 1050 * Tests the network connection initiation sequence with the default network request pending 1051 * from WifiNetworkFactory. 1052 * This simulates the connect sequence using the public 1053 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 1054 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1055 */ 1056 @Test triggerConnect()1057 public void triggerConnect() throws Exception { 1058 WifiConfiguration config = mConnectedNetwork; 1059 config.networkId = FRAMEWORK_NETWORK_ID; 1060 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 1061 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1062 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 1063 assertEquals(null, config.getNetworkSelectionStatus().getCandidateSecurityParams()); 1064 setupAndStartConnectSequence(config); 1065 validateSuccessfulConnectSequence(config); 1066 assertEquals(config.getSecurityParamsList().stream() 1067 .filter(WifiConfigurationUtil::isSecurityParamsValid) 1068 .findFirst().orElse(null), 1069 config.getNetworkSelectionStatus().getCandidateSecurityParams()); 1070 mConnectedNetwork.getNetworkSelectionStatus().setLastUsedSecurityParams( 1071 config.getNetworkSelectionStatus().getCandidateSecurityParams()); 1072 } 1073 1074 /** 1075 * Tests the manual connection request will run network selection to find 1076 * a proper security params, but not use the default one. 1077 */ 1078 @Test triggerConnectWithUpgradeType()1079 public void triggerConnectWithUpgradeType() throws Exception { 1080 String ssid = "TestOpenOweSsid"; 1081 WifiConfiguration config = spy(WifiConfigurationTestUtil.createOpenOweNetwork( 1082 ScanResultUtil.createQuotedSsid(ssid))); 1083 doAnswer(new AnswerWithArguments() { 1084 public WifiConfiguration answer(List<WifiCandidates.Candidate> candidates) { 1085 config.getNetworkSelectionStatus().setCandidateSecurityParams( 1086 SecurityParams.createSecurityParamsBySecurityType( 1087 WifiConfiguration.SECURITY_TYPE_OWE)); 1088 return config; 1089 } 1090 }).when(mWifiNetworkSelector).selectNetwork(any()); 1091 String caps = "[RSN-OWE_TRANSITION]"; 1092 ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid), 1093 TEST_BSSID_STR) 1094 .setHessid(1245) 1095 .setCaps(caps) 1096 .setRssi(-78) 1097 .setFrequency(2450) 1098 .setTsf(1025) 1099 .setDistanceCm(22) 1100 .setDistanceSdCm(33) 1101 .setIs80211McRTTResponder(true) 1102 .build(); 1103 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 1104 ssid.getBytes(StandardCharsets.UTF_8)); 1105 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 1106 when(mScanRequestProxy.getScanResults()).thenReturn(Arrays.asList(scanResult)); 1107 1108 config.networkId = FRAMEWORK_NETWORK_ID; 1109 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 1110 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1111 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 1112 assertEquals(null, config.getNetworkSelectionStatus().getCandidateSecurityParams()); 1113 1114 setupAndStartConnectSequence(config); 1115 validateSuccessfulConnectSequence(config); 1116 assertEquals(WifiConfiguration.SECURITY_TYPE_OWE, 1117 config.getNetworkSelectionStatus().getCandidateSecurityParams().getSecurityType()); 1118 } 1119 1120 /** 1121 * Tests the manual connection request will use the last used security params when there 1122 * is no scan result. 1123 */ 1124 @Test triggerConnectWithLastUsedSecurityParams()1125 public void triggerConnectWithLastUsedSecurityParams() throws Exception { 1126 String ssid = "TestOpenOweSsid"; 1127 WifiConfiguration config = spy(WifiConfigurationTestUtil.createOpenOweNetwork( 1128 ScanResultUtil.createQuotedSsid(ssid))); 1129 when(mScanRequestProxy.getScanResults()).thenReturn(new ArrayList<>()); 1130 1131 config.networkId = FRAMEWORK_NETWORK_ID; 1132 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 1133 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 1134 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 1135 config.getNetworkSelectionStatus().setLastUsedSecurityParams( 1136 SecurityParams.createSecurityParamsBySecurityType( 1137 WifiConfiguration.SECURITY_TYPE_OWE)); 1138 assertEquals(null, config.getNetworkSelectionStatus().getCandidateSecurityParams()); 1139 1140 setupAndStartConnectSequence(config); 1141 validateSuccessfulConnectSequence(config); 1142 assertEquals(WifiConfiguration.SECURITY_TYPE_OWE, 1143 config.getNetworkSelectionStatus().getCandidateSecurityParams().getSecurityType()); 1144 } 1145 1146 /** 1147 * Tests the network connection initiation sequence with the default network request pending 1148 * from WifiNetworkFactory. 1149 * This simulates the connect sequence using the public 1150 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 1151 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1152 */ 1153 @Test triggerConnectFromNonSettingsApp()1154 public void triggerConnectFromNonSettingsApp() throws Exception { 1155 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1156 config.networkId = FRAMEWORK_NETWORK_ID; 1157 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(Process.myUid())) 1158 .thenReturn(false); 1159 setupAndStartConnectSequence(config); 1160 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 1161 verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId)); 1162 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 1163 } 1164 1165 /** 1166 * Tests the network connection initiation sequence with no network request pending from 1167 * from WifiNetworkFactory. 1168 * This simulates the connect sequence using the public 1169 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 1170 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 1171 */ 1172 @Test triggerConnectWithNoNetworkRequest()1173 public void triggerConnectWithNoNetworkRequest() throws Exception { 1174 // Remove the network requests. 1175 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1176 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1177 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 1178 when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(false); 1179 1180 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1181 config.networkId = FRAMEWORK_NETWORK_ID; 1182 setupAndStartConnectSequence(config); 1183 validateFailureConnectSequence(config); 1184 } 1185 1186 /** 1187 * Tests the entire successful network connection flow. 1188 */ 1189 @Test testConnect()1190 public void testConnect() throws Exception { 1191 connect(null); 1192 } 1193 connect()1194 private void connect() throws Exception { 1195 connect(null); 1196 } 1197 1198 /** 1199 * Simulate a connect 1200 * 1201 * @param wnmDataForTermsAndConditions Use null unless it is required to simulate a terms and 1202 * conditions acceptance notification from Passpoint 1203 * @throws Exception 1204 */ connect(WnmData wnmDataForTermsAndConditions)1205 private void connect(WnmData wnmDataForTermsAndConditions) throws Exception { 1206 assertNull(mCmi.getConnectingWifiConfiguration()); 1207 assertNull(mCmi.getConnectedWifiConfiguration()); 1208 1209 triggerConnect(); 1210 validateConnectionInfo(); 1211 1212 assertNotNull(mCmi.getConnectingWifiConfiguration()); 1213 assertNull(mCmi.getConnectedWifiConfiguration()); 1214 1215 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 1216 config.carrierId = CARRIER_ID_1; 1217 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1218 .thenReturn(mScanDetailCache); 1219 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 ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid), 1225 TEST_BSSID_STR) 1226 .setHessid(1245) 1227 .setRssi(-78) 1228 .setFrequency(2450) 1229 .setTsf(1025) 1230 .setDistanceCm(22) 1231 .setDistanceSdCm(33) 1232 .setIs80211McRTTResponder(true) 1233 .build(); 1234 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 1235 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 1236 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 1237 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 1238 1239 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1240 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 1241 SupplicantState.ASSOCIATED)); 1242 mLooper.dispatchAll(); 1243 validateConnectionInfo(); 1244 1245 WifiSsid wifiSsid = WifiSsid.fromBytes( 1246 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1247 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1248 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1249 mLooper.dispatchAll(); 1250 // WifiInfo should be updated if it is primary 1251 validateConnectionInfo(); 1252 1253 verify(mWifiMetrics).noteFirstL2ConnectionAfterBoot(true); 1254 1255 // L2 connected, but not L3 connected yet. So, still "Connecting"... 1256 assertNotNull(mCmi.getConnectingWifiConfiguration()); 1257 assertNull(mCmi.getConnectedWifiConfiguration()); 1258 1259 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1260 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 1261 SupplicantState.COMPLETED)); 1262 mLooper.dispatchAll(); 1263 validateConnectionInfo(); 1264 1265 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1266 verifyNetworkStateChangedBroadcast(times(1), 1267 new NetworkStateChangedIntentMatcher(CONNECTING)); 1268 verifyNetworkStateChangedBroadcast(times(1), 1269 new NetworkStateChangedIntentMatcher(OBTAINING_IPADDR)); 1270 1271 if (wnmDataForTermsAndConditions != null) { 1272 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 1273 0, 0, wnmDataForTermsAndConditions); 1274 mLooper.dispatchAll(); 1275 } 1276 1277 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 1278 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 1279 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 1280 dhcpResults.baseConfiguration.ipAddress = 1281 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 1282 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 1283 dhcpResults.leaseDuration = 3600; 1284 1285 injectDhcpSuccess(dhcpResults); 1286 mLooper.dispatchAll(); 1287 1288 assertNull(mCmi.getConnectingWifiConfiguration()); 1289 assertNotNull(mCmi.getConnectedWifiConfiguration()); 1290 1291 // Verify WifiMetrics logging for metered metrics based on DHCP results 1292 verify(mWifiMetrics).addMeteredStat(any(), anyBoolean()); 1293 WifiInfo wifiInfo = mWifiInfo; 1294 assertNotNull(wifiInfo); 1295 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 1296 assertEquals(sFreq, wifiInfo.getFrequency()); 1297 assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid()); 1298 assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, wifiInfo.getMacAddress()); 1299 assertEquals(mConnectedNetwork.getDefaultSecurityParams().getSecurityType(), 1300 mWifiInfo.getCurrentSecurityType()); 1301 if (wifiInfo.isPasspointAp()) { 1302 assertEquals(wifiInfo.getPasspointProviderFriendlyName(), 1303 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1304 } else { 1305 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1306 } 1307 assertEquals(Arrays.asList(scanResult.informationElements), 1308 wifiInfo.getInformationElements()); 1309 assertNotNull(wifiInfo.getNetworkKey()); 1310 expectRegisterNetworkAgent((na) -> { 1311 if (!mConnectedNetwork.carrierMerged) { 1312 assertNull(na.subscriberId); 1313 } 1314 }, (nc) -> { 1315 if (SdkLevel.isAtLeastS()) { 1316 WifiInfo wifiInfoFromTi = (WifiInfo) nc.getTransportInfo(); 1317 assertEquals(TEST_BSSID_STR, wifiInfoFromTi.getBSSID()); 1318 assertEquals(sFreq, wifiInfoFromTi.getFrequency()); 1319 assertEquals(TEST_WIFI_SSID, wifiInfoFromTi.getWifiSsid()); 1320 if (wifiInfo.isPasspointAp()) { 1321 assertEquals(wifiInfoFromTi.getPasspointProviderFriendlyName(), 1322 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1323 } else { 1324 assertNull(wifiInfoFromTi.getPasspointProviderFriendlyName()); 1325 } 1326 } 1327 }); 1328 1329 assertFalse(mCmi.isIpProvisioningTimedOut()); 1330 // Ensure the connection stats for the network is updated. 1331 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 1332 anyBoolean(), anyBoolean(), anyInt()); 1333 verify(mWifiConfigManager).updateRandomizedMacExpireTime(any(), anyLong()); 1334 verifyNetworkStateChangedBroadcast(times(1), 1335 new NetworkStateChangedIntentMatcher(CONNECTED)); 1336 1337 // Anonymous Identity is not set. 1338 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1339 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.CONNECTED); 1340 assertEquals("L3ConnectedState", getCurrentState().getName()); 1341 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionSuccess(); 1342 verify(mWifiLockManager).updateWifiClientConnected(mClientModeManager, true); 1343 verify(mWifiNative).getConnectionCapabilities(any()); 1344 verify(mThroughputPredictor).predictMaxTxThroughput(any()); 1345 verify(mWifiMetrics).setConnectionMaxSupportedLinkSpeedMbps(WIFI_IFACE_NAME, 90, 80); 1346 assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); 1347 verify(mWifiMetrics).noteFirstL3ConnectionAfterBoot(true); 1348 validateConnectionInfo(); 1349 } 1350 connectWithIpProvisionTimeout(boolean lateDhcpResponse)1351 private void connectWithIpProvisionTimeout(boolean lateDhcpResponse) throws Exception { 1352 mResources.setBoolean(R.bool.config_wifiRemainConnectedAfterIpProvisionTimeout, true); 1353 assertNull(mCmi.getConnectingWifiConfiguration()); 1354 assertNull(mCmi.getConnectedWifiConfiguration()); 1355 1356 triggerConnect(); 1357 validateConnectionInfo(); 1358 1359 assertNotNull(mCmi.getConnectingWifiConfiguration()); 1360 assertNull(mCmi.getConnectedWifiConfiguration()); 1361 1362 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 1363 config.carrierId = CARRIER_ID_1; 1364 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1365 .thenReturn(mScanDetailCache); 1366 1367 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1368 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1369 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1370 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1371 ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid), 1372 TEST_BSSID_STR) 1373 .setHessid(1245) 1374 .setRssi(-78) 1375 .setFrequency(2450) 1376 .setTsf(1025) 1377 .setDistanceCm(22) 1378 .setDistanceSdCm(33) 1379 .setIs80211McRTTResponder(true) 1380 .build(); 1381 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 1382 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 1383 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 1384 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 1385 1386 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1387 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 1388 SupplicantState.ASSOCIATED)); 1389 mLooper.dispatchAll(); 1390 validateConnectionInfo(); 1391 1392 WifiSsid wifiSsid = WifiSsid.fromBytes( 1393 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1394 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1395 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1396 mLooper.dispatchAll(); 1397 // WifiInfo should be updated if it is primary 1398 validateConnectionInfo(); 1399 1400 verify(mWifiMetrics).noteFirstL2ConnectionAfterBoot(true); 1401 1402 // L2 connected, but not L3 connected yet. So, still "Connecting"... 1403 assertNotNull(mCmi.getConnectingWifiConfiguration()); 1404 assertNull(mCmi.getConnectedWifiConfiguration()); 1405 1406 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1407 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 1408 SupplicantState.COMPLETED)); 1409 mLooper.dispatchAll(); 1410 validateConnectionInfo(); 1411 1412 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1413 verifyNetworkStateChangedBroadcast(times(1), 1414 new NetworkStateChangedIntentMatcher(CONNECTING)); 1415 verifyNetworkStateChangedBroadcast(times(1), 1416 new NetworkStateChangedIntentMatcher(OBTAINING_IPADDR)); 1417 mLooper.dispatchAll(); 1418 1419 mLooper.moveTimeForward(mCmi.WAIT_FOR_L3_PROVISIONING_TIMEOUT_MS); 1420 mLooper.dispatchAll(); 1421 verify(mWifiConnectivityManager).handleConnectionStateChanged(mClientModeManager, 1422 WifiConnectivityManager.WIFI_STATE_CONNECTED); 1423 assertTrue(mCmi.isIpProvisioningTimedOut()); 1424 verify(mWifiConfigManager).setIpProvisioningTimedOut(eq(FRAMEWORK_NETWORK_ID), eq(true)); 1425 1426 if (!lateDhcpResponse) { 1427 return; 1428 } 1429 1430 // Simulate the scenario of a late response of the dhcp after the network is labeled a local 1431 // only due to ip provisioning timeout. 1432 1433 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 1434 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 1435 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 1436 dhcpResults.baseConfiguration.ipAddress = 1437 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 1438 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 1439 dhcpResults.leaseDuration = 3600; 1440 1441 injectDhcpSuccess(dhcpResults); 1442 mLooper.dispatchAll(); 1443 assertNull(mCmi.getConnectingWifiConfiguration()); 1444 assertNotNull(mCmi.getConnectedWifiConfiguration()); 1445 1446 // Verify WifiMetrics logging for metered metrics based on DHCP results 1447 verify(mWifiMetrics).addMeteredStat(any(), anyBoolean()); 1448 WifiInfo wifiInfo = mWifiInfo; 1449 assertNotNull(wifiInfo); 1450 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 1451 assertEquals(sFreq, wifiInfo.getFrequency()); 1452 assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid()); 1453 assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, wifiInfo.getMacAddress()); 1454 assertEquals(mConnectedNetwork.getDefaultSecurityParams().getSecurityType(), 1455 mWifiInfo.getCurrentSecurityType()); 1456 1457 if (wifiInfo.isPasspointAp()) { 1458 assertEquals(wifiInfo.getPasspointProviderFriendlyName(), 1459 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1460 } else { 1461 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 1462 } 1463 assertEquals(Arrays.asList(scanResult.informationElements), 1464 wifiInfo.getInformationElements()); 1465 assertNotNull(wifiInfo.getNetworkKey()); 1466 expectRegisterNetworkAgent((na) -> { 1467 if (!mConnectedNetwork.carrierMerged) { 1468 assertNull(na.subscriberId); 1469 } 1470 }, (nc) -> { 1471 if (SdkLevel.isAtLeastS()) { 1472 WifiInfo wifiInfoFromTi = (WifiInfo) nc.getTransportInfo(); 1473 assertEquals(TEST_BSSID_STR, wifiInfoFromTi.getBSSID()); 1474 assertEquals(sFreq, wifiInfoFromTi.getFrequency()); 1475 assertEquals(TEST_WIFI_SSID, wifiInfoFromTi.getWifiSsid()); 1476 if (wifiInfo.isPasspointAp()) { 1477 assertEquals(wifiInfoFromTi.getPasspointProviderFriendlyName(), 1478 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME); 1479 } else { 1480 assertNull(wifiInfoFromTi.getPasspointProviderFriendlyName()); 1481 } 1482 } 1483 }); 1484 1485 assertFalse(mCmi.isIpProvisioningTimedOut()); 1486 verify(mWifiConfigManager).setIpProvisioningTimedOut(eq(FRAMEWORK_NETWORK_ID), eq(false)); 1487 1488 // Ensure the connection stats for the network is updated. 1489 verify(mWifiConfigManager).updateRandomizedMacExpireTime(any(), anyLong()); 1490 verifyNetworkStateChangedBroadcast(atLeast(1), 1491 new NetworkStateChangedIntentMatcher(CONNECTED)); 1492 1493 //Ensure that the network is registered 1494 verify(mWifiConfigManager).updateNetworkAfterConnect( 1495 eq(FRAMEWORK_NETWORK_ID), anyBoolean(), anyBoolean(), anyInt()); 1496 verify(mWifiConnectivityManager, times(2)).handleConnectionStateChanged(mClientModeManager, 1497 WifiConnectivityManager.WIFI_STATE_CONNECTED); 1498 1499 1500 // Anonymous Identity is not set. 1501 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1502 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.CONNECTED); 1503 assertEquals("L3ConnectedState", getCurrentState().getName()); 1504 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionSuccess(); 1505 verify(mWifiLockManager).updateWifiClientConnected(mClientModeManager, true); 1506 verify(mWifiNative).getConnectionCapabilities(any()); 1507 verify(mThroughputPredictor).predictMaxTxThroughput(any()); 1508 verify(mWifiMetrics).setConnectionMaxSupportedLinkSpeedMbps(WIFI_IFACE_NAME, 90, 80); 1509 assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); 1510 verify(mWifiMetrics).noteFirstL3ConnectionAfterBoot(true); 1511 validateConnectionInfo(); 1512 1513 } 1514 1515 @Test testConnectWithIpProvisioningTimeout()1516 public void testConnectWithIpProvisioningTimeout() throws Exception { 1517 connectWithIpProvisionTimeout(false); 1518 } 1519 1520 @Test testConnectWithIpProvisioningTimeoutLateDhcpResponse()1521 public void testConnectWithIpProvisioningTimeoutLateDhcpResponse() throws Exception { 1522 connectWithIpProvisionTimeout(true); 1523 } 1524 verifyNetworkStateChangedBroadcast(VerificationMode mode, ArgumentCaptor<Intent> intentCaptor)1525 private void verifyNetworkStateChangedBroadcast(VerificationMode mode, 1526 ArgumentCaptor<Intent> intentCaptor) { 1527 if (SdkLevel.isAtLeastU()) { 1528 verify(mUserAllContext, mode).sendStickyBroadcast(intentCaptor.capture(), any()); 1529 } else { 1530 verify(mContext, mode).sendStickyBroadcastAsUser(intentCaptor.capture(), any()); 1531 } 1532 } 1533 verifyNetworkStateChangedBroadcast(VerificationMode mode, ArgumentMatcher<Intent> intentMatcher)1534 private void verifyNetworkStateChangedBroadcast(VerificationMode mode, 1535 ArgumentMatcher<Intent> intentMatcher) { 1536 if (SdkLevel.isAtLeastU()) { 1537 verify(mUserAllContext, mode).sendStickyBroadcast(argThat(intentMatcher), any()); 1538 } else { 1539 verify(mContext, mode).sendStickyBroadcastAsUser(argThat(intentMatcher), any()); 1540 } 1541 } 1542 inOrderVerifyNetworkStateChangedBroadcasts( ArgumentMatcher<Intent>.... intentMatchers)1543 private void inOrderVerifyNetworkStateChangedBroadcasts( 1544 ArgumentMatcher<Intent>... intentMatchers) { 1545 final InOrder inOrder = SdkLevel.isAtLeastU() 1546 ? inOrder(mUserAllContext) : inOrder(mContext); 1547 for (ArgumentMatcher<Intent> intentMatcher : intentMatchers) { 1548 if (SdkLevel.isAtLeastU()) { 1549 inOrder.verify(mUserAllContext).sendStickyBroadcast(argThat(intentMatcher), any()); 1550 } else { 1551 inOrder.verify(mContext).sendStickyBroadcastAsUser(argThat(intentMatcher), any()); 1552 } 1553 } 1554 } 1555 setupEapSimConnection()1556 private void setupEapSimConnection() throws Exception { 1557 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1558 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1559 mConnectedNetwork.carrierId = CARRIER_ID_1; 1560 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1561 .thenReturn(DATA_SUBID); 1562 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1563 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1564 1565 triggerConnect(); 1566 1567 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1568 .thenReturn(mScanDetailCache); 1569 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1570 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1571 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1572 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1573 1574 WifiSsid wifiSsid = WifiSsid.fromBytes( 1575 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1576 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1577 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1578 mLooper.dispatchAll(); 1579 verify(mEapFailureNotifier).dismissEapFailureNotification(mConnectedNetwork.SSID); 1580 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1581 } 1582 setupCarrierConnectionNotSimBased()1583 private void setupCarrierConnectionNotSimBased() throws Exception { 1584 mConnectedNetwork.carrierId = CARRIER_ID_1; 1585 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1586 .thenReturn(DATA_SUBID); 1587 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1588 1589 triggerConnect(); 1590 1591 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1592 .thenReturn(mScanDetailCache); 1593 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1594 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1595 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1596 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1597 1598 WifiSsid wifiSsid = WifiSsid.fromBytes( 1599 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1600 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1601 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1602 mLooper.dispatchAll(); 1603 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1604 } 1605 1606 @Test testUpdatingOobPseudonymToSupplicant()1607 public void testUpdatingOobPseudonymToSupplicant() throws Exception { 1608 when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true); 1609 when(mDeviceConfigFacade.isOobPseudonymEnabled()).thenReturn(true); 1610 1611 ArgumentCaptor<WifiPseudonymManager.PseudonymUpdatingListener> listenerCaptor = 1612 ArgumentCaptor.forClass(WifiPseudonymManager.PseudonymUpdatingListener.class); 1613 setupEapSimConnection(); 1614 verify(mWifiPseudonymManager).registerPseudonymUpdatingListener(listenerCaptor.capture()); 1615 String expectedPseudonym = "abc-123"; 1616 String expectedDecoratedPseudonym = "abc-123@wlan.mnc456.mcc123.3gppnetwork.org"; 1617 when(mWifiCarrierInfoManager.decoratePseudonymWith3GppRealm(any(), eq(expectedPseudonym))) 1618 .thenReturn(expectedDecoratedPseudonym); 1619 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 1620 listenerCaptor.getValue().onUpdated(CARRIER_ID_1, expectedPseudonym); 1621 mLooper.dispatchAll(); 1622 1623 verify(mWifiNative).setEapAnonymousIdentity( 1624 anyString(), eq(expectedDecoratedPseudonym), eq(true)); 1625 1626 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 1627 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false)); 1628 mLooper.dispatchAll(); 1629 1630 assertEquals("DisconnectedState", getCurrentState().getName()); 1631 verify(mWifiPseudonymManager) 1632 .unregisterPseudonymUpdatingListener(eq(listenerCaptor.getValue())); 1633 } 1634 1635 @Test testNotUpdatingOobPseudonymToSupplicant()1636 public void testNotUpdatingOobPseudonymToSupplicant() throws Exception { 1637 when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true); 1638 when(mDeviceConfigFacade.isOobPseudonymEnabled()).thenReturn(true); 1639 1640 ArgumentCaptor<WifiPseudonymManager.PseudonymUpdatingListener> listenerCaptor = 1641 ArgumentCaptor.forClass(WifiPseudonymManager.PseudonymUpdatingListener.class); 1642 setupEapSimConnection(); 1643 verify(mWifiPseudonymManager).registerPseudonymUpdatingListener(listenerCaptor.capture()); 1644 String expectedPseudonym = "abc-123"; 1645 String expectedDecoratedPseudonym = "abc-123@wlan.mnc456.mcc123.3gppnetwork.org"; 1646 when(mWifiCarrierInfoManager.decoratePseudonymWith3GppRealm(any(), eq(expectedPseudonym))) 1647 .thenReturn(expectedDecoratedPseudonym); 1648 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(false); 1649 listenerCaptor.getValue().onUpdated(CARRIER_ID_1, expectedPseudonym); 1650 mLooper.dispatchAll(); 1651 1652 verify(mWifiNative, never()).setEapAnonymousIdentity( 1653 anyString(), anyString(), anyBoolean()); 1654 1655 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 1656 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false)); 1657 mLooper.dispatchAll(); 1658 1659 assertEquals("DisconnectedState", getCurrentState().getName()); 1660 verify(mWifiPseudonymManager) 1661 .unregisterPseudonymUpdatingListener(eq(listenerCaptor.getValue())); 1662 } 1663 1664 /** 1665 * Test when a roam occurs simultaneously with another connection attempt. 1666 * The roam's NETWORK_CONNECTION_EVENT should be ignored, only the new network's 1667 * NETWORK_CONNECTION_EVENT should be acted upon. 1668 */ 1669 @Test roamRaceWithConnect()1670 public void roamRaceWithConnect() throws Exception { 1671 connect(); 1672 1673 initializeAndAddNetworkAndVerifySuccess(); 1674 1675 // connect to new network 1676 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 1677 config.networkId = OTHER_NETWORK_ID; 1678 setupAndStartConnectSequence(config); 1679 1680 // in L2ConnectingState 1681 assertEquals("L2ConnectingState", getCurrentState().getName()); 1682 1683 // send NETWORK_CONNECTION_EVENT for previous network ID 1684 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1685 new NetworkConnectionEventInfo( 1686 FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 1687 mLooper.dispatchAll(); 1688 1689 // should ignore it, stay in L2ConnectingState 1690 assertEquals("L2ConnectingState", getCurrentState().getName()); 1691 1692 // send expected new network SSID 1693 WifiSsid wifiSsid = WifiSsid.fromBytes( 1694 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(config.SSID))); 1695 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1696 new NetworkConnectionEventInfo( 1697 OTHER_NETWORK_ID, wifiSsid, TEST_BSSID_STR1, false, null)); 1698 mLooper.dispatchAll(); 1699 1700 // then move to next state 1701 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1702 } 1703 1704 @Test testSimAuthRequestIsHandledWhileAlreadyConnectedSuccess()1705 public void testSimAuthRequestIsHandledWhileAlreadyConnectedSuccess() throws Exception { 1706 connect(); 1707 1708 WifiCarrierInfoManager.SimAuthRequestData requestData = 1709 new WifiCarrierInfoManager.SimAuthRequestData(); 1710 requestData.protocol = WifiEnterpriseConfig.Eap.SIM; 1711 requestData.networkId = FRAMEWORK_NETWORK_ID; 1712 String testSimAuthResponse = "TEST_SIM_AUTH_RESPONSE"; 1713 when(mWifiCarrierInfoManager.getGsmSimAuthResponse(any(), any())) 1714 .thenReturn(testSimAuthResponse); 1715 mCmi.sendMessage(WifiMonitor.SUP_REQUEST_SIM_AUTH, requestData); 1716 mLooper.dispatchAll(); 1717 1718 // Expect success 1719 verify(mWifiNative).simAuthResponse(WIFI_IFACE_NAME, WifiNative.SIM_AUTH_RESP_TYPE_GSM_AUTH, 1720 testSimAuthResponse); 1721 } 1722 1723 @Test testSimAuthRequestIsHandledWhileAlreadyConnectedFail()1724 public void testSimAuthRequestIsHandledWhileAlreadyConnectedFail() throws Exception { 1725 connect(); 1726 1727 WifiCarrierInfoManager.SimAuthRequestData requestData = 1728 new WifiCarrierInfoManager.SimAuthRequestData(); 1729 requestData.protocol = WifiEnterpriseConfig.Eap.SIM; 1730 requestData.networkId = FRAMEWORK_NETWORK_ID; 1731 // Mock WifiCarrierInfoManager to return null so that sim auth fails. 1732 when(mWifiCarrierInfoManager.getGsmSimAuthResponse(any(), any())).thenReturn(null); 1733 mCmi.sendMessage(WifiMonitor.SUP_REQUEST_SIM_AUTH, requestData); 1734 mLooper.dispatchAll(); 1735 1736 // Expect failure 1737 verify(mWifiNative).simAuthFailedResponse(WIFI_IFACE_NAME); 1738 } 1739 1740 /** 1741 * When the SIM card was removed, if the current wifi connection is not using it, the connection 1742 * should be kept. 1743 */ 1744 @Test testResetSimWhenNonConnectedSimRemoved()1745 public void testResetSimWhenNonConnectedSimRemoved() throws Exception { 1746 setupEapSimConnection(); 1747 doReturn(true).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1748 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1749 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1750 mLooper.dispatchAll(); 1751 1752 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); 1753 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1754 } 1755 1756 /** 1757 * When the SIM card was removed, if the current wifi connection is using it, the connection 1758 * should be disconnected, otherwise, the connection shouldn't be impacted. 1759 */ 1760 @Test testResetSimWhenConnectedSimRemoved()1761 public void testResetSimWhenConnectedSimRemoved() throws Exception { 1762 when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true); 1763 setupEapSimConnection(); 1764 doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1765 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1766 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1767 mLooper.dispatchAll(); 1768 1769 verify(mSimRequiredNotifier).showSimRequiredNotification(any(), any()); 1770 verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME); 1771 verify(mWifiMetrics).startConnectionEvent( 1772 anyString(), any(), anyString(), anyInt(), eq(true), anyInt(), anyInt()); 1773 } 1774 1775 /** 1776 * When the SIM card was removed, if the current wifi connection is using it, the connection 1777 * should be disconnected, otherwise, the connection shouldn't be impacted. 1778 */ 1779 @Test testResetSimWhenConnectedSimRemovedAfterNetworkRemoval()1780 public void testResetSimWhenConnectedSimRemovedAfterNetworkRemoval() throws Exception { 1781 setupEapSimConnection(); 1782 doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1783 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 1784 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1785 ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); 1786 mLooper.dispatchAll(); 1787 1788 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); 1789 assertEquals("L3ProvisioningState", getCurrentState().getName()); 1790 } 1791 1792 /** 1793 * When the default data SIM is changed, if the current wifi connection is carrier wifi, 1794 * the connection should be disconnected. 1795 */ 1796 @Test testResetSimWhenDefaultDataSimChanged()1797 public void testResetSimWhenDefaultDataSimChanged() throws Exception { 1798 setupEapSimConnection(); 1799 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1800 ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); 1801 mLooper.dispatchAll(); 1802 1803 verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME); 1804 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 1805 eq(StaEvent.DISCONNECT_RESET_SIM_NETWORKS)); 1806 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), anyString()); 1807 } 1808 1809 /** 1810 * When the default data SIM is changed, if the current wifi connection is carrier wifi, 1811 * the connection should be disconnected, and if the network is not SIM-based, no notification 1812 * should be send 1813 */ 1814 @Test testDefaultDataSimChangedNotSimBased()1815 public void testDefaultDataSimChangedNotSimBased() throws Exception { 1816 setupCarrierConnectionNotSimBased(); 1817 doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID)); 1818 mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1819 ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); 1820 mLooper.dispatchAll(); 1821 1822 verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME); 1823 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 1824 eq(StaEvent.DISCONNECT_RESET_SIM_NETWORKS)); 1825 verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), anyString()); 1826 } 1827 1828 /** 1829 * Tests anonymous identity is set again whenever a connection is established for the carrier 1830 * that supports encrypted IMSI and anonymous identity and no real pseudonym was provided. 1831 */ 1832 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym()1833 public void testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym() throws Exception { 1834 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1835 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1836 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1837 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1838 1839 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1840 .thenReturn(DATA_SUBID); 1841 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1842 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1843 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1844 .thenReturn(expectedAnonymousIdentity); 1845 1846 // Initial value should be "not set" 1847 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1848 1849 triggerConnect(); 1850 1851 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1852 assertEquals(expectedAnonymousIdentity, 1853 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1854 1855 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1856 .thenReturn(mScanDetailCache); 1857 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1858 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1859 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1860 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1861 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1862 .thenReturn(expectedAnonymousIdentity); 1863 1864 WifiSsid wifiSsid = WifiSsid.fromBytes( 1865 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1866 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1867 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1868 mLooper.dispatchAll(); 1869 1870 verify(mWifiNative).getEapAnonymousIdentity(any()); 1871 1872 // Post connection value should remain "not set" 1873 assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1874 // verify that WifiConfigManager#addOrUpdateNetwork() was called to clear any previously 1875 // stored pseudonym. i.e. to enable Encrypted IMSI for subsequent connections. 1876 // Note: This test will fail if future logic will have additional conditions that would 1877 // trigger "add or update network" operation. The test needs to be updated to account for 1878 // this change. 1879 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1880 } 1881 1882 /** 1883 * Tests anonymous identity is set again whenever a connection is established for the carrier 1884 * that supports encrypted IMSI and anonymous identity but real pseudonym was provided for 1885 * subsequent connections. 1886 */ 1887 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym()1888 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym() 1889 throws Exception { 1890 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1891 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1892 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1893 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1894 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 1895 1896 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1897 .thenReturn(DATA_SUBID); 1898 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1899 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1900 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1901 .thenReturn(expectedAnonymousIdentity); 1902 1903 triggerConnect(); 1904 1905 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1906 assertEquals(expectedAnonymousIdentity, 1907 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1908 1909 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1910 .thenReturn(mScanDetailCache); 1911 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1912 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1913 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1914 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1915 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1916 .thenReturn(pseudonym); 1917 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 1918 1919 WifiSsid wifiSsid = WifiSsid.fromBytes( 1920 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1921 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1922 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1923 mLooper.dispatchAll(); 1924 1925 verify(mWifiNative).getEapAnonymousIdentity(any()); 1926 // No decorated pseudonum, only update the cached data. 1927 verify(mWifiNative).setEapAnonymousIdentity(any(), eq(pseudonym), eq(false)); 1928 assertEquals(pseudonym, 1929 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1930 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1931 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1932 // pseudonym usage in all subsequent connections. 1933 // Note: This test will fail if future logic will have additional conditions that would 1934 // trigger "add or update network" operation. The test needs to be updated to account for 1935 // this change. 1936 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1937 } 1938 1939 /** 1940 * Tests anonymous identity is set again whenever a connection is established for the carrier 1941 * that supports encrypted IMSI and anonymous identity but real but not decorated pseudonym was 1942 * provided for subsequent connections. 1943 */ 1944 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym()1945 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym() 1946 throws Exception { 1947 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 1948 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 1949 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 1950 String pseudonym = "83bcca9384fca"; 1951 String realm = "wlan.mnc456.mcc123.3gppnetwork.org"; 1952 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 1953 1954 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 1955 .thenReturn(DATA_SUBID); 1956 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 1957 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 1958 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 1959 .thenReturn(expectedAnonymousIdentity); 1960 doAnswer(invocation -> { return invocation.getArgument(1) + "@" + realm; }) 1961 .when(mWifiCarrierInfoManager).decoratePseudonymWith3GppRealm(any(), anyString()); 1962 triggerConnect(); 1963 1964 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 1965 assertEquals(expectedAnonymousIdentity, 1966 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1967 1968 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 1969 .thenReturn(mScanDetailCache); 1970 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 1971 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 1972 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 1973 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 1974 when(mWifiNative.getEapAnonymousIdentity(anyString())) 1975 .thenReturn(pseudonym); 1976 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 1977 1978 WifiSsid wifiSsid = WifiSsid.fromBytes( 1979 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 1980 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 1981 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 1982 mLooper.dispatchAll(); 1983 1984 verify(mWifiNative).getEapAnonymousIdentity(any()); 1985 verify(mWifiNative).setEapAnonymousIdentity(any(), eq(pseudonym + "@" + realm), 1986 eq(true)); 1987 assertEquals(pseudonym + "@" + realm, 1988 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 1989 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 1990 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 1991 // pseudonym usage in all subsequent connections. 1992 // Note: This test will fail if future logic will have additional conditions that would 1993 // trigger "add or update network" operation. The test needs to be updated to account for 1994 // this change. 1995 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 1996 } 1997 1998 /** 1999 * Tests anonymous identity will be set to suggestion network. 2000 */ 2001 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForSuggestion()2002 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForSuggestion() 2003 throws Exception { 2004 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 2005 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 2006 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 2007 mConnectedNetwork.fromWifiNetworkSuggestion = true; 2008 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 2009 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 2010 2011 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 2012 .thenReturn(DATA_SUBID); 2013 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 2014 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 2015 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 2016 .thenReturn(expectedAnonymousIdentity); 2017 2018 triggerConnect(); 2019 2020 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 2021 assertEquals(expectedAnonymousIdentity, 2022 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2023 2024 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2025 .thenReturn(mScanDetailCache); 2026 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 2027 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 2028 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 2029 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 2030 when(mWifiNative.getEapAnonymousIdentity(anyString())) 2031 .thenReturn(pseudonym); 2032 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 2033 2034 WifiSsid wifiSsid = WifiSsid.fromBytes( 2035 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 2036 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2037 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 2038 mLooper.dispatchAll(); 2039 2040 verify(mWifiNative).getEapAnonymousIdentity(any()); 2041 // No decorated pseudonum, only update the cached data. 2042 verify(mWifiNative).setEapAnonymousIdentity(any(), eq(pseudonym), eq(false)); 2043 assertEquals(pseudonym, 2044 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2045 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 2046 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 2047 // pseudonym usage in all subsequent connections. 2048 // Note: This test will fail if future logic will have additional conditions that would 2049 // trigger "add or update network" operation. The test needs to be updated to account for 2050 // this change. 2051 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 2052 verify(mWifiNetworkSuggestionsManager).setAnonymousIdentity(any()); 2053 } 2054 2055 /** 2056 * For EAP SIM network, the In-band pseudonym from supplicant should override the OOB 2057 * pseudonym if the OOB Pseudonym feature is enabled. 2058 */ 2059 @Test testUpdatePseudonymAsInBandPseudonymWhenConnectionIsEstablished()2060 public void testUpdatePseudonymAsInBandPseudonymWhenConnectionIsEstablished() 2061 throws Exception { 2062 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 2063 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 2064 String initialOobPseudonym = "1234abcg@wlan.mnc456.mcc123.3gppnetwork.org"; 2065 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(initialOobPseudonym); 2066 mConnectedNetwork.fromWifiNetworkSuggestion = true; 2067 String pseudonymFromSupplicant = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 2068 2069 when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true); 2070 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 2071 .thenReturn(DATA_SUBID); 2072 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 2073 2074 triggerConnect(); 2075 2076 // CMD_START_CONNECT doesn't change the anonymous identity. 2077 assertEquals(initialOobPseudonym, 2078 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2079 2080 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2081 .thenReturn(mScanDetailCache); 2082 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 2083 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 2084 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 2085 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 2086 when(mWifiNative.getEapAnonymousIdentity(anyString())) 2087 .thenReturn(pseudonymFromSupplicant); 2088 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 2089 2090 WifiSsid wifiSsid = WifiSsid.fromBytes( 2091 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 2092 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2093 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 2094 mLooper.dispatchAll(); 2095 2096 verify(mWifiNative).getEapAnonymousIdentity(any()); 2097 // No decorated pseudonum, only update the cached data. 2098 verify(mWifiNative).setEapAnonymousIdentity(any(), eq(pseudonymFromSupplicant), 2099 eq(false)); 2100 verify(mWifiPseudonymManager).setInBandPseudonym(anyInt(), eq(pseudonymFromSupplicant)); 2101 assertEquals(pseudonymFromSupplicant, 2102 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2103 } 2104 2105 /** 2106 * Tests anonymous identity will be set to passpoint network. 2107 */ 2108 @Test testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForPasspoint()2109 public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonymForPasspoint() 2110 throws Exception { 2111 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 2112 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 2113 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 2114 mConnectedNetwork.FQDN = WifiConfigurationTestUtil.TEST_FQDN; 2115 mConnectedNetwork.providerFriendlyName = 2116 WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 2117 mConnectedNetwork.setPasspointUniqueId(WifiConfigurationTestUtil.TEST_FQDN + "_" 2118 + WifiConfigurationTestUtil.TEST_FQDN.hashCode()); 2119 String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; 2120 String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; 2121 2122 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 2123 .thenReturn(DATA_SUBID); 2124 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 2125 when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true); 2126 when(mWifiCarrierInfoManager.getAnonymousIdentityWith3GppRealm(any())) 2127 .thenReturn(expectedAnonymousIdentity); 2128 2129 triggerConnect(); 2130 2131 // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm> 2132 assertEquals(expectedAnonymousIdentity, 2133 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2134 2135 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2136 .thenReturn(mScanDetailCache); 2137 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 2138 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 2139 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 2140 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 2141 when(mWifiNative.getEapAnonymousIdentity(anyString())) 2142 .thenReturn(pseudonym); 2143 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(1)).thenReturn(true); 2144 2145 WifiSsid wifiSsid = WifiSsid.fromBytes( 2146 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 2147 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2148 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 2149 mLooper.dispatchAll(); 2150 2151 verify(mWifiNative).getEapAnonymousIdentity(any()); 2152 // No decorated pseudonum, only update the cached data. 2153 verify(mWifiNative).setEapAnonymousIdentity(any(), eq(pseudonym), eq(false)); 2154 assertEquals(pseudonym, 2155 mConnectedNetwork.enterpriseConfig.getAnonymousIdentity()); 2156 // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a 2157 // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by 2158 // pseudonym usage in all subsequent connections. 2159 // Note: This test will fail if future logic will have additional conditions that would 2160 // trigger "add or update network" operation. The test needs to be updated to account for 2161 // this change. 2162 verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt()); 2163 verify(mPasspointManager).setAnonymousIdentity(any()); 2164 } 2165 /** 2166 * Tests the Passpoint information is set in WifiInfo for Passpoint AP connection. 2167 */ 2168 @Test connectPasspointAp()2169 public void connectPasspointAp() throws Exception { 2170 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 2171 config.SSID = TEST_WIFI_SSID.toString(); 2172 config.BSSID = TEST_BSSID_STR; 2173 config.networkId = FRAMEWORK_NETWORK_ID; 2174 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 2175 config.roamingConsortiumIds = TEST_RCOI_ARRAY; 2176 when(mPasspointManager.getSelectedRcoiForNetwork(eq(config.getPasspointUniqueId()), 2177 eq(config.SSID))).thenReturn(TEST_MATCHED_RCOI); 2178 setupAndStartConnectSequence(config); 2179 validateSuccessfulConnectSequence(config); 2180 assertEquals(TEST_MATCHED_RCOI, config.enterpriseConfig.getSelectedRcoi()); 2181 2182 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2183 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2184 SupplicantState.ASSOCIATING)); 2185 mLooper.dispatchAll(); 2186 2187 WifiInfo wifiInfo = mWifiInfo; 2188 assertNotNull(wifiInfo); 2189 assertEquals(WifiConfigurationTestUtil.TEST_FQDN, wifiInfo.getPasspointFqdn()); 2190 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 2191 wifiInfo.getPasspointProviderFriendlyName()); 2192 } 2193 2194 /** 2195 * Tests that Passpoint fields in WifiInfo are reset when connecting to a non-Passpoint network 2196 * during DisconnectedState. 2197 * @throws Exception 2198 */ 2199 @Test testResetWifiInfoPasspointFields()2200 public void testResetWifiInfoPasspointFields() throws Exception { 2201 WifiConfiguration config = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 2202 config.SSID = TEST_WIFI_SSID.toString(); 2203 config.BSSID = TEST_BSSID_STR; 2204 config.networkId = PASSPOINT_NETWORK_ID; 2205 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 2206 setupAndStartConnectSequence(config); 2207 validateSuccessfulConnectSequence(config); 2208 2209 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2210 new StateChangeResult(PASSPOINT_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2211 SupplicantState.ASSOCIATING)); 2212 mLooper.dispatchAll(); 2213 2214 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2215 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2216 SupplicantState.ASSOCIATING)); 2217 mLooper.dispatchAll(); 2218 2219 WifiInfo wifiInfo = mWifiInfo; 2220 assertNotNull(wifiInfo); 2221 assertNull(wifiInfo.getPasspointFqdn()); 2222 assertNull(wifiInfo.getPasspointProviderFriendlyName()); 2223 } 2224 2225 /** 2226 * Tests the OSU information is set in WifiInfo for OSU AP connection. 2227 */ 2228 @Test connectOsuAp()2229 public void connectOsuAp() throws Exception { 2230 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 2231 osuConfig.SSID = TEST_WIFI_SSID.toString(); 2232 osuConfig.BSSID = TEST_BSSID_STR; 2233 osuConfig.osu = true; 2234 osuConfig.networkId = FRAMEWORK_NETWORK_ID; 2235 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 2236 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 2237 setupAndStartConnectSequence(osuConfig); 2238 validateSuccessfulConnectSequence(osuConfig); 2239 2240 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2241 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2242 SupplicantState.ASSOCIATING)); 2243 mLooper.dispatchAll(); 2244 2245 WifiInfo wifiInfo = mWifiInfo; 2246 assertNotNull(wifiInfo); 2247 assertTrue(wifiInfo.isOsuAp()); 2248 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 2249 wifiInfo.getPasspointProviderFriendlyName()); 2250 } 2251 2252 /** 2253 * Tests that OSU fields in WifiInfo are reset when connecting to a non-OSU network during 2254 * DisconnectedState. 2255 * @throws Exception 2256 */ 2257 @Test testResetWifiInfoOsuFields()2258 public void testResetWifiInfoOsuFields() throws Exception { 2259 WifiConfiguration osuConfig = spy(WifiConfigurationTestUtil.createEphemeralNetwork()); 2260 osuConfig.SSID = TEST_WIFI_SSID.toString(); 2261 osuConfig.BSSID = TEST_BSSID_STR; 2262 osuConfig.osu = true; 2263 osuConfig.networkId = PASSPOINT_NETWORK_ID; 2264 osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME; 2265 osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 2266 setupAndStartConnectSequence(osuConfig); 2267 validateSuccessfulConnectSequence(osuConfig); 2268 2269 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2270 new StateChangeResult(PASSPOINT_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2271 SupplicantState.ASSOCIATING)); 2272 mLooper.dispatchAll(); 2273 2274 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2275 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 2276 SupplicantState.ASSOCIATING)); 2277 mLooper.dispatchAll(); 2278 2279 WifiInfo wifiInfo = mWifiInfo; 2280 assertNotNull(wifiInfo); 2281 assertFalse(wifiInfo.isOsuAp()); 2282 } 2283 2284 /** 2285 * Tests that {@link WifiInfo#getHiddenSsid()} returns {@code true} if we've connected to a 2286 * hidden SSID network. 2287 * @throws Exception 2288 */ 2289 @Test testConnectHiddenSsid()2290 public void testConnectHiddenSsid() throws Exception { 2291 connect(); 2292 2293 // Set the scan detail cache for hidden SSID. 2294 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 2295 .thenReturn(mScanDetailCache); 2296 ScanDetail hiddenScanDetail = getHiddenScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1); 2297 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn(hiddenScanDetail); 2298 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 2299 hiddenScanDetail.getScanResult()); 2300 2301 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR1); 2302 mLooper.dispatchAll(); 2303 2304 // Hidden SSID scan result should set WifiInfo.getHiddenSsid() to true. 2305 assertTrue(mWifiInfo.getHiddenSSID()); 2306 2307 // Set the scan detail cache for non-hidden SSID. 2308 ScanDetail googleGuestScanDetail = 2309 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq1); 2310 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn(googleGuestScanDetail); 2311 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 2312 googleGuestScanDetail.getScanResult()); 2313 2314 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR); 2315 mLooper.dispatchAll(); 2316 2317 // Non-hidden SSID scan result should set WifiInfo.getHiddenSsid() to false. 2318 assertFalse(mWifiInfo.getHiddenSSID()); 2319 } 2320 2321 /** 2322 * Verify that WifiStateTracker is called if wifi is disabled while connected. 2323 */ 2324 @Test verifyWifiStateTrackerUpdatedWhenDisabled()2325 public void verifyWifiStateTrackerUpdatedWhenDisabled() throws Exception { 2326 connect(); 2327 2328 mCmi.stop(); 2329 mLooper.dispatchAll(); 2330 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.DISCONNECTED); 2331 } 2332 2333 @Test testIdleModeChanged_firmwareRoaming()2334 public void testIdleModeChanged_firmwareRoaming() throws Exception { 2335 // verify no-op when either the feature flag is disabled or firmware roaming is not 2336 // supported 2337 when(mWifiGlobals.isDisableFirmwareRoamingInIdleMode()).thenReturn(false); 2338 when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 2339 mCmi.onIdleModeChanged(true); 2340 verify(mWifiNative, never()).enableFirmwareRoaming(anyString(), anyInt()); 2341 when(mWifiGlobals.isDisableFirmwareRoamingInIdleMode()).thenReturn(true); 2342 when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(false); 2343 mCmi.onIdleModeChanged(true); 2344 verify(mWifiNative, never()).enableFirmwareRoaming(anyString(), anyInt()); 2345 2346 // Enable both, then verify firmware roaming is not yet disabled when idle mode is entered 2347 // because screen is still on 2348 when(mWifiGlobals.isDisableFirmwareRoamingInIdleMode()).thenReturn(true); 2349 when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 2350 mCmi.onIdleModeChanged(true); 2351 verify(mWifiNative, never()).enableFirmwareRoaming(anyString(), anyInt()); 2352 2353 // Verify firmware roaming is now disabled after screen turns off 2354 setScreenState(false); 2355 mLooper.dispatchAll(); 2356 verify(mWifiNative).enableFirmwareRoaming(anyString(), 2357 eq(WifiNative.DISABLE_FIRMWARE_ROAMING)); 2358 2359 // Verify firmware roaming is enabled when idle mode exited 2360 when(mWifiRoamingConfigStore.getRoamingMode(anyString())).thenReturn( 2361 WifiManager.ROAMING_MODE_NORMAL); 2362 mCmi.onIdleModeChanged(false); 2363 verify(mWifiNative).setRoamingMode(anyString(), 2364 eq(WifiManager.ROAMING_MODE_NORMAL)); 2365 } 2366 2367 @Test testIdleModeChanged_firmwareRoamingLocalOnlyCase()2368 public void testIdleModeChanged_firmwareRoamingLocalOnlyCase() throws Exception { 2369 // mock connected network to be local only 2370 connect(); 2371 mConnectedNetwork.fromWifiNetworkSpecifier = true; 2372 2373 // Enable feature, then verify firmware roaming is disabled when idle mode is entered 2374 when(mWifiGlobals.isDisableFirmwareRoamingInIdleMode()).thenReturn(true); 2375 when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 2376 mCmi.onIdleModeChanged(true); 2377 setScreenState(false); 2378 mLooper.dispatchAll(); 2379 verify(mWifiNative).enableFirmwareRoaming(anyString(), 2380 eq(WifiNative.DISABLE_FIRMWARE_ROAMING)); 2381 2382 // Verify firmware roaming is not enabled when idle mode exited 2383 mCmi.onIdleModeChanged(false); 2384 verify(mWifiNative, never()).enableFirmwareRoaming(anyString(), 2385 eq(WifiNative.ENABLE_FIRMWARE_ROAMING)); 2386 } 2387 2388 /** 2389 * Verify that when the primary connects, roaming mode is set 2390 * based on the connected network ssid. 2391 */ 2392 @Test testPerSsidRoamingModePrimary()2393 public void testPerSsidRoamingModePrimary() throws Exception { 2394 when(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID)).thenReturn( 2395 WifiManager.ROAMING_MODE_NORMAL); 2396 connect(); 2397 verify(mWifiRoamingConfigStore).getRoamingMode(TEST_SSID); 2398 verify(mWifiNative).setRoamingMode(anyString(), 2399 eq(WifiManager.ROAMING_MODE_NORMAL)); 2400 } 2401 2402 /** 2403 * Verify that when the secondary connects, roaming mode is not set. 2404 */ 2405 @Test testPerSsidRoamingModeSecondary()2406 public void testPerSsidRoamingModeSecondary() throws Exception { 2407 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 2408 connect(); 2409 verify(mWifiRoamingConfigStore, never()).getRoamingMode(anyString()); 2410 verify(mWifiNative, never()).setRoamingMode(anyString(), anyInt()); 2411 } 2412 2413 /** 2414 * Tests the network connection initiation sequence with no network request pending from 2415 * from WifiNetworkFactory when we're already connected to a different network. 2416 * This simulates the connect sequence using the public 2417 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke 2418 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 2419 */ 2420 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnected()2421 public void triggerConnectWithNoNetworkRequestAndAlreadyConnected() throws Exception { 2422 // Simulate the first connection. 2423 connect(); 2424 2425 // Remove the network requests. 2426 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2427 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2428 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2429 when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(false); 2430 2431 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 2432 config.networkId = FRAMEWORK_NETWORK_ID + 1; 2433 setupAndStartConnectSequence(config); 2434 validateSuccessfulConnectSequence(config); 2435 verify(mWifiPermissionsUtil, atLeastOnce()).checkNetworkSettingsPermission(anyInt()); 2436 } 2437 2438 /** 2439 * Tests the network connection initiation sequence from a non-privileged app with no network 2440 * request pending from from WifiNetworkFactory when we're already connected to a different 2441 * network. 2442 * This simulates the connect sequence using the public 2443 * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke 2444 * {@link WifiNative#connectToNetwork(WifiConfiguration)}. 2445 */ 2446 @Test triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp()2447 public void triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp() 2448 throws Exception { 2449 // Simulate the first connection. 2450 connect(); 2451 2452 // Remove the network requests. 2453 when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2454 when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2455 when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(false); 2456 when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(false); 2457 2458 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 2459 2460 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 2461 config.networkId = FRAMEWORK_NETWORK_ID + 1; 2462 setupAndStartConnectSequence(config); 2463 verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); 2464 verify(mWifiConfigManager, never()) 2465 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 2466 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 2467 // These are called from connectToUserSelectNetwork() and L2ConnectedState::enter() 2468 verify(mWifiPermissionsUtil, times(4)).checkNetworkSettingsPermission(anyInt()); 2469 } 2470 2471 /** 2472 * If caller tries to connect to a network that is already connected, the connection request 2473 * should succeed. 2474 * 2475 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 2476 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 2477 */ 2478 @Test reconnectToConnectedNetworkWithNetworkId()2479 public void reconnectToConnectedNetworkWithNetworkId() throws Exception { 2480 connect(); 2481 2482 // try to reconnect 2483 IActionListener connectActionListener = mock(IActionListener.class); 2484 mCmi.connectNetwork( 2485 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2486 new ActionListenerWrapper(connectActionListener), 2487 Binder.getCallingUid(), OP_PACKAGE_NAME, TEST_ATTRIBUTION_TAG); 2488 mLooper.dispatchAll(); 2489 verify(connectActionListener).onSuccess(); 2490 2491 // Verify that we didn't trigger a second connection. 2492 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2493 } 2494 2495 /** 2496 * If caller tries to connect to a network that is already connected, the connection request 2497 * should succeed. 2498 * 2499 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 2500 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 2501 */ 2502 @Test reconnectToConnectedNetworkWithConfig()2503 public void reconnectToConnectedNetworkWithConfig() throws Exception { 2504 connect(); 2505 2506 // try to reconnect 2507 IActionListener connectActionListener = mock(IActionListener.class); 2508 int callingUid = Binder.getCallingUid(); 2509 mCmi.connectNetwork( 2510 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2511 new ActionListenerWrapper(connectActionListener), 2512 callingUid, OP_PACKAGE_NAME, TEST_ATTRIBUTION_TAG); 2513 mLooper.dispatchAll(); 2514 verify(connectActionListener).onSuccess(); 2515 2516 // Verify that we didn't trigger a second connection. 2517 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2518 } 2519 2520 /** 2521 * If caller tries to connect to a network that is already connecting, the connection request 2522 * should succeed. 2523 * 2524 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 2525 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did not trigger a 2526 * new connection. 2527 */ 2528 @Test reconnectToConnectingNetwork()2529 public void reconnectToConnectingNetwork() throws Exception { 2530 triggerConnect(); 2531 2532 // try to reconnect to the same network (before connection is established). 2533 IActionListener connectActionListener = mock(IActionListener.class); 2534 mCmi.connectNetwork( 2535 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2536 new ActionListenerWrapper(connectActionListener), 2537 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2538 mLooper.dispatchAll(); 2539 verify(connectActionListener).onSuccess(); 2540 2541 // Verify that we didn't trigger a second connection. 2542 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2543 } 2544 2545 /** 2546 * If caller tries to connect to a network that is already connecting, the connection request 2547 * should succeed. 2548 * 2549 * Test: Create and trigger connect to a network, then try to reconnect to the same network. 2550 * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did trigger a new 2551 * connection. 2552 */ 2553 @Test reconnectToConnectingNetworkWithCredentialChange()2554 public void reconnectToConnectingNetworkWithCredentialChange() throws Exception { 2555 triggerConnect(); 2556 2557 // try to reconnect to the same network with a credential changed (before connection is 2558 // established). 2559 NetworkUpdateResult networkUpdateResult = new NetworkUpdateResult( 2560 FRAMEWORK_NETWORK_ID, 2561 STATUS_SUCCESS, 2562 false /* ip */, 2563 false /* proxy */, 2564 true /* credential */, 2565 false /* isNewNetwork */); 2566 IActionListener connectActionListener = mock(IActionListener.class); 2567 mCmi.connectNetwork( 2568 networkUpdateResult, 2569 new ActionListenerWrapper(connectActionListener), 2570 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2571 mLooper.dispatchAll(); 2572 verify(connectActionListener).onSuccess(); 2573 2574 // Verify that we triggered a second connection. 2575 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2576 } 2577 2578 /** 2579 * If caller tries to connect to a network that previously failed connection, the connection 2580 * request should succeed. 2581 * 2582 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 2583 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 2584 * and did trigger a new * connection. 2585 */ 2586 @Test connectAfterAssociationRejection()2587 public void connectAfterAssociationRejection() throws Exception { 2588 triggerConnect(); 2589 2590 // fail the connection. 2591 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 2592 new AssocRejectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 2593 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 2594 mLooper.dispatchAll(); 2595 2596 IActionListener connectActionListener = mock(IActionListener.class); 2597 mCmi.connectNetwork( 2598 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2599 new ActionListenerWrapper(connectActionListener), 2600 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2601 mLooper.dispatchAll(); 2602 verify(connectActionListener).onSuccess(); 2603 2604 // Verify that we triggered a second connection. 2605 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2606 } 2607 2608 /** 2609 * If caller tries to connect to a network that previously failed connection, the connection 2610 * request should succeed. 2611 * 2612 * Test: Create and trigger connect to a network, then fail the connection. Now try to reconnect 2613 * to the same network. Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED 2614 * and did trigger a new * connection. 2615 */ 2616 @Test connectAfterConnectionFailure()2617 public void connectAfterConnectionFailure() throws Exception { 2618 triggerConnect(); 2619 2620 // fail the connection. 2621 DisconnectEventInfo disconnectEventInfo = 2622 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 2623 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2624 mLooper.dispatchAll(); 2625 2626 IActionListener connectActionListener = mock(IActionListener.class); 2627 mCmi.connectNetwork( 2628 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2629 new ActionListenerWrapper(connectActionListener), 2630 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2631 mLooper.dispatchAll(); 2632 verify(connectActionListener).onSuccess(); 2633 2634 // Verify that we triggered a second connection. 2635 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any()); 2636 } 2637 2638 /** 2639 * If the interface has been switched to scan, the network disconnection event should clear the 2640 * current network. 2641 * @throws Exception 2642 */ 2643 @Test testNetworkDisconnectAfterInterfaceSwitchedToScan()2644 public void testNetworkDisconnectAfterInterfaceSwitchedToScan() throws Exception { 2645 triggerConnect(); 2646 IActionListener connectActionListener = mock(IActionListener.class); 2647 mCmi.connectNetwork( 2648 new NetworkUpdateResult(FRAMEWORK_NETWORK_ID), 2649 new ActionListenerWrapper(connectActionListener), 2650 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2651 mLooper.dispatchAll(); 2652 verify(connectActionListener).onSuccess(); 2653 2654 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY); 2655 // Disconnection from previous network. 2656 DisconnectEventInfo disconnectEventInfo = 2657 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2658 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2659 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2660 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2661 SupplicantState.DISCONNECTED)); 2662 mLooper.dispatchAll(); 2663 verify(mActiveModeWarden).setCurrentNetwork(null); 2664 } 2665 2666 @Test testWifiInfoNetworkIdSetInScanningState()2667 public void testWifiInfoNetworkIdSetInScanningState() throws Exception { 2668 triggerConnect(); 2669 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, mWifiInfo.getNetworkId()); 2670 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2671 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2672 SupplicantState.SCANNING)); 2673 mLooper.dispatchAll(); 2674 assertEquals(0, mWifiInfo.getNetworkId()); 2675 } 2676 2677 /** 2678 * If caller tries to connect to a new network while still provisioning the current one, 2679 * the connection attempt should succeed. 2680 */ 2681 @Test connectWhileObtainingIp()2682 public void connectWhileObtainingIp() throws Exception { 2683 initializeAndAddNetworkAndVerifySuccess(); 2684 2685 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 2686 2687 startConnectSuccess(); 2688 2689 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2690 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 2691 mLooper.dispatchAll(); 2692 2693 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2694 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2695 SupplicantState.COMPLETED)); 2696 mLooper.dispatchAll(); 2697 2698 assertEquals("L3ProvisioningState", getCurrentState().getName()); 2699 2700 // Connect to a different network 2701 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 2702 config.networkId = FRAMEWORK_NETWORK_ID + 1; 2703 setupAndStartConnectSequence(config); 2704 validateSuccessfulConnectSequence(config); 2705 2706 // Disconnection from previous network. 2707 DisconnectEventInfo disconnectEventInfo = 2708 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2709 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2710 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2711 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2712 SupplicantState.DISCONNECTED)); 2713 mLooper.dispatchAll(); 2714 2715 // Ensure we don't end the new connection event. 2716 verify(mWifiMetrics, never()).endConnectionEvent( 2717 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 2718 anyInt(), anyInt(), anyInt(), anyInt()); 2719 verify(mWifiConnectivityManager).prepareForForcedConnection(FRAMEWORK_NETWORK_ID + 1); 2720 } 2721 2722 /** 2723 * If there is a network removal while still connecting to it, the connection 2724 * should be aborted. 2725 */ 2726 @Test networkRemovalWhileObtainingIp()2727 public void networkRemovalWhileObtainingIp() throws Exception { 2728 initializeAndAddNetworkAndVerifySuccess(); 2729 2730 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 2731 2732 startConnectSuccess(); 2733 2734 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2735 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 2736 mLooper.dispatchAll(); 2737 2738 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2739 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2740 SupplicantState.COMPLETED)); 2741 mLooper.dispatchAll(); 2742 2743 assertEquals("L3ProvisioningState", getCurrentState().getName()); 2744 reset(mWifiNative); 2745 2746 // Simulate the target network removal & the disconnect trigger. 2747 WifiConfiguration removedNetwork = new WifiConfiguration(); 2748 removedNetwork.networkId = FRAMEWORK_NETWORK_ID; 2749 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 2750 .getAllValues()) { 2751 listener.onNetworkRemoved(removedNetwork); 2752 } 2753 mLooper.dispatchAll(); 2754 2755 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 2756 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 2757 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 2758 eq(StaEvent.DISCONNECT_NETWORK_REMOVED)); 2759 2760 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)).thenReturn(null); 2761 DisconnectEventInfo disconnectEventInfo = 2762 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2763 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2764 mLooper.dispatchAll(); 2765 2766 assertEquals("DisconnectedState", getCurrentState().getName()); 2767 } 2768 2769 /** 2770 * Tests that manual connection to a network (from settings app) logs the correct nominator ID. 2771 */ 2772 @Test testManualConnectNominator()2773 public void testManualConnectNominator() throws Exception { 2774 initializeAndAddNetworkAndVerifySuccess(); 2775 2776 WifiConfiguration config = new WifiConfiguration(); 2777 config.networkId = TEST_NETWORK_ID; 2778 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 2779 2780 IActionListener connectActionListener = mock(IActionListener.class); 2781 mCmi.connectNetwork( 2782 new NetworkUpdateResult(TEST_NETWORK_ID), 2783 new ActionListenerWrapper(connectActionListener), 2784 Process.SYSTEM_UID, OP_PACKAGE_NAME, null); 2785 mLooper.dispatchAll(); 2786 verify(connectActionListener).onSuccess(); 2787 2788 verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, 2789 WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); 2790 } 2791 startConnectSuccess()2792 private void startConnectSuccess() throws Exception { 2793 startConnectSuccess(FRAMEWORK_NETWORK_ID); 2794 } 2795 startConnectSuccess(int networkId)2796 private void startConnectSuccess(int networkId) throws Exception { 2797 IActionListener connectActionListener = mock(IActionListener.class); 2798 mCmi.connectNetwork( 2799 new NetworkUpdateResult(networkId), 2800 new ActionListenerWrapper(connectActionListener), 2801 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 2802 mLooper.dispatchAll(); 2803 verify(connectActionListener).onSuccess(); 2804 } 2805 2806 @Test testDhcpFailure()2807 public void testDhcpFailure() throws Exception { 2808 initializeAndAddNetworkAndVerifySuccess(); 2809 2810 startConnectSuccess(); 2811 2812 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2813 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2814 SupplicantState.ASSOCIATED)); 2815 mLooper.dispatchAll(); 2816 2817 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 2818 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 2819 mLooper.dispatchAll(); 2820 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 2821 2822 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 2823 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 2824 SupplicantState.COMPLETED)); 2825 mLooper.dispatchAll(); 2826 2827 assertEquals("L3ProvisioningState", getCurrentState().getName()); 2828 injectDhcpFailure(); 2829 mLooper.dispatchAll(); 2830 2831 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 2832 // Verify this is not counted as a IP renewal failure 2833 verify(mWifiMetrics, never()).incrementIpRenewalFailure(); 2834 // Verifies that WifiLastResortWatchdog be notified 2835 // by DHCP failure 2836 verify(mWifiLastResortWatchdog, times(2)).noteConnectionFailureAndTriggerIfNeeded( 2837 eq(TEST_SSID), eq(TEST_BSSID_STR), 2838 eq(WifiLastResortWatchdog.FAILURE_CODE_DHCP), anyBoolean()); 2839 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 2840 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_DHCP_FAILURE), anyInt()); 2841 verify(mWifiBlocklistMonitor, never()).handleDhcpProvisioningSuccess( 2842 TEST_BSSID_STR, TEST_SSID); 2843 verify(mWifiBlocklistMonitor, never()).handleNetworkValidationSuccess( 2844 TEST_BSSID_STR, TEST_SSID); 2845 DisconnectEventInfo disconnectEventInfo = 2846 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 3, true); 2847 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2848 mLooper.dispatchAll(); 2849 } 2850 2851 /** 2852 * Verify that a IP renewal failure is logged when IP provisioning fail in the 2853 * L3ConnectedState. 2854 */ 2855 @Test testDhcpRenewalMetrics()2856 public void testDhcpRenewalMetrics() throws Exception { 2857 connect(); 2858 injectDhcpFailure(); 2859 mLooper.dispatchAll(); 2860 2861 verify(mWifiMetrics).incrementIpRenewalFailure(); 2862 } 2863 2864 /** 2865 * Verify that the network selection status will be updated with DISABLED_AUTHENTICATION_FAILURE 2866 * when wrong password authentication failure is detected and the network had been 2867 * connected previously. 2868 */ 2869 @Test testWrongPasswordWithPreviouslyConnected()2870 public void testWrongPasswordWithPreviouslyConnected() throws Exception { 2871 initializeAndAddNetworkAndVerifySuccess(); 2872 2873 startConnectSuccess(); 2874 2875 WifiConfiguration config = createTestNetwork(false); 2876 config.getNetworkSelectionStatus().setHasEverConnected(true); 2877 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2878 2879 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2880 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 2881 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 2882 DisconnectEventInfo disconnectEventInfo = 2883 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2884 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2885 mLooper.dispatchAll(); 2886 2887 verify(mWrongPasswordNotifier, never()).onWrongPasswordError(any()); 2888 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 2889 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE)); 2890 2891 assertEquals("DisconnectedState", getCurrentState().getName()); 2892 } 2893 2894 /** 2895 * Verify that when wrong password authentication failure notification is not sent when 2896 * the network was local only. 2897 */ 2898 @Test testWrongPasswordWithLocalOnlyConnection()2899 public void testWrongPasswordWithLocalOnlyConnection() throws Exception { 2900 initializeAndAddNetworkAndVerifySuccess(); 2901 2902 startConnectSuccess(); 2903 2904 WifiConfiguration config = createTestNetwork(false); 2905 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2906 2907 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 2908 .thenReturn(Set.of(TEST_UID)); 2909 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 2910 .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME)); 2911 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2912 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 2913 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 2914 DisconnectEventInfo disconnectEventInfo = 2915 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2916 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2917 mLooper.dispatchAll(); 2918 2919 verify(mWrongPasswordNotifier, never()).onWrongPasswordError(any()); 2920 assertEquals("DisconnectedState", getCurrentState().getName()); 2921 } 2922 2923 /** 2924 * Verify that when wrong password authentication failure notification is sent when 2925 * the network was NOT local only. 2926 */ 2927 @Test testWrongPasswordWithNonLocalOnlyConnection()2928 public void testWrongPasswordWithNonLocalOnlyConnection() throws Exception { 2929 initializeAndAddNetworkAndVerifySuccess(); 2930 2931 startConnectSuccess(); 2932 2933 WifiConfiguration config = createTestNetwork(false); 2934 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2935 2936 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 2937 .thenReturn(Collections.emptySet()); 2938 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 2939 .thenReturn(Pair.create(Process.INVALID_UID, "")); 2940 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 2941 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 2942 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 2943 DisconnectEventInfo disconnectEventInfo = 2944 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2945 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2946 mLooper.dispatchAll(); 2947 2948 verify(mWrongPasswordNotifier).onWrongPasswordError(any()); 2949 assertEquals("DisconnectedState", getCurrentState().getName()); 2950 } 2951 2952 /** 2953 * It is observed sometimes the WifiMonitor.NETWORK_DISCONNECTION_EVENT is observed before the 2954 * actual connection failure messages while making a connection. 2955 * The test make sure that make sure that the connection event is ended properly in the above 2956 * case. 2957 */ 2958 @Test testDisconnectionEventInL2ConnectingStateEndsConnectionEvent()2959 public void testDisconnectionEventInL2ConnectingStateEndsConnectionEvent() throws Exception { 2960 initializeAndAddNetworkAndVerifySuccess(); 2961 2962 startConnectSuccess(); 2963 2964 WifiConfiguration config = createTestNetwork(false); 2965 config.getNetworkSelectionStatus().setHasEverConnected(true); 2966 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2967 2968 DisconnectEventInfo disconnectEventInfo = 2969 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 2970 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 2971 mLooper.dispatchAll(); 2972 2973 verify(mWifiMetrics).endConnectionEvent( 2974 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 2975 anyInt(), anyInt(), anyInt(), anyInt()); 2976 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 2977 any(), anyInt(), anyInt(), any(), any()); 2978 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, mWifiInfo.getCurrentSecurityType()); 2979 assertEquals("DisconnectedState", getCurrentState().getName()); 2980 } 2981 2982 /** 2983 * Verify that the network selection status will be updated with DISABLED_BY_WRONG_PASSWORD 2984 * when wrong password authentication failure is detected and the network has never been 2985 * connected. 2986 */ 2987 @Test testWrongPasswordWithNeverConnected()2988 public void testWrongPasswordWithNeverConnected() throws Exception { 2989 initializeAndAddNetworkAndVerifySuccess(); 2990 2991 startConnectSuccess(); 2992 2993 WifiConfiguration config = new WifiConfiguration(); 2994 config.SSID = TEST_SSID; 2995 config.getNetworkSelectionStatus().setHasEverConnected(false); 2996 config.carrierId = CARRIER_ID_1; 2997 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 2998 2999 // Need to add supplicant state changed event to simulate broadcasts correctly 3000 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3001 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 3002 SupplicantState.ASSOCIATED)); 3003 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3004 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 3005 SupplicantState.FOUR_WAY_HANDSHAKE)); 3006 3007 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3008 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3009 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 3010 DisconnectEventInfo disconnectEventInfo = 3011 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 3012 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3013 mLooper.dispatchAll(); 3014 3015 verify(mWrongPasswordNotifier).onWrongPasswordError(config); 3016 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 3017 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD)); 3018 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionAuthFailure(); 3019 // Verify broadcasts corresponding to supplicant ASSOCIATED, FOUR_WAY_HANDSHAKE, then 3020 // finally wrong password causing disconnect. 3021 inOrderVerifyNetworkStateChangedBroadcasts( 3022 new NetworkStateChangedIntentMatcher(CONNECTING), 3023 new NetworkStateChangedIntentMatcher(AUTHENTICATING), 3024 new NetworkStateChangedIntentMatcher(DISCONNECTED)); 3025 assertEquals("DisconnectedState", getCurrentState().getName()); 3026 } 3027 3028 /** 3029 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 3030 * is called when a Authentication failure is detected with a vendor specific EAP Error 3031 * of certification expired while using EAP-SIM 3032 * In this test case, it is assumed that the network had been connected previously. 3033 */ 3034 @Test testEapSimErrorVendorSpecific()3035 public void testEapSimErrorVendorSpecific() throws Exception { 3036 when(mWifiMetrics.startConnectionEvent(any(), any(), anyString(), anyInt(), anyBoolean(), 3037 anyInt(), anyInt())).thenReturn(80000); 3038 initializeAndAddNetworkAndVerifySuccess(); 3039 3040 startConnectSuccess(); 3041 3042 WifiConfiguration config = new WifiConfiguration(); 3043 config.SSID = TEST_SSID; 3044 config.getNetworkSelectionStatus().setHasEverConnected(true); 3045 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 3046 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 3047 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 3048 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 3049 .thenReturn(WifiHealthMonitor.REASON_AUTH_FAILURE); 3050 3051 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3052 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3053 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 3054 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED)); 3055 mLooper.dispatchAll(); 3056 3057 verify(mEapFailureNotifier).onEapFailure( 3058 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED, config, true); 3059 verify(mWifiCarrierInfoManager).resetCarrierKeysForImsiEncryption(any()); 3060 verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled(); 3061 verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString()); 3062 verify(mWifiDiagnostics, times(2)).takeBugReport(anyString(), anyString()); 3063 } 3064 3065 @Test testEapAkaRetrieveOobPseudonymTriggeredByAuthenticationFailure()3066 public void testEapAkaRetrieveOobPseudonymTriggeredByAuthenticationFailure() throws Exception { 3067 when(mWifiMetrics.startConnectionEvent(any(), any(), anyString(), anyInt(), anyBoolean(), 3068 anyInt(), anyInt())).thenReturn(80000); 3069 when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true); 3070 initializeAndAddNetworkAndVerifySuccess(); 3071 3072 startConnectSuccess(); 3073 3074 WifiConfiguration config = new WifiConfiguration(); 3075 config.SSID = TEST_SSID; 3076 config.getNetworkSelectionStatus().setHasEverConnected(true); 3077 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 3078 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.AKA); 3079 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 3080 when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) 3081 .thenReturn(WifiHealthMonitor.REASON_AUTH_FAILURE); 3082 3083 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3084 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3085 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 3086 -1)); 3087 mLooper.dispatchAll(); 3088 3089 verify(mEapFailureNotifier).onEapFailure( 3090 -1, config, true); 3091 verify(mWifiPseudonymManager).retrieveOobPseudonymWithRateLimit(anyInt()); 3092 verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled(); 3093 verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString()); 3094 verify(mWifiDiagnostics, times(2)).takeBugReport(anyString(), anyString()); 3095 } 3096 3097 /** 3098 * Verify that the function resetCarrierKeysForImsiEncryption() in TelephonyManager 3099 * is not called when a Authentication failure is detected with a vendor specific EAP Error 3100 * of certification expired while using other methods than EAP-SIM, EAP-AKA, or EAP-AKA'. 3101 */ 3102 @Test testEapTlsErrorVendorSpecific()3103 public void testEapTlsErrorVendorSpecific() throws Exception { 3104 initializeAndAddNetworkAndVerifySuccess(); 3105 3106 startConnectSuccess(); 3107 3108 WifiConfiguration config = new WifiConfiguration(); 3109 config.getNetworkSelectionStatus().setHasEverConnected(true); 3110 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 3111 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 3112 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 3113 3114 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3115 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3116 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 3117 WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED)); 3118 mLooper.dispatchAll(); 3119 3120 verify(mWifiCarrierInfoManager, never()).resetCarrierKeysForImsiEncryption(any()); 3121 } 3122 3123 @Test testAuthFailureOnDifferentSsidIsIgnored()3124 public void testAuthFailureOnDifferentSsidIsIgnored() throws Exception { 3125 initializeAndAddNetworkAndVerifySuccess(); 3126 3127 startConnectSuccess(); 3128 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3129 new AuthenticationFailureEventInfo("WRONG_SSID", 3130 MacAddress.fromString(TEST_BSSID_STR), 3131 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 3132 WifiNative.EAP_SIM_NOT_SUBSCRIBED)); 3133 mLooper.dispatchAll(); 3134 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(), 3135 eq(WifiConfiguration.NetworkSelectionStatus 3136 .DISABLED_AUTHENTICATION_NO_SUBSCRIPTION)); 3137 } 3138 3139 /** 3140 * Verify that the network selection status will be updated with 3141 * DISABLED_AUTHENTICATION_NO_SUBSCRIBED when service is not subscribed. 3142 */ 3143 @Test testEapSimNoSubscribedError()3144 public void testEapSimNoSubscribedError() throws Exception { 3145 initializeAndAddNetworkAndVerifySuccess(); 3146 3147 startConnectSuccess(); 3148 3149 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3150 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3151 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, 3152 WifiNative.EAP_SIM_NOT_SUBSCRIBED)); 3153 mLooper.dispatchAll(); 3154 3155 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 3156 eq(WifiConfiguration.NetworkSelectionStatus 3157 .DISABLED_AUTHENTICATION_NO_SUBSCRIPTION)); 3158 } 3159 3160 @Test testBadNetworkEvent()3161 public void testBadNetworkEvent() throws Exception { 3162 initializeAndAddNetworkAndVerifySuccess(); 3163 3164 startConnectSuccess(); 3165 3166 DisconnectEventInfo disconnectEventInfo = 3167 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 3168 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3169 mLooper.dispatchAll(); 3170 3171 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3172 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 3173 SupplicantState.COMPLETED)); 3174 mLooper.dispatchAll(); 3175 3176 assertEquals("DisconnectedState", getCurrentState().getName()); 3177 verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString()); 3178 } 3179 3180 3181 @Test getWhatToString()3182 public void getWhatToString() throws Exception { 3183 assertEquals("CMD_PRE_DHCP_ACTION", mCmi.getWhatToString(CMD_PRE_DHCP_ACTION)); 3184 assertEquals("CMD_IP_REACHABILITY_LOST", mCmi.getWhatToString( 3185 ClientModeImpl.CMD_IP_REACHABILITY_LOST)); 3186 assertEquals("CMD_IP_REACHABILITY_FAILURE", mCmi.getWhatToString( 3187 ClientModeImpl.CMD_IP_REACHABILITY_FAILURE)); 3188 } 3189 3190 @Test disconnect()3191 public void disconnect() throws Exception { 3192 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 3193 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 3194 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 3195 connect(); 3196 inOrderWifiLockManager.verify(mWifiLockManager) 3197 .updateWifiClientConnected(mClientModeManager, true); 3198 3199 DisconnectEventInfo disconnectEventInfo = 3200 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 3201 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3202 mLooper.dispatchAll(); 3203 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3204 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 3205 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 3206 mLooper.dispatchAll(); 3207 3208 verify(mWifiStateTracker).updateState(WIFI_IFACE_NAME, WifiStateTracker.DISCONNECTED); 3209 assertEquals("DisconnectedState", getCurrentState().getName()); 3210 verify(mCmiMonitor).onConnectionEnd(mClientModeManager); 3211 inOrderWifiLockManager.verify(mWifiLockManager) 3212 .updateWifiClientConnected(mClientModeManager, false); 3213 verify(mWifiScoreCard).detectAbnormalDisconnection(WIFI_IFACE_NAME); 3214 verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); 3215 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 3216 // Set MAC address thrice - once at bootup, once for new connection, once for disconnect. 3217 verify(mWifiNative, times(3)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 3218 // ClientModeManager should only be stopped when in lingering mode 3219 verify(mClientModeManager, never()).stop(); 3220 } 3221 3222 @Test secondaryRoleCmmDisconnected_stopsClientModeManager()3223 public void secondaryRoleCmmDisconnected_stopsClientModeManager() throws Exception { 3224 // Owning ClientModeManager has role SECONDARY_TRANSIENT 3225 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 3226 3227 connect(); 3228 3229 // ClientModeManager never stopped 3230 verify(mClientModeManager, never()).stop(); 3231 3232 // Disconnected from network 3233 DisconnectEventInfo disconnectEventInfo = 3234 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 3235 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3236 mLooper.dispatchAll(); 3237 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3238 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 3239 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 3240 mLooper.dispatchAll(); 3241 3242 assertEquals("DisconnectedState", getCurrentState().getName()); 3243 3244 // Since in lingering mode, disconnect => stop ClientModeManager 3245 verify(mClientModeManager).stop(); 3246 } 3247 3248 @Test primaryCmmDisconnected_doesntStopsClientModeManager()3249 public void primaryCmmDisconnected_doesntStopsClientModeManager() throws Exception { 3250 // Owning ClientModeManager is primary 3251 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 3252 3253 connect(); 3254 3255 // ClientModeManager never stopped 3256 verify(mClientModeManager, never()).stop(); 3257 3258 // Disconnected from network 3259 DisconnectEventInfo disconnectEventInfo = 3260 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 3261 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3262 mLooper.dispatchAll(); 3263 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3264 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 3265 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 3266 mLooper.dispatchAll(); 3267 3268 assertEquals("DisconnectedState", getCurrentState().getName()); 3269 3270 // Since primary => don't stop ClientModeManager 3271 verify(mClientModeManager, never()).stop(); 3272 } 3273 3274 /** 3275 * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected 3276 * to true. 3277 * 3278 * Test: Successfully create and connect to a network. Check the config and verify 3279 * WifiConfiguration.getHasEverConnected() is true. 3280 */ 3281 @Test setHasEverConnectedTrueOnConnect()3282 public void setHasEverConnectedTrueOnConnect() throws Exception { 3283 connect(); 3284 verify(mWifiConfigManager, atLeastOnce()).updateNetworkAfterConnect(eq(0), eq(true), 3285 eq(false), 3286 anyInt()); 3287 } 3288 3289 /** 3290 * Fail network connection attempt and verify HasEverConnected remains false. 3291 * 3292 * Test: Successfully create a network but fail when connecting. Check the config and verify 3293 * WifiConfiguration.getHasEverConnected() is false. 3294 */ 3295 @Test connectionFailureDoesNotSetHasEverConnectedTrue()3296 public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception { 3297 testDhcpFailure(); 3298 verify(mWifiConfigManager, never()) 3299 .updateNetworkAfterConnect(eq(0), eq(true), eq(false), anyInt()); 3300 } 3301 3302 @Test iconQueryTest()3303 public void iconQueryTest() throws Exception { 3304 // TODO(b/31065385): Passpoint config management. 3305 } 3306 3307 @Test verboseLogRecSizeIsGreaterThanNormalSize()3308 public void verboseLogRecSizeIsGreaterThanNormalSize() { 3309 assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > mWifiGlobals.getClientModeImplNumLogRecs()); 3310 } 3311 3312 /** 3313 * Verifies that, by default, we allow only the "normal" number of log records. 3314 */ 3315 @Test normalLogRecSizeIsUsedByDefault()3316 public void normalLogRecSizeIsUsedByDefault() { 3317 mCmi.enableVerboseLogging(false); 3318 assertEquals(mWifiGlobals.getClientModeImplNumLogRecs(), mCmi.getLogRecMaxSize()); 3319 } 3320 3321 /** 3322 * Verifies that, in verbose mode, we allow a larger number of log records. 3323 */ 3324 @Test enablingVerboseLoggingUpdatesLogRecSize()3325 public void enablingVerboseLoggingUpdatesLogRecSize() { 3326 when(mActivityManager.isLowRamDevice()).thenReturn(false); 3327 mCmi.enableVerboseLogging(true); 3328 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mCmi.getLogRecMaxSize()); 3329 } 3330 3331 /** 3332 * Verifies that, in verbose mode, we allow a larger number of log records on a low ram device. 3333 */ 3334 @Test enablingVerboseLoggingUpdatesLogRecSizeLowRamDevice()3335 public void enablingVerboseLoggingUpdatesLogRecSizeLowRamDevice() { 3336 when(mActivityManager.isLowRamDevice()).thenReturn(true); 3337 mCmi.enableVerboseLogging(true); 3338 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE_LOW_RAM, mCmi.getLogRecMaxSize()); 3339 } 3340 3341 @Test disablingVerboseLoggingClearsRecords()3342 public void disablingVerboseLoggingClearsRecords() { 3343 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 3344 mLooper.dispatchAll(); 3345 assertTrue(mCmi.getLogRecSize() >= 1); 3346 3347 mCmi.enableVerboseLogging(false); 3348 assertEquals(0, mCmi.getLogRecSize()); 3349 } 3350 3351 @Test disablingVerboseLoggingUpdatesLogRecSize()3352 public void disablingVerboseLoggingUpdatesLogRecSize() { 3353 mCmi.enableVerboseLogging(true); 3354 mCmi.enableVerboseLogging(false); 3355 assertEquals(mWifiGlobals.getClientModeImplNumLogRecs(), mCmi.getLogRecMaxSize()); 3356 } 3357 3358 @Test logRecsIncludeDisconnectCommand()3359 public void logRecsIncludeDisconnectCommand() { 3360 // There's nothing special about the DISCONNECT command. It's just representative of 3361 // "normal" commands. 3362 mCmi.sendMessage(ClientModeImpl.CMD_DISCONNECT); 3363 mLooper.dispatchAll(); 3364 assertEquals(2, mCmi.copyLogRecs() 3365 .stream() 3366 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_DISCONNECT) 3367 .count()); 3368 } 3369 3370 @Test logRecsExcludeRssiPollCommandByDefault()3371 public void logRecsExcludeRssiPollCommandByDefault() { 3372 mCmi.enableVerboseLogging(false); 3373 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 3374 mLooper.dispatchAll(); 3375 assertEquals(0, mCmi.copyLogRecs() 3376 .stream() 3377 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 3378 .count()); 3379 } 3380 3381 @Test logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled()3382 public void logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled() { 3383 mCmi.enableVerboseLogging(true); 3384 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL); 3385 mLooper.dispatchAll(); 3386 assertEquals(1, mCmi.copyLogRecs() 3387 .stream() 3388 .filter(logRec -> logRec.getWhat() == ClientModeImpl.CMD_RSSI_POLL) 3389 .count()); 3390 } 3391 3392 /** 3393 * Verify that syncStartSubscriptionProvisioning will redirect calls with right parameters 3394 * to {@link PasspointManager} with expected true being returned when in client mode. 3395 */ 3396 @Test syncStartSubscriptionProvisioningInClientMode()3397 public void syncStartSubscriptionProvisioningInClientMode() throws Exception { 3398 when(mPasspointManager.startSubscriptionProvisioning(anyInt(), 3399 any(OsuProvider.class), any(IProvisioningCallback.class))).thenReturn(true); 3400 mLooper.startAutoDispatch(); 3401 assertTrue(mCmi.syncStartSubscriptionProvisioning( 3402 OTHER_USER_UID, mOsuProvider, mProvisioningCallback)); 3403 verify(mPasspointManager).startSubscriptionProvisioning(OTHER_USER_UID, mOsuProvider, 3404 mProvisioningCallback); 3405 mLooper.stopAutoDispatch(); 3406 } 3407 3408 @Test testGetCurrentNetwork()3409 public void testGetCurrentNetwork() throws Exception { 3410 // getCurrentNetwork() returns null when disconnected 3411 assertNull(mCmi.getCurrentNetwork()); 3412 connect(); 3413 3414 assertEquals("L3ConnectedState", getCurrentState().getName()); 3415 // getCurrentNetwork() returns non-null Network when connected 3416 assertEquals(mNetwork, mCmi.getCurrentNetwork()); 3417 // Now trigger disconnect 3418 mCmi.disconnect(); 3419 DisconnectEventInfo disconnectEventInfo = 3420 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 3421 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3422 mLooper.dispatchAll(); 3423 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3424 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 3425 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 3426 mLooper.dispatchAll(); 3427 assertEquals("DisconnectedState", getCurrentState().getName()); 3428 assertNull(mCmi.getCurrentNetwork()); 3429 } 3430 3431 /** 3432 * Test that we disconnect from a network if it was removed while we are in the 3433 * L3ProvisioningState. 3434 */ 3435 @Test disconnectFromNetworkWhenRemovedWhileObtainingIpAddr()3436 public void disconnectFromNetworkWhenRemovedWhileObtainingIpAddr() throws Exception { 3437 initializeAndAddNetworkAndVerifySuccess(); 3438 3439 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 3440 3441 startConnectSuccess(); 3442 3443 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3444 .thenReturn(mScanDetailCache); 3445 3446 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 3447 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 3448 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 3449 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 3450 3451 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 3452 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 3453 mLooper.dispatchAll(); 3454 3455 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3456 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 3457 SupplicantState.COMPLETED)); 3458 mLooper.dispatchAll(); 3459 3460 assertEquals("L3ProvisioningState", getCurrentState().getName()); 3461 3462 // trigger removal callback to trigger disconnect. 3463 WifiConfiguration removedConfig = new WifiConfiguration(); 3464 removedConfig.networkId = FRAMEWORK_NETWORK_ID; 3465 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 3466 .getAllValues()) { 3467 listener.onNetworkRemoved(removedConfig); 3468 } 3469 3470 reset(mWifiConfigManager); 3471 3472 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)).thenReturn(null); 3473 3474 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 3475 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 3476 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 3477 dhcpResults.baseConfiguration.ipAddress = 3478 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 3479 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 3480 dhcpResults.leaseDuration = 3600; 3481 3482 injectDhcpSuccess(dhcpResults); 3483 mLooper.dispatchAll(); 3484 3485 verify(mWifiNative, times(2)).disconnect(WIFI_IFACE_NAME); 3486 } 3487 3488 /** 3489 * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. 3490 */ 3491 @Test testWifiInfoUpdatedUponSupplicantStateChangedEvent()3492 public void testWifiInfoUpdatedUponSupplicantStateChangedEvent() throws Exception { 3493 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 3494 connect(); 3495 3496 // Set the scan detail cache for roaming target. 3497 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3498 .thenReturn(mScanDetailCache); 3499 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 3500 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 3501 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 3502 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 3503 3504 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 3505 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. 3506 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3507 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 3508 SupplicantState.COMPLETED)); 3509 mLooper.dispatchAll(); 3510 3511 WifiInfo wifiInfo = mWifiInfo; 3512 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 3513 assertEquals(sFreq1, wifiInfo.getFrequency()); 3514 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 3515 3516 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3517 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 3518 SupplicantState.DISCONNECTED)); 3519 mLooper.dispatchAll(); 3520 3521 wifiInfo = mWifiInfo; 3522 assertNull(wifiInfo.getBSSID()); 3523 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 3524 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, wifiInfo.getNetworkId()); 3525 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 3526 assertEquals("DisconnectedState", getCurrentState().getName()); 3527 } 3528 3529 3530 /** 3531 * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. 3532 */ 3533 @Test testWifiInfoUpdatedUponSupplicantStateChangedEventWithWrongSsid()3534 public void testWifiInfoUpdatedUponSupplicantStateChangedEventWithWrongSsid() throws Exception { 3535 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 3536 connect(); 3537 3538 // Set the scan detail cache for roaming target. 3539 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3540 .thenReturn(mScanDetailCache); 3541 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 3542 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 3543 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 3544 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 3545 3546 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 3547 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. 3548 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3549 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 3550 SupplicantState.COMPLETED)); 3551 mLooper.dispatchAll(); 3552 3553 WifiInfo wifiInfo = mWifiInfo; 3554 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 3555 assertEquals(sFreq1, wifiInfo.getFrequency()); 3556 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 3557 3558 // Send state change event with wrong ssid. 3559 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3560 new StateChangeResult(0, TEST_WIFI_SSID1, TEST_BSSID_STR, sFreq, 3561 SupplicantState.DISCONNECTED)); 3562 mLooper.dispatchAll(); 3563 3564 wifiInfo = mWifiInfo; 3565 assertNull(wifiInfo.getBSSID()); 3566 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 3567 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, wifiInfo.getNetworkId()); 3568 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 3569 assertEquals("DisconnectedState", getCurrentState().getName()); 3570 } 3571 3572 @Test testTriggerWifiNetworkStateChangedListener()3573 public void testTriggerWifiNetworkStateChangedListener() throws Exception { 3574 InOrder inOrder = inOrder(mActiveModeWarden); 3575 connect(); 3576 inOrder.verify(mActiveModeWarden).onNetworkStateChanged( 3577 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 3578 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_CONNECTING); 3579 inOrder.verify(mActiveModeWarden).onNetworkStateChanged( 3580 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 3581 WifiManager.WifiNetworkStateChangedListener 3582 .WIFI_NETWORK_STATUS_OBTAINING_IPADDR); 3583 inOrder.verify(mActiveModeWarden).onNetworkStateChanged( 3584 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 3585 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_CONNECTED); 3586 inOrder.verify(mActiveModeWarden, never()).onNetworkStateChanged( 3587 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 3588 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_DISCONNECTED); 3589 } 3590 3591 /** 3592 * Verifies that WifiInfo is updated upon CMD_ASSOCIATED_BSSID event. 3593 */ 3594 @Test testWifiInfoUpdatedUponAssociatedBSSIDEvent()3595 public void testWifiInfoUpdatedUponAssociatedBSSIDEvent() throws Exception { 3596 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 3597 connect(); 3598 3599 // Set the scan detail cache for roaming target. 3600 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 3601 .thenReturn(mScanDetailCache); 3602 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn( 3603 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1)); 3604 when(mScanDetailCache.getScanResult(TEST_BSSID_STR1)).thenReturn( 3605 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq1).getScanResult()); 3606 3607 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 3608 // Send a CMD_ASSOCIATED_BSSID, verify WifiInfo is updated. 3609 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR1); 3610 mLooper.dispatchAll(); 3611 3612 WifiInfo wifiInfo = mWifiInfo; 3613 assertEquals(TEST_BSSID_STR1, wifiInfo.getBSSID()); 3614 assertEquals(sFreq1, wifiInfo.getFrequency()); 3615 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 3616 verifyNetworkStateChangedBroadcast(times(2), 3617 new NetworkStateChangedIntentMatcher(CONNECTED)); 3618 } 3619 callmethod(VerificationMode mode, ArgumentMatcher<Intent> intentMatcher)3620 private void callmethod(VerificationMode mode, ArgumentMatcher<Intent> intentMatcher) { 3621 if (SdkLevel.isAtLeastU()) { 3622 verify(mUserAllContext, mode).sendStickyBroadcast( 3623 argThat(intentMatcher), any()); 3624 } else { 3625 verify(mContext, mode).sendStickyBroadcastAsUser( 3626 argThat(intentMatcher), any()); 3627 } 3628 } 3629 3630 /** 3631 * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not 3632 * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState. 3633 * This protects ClientModeImpl from getting into a bad state where WifiInfo says wifi is 3634 * already Connected or Connecting, (when it is in-fact Disconnected), so 3635 * WifiConnectivityManager does not attempt any new Connections, freezing wifi. 3636 */ 3637 @Test testWifiInfoCleanedUpEnteringExitingConnectableState()3638 public void testWifiInfoCleanedUpEnteringExitingConnectableState() throws Exception { 3639 InOrder inOrderMetrics = inOrder(mWifiMetrics); 3640 Log.i(TAG, mCmi.getCurrentState().getName()); 3641 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 3642 WifiInfo wifiInfo = mWifiInfo; 3643 wifiInfo.setBSSID(initialBSSID); 3644 3645 // reset mWifiNative since initializeCmi() was called in setup() 3646 resetWifiNative(); 3647 3648 // Set CMI to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager 3649 initializeCmi(); 3650 inOrderMetrics.verify(mWifiMetrics) 3651 .setWifiState(WIFI_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 3652 inOrderMetrics.verify(mWifiMetrics) 3653 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_ENABLED); 3654 assertNull(wifiInfo.getBSSID()); 3655 3656 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated 3657 connect(); 3658 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 3659 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 3660 3661 // Set CMI to DISABLED_MODE, verify state and wifi disabled in ConnectivityManager, and 3662 // WifiInfo is reset() and state set to DISCONNECTED 3663 mCmi.stop(); 3664 mLooper.dispatchAll(); 3665 3666 inOrderMetrics.verify(mWifiMetrics).setWifiState(WIFI_IFACE_NAME, 3667 WifiMetricsProto.WifiLog.WIFI_DISABLED); 3668 inOrderMetrics.verify(mWifiMetrics) 3669 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_DISABLED); 3670 assertNull(wifiInfo.getBSSID()); 3671 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 3672 } 3673 3674 @Test testWifiInfoCleanedUpEnteringExitingConnectableState2()3675 public void testWifiInfoCleanedUpEnteringExitingConnectableState2() throws Exception { 3676 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated 3677 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 3678 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 3679 SupplicantState.COMPLETED)); 3680 mLooper.dispatchAll(); 3681 assertNull(mWifiInfo.getBSSID()); 3682 assertEquals(SupplicantState.DISCONNECTED, mWifiInfo.getSupplicantState()); 3683 } 3684 3685 @Test testWifiInfoCleanedUpEnteringExitingConnectableState3()3686 public void testWifiInfoCleanedUpEnteringExitingConnectableState3() throws Exception { 3687 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 3688 InOrder inOrderMetrics = inOrder(mWifiMetrics); 3689 3690 // Set the bssid to something, so we can verify it is cleared (just in case) 3691 mWifiInfo.setBSSID(initialBSSID); 3692 3693 initializeCmi(); 3694 3695 inOrderMetrics.verify(mWifiMetrics) 3696 .setWifiState(WIFI_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); 3697 inOrderMetrics.verify(mWifiMetrics) 3698 .logStaEvent(WIFI_IFACE_NAME, StaEvent.TYPE_WIFI_ENABLED); 3699 assertEquals("DisconnectedState", getCurrentState().getName()); 3700 assertEquals(SupplicantState.DISCONNECTED, mWifiInfo.getSupplicantState()); 3701 assertNull(mWifiInfo.getBSSID()); 3702 } 3703 3704 /** 3705 * Test that connected SSID and BSSID are exposed to system server. 3706 * Also tests that {@link ClientModeImpl#getConnectionInfo()} always 3707 * returns a copy of WifiInfo. 3708 */ 3709 @Test testConnectedIdsAreVisibleFromSystemServer()3710 public void testConnectedIdsAreVisibleFromSystemServer() throws Exception { 3711 WifiInfo wifiInfo = mWifiInfo; 3712 // Get into a connected state, with known BSSID and SSID 3713 connect(); 3714 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 3715 assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid()); 3716 3717 WifiInfo connectionInfo = mCmi.getConnectionInfo(); 3718 assertEquals(wifiInfo.getSSID(), connectionInfo.getSSID()); 3719 assertEquals(wifiInfo.getBSSID(), connectionInfo.getBSSID()); 3720 assertEquals(wifiInfo.getMacAddress(), connectionInfo.getMacAddress()); 3721 } 3722 3723 /** 3724 * Test that reconnectCommand() triggers connectivity scan when ClientModeImpl 3725 * is in DisconnectedMode. 3726 */ 3727 @Test testReconnectCommandWhenDisconnected()3728 public void testReconnectCommandWhenDisconnected() throws Exception { 3729 // Connect to network with |TEST_BSSID_STR|, |sFreq|, and then disconnect. 3730 disconnect(); 3731 verify(mActiveModeWarden).onNetworkStateChanged( 3732 WifiManager.WifiNetworkStateChangedListener.WIFI_ROLE_CLIENT_PRIMARY, 3733 WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_DISCONNECTED); 3734 3735 mCmi.reconnect(ClientModeImpl.WIFI_WORK_SOURCE); 3736 mLooper.dispatchAll(); 3737 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 3738 } 3739 3740 /** 3741 * Test that reconnectCommand() doesn't trigger connectivity scan when ClientModeImpl 3742 * is in ConnectedMode. 3743 */ 3744 @Test testReconnectCommandWhenConnected()3745 public void testReconnectCommandWhenConnected() throws Exception { 3746 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 3747 connect(); 3748 3749 mCmi.reconnect(ClientModeImpl.WIFI_WORK_SOURCE); 3750 mLooper.dispatchAll(); 3751 verify(mWifiConnectivityManager, never()) 3752 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 3753 } 3754 3755 /** 3756 * Verifies that ClientModeImpl sets and unsets appropriate 'RecentFailureReason' values 3757 * on a WifiConfiguration when it fails association, authentication, or successfully connects 3758 */ 3759 @Test testExtraFailureReason_ApIsBusy()3760 public void testExtraFailureReason_ApIsBusy() throws Exception { 3761 // Setup CONNECT_MODE & a WifiConfiguration 3762 initializeAndAddNetworkAndVerifySuccess(); 3763 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 3764 // targetNetworkId state) 3765 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3766 mLooper.dispatchAll(); 3767 // Simulate an ASSOCIATION_REJECTION_EVENT, due to the AP being busy 3768 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 3769 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 3770 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, 3771 false)); 3772 mLooper.dispatchAll(); 3773 verify(mWifiConfigManager).setRecentFailureAssociationStatus(eq(0), 3774 eq(WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA)); 3775 assertEquals("DisconnectedState", getCurrentState().getName()); 3776 3777 // Simulate an AUTHENTICATION_FAILURE_EVENT, which should clear the ExtraFailureReason 3778 reset(mWifiConfigManager); 3779 initializeAndAddNetworkAndVerifySuccess(); 3780 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 3781 // targetNetworkId state) 3782 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3783 mLooper.dispatchAll(); 3784 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 3785 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 3786 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT, -1)); 3787 DisconnectEventInfo disconnectEventInfo = 3788 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 3789 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 3790 mLooper.dispatchAll(); 3791 verify(mWifiConfigManager).clearRecentFailureReason(eq(0)); 3792 verify(mWifiConfigManager, never()).setRecentFailureAssociationStatus(anyInt(), anyInt()); 3793 3794 // Simulate a NETWORK_CONNECTION_EVENT which should clear the ExtraFailureReason 3795 reset(mWifiConfigManager); 3796 initializeAndAddNetworkAndVerifySuccess(); 3797 // Trigger a connection to this (CMD_START_CONNECT will actually fail, but it sets up 3798 // targetNetworkId state) 3799 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 3800 mLooper.dispatchAll(); 3801 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 3802 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, null, false, null)); 3803 mLooper.dispatchAll(); 3804 verify(mWifiConfigManager).clearRecentFailureReason(eq(0)); 3805 verify(mWifiConfigManager, never()).setRecentFailureAssociationStatus(anyInt(), anyInt()); 3806 } 3807 makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, long timeSinceLastSelected)3808 private WifiConfiguration makeLastSelectedWifiConfiguration(int lastSelectedNetworkId, 3809 long timeSinceLastSelected) { 3810 long lastSelectedTimestamp = 45666743454L; 3811 3812 when(mClock.getElapsedSinceBootMillis()).thenReturn( 3813 lastSelectedTimestamp + timeSinceLastSelected); 3814 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(lastSelectedTimestamp); 3815 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(lastSelectedNetworkId); 3816 3817 WifiConfiguration currentConfig = new WifiConfiguration(); 3818 currentConfig.networkId = lastSelectedNetworkId; 3819 return currentConfig; 3820 } 3821 3822 /** 3823 * Test that the helper method 3824 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 3825 * returns true when we connect to the last selected network before expiration of 3826 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 3827 */ 3828 @Test testIsRecentlySelectedByTheUser_SameNetworkNotExpired()3829 public void testIsRecentlySelectedByTheUser_SameNetworkNotExpired() { 3830 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 3831 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 3832 assertTrue(mCmi.isRecentlySelectedByTheUser(currentConfig)); 3833 } 3834 3835 /** 3836 * Test that the helper method 3837 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 3838 * returns false when we connect to the last selected network after expiration of 3839 * {@link ClientModeImpl#LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS}. 3840 */ 3841 @Test testIsRecentlySelectedByTheUser_SameNetworkExpired()3842 public void testIsRecentlySelectedByTheUser_SameNetworkExpired() { 3843 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 3844 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 3845 assertFalse(mCmi.isRecentlySelectedByTheUser(currentConfig)); 3846 } 3847 3848 /** 3849 * Test that the helper method 3850 * {@link ClientModeImpl#isRecentlySelectedByTheUser(WifiConfiguration)} 3851 * returns false when we connect to a different network to the last selected network. 3852 */ 3853 @Test testIsRecentlySelectedByTheUser_DifferentNetwork()3854 public void testIsRecentlySelectedByTheUser_DifferentNetwork() { 3855 WifiConfiguration currentConfig = makeLastSelectedWifiConfiguration(5, 3856 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 3857 currentConfig.networkId = 4; 3858 assertFalse(mCmi.isRecentlySelectedByTheUser(currentConfig)); 3859 } 3860 expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, Consumer<NetworkCapabilities> networkCapabilitiesChecker)3861 private void expectRegisterNetworkAgent(Consumer<NetworkAgentConfig> configChecker, 3862 Consumer<NetworkCapabilities> networkCapabilitiesChecker) { 3863 // Expects that the code calls registerNetworkAgent and provides a way for the test to 3864 // verify the messages sent through the NetworkAgent to ConnectivityService. 3865 // We cannot just use a mock object here because mWifiNetworkAgent is private to CMI. 3866 ArgumentCaptor<NetworkAgentConfig> configCaptor = 3867 ArgumentCaptor.forClass(NetworkAgentConfig.class); 3868 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 3869 ArgumentCaptor.forClass(NetworkCapabilities.class); 3870 3871 verify(mWifiInjector).makeWifiNetworkAgent( 3872 networkCapabilitiesCaptor.capture(), 3873 any(), 3874 configCaptor.capture(), 3875 any(), 3876 mWifiNetworkAgentCallbackCaptor.capture()); 3877 3878 configChecker.accept(configCaptor.getValue()); 3879 networkCapabilitiesChecker.accept(networkCapabilitiesCaptor.getValue()); 3880 } 3881 expectNetworkAgentUpdateCapabilities( Consumer<NetworkCapabilities> networkCapabilitiesChecker)3882 private void expectNetworkAgentUpdateCapabilities( 3883 Consumer<NetworkCapabilities> networkCapabilitiesChecker) throws Exception { 3884 ArgumentCaptor<NetworkCapabilities> captor = ArgumentCaptor.forClass( 3885 NetworkCapabilities.class); 3886 mLooper.dispatchAll(); 3887 verify(mWifiNetworkAgent).sendNetworkCapabilitiesAndCache(captor.capture()); 3888 networkCapabilitiesChecker.accept(captor.getValue()); 3889 } 3890 3891 /** 3892 * Verify that when a network is explicitly selected, but noInternetAccessExpected is false, 3893 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 3894 * acceptUnvalidated and acceptPartialConnectivity. 3895 */ 3896 @Test testExplicitlySelected_ExplicitInternetExpected()3897 public void testExplicitlySelected_ExplicitInternetExpected() throws Exception { 3898 // Network is explicitly selected. 3899 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 3900 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 3901 mConnectedNetwork.noInternetAccessExpected = false; 3902 3903 connect(); 3904 expectRegisterNetworkAgent((agentConfig) -> { 3905 assertTrue(agentConfig.explicitlySelected); 3906 assertFalse(agentConfig.acceptUnvalidated); 3907 assertFalse(agentConfig.acceptPartialConnectivity); 3908 }, (cap) -> { }); 3909 } 3910 3911 /** 3912 * Verify that when a network is explicitly selected, has role SECONDARY_TRANSIENT, but 3913 * noInternetAccessExpected is false, the {@link NetworkAgentConfig} contains the right values 3914 * of explicitlySelected, acceptUnvalidated and acceptPartialConnectivity. 3915 */ 3916 @Test testExplicitlySelected_secondaryTransient_expectNotExplicitlySelected()3917 public void testExplicitlySelected_secondaryTransient_expectNotExplicitlySelected() 3918 throws Exception { 3919 // Network is explicitly selected. 3920 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 3921 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 3922 mConnectedNetwork.noInternetAccessExpected = false; 3923 3924 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 3925 3926 connect(); 3927 expectRegisterNetworkAgent((agentConfig) -> { 3928 assertFalse(agentConfig.explicitlySelected); 3929 assertFalse(agentConfig.acceptUnvalidated); 3930 assertFalse(agentConfig.acceptPartialConnectivity); 3931 }, (cap) -> { }); 3932 } 3933 3934 /** 3935 * Verify that when a network is not explicitly selected, but noInternetAccessExpected is true, 3936 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 3937 * acceptUnvalidated and acceptPartialConnectivity. 3938 */ 3939 @Test testExplicitlySelected_NotExplicitNoInternetExpected()3940 public void testExplicitlySelected_NotExplicitNoInternetExpected() throws Exception { 3941 // Network is no longer explicitly selected. 3942 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 3943 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS + 1); 3944 mConnectedNetwork.noInternetAccessExpected = true; 3945 3946 connect(); 3947 expectRegisterNetworkAgent((agentConfig) -> { 3948 assertFalse(agentConfig.explicitlySelected); 3949 assertFalse(agentConfig.acceptUnvalidated); 3950 assertTrue(agentConfig.acceptPartialConnectivity); 3951 }, (cap) -> { }); 3952 } 3953 3954 /** 3955 * Verify that when a network is explicitly selected, and noInternetAccessExpected is true, 3956 * the {@link NetworkAgentConfig} contains the right values of explicitlySelected, 3957 * acceptUnvalidated and acceptPartialConnectivity. 3958 */ 3959 @Test testExplicitlySelected_ExplicitNoInternetExpected()3960 public void testExplicitlySelected_ExplicitNoInternetExpected() throws Exception { 3961 // Network is explicitly selected. 3962 WifiConfiguration config = makeLastSelectedWifiConfiguration(FRAMEWORK_NETWORK_ID, 3963 ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS - 1); 3964 mConnectedNetwork.noInternetAccessExpected = true; 3965 3966 connect(); 3967 expectRegisterNetworkAgent((agentConfig) -> { 3968 assertTrue(agentConfig.explicitlySelected); 3969 assertTrue(agentConfig.acceptUnvalidated); 3970 assertTrue(agentConfig.acceptPartialConnectivity); 3971 }, (cap) -> { }); 3972 } 3973 3974 /** 3975 * Verify that Rssi Monitoring is started and the callback registered after connecting. 3976 */ 3977 @Test verifyRssiMonitoringCallbackIsRegistered()3978 public void verifyRssiMonitoringCallbackIsRegistered() throws Exception { 3979 // Simulate the first connection. 3980 connect(); 3981 3982 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 3983 mWifiNetworkAgentCallbackCaptor.capture()); 3984 3985 ArrayList<Integer> thresholdsArray = new ArrayList<>(); 3986 thresholdsArray.add(RSSI_THRESHOLD_MAX); 3987 thresholdsArray.add(RSSI_THRESHOLD_MIN); 3988 mWifiNetworkAgentCallbackCaptor.getValue().onSignalStrengthThresholdsUpdated( 3989 thresholdsArray.stream().mapToInt(Integer::intValue).toArray()); 3990 mLooper.dispatchAll(); 3991 3992 ArgumentCaptor<WifiNative.WifiRssiEventHandler> rssiEventHandlerCaptor = 3993 ArgumentCaptor.forClass(WifiNative.WifiRssiEventHandler.class); 3994 verify(mWifiNative).startRssiMonitoring(anyString(), anyByte(), anyByte(), 3995 rssiEventHandlerCaptor.capture()); 3996 3997 // breach below min 3998 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MIN); 3999 mLooper.dispatchAll(); 4000 WifiInfo wifiInfo = mWifiInfo; 4001 assertEquals(RSSI_THRESHOLD_BREACH_MIN, wifiInfo.getRssi()); 4002 4003 // breach above max 4004 rssiEventHandlerCaptor.getValue().onRssiThresholdBreached(RSSI_THRESHOLD_BREACH_MAX); 4005 mLooper.dispatchAll(); 4006 assertEquals(RSSI_THRESHOLD_BREACH_MAX, wifiInfo.getRssi()); 4007 } 4008 4009 /** 4010 * Verify that RSSI monitoring is not enabled on secondary STA. 4011 */ 4012 @Test testRssiMonitoringOnSecondaryIsNotEnabled()4013 public void testRssiMonitoringOnSecondaryIsNotEnabled() throws Exception { 4014 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 4015 connect(); 4016 4017 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 4018 mWifiNetworkAgentCallbackCaptor.capture()); 4019 4020 int[] thresholds = {RSSI_THRESHOLD_BREACH_MAX}; 4021 mWifiNetworkAgentCallbackCaptor.getValue().onSignalStrengthThresholdsUpdated(thresholds); 4022 mLooper.dispatchAll(); 4023 4024 verify(mWifiNative, never()).startRssiMonitoring(anyString(), anyByte(), anyByte(), 4025 any()); 4026 } 4027 4028 /** 4029 * Verify that RSSI and link layer stats polling works in connected mode 4030 */ 4031 @Test verifyConnectedModeRssiPolling()4032 public void verifyConnectedModeRssiPolling() throws Exception { 4033 final long startMillis = 1_500_000_000_100L; 4034 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4035 llStats.txmpdu_be = 1000; 4036 llStats.rxmpdu_bk = 2000; 4037 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4038 signalPollResults.addEntry(0, -42, 65, 54, sFreq); 4039 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4040 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4041 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4042 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4043 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 4044 mCmi.enableRssiPolling(true); 4045 connect(); 4046 mLooper.dispatchAll(); 4047 assertRssiChangeBroadcastSent(1); 4048 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 4049 mLooper.dispatchAll(); 4050 WifiInfo wifiInfo = mWifiInfo; 4051 assertEquals(llStats.txmpdu_be, wifiInfo.txSuccess); 4052 assertEquals(llStats.rxmpdu_bk, wifiInfo.rxSuccess); 4053 assertEquals(signalPollResults.getRssi(), wifiInfo.getRssi()); 4054 assertEquals(signalPollResults.getTxLinkSpeed(), wifiInfo.getLinkSpeed()); 4055 assertEquals(signalPollResults.getTxLinkSpeed(), wifiInfo.getTxLinkSpeedMbps()); 4056 assertEquals(signalPollResults.getRxLinkSpeed(), wifiInfo.getRxLinkSpeedMbps()); 4057 assertEquals(sFreq, wifiInfo.getFrequency()); 4058 verify(mPerNetwork, atLeastOnce()).getTxLinkBandwidthKbps(); 4059 verify(mPerNetwork, atLeastOnce()).getRxLinkBandwidthKbps(); 4060 verify(mWifiScoreCard).noteSignalPoll(any()); 4061 } 4062 4063 /** 4064 * Verify that RSSI polling will send RSSI broadcasts if the RSSI signal level has changed 4065 */ 4066 @Test verifyConnectedModeRssiPollingWithSameSignalLevel()4067 public void verifyConnectedModeRssiPollingWithSameSignalLevel() throws Exception { 4068 final long startMillis = 1_500_000_000_100L; 4069 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4070 llStats.txmpdu_be = 1000; 4071 llStats.rxmpdu_bk = 2000; 4072 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4073 signalPollResults.addEntry(0, -42, 65, 54, sFreq); 4074 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4075 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4076 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4077 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4078 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 4079 mCmi.enableRssiPolling(true); 4080 connect(); 4081 mLooper.dispatchAll(); 4082 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 4083 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4084 mLooper.dispatchAll(); 4085 // Two broadcasts, one when enabling RSSI polling and the other for RSSI polling after 4086 // IP configuration success resets the current level. 4087 assertRssiChangeBroadcastSent(2); 4088 4089 // Same RSSI should not send another broadcast 4090 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4091 mLooper.dispatchAll(); 4092 assertRssiChangeBroadcastSent(2); 4093 4094 // Same signal level should not send another broadcast 4095 signalPollResults.addEntry(0, -43, 65, 54, sFreq); 4096 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4097 mLooper.dispatchAll(); 4098 assertRssiChangeBroadcastSent(2); 4099 4100 // Different signal level should send another broadcast 4101 signalPollResults.addEntry(0, -70, 65, 54, sFreq); 4102 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4103 mLooper.dispatchAll(); 4104 assertRssiChangeBroadcastSent(3); 4105 4106 // Setup for invalid RSSI poll, should not send broadcast 4107 signalPollResults.addEntry(0, -999, 65, 54, sFreq); 4108 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4109 mLooper.dispatchAll(); 4110 assertRssiChangeBroadcastSent(3); 4111 } 4112 4113 /** 4114 * Verify that RSSI polling with verbose logging enabled by the user will send RSSI broadcasts 4115 * if the RSSI has changed at all. 4116 */ 4117 @Test verifyConnectedModeRssiPollingWithSameSignalLevelVerboseLoggingEnabled()4118 public void verifyConnectedModeRssiPollingWithSameSignalLevelVerboseLoggingEnabled() 4119 throws Exception { 4120 when(mWifiGlobals.getVerboseLoggingLevel()) 4121 .thenReturn(WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED); 4122 final long startMillis = 1_500_000_000_100L; 4123 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4124 llStats.txmpdu_be = 1000; 4125 llStats.rxmpdu_bk = 2000; 4126 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4127 signalPollResults.addEntry(0, -42, 65, 54, sFreq); 4128 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4129 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4130 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4131 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4132 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 4133 mCmi.enableRssiPolling(true); 4134 connect(); 4135 mLooper.dispatchAll(); 4136 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 4137 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4138 mLooper.dispatchAll(); 4139 // Two broadcasts, one when enabling RSSI polling and the other for RSSI polling after 4140 // IP configuration success resets the current level. 4141 assertRssiChangeBroadcastSent(2); 4142 4143 // Same RSSI should not send another broadcast 4144 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4145 mLooper.dispatchAll(); 4146 assertRssiChangeBroadcastSent(2); 4147 4148 // Different RSSI but same signal level should send another broadcast since we're verbose. 4149 signalPollResults.addEntry(0, -43, 65, 54, sFreq); 4150 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 4151 mLooper.dispatchAll(); 4152 assertRssiChangeBroadcastSent(3); 4153 } 4154 4155 /** 4156 * Verify that RSSI polling starts/ stops/ one-offs are properly recorded in the capture buffer. 4157 */ 4158 @Test testCaptureBufferRssiOnOff()4159 public void testCaptureBufferRssiOnOff() throws Exception { 4160 // Log should indicate RSSI polling turned on. 4161 mCmi.enableRssiPolling(true); 4162 connect(); 4163 verify(mWifiMetrics).logAsynchronousEvent( 4164 eq(WIFI_IFACE_NAME), 4165 eq(WifiUsabilityStatsEntry.CAPTURE_EVENT_TYPE_RSSI_POLLING_ENABLED)); 4166 reset(mWifiMetrics); 4167 4168 // Normal RSSI polling loop. No events should be logged. 4169 mLooper.moveTimeForward(3000); 4170 mLooper.dispatchAll(); 4171 verify(mWifiMetrics, never()).logAsynchronousEvent(anyString(), anyInt()); 4172 verify(mWifiMetrics, never()).logAsynchronousEvent(anyString(), anyInt(), anyInt()); 4173 reset(mWifiMetrics); 4174 4175 // Normal RSSI polling loop. No events should be logged here either. 4176 mLooper.moveTimeForward(3000); 4177 mLooper.dispatchAll(); 4178 verify(mWifiMetrics, never()).logAsynchronousEvent(anyString(), anyInt()); 4179 verify(mWifiMetrics, never()).logAsynchronousEvent(anyString(), anyInt(), anyInt()); 4180 reset(mWifiMetrics); 4181 4182 // Turn off RSSI polling. This should show up in the capture buffer. 4183 mCmi.enableRssiPolling(false); 4184 mLooper.moveTimeForward(3000); 4185 mLooper.dispatchAll(); 4186 verify(mWifiMetrics).logAsynchronousEvent( 4187 eq(WIFI_IFACE_NAME), 4188 eq(WifiUsabilityStatsEntry.CAPTURE_EVENT_TYPE_RSSI_POLLING_DISABLED)); 4189 reset(mWifiMetrics); 4190 } 4191 4192 /** 4193 * Verify that IP reachability problems are recorded in the capture buffer. 4194 */ 4195 @Test testCaptureBufferReachabilityLost()4196 public void testCaptureBufferReachabilityLost() throws Exception { 4197 // Log should indicate RSSI polling turned on. 4198 connect(); 4199 verify(mWifiMetrics).logAsynchronousEvent( 4200 eq(WIFI_IFACE_NAME), 4201 eq(WifiUsabilityStatsEntry.CAPTURE_EVENT_TYPE_RSSI_POLLING_ENABLED)); 4202 reset(mWifiMetrics); 4203 4204 // Simulate an IP_REACHABILITY_LOST event. 4205 mIpClientCallback.onReachabilityLost("CMD_IP_REACHABILITY_LOST"); 4206 mLooper.dispatchAll(); 4207 verify(mWifiMetrics).logAsynchronousEvent( 4208 eq(WIFI_IFACE_NAME), 4209 eq(WifiUsabilityStatsEntry.CAPTURE_EVENT_TYPE_IP_REACHABILITY_LOST), 4210 eq(-1)); 4211 reset(mWifiMetrics); 4212 4213 // Simulate an IP_REACHABILITY_FAILURE event. 4214 ReachabilityLossInfoParcelable lossInfo = 4215 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.CONFIRM); 4216 mIpClientCallback.onReachabilityFailure(lossInfo); 4217 mLooper.dispatchAll(); 4218 verify(mWifiMetrics).logAsynchronousEvent( 4219 eq(WIFI_IFACE_NAME), 4220 eq(WifiUsabilityStatsEntry.CAPTURE_EVENT_TYPE_IP_REACHABILITY_FAILURE), 4221 eq(ReachabilityLossReason.CONFIRM)); 4222 reset(mWifiMetrics); 4223 } 4224 4225 /** 4226 * Verify link bandwidth update in connected mode 4227 */ 4228 @Test verifyConnectedModeNetworkCapabilitiesBandwidthUpdate()4229 public void verifyConnectedModeNetworkCapabilitiesBandwidthUpdate() throws Exception { 4230 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(40_000); 4231 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(50_000); 4232 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 4233 .thenReturn(Collections.emptySet()); 4234 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 4235 .thenReturn(Pair.create(Process.INVALID_UID, "")); 4236 mCmi.enableRssiPolling(true); 4237 // Simulate the first connection. 4238 connectWithValidInitRssi(-42); 4239 4240 // NetworkCapabilities should be always updated after the connection 4241 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 4242 ArgumentCaptor.forClass(NetworkCapabilities.class); 4243 verify(mWifiInjector).makeWifiNetworkAgent( 4244 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 4245 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 4246 assertNotNull(networkCapabilities); 4247 assertEquals(-42, mWifiInfo.getRssi()); 4248 assertEquals(40_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 4249 assertEquals(50_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 4250 verify(mCmi.mNetworkAgent, times(2)) 4251 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 4252 4253 // Enable RSSI polling 4254 final long startMillis = 1_500_000_000_100L; 4255 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4256 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4257 signalPollResults.addEntry(0, -42, 65, 54, sFreq); 4258 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4259 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4260 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4261 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4262 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 4263 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(82_000); 4264 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(92_000); 4265 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4266 mLooper.dispatchAll(); 4267 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 4268 mLooper.dispatchAll(); 4269 4270 // NetworkCapabilities should be updated after a big change of bandwidth 4271 verify(mCmi.mNetworkAgent, times(3)) 4272 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 4273 networkCapabilities = networkCapabilitiesCaptor.getValue(); 4274 assertEquals(82_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 4275 assertEquals(92_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 4276 4277 // NetworkCapabilities should be updated when the connected channel frequency is changed 4278 // For example due to AP channel switch announcement(CSA). 4279 WifiSignalPollResults signalPollResults1 = new WifiSignalPollResults(); 4280 signalPollResults1.addEntry(0, -42, 65, 54, sFreq1); 4281 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults1); 4282 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 4283 mLooper.dispatchAll(); 4284 4285 verify(mCmi.mNetworkAgent, times(4)) 4286 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 4287 assertEquals(sFreq1, mWifiInfo.getFrequency()); 4288 4289 // No update after a small change of bandwidth 4290 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(72_000); 4291 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(82_000); 4292 when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); 4293 mLooper.dispatchAll(); 4294 verify(mCmi.mNetworkAgent, times(4)) 4295 .sendNetworkCapabilitiesAndCache(networkCapabilitiesCaptor.capture()); 4296 networkCapabilities = networkCapabilitiesCaptor.getValue(); 4297 assertEquals(82_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 4298 assertEquals(92_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 4299 } 4300 4301 /** 4302 * Verify RSSI polling with verbose logging 4303 */ 4304 @Test verifyConnectedModeRssiPollingWithVerboseLogging()4305 public void verifyConnectedModeRssiPollingWithVerboseLogging() throws Exception { 4306 mCmi.enableVerboseLogging(true); 4307 verifyConnectedModeRssiPolling(); 4308 } 4309 4310 /** 4311 * Verify that calls to start and stop filtering multicast packets are passed on to the IpClient 4312 * instance. 4313 */ 4314 @Test verifyMcastLockManagerFilterControllerCallsUpdateIpClient()4315 public void verifyMcastLockManagerFilterControllerCallsUpdateIpClient() throws Exception { 4316 reset(mIpClient); 4317 WifiMulticastLockManager.FilterController filterController = 4318 mCmi.getMcastLockManagerFilterController(); 4319 filterController.startFilteringMulticastPackets(); 4320 verify(mIpClient).setMulticastFilter(eq(true)); 4321 filterController.stopFilteringMulticastPackets(); 4322 verify(mIpClient).setMulticastFilter(eq(false)); 4323 } 4324 4325 /** 4326 * Verifies that when 4327 * 1. Global feature support flag is set to false 4328 * 2. connected MAC randomization is on and 4329 * 3. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 4330 * 4. randomized MAC for the network to connect to is different from the current MAC. 4331 * 4332 * The factory MAC address is used for the connection, and no attempt is made to change it. 4333 */ 4334 @Test testConnectedMacRandomizationNotSupported()4335 public void testConnectedMacRandomizationNotSupported() throws Exception { 4336 // reset mWifiNative since initializeCmi() was called in setup() 4337 resetWifiNative(); 4338 4339 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 4340 initializeCmi(); 4341 initializeAndAddNetworkAndVerifySuccess(); 4342 4343 connect(); 4344 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4345 verify(mWifiNative, never()).setStaMacAddress(any(), any()); 4346 // try to retrieve factory MAC address (once at bootup, once for this connection) 4347 verify(mSettingsConfigStore, times(2)).get(any()); 4348 } 4349 4350 /** 4351 * Verifies that when 4352 * 1. connected MAC randomization is on and 4353 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 4354 * 3. current MAC set to the driver is a randomized MAC address. 4355 * 4. SSID of network to connect is in the MAC randomization forced disable list. 4356 * 4357 * Then the current MAC will be set to the factory MAC when CMD_START_CONNECT executes. 4358 */ 4359 @Test testConnectedMacRandomizationRandomizationForceDisabled()4360 public void testConnectedMacRandomizationRandomizationForceDisabled() throws Exception { 4361 initializeAndAddNetworkAndVerifySuccess(); 4362 4363 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4364 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4365 mResources.setStringArray(R.array.config_wifiForceDisableMacRandomizationSsidList, 4366 new String[]{mConnectedNetwork.SSID}); 4367 4368 connect(); 4369 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); 4370 verify(mWifiMetrics).logStaEvent( 4371 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4372 verify(mWifiConfigManager).addOrUpdateNetwork(any(), eq(Process.SYSTEM_UID)); 4373 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4374 } 4375 4376 @Test testConnectedMacRandomizationForceDisabledSsidPrefix()4377 public void testConnectedMacRandomizationForceDisabledSsidPrefix() throws Exception { 4378 initializeAndAddNetworkAndVerifySuccess(); 4379 4380 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4381 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4382 4383 Set<String> ssidPrefixSet = new ArraySet<>(); 4384 // Take the prefix of 2 characters, which should include the " and the first letter of 4385 // actual SSID 4386 ssidPrefixSet.add(mConnectedNetwork.SSID.substring(0, 2)); 4387 when(mWifiGlobals.getMacRandomizationUnsupportedSsidPrefixes()).thenReturn(ssidPrefixSet); 4388 4389 // Verify MAC randomization is disabled 4390 connect(); 4391 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); 4392 verify(mWifiMetrics).logStaEvent( 4393 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4394 verify(mWifiConfigManager).addOrUpdateNetwork(any(), eq(Process.SYSTEM_UID)); 4395 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4396 } 4397 4398 /** 4399 * Verifies that when 4400 * 1. connected MAC randomization is on and 4401 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 4402 * 3. randomized MAC for the network to connect to is different from the current MAC. 4403 * 4404 * Then the current MAC gets set to the randomized MAC when CMD_START_CONNECT executes. 4405 */ 4406 @Test testConnectedMacRandomizationRandomizationPersistentDifferentMac()4407 public void testConnectedMacRandomizationRandomizationPersistentDifferentMac() 4408 throws Exception { 4409 initializeAndAddNetworkAndVerifySuccess(); 4410 4411 connect(); 4412 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 4413 verify(mWifiMetrics).logStaEvent( 4414 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4415 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4416 } 4417 4418 /** 4419 * Verifies that when 4420 * 1. connected MAC randomization is on and 4421 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_AUTO and 4422 * 3. randomized MAC for the network to connect to is same as the current MAC. 4423 * 4424 * Then MAC change should not occur when CMD_START_CONNECT executes. 4425 */ 4426 @Test testConnectedMacRandomizationRandomizationPersistentSameMac()4427 public void testConnectedMacRandomizationRandomizationPersistentSameMac() throws Exception { 4428 initializeAndAddNetworkAndVerifySuccess(); 4429 4430 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4431 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4432 4433 connect(); 4434 verify(mWifiNative, never()).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 4435 verify(mWifiMetrics, never()).logStaEvent( 4436 any(), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4437 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4438 } 4439 4440 /** Verifies connecting to secondary DBS network with Mac randomization, the MAC address is 4441 * the expected secondary Mac address. 4442 * @throws Exception 4443 */ 4444 @Test testConnectedMacRandomizationRandomizationSecondaryDbs()4445 public void testConnectedMacRandomizationRandomizationSecondaryDbs() 4446 throws Exception { 4447 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 4448 when(mClientModeManager.isSecondaryInternet()).thenReturn(true); 4449 when(mClientModeManager.isSecondaryInternetDbsAp()).thenReturn(true); 4450 initializeAndAddNetworkAndVerifySuccess(); 4451 connect(); 4452 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS_SECONDARY_DBS); 4453 verify(mWifiMetrics).logStaEvent( 4454 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4455 assertEquals(TEST_LOCAL_MAC_ADDRESS_SECONDARY_DBS.toString(), mWifiInfo.getMacAddress()); 4456 } 4457 4458 /** 4459 * Verifies that when 4460 * 1. connected MAC randomization is on and 4461 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 4462 * 3. current MAC address is not the factory MAC. 4463 * 4464 * Then the current MAC gets set to the factory MAC when CMD_START_CONNECT executes. 4465 * @throws Exception 4466 */ 4467 @Test testConnectedMacRandomizationRandomizationNoneDifferentMac()4468 public void testConnectedMacRandomizationRandomizationNoneDifferentMac() throws Exception { 4469 initializeAndAddNetworkAndVerifySuccess(); 4470 4471 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4472 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4473 4474 WifiConfiguration config = new WifiConfiguration(); 4475 config.SSID = TEST_SSID; 4476 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 4477 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 4478 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4479 4480 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4481 mLooper.dispatchAll(); 4482 4483 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); 4484 verify(mWifiMetrics).logStaEvent( 4485 eq(WIFI_IFACE_NAME), eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); 4486 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4487 } 4488 4489 /** 4490 * Verifies that when 4491 * 1. connected MAC randomization is on and 4492 * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and 4493 * 4494 * Then the factory MAC should be used to connect to the network. 4495 * @throws Exception 4496 */ 4497 @Test testConnectedMacRandomizationRandomizationNoneSameMac()4498 public void testConnectedMacRandomizationRandomizationNoneSameMac() throws Exception { 4499 initializeAndAddNetworkAndVerifySuccess(); 4500 4501 clearInvocations(mWifiNative, mSettingsConfigStore); 4502 4503 WifiConfiguration config = new WifiConfiguration(); 4504 config.SSID = TEST_SSID; 4505 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 4506 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 4507 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4508 4509 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4510 mLooper.dispatchAll(); 4511 4512 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 4513 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); 4514 verify(mSettingsConfigStore, never()).put( 4515 WIFI_STA_FACTORY_MAC_ADDRESS, TEST_GLOBAL_MAC_ADDRESS.toString()); 4516 4517 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4518 4519 // Now disconnect & reconnect - should use the cached factory MAC address. 4520 mCmi.disconnect(); 4521 mLooper.dispatchAll(); 4522 4523 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4524 mLooper.dispatchAll(); 4525 4526 verify(mSettingsConfigStore, times(2)).get(WIFI_STA_FACTORY_MAC_ADDRESS); 4527 // No new call to retrieve & store factory MAC address. 4528 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); 4529 verify(mSettingsConfigStore, never()).put( 4530 WIFI_STA_FACTORY_MAC_ADDRESS, TEST_GLOBAL_MAC_ADDRESS.toString()); 4531 } 4532 4533 /** 4534 * Verifies that WifiInfo returns DEFAULT_MAC_ADDRESS as mac address when Connected MAC 4535 * Randomization is on and the device is not connected to a wifi network. 4536 */ 4537 @Test testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization()4538 public void testWifiInfoReturnDefaultMacWhenDisconnectedWithRandomization() throws Exception { 4539 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 4540 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 4541 4542 connect(); 4543 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 4544 4545 DisconnectEventInfo disconnectEventInfo = 4546 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 4547 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4548 mLooper.dispatchAll(); 4549 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 4550 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 4551 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 4552 mLooper.dispatchAll(); 4553 4554 assertEquals("DisconnectedState", getCurrentState().getName()); 4555 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mWifiInfo.getMacAddress()); 4556 assertFalse(mWifiInfo.hasRealMacAddress()); 4557 } 4558 4559 /** 4560 * Verifies that we don't set MAC address when config returns an invalid MAC address. 4561 */ 4562 @Test testDoNotSetMacWhenInvalid()4563 public void testDoNotSetMacWhenInvalid() throws Exception { 4564 initializeAndAddNetworkAndVerifySuccess(); 4565 4566 WifiConfiguration config = new WifiConfiguration(); 4567 config.SSID = TEST_SSID; 4568 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 4569 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 4570 config.setRandomizedMacAddress(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS)); 4571 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config); 4572 4573 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4574 mLooper.dispatchAll(); 4575 4576 // setStaMacAddress is invoked once when ClientModeImpl starts to prevent leak of factory 4577 // MAC. 4578 verify(mWifiNative).setStaMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class)); 4579 } 4580 4581 /** 4582 * Verify that we don't crash when WifiNative returns null as the current MAC address. 4583 * @throws Exception 4584 */ 4585 @Test testMacRandomizationWifiNativeReturningNull()4586 public void testMacRandomizationWifiNativeReturningNull() throws Exception { 4587 when(mWifiNative.getMacAddress(anyString())).thenReturn(null); 4588 initializeAndAddNetworkAndVerifySuccess(); 4589 4590 connect(); 4591 verify(mWifiNative).setStaMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); 4592 } 4593 4594 /** 4595 * Verifies that a notification is posted when a connection failure happens on a network 4596 * in the hotlist. Then verify that tapping on the notification launches an dialog, which 4597 * could be used to set the randomization setting for a network to "Trusted". 4598 */ 4599 @Test testConnectionFailureSendRandomizationSettingsNotification()4600 public void testConnectionFailureSendRandomizationSettingsNotification() throws Exception { 4601 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 4602 // Setup CONNECT_MODE & a WifiConfiguration 4603 initializeAndAddNetworkAndVerifySuccess(); 4604 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 4605 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 4606 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 4607 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT, -1)); 4608 mLooper.dispatchAll(); 4609 4610 WifiConfiguration config = mCmi.getConnectedWifiConfiguration(); 4611 verify(mConnectionFailureNotifier) 4612 .showFailedToConnectDueToNoRandomizedMacSupportNotification(FRAMEWORK_NETWORK_ID); 4613 } 4614 4615 /** 4616 * Verifies that a notification is not posted when a wrong password failure happens on a 4617 * network in the hotlist. 4618 */ 4619 @Test testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword()4620 public void testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword() throws Exception { 4621 when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true); 4622 // Setup CONNECT_MODE & a WifiConfiguration 4623 initializeAndAddNetworkAndVerifySuccess(); 4624 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 4625 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 4626 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 4627 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 4628 mLooper.dispatchAll(); 4629 4630 verify(mConnectionFailureNotifier, never()) 4631 .showFailedToConnectDueToNoRandomizedMacSupportNotification(anyInt()); 4632 } 4633 4634 /** 4635 * Verifies that CMD_START_CONNECT make WifiDiagnostics report 4636 * CONNECTION_EVENT_STARTED 4637 * @throws Exception 4638 */ 4639 @Test testReportConnectionEventIsCalledAfterCmdStartConnect()4640 public void testReportConnectionEventIsCalledAfterCmdStartConnect() throws Exception { 4641 // Setup CONNECT_MODE & a WifiConfiguration 4642 initializeAndAddNetworkAndVerifySuccess(); 4643 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4644 verify(mWifiDiagnostics, never()).reportConnectionEvent( 4645 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED), any()); 4646 mLooper.dispatchAll(); 4647 verify(mWifiDiagnostics).reportConnectionEvent( 4648 eq(WifiDiagnostics.CONNECTION_EVENT_STARTED), any()); 4649 } 4650 4651 @Test testApNoResponseTriggerTimeout()4652 public void testApNoResponseTriggerTimeout() throws Exception { 4653 initializeAndAddNetworkAndVerifySuccess(); 4654 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4655 mLooper.dispatchAll(); 4656 verify(mWifiBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(), 4657 anyInt(), anyInt()); 4658 4659 mLooper.moveTimeForward(ClientModeImpl.CONNECTING_WATCHDOG_TIMEOUT_MS); 4660 mLooper.dispatchAll(); 4661 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(any(), any(), 4662 eq(WifiBlocklistMonitor.REASON_FAILURE_NO_RESPONSE), anyInt()); 4663 verify(mWifiDiagnostics).reportConnectionEvent( 4664 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 4665 } 4666 4667 @Test testApNoResponseTimerCanceledAfterConnectionSuccess()4668 public void testApNoResponseTimerCanceledAfterConnectionSuccess() throws Exception { 4669 connect(); 4670 mLooper.moveTimeForward(ClientModeImpl.CONNECTING_WATCHDOG_TIMEOUT_MS); 4671 mLooper.dispatchAll(); 4672 verify(mWifiBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(), 4673 anyInt(), anyInt()); 4674 verify(mWifiDiagnostics, never()).reportConnectionEvent( 4675 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 4676 } 4677 verifyConnectionEventTimeoutDoesNotOccur()4678 private void verifyConnectionEventTimeoutDoesNotOccur() { 4679 mLooper.moveTimeForward(ClientModeImpl.CONNECTING_WATCHDOG_TIMEOUT_MS); 4680 mLooper.dispatchAll(); 4681 verify(mWifiDiagnostics, never()).reportConnectionEvent( 4682 eq(WifiDiagnostics.CONNECTION_EVENT_TIMEOUT), any()); 4683 } 4684 4685 /** 4686 * Verifies that association failures make WifiDiagnostics report CONNECTION_EVENT_FAILED 4687 * and then cancel any pending timeouts. 4688 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 4689 * @throws Exception 4690 */ 4691 @Test testReportConnectionEventIsCalledAfterAssociationFailure()4692 public void testReportConnectionEventIsCalledAfterAssociationFailure() throws Exception { 4693 mConnectedNetwork.getNetworkSelectionStatus() 4694 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 4695 .getScanResult()); 4696 // Setup CONNECT_MODE & a WifiConfiguration 4697 initializeAndAddNetworkAndVerifySuccess(); 4698 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4699 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 4700 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 4701 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 4702 verify(mWifiDiagnostics, never()).reportConnectionEvent( 4703 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 4704 mLooper.dispatchAll(); 4705 verify(mWifiDiagnostics).reportConnectionEvent( 4706 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 4707 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 4708 mClientModeManager, 4709 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION, 4710 WifiMetricsProto.ConnectionEvent.ASSOCIATION_REJECTION_AP_UNABLE_TO_HANDLE_NEW_STA, 4711 TEST_BSSID_STR, 4712 mTestConfig); 4713 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 4714 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 4715 eq(mTestConfig), eq(TEST_BSSID_STR), eq(WifiMetricsProto.ConnectionEvent 4716 .ASSOCIATION_REJECTION_AP_UNABLE_TO_HANDLE_NEW_STA)); 4717 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 4718 eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION), 4719 eq(mTestConfig), eq(null)); 4720 verify(mWifiMetrics, never()) 4721 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 4722 verifyConnectionEventTimeoutDoesNotOccur(); 4723 4724 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 4725 mWifiNetworkSuggestionsManager); 4726 4727 // Now trigger a disconnect event from supplicant, this should be ignored since the 4728 // connection tracking should have already ended. 4729 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 4730 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 4731 mLooper.dispatchAll(); 4732 4733 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 4734 mWifiNetworkSuggestionsManager); 4735 } 4736 4737 /** 4738 * Verifies that authentication failures make WifiDiagnostics report 4739 * CONNECTION_EVENT_FAILED and then cancel any pending timeouts. 4740 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 4741 * @throws Exception 4742 */ 4743 @Test testReportConnectionEventIsCalledAfterAuthenticationFailure()4744 public void testReportConnectionEventIsCalledAfterAuthenticationFailure() throws Exception { 4745 mConnectedNetwork.getNetworkSelectionStatus() 4746 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 4747 .getScanResult()); 4748 // Setup CONNECT_MODE & a WifiConfiguration 4749 initializeAndAddNetworkAndVerifySuccess(); 4750 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4751 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 4752 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 4753 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 4754 mLooper.dispatchAll(); 4755 verify(mWifiDiagnostics).reportConnectionEvent( 4756 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 4757 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 4758 mClientModeManager, 4759 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, 4760 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, TEST_BSSID_STR, 4761 mTestConfig); 4762 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 4763 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 4764 eq(mTestConfig), eq(TEST_BSSID_STR), eq(WifiMetricsProto.ConnectionEvent 4765 .AUTH_FAILURE_WRONG_PSWD)); 4766 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 4767 eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 4768 eq(mTestConfig), eq(null)); 4769 verify(mWifiMetrics, never()) 4770 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 4771 verifyConnectionEventTimeoutDoesNotOccur(); 4772 4773 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 4774 mWifiNetworkSuggestionsManager); 4775 4776 // Now trigger a disconnect event from supplicant, this should be ignored since the 4777 // connection tracking should have already ended. 4778 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 4779 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 4780 mLooper.dispatchAll(); 4781 4782 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 4783 mWifiNetworkSuggestionsManager); 4784 } 4785 4786 /** 4787 * Verify that if a NETWORK_DISCONNECTION_EVENT is received in L3ConnectedState, then an 4788 * abnormal disconnect is reported to WifiBlocklistMonitor. 4789 */ 4790 @Test testAbnormalDisconnectNotifiesWifiBlocklistMonitor()4791 public void testAbnormalDisconnectNotifiesWifiBlocklistMonitor() throws Exception { 4792 // trigger RSSI poll to update WifiInfo 4793 mCmi.enableRssiPolling(true); 4794 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4795 llStats.txmpdu_be = 1000; 4796 llStats.rxmpdu_bk = 2000; 4797 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4798 signalPollResults.addEntry(0, TEST_RSSI, 65, 54, sFreq); 4799 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4800 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4801 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4802 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4803 4804 connect(); 4805 mLooper.dispatchAll(); 4806 DisconnectEventInfo disconnectEventInfo = 4807 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 4808 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4809 mLooper.dispatchAll(); 4810 4811 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 4812 eq(mConnectedNetwork), eq(WifiBlocklistMonitor.REASON_ABNORMAL_DISCONNECT), 4813 anyInt()); 4814 } 4815 4816 @Test testAbnormalDisconnectIpReachabilityLostNotifiesWifiBlocklistMonitor()4817 public void testAbnormalDisconnectIpReachabilityLostNotifiesWifiBlocklistMonitor() 4818 throws Exception { 4819 // trigger RSSI poll to update WifiInfo 4820 mCmi.enableRssiPolling(true); 4821 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 4822 llStats.txmpdu_be = 1000; 4823 llStats.rxmpdu_bk = 2000; 4824 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 4825 signalPollResults.addEntry(0, TEST_RSSI, 65, 54, sFreq); 4826 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 4827 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 4828 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 4829 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 4830 4831 // Connect, trigger CMD_IP_REACHABILITY_LOST and verifiy REASON_ABNORMAL_DISCONNECT is 4832 // sent to mWifiBlocklistMonitor 4833 connect(); 4834 mLooper.dispatchAll(); 4835 DisconnectEventInfo disconnectEventInfo = 4836 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 4837 mIpClientCallback.onReachabilityLost("CMD_IP_REACHABILITY_LOST"); 4838 mLooper.dispatchAll(); 4839 4840 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 4841 eq(mConnectedNetwork), eq(WifiBlocklistMonitor.REASON_ABNORMAL_DISCONNECT), 4842 anyInt()); 4843 } 4844 4845 /** 4846 * Verify that ClientModeImpl notifies WifiBlocklistMonitor correctly when the RSSI is 4847 * too low. 4848 */ 4849 @Test testNotifiesWifiBlocklistMonitorLowRssi()4850 public void testNotifiesWifiBlocklistMonitorLowRssi() throws Exception { 4851 int testLowRssi = -80; 4852 initializeAndAddNetworkAndVerifySuccess(); 4853 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, 4854 ClientModeImpl.SUPPLICANT_BSSID_ANY); 4855 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 4856 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, true)); 4857 when(mWifiConfigManager.findScanRssi(eq(FRAMEWORK_NETWORK_ID), anyInt())) 4858 .thenReturn(testLowRssi); 4859 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 4860 .thenReturn(mScanDetailCache); 4861 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 4862 getGoogleGuestScanDetail(testLowRssi, TEST_BSSID_STR, sFreq)); 4863 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 4864 getGoogleGuestScanDetail(testLowRssi, TEST_BSSID_STR, sFreq).getScanResult()); 4865 mLooper.dispatchAll(); 4866 4867 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(TEST_BSSID_STR, mTestConfig, 4868 WifiBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, testLowRssi); 4869 } 4870 4871 /** 4872 * Verify that the recent failure association status is updated properly when 4873 * ASSOC_REJECTED_TEMPORARILY occurs. 4874 */ 4875 @Test testAssocRejectedTemporarilyUpdatesRecentAssociationFailureStatus()4876 public void testAssocRejectedTemporarilyUpdatesRecentAssociationFailureStatus() 4877 throws Exception { 4878 initializeAndAddNetworkAndVerifySuccess(); 4879 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4880 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 4881 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 4882 ISupplicantStaIfaceCallback.StatusCode.ASSOC_REJECTED_TEMPORARILY, 4883 false)); 4884 mLooper.dispatchAll(); 4885 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 4886 eq(WifiConfiguration.RECENT_FAILURE_REFUSED_TEMPORARILY)); 4887 } 4888 4889 /** 4890 * Verify that WifiScoreCard and WifiBlocklistMonitor are notified properly when 4891 * disconnection occurs in middle of connection states. 4892 */ 4893 @Test testDisconnectConnecting()4894 public void testDisconnectConnecting() throws Exception { 4895 initializeAndAddNetworkAndVerifySuccess(); 4896 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 4897 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 4898 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 4899 ISupplicantStaIfaceCallback.ReasonCode.FOURWAY_HANDSHAKE_TIMEOUT, 4900 false)); 4901 mLooper.dispatchAll(); 4902 verify(mWifiScoreCard).noteConnectionFailure(any(), anyInt(), anyString(), anyInt()); 4903 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 4904 // Verify that the WifiBlocklistMonitor is notified of a non-locally generated disconnect 4905 // that occurred mid connection attempt. 4906 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(anyString(), eq(mTestConfig), 4907 eq(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING), anyInt()); 4908 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(), 4909 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES)); 4910 } 4911 triggerConnectionWithConsecutiveFailure()4912 private void triggerConnectionWithConsecutiveFailure() throws Exception { 4913 when(mPerNetworkRecentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE)) 4914 .thenReturn(WifiBlocklistMonitor.NUM_CONSECUTIVE_FAILURES_PER_NETWORK_EXP_BACKOFF); 4915 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, TEST_BSSID_STR); 4916 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 4917 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 4918 ISupplicantStaIfaceCallback.ReasonCode.FOURWAY_HANDSHAKE_TIMEOUT, 4919 false)); 4920 mLooper.dispatchAll(); 4921 } 4922 4923 /** 4924 * Verify that the WifiConfigManager is notified when a network experiences consecutive 4925 * connection failures. 4926 */ 4927 @Test testDisableNetworkConsecutiveFailures()4928 public void testDisableNetworkConsecutiveFailures() throws Exception { 4929 initializeAndAddNetworkAndVerifySuccess(); 4930 triggerConnectionWithConsecutiveFailure(); 4931 4932 verify(mWifiScoreCard).noteConnectionFailure(any(), anyInt(), anyString(), anyInt()); 4933 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 4934 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(anyString(), eq(mTestConfig), 4935 eq(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING), anyInt()); 4936 verify(mWifiConfigManager).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 4937 WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES); 4938 } 4939 4940 @Test testDisableNetworkConsecutiveFailuresDoNotOverrideDisabledNetworks()4941 public void testDisableNetworkConsecutiveFailuresDoNotOverrideDisabledNetworks() 4942 throws Exception { 4943 initializeAndAddNetworkAndVerifySuccess(); 4944 // Now mock the connecting network to be already disabled 4945 mTestConfig.getNetworkSelectionStatus().setNetworkSelectionStatus( 4946 NETWORK_SELECTION_PERMANENTLY_DISABLED); 4947 triggerConnectionWithConsecutiveFailure(); 4948 4949 verify(mWifiScoreCard).noteConnectionFailure(any(), anyInt(), anyString(), anyInt()); 4950 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 4951 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(anyString(), eq(mTestConfig), 4952 eq(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING), anyInt()); 4953 4954 // should not disable due to DISABLED_CONSECUTIVE_FAILURES 4955 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 4956 WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES); 4957 } 4958 4959 /** 4960 * Verify that a network that was successfully connected to before will get permanently disabled 4961 * for wrong password when the number of wrong password failures exceed a threshold. 4962 */ 4963 @Test testUpgradeMultipleWrongPasswordFailuresToPermanentWrongPassword()4964 public void testUpgradeMultipleWrongPasswordFailuresToPermanentWrongPassword() 4965 throws Exception { 4966 initializeAndAddNetworkAndVerifySuccess(); 4967 startConnectSuccess(); 4968 4969 // mock the target network to be something that had been successfully connected before 4970 WifiConfiguration config = createTestNetwork(false); 4971 config.getNetworkSelectionStatus().setHasEverConnected(true); 4972 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 4973 4974 // mock number of wrong password failures to be less than the threshold 4975 when(mPerNetworkRecentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_WRONG_PASSWORD_FAILURE)) 4976 .thenReturn(ClientModeImpl.THRESHOLD_TO_PERM_WRONG_PASSWORD - 1); 4977 4978 // trigger the wrong password failure 4979 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 4980 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 4981 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 4982 DisconnectEventInfo disconnectEventInfo = 4983 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 4984 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 4985 mLooper.dispatchAll(); 4986 4987 // should not disable network permanently 4988 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 4989 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 4990 4991 // Bump up the wrong password count to reach the threshold and verify the network is 4992 // disabled permanently. 4993 when(mPerNetworkRecentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_WRONG_PASSWORD_FAILURE)) 4994 .thenReturn(ClientModeImpl.THRESHOLD_TO_PERM_WRONG_PASSWORD); 4995 4996 startConnectSuccess(); 4997 // trigger the wrong password failure 4998 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 4999 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 5000 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 5001 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5002 mLooper.dispatchAll(); 5003 5004 verify(mWifiConfigManager).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 5005 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 5006 } 5007 5008 /** 5009 * Verify that the recent failure association status is updated properly when 5010 * DENIED_POOR_CHANNEL_CONDITIONS occurs. 5011 */ 5012 @Test testAssocRejectedPoorChannelConditionsUpdatesRecentAssociationFailureStatus()5013 public void testAssocRejectedPoorChannelConditionsUpdatesRecentAssociationFailureStatus() 5014 throws Exception { 5015 initializeAndAddNetworkAndVerifySuccess(); 5016 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5017 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5018 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 5019 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS, 5020 false)); 5021 mLooper.dispatchAll(); 5022 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 5023 eq(WifiConfiguration.RECENT_FAILURE_POOR_CHANNEL_CONDITIONS)); 5024 } 5025 5026 /** 5027 * Verify that the recent failure association status is updated properly when a disconnection 5028 * with reason code DISASSOC_AP_BUSY occurs. 5029 */ 5030 @Test testNetworkDisconnectionApBusyUpdatesRecentAssociationFailureStatus()5031 public void testNetworkDisconnectionApBusyUpdatesRecentAssociationFailureStatus() 5032 throws Exception { 5033 connect(); 5034 // Disconnection with reason = DISASSOC_AP_BUSY 5035 DisconnectEventInfo disconnectEventInfo = 5036 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 5037 SupplicantStaIfaceHal.StaIfaceReasonCode.DISASSOC_AP_BUSY, false); 5038 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5039 mLooper.dispatchAll(); 5040 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 5041 eq(WifiConfiguration.RECENT_FAILURE_DISCONNECTION_AP_BUSY)); 5042 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(any(), any(), 5043 anyLong(), eq(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA), anyInt()); 5044 } 5045 5046 /** 5047 * Verify that the recent failure association status is updated properly when a disconnection 5048 * with reason code DISASSOC_AP_BUSY occurs. 5049 */ 5050 @Test testMidConnectionDisconnectionApBusyUpdatesRecentAssociationFailureStatus()5051 public void testMidConnectionDisconnectionApBusyUpdatesRecentAssociationFailureStatus() 5052 throws Exception { 5053 initializeAndAddNetworkAndVerifySuccess(); 5054 startConnectSuccess(); 5055 assertEquals("L2ConnectingState", getCurrentState().getName()); 5056 5057 // Disconnection with reason = DISASSOC_AP_BUSY 5058 DisconnectEventInfo disconnectEventInfo = 5059 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 5, false); 5060 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5061 mLooper.dispatchAll(); 5062 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 5063 eq(WifiConfiguration.RECENT_FAILURE_DISCONNECTION_AP_BUSY)); 5064 } 5065 5066 /** 5067 * Verify that the recent failure association status is updated properly when 5068 * ASSOCIATION_REJECTION_EVENT with OCE RSSI based association rejection attribute is received. 5069 */ 5070 @Test testOceRssiBasedAssociationRejectionUpdatesRecentAssociationFailureStatus()5071 public void testOceRssiBasedAssociationRejectionUpdatesRecentAssociationFailureStatus() 5072 throws Exception { 5073 assumeTrue(SdkLevel.isAtLeastS()); 5074 initializeAndAddNetworkAndVerifySuccess(); 5075 AssociationRejectionData assocRejectData = new AssociationRejectionData(); 5076 assocRejectData.ssid = NativeUtil.decodeSsid(TEST_SSID); 5077 assocRejectData.bssid = NativeUtil.macAddressToByteArray(TEST_BSSID_STR); 5078 assocRejectData.statusCode = 5079 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS; 5080 assocRejectData.isOceRssiBasedAssocRejectAttrPresent = true; 5081 assocRejectData.oceRssiBasedAssocRejectData.retryDelayS = 10; 5082 assocRejectData.oceRssiBasedAssocRejectData.deltaRssi = 20; 5083 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5084 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5085 new AssocRejectEventInfo(assocRejectData)); 5086 mLooper.dispatchAll(); 5087 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 5088 eq(WifiConfiguration.RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION)); 5089 } 5090 5091 /** 5092 * Verify that the recent failure association status is updated properly when 5093 * ASSOCIATION_REJECTION_EVENT with MBO association disallowed attribute is received. 5094 */ 5095 @Test testMboAssocDisallowedIndInAssocRejectUpdatesRecentAssociationFailureStatus()5096 public void testMboAssocDisallowedIndInAssocRejectUpdatesRecentAssociationFailureStatus() 5097 throws Exception { 5098 assumeTrue(SdkLevel.isAtLeastS()); 5099 initializeAndAddNetworkAndVerifySuccess(); 5100 AssociationRejectionData assocRejectData = new AssociationRejectionData(); 5101 assocRejectData.ssid = NativeUtil.decodeSsid(TEST_SSID); 5102 assocRejectData.bssid = NativeUtil.macAddressToByteArray(TEST_BSSID_STR); 5103 assocRejectData.statusCode = 5104 ISupplicantStaIfaceCallback.StatusCode.DENIED_POOR_CHANNEL_CONDITIONS; 5105 assocRejectData.isMboAssocDisallowedReasonCodePresent = true; 5106 assocRejectData.mboAssocDisallowedReason = MboAssocDisallowedReasonCode 5107 .MAX_NUM_STA_ASSOCIATED; 5108 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5109 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5110 new AssocRejectEventInfo(assocRejectData)); 5111 mLooper.dispatchAll(); 5112 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 5113 eq(WifiConfiguration.RECENT_FAILURE_MBO_ASSOC_DISALLOWED_MAX_NUM_STA_ASSOCIATED)); 5114 } 5115 5116 /** 5117 * Verifies that the WifiBlocklistMonitor is notified, but the WifiLastResortWatchdog is 5118 * not notified of association rejections of type REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA. 5119 * @throws Exception 5120 */ 5121 @Test testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog()5122 public void testAssociationRejectionWithReasonApUnableToHandleNewStaUpdatesWatchdog() 5123 throws Exception { 5124 initializeAndAddNetworkAndVerifySuccess(); 5125 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5126 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5127 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 5128 ISupplicantStaIfaceCallback.StatusCode.AP_UNABLE_TO_HANDLE_NEW_STA, false)); 5129 mLooper.dispatchAll(); 5130 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 5131 anyString(), anyString(), anyInt(), anyBoolean()); 5132 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5133 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA), 5134 anyInt()); 5135 } 5136 5137 /** 5138 * Verifies that the WifiBlocklistMonitor is notified, but the WifiLastResortWatchdog is 5139 * not notified of association rejections of type DENIED_INSUFFICIENT_BANDWIDTH. 5140 * @throws Exception 5141 */ 5142 @Test testAssociationRejectionWithReasonDeniedInsufficientBandwidth()5143 public void testAssociationRejectionWithReasonDeniedInsufficientBandwidth() 5144 throws Exception { 5145 initializeAndAddNetworkAndVerifySuccess(); 5146 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5147 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5148 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, ISupplicantStaIfaceCallback 5149 .StatusCode.DENIED_INSUFFICIENT_BANDWIDTH, false)); 5150 mLooper.dispatchAll(); 5151 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 5152 anyString(), anyString(), anyInt(), anyBoolean()); 5153 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5154 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA), 5155 anyInt()); 5156 } 5157 5158 /** 5159 * Verifies that WifiLastResortWatchdog and WifiBlocklistMonitor is notified of 5160 * general association rejection failures. 5161 * @throws Exception 5162 */ 5163 @Test testAssociationRejectionUpdatesWatchdog()5164 public void testAssociationRejectionUpdatesWatchdog() throws Exception { 5165 initializeAndAddNetworkAndVerifySuccess(); 5166 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID); 5167 config.carrierId = CARRIER_ID_1; 5168 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5169 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5170 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 5171 mLooper.dispatchAll(); 5172 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 5173 anyString(), anyString(), anyInt(), anyBoolean()); 5174 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5175 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_ASSOCIATION_REJECTION), anyInt()); 5176 verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionNonAuthFailure(); 5177 } 5178 testAssociationRejectionForRole(boolean isSecondary)5179 private void testAssociationRejectionForRole(boolean isSecondary) throws Exception { 5180 if (isSecondary) { 5181 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 5182 when(mClientModeManager.isSecondaryInternet()).thenReturn(true); 5183 } 5184 when(mPerNetworkRecentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE)) 5185 .thenReturn(WifiBlocklistMonitor.NUM_CONSECUTIVE_FAILURES_PER_NETWORK_EXP_BACKOFF); 5186 initializeAndAddNetworkAndVerifySuccess(); 5187 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5188 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 5189 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 5190 ISupplicantStaIfaceCallback.StatusCode.SUPPORTED_CHANNEL_NOT_VALID, false)); 5191 mLooper.dispatchAll(); 5192 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5193 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_ASSOCIATION_REJECTION), 5194 anyInt()); 5195 if (isSecondary) { 5196 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 5197 WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION); 5198 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 5199 WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES); 5200 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 5201 anyString(), anyString(), anyInt(), anyBoolean()); 5202 } 5203 else { 5204 verify(mWifiConfigManager).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 5205 WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION); 5206 verify(mWifiConfigManager).updateNetworkSelectionStatus(FRAMEWORK_NETWORK_ID, 5207 WifiConfiguration.NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES); 5208 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 5209 anyString(), anyString(), anyInt(), anyBoolean()); 5210 } 5211 } 5212 5213 @Test testAssociationRejectionPrimary()5214 public void testAssociationRejectionPrimary() throws Exception { 5215 testAssociationRejectionForRole(false); 5216 } 5217 5218 @Test testAssociationRejectionSecondary()5219 public void testAssociationRejectionSecondary() throws Exception { 5220 testAssociationRejectionForRole(true); 5221 } 5222 5223 /** 5224 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 5225 * ERROR_AUTH_FAILURE_WRONG_PSWD. 5226 * @throws Exception 5227 */ 5228 @Test testFailureWrongPassIsIgnoredByWatchdog()5229 public void testFailureWrongPassIsIgnoredByWatchdog() throws Exception { 5230 // Setup CONNECT_MODE & a WifiConfiguration 5231 initializeAndAddNetworkAndVerifySuccess(); 5232 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5233 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5234 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 5235 SupplicantState.COMPLETED)); 5236 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 5237 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 5238 WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1)); 5239 mLooper.dispatchAll(); 5240 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 5241 anyString(), anyString(), anyInt(), anyBoolean()); 5242 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5243 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_WRONG_PASSWORD), anyInt()); 5244 } 5245 5246 /** 5247 * Verifies that WifiLastResortWatchdog is not notified of authentication failures of type 5248 * ERROR_AUTH_FAILURE_EAP_FAILURE. 5249 * @throws Exception 5250 */ 5251 @Test testEapFailureIsIgnoredByWatchdog()5252 public void testEapFailureIsIgnoredByWatchdog() throws Exception { 5253 // Setup CONNECT_MODE & a WifiConfiguration 5254 initializeAndAddNetworkAndVerifySuccess(); 5255 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5256 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5257 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 5258 SupplicantState.COMPLETED)); 5259 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 5260 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 5261 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, -1)); 5262 mLooper.dispatchAll(); 5263 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 5264 anyString(), anyString(), anyInt(), anyBoolean()); 5265 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5266 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_EAP_FAILURE), anyInt()); 5267 } 5268 5269 /** 5270 * Verifies that WifiLastResortWatchdog is notified of other types of authentication failures. 5271 * @throws Exception 5272 */ 5273 @Test testAuthenticationFailureUpdatesWatchdog()5274 public void testAuthenticationFailureUpdatesWatchdog() throws Exception { 5275 // Setup CONNECT_MODE & a WifiConfiguration 5276 initializeAndAddNetworkAndVerifySuccess(); 5277 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5278 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5279 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 5280 SupplicantState.COMPLETED)); 5281 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 5282 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 5283 WifiManager.ERROR_AUTH_FAILURE_TIMEOUT, -1)); 5284 mLooper.dispatchAll(); 5285 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 5286 anyString(), anyString(), anyInt(), anyBoolean()); 5287 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(eq(TEST_BSSID_STR), 5288 eq(mTestConfig), eq(WifiBlocklistMonitor.REASON_AUTHENTICATION_FAILURE), anyInt()); 5289 } 5290 5291 /** 5292 * Verify that WifiBlocklistMonitor is notified of the SSID pre-connection so that it could 5293 * send down to firmware the list of blocked BSSIDs. 5294 */ 5295 @Test testBssidBlocklistSentToFirmwareAfterCmdStartConnect()5296 public void testBssidBlocklistSentToFirmwareAfterCmdStartConnect() throws Exception { 5297 initializeAndAddNetworkAndVerifySuccess(); 5298 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5299 verify(mWifiBlocklistMonitor, never()).updateFirmwareRoamingConfiguration( 5300 Set.of(TEST_SSID)); 5301 mLooper.dispatchAll(); 5302 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration(Set.of(TEST_SSID)); 5303 // But don't expect to see connection success yet 5304 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 5305 // And certainly not validation success 5306 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 5307 } 5308 5309 /** 5310 * Verifies that dhcp failures make WifiDiagnostics report CONNECTION_EVENT_FAILED and then 5311 * cancel any pending timeouts. 5312 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 5313 * @throws Exception 5314 */ 5315 @Test testReportConnectionEventIsCalledAfterDhcpFailure()5316 public void testReportConnectionEventIsCalledAfterDhcpFailure() throws Exception { 5317 mConnectedNetwork.getNetworkSelectionStatus() 5318 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq) 5319 .getScanResult()); 5320 testDhcpFailure(); 5321 verify(mWifiDiagnostics).reportConnectionEvent( 5322 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 5323 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 5324 mClientModeManager, 5325 WifiMetrics.ConnectionEvent.FAILURE_DHCP, 5326 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_BSSID_STR, 5327 mTestConfig); 5328 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 5329 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class), 5330 eq(TEST_BSSID_STR), eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN)); 5331 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 5332 eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class), 5333 any(String.class)); 5334 verify(mWifiMetrics, never()) 5335 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 5336 verifyConnectionEventTimeoutDoesNotOccur(); 5337 } 5338 5339 /** 5340 * Verifies that a successful validation make WifiDiagnostics report CONNECTION_EVENT_SUCCEEDED 5341 * and then cancel any pending timeouts. 5342 * Also, send connection status to {@link WifiNetworkFactory} & {@link WifiConnectivityManager}. 5343 */ 5344 @Test testReportConnectionEventIsCalledAfterSuccessfulConnection()5345 public void testReportConnectionEventIsCalledAfterSuccessfulConnection() throws Exception { 5346 mConnectedNetwork.getNetworkSelectionStatus() 5347 .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR1, sFreq) 5348 .getScanResult()); 5349 connect(); 5350 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5351 mWifiNetworkAgentCallbackCaptor.capture()); 5352 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5353 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 5354 mLooper.dispatchAll(); 5355 5356 verify(mWifiDiagnostics).reportConnectionEvent( 5357 eq(WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED), any()); 5358 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 5359 mClientModeManager, 5360 WifiMetrics.ConnectionEvent.FAILURE_NONE, 5361 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_BSSID_STR, 5362 mConnectedNetwork); 5363 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 5364 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), eq(mConnectedNetwork), 5365 eq(TEST_BSSID_STR), eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN)); 5366 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 5367 eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), eq(mConnectedNetwork), 5368 any(String.class)); 5369 verify(mCmiMonitor).onInternetValidated(mClientModeManager); 5370 // BSSID different, record this connection. 5371 verify(mWifiMetrics).incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 5372 verifyConnectionEventTimeoutDoesNotOccur(); 5373 5374 // Disconnect now should not trigger handleConnectionAttemptEnded 5375 DisconnectEventInfo disconnectEventInfo = 5376 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 5377 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 5378 mLooper.dispatchAll(); 5379 5380 verify(mWifiMetrics, never()).endConnectionEvent( 5381 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 5382 anyInt(), anyInt(), anyInt(), anyInt()); 5383 verify(mWifiConnectivityManager, never()).handleConnectionAttemptEnded( 5384 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 5385 anyInt(), any(), any()); 5386 } 5387 5388 /** 5389 * Verify that score card is notified of a connection attempt 5390 */ 5391 @Test testScoreCardNoteConnectionAttemptAfterCmdStartConnect()5392 public void testScoreCardNoteConnectionAttemptAfterCmdStartConnect() throws Exception { 5393 initializeAndAddNetworkAndVerifySuccess(); 5394 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 5395 verify(mWifiScoreCard, never()).noteConnectionAttempt(any(), anyInt(), anyString()); 5396 mLooper.dispatchAll(); 5397 verify(mWifiScoreCard).noteConnectionAttempt(any(), anyInt(), anyString()); 5398 verify(mWifiConfigManager).findScanRssi(anyInt(), anyInt()); 5399 // But don't expect to see connection success yet 5400 verify(mWifiScoreCard, never()).noteIpConfiguration(any()); 5401 // And certainly not validation success 5402 verify(mWifiScoreCard, never()).noteValidationSuccess(any()); 5403 5404 } 5405 5406 /** 5407 * Verify that score card is notified of a successful connection 5408 */ 5409 @Test testScoreCardNoteConnectionComplete()5410 public void testScoreCardNoteConnectionComplete() throws Exception { 5411 Pair<String, String> l2KeyAndCluster = Pair.create("Wad", "Gab"); 5412 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(l2KeyAndCluster); 5413 connect(); 5414 mLooper.dispatchAll(); 5415 verify(mWifiScoreCard).noteIpConfiguration(any()); 5416 ArgumentCaptor<Layer2InformationParcelable> captor = 5417 ArgumentCaptor.forClass(Layer2InformationParcelable.class); 5418 verify(mIpClient, atLeastOnce()).updateLayer2Information(captor.capture()); 5419 final Layer2InformationParcelable info = captor.getValue(); 5420 assertEquals(info.l2Key, "Wad"); 5421 assertEquals(info.cluster, "Gab"); 5422 } 5423 5424 /** 5425 * Verifies that Layer2 information is updated only when supplicant state change moves 5426 * to COMPLETED and on Wi-Fi disconnection. ie when device connect, roam & disconnect. 5427 */ 5428 @Test testLayer2InformationUpdate()5429 public void testLayer2InformationUpdate() throws Exception { 5430 InOrder inOrder = inOrder(mIpClient); 5431 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn( 5432 Pair.create("Wad", "Gab")); 5433 // Simulate connection 5434 connect(); 5435 5436 inOrder.verify(mIpClient).updateLayer2Information(any()); 5437 inOrder.verify(mIpClient).startProvisioning(any()); 5438 5439 // Simulate Roaming 5440 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn( 5441 Pair.create("aaa", "bbb")); 5442 // Now send a network connection (indicating a roam) event 5443 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5444 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null)); 5445 mLooper.dispatchAll(); 5446 5447 inOrder.verify(mIpClient).updateLayer2Information(any()); 5448 5449 // Simulate disconnection 5450 when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null)); 5451 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5452 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 5453 SupplicantState.DISCONNECTED)); 5454 mLooper.dispatchAll(); 5455 5456 verify(mWifiScoreCard, times(3)).getL2KeyAndGroupHint(any()); 5457 verify(mIpClient, times(3)).updateLayer2Information(any()); 5458 5459 5460 5461 } 5462 5463 /** 5464 * Verify that score card/health monitor are notified when wifi is disabled while disconnected 5465 */ 5466 @Test testScoreCardNoteWifiDisabledWhileDisconnected()5467 public void testScoreCardNoteWifiDisabledWhileDisconnected() throws Exception { 5468 // connecting and disconnecting shouldn't note wifi disabled 5469 disconnect(); 5470 mLooper.dispatchAll(); 5471 5472 verify(mWifiScoreCard, times(1)).resetConnectionState(WIFI_IFACE_NAME); 5473 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 5474 5475 // disabling while disconnected should note wifi disabled 5476 mCmi.stop(); 5477 mLooper.dispatchAll(); 5478 verify(mWifiScoreCard, times(2)).resetConnectionState(WIFI_IFACE_NAME); 5479 } 5480 5481 /** 5482 * Verify that score card/health monitor are notified when wifi is disabled while connected 5483 */ 5484 @Test testScoreCardNoteWifiDisabledWhileConnected()5485 public void testScoreCardNoteWifiDisabledWhileConnected() throws Exception { 5486 // Get into connected state 5487 connect(); 5488 mLooper.dispatchAll(); 5489 verify(mWifiScoreCard, never()).noteWifiDisabled(any()); 5490 5491 // disabling while connected should note wifi disabled 5492 mCmi.stop(); 5493 mLooper.dispatchAll(); 5494 5495 verify(mWifiScoreCard).noteWifiDisabled(any()); 5496 verify(mWifiScoreCard).resetConnectionState(WIFI_IFACE_NAME); 5497 } 5498 5499 /** 5500 * Verify that IPClient instance is shutdown when wifi is disabled. 5501 */ 5502 @Test verifyIpClientShutdownWhenDisabled()5503 public void verifyIpClientShutdownWhenDisabled() throws Exception { 5504 mCmi.stop(); 5505 mLooper.dispatchAll(); 5506 verify(mIpClient).shutdown(); 5507 } 5508 5509 /** 5510 * Verify that WifiInfo's MAC address is updated when the state machine receives 5511 * NETWORK_CONNECTION_EVENT while in L3ConnectedState. 5512 */ 5513 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected()5514 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileConnected() throws Exception { 5515 connect(); 5516 assertEquals("L3ConnectedState", getCurrentState().getName()); 5517 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 5518 5519 // Verify receiving a NETWORK_CONNECTION_EVENT changes the MAC in WifiInfo 5520 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 5521 .thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString()); 5522 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5523 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 5524 mLooper.dispatchAll(); 5525 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 5526 } 5527 5528 /** 5529 * Verify that WifiInfo's MAC address is updated when the state machine receives 5530 * NETWORK_CONNECTION_EVENT while in DisconnectedState. 5531 */ 5532 @Test verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected()5533 public void verifyWifiInfoMacUpdatedWithNetworkConnectionWhileDisconnected() throws Exception { 5534 disconnect(); 5535 assertEquals("DisconnectedState", getCurrentState().getName()); 5536 // Since MAC randomization is enabled, wifiInfo's MAC should be set to default MAC 5537 // when disconnect happens. 5538 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mWifiInfo.getMacAddress()); 5539 5540 setupAndStartConnectSequence(mConnectedNetwork); 5541 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 5542 .thenReturn(TEST_LOCAL_MAC_ADDRESS.toString()); 5543 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5544 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 5545 mLooper.dispatchAll(); 5546 assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress()); 5547 } 5548 5549 @Test internetValidationFailure_notUserSelected_expectTemporarilyDisabled()5550 public void internetValidationFailure_notUserSelected_expectTemporarilyDisabled() 5551 throws Exception { 5552 // Setup RSSI poll to update WifiInfo with low RSSI 5553 mCmi.enableRssiPolling(true); 5554 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 5555 llStats.txmpdu_be = 1000; 5556 llStats.rxmpdu_bk = 2000; 5557 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 5558 signalPollResults.addEntry(0, RSSI_THRESHOLD_BREACH_MIN, 65, 54, sFreq); 5559 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 5560 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 5561 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 5562 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 5563 5564 connect(); 5565 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5566 mWifiNetworkAgentCallbackCaptor.capture()); 5567 5568 WifiConfiguration currentNetwork = new WifiConfiguration(); 5569 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 5570 currentNetwork.SSID = DEFAULT_TEST_SSID; 5571 currentNetwork.noInternetAccessExpected = false; 5572 currentNetwork.numNoInternetAccessReports = 1; 5573 currentNetwork.getNetworkSelectionStatus().setHasEverValidatedInternetAccess(true); 5574 5575 // not user selected 5576 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 5577 .thenReturn(currentNetwork); 5578 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(FRAMEWORK_NETWORK_ID)) 5579 .thenReturn(currentNetwork); 5580 5581 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 5582 5583 // internet validation failure 5584 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5585 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUr; */); 5586 mLooper.dispatchAll(); 5587 5588 verify(mWifiConfigManager) 5589 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 5590 // expect temporarily disabled 5591 verify(mWifiConfigManager).updateNetworkSelectionStatus( 5592 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 5593 verify(mWifiBlocklistMonitor).handleBssidConnectionFailure(TEST_BSSID_STR, 5594 currentNetwork, WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, 5595 RSSI_THRESHOLD_BREACH_MIN); 5596 verify(mWifiScoreCard).noteValidationFailure(any()); 5597 } 5598 5599 @Test testMbbInternetValidationErrorExpectDisconnect()5600 public void testMbbInternetValidationErrorExpectDisconnect() throws Exception { 5601 connect(); 5602 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5603 mWifiNetworkAgentCallbackCaptor.capture()); 5604 5605 // Make Before Break CMM 5606 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 5607 when(mActiveModeWarden.getClientModeManagerInRole( 5608 ROLE_CLIENT_SECONDARY_TRANSIENT)).thenReturn(mock(ConcreteClientModeManager.class)); 5609 5610 // internet validation failure without detecting captive portal 5611 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5612 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUr; */); 5613 mLooper.dispatchAll(); 5614 verify(mCmiMonitor).onInternetValidationFailed(mClientModeManager, false); 5615 } 5616 5617 @Test testMbbNetworkUnwantedExpectDisconnect()5618 public void testMbbNetworkUnwantedExpectDisconnect() throws Exception { 5619 connect(); 5620 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5621 mWifiNetworkAgentCallbackCaptor.capture()); 5622 5623 // Make Before Break CMM 5624 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 5625 when(mActiveModeWarden.getClientModeManagerInRole( 5626 ROLE_CLIENT_SECONDARY_TRANSIENT)).thenReturn(mock(ConcreteClientModeManager.class)); 5627 5628 // internet was lost and network got unwanted. 5629 mWifiNetworkAgentCallbackCaptor.getValue().onNetworkUnwanted(); 5630 mLooper.dispatchAll(); 5631 // expect disconnection 5632 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 5633 } 5634 5635 @Test testMbbInternetValidationErrorCaptivePortalNoDisconnect()5636 public void testMbbInternetValidationErrorCaptivePortalNoDisconnect() throws Exception { 5637 connect(); 5638 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5639 mWifiNetworkAgentCallbackCaptor.capture()); 5640 5641 // Make Before Break CMM 5642 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 5643 5644 // mock internet validation failure with captive portal detected 5645 when(mMockUri.toString()).thenReturn("TEST_URI"); 5646 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5647 NetworkAgent.VALIDATION_STATUS_NOT_VALID, mMockUri); 5648 mLooper.dispatchAll(); 5649 5650 // expect no disconnection 5651 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 5652 } 5653 5654 @Test testCaptivePortalDetectedNotifiesCmiMonitor()5655 public void testCaptivePortalDetectedNotifiesCmiMonitor() throws Exception { 5656 connect(); 5657 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5658 mWifiNetworkAgentCallbackCaptor.capture()); 5659 5660 // captive portal detected 5661 when(mMockUri.toString()).thenReturn("TEST_URI"); 5662 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5663 NetworkAgent.VALIDATION_STATUS_NOT_VALID, mMockUri); 5664 mLooper.dispatchAll(); 5665 5666 verify(mWifiConfigManager).noteCaptivePortalDetected(anyInt()); 5667 verify(mCmiMonitor).onCaptivePortalDetected(mClientModeManager); 5668 } 5669 5670 @Test testInternetValidationFailureUserSelectedRecently_ExpectDisabled()5671 public void testInternetValidationFailureUserSelectedRecently_ExpectDisabled() 5672 throws Exception { 5673 testInternetValidationUserSelectedRecently(false); 5674 // expect disabled because the network has never had internet validation passed 5675 verify(mWifiConfigManager).updateNetworkSelectionStatus( 5676 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_PERMANENT); 5677 } 5678 5679 @Test testInternetValidationFailureUserSelectedRecently_ExpectNotDisabled()5680 public void testInternetValidationFailureUserSelectedRecently_ExpectNotDisabled() 5681 throws Exception { 5682 testInternetValidationUserSelectedRecently(true); 5683 // expect not disabled 5684 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 5685 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_PERMANENT); 5686 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 5687 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 5688 } 5689 testInternetValidationUserSelectedRecently(boolean hasEverValidatedInternetAccess)5690 private void testInternetValidationUserSelectedRecently(boolean hasEverValidatedInternetAccess) 5691 throws Exception { 5692 connect(); 5693 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5694 mWifiNetworkAgentCallbackCaptor.capture()); 5695 5696 WifiConfiguration currentNetwork = new WifiConfiguration(); 5697 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 5698 currentNetwork.noInternetAccessExpected = false; 5699 currentNetwork.numNoInternetAccessReports = 1; 5700 currentNetwork.getNetworkSelectionStatus().setHasEverValidatedInternetAccess( 5701 hasEverValidatedInternetAccess); 5702 5703 // user last picked this network 5704 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 5705 .thenReturn(currentNetwork); 5706 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); 5707 5708 // user recently picked this network 5709 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(1234L); 5710 when(mClock.getElapsedSinceBootMillis()).thenReturn(1235L); 5711 5712 // internet validation failure 5713 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5714 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 5715 mLooper.dispatchAll(); 5716 5717 verify(mWifiConfigManager) 5718 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 5719 } 5720 5721 @Test testInternetValidationFailureUserSelectedTooLongAgoExpectTemporarilyDisabled()5722 public void testInternetValidationFailureUserSelectedTooLongAgoExpectTemporarilyDisabled() 5723 throws Exception { 5724 connect(); 5725 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5726 mWifiNetworkAgentCallbackCaptor.capture()); 5727 5728 WifiConfiguration currentNetwork = new WifiConfiguration(); 5729 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 5730 currentNetwork.noInternetAccessExpected = false; 5731 currentNetwork.numNoInternetAccessReports = 1; 5732 currentNetwork.getNetworkSelectionStatus().setHasEverValidatedInternetAccess(true); 5733 5734 // user last picked this network 5735 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 5736 .thenReturn(currentNetwork); 5737 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID); 5738 5739 // user picked this network a long time ago 5740 when(mWifiConfigManager.getLastSelectedTimeStamp()).thenReturn(1234L); 5741 when(mClock.getElapsedSinceBootMillis()) 5742 .thenReturn(1235L + ClientModeImpl.LAST_SELECTED_NETWORK_EXPIRATION_AGE_MILLIS); 5743 5744 // internet validation failure 5745 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5746 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 5747 mLooper.dispatchAll(); 5748 5749 verify(mWifiConfigManager) 5750 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 5751 // expect temporarily disabled 5752 verify(mWifiConfigManager).updateNetworkSelectionStatus( 5753 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 5754 } 5755 5756 @Test testNetworkInternetValidationFailureNoInternetExpected_ExpectNotDisabled()5757 public void testNetworkInternetValidationFailureNoInternetExpected_ExpectNotDisabled() 5758 throws Exception { 5759 connect(); 5760 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5761 mWifiNetworkAgentCallbackCaptor.capture()); 5762 5763 WifiConfiguration currentNetwork = new WifiConfiguration(); 5764 currentNetwork.networkId = FRAMEWORK_NETWORK_ID; 5765 // no internet expected 5766 currentNetwork.noInternetAccessExpected = true; 5767 currentNetwork.numNoInternetAccessReports = 1; 5768 5769 // user didn't pick this network 5770 when(mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID)) 5771 .thenReturn(currentNetwork); 5772 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(FRAMEWORK_NETWORK_ID)) 5773 .thenReturn(currentNetwork); 5774 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 5775 5776 // internet validation failure 5777 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5778 NetworkAgent.VALIDATION_STATUS_NOT_VALID, null /* captivePortalUrl */); 5779 mLooper.dispatchAll(); 5780 5781 verify(mWifiConfigManager) 5782 .incrementNetworkNoInternetAccessReports(FRAMEWORK_NETWORK_ID); 5783 // expect not disabled since no internet is expected on this network 5784 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus( 5785 FRAMEWORK_NETWORK_ID, DISABLED_NO_INTERNET_TEMPORARY); 5786 } 5787 5788 /** 5789 * Verify that we do not set the user connect choice after a successful connection if the 5790 * connection is not made by the user. 5791 */ 5792 @Test testNonSettingsConnectionNotSetUserConnectChoice()5793 public void testNonSettingsConnectionNotSetUserConnectChoice() throws Exception { 5794 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 5795 connect(); 5796 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5797 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 5798 eq(false), eq(false), 5799 anyInt()); 5800 } 5801 5802 /** 5803 * Verify that we do not set the user connect choice after connecting to a newly added saved 5804 * network. 5805 */ 5806 @Test testNoSetUserConnectChoiceOnFirstConnection()5807 public void testNoSetUserConnectChoiceOnFirstConnection() throws Exception { 5808 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 5809 connect(); 5810 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5811 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 5812 eq(true), eq(false), 5813 anyInt()); 5814 } 5815 verifyUserConnectChoice(boolean shouldSetUcc)5816 private void verifyUserConnectChoice(boolean shouldSetUcc) throws Exception { 5817 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 5818 mTestNetworkParams.hasEverConnected = true; 5819 connect(); 5820 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5821 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 5822 eq(shouldSetUcc), eq(shouldSetUcc), 5823 anyInt()); 5824 } 5825 5826 /** 5827 * Verify that on the second successful connection to a saved network we set the user connect 5828 * choice. 5829 */ 5830 @Test testConnectionSetUserConnectChoiceOnSecondConnection()5831 public void testConnectionSetUserConnectChoiceOnSecondConnection() throws Exception { 5832 verifyUserConnectChoice(true); 5833 } 5834 5835 @Test testDisallowUserConnectChoice()5836 public void testDisallowUserConnectChoice() throws Exception { 5837 mAttributionTagForConnect = ClientModeImpl.ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE; 5838 verifyUserConnectChoice(false); 5839 } 5840 5841 /** 5842 * Verify that on the first successful connection to an ephemeral network we set the user 5843 * connect choice. 5844 */ 5845 @Test testConnectionSetUserConnectChoiceOnEphemeralConfig()5846 public void testConnectionSetUserConnectChoiceOnEphemeralConfig() throws Exception { 5847 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); 5848 mConnectedNetwork.ephemeral = true; 5849 connect(); 5850 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5851 verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID), 5852 eq(true), eq(true), 5853 anyInt()); 5854 } 5855 5856 /** 5857 * Verify that we enable the network when we detect validated internet access. 5858 */ 5859 @Test verifyNetworkSelectionEnableOnInternetValidation()5860 public void verifyNetworkSelectionEnableOnInternetValidation() throws Exception { 5861 // Simulate the first connection. 5862 connect(); 5863 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5864 verify(mWifiBlocklistMonitor).handleDhcpProvisioningSuccess(TEST_BSSID_STR, TEST_SSID); 5865 verify(mWifiBlocklistMonitor, never()).handleNetworkValidationSuccess( 5866 TEST_BSSID_STR, TEST_SSID); 5867 5868 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5869 mWifiNetworkAgentCallbackCaptor.capture()); 5870 5871 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 5872 5873 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5874 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 5875 mLooper.dispatchAll(); 5876 5877 verify(mWifiConfigManager) 5878 .setNetworkValidatedInternetAccess(FRAMEWORK_NETWORK_ID, true); 5879 verify(mWifiConfigManager).updateNetworkSelectionStatus( 5880 FRAMEWORK_NETWORK_ID, DISABLED_NONE); 5881 verify(mWifiScoreCard).noteValidationSuccess(any()); 5882 verify(mWifiBlocklistMonitor).handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 5883 } 5884 5885 /** 5886 * Verify that the logic clears the terms and conditions URL after we got a notification that 5887 * the network was validated (i.e. the user accepted and internt access is available). 5888 */ 5889 @Test testTermsAndConditionsClearUrlAfterNetworkValidation()5890 public void testTermsAndConditionsClearUrlAfterNetworkValidation() throws Exception { 5891 assumeTrue(SdkLevel.isAtLeastS()); 5892 InOrder inOrder = inOrder(mWifiNetworkAgent); 5893 5894 // Simulate the first connection. 5895 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 5896 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 5897 TEST_TERMS_AND_CONDITIONS_URL); 5898 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 5899 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 5900 connect(wnmData); 5901 // Verify that link properties contains the T&C URL and captive is set to true 5902 inOrder.verify(mWifiNetworkAgent) 5903 .sendLinkProperties(argThat(linkProperties -> TEST_TERMS_AND_CONDITIONS_URL.equals( 5904 linkProperties.getCaptivePortalData().getUserPortalUrl().toString()) 5905 && linkProperties.getCaptivePortalData().isCaptive())); 5906 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 5907 verify(mWifiBlocklistMonitor).handleDhcpProvisioningSuccess(TEST_BSSID_STR, TEST_SSID); 5908 verify(mWifiBlocklistMonitor, never()) 5909 .handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 5910 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 5911 mWifiNetworkAgentCallbackCaptor.capture()); 5912 5913 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(FRAMEWORK_NETWORK_ID + 1); 5914 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 5915 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 5916 mLooper.dispatchAll(); 5917 5918 verify(mWifiConfigManager) 5919 .setNetworkValidatedInternetAccess(FRAMEWORK_NETWORK_ID, true); 5920 verify(mWifiConfigManager).updateNetworkSelectionStatus( 5921 FRAMEWORK_NETWORK_ID, DISABLED_NONE); 5922 verify(mWifiScoreCard).noteValidationSuccess(any()); 5923 verify(mWifiBlocklistMonitor).handleNetworkValidationSuccess(TEST_BSSID_STR, TEST_SSID); 5924 5925 // Now that the network has been validated, link properties must not have a T&C URL anymore 5926 // and captive is set to false 5927 inOrder.verify(mWifiNetworkAgent) 5928 .sendLinkProperties(argThat(linkProperties -> 5929 linkProperties.getCaptivePortalData().getUserPortalUrl() == null 5930 && !linkProperties.getCaptivePortalData().isCaptive())); 5931 } 5932 connectWithValidInitRssi(int initRssiDbm)5933 private void connectWithValidInitRssi(int initRssiDbm) throws Exception { 5934 triggerConnect(); 5935 mWifiInfo.setRssi(initRssiDbm); 5936 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5937 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 5938 SupplicantState.ASSOCIATED)); 5939 mLooper.dispatchAll(); 5940 5941 WifiSsid wifiSsid = WifiSsid.fromBytes( 5942 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 5943 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 5944 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 5945 mLooper.dispatchAll(); 5946 5947 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 5948 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 5949 SupplicantState.COMPLETED)); 5950 mLooper.dispatchAll(); 5951 5952 assertEquals("L3ProvisioningState", getCurrentState().getName()); 5953 5954 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 5955 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 5956 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 5957 dhcpResults.baseConfiguration.ipAddress = 5958 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 5959 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 5960 dhcpResults.leaseDuration = 3600; 5961 5962 injectDhcpSuccess(dhcpResults); 5963 mLooper.dispatchAll(); 5964 5965 } 5966 5967 /** 5968 * Verify that we set the INTERNET and bandwidth capability in the network agent when connected 5969 * as a result of auto-join/legacy API's. Also verify up/down stream bandwidth values when 5970 * Rx link speed is unavailable. 5971 */ 5972 @Test verifyNetworkCapabilities()5973 public void verifyNetworkCapabilities() throws Exception { 5974 mWifiInfo.setFrequency(5825); 5975 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(40_000); 5976 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(50_000); 5977 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 5978 .thenReturn(Collections.emptySet()); 5979 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 5980 .thenReturn(Pair.create(Process.INVALID_UID, "")); 5981 // Simulate the first connection. 5982 connectWithValidInitRssi(-42); 5983 5984 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 5985 ArgumentCaptor.forClass(NetworkCapabilities.class); 5986 verify(mWifiInjector).makeWifiNetworkAgent( 5987 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 5988 5989 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 5990 assertNotNull(networkCapabilities); 5991 5992 // Should have internet capability. 5993 assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 5994 5995 assertEquals(mConnectedNetwork.creatorUid, networkCapabilities.getOwnerUid()); 5996 if (SdkLevel.isAtLeastT()) { 5997 assertEquals(Set.of(mConnectedNetwork.creatorUid), 5998 networkCapabilities.getAllowedUids()); 5999 } 6000 assertArrayEquals( 6001 new int[] {mConnectedNetwork.creatorUid}, 6002 networkCapabilities.getAdministratorUids()); 6003 6004 // Should set bandwidth correctly 6005 assertEquals(-42, mWifiInfo.getRssi()); 6006 assertEquals(40_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 6007 assertEquals(50_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 6008 6009 // Should set band correctly. 6010 // There is no accessor to get the band from the WifiNetworkAgentSpecifier, so match against 6011 // a WifiNetworkSpecifier. 6012 // TODO: should there be? 6013 final NetworkSpecifier spec = networkCapabilities.getNetworkSpecifier(); 6014 assertTrue(spec instanceof WifiNetworkAgentSpecifier); 6015 final WifiNetworkAgentSpecifier wnas = (WifiNetworkAgentSpecifier) spec; 6016 assertTrue(wnas.satisfiesNetworkSpecifier( 6017 new WifiNetworkSpecifier.Builder().setBand(ScanResult.WIFI_BAND_5_GHZ).build())); 6018 } 6019 6020 /** 6021 * Verify that we don't set the INTERNET capability in the network agent when connected 6022 * as a result of the new network request API. Also verify up/down stream bandwidth values 6023 * when both Tx and Rx link speed are unavailable. 6024 */ 6025 @Test verifyNetworkCapabilitiesForSpecificRequestWithInternet()6026 public void verifyNetworkCapabilitiesForSpecificRequestWithInternet() throws Exception { 6027 mWifiInfo.setFrequency(2437); 6028 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000); 6029 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000); 6030 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 6031 .thenReturn(Set.of(TEST_UID)); 6032 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 6033 .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME)); 6034 when(mWifiConnectivityManager.hasMultiInternetConnection()).thenReturn(true); 6035 // Simulate the first connection. 6036 connectWithValidInitRssi(-42); 6037 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 6038 ArgumentCaptor.forClass(NetworkCapabilities.class); 6039 6040 verify(mWifiInjector).makeWifiNetworkAgent( 6041 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 6042 6043 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 6044 assertNotNull(networkCapabilities); 6045 6046 // should not have internet capability. 6047 assertFalse(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 6048 6049 NetworkSpecifier networkSpecifier = networkCapabilities.getNetworkSpecifier(); 6050 assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier); 6051 WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = 6052 (WifiNetworkAgentSpecifier) networkSpecifier; 6053 6054 // createNetworkAgentSpecifier does not write the BSSID to the current wifi configuration. 6055 WifiConfiguration expectedConfig = new WifiConfiguration( 6056 mCmi.getConnectedWifiConfiguration()); 6057 expectedConfig.BSSID = TEST_BSSID_STR; 6058 WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier = 6059 new WifiNetworkAgentSpecifier(expectedConfig, ScanResult.WIFI_BAND_24_GHZ, 6060 true /* matchLocalOnlySpecifiers */); 6061 assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier); 6062 if (SdkLevel.isAtLeastS()) { 6063 assertEquals(Set.of(new Range<Integer>(TEST_UID, TEST_UID)), 6064 networkCapabilities.getUids()); 6065 } else { 6066 assertEquals(TEST_UID, networkCapabilities.getRequestorUid()); 6067 assertEquals(OP_PACKAGE_NAME, networkCapabilities.getRequestorPackageName()); 6068 } 6069 assertEquals(30_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 6070 assertEquals(40_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 6071 } 6072 6073 /** 6074 * Verify that we set the INTERNET capability in the network agent when connected 6075 * as a result of the new network which indicate the internet capabilites should be set. 6076 */ 6077 @Test verifyNetworkCapabilitiesForSpecificRequest()6078 public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception { 6079 mWifiInfo.setFrequency(2437); 6080 when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000); 6081 when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000); 6082 when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any())) 6083 .thenReturn(Set.of(TEST_UID)); 6084 when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any())) 6085 .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME)); 6086 when(mWifiNetworkFactory.shouldHaveInternetCapabilities()).thenReturn(true); 6087 when(mWifiConnectivityManager.hasMultiInternetConnection()).thenReturn(true); 6088 // Simulate the first connection. 6089 connectWithValidInitRssi(-42); 6090 ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor = 6091 ArgumentCaptor.forClass(NetworkCapabilities.class); 6092 6093 verify(mWifiInjector).makeWifiNetworkAgent( 6094 networkCapabilitiesCaptor.capture(), any(), any(), any(), any()); 6095 6096 NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue(); 6097 assertNotNull(networkCapabilities); 6098 6099 // should not have internet capability. 6100 assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)); 6101 6102 NetworkSpecifier networkSpecifier = networkCapabilities.getNetworkSpecifier(); 6103 assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier); 6104 WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = 6105 (WifiNetworkAgentSpecifier) networkSpecifier; 6106 6107 // createNetworkAgentSpecifier does not write the BSSID to the current wifi configuration. 6108 WifiConfiguration expectedConfig = new WifiConfiguration( 6109 mCmi.getConnectedWifiConfiguration()); 6110 expectedConfig.BSSID = TEST_BSSID_STR; 6111 WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier = 6112 new WifiNetworkAgentSpecifier(expectedConfig, ScanResult.WIFI_BAND_24_GHZ, 6113 true /* matchLocalOnlySpecifiers */); 6114 assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier); 6115 if (SdkLevel.isAtLeastS()) { 6116 assertEquals(Set.of(new Range<Integer>(TEST_UID, TEST_UID)), 6117 networkCapabilities.getUids()); 6118 } else { 6119 assertEquals(TEST_UID, networkCapabilities.getRequestorUid()); 6120 assertEquals(OP_PACKAGE_NAME, networkCapabilities.getRequestorPackageName()); 6121 } 6122 assertEquals(30_000, networkCapabilities.getLinkUpstreamBandwidthKbps()); 6123 assertEquals(40_000, networkCapabilities.getLinkDownstreamBandwidthKbps()); 6124 } 6125 6126 /** 6127 * Verifies that no RSSI change broadcast should be sent 6128 */ failOnRssiChangeBroadcast()6129 private void failOnRssiChangeBroadcast() throws Exception { 6130 mCmi.enableVerboseLogging(true); 6131 doAnswer(invocation -> { 6132 final Intent intent = invocation.getArgument(0); 6133 if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) { 6134 fail("Should not send RSSI_CHANGED broadcast!"); 6135 } 6136 return null; 6137 }).when(mContext).sendBroadcastAsUser(any(), any()); 6138 6139 doAnswer(invocation -> { 6140 final Intent intent = invocation.getArgument(0); 6141 if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) { 6142 fail("Should not send RSSI_CHANGED broadcast!"); 6143 } 6144 return null; 6145 }).when(mContext).sendBroadcastAsUser(any(), any(), anyString()); 6146 6147 doAnswer(invocation -> { 6148 final Intent intent = invocation.getArgument(0); 6149 if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) { 6150 fail("Should not send RSSI_CHANGED broadcast!"); 6151 } 6152 return null; 6153 }).when(mContext).sendBroadcastAsUser(any(), any(), anyString(), any()); 6154 } 6155 6156 /** 6157 * Verifies that RSSI change broadcast is sent. 6158 */ assertRssiChangeBroadcastSent(int times)6159 private void assertRssiChangeBroadcastSent(int times) throws Exception { 6160 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 6161 verify(mContext, times(times)).sendBroadcastAsUser(intentCaptor.capture(), 6162 eq(UserHandle.ALL), eq(Manifest.permission.ACCESS_WIFI_STATE), any()); 6163 if (times > 0) { 6164 Intent intent = intentCaptor.getValue(); 6165 assertNotNull(intent); 6166 assertEquals(WifiManager.RSSI_CHANGED_ACTION, intent.getAction()); 6167 } 6168 } 6169 6170 /** 6171 * Verify that we check for data stall during rssi poll 6172 * and then check that wifi link layer usage data are being updated. 6173 */ 6174 @Test verifyRssiPollChecksDataStall()6175 public void verifyRssiPollChecksDataStall() throws Exception { 6176 mCmi.enableRssiPolling(true); 6177 connect(); 6178 6179 failOnRssiChangeBroadcast(); 6180 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 6181 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 6182 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 6183 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 6184 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 6185 mLooper.dispatchAll(); 6186 WifiLinkLayerStats newLLStats = new WifiLinkLayerStats(); 6187 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(newLLStats); 6188 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 6189 mLooper.dispatchAll(); 6190 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 6191 mConnectionCapabilities, oldLLStats, newLLStats, mWifiInfo, TEST_TX_BYTES, 6192 TEST_RX_BYTES); 6193 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, newLLStats); 6194 } 6195 6196 /** 6197 * Verify that we update wifi usability stats entries during rssi poll and that when we get 6198 * a data stall we label and save the current list of usability stats entries. 6199 * @throws Exception 6200 */ 6201 @Test verifyRssiPollUpdatesWifiUsabilityMetrics()6202 public void verifyRssiPollUpdatesWifiUsabilityMetrics() throws Exception { 6203 mCmi.enableRssiPolling(true); 6204 connect(); 6205 6206 failOnRssiChangeBroadcast(); 6207 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 6208 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 6209 WifiLinkLayerStats stats = new WifiLinkLayerStats(); 6210 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(stats); 6211 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), 6212 any(), any(), any(), any(), anyLong(), anyLong())) 6213 .thenReturn(WifiIsUnusableEvent.TYPE_UNKNOWN); 6214 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 6215 mLooper.dispatchAll(); 6216 verify(mWifiMetrics).updateWifiUsabilityStatsEntries(any(), any(), eq(stats), eq(false), 6217 anyInt()); 6218 6219 when(mWifiDataStall.checkDataStallAndThroughputSufficiency(any(), any(), any(), any(), 6220 any(), anyLong(), anyLong())) 6221 .thenReturn(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX); 6222 when(mClock.getElapsedSinceBootMillis()).thenReturn(10L); 6223 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 6224 mLooper.dispatchAll(); 6225 verify(mWifiMetrics, times(2)).updateWifiUsabilityStatsEntries(any(), any(), eq(stats), 6226 eq(false), anyInt()); 6227 } 6228 6229 /** 6230 * Verify that when ordered to setPowerSave(true) while Interface is created, 6231 * WifiNative is called with the right powerSave mode. 6232 */ 6233 @Test verifySetPowerSaveTrueSuccess()6234 public void verifySetPowerSaveTrueSuccess() throws Exception { 6235 // called once during setup() 6236 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 6237 6238 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, true)); 6239 assertTrue(mCmi.enablePowerSave()); 6240 verify(mWifiNative, times(3)).setPowerSave(WIFI_IFACE_NAME, true); 6241 } 6242 6243 /** 6244 * Verify that when ordered to setPowerSave(false) while Interface is created, 6245 * WifiNative is called with the right powerSave mode. 6246 */ 6247 @Test verifySetPowerSaveFalseSuccess()6248 public void verifySetPowerSaveFalseSuccess() throws Exception { 6249 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, false)); 6250 verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6251 } 6252 6253 /** 6254 * Verify that using setPowerSave with multiple clients (DHCP/WifiLock) operates correctly: 6255 * - Disable power save if ANY client disables it 6256 * - Enable power save only if ALL clients no longer disable it 6257 */ 6258 @Test verifySetPowerSaveMultipleSources()6259 public void verifySetPowerSaveMultipleSources() { 6260 InOrder inOrderWifiNative = inOrder(mWifiNative); 6261 6262 // #1 Disable-> #2 Disable-> #2 Enable-> #1 Enable 6263 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, false)); 6264 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6265 6266 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, false)); 6267 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6268 6269 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, true)); 6270 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6271 6272 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, true)); 6273 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 6274 6275 // #1 Disable-> #2 Disable-> #1 Enable-> #2 Enable 6276 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, false)); 6277 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6278 6279 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, false)); 6280 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6281 6282 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, true)); 6283 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6284 6285 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, true)); 6286 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 6287 6288 // #1 Disable-> #2 Disable-> global enable 6289 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK, false)); 6290 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6291 6292 assertTrue(mCmi.setPowerSave(ClientMode.POWER_SAVE_CLIENT_DHCP, false)); 6293 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, false); 6294 6295 assertTrue(mCmi.enablePowerSave()); 6296 inOrderWifiNative.verify(mWifiNative).setPowerSave(WIFI_IFACE_NAME, true); 6297 } 6298 6299 /** 6300 * Verify that we call into WifiTrafficPoller during rssi poll 6301 */ 6302 @Test verifyRssiPollCallsWifiTrafficPoller()6303 public void verifyRssiPollCallsWifiTrafficPoller() throws Exception { 6304 mCmi.enableRssiPolling(true); 6305 connect(); 6306 6307 verify(mWifiTrafficPoller).notifyOnDataActivity(anyLong(), anyLong()); 6308 } 6309 6310 /** 6311 * Verify that when ordered to setLowLatencyMode(true), 6312 * WifiNative is called with the right lowLatency mode. 6313 */ 6314 @Test verifySetLowLatencyTrueSuccess()6315 public void verifySetLowLatencyTrueSuccess() throws Exception { 6316 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 6317 assertTrue(mCmi.setLowLatencyMode(true)); 6318 verify(mWifiNative).setLowLatencyMode(true); 6319 } 6320 6321 /** 6322 * Verify that when ordered to setLowLatencyMode(false), 6323 * WifiNative is called with the right lowLatency mode. 6324 */ 6325 @Test verifySetLowLatencyFalseSuccess()6326 public void verifySetLowLatencyFalseSuccess() throws Exception { 6327 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(true); 6328 assertTrue(mCmi.setLowLatencyMode(false)); 6329 verify(mWifiNative).setLowLatencyMode(false); 6330 } 6331 6332 /** 6333 * Verify that when WifiNative fails to set low latency mode, 6334 * then the call setLowLatencyMode() returns with failure, 6335 */ 6336 @Test verifySetLowLatencyModeFailure()6337 public void verifySetLowLatencyModeFailure() throws Exception { 6338 final boolean lowLatencyMode = true; 6339 when(mWifiNative.setLowLatencyMode(anyBoolean())).thenReturn(false); 6340 assertFalse(mCmi.setLowLatencyMode(lowLatencyMode)); 6341 verify(mWifiNative).setLowLatencyMode(eq(lowLatencyMode)); 6342 } 6343 6344 /** 6345 * Verify the wifi module can be confiured to always get the factory MAC address from 6346 * WifiNative instead of using saved value in WifiConfigStore. 6347 */ 6348 @Test testGetFactoryMacAddressAlwaysFromWifiNative()6349 public void testGetFactoryMacAddressAlwaysFromWifiNative() throws Exception { 6350 // Configure overlay to always retrieve the MAC address from WifiNative. 6351 when(mWifiGlobals.isSaveFactoryMacToConfigStoreEnabled()).thenReturn(false); 6352 initializeAndAddNetworkAndVerifySuccess(); 6353 6354 clearInvocations(mWifiNative, mSettingsConfigStore); 6355 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6356 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6357 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6358 6359 verify(mWifiNative, times(3)).getStaFactoryMacAddress(WIFI_IFACE_NAME); 6360 } 6361 6362 /** 6363 * Verify getting the factory MAC address success case. 6364 */ 6365 @Test testGetFactoryMacAddressSuccess()6366 public void testGetFactoryMacAddressSuccess() throws Exception { 6367 initializeAndAddNetworkAndVerifySuccess(); 6368 6369 clearInvocations(mWifiNative, mSettingsConfigStore); 6370 6371 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6372 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); // try config store. 6373 verify(mWifiNative, never()).getStaFactoryMacAddress(WIFI_IFACE_NAME); // not native 6374 verify(mSettingsConfigStore, never()).put(eq(WIFI_STA_FACTORY_MAC_ADDRESS), any()); 6375 6376 clearInvocations(mWifiNative, mSettingsConfigStore); 6377 6378 // get it again, should now use the config store MAC address, not native. 6379 assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6380 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 6381 6382 // Verify secondary MAC is not stored 6383 verify(mSettingsConfigStore, never()).put( 6384 eq(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS), any()); 6385 verify(mSettingsConfigStore, never()).get(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS); 6386 6387 // Query again as secondary STA, and then verify the result is saved to secondary. 6388 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 6389 mCmi.getFactoryMacAddress(); 6390 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 6391 verify(mSettingsConfigStore).put(eq(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS), any()); 6392 verify(mSettingsConfigStore).get(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS); 6393 6394 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 6395 } 6396 6397 /** 6398 * Verify getting the factory MAC address failure case. 6399 */ 6400 @Test testGetFactoryMacAddressFail()6401 public void testGetFactoryMacAddressFail() throws Exception { 6402 initializeAndAddNetworkAndVerifySuccess(); 6403 6404 clearInvocations(mWifiNative, mSettingsConfigStore); 6405 6406 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)).thenReturn(null); 6407 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 6408 assertNull(mCmi.getFactoryMacAddress()); 6409 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 6410 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 6411 6412 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 6413 } 6414 6415 /** 6416 * Verify that when WifiNative#getStaFactoryMacAddress fails, if the device does not support 6417 * MAC randomization then the currently programmed MAC address gets returned. 6418 */ 6419 @Test testGetFactoryMacAddressFailWithNoMacRandomizationSupport()6420 public void testGetFactoryMacAddressFailWithNoMacRandomizationSupport() throws Exception { 6421 // reset mWifiNative since initializeCmi() was called in setup() 6422 resetWifiNative(); 6423 6424 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 6425 initializeCmi(); 6426 initializeAndAddNetworkAndVerifySuccess(); 6427 6428 clearInvocations(mWifiNative, mSettingsConfigStore); 6429 6430 when(mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS)).thenReturn(null); 6431 when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 6432 when(mWifiNative.getMacAddress(WIFI_IFACE_NAME)) 6433 .thenReturn(TEST_DEFAULT_MAC_ADDRESS.toString()); 6434 assertEquals(TEST_DEFAULT_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); 6435 6436 verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS); 6437 verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME); 6438 verify(mWifiNative).getMacAddress(WIFI_IFACE_NAME); 6439 6440 verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore); 6441 } 6442 6443 /** 6444 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 6445 */ 6446 @Test testRandomizeMacAddressOnStart()6447 public void testRandomizeMacAddressOnStart() throws Exception { 6448 ArgumentCaptor<MacAddress> macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class); 6449 verify(mWifiNative).setStaMacAddress(anyString(), macAddressCaptor.capture()); 6450 MacAddress currentMac = macAddressCaptor.getValue(); 6451 6452 assertNotEquals("The currently programmed MAC address should be different from the factory " 6453 + "MAC address after ClientModeImpl starts", 6454 mCmi.getFactoryMacAddress(), currentMac.toString()); 6455 6456 // Verify interface up will not re-randomize the MAC address again. 6457 mCmi.onUpChanged(true); 6458 verify(mWifiNative).setStaMacAddress(anyString(), macAddressCaptor.capture()); 6459 } 6460 6461 /** 6462 * Verify if re-randomizing had failed, then we will retry the next time the interface comes up. 6463 */ 6464 @Test testRandomizeMacAddressFailedRetryOnInterfaceUp()6465 public void testRandomizeMacAddressFailedRetryOnInterfaceUp() throws Exception { 6466 // mock setting the MAC address to fail 6467 when(mWifiNative.setStaMacAddress(eq(WIFI_IFACE_NAME), any())).thenReturn(false); 6468 initializeCmi(); 6469 6470 ArgumentCaptor<MacAddress> macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class); 6471 verify(mWifiNative, times(2)).setStaMacAddress(anyString(), macAddressCaptor.capture()); 6472 MacAddress currentMac = macAddressCaptor.getValue(); 6473 6474 // mock setting the MAC address to succeed 6475 when(mWifiNative.setStaMacAddress(eq(WIFI_IFACE_NAME), any())) 6476 .then(new AnswerWithArguments() { 6477 public boolean answer(String iface, MacAddress mac) { 6478 when(mWifiNative.getMacAddress(iface)).thenReturn(mac.toString()); 6479 return true; 6480 } 6481 }); 6482 6483 // Verify interface up will re-randomize the MAC address since the last attempt failed. 6484 mCmi.onUpChanged(true); 6485 verify(mWifiNative, times(3)).setStaMacAddress(anyString(), macAddressCaptor.capture()); 6486 assertNotEquals("The currently programmed MAC address should be different from the factory " 6487 + "MAC address after ClientModeImpl starts", 6488 mCmi.getFactoryMacAddress(), currentMac.toString()); 6489 6490 // Verify interface up will not re-randomize the MAC address since the last attempt 6491 // succeeded. 6492 mCmi.onUpChanged(true); 6493 verify(mWifiNative, times(3)).setStaMacAddress(anyString(), macAddressCaptor.capture()); 6494 } 6495 6496 /** 6497 * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. 6498 */ 6499 @Test testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled()6500 public void testNoRandomizeMacAddressOnStartIfMacRandomizationNotEnabled() throws Exception { 6501 // reset mWifiNative since initializeCmi() was called in setup() 6502 resetWifiNative(); 6503 6504 when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); 6505 initializeCmi(); 6506 verify(mWifiNative, never()).setStaMacAddress(anyString(), any()); 6507 } 6508 6509 /** 6510 * Verify bugreport will be taken when get IP_REACHABILITY_LOST 6511 */ 6512 @Test testTakebugreportbyIpReachabilityLost()6513 public void testTakebugreportbyIpReachabilityLost() throws Exception { 6514 connect(); 6515 6516 mIpClientCallback.onReachabilityLost("CMD_IP_REACHABILITY_LOST"); 6517 mLooper.dispatchAll(); 6518 verify(mWifiDiagnostics).triggerBugReportDataCapture( 6519 eq(WifiDiagnostics.REPORT_REASON_REACHABILITY_LOST)); 6520 } 6521 6522 /** 6523 * Verify bugreport will be taken when get IP_REACHABILITY_FAILURE 6524 */ 6525 @Test testTakeBugReportByIpReachabilityFailure()6526 public void testTakeBugReportByIpReachabilityFailure() throws Exception { 6527 assumeTrue(SdkLevel.isAtLeastT()); 6528 connect(); 6529 6530 ReachabilityLossInfoParcelable lossInfo = 6531 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ROAM); 6532 mIpClientCallback.onReachabilityFailure(lossInfo); 6533 mLooper.dispatchAll(); 6534 verify(mWifiDiagnostics).triggerBugReportDataCapture( 6535 eq(WifiDiagnostics.REPORT_REASON_REACHABILITY_FAILURE)); 6536 } 6537 /** 6538 * Verifies that WifiLastResortWatchdog is notified of FOURWAY_HANDSHAKE_TIMEOUT. 6539 */ 6540 @Test testHandshakeTimeoutUpdatesWatchdog()6541 public void testHandshakeTimeoutUpdatesWatchdog() throws Exception { 6542 // Setup CONNECT_MODE & a WifiConfiguration 6543 initializeAndAddNetworkAndVerifySuccess(); 6544 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 6545 mLooper.dispatchAll(); 6546 // Verifies that WifiLastResortWatchdog won't be notified 6547 // by other reason code 6548 DisconnectEventInfo disconnectEventInfo = 6549 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 2, false); 6550 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 6551 mLooper.dispatchAll(); 6552 6553 assertEquals("DisconnectedState", getCurrentState().getName()); 6554 verify(mWifiLastResortWatchdog, never()).noteConnectionFailureAndTriggerIfNeeded( 6555 eq(TEST_SSID), eq(TEST_BSSID_STR), 6556 eq(WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION), anyBoolean()); 6557 6558 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 6559 mLooper.dispatchAll(); 6560 // Verifies that WifiLastResortWatchdog be notified 6561 // for FOURWAY_HANDSHAKE_TIMEOUT. 6562 disconnectEventInfo = new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 6563 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 6564 mLooper.dispatchAll(); 6565 6566 assertEquals("DisconnectedState", getCurrentState().getName()); 6567 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 6568 eq(TEST_SSID), eq(TEST_BSSID_STR), 6569 eq(WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION), anyBoolean()); 6570 6571 } 6572 6573 /** 6574 * Verify that WifiInfo is correctly populated after connection. 6575 */ 6576 @Test verifyWifiInfoGetNetworkSpecifierPackageName()6577 public void verifyWifiInfoGetNetworkSpecifierPackageName() throws Exception { 6578 mConnectedNetwork.fromWifiNetworkSpecifier = true; 6579 mConnectedNetwork.ephemeral = true; 6580 mConnectedNetwork.trusted = true; 6581 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 6582 mConnectedNetwork.restricted = true; 6583 connect(); 6584 6585 assertTrue(mWifiInfo.isEphemeral()); 6586 assertTrue(mWifiInfo.isTrusted()); 6587 assumeTrue(mWifiInfo.isRestricted()); 6588 assertEquals(OP_PACKAGE_NAME, 6589 mWifiInfo.getRequestingPackageName()); 6590 6591 verify(mWifiConfigManager, never()).userTemporarilyDisabledNetwork( 6592 eq(mConnectedNetwork.SSID), anyInt()); 6593 // Setup new manual connection to another network 6594 WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork(); 6595 config.networkId = TEST_NETWORK_ID; 6596 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 6597 6598 IActionListener connectActionListener = mock(IActionListener.class); 6599 mCmi.connectNetwork( 6600 new NetworkUpdateResult(TEST_NETWORK_ID), 6601 new ActionListenerWrapper(connectActionListener), 6602 Process.SYSTEM_UID, OP_PACKAGE_NAME, null); 6603 mLooper.dispatchAll(); 6604 verify(connectActionListener).onSuccess(); 6605 6606 // verify new manual connection will add the wifi network specifier network to temporary 6607 // blocklist 6608 verify(mWifiConfigManager).userTemporarilyDisabledNetwork(eq(mConnectedNetwork.SSID), 6609 anyInt()); 6610 } 6611 6612 /** 6613 * Verify that WifiInfo is correctly populated after connection. 6614 */ 6615 @Test verifyWifiInfoGetNetworkSuggestionPackageName()6616 public void verifyWifiInfoGetNetworkSuggestionPackageName() throws Exception { 6617 mConnectedNetwork.fromWifiNetworkSuggestion = true; 6618 mConnectedNetwork.ephemeral = true; 6619 mConnectedNetwork.trusted = true; 6620 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 6621 mConnectedNetwork.restricted = true; 6622 connect(); 6623 6624 assertTrue(mWifiInfo.isEphemeral()); 6625 assertTrue(mWifiInfo.isTrusted()); 6626 assumeTrue(mWifiInfo.isRestricted()); 6627 assertEquals(OP_PACKAGE_NAME, 6628 mWifiInfo.getRequestingPackageName()); 6629 } 6630 6631 /** 6632 * Verify that a WifiIsUnusableEvent is logged and the current list of usability stats entries 6633 * are labeled and saved when receiving an IP reachability lost message. 6634 * @throws Exception 6635 */ 6636 @Test verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics()6637 public void verifyIpReachabilityLostMsgUpdatesWifiUsabilityMetrics() throws Exception { 6638 connect(); 6639 6640 mIpClientCallback.onReachabilityLost("CMD_IP_REACHABILITY_LOST"); 6641 mLooper.dispatchAll(); 6642 verify(mWifiMetrics).logWifiIsUnusableEvent(WIFI_IFACE_NAME, 6643 WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST); 6644 } 6645 6646 /** 6647 * Verify that a WifiIsUnusableEvent is logged and the current list of usability stats entries 6648 * are labeled and saved when receiving an IP reachability failure message with non roam type. 6649 * @throws Exception 6650 */ 6651 @Test verifyIpReachabilityFailureMsgUpdatesWifiUsabilityMetrics()6652 public void verifyIpReachabilityFailureMsgUpdatesWifiUsabilityMetrics() throws Exception { 6653 assumeTrue(SdkLevel.isAtLeastT()); 6654 connect(); 6655 6656 ReachabilityLossInfoParcelable lossInfo = 6657 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.CONFIRM); 6658 mIpClientCallback.onReachabilityFailure(lossInfo); 6659 mLooper.dispatchAll(); 6660 verify(mWifiMetrics).logWifiIsUnusableEvent(WIFI_IFACE_NAME, 6661 WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST); 6662 } 6663 6664 /** 6665 * Verify that a WifiIsUnusableEvent isn't logged and the current list of usability stats 6666 * entries are not labeled and saved when receiving an IP reachability failure message with 6667 * non roam type but {@link isHandleRssiOrganicKernelFailuresEnabled} is enabled. 6668 * @throws Exception 6669 */ 6670 @Test verifyIpReachabilityFailureMsgUpdatesWifiUsabilityMetrics_enableFlag()6671 public void verifyIpReachabilityFailureMsgUpdatesWifiUsabilityMetrics_enableFlag() 6672 throws Exception { 6673 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 6674 assumeTrue(SdkLevel.isAtLeastU()); 6675 connect(); 6676 6677 ReachabilityLossInfoParcelable lossInfo = 6678 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.CONFIRM); 6679 mCmi.sendMessage(ClientModeImpl.CMD_IP_REACHABILITY_FAILURE, lossInfo); 6680 mLooper.dispatchAll(); 6681 verify(mWifiMetrics, never()).logWifiIsUnusableEvent(WIFI_IFACE_NAME, 6682 WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST); 6683 } 6684 6685 /** 6686 * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds 6687 * to the supplicant with the SIM identity. 6688 */ 6689 @Test testSupRequestIdentity_setsIdentityResponse()6690 public void testSupRequestIdentity_setsIdentityResponse() throws Exception { 6691 mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( 6692 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 6693 mConnectedNetwork.SSID = DEFAULT_TEST_SSID; 6694 String expectetIdentity = "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org"; 6695 6696 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 6697 .thenReturn(DATA_SUBID); 6698 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 6699 when(mWifiCarrierInfoManager.getSimIdentity(any())) 6700 .thenReturn(Pair.create(expectetIdentity, "")); 6701 6702 triggerConnect(); 6703 6704 mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY, 6705 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID); 6706 mLooper.dispatchAll(); 6707 6708 verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME, 6709 expectetIdentity, ""); 6710 } 6711 6712 /** 6713 * Verifies that WifiLastResortWatchdog is notified of DHCP failures when recevied 6714 * NETWORK_DISCONNECTION_EVENT while in L3ProvisioningState. 6715 */ 6716 @Test testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr()6717 public void testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr() 6718 throws Exception { 6719 initializeAndAddNetworkAndVerifySuccess(); 6720 6721 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 6722 6723 startConnectSuccess(); 6724 6725 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 6726 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 6727 mLooper.dispatchAll(); 6728 6729 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 6730 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 6731 SupplicantState.COMPLETED)); 6732 mLooper.dispatchAll(); 6733 6734 assertEquals("L3ProvisioningState", getCurrentState().getName()); 6735 6736 // Verifies that WifiLastResortWatchdog be notified. 6737 DisconnectEventInfo disconnectEventInfo = 6738 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 6739 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 6740 mLooper.dispatchAll(); 6741 6742 assertEquals("DisconnectedState", getCurrentState().getName()); 6743 verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded( 6744 eq(TEST_SSID), eq(TEST_BSSID_STR), 6745 eq(WifiLastResortWatchdog.FAILURE_CODE_DHCP), anyBoolean()); 6746 } 6747 6748 /** 6749 * Verifies that we trigger a disconnect when the {@link WifiConfigManager}. 6750 * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked. 6751 */ 6752 @Test testOnNetworkRemoved()6753 public void testOnNetworkRemoved() throws Exception { 6754 connect(); 6755 6756 WifiConfiguration removedNetwork = new WifiConfiguration(); 6757 removedNetwork.networkId = FRAMEWORK_NETWORK_ID; 6758 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 6759 .getAllValues()) { 6760 listener.onNetworkRemoved(removedNetwork); 6761 } 6762 mLooper.dispatchAll(); 6763 6764 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 6765 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 6766 } 6767 6768 /** 6769 * Verifies that we trigger a disconnect when the {@link WifiConfigManager 6770 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 6771 */ 6772 @Test testOnNetworkPermanentlyDisabled()6773 public void testOnNetworkPermanentlyDisabled() throws Exception { 6774 connect(); 6775 6776 // Verify connection failure related disable reason should not trigger disconnect because 6777 // this could be from another STA 6778 WifiConfiguration disabledNetwork = new WifiConfiguration(); 6779 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 6780 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 6781 .getAllValues()) { 6782 listener.onNetworkPermanentlyDisabled(disabledNetwork, 6783 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 6784 } 6785 mLooper.dispatchAll(); 6786 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 6787 6788 // Verify that the network is disconnect if the profile is disabled by wifi API call 6789 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 6790 .getAllValues()) { 6791 listener.onNetworkPermanentlyDisabled(disabledNetwork, 6792 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER); 6793 } 6794 mLooper.dispatchAll(); 6795 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 6796 } 6797 6798 @Test testUnwantedDisconnectTemporarilyDisableNetwork()6799 public void testUnwantedDisconnectTemporarilyDisableNetwork() throws Exception { 6800 connect(); 6801 when(mWifiGlobals.disableUnwantedNetworkOnLowRssi()).thenReturn(true); 6802 when(mWifiConfigManager.getLastSelectedNetwork()).thenReturn(-1); 6803 mWifiInfo.setRssi(RSSI_THRESHOLD_MIN); 6804 mCmi.sendMessage(CMD_UNWANTED_NETWORK, 6805 ClientModeImpl.NETWORK_STATUS_UNWANTED_DISCONNECT); 6806 mLooper.dispatchAll(); 6807 6808 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 6809 eq(DISABLED_UNWANTED_LOW_RSSI)); 6810 } 6811 6812 /** 6813 * Verify that the current network is permanently disabled when 6814 * NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN is received and percent internet availability is 6815 * less than the threshold. 6816 */ 6817 @Test testLowPrababilityInternetPermanentlyDisableNetwork()6818 public void testLowPrababilityInternetPermanentlyDisableNetwork() throws Exception { 6819 connect(); 6820 when(mPerBssid.estimatePercentInternetAvailability()).thenReturn( 6821 ClientModeImpl.PROBABILITY_WITH_INTERNET_TO_PERMANENTLY_DISABLE_NETWORK - 1); 6822 mCmi.sendMessage(CMD_UNWANTED_NETWORK, 6823 ClientModeImpl.NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN); 6824 mLooper.dispatchAll(); 6825 6826 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 6827 eq(DISABLED_NO_INTERNET_PERMANENT)); 6828 } 6829 6830 /** 6831 * Verify that the current network is temporarily disabled when 6832 * NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN is received and percent internet availability is 6833 * over the threshold. 6834 */ 6835 @Test testHighProbabilityInternetTemporarilyDisableNetwork()6836 public void testHighProbabilityInternetTemporarilyDisableNetwork() throws Exception { 6837 connect(); 6838 when(mPerBssid.estimatePercentInternetAvailability()).thenReturn( 6839 ClientModeImpl.PROBABILITY_WITH_INTERNET_TO_PERMANENTLY_DISABLE_NETWORK); 6840 mCmi.sendMessage(CMD_UNWANTED_NETWORK, 6841 ClientModeImpl.NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN); 6842 mLooper.dispatchAll(); 6843 6844 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 6845 eq(DISABLED_NO_INTERNET_TEMPORARY)); 6846 } 6847 6848 /** 6849 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 6850 * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked. 6851 */ 6852 @Test testOnNetworkPermanentlyDisabledWithNoInternet()6853 public void testOnNetworkPermanentlyDisabledWithNoInternet() throws Exception { 6854 connect(); 6855 6856 WifiConfiguration disabledNetwork = new WifiConfiguration(); 6857 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 6858 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 6859 .getAllValues()) { 6860 listener.onNetworkPermanentlyDisabled(disabledNetwork, 6861 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT); 6862 } 6863 mLooper.dispatchAll(); 6864 6865 assertEquals("L3ConnectedState", getCurrentState().getName()); 6866 } 6867 6868 /** 6869 * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager 6870 * .OnNetworkUpdateListener#onNetworkTemporarilyDisabled(WifiConfiguration, int)} is invoked. 6871 */ 6872 @Test testOnNetworkTemporarilyDisabledWithNoInternet()6873 public void testOnNetworkTemporarilyDisabledWithNoInternet() throws Exception { 6874 connect(); 6875 6876 WifiConfiguration disabledNetwork = new WifiConfiguration(); 6877 disabledNetwork.networkId = FRAMEWORK_NETWORK_ID; 6878 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 6879 .getAllValues()) { 6880 listener.onNetworkTemporarilyDisabled(disabledNetwork, 6881 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY); 6882 } 6883 mLooper.dispatchAll(); 6884 6885 assertEquals("L3ConnectedState", getCurrentState().getName()); 6886 } 6887 6888 /** 6889 * Verify that MboOce/WifiDataStall enable/disable methods are called in ClientMode. 6890 */ 6891 @Test verifyMboOceWifiDataStallSetupInClientMode()6892 public void verifyMboOceWifiDataStallSetupInClientMode() throws Exception { 6893 verify(mMboOceController).enable(); 6894 mCmi.stop(); 6895 mLooper.dispatchAll(); 6896 verify(mMboOceController).disable(); 6897 } 6898 6899 @Test verifyWifiMonitorHandlersDeregisteredOnStop()6900 public void verifyWifiMonitorHandlersDeregisteredOnStop() throws Exception { 6901 verify(mWifiMonitor, atLeastOnce()) 6902 .registerHandler(eq(WIFI_IFACE_NAME), anyInt(), any()); 6903 verify(mWifiMetrics).registerForWifiMonitorEvents(WIFI_IFACE_NAME); 6904 verify(mWifiLastResortWatchdog).registerForWifiMonitorEvents(WIFI_IFACE_NAME); 6905 6906 mCmi.stop(); 6907 mLooper.dispatchAll(); 6908 6909 verify(mWifiMonitor, atLeastOnce()) 6910 .deregisterHandler(eq(WIFI_IFACE_NAME), anyInt(), any()); 6911 verify(mWifiMetrics).deregisterForWifiMonitorEvents(WIFI_IFACE_NAME); 6912 verify(mWifiLastResortWatchdog).deregisterForWifiMonitorEvents(WIFI_IFACE_NAME); 6913 } 6914 6915 @Test onBluetoothConnectionStateChanged()6916 public void onBluetoothConnectionStateChanged() throws Exception { 6917 // reset mWifiNative since initializeCmi() was called in setup() 6918 resetWifiNative(); 6919 6920 when(mWifiGlobals.isBluetoothConnected()).thenReturn(false); 6921 initializeCmi(); 6922 verify(mWifiNative).setBluetoothCoexistenceScanMode(any(), eq(false)); 6923 6924 when(mWifiGlobals.isBluetoothConnected()).thenReturn(true); 6925 mCmi.onBluetoothConnectionStateChanged(); 6926 mLooper.dispatchAll(); 6927 verify(mWifiNative).setBluetoothCoexistenceScanMode(any(), eq(true)); 6928 6929 when(mWifiGlobals.isBluetoothConnected()).thenReturn(false); 6930 mCmi.onBluetoothConnectionStateChanged(); 6931 mLooper.dispatchAll(); 6932 verify(mWifiNative, times(2)).setBluetoothCoexistenceScanMode(any(), eq(false)); 6933 } 6934 6935 /** 6936 * Test that handleBssTransitionRequest() blocklist the BSS upon 6937 * receiving BTM request frame that contains MBO-OCE IE with an 6938 * association retry delay attribute. 6939 */ 6940 @Test testBtmFrameWithMboAssocretryDelayBlockListTheBssid()6941 public void testBtmFrameWithMboAssocretryDelayBlockListTheBssid() throws Exception { 6942 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 6943 connect(); 6944 6945 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 6946 6947 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 6948 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 6949 | MboOceConstants.BTM_DATA_FLAG_MBO_ASSOC_RETRY_DELAY_INCLUDED; 6950 btmFrmData.mBlockListDurationMs = 60000; 6951 6952 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 6953 mLooper.dispatchAll(); 6954 6955 verify(mWifiMetrics, times(1)).incrementSteeringRequestCountIncludingMboAssocRetryDelay(); 6956 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), any(), 6957 eq(btmFrmData.mBlockListDurationMs), anyInt(), anyInt()); 6958 } 6959 6960 /** 6961 * Test that handleBssTransitionRequest() blocklist the BSS upon 6962 * receiving BTM request frame that contains disassociation imminent bit 6963 * set to 1. 6964 */ 6965 @Test testBtmFrameWithDisassocImminentBitBlockListTheBssid()6966 public void testBtmFrameWithDisassocImminentBitBlockListTheBssid() throws Exception { 6967 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 6968 connect(); 6969 6970 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 6971 6972 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT; 6973 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT; 6974 6975 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 6976 mLooper.dispatchAll(); 6977 6978 verify(mWifiMetrics, never()).incrementSteeringRequestCountIncludingMboAssocRetryDelay(); 6979 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), any(), 6980 eq(MboOceConstants.DEFAULT_BLOCKLIST_DURATION_MS), anyInt(), anyInt()); 6981 } 6982 6983 /** 6984 * Test that handleBssTransitionRequest() trigger force scan for 6985 * network selection when status code is REJECT. 6986 */ 6987 @Test testBTMRequestRejectTriggerNetworkSelction()6988 public void testBTMRequestRejectTriggerNetworkSelction() throws Exception { 6989 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 6990 connect(); 6991 6992 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 6993 6994 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED; 6995 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT 6996 | MboOceConstants.BTM_DATA_FLAG_BSS_TERMINATION_INCLUDED 6997 | MboOceConstants.BTM_DATA_FLAG_MBO_CELL_DATA_CONNECTION_PREFERENCE_INCLUDED; 6998 btmFrmData.mBlockListDurationMs = 60000; 6999 7000 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 7001 mLooper.dispatchAll(); 7002 7003 verify(mWifiBlocklistMonitor, never()).blockBssidForDurationMs(eq(TEST_BSSID_STR), 7004 any(), eq(btmFrmData.mBlockListDurationMs), anyInt(), anyInt()); 7005 verify(mWifiConnectivityManager).forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 7006 verify(mWifiMetrics, times(1)).incrementMboCellularSwitchRequestCount(); 7007 verify(mWifiMetrics, times(1)) 7008 .incrementForceScanCountDueToSteeringRequest(); 7009 7010 } 7011 7012 /** 7013 * Test that handleBssTransitionRequest() does not trigger force 7014 * scan when status code is accept. 7015 */ 7016 @Test testBTMRequestAcceptDoNotTriggerNetworkSelction()7017 public void testBTMRequestAcceptDoNotTriggerNetworkSelction() throws Exception { 7018 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 7019 connect(); 7020 7021 MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData(); 7022 7023 btmFrmData.mStatus = MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT; 7024 btmFrmData.mBssTmDataFlagsMask = MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT; 7025 7026 mCmi.sendMessage(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData); 7027 mLooper.dispatchAll(); 7028 7029 verify(mWifiConnectivityManager, never()) 7030 .forceConnectivityScan(ClientModeImpl.WIFI_WORK_SOURCE); 7031 } 7032 createIE(int id, byte[] bytes)7033 private static ScanResult.InformationElement createIE(int id, byte[] bytes) { 7034 ScanResult.InformationElement ie = new ScanResult.InformationElement(); 7035 ie.id = id; 7036 ie.bytes = bytes; 7037 return ie; 7038 } 7039 7040 /** 7041 * Helper function for setting up fils test. 7042 * 7043 * @param isDriverSupportFils true if driver support fils. 7044 * @return wifi configuration. 7045 */ setupFilsTest(boolean isDriverSupportFils)7046 private WifiConfiguration setupFilsTest(boolean isDriverSupportFils) { 7047 WifiConfiguration config = new WifiConfiguration(); 7048 config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); 7049 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); 7050 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); 7051 config.SSID = ScanResultUtil.createQuotedSsid(sFilsSsid); 7052 config.networkId = 1; 7053 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 7054 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 7055 7056 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config); 7057 if (isDriverSupportFils) { 7058 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 7059 createCapabilityBitset(WifiManager.WIFI_FEATURE_FILS_SHA256, 7060 WifiManager.WIFI_FEATURE_FILS_SHA384)); 7061 } else { 7062 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(new BitSet()); 7063 } 7064 7065 return config; 7066 } 7067 7068 /** 7069 * Helper function for setting up a scan result with FILS supported AP. 7070 * 7071 */ setupFilsEnabledApInScanResult()7072 private void setupFilsEnabledApInScanResult() { 7073 String caps = "[WPA2-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]" 7074 + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP][ESS]"; 7075 ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid), 7076 TEST_BSSID_STR) 7077 .setHessid(1245) 7078 .setCaps(caps) 7079 .setRssi(-78) 7080 .setFrequency(2450) 7081 .setTsf(1025) 7082 .setDistanceCm(22) 7083 .setDistanceSdCm(33) 7084 .setIs80211McRTTResponder(true) 7085 .build(); 7086 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 7087 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 7088 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 7089 when(mScanRequestProxy.getScanResults()).thenReturn(Arrays.asList(scanResult)); 7090 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 7091 } 7092 7093 7094 /** 7095 * Helper function to send CMD_START_FILS_CONNECTION along with HLP IEs. 7096 * 7097 */ prepareFilsHlpPktAndSendStartConnect()7098 private void prepareFilsHlpPktAndSendStartConnect() { 7099 Layer2PacketParcelable l2Packet = new Layer2PacketParcelable(); 7100 l2Packet.dstMacAddress = TEST_GLOBAL_MAC_ADDRESS; 7101 l2Packet.payload = new byte[] {0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 7102 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x55, 0x66}; 7103 mIpClientCallback.onPreconnectionStart(Collections.singletonList(l2Packet)); 7104 mLooper.dispatchAll(); 7105 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 7106 } 7107 7108 /** 7109 * Verifies that while connecting to AP, the logic looks into the scan result and 7110 * looks for AP matching the network type and ssid and update the wificonfig with FILS 7111 * AKM if supported. 7112 * 7113 * @throws Exception 7114 */ 7115 @Test testFilsAKMUpdateBeforeConnect()7116 public void testFilsAKMUpdateBeforeConnect() throws Exception { 7117 initializeAndAddNetworkAndVerifySuccess(); 7118 WifiConfiguration config = setupFilsTest(true); 7119 setupFilsEnabledApInScanResult(); 7120 7121 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7122 mLooper.dispatchAll(); 7123 7124 assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 7125 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 7126 } 7127 7128 /** 7129 * Verifies that while connecting to AP, framework updates the wifi config with 7130 * FILS AKM only if underlying driver support FILS feature. 7131 * 7132 * @throws Exception 7133 */ 7134 @Test testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils()7135 public void testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils() throws Exception { 7136 initializeAndAddNetworkAndVerifySuccess(); 7137 WifiConfiguration config = setupFilsTest(false); 7138 setupFilsEnabledApInScanResult(); 7139 7140 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7141 mLooper.dispatchAll(); 7142 7143 assertFalse(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256)); 7144 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 7145 } 7146 7147 7148 /** 7149 * Verifies that the HLP (DHCP) packets are send to wpa_supplicant 7150 * prior to Fils connection. 7151 * 7152 * @throws Exception 7153 */ 7154 @Test testFilsHlpUpdateBeforeFilsConnection()7155 public void testFilsHlpUpdateBeforeFilsConnection() throws Exception { 7156 initializeAndAddNetworkAndVerifySuccess(); 7157 WifiConfiguration config = setupFilsTest(true); 7158 setupFilsEnabledApInScanResult(); 7159 7160 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7161 mLooper.dispatchAll(); 7162 7163 prepareFilsHlpPktAndSendStartConnect(); 7164 7165 verify(mWifiNative).flushAllHlp(eq(WIFI_IFACE_NAME)); 7166 verify(mWifiNative).addHlpReq(eq(WIFI_IFACE_NAME), any(), any()); 7167 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 7168 } 7169 7170 /** 7171 * Verifies that an association rejection in first FILS connect attempt doesn't block 7172 * the second connection attempt. 7173 * 7174 * @throws Exception 7175 */ 7176 @Test testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject()7177 public void testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject() throws Exception { 7178 initializeAndAddNetworkAndVerifySuccess(); 7179 WifiConfiguration config = setupFilsTest(true); 7180 setupFilsEnabledApInScanResult(); 7181 7182 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7183 mLooper.dispatchAll(); 7184 7185 prepareFilsHlpPktAndSendStartConnect(); 7186 7187 verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 7188 7189 mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 7190 new AssocRejectEventInfo(TEST_SSID, TEST_BSSID_STR, 2, false)); 7191 mLooper.dispatchAll(); 7192 7193 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7194 mLooper.dispatchAll(); 7195 prepareFilsHlpPktAndSendStartConnect(); 7196 7197 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 7198 } 7199 7200 /** 7201 * Verifies Fils connection. 7202 * 7203 * @throws Exception 7204 */ 7205 @Test testFilsConnection()7206 public void testFilsConnection() throws Exception { 7207 initializeAndAddNetworkAndVerifySuccess(); 7208 WifiConfiguration config = setupFilsTest(true); 7209 setupFilsEnabledApInScanResult(); 7210 7211 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7212 mLooper.dispatchAll(); 7213 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 7214 7215 prepareFilsHlpPktAndSendStartConnect(); 7216 7217 verify(mWifiMetrics, times(1)).incrementConnectRequestWithFilsAkmCount(); 7218 7219 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 7220 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, true, null)); 7221 mLooper.dispatchAll(); 7222 7223 verify(mWifiMetrics, times(1)).incrementL2ConnectionThroughFilsAuthCount(); 7224 7225 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 7226 new StateChangeResult(0, WifiSsid.fromUtf8Text(sFilsSsid), 7227 TEST_BSSID_STR, sFreq, SupplicantState.COMPLETED)); 7228 mLooper.dispatchAll(); 7229 7230 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7231 7232 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 7233 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 7234 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 7235 dhcpResults.baseConfiguration.ipAddress = 7236 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 7237 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 7238 dhcpResults.leaseDuration = 3600; 7239 7240 injectDhcpSuccess(dhcpResults); 7241 mLooper.dispatchAll(); 7242 7243 WifiInfo wifiInfo = mWifiInfo; 7244 assertNotNull(wifiInfo); 7245 assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID()); 7246 assertTrue(WifiSsid.fromUtf8Text(sFilsSsid).equals(wifiInfo.getWifiSsid())); 7247 assertEquals("L3ConnectedState", getCurrentState().getName()); 7248 } 7249 7250 /** 7251 * Verifies that while connecting to secondary STA, framework doesn't change the roaming 7252 * configuration. 7253 * @throws Exception 7254 */ 7255 @Test testConnectSecondaryStaNotChangeRoamingConfig()7256 public void testConnectSecondaryStaNotChangeRoamingConfig() throws Exception { 7257 initializeAndAddNetworkAndVerifySuccess(); 7258 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 7259 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7260 mLooper.dispatchAll(); 7261 7262 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(mTestConfig)); 7263 verify(mWifiBlocklistMonitor, never()).setAllowlistSsids(anyString(), any()); 7264 } 7265 7266 /** 7267 * Tests the wifi info is updated correctly for connecting network. 7268 */ 7269 @Test testWifiInfoOnConnectingNextNetwork()7270 public void testWifiInfoOnConnectingNextNetwork() throws Exception { 7271 mConnectedNetwork.ephemeral = true; 7272 mConnectedNetwork.trusted = true; 7273 mConnectedNetwork.oemPaid = true; 7274 mConnectedNetwork.oemPrivate = true; 7275 mConnectedNetwork.carrierMerged = true; 7276 mConnectedNetwork.osu = true; 7277 mConnectedNetwork.subscriptionId = DATA_SUBID; 7278 7279 triggerConnect(); 7280 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 7281 .thenReturn(mScanDetailCache); 7282 7283 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 7284 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 7285 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 7286 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 7287 7288 // before the fist success connection, there is no valid wifi info. 7289 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, mWifiInfo.getNetworkId()); 7290 7291 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 7292 new StateChangeResult(FRAMEWORK_NETWORK_ID, 7293 TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, SupplicantState.ASSOCIATED)); 7294 mLooper.dispatchAll(); 7295 7296 // retrieve correct wifi info on receiving the supplicant state change event. 7297 assertEquals(FRAMEWORK_NETWORK_ID, mWifiInfo.getNetworkId()); 7298 assertEquals(mConnectedNetwork.ephemeral, mWifiInfo.isEphemeral()); 7299 assertEquals(mConnectedNetwork.trusted, mWifiInfo.isTrusted()); 7300 assertEquals(mConnectedNetwork.osu, mWifiInfo.isOsuAp()); 7301 assertEquals(mConnectedNetwork.restricted, mWifiInfo.isRestricted()); 7302 if (SdkLevel.isAtLeastS()) { 7303 assertEquals(mConnectedNetwork.oemPaid, mWifiInfo.isOemPaid()); 7304 assertEquals(mConnectedNetwork.oemPrivate, mWifiInfo.isOemPrivate()); 7305 assertEquals(mConnectedNetwork.carrierMerged, mWifiInfo.isCarrierMerged()); 7306 assertEquals(DATA_SUBID, mWifiInfo.getSubscriptionId()); 7307 } 7308 } 7309 7310 /** 7311 * Verify that we disconnect when we mark a previous unmetered network metered. 7312 */ 7313 @Test verifyDisconnectOnMarkingNetworkMetered()7314 public void verifyDisconnectOnMarkingNetworkMetered() throws Exception { 7315 connect(); 7316 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7317 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7318 }); 7319 7320 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7321 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 7322 7323 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7324 .getAllValues()) { 7325 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7326 } 7327 mLooper.dispatchAll(); 7328 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7329 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 7330 eq(StaEvent.DISCONNECT_NETWORK_METERED)); 7331 } 7332 7333 /** 7334 * Verify that we only update capabilites when we mark a previous unmetered network metered. 7335 */ 7336 @Test verifyUpdateCapabilitiesOnMarkingNetworkUnmetered()7337 public void verifyUpdateCapabilitiesOnMarkingNetworkUnmetered() throws Exception { 7338 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 7339 connect(); 7340 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7341 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7342 }); 7343 reset(mWifiNetworkAgent); 7344 7345 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7346 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 7347 7348 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7349 .getAllValues()) { 7350 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7351 } 7352 mLooper.dispatchAll(); 7353 assertEquals("L3ConnectedState", getCurrentState().getName()); 7354 7355 expectNetworkAgentUpdateCapabilities((cap) -> { 7356 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7357 }); 7358 } 7359 7360 7361 /** 7362 * Verify that we disconnect when we mark a previous unmetered network metered. 7363 */ 7364 @Test verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint()7365 public void verifyDisconnectOnMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 7366 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 7367 connect(); 7368 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7369 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7370 }); 7371 reset(mWifiNetworkAgent); 7372 7373 // Mark network metered none. 7374 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7375 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 7376 7377 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 7378 WifiInfo wifiInfo = mWifiInfo; 7379 wifiInfo.setMeteredHint(true); 7380 7381 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7382 .getAllValues()) { 7383 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7384 } 7385 mLooper.dispatchAll(); 7386 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7387 } 7388 7389 /** 7390 * Verify that we only update capabilites when we mark a previous unmetered network metered. 7391 */ 7392 @Test verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint()7393 public void verifyUpdateCapabilitiesOnMarkingNetworkAutoMeteredWithoutMeteredHint() 7394 throws Exception { 7395 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 7396 connect(); 7397 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7398 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7399 }); 7400 reset(mWifiNetworkAgent); 7401 7402 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7403 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 7404 7405 // Reset metered hint in WifiInfo. 7406 WifiInfo wifiInfo = mWifiInfo; 7407 wifiInfo.setMeteredHint(false); 7408 7409 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7410 .getAllValues()) { 7411 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7412 } 7413 mLooper.dispatchAll(); 7414 assertEquals("L3ConnectedState", getCurrentState().getName()); 7415 7416 expectNetworkAgentUpdateCapabilities((cap) -> { 7417 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7418 }); 7419 } 7420 7421 /** 7422 * Verify that we do nothing on no metered change. 7423 */ 7424 @Test verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint()7425 public void verifyDoNothingMarkingNetworkAutoMeteredWithMeteredHint() throws Exception { 7426 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED; 7427 connect(); 7428 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7429 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7430 }); 7431 reset(mWifiNetworkAgent); 7432 7433 // Mark network metered none. 7434 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7435 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 7436 7437 // Set metered hint in WifiInfo (either via DHCP or ScanResult IE). 7438 WifiInfo wifiInfo = mWifiInfo; 7439 wifiInfo.setMeteredHint(true); 7440 7441 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7442 .getAllValues()) { 7443 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7444 } 7445 mLooper.dispatchAll(); 7446 assertEquals("L3ConnectedState", getCurrentState().getName()); 7447 7448 verifyNoMoreInteractions(mWifiNetworkAgent); 7449 } 7450 7451 /** 7452 * Verify that we do nothing on no metered change. 7453 */ 7454 @Test verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint()7455 public void verifyDoNothingMarkingNetworkAutoMeteredWithoutMeteredHint() throws Exception { 7456 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED; 7457 connect(); 7458 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 7459 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 7460 }); 7461 reset(mWifiNetworkAgent); 7462 7463 // Mark network metered none. 7464 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7465 mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NONE; 7466 7467 // Reset metered hint in WifiInfo. 7468 WifiInfo wifiInfo = mWifiInfo; 7469 wifiInfo.setMeteredHint(false); 7470 7471 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7472 .getAllValues()) { 7473 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 7474 } 7475 mLooper.dispatchAll(); 7476 assertEquals("L3ConnectedState", getCurrentState().getName()); 7477 7478 verifyNoMoreInteractions(mWifiNetworkAgent); 7479 } 7480 7481 /* 7482 * Verify that network cached data is cleared correctly in 7483 * disconnected state. 7484 */ 7485 @Test testNetworkCachedDataIsClearedCorrectlyInDisconnectedState()7486 public void testNetworkCachedDataIsClearedCorrectlyInDisconnectedState() throws Exception { 7487 // Setup CONNECT_MODE & a WifiConfiguration 7488 initializeAndAddNetworkAndVerifySuccess(); 7489 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7490 mLooper.dispatchAll(); 7491 7492 // got UNSPECIFIED during this connection attempt 7493 DisconnectEventInfo disconnectEventInfo = 7494 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 1, false); 7495 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7496 mLooper.dispatchAll(); 7497 7498 assertEquals("DisconnectedState", getCurrentState().getName()); 7499 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 7500 7501 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 7502 mLooper.dispatchAll(); 7503 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 7504 disconnectEventInfo = new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 7505 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7506 mLooper.dispatchAll(); 7507 7508 assertEquals("DisconnectedState", getCurrentState().getName()); 7509 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 7510 } 7511 7512 /* 7513 * Verify that network cached data is cleared correctly in 7514 * disconnected state. 7515 */ 7516 @Test testNetworkCachedDataIsClearedCorrectlyInL3ProvisioningState()7517 public void testNetworkCachedDataIsClearedCorrectlyInL3ProvisioningState() throws Exception { 7518 initializeAndAddNetworkAndVerifySuccess(); 7519 7520 verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME); 7521 7522 startConnectSuccess(); 7523 7524 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 7525 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 7526 mLooper.dispatchAll(); 7527 7528 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 7529 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 7530 SupplicantState.COMPLETED)); 7531 mLooper.dispatchAll(); 7532 7533 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7534 7535 // got 4WAY_HANDSHAKE_TIMEOUT during this connection attempt 7536 DisconnectEventInfo disconnectEventInfo = 7537 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 7538 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7539 mLooper.dispatchAll(); 7540 7541 verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID); 7542 } 7543 7544 /* 7545 * Verify that network cached data is NOT cleared in L3ConnectedState. 7546 */ 7547 @Test testNetworkCachedDataIsClearedIf4WayHandshakeFailure()7548 public void testNetworkCachedDataIsClearedIf4WayHandshakeFailure() throws Exception { 7549 when(mWifiScoreCard.detectAbnormalDisconnection(any())) 7550 .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL); 7551 InOrder inOrderWifiLockManager = inOrder(mWifiLockManager); 7552 connect(); 7553 inOrderWifiLockManager.verify(mWifiLockManager) 7554 .updateWifiClientConnected(mClientModeManager, true); 7555 7556 // got 4WAY_HANDSHAKE_TIMEOUT 7557 DisconnectEventInfo disconnectEventInfo = 7558 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 15, false); 7559 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7560 mLooper.dispatchAll(); 7561 verify(mWifiNative, never()).removeNetworkCachedData(anyInt()); 7562 } 7563 7564 /** 7565 * Verify that network cached data is cleared on changing the credential. 7566 */ 7567 @Test testNetworkCachedDataIsClearedOnChangingTheCredential()7568 public void testNetworkCachedDataIsClearedOnChangingTheCredential() throws Exception { 7569 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 7570 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 7571 mConnectedNetwork.enterpriseConfig.setPassword("fakePassword"); 7572 7573 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 7574 .getAllValues()) { 7575 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, true); 7576 } 7577 mLooper.dispatchAll(); 7578 verify(mWifiNative).removeNetworkCachedData(eq(oldConfig.networkId)); 7579 } 7580 7581 7582 @Test testVerifyWifiInfoStateOnFrameworkDisconnect()7583 public void testVerifyWifiInfoStateOnFrameworkDisconnect() throws Exception { 7584 connect(); 7585 7586 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.COMPLETED); 7587 7588 // Now trigger disconnect 7589 mCmi.disconnect(); 7590 mLooper.dispatchAll(); 7591 7592 // get disconnect event 7593 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 7594 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 7595 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 7596 mLooper.dispatchAll(); 7597 7598 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.DISCONNECTED); 7599 } 7600 7601 @Test testVerifyWifiInfoStateOnFrameworkDisconnectButMissingDisconnectEvent()7602 public void testVerifyWifiInfoStateOnFrameworkDisconnectButMissingDisconnectEvent() 7603 throws Exception { 7604 connect(); 7605 7606 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.COMPLETED); 7607 7608 // Now trigger disconnect 7609 mCmi.disconnect(); 7610 mLooper.dispatchAll(); 7611 7612 // missing disconnect event, but got supplicant state change with disconnect state instead. 7613 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 7614 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 7615 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 7616 mLooper.dispatchAll(); 7617 7618 assertEquals(mWifiInfo.getSupplicantState(), SupplicantState.DISCONNECTED); 7619 } 7620 7621 /** 7622 * Ensures that we only disable the current network & set MAC address only when we exit 7623 * ConnectingState. 7624 * @throws Exception 7625 */ 7626 @Test testDisableNetworkOnExitingConnectingOrConnectedState()7627 public void testDisableNetworkOnExitingConnectingOrConnectedState() throws Exception { 7628 connect(); 7629 String oldSsid = mConnectedNetwork.SSID; 7630 7631 // Trigger connection to a different network 7632 mConnectedNetwork.SSID = "\"" + oldSsid.concat("blah") + "\""; 7633 mConnectedNetwork.networkId++; 7634 mConnectedNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; 7635 setupAndStartConnectSequence(mConnectedNetwork); 7636 7637 // Send disconnect event for the old network. 7638 DisconnectEventInfo disconnectEventInfo = 7639 new DisconnectEventInfo(oldSsid, TEST_BSSID_STR, 0, false); 7640 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7641 mLooper.dispatchAll(); 7642 7643 assertEquals("L2ConnectingState", getCurrentState().getName()); 7644 // Since we remain in connecting state, we should not disable the network or set random MAC 7645 // address on disconnect. 7646 verify(mWifiNative, never()).disableNetwork(WIFI_IFACE_NAME); 7647 // Set MAC address thrice - once at bootup, twice for the 2 connections. 7648 verify(mWifiNative, times(3)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 7649 7650 // Send disconnect event for the new network. 7651 disconnectEventInfo = 7652 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 7653 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 7654 mLooper.dispatchAll(); 7655 7656 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 7657 // Set MAC address thrice - once at bootup, twice for the connections, 7658 // once for the disconnect. 7659 verify(mWifiNative, times(4)).setStaMacAddress(eq(WIFI_IFACE_NAME), any()); 7660 } 7661 7662 @Test testIpReachabilityFailureConfirmTriggersDisconnection()7663 public void testIpReachabilityFailureConfirmTriggersDisconnection() throws Exception { 7664 assumeTrue(SdkLevel.isAtLeastT()); 7665 connect(); 7666 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7667 reset(mWifiNetworkAgent); 7668 7669 // normal behavior w/o overlay 7670 when(mWifiGlobals.disableNudDisconnectsForWapiInSpecificCc()).thenReturn(false); 7671 when(mWifiCountryCode.getCountryCode()).thenReturn("CN"); 7672 7673 // Trigger ip reachability failure and ensure we trigger a disconnect. 7674 ReachabilityLossInfoParcelable lossInfo = 7675 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.CONFIRM); 7676 mIpClientCallback.onReachabilityFailure(lossInfo); 7677 mLooper.dispatchAll(); 7678 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7679 } 7680 7681 @Test testIpReachabilityFailureConfirmDoesNotTriggersDisconnectionForWapi()7682 public void testIpReachabilityFailureConfirmDoesNotTriggersDisconnectionForWapi() 7683 throws Exception { 7684 mConnectedNetwork = spy(WifiConfigurationTestUtil.createWapiPskNetwork()); 7685 7686 assumeTrue(SdkLevel.isAtLeastT()); 7687 connect(); 7688 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7689 reset(mWifiNetworkAgent); 7690 7691 when(mWifiGlobals.disableNudDisconnectsForWapiInSpecificCc()).thenReturn(true); 7692 when(mWifiCountryCode.getCountryCode()).thenReturn("CN"); 7693 7694 // Trigger ip reachability failure and ensure we trigger a disconnect. 7695 ReachabilityLossInfoParcelable lossInfo = 7696 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.CONFIRM); 7697 mIpClientCallback.onReachabilityFailure(lossInfo); 7698 mLooper.dispatchAll(); 7699 if (SdkLevel.isAtLeastV()) { 7700 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7701 } else { 7702 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7703 } 7704 } 7705 7706 @Test testIpReachabilityMonitorNotStartOnStaticIpConfiguration()7707 public void testIpReachabilityMonitorNotStartOnStaticIpConfiguration() throws Exception { 7708 final List<InetAddress> dnsServers = new ArrayList<>(); 7709 dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 7710 dnsServers.add(InetAddresses.parseNumericAddress("4.4.4.4")); 7711 final StaticIpConfiguration staticIpConfig = 7712 new StaticIpConfiguration.Builder() 7713 .setIpAddress(new LinkAddress("192.0.2.2/25")) 7714 .setGateway(InetAddresses.parseNumericAddress("192.0.2.1")) 7715 .setDnsServers(dnsServers) 7716 .build(); 7717 final IpConfiguration ipConfig = new IpConfiguration(); 7718 ipConfig.setStaticIpConfiguration(staticIpConfig); 7719 ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); 7720 mConnectedNetwork.setIpConfiguration(ipConfig); 7721 7722 triggerConnect(); 7723 validateConnectionInfo(); 7724 7725 // Simulate L2 connection. 7726 final WifiSsid wifiSsid = 7727 WifiSsid.fromBytes( 7728 NativeUtil.byteArrayFromArrayList( 7729 NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 7730 mCmi.sendMessage( 7731 WifiMonitor.NETWORK_CONNECTION_EVENT, 7732 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 7733 mLooper.dispatchAll(); 7734 7735 // Simulate L3 connection. 7736 final DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 7737 dhcpResults.baseConfiguration = staticIpConfig; 7738 injectDhcpSuccess(dhcpResults); 7739 mLooper.dispatchAll(); 7740 expectRegisterNetworkAgent((agentConfig) -> {}, (cap) -> {}); 7741 7742 verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture()); 7743 assertFalse(mProvisioningConfigurationCaptor.getValue().usingIpReachabilityMonitor); 7744 } 7745 doIpReachabilityFailureTest(int lossReason, boolean shouldWifiDisconnect)7746 private void doIpReachabilityFailureTest(int lossReason, boolean shouldWifiDisconnect) 7747 throws Exception { 7748 assumeTrue(SdkLevel.isAtLeastU()); 7749 connect(); 7750 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7751 reset(mWifiNetworkAgent); 7752 7753 // Trigger ip reachability failure from cmd_confirm or organic kernel probe and ensure 7754 // wifi never disconnects and eventually state machine transits to L3ProvisioningState 7755 // on U and above, but wifi should still disconnect on previous platforms. 7756 ReachabilityLossInfoParcelable lossInfo = 7757 new ReachabilityLossInfoParcelable("", lossReason); 7758 mIpClientCallback.onReachabilityFailure(lossInfo); 7759 mLooper.dispatchAll(); 7760 if (!shouldWifiDisconnect) { 7761 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7762 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7763 } else { 7764 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7765 } 7766 } 7767 7768 @Test testIpReachabilityFailureConfirm_enableHandleRssiOrganicKernelFailuresFlag()7769 public void testIpReachabilityFailureConfirm_enableHandleRssiOrganicKernelFailuresFlag() 7770 throws Exception { 7771 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 7772 7773 doIpReachabilityFailureTest(ReachabilityLossReason.CONFIRM, 7774 false /* shouldWifiDisconnect */); 7775 } 7776 7777 @Test testIpReachabilityFailureConfirm_disableHandleRssiOrganicKernelFailuresFlag()7778 public void testIpReachabilityFailureConfirm_disableHandleRssiOrganicKernelFailuresFlag() 7779 throws Exception { 7780 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(false); 7781 7782 // should still disconnect in following scenario 7783 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPskNetwork()); 7784 when(mWifiGlobals.disableNudDisconnectsForWapiInSpecificCc()).thenReturn(true); 7785 when(mWifiCountryCode.getCurrentDriverCountryCode()).thenReturn("CN"); 7786 7787 doIpReachabilityFailureTest(ReachabilityLossReason.CONFIRM, 7788 true /* shouldWifiDisconnect */); 7789 } 7790 7791 @Test testIpReachabilityFailureOrganicTriggersDisconnection()7792 public void testIpReachabilityFailureOrganicTriggersDisconnection() throws Exception { 7793 assumeTrue(SdkLevel.isAtLeastT()); 7794 connect(); 7795 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7796 reset(mWifiNetworkAgent); 7797 7798 // Trigger ip reachability failure and ensure we trigger a disconnect. 7799 ReachabilityLossInfoParcelable lossInfo = 7800 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC); 7801 mIpClientCallback.onReachabilityFailure(lossInfo); 7802 mLooper.dispatchAll(); 7803 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7804 } 7805 7806 /** 7807 * Verify that when HandleRssiOrganicKernelFailuresEnabled, multiple IP reachability failures 7808 * within a specified time window will lead to disconnect and network disabled. 7809 */ 7810 @Test testRepeatedIpReachabilityFailureDisableNetwork()7811 public void testRepeatedIpReachabilityFailureDisableNetwork() throws Exception { 7812 assumeTrue(SdkLevel.isAtLeastU()); 7813 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 7814 int failureThreshold = 5; 7815 int failureWindowMs = 60000; 7816 when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(failureThreshold); 7817 when(mWifiGlobals.getRepeatedNudFailuresWindowMs()).thenReturn(failureWindowMs); 7818 when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); 7819 7820 connect(); 7821 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7822 reset(mWifiNetworkAgent); 7823 7824 for (int i = 0; i < failureThreshold; i++) { 7825 // increment time outside the failure window. Failure counter should never add up and 7826 // thus not trigger blocking. 7827 when(mClock.getElapsedSinceBootMillis()).thenReturn( 7828 (long) (i + 1) * (failureWindowMs + 1)); 7829 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7830 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(), 7831 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES)); 7832 ReachabilityLossInfoParcelable lossInfo = 7833 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC); 7834 mIpClientCallback.onReachabilityFailure(lossInfo); 7835 mLooper.dispatchAll(); 7836 } 7837 7838 // Now trigger NUD failure within the failure window and verify the network is blocked. 7839 for (int i = 0; i < failureThreshold - 1; i++) { 7840 when(mClock.getElapsedSinceBootMillis()).thenReturn( 7841 (long) (i + failureThreshold + 1) * (failureWindowMs)); 7842 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7843 verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(), 7844 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES)); 7845 ReachabilityLossInfoParcelable lossInfo = 7846 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC); 7847 mIpClientCallback.onReachabilityFailure(lossInfo); 7848 mLooper.dispatchAll(); 7849 } 7850 7851 // Should disconnect and block network after the last iteration. 7852 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 7853 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES)); 7854 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7855 } 7856 7857 @Test testIpReachabilityFailureOrganic_enableHandleRssiOrganicKernelFailuresFlag()7858 public void testIpReachabilityFailureOrganic_enableHandleRssiOrganicKernelFailuresFlag() 7859 throws Exception { 7860 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 7861 7862 doIpReachabilityFailureTest(ReachabilityLossReason.ORGANIC, 7863 false /* shouldWifiDisconnect */); 7864 } 7865 7866 @Test testIpReachabilityFailureOrganic_disableHandleRssiOrganicKernelFailuresFlag()7867 public void testIpReachabilityFailureOrganic_disableHandleRssiOrganicKernelFailuresFlag() 7868 throws Exception { 7869 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(false); 7870 7871 doIpReachabilityFailureTest(ReachabilityLossReason.ORGANIC, 7872 true /* shouldWifiDisconnect */); 7873 } 7874 7875 @Test testIpReachabilityFailureRoamWithNullConfigDisconnect()7876 public void testIpReachabilityFailureRoamWithNullConfigDisconnect() throws Exception { 7877 assumeTrue(SdkLevel.isAtLeastT()); 7878 connect(); 7879 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7880 reset(mWifiNetworkAgent); 7881 7882 // mock the current network as removed 7883 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 7884 7885 // Trigger ip reachability failure and ensure we disconnect. 7886 ReachabilityLossInfoParcelable lossInfo = 7887 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ROAM); 7888 mIpClientCallback.onReachabilityFailure(lossInfo); 7889 mLooper.dispatchAll(); 7890 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7891 } 7892 7893 @Test testIpReachabilityFailureRoamL3ProvisioningState()7894 public void testIpReachabilityFailureRoamL3ProvisioningState() throws Exception { 7895 assumeTrue(SdkLevel.isAtLeastT()); 7896 connect(); 7897 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7898 reset(mWifiNetworkAgent); 7899 7900 // Trigger ip reachability failure and ensure we do not trigger a disconnect. 7901 ReachabilityLossInfoParcelable lossInfo = 7902 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ROAM); 7903 mIpClientCallback.onReachabilityFailure(lossInfo); 7904 mLooper.dispatchAll(); 7905 verify(mWifiNetworkAgent).unregisterAfterReplacement(anyInt()); 7906 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7907 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7908 } 7909 7910 @Test testIpReachabilityFailureRoamL3ProvisioningState_recreateIpClient()7911 public void testIpReachabilityFailureRoamL3ProvisioningState_recreateIpClient() 7912 throws Exception { 7913 assumeTrue(SdkLevel.isAtLeastT()); 7914 connect(); 7915 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7916 reset(mWifiNetworkAgent); 7917 7918 // Save current IpClientCallbacks instance and verify the onProvisioningFailure 7919 // from this instance won't trigger wifi disconnection after recreating a new 7920 // IpClient and IpClientCallbacks in WaitBeforeL3ProvisioningState. 7921 final IpClientCallbacks callback = mIpClientCallback; 7922 7923 // Trigger ip reachability failure and ensure we do not trigger a disconnect. 7924 ReachabilityLossInfoParcelable lossInfo = 7925 new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ROAM); 7926 callback.onReachabilityFailure(lossInfo); 7927 mLooper.dispatchAll(); 7928 verify(mWifiNetworkAgent).unregisterAfterReplacement(anyInt()); 7929 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7930 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7931 7932 // Verify that onProvisioningFailure from the legacy IpClientCallbacks instance 7933 // doesn't trigger wifi disconnection. 7934 callback.onProvisioningFailure(new LinkProperties()); 7935 mLooper.dispatchAll(); 7936 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7937 7938 // Verify that onProvisioningFailure from the current IpClientCallbacks instance 7939 // triggers wifi disconnection. 7940 mIpClientCallback.onProvisioningFailure(new LinkProperties()); 7941 mLooper.dispatchAll(); 7942 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7943 } 7944 runProvisioningFailureCalledAfterReachabilityFailureTest(int lossReason)7945 private void runProvisioningFailureCalledAfterReachabilityFailureTest(int lossReason) 7946 throws Exception { 7947 assumeTrue(SdkLevel.isAtLeastT()); 7948 connect(); 7949 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 7950 reset(mWifiNetworkAgent); 7951 7952 // Save current IpClientCallbacks instance and verify an immediate IP provisioning 7953 // failure event from this instance after IP reachability failure still triggers a 7954 // WiFi disconnection due to the race, for example: 7955 // - IpClient sends onReachabilityFailure callback, wifi module receives this callback 7956 // and post CMD_IP_REACHABILITY_FAILURE, return; 7957 // - IpClient sends onProvisioningFailure callback, wifi module receives this callback 7958 // and post CMD_IP_CONFIGURATION_LOST, return; 7959 // - state machine processes CMD_IP_REACHABILITY_FAILURE first and eventually transition 7960 // to WaitBeforeL3ProvisioningState and recreate an IpClient instance there. 7961 // - state machine receives CMD_IP_CONFIGURATION_LOST from the old IpClientCallbacks 7962 // instanceat at WaitBeforeL3ProvisioningState, but defer the command to its parent state 7963 // until transition to L3ProvisioningState. 7964 // - CMD_IP_CONFIGURATION_LOST is processed at L2ConnectedState eventually, and trigger 7965 // WiFi disconnection there. 7966 final IpClientCallbacks callback = mIpClientCallback; 7967 final ReachabilityLossInfoParcelable lossInfo = 7968 new ReachabilityLossInfoParcelable("", lossReason); 7969 assertNull(mCmi.getConnectingWifiConfiguration()); 7970 callback.onReachabilityFailure(lossInfo); 7971 callback.onProvisioningFailure(new LinkProperties()); 7972 mLooper.dispatchAll(); 7973 verify(mWifiNetworkAgent).unregisterAfterReplacement(anyInt()); 7974 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 7975 assertEquals("L3ProvisioningState", getCurrentState().getName()); 7976 assertEquals(FRAMEWORK_NETWORK_ID, mCmi.getConnectingWifiConfiguration().networkId); 7977 7978 // Verify that onProvisioningFailure from the current IpClientCallbacks instance 7979 // triggers wifi disconnection. 7980 mIpClientCallback.onProvisioningFailure(new LinkProperties()); 7981 mLooper.dispatchAll(); 7982 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 7983 } 7984 7985 @Test testProvisioningFailureCalledAfterReachabilityFailure_postRoam()7986 public void testProvisioningFailureCalledAfterReachabilityFailure_postRoam() 7987 throws Exception { 7988 runProvisioningFailureCalledAfterReachabilityFailureTest(ReachabilityLossReason.ROAM); 7989 } 7990 7991 @Test testProvisioningFailureCalledAfterReachabilityFailure_rssiConfirm()7992 public void testProvisioningFailureCalledAfterReachabilityFailure_rssiConfirm() 7993 throws Exception { 7994 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 7995 7996 runProvisioningFailureCalledAfterReachabilityFailureTest(ReachabilityLossReason.CONFIRM); 7997 } 7998 7999 @Test testProvisioningFailureCalledAfterReachabilityFailure_organicKernel()8000 public void testProvisioningFailureCalledAfterReachabilityFailure_organicKernel() 8001 throws Exception { 8002 when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true); 8003 8004 runProvisioningFailureCalledAfterReachabilityFailureTest(ReachabilityLossReason.ORGANIC); 8005 } 8006 8007 @Test testIpReachabilityLostAndRoamEventsRace()8008 public void testIpReachabilityLostAndRoamEventsRace() throws Exception { 8009 connect(); 8010 expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { }); 8011 reset(mWifiNetworkAgent); 8012 8013 // Trigger ip reachability loss and ensure we trigger a disconnect. 8014 mIpClientCallback.onReachabilityLost("CMD_IP_REACHABILITY_LOST"); 8015 mLooper.dispatchAll(); 8016 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 8017 8018 // Now send a network connection (indicating a roam) event before we get the disconnect 8019 // event. 8020 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8021 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 8022 mLooper.dispatchAll(); 8023 // ensure that we ignored the transient roam while we're disconnecting. 8024 verifyNoMoreInteractions(mWifiNetworkAgent); 8025 8026 // Now send the disconnect event and ensure that we transition to "DisconnectedState". 8027 DisconnectEventInfo disconnectEventInfo = 8028 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 8029 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 8030 mLooper.dispatchAll(); 8031 assertEquals("DisconnectedState", getCurrentState().getName()); 8032 verify(mWifiNetworkAgent).unregister(); 8033 8034 verifyNoMoreInteractions(mWifiNetworkAgent); 8035 } 8036 8037 /** 8038 * Verify that roaming mode is enabled on disconnect for primary. 8039 */ 8040 @Test testRoamingModeOnDisconnectPrimary()8041 public void testRoamingModeOnDisconnectPrimary() throws Exception { 8042 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 8043 connect(); 8044 mCmi.disconnect(); 8045 mLooper.dispatchAll(); 8046 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8047 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 8048 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 8049 mLooper.dispatchAll(); 8050 verify(mWifiNative).enableFirmwareRoaming(anyString(), 8051 eq(WifiNative.ENABLE_FIRMWARE_ROAMING)); 8052 } 8053 8054 /** 8055 * Verify that roaming mode doesn't change on disconnect for secondary. 8056 */ 8057 @Test testRoamingModeOnDisconnectSecondary()8058 public void testRoamingModeOnDisconnectSecondary() throws Exception { 8059 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 8060 connect(); 8061 mCmi.disconnect(); 8062 mLooper.dispatchAll(); 8063 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8064 new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID), 8065 TEST_BSSID_STR, sFreq, SupplicantState.DISCONNECTED)); 8066 mLooper.dispatchAll(); 8067 verify(mWifiNative, never()).enableFirmwareRoaming(anyString(), anyInt()); 8068 } 8069 8070 @Test testConnectionWhileDisconnecting()8071 public void testConnectionWhileDisconnecting() throws Exception { 8072 connect(); 8073 8074 // Trigger a disconnect event. 8075 mCmi.disconnect(); 8076 mLooper.dispatchAll(); 8077 assertEquals("L3ConnectedState", getCurrentState().getName()); 8078 8079 // Trigger a new connection before the NETWORK_DISCONNECTION_EVENT comes in. 8080 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 8081 config.networkId = FRAMEWORK_NETWORK_ID + 1; 8082 setupAndStartConnectSequence(config); 8083 // Ensure that we triggered the connection attempt. 8084 validateSuccessfulConnectSequence(config); 8085 8086 // Now trigger the disconnect event for the previous disconnect and ensure we handle it 8087 // correctly and remain in ConnectingState. 8088 DisconnectEventInfo disconnectEventInfo = 8089 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 8090 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 8091 mLooper.dispatchAll(); 8092 assertEquals("L2ConnectingState", mCmi.getCurrentState().getName()); 8093 } 8094 8095 @Test testConnectionWatchdog()8096 public void testConnectionWatchdog() throws Exception { 8097 triggerConnect(); 8098 Log.i(TAG, "Triggering Connect done"); 8099 8100 // Simulate watchdog timeout and ensure we retuned to disconnected state. 8101 mLooper.moveTimeForward(ClientModeImpl.CONNECTING_WATCHDOG_TIMEOUT_MS + 5L); 8102 mLooper.dispatchAll(); 8103 8104 verify(mWifiNative).disableNetwork(WIFI_IFACE_NAME); 8105 assertEquals("DisconnectedState", mCmi.getCurrentState().getName()); 8106 } 8107 8108 @Test testRoamAfterConnectDoesNotChangeNetworkInfoInNetworkStateChangeBroadcast()8109 public void testRoamAfterConnectDoesNotChangeNetworkInfoInNetworkStateChangeBroadcast() 8110 throws Exception { 8111 connect(); 8112 8113 // The last NETWORK_STATE_CHANGED_ACTION should be to mark the network connected. 8114 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 8115 8116 verifyNetworkStateChangedBroadcast(atLeastOnce(), intentCaptor); 8117 Intent intent = intentCaptor.getValue(); 8118 assertNotNull(intent); 8119 assertEquals(WifiManager.NETWORK_STATE_CHANGED_ACTION, intent.getAction()); 8120 NetworkInfo networkInfo = (NetworkInfo) intent.getExtra(WifiManager.EXTRA_NETWORK_INFO); 8121 assertTrue(networkInfo.isConnected()); 8122 8123 reset(mContext); 8124 when(mContext.getResources()).thenReturn(mResources); 8125 when(mContext.createContextAsUser(UserHandle.ALL, 0)).thenReturn(mUserAllContext); 8126 8127 // send roam event 8128 mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, TEST_BSSID_STR1); 8129 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8130 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 8131 SupplicantState.COMPLETED)); 8132 mLooper.dispatchAll(); 8133 8134 verifyNetworkStateChangedBroadcast(atLeastOnce(), intentCaptor); 8135 intent = intentCaptor.getValue(); 8136 assertNotNull(intent); 8137 assertEquals(WifiManager.NETWORK_STATE_CHANGED_ACTION, intent.getAction()); 8138 networkInfo = (NetworkInfo) intent.getExtra(WifiManager.EXTRA_NETWORK_INFO); 8139 assertTrue(networkInfo.isConnected()); 8140 } 8141 8142 8143 /** 8144 * Ensure that {@link ClientModeImpl#dump(FileDescriptor, PrintWriter, String[])} 8145 * {@link WifiNative#getWifiLinkLayerStats(String)}, at least once before calling 8146 * {@link WifiScoreReport#dump(FileDescriptor, PrintWriter, String[])}. 8147 * 8148 * This ensures that WifiScoreReport will always get updated RSSI and link layer stats before 8149 * dumping during a bug report, no matter if the screen is on or not. 8150 */ 8151 @Test testWifiScoreReportDump()8152 public void testWifiScoreReportDump() throws Exception { 8153 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 8154 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 8155 InOrder inOrder = inOrder(mWifiNative, mWifiScoreReport); 8156 inOrder.verify(mWifiNative, never()).getWifiLinkLayerStats(any()); 8157 connect(); 8158 8159 mCmi.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null); 8160 mLooper.dispatchAll(); 8161 8162 inOrder.verify(mWifiNative, atLeastOnce()).getWifiLinkLayerStats(any()); 8163 inOrder.verify(mWifiScoreReport).dump(any(), any(), any()); 8164 } 8165 8166 @Test testHandleScreenChangedDontUpdateLinkLayerStatsWhenDisconnected()8167 public void testHandleScreenChangedDontUpdateLinkLayerStatsWhenDisconnected() { 8168 setScreenState(true); 8169 setScreenState(false); 8170 setScreenState(true); 8171 verify(mWifiNative, never()).getWifiLinkLayerStats(any()); 8172 } 8173 8174 @Test clearRequestingPackageNameInWifiInfoOnConnectionFailure()8175 public void clearRequestingPackageNameInWifiInfoOnConnectionFailure() throws Exception { 8176 mConnectedNetwork.fromWifiNetworkSpecifier = true; 8177 mConnectedNetwork.ephemeral = true; 8178 mConnectedNetwork.creatorName = OP_PACKAGE_NAME; 8179 8180 triggerConnect(); 8181 8182 // association completed 8183 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8184 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 8185 SupplicantState.ASSOCIATED)); 8186 mLooper.dispatchAll(); 8187 8188 assertTrue(mWifiInfo.isEphemeral()); 8189 assertEquals(OP_PACKAGE_NAME, mWifiInfo.getRequestingPackageName()); 8190 8191 // fail the connection. 8192 DisconnectEventInfo disconnectEventInfo = 8193 new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false); 8194 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 8195 mLooper.dispatchAll(); 8196 8197 assertFalse(mWifiInfo.isEphemeral()); 8198 assertNull(mWifiInfo.getRequestingPackageName()); 8199 } 8200 8201 @Test handleAssociationRejectionWhenRoaming()8202 public void handleAssociationRejectionWhenRoaming() throws Exception { 8203 connect(); 8204 8205 assertTrue(SupplicantState.isConnecting(mWifiInfo.getSupplicantState())); 8206 8207 when(mWifiNative.roamToNetwork(any(), any())).thenReturn(true); 8208 8209 // Trigger roam to a BSSID. 8210 mCmi.startRoamToNetwork(FRAMEWORK_NETWORK_ID, TEST_BSSID_STR1); 8211 mLooper.dispatchAll(); 8212 8213 8214 assertEquals(TEST_BSSID_STR1, mCmi.getConnectingBssid()); 8215 assertEquals(FRAMEWORK_NETWORK_ID, mCmi.getConnectingWifiConfiguration().networkId); 8216 8217 verify(mWifiNative).roamToNetwork(any(), any()); 8218 assertEquals("RoamingState", getCurrentState().getName()); 8219 8220 // fail the connection. 8221 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8222 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, 0, 8223 SupplicantState.DISCONNECTED)); 8224 mLooper.dispatchAll(); 8225 8226 // Ensure we reset WifiInfo fields. 8227 assertFalse(SupplicantState.isConnecting(mWifiInfo.getSupplicantState())); 8228 } 8229 8230 @Test testOemPaidNetworkCapability()8231 public void testOemPaidNetworkCapability() throws Exception { 8232 // oemPaid introduced in S, not applicable to R 8233 assumeTrue(SdkLevel.isAtLeastS()); 8234 mConnectedNetwork.oemPaid = true; 8235 connect(); 8236 expectRegisterNetworkAgent((agentConfig) -> { }, 8237 (cap) -> { 8238 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)); 8239 assertFalse(cap.hasCapability(NetworkCapabilities 8240 .NET_CAPABILITY_NOT_RESTRICTED)); 8241 }); 8242 } 8243 @Test testNotOemPaidNetworkCapability()8244 public void testNotOemPaidNetworkCapability() throws Exception { 8245 // oemPaid introduced in S, not applicable to R 8246 assumeTrue(SdkLevel.isAtLeastS()); 8247 mConnectedNetwork.oemPaid = false; 8248 connect(); 8249 expectRegisterNetworkAgent((agentConfig) -> { }, 8250 (cap) -> { 8251 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)); 8252 assertTrue(cap.hasCapability(NetworkCapabilities 8253 .NET_CAPABILITY_NOT_RESTRICTED)); 8254 }); 8255 } 8256 8257 @Test testRestrictedetworkCapability()8258 public void testRestrictedetworkCapability() throws Exception { 8259 // oemPaid introduced in S, not applicable to R 8260 assumeTrue(SdkLevel.isAtLeastS()); 8261 mConnectedNetwork.restricted = true; 8262 connect(); 8263 expectRegisterNetworkAgent((agentConfig) -> { }, 8264 (cap) -> { 8265 assertFalse(cap.hasCapability(NetworkCapabilities 8266 .NET_CAPABILITY_NOT_RESTRICTED)); 8267 }); 8268 } 8269 8270 @Test testOemPrivateNetworkCapability()8271 public void testOemPrivateNetworkCapability() throws Exception { 8272 // oemPrivate introduced in S, not applicable to R 8273 assumeTrue(SdkLevel.isAtLeastS()); 8274 mConnectedNetwork.oemPrivate = true; 8275 connect(); 8276 expectRegisterNetworkAgent((agentConfig) -> { }, 8277 (cap) -> { 8278 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)); 8279 assertFalse(cap.hasCapability(NetworkCapabilities 8280 .NET_CAPABILITY_NOT_RESTRICTED)); 8281 }); 8282 } 8283 8284 @Test testNotOemPrivateNetworkCapability()8285 public void testNotOemPrivateNetworkCapability() throws Exception { 8286 // oemPrivate introduced in S, not applicable to R 8287 assumeTrue(SdkLevel.isAtLeastS()); 8288 mConnectedNetwork.oemPrivate = false; 8289 connect(); 8290 expectRegisterNetworkAgent((agentConfig) -> { }, 8291 (cap) -> { 8292 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)); 8293 assertTrue(cap.hasCapability(NetworkCapabilities 8294 .NET_CAPABILITY_NOT_RESTRICTED)); 8295 }); 8296 } 8297 8298 @Test testSendLinkProbeFailure()8299 public void testSendLinkProbeFailure() throws Exception { 8300 mCmi.probeLink(mLinkProbeCallback, -1); 8301 8302 verify(mLinkProbeCallback).onFailure(LinkProbeCallback.LINK_PROBE_ERROR_NOT_CONNECTED); 8303 verify(mLinkProbeCallback, never()).onAck(anyInt()); 8304 verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt()); 8305 } 8306 8307 @Test testSendLinkProbeSuccess()8308 public void testSendLinkProbeSuccess() throws Exception { 8309 connect(); 8310 8311 mCmi.probeLink(mLinkProbeCallback, -1); 8312 8313 verify(mWifiNative).probeLink(any(), any(), eq(mLinkProbeCallback), eq(-1)); 8314 verify(mLinkProbeCallback, never()).onFailure(anyInt()); 8315 verify(mLinkProbeCallback, never()).onAck(anyInt()); 8316 } 8317 setupPasspointConnection()8318 private void setupPasspointConnection() throws Exception { 8319 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPasspointNetwork()); 8320 mConnectedNetwork.carrierId = CARRIER_ID_1; 8321 when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class))) 8322 .thenReturn(DATA_SUBID); 8323 when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true); 8324 mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); 8325 triggerConnect(); 8326 8327 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(mConnectedNetwork); 8328 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 8329 .thenReturn(mScanDetailCache); 8330 when(mScanRequestProxy.getScanResult(TEST_BSSID_STR)).thenReturn( 8331 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 8332 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn( 8333 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq)); 8334 when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn( 8335 getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult()); 8336 8337 WifiSsid wifiSsid = WifiSsid.fromBytes( 8338 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 8339 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8340 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null)); 8341 mLooper.dispatchAll(); 8342 assertEquals("L3ProvisioningState", getCurrentState().getName()); 8343 } 8344 8345 /** 8346 * When connecting to a Passpoint network, verify that the Venue URL ANQP request is sent. 8347 */ 8348 @Test testVenueUrlRequestForPasspointNetworks()8349 public void testVenueUrlRequestForPasspointNetworks() throws Exception { 8350 setupPasspointConnection(); 8351 verify(mPasspointManager).requestVenueUrlAnqpElement(any(ScanResult.class)); 8352 assertEquals("L3ProvisioningState", getCurrentState().getName()); 8353 } 8354 8355 /** 8356 * Verify that the Venue URL ANQP request is not sent for non-Passpoint EAP networks 8357 */ 8358 @Test testVenueUrlNotRequestedForNonPasspointNetworks()8359 public void testVenueUrlNotRequestedForNonPasspointNetworks() throws Exception { 8360 setupEapSimConnection(); 8361 verify(mPasspointManager, never()).requestVenueUrlAnqpElement(any(ScanResult.class)); 8362 assertEquals("L3ProvisioningState", getCurrentState().getName()); 8363 } 8364 8365 @Test testFirmwareRoam()8366 public void testFirmwareRoam() throws Exception { 8367 connect(); 8368 8369 // Now send a network connection (indicating a roam) event 8370 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8371 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null)); 8372 mLooper.dispatchAll(); 8373 8374 verifyNetworkStateChangedBroadcast(times(2), 8375 new NetworkStateChangedIntentMatcher(CONNECTED)); 8376 } 8377 8378 @Test testFirmwareRoamDisconnectSecondaryInternetOnSameBand()8379 public void testFirmwareRoamDisconnectSecondaryInternetOnSameBand() throws Exception { 8380 connect(); 8381 // After connection, the primary should be on 2.4Ghz. 8382 assertTrue(mWifiInfo.is24GHz()); 8383 8384 // Verify no disconnection of secondary if it's on another band. 8385 ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class); 8386 WifiInfo secondaryWifiInfo = mock(WifiInfo.class); 8387 when(secondaryWifiInfo.is24GHz()).thenReturn(false); 8388 when(secondaryWifiInfo.is5GHz()).thenReturn(true); 8389 when(secondaryCmm.isConnected()).thenReturn(true); 8390 when(secondaryCmm.isSecondaryInternet()).thenReturn(true); 8391 when(secondaryCmm.getConnectionInfo()).thenReturn(secondaryWifiInfo); 8392 when(mActiveModeWarden.getClientModeManagerInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED)) 8393 .thenReturn(secondaryCmm); 8394 8395 // Now send a network connection (indicating a roam) event, and verify no disconnection 8396 // of secondary 8397 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8398 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null)); 8399 mLooper.dispatchAll(); 8400 8401 assertTrue(mWifiInfo.is24GHz()); 8402 verify(secondaryCmm, never()).disconnect(); 8403 8404 // Set the secondary to the same band as primary and then verify a disconnect after the 8405 // primary roams. 8406 when(secondaryWifiInfo.is24GHz()).thenReturn(true); 8407 when(secondaryWifiInfo.is5GHz()).thenReturn(false); 8408 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8409 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null)); 8410 mLooper.dispatchAll(); 8411 8412 assertTrue(mWifiInfo.is24GHz()); 8413 verify(secondaryCmm).disconnect(); 8414 } 8415 8416 @Test testProvisioningUpdateAfterConnect()8417 public void testProvisioningUpdateAfterConnect() throws Exception { 8418 connect(); 8419 8420 // Trigger a IP params update (maybe a dhcp lease renewal). 8421 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 8422 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 8423 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 8424 dhcpResults.baseConfiguration.ipAddress = 8425 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 8426 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 8427 dhcpResults.leaseDuration = 3600; 8428 8429 injectDhcpSuccess(dhcpResults); 8430 mLooper.dispatchAll(); 8431 8432 verifyNetworkStateChangedBroadcast(times(2), 8433 new NetworkStateChangedIntentMatcher(CONNECTED)); 8434 } 8435 8436 /** 8437 * Verify that the Deauth-Imminent WNM-Notification is handled by relaying to the Passpoint 8438 * Manager. 8439 */ 8440 @Test testHandlePasspointDeauthImminentWnmNotification()8441 public void testHandlePasspointDeauthImminentWnmNotification() throws Exception { 8442 setupEapSimConnection(); 8443 WnmData wnmData = WnmData.createDeauthImminentEvent(TEST_BSSID, "", false, 8444 TEST_DELAY_IN_SECONDS); 8445 mCmi.sendMessage(WifiMonitor.HS20_DEAUTH_IMMINENT_EVENT, 0, 0, wnmData); 8446 mLooper.dispatchAll(); 8447 verify(mPasspointManager).handleDeauthImminentEvent(eq(wnmData), 8448 any(WifiConfiguration.class)); 8449 } 8450 8451 /** 8452 * Verify that the network selection status will be updated and the function onEapFailure() 8453 * in EapFailureNotifier is called when a EAP Authentication failure is detected 8454 * with carrier erroe code. 8455 */ 8456 @Test testCarrierEapFailure()8457 public void testCarrierEapFailure() throws Exception { 8458 initializeAndAddNetworkAndVerifySuccess(); 8459 WifiBlocklistMonitor.CarrierSpecificEapFailureConfig eapFailureConfig = 8460 new WifiBlocklistMonitor.CarrierSpecificEapFailureConfig(1, -1, true); 8461 8462 startConnectSuccess(); 8463 8464 WifiConfiguration config = new WifiConfiguration(); 8465 config.SSID = TEST_SSID; 8466 config.getNetworkSelectionStatus().setHasEverConnected(true); 8467 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); 8468 when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config); 8469 when(mEapFailureNotifier.onEapFailure(anyInt(), eq(config), anyBoolean())).thenReturn( 8470 eapFailureConfig); 8471 8472 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 8473 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 8474 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, DEFINED_ERROR_CODE) 8475 ); 8476 mLooper.dispatchAll(); 8477 8478 verify(mEapFailureNotifier).onEapFailure(DEFINED_ERROR_CODE, config, true); 8479 verify(mWifiBlocklistMonitor).loadCarrierConfigsForDisableReasonInfos(eapFailureConfig); 8480 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 8481 eq(WifiConfiguration.NetworkSelectionStatus 8482 .DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR)); 8483 } 8484 8485 /** 8486 * When connected to a Passpoint network, verify that the Venue URL and T&C URL are updated in 8487 * the {@link LinkProperties} object when provisioning complete and when link properties change 8488 * events are received. 8489 */ 8490 @Test testVenueAndTCUrlsUpdateForPasspointNetworks()8491 public void testVenueAndTCUrlsUpdateForPasspointNetworks() throws Exception { 8492 // This tests new S functionality/APIs, not applicable to R. 8493 assumeTrue(SdkLevel.isAtLeastS()); 8494 setupPasspointConnection(); 8495 when(mPasspointManager.getVenueUrl(any(ScanResult.class))).thenReturn(new URL(VENUE_URL)); 8496 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 8497 TEST_TERMS_AND_CONDITIONS_URL); 8498 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 8499 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 8500 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 8501 0, 0, wnmData); 8502 DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable(); 8503 dhcpResults.baseConfiguration = new StaticIpConfiguration(); 8504 dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4"); 8505 dhcpResults.baseConfiguration.ipAddress = 8506 new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0); 8507 dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8")); 8508 dhcpResults.leaseDuration = 3600; 8509 injectDhcpSuccess(dhcpResults); 8510 mCmi.mNetworkAgent = null; 8511 mLooper.dispatchAll(); 8512 LinkProperties linkProperties = mock(LinkProperties.class); 8513 mIpClientCallback.onLinkPropertiesChange(linkProperties); 8514 mLooper.dispatchAll(); 8515 verify(mPasspointManager, times(2)).getVenueUrl(any(ScanResult.class)); 8516 final ArgumentCaptor<CaptivePortalData> captivePortalDataCaptor = 8517 ArgumentCaptor.forClass(CaptivePortalData.class); 8518 verify(linkProperties).setCaptivePortalData(captivePortalDataCaptor.capture()); 8519 assertEquals(WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME, 8520 captivePortalDataCaptor.getValue().getVenueFriendlyName()); 8521 assertEquals(VENUE_URL, captivePortalDataCaptor.getValue().getVenueInfoUrl().toString()); 8522 assertEquals(TEST_TERMS_AND_CONDITIONS_URL, captivePortalDataCaptor.getValue() 8523 .getUserPortalUrl().toString()); 8524 } 8525 8526 /** 8527 * Verify that the T&C WNM-Notification is handled by relaying to the Passpoint 8528 * Manager. 8529 */ 8530 @Test testHandlePasspointTermsAndConditionsWnmNotification()8531 public void testHandlePasspointTermsAndConditionsWnmNotification() throws Exception { 8532 setupEapSimConnection(); 8533 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 8534 TEST_TERMS_AND_CONDITIONS_URL); 8535 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 8536 any(WifiConfiguration.class))).thenReturn(new URL(TEST_TERMS_AND_CONDITIONS_URL)); 8537 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 8538 0, 0, wnmData); 8539 mLooper.dispatchAll(); 8540 verify(mPasspointManager).handleTermsAndConditionsEvent(eq(wnmData), 8541 any(WifiConfiguration.class)); 8542 verify(mWifiNative, never()).disconnect(anyString()); 8543 } 8544 8545 /** 8546 * Verify that when a bad URL is received in the T&C WNM-Notification, the connection is 8547 * disconnected. 8548 */ 8549 @Test testHandlePasspointTermsAndConditionsWnmNotificationWithBadUrl()8550 public void testHandlePasspointTermsAndConditionsWnmNotificationWithBadUrl() throws Exception { 8551 setupEapSimConnection(); 8552 WnmData wnmData = WnmData.createTermsAndConditionsAccetanceRequiredEvent(TEST_BSSID, 8553 TEST_TERMS_AND_CONDITIONS_URL); 8554 when(mPasspointManager.handleTermsAndConditionsEvent(eq(wnmData), 8555 any(WifiConfiguration.class))).thenReturn(null); 8556 mCmi.sendMessage(WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, 8557 0, 0, wnmData); 8558 mLooper.dispatchAll(); 8559 verify(mPasspointManager).handleTermsAndConditionsEvent(eq(wnmData), 8560 any(WifiConfiguration.class)); 8561 verify(mWifiNative).disconnect(eq(WIFI_IFACE_NAME)); 8562 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 8563 eq(StaEvent.DISCONNECT_PASSPOINT_TAC)); 8564 } 8565 verifyTransitionDisableEvent(String caps, int indication, boolean shouldUpdate)8566 private void verifyTransitionDisableEvent(String caps, int indication, boolean shouldUpdate) 8567 throws Exception { 8568 final int networkId = FRAMEWORK_NETWORK_ID; 8569 ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid), 8570 TEST_BSSID_STR) 8571 .setHessid(1245) 8572 .setCaps(caps) 8573 .setRssi(-78) 8574 .setFrequency(2450) 8575 .setTsf(1025) 8576 .setDistanceCm(22) 8577 .setDistanceSdCm(33) 8578 .setIs80211McRTTResponder(true) 8579 .build(); 8580 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 8581 sFilsSsid.getBytes(StandardCharsets.UTF_8)); 8582 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 8583 when(mScanRequestProxy.getScanResults()).thenReturn(Arrays.asList(scanResult)); 8584 when(mScanRequestProxy.getScanResult(eq(TEST_BSSID_STR))).thenReturn(scanResult); 8585 8586 initializeAndAddNetworkAndVerifySuccess(); 8587 8588 startConnectSuccess(); 8589 8590 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 8591 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 8592 mLooper.dispatchAll(); 8593 8594 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 8595 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 8596 SupplicantState.COMPLETED)); 8597 mLooper.dispatchAll(); 8598 8599 assertEquals("L3ProvisioningState", getCurrentState().getName()); 8600 8601 mCmi.sendMessage(WifiMonitor.TRANSITION_DISABLE_INDICATION, 8602 networkId, indication); 8603 mLooper.dispatchAll(); 8604 8605 if (shouldUpdate) { 8606 verify(mWifiConfigManager).updateNetworkTransitionDisable( 8607 eq(networkId), eq(indication)); 8608 } else { 8609 verify(mWifiConfigManager, never()).updateNetworkTransitionDisable( 8610 anyInt(), anyInt()); 8611 } 8612 } 8613 8614 /** 8615 * Verify that the Transition Disable event is routed correctly. 8616 */ 8617 @Test testUpdateSaeOnlyTransitionDisableIndicationFromPskSaeBss()8618 public void testUpdateSaeOnlyTransitionDisableIndicationFromPskSaeBss() throws Exception { 8619 String caps = "[PSK][SAE]"; 8620 int indication = WifiMonitor.TDI_USE_WPA3_PERSONAL; 8621 boolean shouldUpdate = true; 8622 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8623 } 8624 8625 /** 8626 * Verify that the Transition Disable event is routed correctly. 8627 */ 8628 @Test testUpdateSaeOnlyTransitionDisableIndicationFromSaeBss()8629 public void testUpdateSaeOnlyTransitionDisableIndicationFromSaeBss() throws Exception { 8630 String caps = "[SAE]"; 8631 int indication = WifiMonitor.TDI_USE_WPA3_PERSONAL; 8632 boolean shouldUpdate = true; 8633 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8634 } 8635 8636 /** 8637 * Verify that the Transition Disable event is routed correctly. 8638 */ 8639 @Test testDropSaeOnlyTransitionDisableIndicationFromPskBss()8640 public void testDropSaeOnlyTransitionDisableIndicationFromPskBss() throws Exception { 8641 String caps = "[PSK]"; 8642 int indication = WifiMonitor.TDI_USE_WPA3_PERSONAL; 8643 boolean shouldUpdate = false; 8644 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8645 } 8646 8647 /** 8648 * Verify that the Transition Disable event is routed correctly. 8649 */ 8650 @Test testUpdateSaePkTransitionDisableIndicationFromPskSaeBss()8651 public void testUpdateSaePkTransitionDisableIndicationFromPskSaeBss() throws Exception { 8652 String caps = "[PSK][SAE]"; 8653 int indication = WifiMonitor.TDI_USE_SAE_PK; 8654 boolean shouldUpdate = true; 8655 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8656 } 8657 8658 /** 8659 * Verify that the Transition Disable event is routed correctly. 8660 */ 8661 @Test testUpdateSaePkTransitionDisableIndicationFromSaeBss()8662 public void testUpdateSaePkTransitionDisableIndicationFromSaeBss() throws Exception { 8663 String caps = "[SAE]"; 8664 int indication = WifiMonitor.TDI_USE_SAE_PK; 8665 boolean shouldUpdate = true; 8666 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8667 } 8668 8669 /** 8670 * Verify that the Transition Disable event is routed correctly. 8671 */ 8672 @Test testDropSaePkTransitionDisableIndicationFromPskBss()8673 public void testDropSaePkTransitionDisableIndicationFromPskBss() throws Exception { 8674 String caps = "[PSK]"; 8675 int indication = WifiMonitor.TDI_USE_SAE_PK; 8676 boolean shouldUpdate = false; 8677 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8678 } 8679 8680 /** 8681 * Verify that the Transition Disable event is routed correctly. 8682 */ 8683 @Test testUpdateOweOnlyTransitionDisableIndicationFromOpenOweBss()8684 public void testUpdateOweOnlyTransitionDisableIndicationFromOpenOweBss() throws Exception { 8685 String caps = "[OWE_TRANSITION]"; 8686 int indication = WifiMonitor.TDI_USE_ENHANCED_OPEN; 8687 boolean shouldUpdate = true; 8688 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8689 } 8690 8691 /** 8692 * Verify that the Transition Disable event is routed correctly. 8693 */ 8694 @Test testUpdateOweOnlyTransitionDisableIndicationFromOweBss()8695 public void testUpdateOweOnlyTransitionDisableIndicationFromOweBss() throws Exception { 8696 String caps = "[OWE]"; 8697 int indication = WifiMonitor.TDI_USE_ENHANCED_OPEN; 8698 boolean shouldUpdate = true; 8699 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8700 } 8701 8702 /** 8703 * Verify that the Transition Disable event is routed correctly. 8704 */ 8705 @Test testDropOweOnlyTransitionDisableIndicationFromOpenBss()8706 public void testDropOweOnlyTransitionDisableIndicationFromOpenBss() throws Exception { 8707 String caps = ""; 8708 int indication = WifiMonitor.TDI_USE_ENHANCED_OPEN; 8709 boolean shouldUpdate = false; 8710 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8711 } 8712 8713 /** 8714 * Verify that the Transition Disable event is routed correctly. 8715 */ 8716 @Test testUpdateWpa3EnterpriseTransitionDisableIndicationFromTransitionBss()8717 public void testUpdateWpa3EnterpriseTransitionDisableIndicationFromTransitionBss() 8718 throws Exception { 8719 String caps = "[EAP/SHA1-EAP/SHA256][RSN][MFPC]"; 8720 int indication = WifiMonitor.TDI_USE_WPA3_ENTERPRISE; 8721 boolean shouldUpdate = true; 8722 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8723 } 8724 8725 /** 8726 * Verify that the Transition Disable event is routed correctly. 8727 */ 8728 @Test testUpdateWpa3EnterpriseTransitionDisableIndicationFromWpa3EnterpriseBss()8729 public void testUpdateWpa3EnterpriseTransitionDisableIndicationFromWpa3EnterpriseBss() 8730 throws Exception { 8731 String caps = "[EAP/SHA256][RSN][MFPC][MFPR]"; 8732 int indication = WifiMonitor.TDI_USE_WPA3_ENTERPRISE; 8733 boolean shouldUpdate = true; 8734 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8735 } 8736 8737 /** 8738 * Verify that the Transition Disable event is routed correctly. 8739 */ 8740 @Test testDropWpa3EnterpriseTransitionDisableIndicationFromWpa2EnterpriseBss()8741 public void testDropWpa3EnterpriseTransitionDisableIndicationFromWpa2EnterpriseBss() 8742 throws Exception { 8743 String caps = "[EAP/SHA1]"; 8744 int indication = WifiMonitor.TDI_USE_WPA3_ENTERPRISE; 8745 boolean shouldUpdate = false; 8746 verifyTransitionDisableEvent(caps, indication, shouldUpdate); 8747 } 8748 8749 /** 8750 * Verify that the network selection status will be updated with DISABLED_NETWORK_NOT_FOUND 8751 * when number of NETWORK_NOT_FOUND_EVENT event reaches the threshold. 8752 */ 8753 @Test testNetworkNotFoundEventUpdatesAssociationFailureStatus()8754 public void testNetworkNotFoundEventUpdatesAssociationFailureStatus() 8755 throws Exception { 8756 assumeTrue(SdkLevel.isAtLeastS()); 8757 initializeAndAddNetworkAndVerifySuccess(); 8758 mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR); 8759 for (int i = 0; i < mWifiGlobals.getNetworkNotFoundEventThreshold(); i++) { 8760 mCmi.sendMessage(WifiMonitor.NETWORK_NOT_FOUND_EVENT, DEFAULT_TEST_SSID); 8761 } 8762 mLooper.dispatchAll(); 8763 verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(), 8764 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_NETWORK_NOT_FOUND)); 8765 verify(mWifiConfigManager).setRecentFailureAssociationStatus(anyInt(), 8766 eq(WifiConfiguration.RECENT_FAILURE_NETWORK_NOT_FOUND)); 8767 8768 verify(mWifiDiagnostics).reportConnectionEvent( 8769 eq(WifiDiagnostics.CONNECTION_EVENT_FAILED), any()); 8770 verify(mWifiConnectivityManager).handleConnectionAttemptEnded( 8771 mClientModeManager, 8772 WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND, 8773 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_BSSID_STR, 8774 mTestConfig); 8775 verify(mWifiNetworkFactory).handleConnectionAttemptEnded( 8776 eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND), 8777 eq(mTestConfig), eq(TEST_BSSID_STR), 8778 eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN)); 8779 verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded( 8780 eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_NOT_FOUND), 8781 eq(mTestConfig), eq(null)); 8782 verify(mWifiMetrics, never()) 8783 .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware(); 8784 verifyConnectionEventTimeoutDoesNotOccur(); 8785 8786 clearInvocations(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 8787 mWifiNetworkSuggestionsManager); 8788 8789 // Now trigger a disconnect event from supplicant, this should be ignored since the 8790 // connection tracking should have already ended. 8791 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 8792 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false)); 8793 mLooper.dispatchAll(); 8794 8795 verifyNoMoreInteractions(mWifiDiagnostics, mWifiConfigManager, mWifiNetworkFactory, 8796 mWifiNetworkSuggestionsManager); 8797 } 8798 8799 /** 8800 * Verify that the subscriberId will be filled in NetworkAgentConfig 8801 * after connecting to a merged network. And also VCN policy will be checked. 8802 */ 8803 @Test triggerConnectToMergedNetwork()8804 public void triggerConnectToMergedNetwork() throws Exception { 8805 assumeTrue(SdkLevel.isAtLeastS()); 8806 VcnManager vcnManager = mock(VcnManager.class); 8807 VcnNetworkPolicyResult vcnUnderlyingNetworkPolicy = mock(VcnNetworkPolicyResult.class); 8808 when(mContext.getSystemService(VcnManager.class)).thenReturn(vcnManager); 8809 ArgumentCaptor<VcnManager.VcnNetworkPolicyChangeListener> policyChangeListenerCaptor = 8810 ArgumentCaptor.forClass(VcnManager.VcnNetworkPolicyChangeListener.class); 8811 InOrder inOrder = inOrder(vcnManager, vcnUnderlyingNetworkPolicy); 8812 doAnswer(new AnswerWithArguments() { 8813 public VcnNetworkPolicyResult answer(NetworkCapabilities networkCapabilities, 8814 LinkProperties linkProperties) throws Exception { 8815 networkCapabilities.removeCapability( 8816 NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 8817 when(vcnUnderlyingNetworkPolicy.getNetworkCapabilities()) 8818 .thenReturn(networkCapabilities); 8819 return vcnUnderlyingNetworkPolicy; 8820 } 8821 }).when(vcnManager).applyVcnNetworkPolicy(any(), any()); 8822 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(false); 8823 8824 String testSubscriberId = "TestSubscriberId"; 8825 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 8826 when(mDataTelephonyManager.getSubscriberId()).thenReturn(testSubscriberId); 8827 mConnectedNetwork.carrierMerged = true; 8828 mConnectedNetwork.subscriptionId = DATA_SUBID; 8829 connect(); 8830 expectRegisterNetworkAgent((agentConfig) -> { 8831 assertEquals(testSubscriberId, agentConfig.subscriberId); 8832 }, (cap) -> { 8833 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)); 8834 assertEquals(Collections.singleton(DATA_SUBID), cap.getSubscriptionIds()); 8835 }); 8836 // Verify VCN policy listener is registered 8837 inOrder.verify(vcnManager).addVcnNetworkPolicyChangeListener(any(), 8838 policyChangeListenerCaptor.capture()); 8839 assertNotNull(policyChangeListenerCaptor.getValue()); 8840 8841 // Verify getting new capability from VcnManager 8842 inOrder.verify(vcnManager).applyVcnNetworkPolicy(any(NetworkCapabilities.class), 8843 any(LinkProperties.class)); 8844 inOrder.verify(vcnUnderlyingNetworkPolicy).isTeardownRequested(); 8845 inOrder.verify(vcnUnderlyingNetworkPolicy).getNetworkCapabilities(); 8846 8847 // Update policy with tear down request. 8848 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(true); 8849 policyChangeListenerCaptor.getValue().onPolicyChanged(); 8850 mLooper.dispatchAll(); 8851 8852 // The merged carrier network should be disconnected. 8853 inOrder.verify(vcnManager).applyVcnNetworkPolicy(any(NetworkCapabilities.class), 8854 any(LinkProperties.class)); 8855 inOrder.verify(vcnUnderlyingNetworkPolicy).isTeardownRequested(); 8856 inOrder.verify(vcnUnderlyingNetworkPolicy).getNetworkCapabilities(); 8857 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 8858 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 8859 eq(StaEvent.DISCONNECT_VCN_REQUEST)); 8860 DisconnectEventInfo disconnectEventInfo = 8861 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 8862 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 8863 mLooper.dispatchAll(); 8864 assertEquals("DisconnectedState", getCurrentState().getName()); 8865 8866 // In DisconnectedState, policy update should result no capability update. 8867 reset(mWifiConfigManager, vcnManager); 8868 policyChangeListenerCaptor.getValue().onPolicyChanged(); 8869 verifyNoMoreInteractions(mWifiConfigManager, vcnManager); 8870 } 8871 8872 /** 8873 * Verify when connect to a unmerged network, will not mark it as a VCN network. 8874 */ 8875 @Test triggerConnectToUnmergedNetwork()8876 public void triggerConnectToUnmergedNetwork() throws Exception { 8877 assumeTrue(SdkLevel.isAtLeastS()); 8878 VcnManager vcnManager = mock(VcnManager.class); 8879 when(mContext.getSystemService(VcnManager.class)).thenReturn(vcnManager); 8880 VcnNetworkPolicyResult vcnUnderlyingNetworkPolicy = mock(VcnNetworkPolicyResult.class); 8881 ArgumentCaptor<VcnManager.VcnNetworkPolicyChangeListener> policyChangeListenerCaptor = 8882 ArgumentCaptor.forClass(VcnManager.VcnNetworkPolicyChangeListener.class); 8883 doAnswer(new AnswerWithArguments() { 8884 public VcnNetworkPolicyResult answer(NetworkCapabilities networkCapabilities, 8885 LinkProperties linkProperties) throws Exception { 8886 networkCapabilities.removeCapability( 8887 NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 8888 when(vcnUnderlyingNetworkPolicy.getNetworkCapabilities()) 8889 .thenReturn(networkCapabilities); 8890 return vcnUnderlyingNetworkPolicy; 8891 } 8892 }).when(vcnManager).applyVcnNetworkPolicy(any(), any()); 8893 when(vcnUnderlyingNetworkPolicy.isTeardownRequested()).thenReturn(false); 8894 8895 String testSubscriberId = "TestSubscriberId"; 8896 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager); 8897 when(mDataTelephonyManager.getSubscriberId()).thenReturn(testSubscriberId); 8898 connect(); 8899 expectRegisterNetworkAgent((agentConfig) -> { 8900 assertEquals(null, agentConfig.subscriberId); 8901 }, (cap) -> { 8902 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)); 8903 assertTrue(cap.getSubscriptionIds().isEmpty()); 8904 }); 8905 8906 // Verify VCN policy listener is registered 8907 verify(vcnManager).addVcnNetworkPolicyChangeListener(any(), 8908 policyChangeListenerCaptor.capture()); 8909 assertNotNull(policyChangeListenerCaptor.getValue()); 8910 8911 policyChangeListenerCaptor.getValue().onPolicyChanged(); 8912 mLooper.dispatchAll(); 8913 8914 verifyNoMoreInteractions(vcnManager, vcnUnderlyingNetworkPolicy); 8915 } 8916 8917 /** 8918 * Verifies that we trigger a disconnect when the {@link WifiConfigManager}. 8919 * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked. 8920 */ 8921 @Test testOnCarrierOffloadDisabled()8922 public void testOnCarrierOffloadDisabled() throws Exception { 8923 mConnectedNetwork.subscriptionId = DATA_SUBID; 8924 connect(); 8925 8926 mOffloadDisabledListenerArgumentCaptor.getValue() 8927 .onCarrierOffloadDisabled(DATA_SUBID, false); 8928 mLooper.dispatchAll(); 8929 8930 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 8931 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 8932 eq(StaEvent.DISCONNECT_CARRIER_OFFLOAD_DISABLED)); 8933 verify(mWifiConnectivityManager).clearCachedCandidates(); 8934 } 8935 8936 @Test testPacketFilter()8937 public void testPacketFilter() throws Exception { 8938 connect(); 8939 8940 verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture()); 8941 assertEquals(APF_CAP, mProvisioningConfigurationCaptor.getValue().apfCapabilities); 8942 8943 byte[] filter = new byte[20]; 8944 new Random().nextBytes(filter); 8945 mIpClientCallback.installPacketFilter(filter); 8946 mLooper.dispatchAll(); 8947 8948 verify(mWifiNative).installPacketFilter(WIFI_IFACE_NAME, filter); 8949 8950 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 8951 mIpClientCallback.startReadPacketFilter(); 8952 mLooper.dispatchAll(); 8953 verify(mIpClient).readPacketFilterComplete(filter); 8954 verify(mWifiNative).readPacketFilter(WIFI_IFACE_NAME); 8955 } 8956 8957 @Test testPacketFilterOnSecondarySupported()8958 public void testPacketFilterOnSecondarySupported() throws Exception { 8959 mResources.setBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta, true); 8960 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 8961 connect(); 8962 8963 verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture()); 8964 assertEquals(APF_CAP, mProvisioningConfigurationCaptor.getValue().apfCapabilities); 8965 } 8966 8967 @Test testPacketFilterOnSecondaryNotSupported()8968 public void testPacketFilterOnSecondaryNotSupported() throws Exception { 8969 mResources.setBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta, false); 8970 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 8971 connect(); 8972 8973 verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture()); 8974 assertNull(mProvisioningConfigurationCaptor.getValue().apfCapabilities); 8975 } 8976 8977 @Test testPacketFilterOnRoleChangeOnSecondaryCmm()8978 public void testPacketFilterOnRoleChangeOnSecondaryCmm() throws Exception { 8979 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 8980 connect(); 8981 8982 verify(mWifiScoreReport).onRoleChanged(ROLE_CLIENT_PRIMARY); 8983 8984 byte[] filter = new byte[20]; 8985 new Random().nextBytes(filter); 8986 mIpClientCallback.installPacketFilter(filter); 8987 mLooper.dispatchAll(); 8988 8989 // packet filter will not be installed if the secondary STA doesn't support APF. 8990 verify(mWifiNative, never()).installPacketFilter(WIFI_IFACE_NAME, filter); 8991 8992 mIpClientCallback.startReadPacketFilter(); 8993 mLooper.dispatchAll(); 8994 // Return null as packet filter is not installed. 8995 verify(mIpClient).readPacketFilterComplete(eq(null)); 8996 verify(mWifiNative, never()).readPacketFilter(WIFI_IFACE_NAME); 8997 8998 // Now invoke role change, that should apply the APF 8999 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 9000 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 9001 mCmi.onRoleChanged(); 9002 mIpClientCallback.installPacketFilter(filter); 9003 mLooper.dispatchAll(); 9004 verify(mWifiScoreReport, times(2)).onRoleChanged(ROLE_CLIENT_PRIMARY); 9005 // verify that the APF capabilities are updated in IpClient. 9006 verify(mWifiNative, times(1)).getApfCapabilities(WIFI_IFACE_NAME); 9007 verify(mIpClient, times(1)).updateApfCapabilities(eq(APF_CAP)); 9008 verify(mWifiNative, times(1)).installPacketFilter(WIFI_IFACE_NAME, filter); 9009 } 9010 9011 @Test testPacketFilterOnRoleChangeOnSecondaryCmmWithSupportForNonPrimaryApf()9012 public void testPacketFilterOnRoleChangeOnSecondaryCmmWithSupportForNonPrimaryApf() 9013 throws Exception { 9014 mResources.setBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta, true); 9015 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 9016 connect(); 9017 9018 byte[] filter = new byte[20]; 9019 new Random().nextBytes(filter); 9020 mIpClientCallback.installPacketFilter(filter); 9021 mLooper.dispatchAll(); 9022 9023 // apply the data. 9024 verify(mWifiNative).installPacketFilter(WIFI_IFACE_NAME, filter); 9025 9026 when(mWifiNative.readPacketFilter(WIFI_IFACE_NAME)).thenReturn(filter); 9027 mIpClientCallback.startReadPacketFilter(); 9028 mLooper.dispatchAll(); 9029 verify(mIpClient).readPacketFilterComplete(filter); 9030 // return the applied data. 9031 verify(mWifiNative).readPacketFilter(WIFI_IFACE_NAME); 9032 9033 // Now invoke role change, that should not apply the APF 9034 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 9035 mCmi.onRoleChanged(); 9036 // ignore (since it was already applied) 9037 verify(mIpClient, never()).updateApfCapabilities(eq(APF_CAP)); 9038 verify(mWifiNative, times(1)).installPacketFilter(WIFI_IFACE_NAME, filter); 9039 } 9040 9041 @Test testSetMaxDtimMultiplier_IPv4OnlyNetwork()9042 public void testSetMaxDtimMultiplier_IPv4OnlyNetwork() throws Exception { 9043 connect(); 9044 9045 mIpClientCallback.setMaxDtimMultiplier(TEST_IPV4_ONLY_NETWORK_MAX_DTIM_MULTIPLIER); 9046 mLooper.dispatchAll(); 9047 9048 verify(mWifiNative).setDtimMultiplier(WIFI_IFACE_NAME, 9049 TEST_IPV4_ONLY_NETWORK_MAX_DTIM_MULTIPLIER); 9050 } 9051 9052 @Test testSetMaxDtimMultiplier_IPv6OnlyNetwork()9053 public void testSetMaxDtimMultiplier_IPv6OnlyNetwork() throws Exception { 9054 connect(); 9055 9056 mIpClientCallback.setMaxDtimMultiplier(TEST_IPV6_ONLY_NETWORK_MAX_DTIM_MULTIPLIER); 9057 mLooper.dispatchAll(); 9058 9059 verify(mWifiNative).setDtimMultiplier(WIFI_IFACE_NAME, 9060 TEST_IPV6_ONLY_NETWORK_MAX_DTIM_MULTIPLIER); 9061 } 9062 runSetMaxDtimMultiplierInDualStackTest()9063 private void runSetMaxDtimMultiplierInDualStackTest() throws Exception { 9064 connect(); 9065 9066 mIpClientCallback.setMaxDtimMultiplier(TEST_DUAL_STACK_NETWORK_MAX_DTIM_MULTIPLIER); 9067 mLooper.dispatchAll(); 9068 9069 verify(mWifiNative).setDtimMultiplier(WIFI_IFACE_NAME, 9070 TEST_DUAL_STACK_NETWORK_MAX_DTIM_MULTIPLIER); 9071 } 9072 9073 @Test testSetMaxDtimMultiplier_DualStackNetwork()9074 public void testSetMaxDtimMultiplier_DualStackNetwork() throws Exception { 9075 runSetMaxDtimMultiplierInDualStackTest(); 9076 } 9077 9078 @Test testSetMaxDtimMultiplier_EnableMulticastLock()9079 public void testSetMaxDtimMultiplier_EnableMulticastLock() throws Exception { 9080 runSetMaxDtimMultiplierInDualStackTest(); 9081 reset(mIpClient); 9082 9083 // simulate the multicast lock is held. 9084 WifiMulticastLockManager.FilterController filterController = 9085 mCmi.getMcastLockManagerFilterController(); 9086 filterController.startFilteringMulticastPackets(); 9087 verify(mIpClient).setMulticastFilter(eq(true)); 9088 9089 reset(mWifiNative); 9090 9091 mIpClientCallback.setMaxDtimMultiplier(TEST_MULTICAST_LOCK_MAX_DTIM_MULTIPLIER); 9092 mLooper.dispatchAll(); 9093 9094 verify(mWifiNative).setDtimMultiplier(WIFI_IFACE_NAME, 9095 TEST_MULTICAST_LOCK_MAX_DTIM_MULTIPLIER); 9096 } 9097 9098 @Test testWifiInfoUpdateOnRoleChange()9099 public void testWifiInfoUpdateOnRoleChange() throws Exception { 9100 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 9101 connect(); 9102 // Should not set WifiInfo.isPrimary 9103 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 9104 if (SdkLevel.isAtLeastS()) { 9105 WifiInfo wifiInfoFromTi = (WifiInfo) cap.getTransportInfo(); 9106 assertFalse(wifiInfoFromTi.isPrimary()); 9107 } 9108 }); 9109 reset(mWifiNetworkAgent); 9110 9111 // Now invoke role change, that should set WifiInfo.isPrimary 9112 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 9113 mCmi.onRoleChanged(); 9114 expectNetworkAgentUpdateCapabilities((cap) -> { 9115 if (SdkLevel.isAtLeastS()) { 9116 WifiInfo wifiInfoFromTi = (WifiInfo) cap.getTransportInfo(); 9117 assertTrue(wifiInfoFromTi.isPrimary()); 9118 } 9119 }); 9120 } 9121 9122 /** 9123 * Verify onCellularConnectivityChanged plumbs the information to the right locations. 9124 */ 9125 @Test testOnCellularConnectivityChanged()9126 public void testOnCellularConnectivityChanged() { 9127 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_AVAILABLE); 9128 verify(mWifiConfigManager).onCellularConnectivityChanged( 9129 WifiDataStall.CELLULAR_DATA_AVAILABLE); 9130 9131 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 9132 verify(mWifiConfigManager).onCellularConnectivityChanged( 9133 WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 9134 } 9135 9136 /** 9137 * Verify that when cellular data is lost and wifi is not connected, we force a connectivity 9138 * scan. 9139 */ 9140 @Test testOnCellularConnectivityChangedForceConnectivityScan()9141 public void testOnCellularConnectivityChangedForceConnectivityScan() throws Exception { 9142 mResources.setBoolean(R.bool.config_wifiScanOnCellularDataLossEnabled, true); 9143 // verify a connectivity scan is forced since wifi is not connected 9144 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 9145 verify(mWifiConnectivityManager).forceConnectivityScan(WIFI_WORK_SOURCE); 9146 9147 // verify that after wifi is connected, loss of cellular data will not trigger scans. 9148 connect(); 9149 mCmi.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE); 9150 verify(mWifiConnectivityManager).forceConnectivityScan(WIFI_WORK_SOURCE); 9151 } 9152 setScreenState(boolean screenOn)9153 private void setScreenState(boolean screenOn) { 9154 WifiDeviceStateChangeManager.StateChangeCallback callback = 9155 mStateChangeCallbackArgumentCaptor.getValue(); 9156 assertNotNull(callback); 9157 callback.onScreenStateChanged(screenOn); 9158 } 9159 9160 @Test verifyRssiPollOnScreenStateChange()9161 public void verifyRssiPollOnScreenStateChange() throws Exception { 9162 setScreenState(true); 9163 connect(); 9164 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9165 9166 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 9167 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 9168 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 9169 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 9170 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9171 mLooper.dispatchAll(); 9172 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 9173 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 9174 mConnectionCapabilities, null, oldLLStats, mWifiInfo, TEST_TX_BYTES, TEST_RX_BYTES); 9175 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 9176 9177 WifiLinkLayerStats newLLStats = new WifiLinkLayerStats(); 9178 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(newLLStats); 9179 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9180 mLooper.dispatchAll(); 9181 verify(mWifiNative, times(2)).getWifiLinkLayerStats(WIFI_IFACE_NAME); 9182 9183 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 9184 mConnectionCapabilities, oldLLStats, newLLStats, mWifiInfo, TEST_TX_BYTES, 9185 TEST_RX_BYTES); 9186 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, newLLStats); 9187 9188 // Now set the screen state to false & move time forward, ensure no more link layer stats 9189 // collection. 9190 setScreenState(false); 9191 mLooper.dispatchAll(); 9192 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9193 9194 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9195 mLooper.dispatchAll(); 9196 9197 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 9198 } 9199 9200 @Test verifyRssiPollOnSecondaryCmm()9201 public void verifyRssiPollOnSecondaryCmm() throws Exception { 9202 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 9203 mCmi.onRoleChanged(); 9204 setScreenState(true); 9205 connect(); 9206 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9207 9208 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 9209 9210 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 9211 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 9212 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(new WifiLinkLayerStats()); 9213 9214 // No link layer stats collection on secondary CMM. 9215 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9216 mLooper.dispatchAll(); 9217 9218 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 9219 } 9220 9221 @Test verifyRssiPollOnOnRoleChangeToPrimary()9222 public void verifyRssiPollOnOnRoleChangeToPrimary() throws Exception { 9223 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 9224 mCmi.onRoleChanged(); 9225 setScreenState(true); 9226 connect(); 9227 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9228 9229 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 9230 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 9231 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(new WifiLinkLayerStats()); 9232 9233 // No link layer stats collection on secondary CMM. 9234 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9235 mLooper.dispatchAll(); 9236 9237 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 9238 9239 // Now invoke role change, that should start rssi polling on the new primary. 9240 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY); 9241 mCmi.onRoleChanged(); 9242 mLooper.dispatchAll(); 9243 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9244 9245 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 9246 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 9247 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9248 mLooper.dispatchAll(); 9249 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 9250 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 9251 mConnectionCapabilities, null, oldLLStats, mWifiInfo, TEST_TX_BYTES, TEST_RX_BYTES); 9252 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 9253 } 9254 9255 @Test verifyRssiPollOnOnRoleChangeToSecondary()9256 public void verifyRssiPollOnOnRoleChangeToSecondary() throws Exception { 9257 setScreenState(true); 9258 connect(); 9259 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9260 9261 // RSSI polling is enabled on primary. 9262 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 9263 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 9264 WifiLinkLayerStats oldLLStats = new WifiLinkLayerStats(); 9265 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(oldLLStats); 9266 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9267 mLooper.dispatchAll(); 9268 verify(mWifiNative).getWifiLinkLayerStats(WIFI_IFACE_NAME); 9269 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 9270 mConnectionCapabilities, null, oldLLStats, mWifiInfo, TEST_TX_BYTES, TEST_RX_BYTES); 9271 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, oldLLStats); 9272 9273 // Now invoke role change, that should stop rssi polling on the secondary. 9274 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT); 9275 mCmi.onRoleChanged(); 9276 mLooper.dispatchAll(); 9277 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9278 9279 // No link layer stats collection on secondary CMM. 9280 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9281 mLooper.dispatchAll(); 9282 9283 verifyNoMoreInteractions(mWifiNative, mWifiMetrics, mWifiDataStall); 9284 } 9285 9286 @Test verifyRssiPollWhenLinkLayerStatsIsNotSupported()9287 public void verifyRssiPollWhenLinkLayerStatsIsNotSupported() throws Exception { 9288 setScreenState(true); 9289 connect(); 9290 clearInvocations(mWifiNative, mWifiMetrics, mWifiDataStall); 9291 9292 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(new BitSet()); 9293 WifiLinkLayerStats stats = new WifiLinkLayerStats(); 9294 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(stats); 9295 mLooper.moveTimeForward(mWifiGlobals.getPollRssiIntervalMillis()); 9296 mLooper.dispatchAll(); 9297 verify(mWifiNative, never()).getWifiLinkLayerStats(any()); 9298 verify(mWifiDataStall).checkDataStallAndThroughputSufficiency(WIFI_IFACE_NAME, 9299 mConnectionCapabilities, null, null, mWifiInfo, TEST_TX_BYTES, TEST_RX_BYTES); 9300 verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(WIFI_IFACE_NAME, null); 9301 } 9302 9303 @Test testClientModeImplWhenIpClientIsNotReady()9304 public void testClientModeImplWhenIpClientIsNotReady() throws Exception { 9305 WifiConfiguration config = mConnectedNetwork; 9306 config.networkId = FRAMEWORK_NETWORK_ID; 9307 config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 9308 config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 9309 config.getNetworkSelectionStatus().setHasEverConnected(mTestNetworkParams.hasEverConnected); 9310 assertNull(config.getNetworkSelectionStatus().getCandidateSecurityParams()); 9311 9312 mFrameworkFacade = mock(FrameworkFacade.class); 9313 ArgumentCaptor<IpClientCallbacks> captor = ArgumentCaptor.forClass(IpClientCallbacks.class); 9314 // reset mWifiNative since initializeCmi() was called in setup() 9315 resetWifiNative(); 9316 9317 // reinitialize ClientModeImpl with IpClient is not ready. 9318 initializeCmi(); 9319 verify(mFrameworkFacade).makeIpClient(any(), anyString(), captor.capture()); 9320 9321 // Manually connect should fail. 9322 IActionListener connectActionListener = mock(IActionListener.class); 9323 mCmi.connectNetwork( 9324 new NetworkUpdateResult(config.networkId), 9325 new ActionListenerWrapper(connectActionListener), 9326 Binder.getCallingUid(), OP_PACKAGE_NAME, null); 9327 mLooper.dispatchAll(); 9328 verify(connectActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR); 9329 verify(mWifiConfigManager, never()) 9330 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 9331 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 9332 9333 // Auto connect should also fail 9334 mCmi.startConnectToNetwork(config.networkId, MANAGED_PROFILE_UID, config.BSSID); 9335 mLooper.dispatchAll(); 9336 verify(mWifiConfigManager, never()) 9337 .getConfiguredNetworkWithoutMasking(eq(config.networkId)); 9338 verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 9339 9340 // Make IpClient ready connection should succeed. 9341 captor.getValue().onIpClientCreated(mIpClient); 9342 mLooper.dispatchAll(); 9343 9344 triggerConnect(); 9345 } 9346 testNetworkRemovedUpdatesLinkedNetworks(boolean isSecondary)9347 private void testNetworkRemovedUpdatesLinkedNetworks(boolean isSecondary) throws Exception { 9348 if (isSecondary) { 9349 when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED); 9350 } 9351 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9352 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9353 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9354 WifiConfiguration removeConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid2\""); 9355 removeConfig.networkId = FRAMEWORK_NETWORK_ID + 1; 9356 connectedConfig.linkedConfigurations = new HashMap<>(); 9357 connectedConfig.linkedConfigurations.put(removeConfig.getProfileKey(), 1); 9358 removeConfig.linkedConfigurations = new HashMap<>(); 9359 removeConfig.linkedConfigurations.put(connectedConfig.getProfileKey(), 1); 9360 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9361 .thenReturn(connectedConfig); 9362 when(mWifiConfigManager.getConfiguredNetwork(removeConfig.networkId)) 9363 .thenReturn(removeConfig); 9364 mConnectedNetwork = connectedConfig; 9365 connect(); 9366 9367 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9368 SecurityParams.createSecurityParamsBySecurityType( 9369 WifiConfiguration.SECURITY_TYPE_PSK)); 9370 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 9371 .getAllValues()) { 9372 listener.onNetworkRemoved(removeConfig); 9373 } 9374 mLooper.dispatchAll(); 9375 9376 if (!isSecondary) { 9377 verify(mWifiConfigManager).updateLinkedNetworks(connectedConfig.networkId); 9378 } else { 9379 verify(mWifiConfigManager, never()).updateLinkedNetworks(connectedConfig.networkId); 9380 } 9381 } 9382 9383 @Test testNetworkRemovedUpdatesLinkedNetworksPrimary()9384 public void testNetworkRemovedUpdatesLinkedNetworksPrimary() throws Exception { 9385 testNetworkRemovedUpdatesLinkedNetworks(false); 9386 } 9387 9388 @Test testNetworkRemovedUpdatesLinkedNetworksSecondary()9389 public void testNetworkRemovedUpdatesLinkedNetworksSecondary() throws Exception { 9390 testNetworkRemovedUpdatesLinkedNetworks(true); 9391 } 9392 9393 @Test testConnectClearsAllowlistSsids()9394 public void testConnectClearsAllowlistSsids() throws Exception { 9395 connect(); 9396 verify(mWifiBlocklistMonitor) 9397 .setAllowlistSsids(eq(mConnectedNetwork.SSID), eq(Collections.emptyList())); 9398 } 9399 9400 @Test testNetworkUpdatedUpdatesLinkedNetworks()9401 public void testNetworkUpdatedUpdatesLinkedNetworks() throws Exception { 9402 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9403 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9404 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9405 WifiConfiguration updatedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid2\""); 9406 updatedConfig.networkId = FRAMEWORK_NETWORK_ID + 1; 9407 connectedConfig.linkedConfigurations = new HashMap<>(); 9408 connectedConfig.linkedConfigurations.put(updatedConfig.getProfileKey(), 1); 9409 updatedConfig.linkedConfigurations = new HashMap<>(); 9410 updatedConfig.linkedConfigurations.put(connectedConfig.getProfileKey(), 1); 9411 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9412 .thenReturn(connectedConfig); 9413 when(mWifiConfigManager.getConfiguredNetwork(updatedConfig.networkId)) 9414 .thenReturn(updatedConfig); 9415 mConnectedNetwork = connectedConfig; 9416 connect(); 9417 9418 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9419 SecurityParams.createSecurityParamsBySecurityType( 9420 WifiConfiguration.SECURITY_TYPE_PSK)); 9421 IActionListener connectActionListener = mock(IActionListener.class); 9422 mCmi.saveNetwork( 9423 new NetworkUpdateResult( 9424 updatedConfig.networkId, STATUS_SUCCESS, false, false, true, false), 9425 new ActionListenerWrapper(connectActionListener), 9426 Binder.getCallingUid(), OP_PACKAGE_NAME); 9427 mLooper.dispatchAll(); 9428 9429 verify(mWifiConfigManager).updateLinkedNetworks(connectedConfig.networkId); 9430 } 9431 9432 @Test testNetworkValidationUpdatesLinkedNetworks()9433 public void testNetworkValidationUpdatesLinkedNetworks() throws Exception { 9434 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9435 BufferedReader reader = mock(BufferedReader.class); 9436 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9437 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9438 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9439 .thenReturn(connectedConfig); 9440 mConnectedNetwork = connectedConfig; 9441 connect(); 9442 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 9443 mWifiNetworkAgentCallbackCaptor.capture()); 9444 verify(mWifiBlocklistMonitor).setAllowlistSsids( 9445 eq(connectedConfig.SSID), eq(Collections.emptyList())); 9446 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration( 9447 eq(Set.of(connectedConfig.SSID))); 9448 9449 LinkProperties linkProperties = mock(LinkProperties.class); 9450 RouteInfo routeInfo = mock(RouteInfo.class); 9451 IpPrefix ipPrefix = mock(IpPrefix.class); 9452 Inet4Address destinationAddress = mock(Inet4Address.class); 9453 InetAddress gatewayAddress = mock(InetAddress.class); 9454 String hostAddress = "127.0.0.1"; 9455 String gatewayMac = "192.168.0.1"; 9456 when(linkProperties.getRoutes()).thenReturn(Arrays.asList(routeInfo)); 9457 when(routeInfo.isDefaultRoute()).thenReturn(true); 9458 when(routeInfo.getDestination()).thenReturn(ipPrefix); 9459 when(ipPrefix.getAddress()).thenReturn(destinationAddress); 9460 when(routeInfo.hasGateway()).thenReturn(true); 9461 when(routeInfo.getGateway()).thenReturn(gatewayAddress); 9462 when(gatewayAddress.getHostAddress()).thenReturn(hostAddress); 9463 when(mWifiInjector.createBufferedReader(ARP_TABLE_PATH)).thenReturn(reader); 9464 when(reader.readLine()).thenReturn(new StringJoiner(" ") 9465 .add(hostAddress) 9466 .add("HWType") 9467 .add("Flags") 9468 .add(gatewayMac) 9469 .add("Mask") 9470 .add("Device") 9471 .toString()); 9472 9473 mIpClientCallback.onLinkPropertiesChange(linkProperties); 9474 mLooper.dispatchAll(); 9475 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9476 SecurityParams.createSecurityParamsBySecurityType( 9477 WifiConfiguration.SECURITY_TYPE_PSK)); 9478 when(mWifiConfigManager.setNetworkDefaultGwMacAddress(anyInt(), any())).thenReturn(true); 9479 when(mWifiConfigManager.saveToStore()).thenReturn(true); 9480 WifiConfiguration linkedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid2\""); 9481 linkedConfig.networkId = connectedConfig.networkId + 1; 9482 Map<String, WifiConfiguration> linkedNetworks = new HashMap<>(); 9483 linkedNetworks.put(linkedConfig.getProfileKey(), linkedConfig); 9484 when(mWifiConfigManager.getLinkedNetworksWithoutMasking(connectedConfig.networkId)) 9485 .thenReturn(linkedNetworks); 9486 when(mWifiNative.updateLinkedNetworks(any(), anyInt(), any())).thenReturn(true); 9487 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9488 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9489 mLooper.dispatchAll(); 9490 9491 verify(mWifiConfigManager) 9492 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9493 verify(mWifiConfigManager).updateLinkedNetworks(connectedConfig.networkId); 9494 verify(mWifiNative).updateLinkedNetworks( 9495 any(), eq(connectedConfig.networkId), eq(linkedNetworks)); 9496 List<String> allowlistSsids = new ArrayList<>(); 9497 allowlistSsids.add(linkedConfig.SSID); 9498 allowlistSsids.add(connectedConfig.SSID); 9499 verify(mWifiBlocklistMonitor).setAllowlistSsids( 9500 eq(connectedConfig.SSID), eq(allowlistSsids)); 9501 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration( 9502 eq(new ArraySet<>(allowlistSsids))); 9503 } 9504 9505 @Test testNonPskNetworkDoesNotUpdateLinkedNetworks()9506 public void testNonPskNetworkDoesNotUpdateLinkedNetworks() throws Exception { 9507 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9508 BufferedReader reader = mock(BufferedReader.class); 9509 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9510 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9511 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9512 .thenReturn(connectedConfig); 9513 mConnectedNetwork = connectedConfig; 9514 connect(); 9515 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 9516 mWifiNetworkAgentCallbackCaptor.capture()); 9517 9518 LinkProperties linkProperties = mock(LinkProperties.class); 9519 RouteInfo routeInfo = mock(RouteInfo.class); 9520 IpPrefix ipPrefix = mock(IpPrefix.class); 9521 Inet4Address destinationAddress = mock(Inet4Address.class); 9522 InetAddress gatewayAddress = mock(InetAddress.class); 9523 String hostAddress = "127.0.0.1"; 9524 String gatewayMac = "192.168.0.1"; 9525 when(linkProperties.getRoutes()).thenReturn(Arrays.asList(routeInfo)); 9526 when(routeInfo.isDefaultRoute()).thenReturn(true); 9527 when(routeInfo.getDestination()).thenReturn(ipPrefix); 9528 when(ipPrefix.getAddress()).thenReturn(destinationAddress); 9529 when(routeInfo.hasGateway()).thenReturn(true); 9530 when(routeInfo.getGateway()).thenReturn(gatewayAddress); 9531 when(gatewayAddress.getHostAddress()).thenReturn(hostAddress); 9532 when(mWifiInjector.createBufferedReader(ARP_TABLE_PATH)).thenReturn(reader); 9533 when(reader.readLine()).thenReturn(new StringJoiner(" ") 9534 .add(hostAddress) 9535 .add("HWType") 9536 .add("Flags") 9537 .add(gatewayMac) 9538 .add("Mask") 9539 .add("Device") 9540 .toString()); 9541 9542 mIpClientCallback.onLinkPropertiesChange(linkProperties); 9543 mLooper.dispatchAll(); 9544 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9545 SecurityParams.createSecurityParamsBySecurityType( 9546 WifiConfiguration.SECURITY_TYPE_SAE)); 9547 when(mWifiConfigManager.setNetworkDefaultGwMacAddress(anyInt(), any())).thenReturn(true); 9548 when(mWifiConfigManager.saveToStore()).thenReturn(true); 9549 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9550 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9551 mLooper.dispatchAll(); 9552 9553 verify(mWifiConfigManager) 9554 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9555 verify(mWifiConfigManager, never()).updateLinkedNetworks(connectedConfig.networkId); 9556 } 9557 9558 @Test testInvalidScanResultDoesNotUpdateLinkedNetworks()9559 public void testInvalidScanResultDoesNotUpdateLinkedNetworks() throws Exception { 9560 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9561 BufferedReader reader = mock(BufferedReader.class); 9562 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9563 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9564 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9565 .thenReturn(connectedConfig); 9566 mConnectedNetwork = connectedConfig; 9567 connect(); 9568 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 9569 mWifiNetworkAgentCallbackCaptor.capture()); 9570 9571 LinkProperties linkProperties = mock(LinkProperties.class); 9572 RouteInfo routeInfo = mock(RouteInfo.class); 9573 IpPrefix ipPrefix = mock(IpPrefix.class); 9574 Inet4Address destinationAddress = mock(Inet4Address.class); 9575 InetAddress gatewayAddress = mock(InetAddress.class); 9576 String hostAddress = "127.0.0.1"; 9577 String gatewayMac = "192.168.0.1"; 9578 when(linkProperties.getRoutes()).thenReturn(Arrays.asList(routeInfo)); 9579 when(routeInfo.isDefaultRoute()).thenReturn(true); 9580 when(routeInfo.getDestination()).thenReturn(ipPrefix); 9581 when(ipPrefix.getAddress()).thenReturn(destinationAddress); 9582 when(routeInfo.hasGateway()).thenReturn(true); 9583 when(routeInfo.getGateway()).thenReturn(gatewayAddress); 9584 when(gatewayAddress.getHostAddress()).thenReturn(hostAddress); 9585 when(mWifiInjector.createBufferedReader(ARP_TABLE_PATH)).thenReturn(reader); 9586 when(reader.readLine()).thenReturn(new StringJoiner(" ") 9587 .add(hostAddress) 9588 .add("HWType") 9589 .add("Flags") 9590 .add(gatewayMac) 9591 .add("Mask") 9592 .add("Device") 9593 .toString()); 9594 9595 mIpClientCallback.onLinkPropertiesChange(linkProperties); 9596 mLooper.dispatchAll(); 9597 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9598 SecurityParams.createSecurityParamsBySecurityType( 9599 WifiConfiguration.SECURITY_TYPE_PSK)); 9600 when(mWifiConfigManager.setNetworkDefaultGwMacAddress(anyInt(), any())).thenReturn(true); 9601 when(mWifiConfigManager.saveToStore()).thenReturn(true); 9602 9603 // FT/PSK scan, do not update linked networks 9604 ScanResult ftPskScan = new ScanResult(); 9605 ftPskScan.capabilities = "FT/PSK"; 9606 when(mScanDetailCache.getScanResult(any())).thenReturn(ftPskScan); 9607 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9608 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9609 mLooper.dispatchAll(); 9610 verify(mWifiConfigManager) 9611 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9612 verify(mWifiConfigManager, never()).updateLinkedNetworks(connectedConfig.networkId); 9613 9614 // FT/SAE scan, do not update linked networks 9615 ScanResult ftSaeScan = new ScanResult(); 9616 ftSaeScan.capabilities = "FT/SAE"; 9617 when(mScanRequestProxy.getScanResult(any())).thenReturn(ftSaeScan); 9618 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9619 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9620 mLooper.dispatchAll(); 9621 verify(mWifiConfigManager) 9622 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9623 verify(mWifiConfigManager, never()).updateLinkedNetworks(connectedConfig.networkId); 9624 9625 // Null scan, do not update linked networks 9626 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9627 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9628 mLooper.dispatchAll(); 9629 verify(mWifiConfigManager) 9630 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9631 verify(mWifiConfigManager, never()).updateLinkedNetworks(connectedConfig.networkId); 9632 } 9633 9634 @Test testLinkedNetworksFiltersOutAutojoinDisabledNetworks()9635 public void testLinkedNetworksFiltersOutAutojoinDisabledNetworks() throws Exception { 9636 mResources.setBoolean(R.bool.config_wifiEnableLinkedNetworkRoaming, true); 9637 BufferedReader reader = mock(BufferedReader.class); 9638 WifiConfiguration connectedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid1\""); 9639 connectedConfig.networkId = FRAMEWORK_NETWORK_ID; 9640 when(mWifiConfigManager.getConfiguredNetwork(connectedConfig.networkId)) 9641 .thenReturn(connectedConfig); 9642 mConnectedNetwork = connectedConfig; 9643 connect(); 9644 verify(mWifiInjector).makeWifiNetworkAgent(any(), any(), any(), any(), 9645 mWifiNetworkAgentCallbackCaptor.capture()); 9646 verify(mWifiBlocklistMonitor).setAllowlistSsids( 9647 eq(connectedConfig.SSID), eq(Collections.emptyList())); 9648 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration( 9649 eq(Set.of(connectedConfig.SSID))); 9650 9651 LinkProperties linkProperties = mock(LinkProperties.class); 9652 RouteInfo routeInfo = mock(RouteInfo.class); 9653 IpPrefix ipPrefix = mock(IpPrefix.class); 9654 Inet4Address destinationAddress = mock(Inet4Address.class); 9655 InetAddress gatewayAddress = mock(InetAddress.class); 9656 String hostAddress = "127.0.0.1"; 9657 String gatewayMac = "192.168.0.1"; 9658 when(linkProperties.getRoutes()).thenReturn(Arrays.asList(routeInfo)); 9659 when(routeInfo.isDefaultRoute()).thenReturn(true); 9660 when(routeInfo.getDestination()).thenReturn(ipPrefix); 9661 when(ipPrefix.getAddress()).thenReturn(destinationAddress); 9662 when(routeInfo.hasGateway()).thenReturn(true); 9663 when(routeInfo.getGateway()).thenReturn(gatewayAddress); 9664 when(gatewayAddress.getHostAddress()).thenReturn(hostAddress); 9665 when(mWifiInjector.createBufferedReader(ARP_TABLE_PATH)).thenReturn(reader); 9666 when(reader.readLine()).thenReturn(new StringJoiner(" ") 9667 .add(hostAddress) 9668 .add("HWType") 9669 .add("Flags") 9670 .add(gatewayMac) 9671 .add("Mask") 9672 .add("Device") 9673 .toString()); 9674 9675 mIpClientCallback.onLinkPropertiesChange(linkProperties); 9676 mLooper.dispatchAll(); 9677 when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn( 9678 SecurityParams.createSecurityParamsBySecurityType( 9679 WifiConfiguration.SECURITY_TYPE_PSK)); 9680 when(mWifiConfigManager.setNetworkDefaultGwMacAddress(anyInt(), any())).thenReturn(true); 9681 when(mWifiConfigManager.saveToStore()).thenReturn(true); 9682 WifiConfiguration linkedConfig = WifiConfigurationTestUtil.createPskNetwork("\"ssid2\""); 9683 linkedConfig.networkId = connectedConfig.networkId + 1; 9684 linkedConfig.allowAutojoin = false; 9685 Map<String, WifiConfiguration> linkedNetworks = new HashMap<>(); 9686 linkedNetworks.put(linkedConfig.getProfileKey(), linkedConfig); 9687 when(mWifiConfigManager.getLinkedNetworksWithoutMasking(connectedConfig.networkId)) 9688 .thenReturn(linkedNetworks); 9689 when(mWifiNative.updateLinkedNetworks(any(), anyInt(), any())).thenReturn(true); 9690 mWifiNetworkAgentCallbackCaptor.getValue().onValidationStatus( 9691 NetworkAgent.VALIDATION_STATUS_VALID, null /* captivePortalUrl */); 9692 mLooper.dispatchAll(); 9693 9694 verify(mWifiConfigManager) 9695 .setNetworkDefaultGwMacAddress(mConnectedNetwork.networkId, gatewayMac); 9696 verify(mWifiConfigManager).updateLinkedNetworks(connectedConfig.networkId); 9697 verify(mWifiNative).updateLinkedNetworks( 9698 any(), eq(connectedConfig.networkId), eq(linkedNetworks)); 9699 verify(mWifiBlocklistMonitor, times(2)).setAllowlistSsids( 9700 eq(connectedConfig.SSID), eq(Collections.emptyList())); 9701 verify(mWifiBlocklistMonitor).updateFirmwareRoamingConfiguration( 9702 eq(Collections.emptySet())); 9703 } 9704 9705 /** 9706 * Verify that we disconnect when we mark a previous trusted network untrusted. 9707 */ 9708 @Test verifyDisconnectOnMarkingNetworkUntrusted()9709 public void verifyDisconnectOnMarkingNetworkUntrusted() throws Exception { 9710 assumeTrue(SdkLevel.isAtLeastT()); 9711 connect(); 9712 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 9713 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)); 9714 }); 9715 9716 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 9717 mConnectedNetwork.trusted = false; 9718 9719 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 9720 .getAllValues()) { 9721 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 9722 } 9723 mLooper.dispatchAll(); 9724 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 9725 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 9726 eq(StaEvent.DISCONNECT_NETWORK_UNTRUSTED)); 9727 } 9728 9729 /** 9730 * Verify that we only update capabilities when we mark a previous untrusted network trusted. 9731 */ 9732 @Test verifyUpdateCapabilitiesOnMarkingNetworkTrusted()9733 public void verifyUpdateCapabilitiesOnMarkingNetworkTrusted() throws Exception { 9734 assumeTrue(SdkLevel.isAtLeastT()); 9735 mConnectedNetwork.trusted = false; 9736 connect(); 9737 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 9738 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)); 9739 }); 9740 reset(mWifiNetworkAgent); 9741 9742 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 9743 mConnectedNetwork.trusted = true; 9744 9745 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 9746 .getAllValues()) { 9747 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 9748 } 9749 mLooper.dispatchAll(); 9750 assertEquals("L3ConnectedState", getCurrentState().getName()); 9751 9752 expectNetworkAgentUpdateCapabilities((cap) -> { 9753 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)); 9754 }); 9755 } 9756 9757 /** 9758 * Verify on device before T we will not disconnect when we mark a previous trusted network 9759 * untrusted. 9760 */ 9761 @Test verifyNoDisconnectOnMarkingNetworkUntrustedBeforeT()9762 public void verifyNoDisconnectOnMarkingNetworkUntrustedBeforeT() throws Exception { 9763 assumeFalse(SdkLevel.isAtLeastT()); 9764 connect(); 9765 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 9766 assertTrue(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)); 9767 }); 9768 9769 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 9770 mConnectedNetwork.trusted = false; 9771 9772 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 9773 .getAllValues()) { 9774 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 9775 } 9776 mLooper.dispatchAll(); 9777 verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME); 9778 verify(mWifiMetrics, never()).logStaEvent(anyString(), anyInt(), anyInt()); 9779 } 9780 9781 /** 9782 * Verify on a build before T we will not update capabilities or disconnect when we mark a 9783 * previous untrusted network trusted. 9784 */ 9785 @Test verifyNoUpdateCapabilitiesOnMarkingNetworkTrustedBeforeT()9786 public void verifyNoUpdateCapabilitiesOnMarkingNetworkTrustedBeforeT() throws Exception { 9787 assumeFalse(SdkLevel.isAtLeastT()); 9788 mConnectedNetwork.trusted = false; 9789 connect(); 9790 expectRegisterNetworkAgent((config) -> { }, (cap) -> { 9791 assertFalse(cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)); 9792 }); 9793 reset(mWifiNetworkAgent); 9794 9795 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 9796 mConnectedNetwork.trusted = true; 9797 9798 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 9799 .getAllValues()) { 9800 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 9801 } 9802 mLooper.dispatchAll(); 9803 assertEquals("L3ConnectedState", getCurrentState().getName()); 9804 verifyNoMoreInteractions(mWifiNetworkAgent); 9805 } 9806 verifyUpdateAutoUpgradeFlagForSaeOnR( boolean isWpa3SaeUpgradeEnabled, boolean isWpa2PersonalOnlyNetworkInRange, boolean isWpa2Wpa3PersonalTransitionNetworkInRange, boolean isWpa3PersonalOnlyNetworkInRange, boolean shouldBeUpdated)9807 private void verifyUpdateAutoUpgradeFlagForSaeOnR( 9808 boolean isWpa3SaeUpgradeEnabled, boolean isWpa2PersonalOnlyNetworkInRange, 9809 boolean isWpa2Wpa3PersonalTransitionNetworkInRange, 9810 boolean isWpa3PersonalOnlyNetworkInRange, boolean shouldBeUpdated) 9811 throws Exception { 9812 9813 when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(isWpa3SaeUpgradeEnabled); 9814 when(mScanRequestProxy.isWpa2PersonalOnlyNetworkInRange(any())) 9815 .thenReturn(isWpa2PersonalOnlyNetworkInRange); 9816 when(mScanRequestProxy.isWpa2Wpa3PersonalTransitionNetworkInRange(any())) 9817 .thenReturn(isWpa2Wpa3PersonalTransitionNetworkInRange); 9818 when(mScanRequestProxy.isWpa3PersonalOnlyNetworkInRange(any())) 9819 .thenReturn(isWpa3PersonalOnlyNetworkInRange); 9820 initializeAndAddNetworkAndVerifySuccess(); 9821 9822 WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork(); 9823 config.networkId = TEST_NETWORK_ID; 9824 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 9825 9826 IActionListener connectActionListener = mock(IActionListener.class); 9827 mCmi.connectNetwork( 9828 new NetworkUpdateResult(TEST_NETWORK_ID), 9829 new ActionListenerWrapper(connectActionListener), 9830 Process.SYSTEM_UID, OP_PACKAGE_NAME, null); 9831 mLooper.dispatchAll(); 9832 verify(connectActionListener).onSuccess(); 9833 if (shouldBeUpdated) { 9834 verify(mWifiConfigManager).updateIsAddedByAutoUpgradeFlag( 9835 eq(TEST_NETWORK_ID), eq(WifiConfiguration.SECURITY_TYPE_SAE), 9836 eq(false)); 9837 } else { 9838 verify(mWifiConfigManager, never()).updateIsAddedByAutoUpgradeFlag( 9839 anyInt(), anyInt(), anyBoolean()); 9840 } 9841 } 9842 9843 /** 9844 * Tests that manual connection to a network (from settings app) updates 9845 * the auto upgrade flag for SAE on R. 9846 * - SAE auto-upgrade is disabled. 9847 * - No WPA2 PSK network 9848 * - No WPA2/WPA3 network 9849 * - A WPA3-SAE-only network exists. 9850 */ 9851 @Test testManualConnectUpdateAutoUpgradeFlagForSaeOnR()9852 public void testManualConnectUpdateAutoUpgradeFlagForSaeOnR() throws Exception { 9853 assumeFalse(SdkLevel.isAtLeastS()); 9854 9855 verifyUpdateAutoUpgradeFlagForSaeOnR(false, false, false, true, true); 9856 } 9857 9858 /** 9859 * Tests that manual connection to a network (from settings app) does not update 9860 * the auto upgrade flag for SAE on R if auto-upgrade is enabled. 9861 */ 9862 @Test testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWhenAutoUpgradeEnabled()9863 public void testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWhenAutoUpgradeEnabled() 9864 throws Exception { 9865 assumeFalse(SdkLevel.isAtLeastS()); 9866 9867 verifyUpdateAutoUpgradeFlagForSaeOnR(true, false, false, true, false); 9868 } 9869 9870 /** 9871 * Tests that manual connection to a network (from settings app) does not update 9872 * the auto upgrade flag for SAE on R if there are psk networks. 9873 */ 9874 @Test testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithPskNetworks()9875 public void testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithPskNetworks() 9876 throws Exception { 9877 assumeFalse(SdkLevel.isAtLeastS()); 9878 9879 verifyUpdateAutoUpgradeFlagForSaeOnR(false, true, false, true, false); 9880 } 9881 9882 /** 9883 * Tests that manual connection to a network (from settings app) does not update 9884 * the auto upgrade flag for SAE on R if there are psk/ase networks. 9885 */ 9886 @Test testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithPskSaeNetworks()9887 public void testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithPskSaeNetworks() 9888 throws Exception { 9889 assumeFalse(SdkLevel.isAtLeastS()); 9890 9891 verifyUpdateAutoUpgradeFlagForSaeOnR(false, false, true, true, false); 9892 } 9893 9894 /** 9895 * Tests that manual connection to a network (from settings app) does not update 9896 * the auto upgrade flag for SAE on R if there is no WPA3 SAE only network.. 9897 */ 9898 @Test testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithoutSaeOnlyNetworks()9899 public void testManualConnectNotUpdateAutoUpgradeFlagForSaeOnRWithoutSaeOnlyNetworks() 9900 throws Exception { 9901 assumeFalse(SdkLevel.isAtLeastS()); 9902 9903 verifyUpdateAutoUpgradeFlagForSaeOnR(false, false, true, true, false); 9904 } 9905 setupLegacyEapNetworkTest(boolean isUserSelected)9906 private WifiConfiguration setupLegacyEapNetworkTest(boolean isUserSelected) throws Exception { 9907 return setupTrustOnFirstUse(false, false, isUserSelected); 9908 } 9909 setupTrustOnFirstUse( boolean isAtLeastT, boolean isTrustOnFirstUseSupported, boolean isUserSelected)9910 private WifiConfiguration setupTrustOnFirstUse( 9911 boolean isAtLeastT, boolean isTrustOnFirstUseSupported, boolean isUserSelected) 9912 throws Exception { 9913 if (isTrustOnFirstUseSupported) { 9914 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 9915 createCapabilityBitset(WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE)); 9916 } 9917 mCmi.mInsecureEapNetworkHandler = mInsecureEapNetworkHandler; 9918 9919 WifiConfiguration eapTlsConfig = spy(WifiConfigurationTestUtil.createEapNetwork( 9920 WifiEnterpriseConfig.Eap.TLS, WifiEnterpriseConfig.Phase2.NONE)); 9921 eapTlsConfig.networkId = FRAMEWORK_NETWORK_ID; 9922 eapTlsConfig.SSID = TEST_SSID; 9923 if (isAtLeastT && isTrustOnFirstUseSupported) { 9924 eapTlsConfig.enterpriseConfig.enableTrustOnFirstUse(true); 9925 } 9926 eapTlsConfig.enterpriseConfig.setCaPath(""); 9927 eapTlsConfig.enterpriseConfig.setDomainSuffixMatch(""); 9928 eapTlsConfig.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS); 9929 eapTlsConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO; 9930 9931 initializeAndAddNetworkAndVerifySuccess(eapTlsConfig); 9932 9933 if (isUserSelected) { 9934 startConnectSuccess(); 9935 } else { 9936 mCmi.startConnectToNetwork( 9937 eapTlsConfig.networkId, 9938 Process.SYSTEM_UID, 9939 ClientModeImpl.SUPPLICANT_BSSID_ANY); 9940 mLooper.dispatchAll(); 9941 } 9942 verify(mInsecureEapNetworkHandler).prepareConnection(eq(eapTlsConfig)); 9943 9944 if (isTrustOnFirstUseSupported) { 9945 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 9946 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 9947 SupplicantState.ASSOCIATED)); 9948 mLooper.dispatchAll(); 9949 9950 CertificateEventInfo certificateEventInfo = 9951 spy(new CertificateEventInfo(FakeKeys.CA_CERT0, "1234")); 9952 mCmi.sendMessage(WifiMonitor.TOFU_CERTIFICATE_EVENT, 9953 FRAMEWORK_NETWORK_ID, 0, certificateEventInfo); 9954 mLooper.dispatchAll(); 9955 verify(mInsecureEapNetworkHandler).addPendingCertificate( 9956 eq(eapTlsConfig.networkId), eq(0), eq(certificateEventInfo)); 9957 9958 // Adding a certificate in depth 0 will cause a disconnection when TOFU is supported 9959 DisconnectEventInfo disconnectEventInfo = 9960 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 3, true); 9961 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 9962 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 9963 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 9964 SupplicantState.DISCONNECTED)); 9965 mLooper.dispatchAll(); 9966 } 9967 9968 verify(mInsecureEapNetworkHandler).startUserApprovalIfNecessary(eq(isUserSelected)); 9969 if (isTrustOnFirstUseSupported) { 9970 assertEquals("DisconnectedState", getCurrentState().getName()); 9971 } 9972 return eapTlsConfig; 9973 } 9974 9975 /** 9976 * Verify Trust On First Use support. 9977 * - This network is selected by a user. 9978 * - Accept the connection. 9979 */ 9980 @Test verifyTrustOnFirstUseAcceptWhenConnectByUser()9981 public void verifyTrustOnFirstUseAcceptWhenConnectByUser() throws Exception { 9982 assumeTrue(SdkLevel.isAtLeastT()); 9983 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, true); 9984 9985 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onAccept(testConfig.SSID, 9986 testConfig.networkId); 9987 mLooper.dispatchAll(); 9988 ArgumentCaptor<WifiConfiguration> wifiConfigurationArgumentCaptor = 9989 ArgumentCaptor.forClass(WifiConfiguration.class); 9990 9991 // TOFU will first connect to get the certificates, and then connect once approved 9992 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), 9993 wifiConfigurationArgumentCaptor.capture()); 9994 assertEquals(testConfig.networkId, wifiConfigurationArgumentCaptor.getValue().networkId); 9995 } 9996 9997 /** 9998 * Verify Trust On First Use support. 9999 * - This network is selected by a user. 10000 * - Reject the connection. 10001 */ 10002 @Test verifyTrustOnFirstUseRejectWhenConnectByUser()10003 public void verifyTrustOnFirstUseRejectWhenConnectByUser() throws Exception { 10004 assumeTrue(SdkLevel.isAtLeastT()); 10005 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, true); 10006 10007 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onReject(testConfig.SSID, false); 10008 mLooper.dispatchAll(); 10009 verify(mWifiConnectivityManager, never()) 10010 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10011 verify(mWifiMetrics).endConnectionEvent( 10012 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 10013 eq(WifiMetricsProto.ConnectionEvent.HLF_NONE), 10014 eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN), 10015 anyInt(), anyInt()); 10016 ArgumentCaptor<WifiConfiguration> wifiConfigurationArgumentCaptor = 10017 ArgumentCaptor.forClass(WifiConfiguration.class); 10018 10019 // TOFU will connect only once to get the certificates, but will not proceed 10020 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), 10021 wifiConfigurationArgumentCaptor.capture()); 10022 assertEquals(testConfig.networkId, wifiConfigurationArgumentCaptor.getValue().networkId); 10023 10024 } 10025 10026 /** 10027 * Verify Trust On First Use support. 10028 * - This network is selected by a user. 10029 * - Errors occur in InsecureEapNetworkHandler. 10030 */ 10031 @Test verifyTrustOnFirstUseErrorWhenConnectByUser()10032 public void verifyTrustOnFirstUseErrorWhenConnectByUser() throws Exception { 10033 assumeTrue(SdkLevel.isAtLeastT()); 10034 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, true); 10035 10036 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onError(testConfig.SSID); 10037 mLooper.dispatchAll(); 10038 verify(mWifiConnectivityManager, never()) 10039 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10040 verify(mWifiMetrics).endConnectionEvent( 10041 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 10042 eq(WifiMetricsProto.ConnectionEvent.HLF_NONE), 10043 eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN), 10044 anyInt(), anyInt()); 10045 } 10046 10047 /** 10048 * Verify Trust On First Use support. 10049 * - this network is automatically connected. 10050 * - Tap the notification. 10051 * - Accept the connection. 10052 */ 10053 @Test verifyTrustOnFirstUseAcceptWhenAutoConnect()10054 public void verifyTrustOnFirstUseAcceptWhenAutoConnect() throws Exception { 10055 assumeTrue(SdkLevel.isAtLeastT()); 10056 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, false); 10057 10058 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onAccept(testConfig.SSID, 10059 testConfig.networkId); 10060 mLooper.dispatchAll(); 10061 ArgumentCaptor<WifiConfiguration> wifiConfigurationArgumentCaptor = 10062 ArgumentCaptor.forClass(WifiConfiguration.class); 10063 10064 // TOFU will first connect to get the certificates, and then connect once approved 10065 verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), 10066 wifiConfigurationArgumentCaptor.capture()); 10067 assertEquals(testConfig.networkId, wifiConfigurationArgumentCaptor.getValue().networkId); 10068 } 10069 10070 /** 10071 * Verify Trust On First Use support. 10072 * - this network is automatically connected. 10073 * - Tap the notification 10074 * - Reject the connection. 10075 */ 10076 @Test verifyTrustOnFirstUseRejectWhenAutoConnect()10077 public void verifyTrustOnFirstUseRejectWhenAutoConnect() throws Exception { 10078 assumeTrue(SdkLevel.isAtLeastT()); 10079 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, false); 10080 10081 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onReject(testConfig.SSID, false); 10082 mLooper.dispatchAll(); 10083 verify(mWifiConnectivityManager, never()) 10084 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10085 verify(mWifiMetrics).endConnectionEvent( 10086 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 10087 eq(WifiMetricsProto.ConnectionEvent.HLF_NONE), 10088 eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN), 10089 anyInt(), anyInt()); 10090 ArgumentCaptor<WifiConfiguration> wifiConfigurationArgumentCaptor = 10091 ArgumentCaptor.forClass(WifiConfiguration.class); 10092 10093 // TOFU will connect only once to get the certificates, but will not proceed 10094 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), 10095 wifiConfigurationArgumentCaptor.capture()); 10096 assertEquals(testConfig.networkId, wifiConfigurationArgumentCaptor.getValue().networkId); 10097 } 10098 10099 /** 10100 * Verify Trust On First Use support. 10101 * - This network is automatically connected. 10102 * - Errors occur in InsecureEapNetworkHandler. 10103 */ 10104 @Test verifyTrustOnFirstUseErrorWhenAutoConnect()10105 public void verifyTrustOnFirstUseErrorWhenAutoConnect() throws Exception { 10106 assumeTrue(SdkLevel.isAtLeastT()); 10107 WifiConfiguration testConfig = setupTrustOnFirstUse(true, true, false); 10108 10109 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onError(testConfig.SSID); 10110 mLooper.dispatchAll(); 10111 verify(mWifiConnectivityManager, never()) 10112 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10113 verify(mWifiMetrics).endConnectionEvent( 10114 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION), 10115 eq(WifiMetricsProto.ConnectionEvent.HLF_NONE), 10116 eq(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN), 10117 anyInt(), anyInt()); 10118 } 10119 10120 /** 10121 * Verify that InsecureEapNetworkHandler cleanup() is called if wifi is disabled. 10122 */ 10123 @Test verifyInsecureEapNetworkCleanUpWhenDisabled()10124 public void verifyInsecureEapNetworkCleanUpWhenDisabled() throws Exception { 10125 mCmi.stop(); 10126 mLooper.dispatchAll(); 10127 verify(mInsecureEapNetworkHandler).cleanup(); 10128 } 10129 10130 /** 10131 * Verify legacy EAP network handling. 10132 * - This network is selected by a user. 10133 * - Accept the connection. 10134 */ 10135 @Test verifyLegacyEapNetworkAcceptWhenConnectByUser()10136 public void verifyLegacyEapNetworkAcceptWhenConnectByUser() throws Exception { 10137 assumeFalse(SdkLevel.isAtLeastT()); 10138 WifiConfiguration testConfig = setupLegacyEapNetworkTest(true); 10139 10140 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onAccept(testConfig.SSID, 10141 testConfig.networkId); 10142 mLooper.dispatchAll(); 10143 verify(mWifiMetrics, never()).endConnectionEvent( 10144 any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); 10145 } 10146 10147 /** 10148 * Verify legacy EAP network handling. 10149 * - This network is selected by a user. 10150 * - Reject the connection. 10151 */ 10152 @Test verifyLegacyEapNetworkRejectWhenConnectByUser()10153 public void verifyLegacyEapNetworkRejectWhenConnectByUser() throws Exception { 10154 assumeFalse(SdkLevel.isAtLeastT()); 10155 WifiConfiguration testConfig = setupLegacyEapNetworkTest(true); 10156 10157 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onReject(testConfig.SSID, true); 10158 mLooper.dispatchAll(); 10159 verify(mWifiConnectivityManager, never()) 10160 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10161 verify(mWifiNative).disconnect(eq(WIFI_IFACE_NAME)); 10162 } 10163 10164 /** 10165 * Verify legacy EAP network handling. 10166 * - This network is automatically connected. 10167 * - Tap "connect anyway" on the notification. 10168 */ 10169 @Test verifyLegacyEapNetworkAcceptOnNotificationWhenAutoConnect()10170 public void verifyLegacyEapNetworkAcceptOnNotificationWhenAutoConnect() throws Exception { 10171 assumeFalse(SdkLevel.isAtLeastT()); 10172 WifiConfiguration testConfig = setupLegacyEapNetworkTest(false); 10173 10174 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onAccept(testConfig.SSID, 10175 testConfig.networkId); 10176 mLooper.dispatchAll(); 10177 verify(mWifiMetrics, never()).endConnectionEvent( 10178 any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); 10179 } 10180 10181 /** 10182 * Verify legacy EAP network handling. 10183 * - This network is automatically connected. 10184 * - Tap "Disconnect now" on the notification 10185 */ 10186 @Test verifyLegacyEapNetworkRejectOnNotificationWhenAutoConnect()10187 public void verifyLegacyEapNetworkRejectOnNotificationWhenAutoConnect() throws Exception { 10188 assumeFalse(SdkLevel.isAtLeastT()); 10189 WifiConfiguration testConfig = setupLegacyEapNetworkTest(false); 10190 10191 mCmi.mInsecureEapNetworkHandlerCallbacksImpl.onReject(testConfig.SSID, true); 10192 mLooper.dispatchAll(); 10193 verify(mFrameworkFacade, never()).makeAlertDialogBuilder(any()); 10194 verify(mWifiConnectivityManager, never()) 10195 .forceConnectivityScan(eq(ClientModeImpl.WIFI_WORK_SOURCE)); 10196 verify(mWifiNative).disconnect(eq(WIFI_IFACE_NAME)); 10197 } 10198 setScanResultWithMloInfo()10199 private void setScanResultWithMloInfo() { 10200 List<MloLink> mloLinks = new ArrayList<>(); 10201 MloLink link1 = new MloLink(); 10202 link1.setBand(WifiScanner.WIFI_BAND_24_GHZ); 10203 link1.setChannel(TEST_CHANNEL); 10204 link1.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR)); 10205 link1.setLinkId(TEST_MLO_LINK_ID); 10206 link1.setRssi(TEST_RSSI); 10207 MloLink link2 = new MloLink(); 10208 link2.setBand(WifiScanner.WIFI_BAND_5_GHZ); 10209 link2.setChannel(TEST_CHANNEL_1); 10210 link2.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR1)); 10211 link2.setLinkId(TEST_MLO_LINK_ID_1); 10212 link2.setRssi(TEST_RSSI); 10213 mloLinks.add(link1); 10214 mloLinks.add(link2); 10215 10216 when(mScanResult.getApMldMacAddress()).thenReturn(TEST_AP_MLD_MAC_ADDRESS); 10217 when(mScanResult.getApMloLinkId()).thenReturn(TEST_MLO_LINK_ID); 10218 when(mScanResult.getAffiliatedMloLinks()).thenReturn(mloLinks); 10219 mScanResult.level = TEST_RSSI; 10220 10221 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 10222 .thenReturn(mScanDetailCache); 10223 when(mScanDetailCache.getScanResult(any())).thenReturn(mScanResult); 10224 } 10225 setScanResultWithoutMloInfo()10226 private void setScanResultWithoutMloInfo() { 10227 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11AC; 10228 10229 when(mScanResult.getApMldMacAddress()).thenReturn(null); 10230 when(mScanResult.getApMloLinkId()).thenReturn(MloLink.INVALID_MLO_LINK_ID); 10231 when(mScanResult.getAffiliatedMloLinks()).thenReturn(Collections.emptyList()); 10232 10233 when(mScanRequestProxy.getScanResults()).thenReturn(Arrays.asList(mScanResult)); 10234 when(mScanRequestProxy.getScanResult(any())).thenReturn(mScanResult); 10235 } 10236 setConnection()10237 private void setConnection() throws Exception { 10238 WifiConfiguration config = createTestNetwork(false); 10239 setupAndStartConnectSequence(config); 10240 validateSuccessfulConnectSequence(config); 10241 } 10242 setConnectionMloLinksInfo()10243 private void setConnectionMloLinksInfo() { 10244 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE; 10245 WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo(); 10246 info.links = new WifiNative.ConnectionMloLink[2]; 10247 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 10248 TEST_AP_MLD_MAC_ADDRESS, Byte.MIN_VALUE, Byte.MAX_VALUE, 5160); 10249 info.links[1] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID_1, TEST_MLO_LINK_ADDR_1, 10250 TEST_AP_MLD_MAC_ADDRESS, Byte.MAX_VALUE, Byte.MIN_VALUE, 2437); 10251 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 10252 } 10253 10254 /** 10255 * Verify Affiliated link BSSID matching 10256 */ 10257 @Test testAffiliatedLinkBssidMatch()10258 public void testAffiliatedLinkBssidMatch() throws Exception { 10259 setConnection(); 10260 setScanResultWithMloInfo(); 10261 // Associate 10262 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10263 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10264 SupplicantState.ASSOCIATED)); 10265 mLooper.dispatchAll(); 10266 // Validate Affiliated BSSID match 10267 assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR))); 10268 assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR1))); 10269 assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR2))); 10270 // Check for null BSSID 10271 assertFalse(mCmi.isAffiliatedLinkBssid(null)); 10272 } 10273 10274 @Test testAffiliatedLinkBssidMatchWithNullLinkMacAddress()10275 public void testAffiliatedLinkBssidMatchWithNullLinkMacAddress() throws Exception { 10276 setConnection(); 10277 List<MloLink> mloLinks = new ArrayList<>(); 10278 // Build MLO link with null link mac address 10279 MloLink link1 = new MloLink(); 10280 link1.setBand(WifiScanner.WIFI_BAND_24_GHZ); 10281 link1.setChannel(TEST_CHANNEL); 10282 link1.setLinkId(TEST_MLO_LINK_ID); 10283 link1.setRssi(TEST_RSSI); 10284 mloLinks.add(link1); 10285 when(mScanResult.getApMldMacAddress()).thenReturn(TEST_AP_MLD_MAC_ADDRESS); 10286 when(mScanResult.getApMloLinkId()).thenReturn(TEST_MLO_LINK_ID); 10287 when(mScanResult.getAffiliatedMloLinks()).thenReturn(mloLinks); 10288 mScanResult.level = TEST_RSSI; 10289 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 10290 .thenReturn(mScanDetailCache); 10291 when(mScanDetailCache.getScanResult(any())).thenReturn(mScanResult); 10292 // Associate 10293 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10294 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10295 SupplicantState.ASSOCIATED)); 10296 mLooper.dispatchAll(); 10297 // Test isAffiliatedLinkBssid match fails with no NPE 10298 assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR))); 10299 // Check for null BSSID 10300 assertFalse(mCmi.isAffiliatedLinkBssid(null)); 10301 } 10302 10303 /** 10304 * Verify MLO parameters update from ScanResult at association 10305 */ 10306 @Test verifyMloParametersUpdateAssoc()10307 public void verifyMloParametersUpdateAssoc() throws Exception { 10308 setConnection(); 10309 setScanResultWithMloInfo(); 10310 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10311 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10312 SupplicantState.ASSOCIATED)); 10313 mLooper.dispatchAll(); 10314 10315 WifiInfo connectionInfo = mCmi.getConnectionInfo(); 10316 assertNotNull(connectionInfo.getApMldMacAddress()); 10317 assertEquals(TEST_AP_MLD_MAC_ADDRESS_STR, connectionInfo.getApMldMacAddress().toString()); 10318 assertEquals(TEST_MLO_LINK_ID, connectionInfo.getApMloLinkId()); 10319 assertEquals(2, connectionInfo.getAffiliatedMloLinks().size()); 10320 // None of the links are active or idle. 10321 assertTrue(connectionInfo.getAssociatedMloLinks().isEmpty()); 10322 } 10323 10324 /** 10325 * Verify MLO parameters update when roaming to a MLD ap, and then get cleared when roaming to 10326 * a non MLD supported AP. 10327 */ 10328 @Test verifyMloParametersUpdateRoam()10329 public void verifyMloParametersUpdateRoam() throws Exception { 10330 connect(); 10331 setScanResultWithMloInfo(); 10332 10333 // Roam to an MLD AP 10334 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10335 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10336 SupplicantState.ASSOCIATED)); 10337 mLooper.dispatchAll(); 10338 10339 WifiInfo connectionInfo = mCmi.getConnectionInfo(); 10340 assertNotNull(connectionInfo.getApMldMacAddress()); 10341 assertEquals(TEST_AP_MLD_MAC_ADDRESS_STR, connectionInfo.getApMldMacAddress().toString()); 10342 assertEquals(TEST_MLO_LINK_ID, connectionInfo.getApMloLinkId()); 10343 assertEquals(2, connectionInfo.getAffiliatedMloLinks().size()); 10344 10345 // Now perform Roaming to a non-MLD AP 10346 setScanResultWithoutMloInfo(); 10347 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10348 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10349 SupplicantState.ASSOCIATED)); 10350 mLooper.dispatchAll(); 10351 10352 connectionInfo = mCmi.getConnectionInfo(); 10353 assertNull(connectionInfo.getApMldMacAddress()); 10354 assertEquals(MloLink.INVALID_MLO_LINK_ID, connectionInfo.getApMloLinkId()); 10355 assertTrue(connectionInfo.getAffiliatedMloLinks().isEmpty()); 10356 assertTrue(connectionInfo.getAssociatedMloLinks().isEmpty()); 10357 } 10358 10359 /** 10360 * Verify API calls on affiliated BSSIDs during association and disconnect. 10361 */ 10362 @Test verifyAffiliatedBssidsAssocDisconnect()10363 public void verifyAffiliatedBssidsAssocDisconnect() throws Exception { 10364 List<String> affiliatedBssids = Arrays.asList(TEST_BSSID_STR1); 10365 10366 connect(); 10367 setScanResultWithMloInfo(); 10368 setConnectionMloLinksInfo(); 10369 mLooper.dispatchAll(); 10370 10371 // Association 10372 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10373 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10374 SupplicantState.ASSOCIATED)); 10375 mLooper.dispatchAll(); 10376 verify(mWifiBlocklistMonitor).setAffiliatedBssids(eq(TEST_BSSID_STR), eq(affiliatedBssids)); 10377 10378 // Disconnect 10379 DisconnectEventInfo disconnectEventInfo = 10380 new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false); 10381 mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo); 10382 mLooper.dispatchAll(); 10383 verify(mWifiBlocklistMonitor).removeAffiliatedBssids(eq(TEST_BSSID_STR)); 10384 } 10385 configureMloLinksInfoWithIdleLinks()10386 private void configureMloLinksInfoWithIdleLinks() { 10387 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE; 10388 WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo(); 10389 info.links = new WifiNative.ConnectionMloLink[2]; 10390 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 10391 TEST_AP_MLD_MAC_ADDRESS, (byte) 0xFF, (byte) 0xFF, 2437); 10392 info.links[1] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID_1, TEST_MLO_LINK_ADDR_1, 10393 TEST_AP_MLD_MAC_ADDRESS, (byte) 0, (byte) 0, 5160); 10394 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 10395 } 10396 reconfigureMloLinksInfoWithOneLink()10397 private void reconfigureMloLinksInfoWithOneLink() { 10398 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE; 10399 WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo(); 10400 info.links = new WifiNative.ConnectionMloLink[1]; 10401 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 10402 TEST_AP_MLD_MAC_ADDRESS, (byte) 0xFF, (byte) 0xFF, 2437); 10403 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 10404 } 10405 10406 @Test verifyMloLinkChangeTidToLinkMapping()10407 public void verifyMloLinkChangeTidToLinkMapping() throws Exception { 10408 // Initialize 10409 connect(); 10410 setScanResultWithMloInfo(); 10411 setConnectionMloLinksInfo(); 10412 mLooper.dispatchAll(); 10413 10414 // Association 10415 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10416 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10417 SupplicantState.ASSOCIATED)); 10418 mLooper.dispatchAll(); 10419 // Make sure all links are active 10420 for (MloLink link: mWifiInfo.getAffiliatedMloLinks()) { 10421 assertEquals(link.getState(), MloLink.MLO_LINK_STATE_ACTIVE); 10422 } 10423 // All links are associated (ACTIVE) 10424 assertEquals(mWifiInfo.getAssociatedMloLinks().size(), 10425 mWifiInfo.getAffiliatedMloLinks().size()); 10426 10427 // TID to link mapping. Make sure one link is IDLE. 10428 configureMloLinksInfoWithIdleLinks(); 10429 mCmi.sendMessage(WifiMonitor.MLO_LINKS_INFO_CHANGED, 10430 WifiMonitor.MloLinkInfoChangeReason.TID_TO_LINK_MAP); 10431 mLooper.dispatchAll(); 10432 List<MloLink> links = mWifiInfo.getAffiliatedMloLinks(); 10433 assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE); 10434 assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_IDLE); 10435 // All links are associated (ACTIVE & IDLE) 10436 assertEquals(mWifiInfo.getAssociatedMloLinks().size(), 10437 mWifiInfo.getAffiliatedMloLinks().size()); 10438 10439 // LInk Removal. Make sure removed link is UNASSOCIATED. 10440 reconfigureMloLinksInfoWithOneLink(); 10441 mCmi.sendMessage(WifiMonitor.MLO_LINKS_INFO_CHANGED, 10442 WifiMonitor.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL); 10443 mLooper.dispatchAll(); 10444 links = mWifiInfo.getAffiliatedMloLinks(); 10445 assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE); 10446 assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_UNASSOCIATED); 10447 // One link is unassociated. 10448 assertEquals(2, mWifiInfo.getAffiliatedMloLinks().size()); 10449 assertEquals(1, mWifiInfo.getAssociatedMloLinks().size()); 10450 10451 } 10452 10453 @Test verifyMloLinkChangeAfterAssociation()10454 public void verifyMloLinkChangeAfterAssociation() throws Exception { 10455 // Initialize 10456 connect(); 10457 setScanResultWithMloInfo(); 10458 setConnectionMloLinksInfo(); 10459 mLooper.dispatchAll(); 10460 10461 // Association 10462 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10463 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10464 SupplicantState.ASSOCIATED)); 10465 mLooper.dispatchAll(); 10466 // Verify all links are associated (ACTIVE) after assciation. 10467 assertEquals(mWifiInfo.getAssociatedMloLinks().size(), 10468 mWifiInfo.getAffiliatedMloLinks().size()); 10469 10470 // verify that affiliated link state the scan results are still in unassociated state. 10471 for (MloLink link : mScanResult.getAffiliatedMloLinks()) { 10472 assertEquals(MloLink.MLO_LINK_STATE_UNASSOCIATED, link.getState()); 10473 } 10474 // verify that affiliated link state are active 10475 for (MloLink link : mWifiInfo.getAffiliatedMloLinks()) { 10476 assertEquals(MloLink.MLO_LINK_STATE_ACTIVE, link.getState()); 10477 } 10478 10479 setScanResultWithMloInfo(); 10480 // Send FOUR_WAY_HANDSHAKE, GROUP_HANDSHAKE and COMPLETED and verify all links are still 10481 // asscoaited. 10482 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10483 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10484 SupplicantState.FOUR_WAY_HANDSHAKE)); 10485 10486 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10487 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10488 SupplicantState.GROUP_HANDSHAKE)); 10489 10490 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 10491 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 10492 SupplicantState.COMPLETED)); 10493 mLooper.dispatchAll(); 10494 // Verify all links are still associated (ACTIVE). 10495 assertEquals(mWifiInfo.getAssociatedMloLinks().size(), 10496 mWifiInfo.getAffiliatedMloLinks().size()); 10497 } 10498 /** 10499 * Verify that an event that occurs on a managed network is handled by 10500 * logEventIfManagedNetwork. 10501 */ 10502 @Test verifyEventHandledByLogEventIfManagedNetwork()10503 public void verifyEventHandledByLogEventIfManagedNetwork() throws Exception { 10504 assumeTrue(SdkLevel.isAtLeastT()); 10505 MacAddress bssid = MacAddress.fromString(TEST_BSSID_STR); 10506 int numMaskedOctets = 4; 10507 10508 mResources.setInteger( 10509 R.integer.config_wifiNumMaskedBssidOctetsInSecurityLog, numMaskedOctets); 10510 when(mWifiPermissionsUtil.isAdmin(anyInt(), any())).thenReturn(true); 10511 MockitoSession scanResultUtilSession = ExtendedMockito.mockitoSession() 10512 .strictness(Strictness.LENIENT) 10513 .mockStatic(ScanResultUtil.class, withSettings().lenient()) 10514 .startMocking(); 10515 connect(); 10516 10517 // Connect will generate the Associated and Connected events. Confirm the events were 10518 // handled by checking that redactBssid() was called for each one. 10519 ExtendedMockito.verify(() -> 10520 ScanResultUtil.redactBssid(bssid, numMaskedOctets), times(2)); 10521 scanResultUtilSession.finishMocking(); 10522 } 10523 10524 /** 10525 * Verify that QoS policy reset events are handled when mNetworkAgent is non-null. 10526 */ 10527 @Test verifyQosPolicyResetEventWithNonNullNetworkAgent()10528 public void verifyQosPolicyResetEventWithNonNullNetworkAgent() throws Exception { 10529 assumeTrue(SdkLevel.isAtLeastT()); 10530 connect(); 10531 assertNotNull(mCmi.mNetworkAgent); 10532 mCmi.sendMessage(WifiMonitor.QOS_POLICY_RESET_EVENT, 0, 0, null); 10533 mLooper.dispatchAll(); 10534 verify(mWifiNetworkAgent).sendRemoveAllDscpPolicies(); 10535 } 10536 10537 /** 10538 * Verify that QoS policy reset events are not handled when mNetworkAgent is null. 10539 */ 10540 @Test verifyQosPolicyResetEventWithNullNetworkAgent()10541 public void verifyQosPolicyResetEventWithNullNetworkAgent() throws Exception { 10542 assumeTrue(SdkLevel.isAtLeastT()); 10543 assertNull(mCmi.mNetworkAgent); 10544 mCmi.sendMessage(WifiMonitor.QOS_POLICY_RESET_EVENT, 0, 0, null); 10545 mLooper.dispatchAll(); 10546 verify(mWifiNetworkAgent, never()).sendRemoveAllDscpPolicies(); 10547 } 10548 10549 /** 10550 * Verify that QoS policy reset events are not handled if the QoS policy feature was 10551 * not enabled in WifiNative. 10552 */ 10553 @Test verifyQosPolicyResetEventWhenQosFeatureNotEnabled()10554 public void verifyQosPolicyResetEventWhenQosFeatureNotEnabled() throws Exception { 10555 assumeTrue(SdkLevel.isAtLeastT()); 10556 connect(); 10557 assertNotNull(mCmi.mNetworkAgent); 10558 when(mWifiNative.isQosPolicyFeatureEnabled()).thenReturn(false); 10559 mCmi.sendMessage(WifiMonitor.QOS_POLICY_RESET_EVENT, 0, 0, null); 10560 mLooper.dispatchAll(); 10561 verify(mWifiNetworkAgent, never()).sendRemoveAllDscpPolicies(); 10562 } 10563 10564 /** 10565 * Verify that QoS policy request events are handled when mNetworkAgent is non-null. 10566 */ 10567 @Test verifyQosPolicyRequestEvent()10568 public void verifyQosPolicyRequestEvent() throws Exception { 10569 assumeTrue(SdkLevel.isAtLeastT()); 10570 final int dialogToken = 124; 10571 10572 // Event should be ignored by the QosPolicyRequestHandler if no network is connected, 10573 // since mNetworkAgent is null. 10574 assertNull(mCmi.mNetworkAgent); 10575 mCmi.sendMessage(WifiMonitor.QOS_POLICY_REQUEST_EVENT, dialogToken, 0, 10576 new ArrayList<SupplicantStaIfaceHal.QosPolicyRequest>()); 10577 mLooper.dispatchAll(); 10578 10579 // New events should be processed after connecting to a network, 10580 // since mNetworkAgent is not null. 10581 connect(); 10582 assertNotNull(mCmi.mNetworkAgent); 10583 mCmi.sendMessage(WifiMonitor.QOS_POLICY_REQUEST_EVENT, dialogToken + 1, 0, 10584 new ArrayList<SupplicantStaIfaceHal.QosPolicyRequest>()); 10585 mLooper.dispatchAll(); 10586 10587 verify(mWifiNative, never()).sendQosPolicyResponse( 10588 eq(WIFI_IFACE_NAME), eq(dialogToken), eq(true), any()); 10589 verify(mWifiNative).sendQosPolicyResponse( 10590 eq(WIFI_IFACE_NAME), eq(dialogToken + 1), eq(true), any()); 10591 } 10592 verifyConnectWithDisabledType( WifiConfiguration config, List<ScanResult> results, boolean shouldDropRequest)10593 private void verifyConnectWithDisabledType( 10594 WifiConfiguration config, List<ScanResult> results, 10595 boolean shouldDropRequest) throws Exception { 10596 WifiDialogManager mockWifiDialogManager = mock(WifiDialogManager.class); 10597 WifiDialogManager.DialogHandle mockDialogHandle = 10598 mock(WifiDialogManager.DialogHandle.class); 10599 when(mockWifiDialogManager.createLegacySimpleDialog(any(), any(), any(), any(), any(), 10600 any(), any())).thenReturn(mockDialogHandle); 10601 when(mWifiInjector.getWifiDialogManager()).thenReturn(mockWifiDialogManager); 10602 // Add some irrelevant networks to ensure they are filtered. 10603 final String irrelevantSsid = "IrrelevantSsid"; 10604 results.add(makeScanResult(irrelevantSsid, "[PSK]")); 10605 results.add(makeScanResult(irrelevantSsid, "[SAE]")); 10606 results.add(makeScanResult(irrelevantSsid, "[PSK][SAE]")); 10607 results.add(makeScanResult(irrelevantSsid, "")); 10608 results.add(makeScanResult(irrelevantSsid, "[OWE_TRANSITION]")); 10609 results.add(makeScanResult(irrelevantSsid, "[OWE]")); 10610 results.add(makeScanResult(irrelevantSsid, "[RSN][EAP/SHA1][MFPC]")); 10611 results.add(makeScanResult(irrelevantSsid, "[RSN][EAP/SHA1][EAP/SHA256][MFPC]")); 10612 results.add(makeScanResult(irrelevantSsid, "[RSN][EAP/SHA256][MFPC][MFPR]")); 10613 when(mScanRequestProxy.getScanResults()).thenReturn(results); 10614 10615 initializeAndAddNetworkAndVerifySuccess(); 10616 10617 when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(TEST_NETWORK_ID)) 10618 .thenReturn(config); 10619 when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); 10620 10621 IActionListener connectActionListener = mock(IActionListener.class); 10622 mCmi.connectNetwork( 10623 new NetworkUpdateResult(TEST_NETWORK_ID), 10624 new ActionListenerWrapper(connectActionListener), 10625 Process.SYSTEM_UID, OP_PACKAGE_NAME, null); 10626 mLooper.dispatchAll(); 10627 verify(connectActionListener).onSuccess(); 10628 if (shouldDropRequest) { 10629 verify(mockDialogHandle).launchDialog(); 10630 verify(mWifiNative, never()).connectToNetwork(any(), any()); 10631 } else { 10632 verify(mockDialogHandle, never()).launchDialog(); 10633 verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config)); 10634 } 10635 } 10636 makeScanResult(String ssid, String caps)10637 private ScanResult makeScanResult(String ssid, String caps) { 10638 ScanResult scanResult = new ScanResult.Builder( 10639 WifiSsid.fromUtf8Text(ssid.replace("\"", "")), 10640 TEST_BSSID_STR) 10641 .setHessid(1245) 10642 .setCaps(caps) 10643 .setRssi(-78) 10644 .setFrequency(2450) 10645 .setTsf(1025) 10646 .setDistanceCm(22) 10647 .setDistanceSdCm(33) 10648 .setIs80211McRTTResponder(true) 10649 .build(); 10650 ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID, 10651 ssid.getBytes(StandardCharsets.UTF_8)); 10652 scanResult.informationElements = new ScanResult.InformationElement[]{ie}; 10653 return scanResult; 10654 } 10655 verifyConnectWithDisabledPskType( boolean isWpa2PersonalOnlyNetworkInRange, boolean isWpa2Wpa3PersonalTransitionNetworkInRange, boolean isWpa3PersonalOnlyNetworkInRange, boolean shouldDropRequest)10656 private void verifyConnectWithDisabledPskType( 10657 boolean isWpa2PersonalOnlyNetworkInRange, 10658 boolean isWpa2Wpa3PersonalTransitionNetworkInRange, 10659 boolean isWpa3PersonalOnlyNetworkInRange, boolean shouldDropRequest) 10660 throws Exception { 10661 WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork(); 10662 config.networkId = TEST_NETWORK_ID; 10663 config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_PSK, false); 10664 List<ScanResult> results = new ArrayList<>(); 10665 if (isWpa2PersonalOnlyNetworkInRange) { 10666 results.add(makeScanResult(config.SSID, "[PSK]")); 10667 } 10668 if (isWpa2Wpa3PersonalTransitionNetworkInRange) { 10669 results.add(makeScanResult(config.SSID, "[PSK][SAE]")); 10670 } 10671 if (isWpa3PersonalOnlyNetworkInRange) { 10672 results.add(makeScanResult(config.SSID, "[SAE]")); 10673 } 10674 10675 verifyConnectWithDisabledType(config, results, shouldDropRequest); 10676 } 10677 10678 @Test testConnectDropWithOnlyDisabledPskNetwork()10679 public void testConnectDropWithOnlyDisabledPskNetwork() throws Exception { 10680 boolean isWpa2PersonalOnlyNetworkInRange = true; 10681 boolean isWpa2Wpa3PersonalTransitionNetworkInRange = false; 10682 boolean isWpa3PersonalOnlyNetworkInRange = false; 10683 boolean shouldDropRequest = true; 10684 10685 verifyConnectWithDisabledPskType(isWpa2PersonalOnlyNetworkInRange, 10686 isWpa2Wpa3PersonalTransitionNetworkInRange, 10687 isWpa3PersonalOnlyNetworkInRange, shouldDropRequest); 10688 } 10689 10690 @Test testConnectAllowedWithPskSaeNetwork()10691 public void testConnectAllowedWithPskSaeNetwork() throws Exception { 10692 boolean isWpa2PersonalOnlyNetworkInRange = true; 10693 boolean isWpa2Wpa3PersonalTransitionNetworkInRange = true; 10694 boolean isWpa3PersonalOnlyNetworkInRange = false; 10695 boolean shouldDropRequest = false; 10696 10697 verifyConnectWithDisabledPskType(isWpa2PersonalOnlyNetworkInRange, 10698 isWpa2Wpa3PersonalTransitionNetworkInRange, 10699 isWpa3PersonalOnlyNetworkInRange, shouldDropRequest); 10700 } 10701 10702 @Test testConnectAllowedWithSaeNetwork()10703 public void testConnectAllowedWithSaeNetwork() throws Exception { 10704 boolean isWpa2PersonalOnlyNetworkInRange = true; 10705 boolean isWpa2Wpa3PersonalTransitionNetworkInRange = false; 10706 boolean isWpa3PersonalOnlyNetworkInRange = true; 10707 boolean shouldDropRequest = false; 10708 10709 verifyConnectWithDisabledPskType(isWpa2PersonalOnlyNetworkInRange, 10710 isWpa2Wpa3PersonalTransitionNetworkInRange, 10711 isWpa3PersonalOnlyNetworkInRange, shouldDropRequest); 10712 } 10713 10714 @Test testConnectAllowedWithoutPskNetwork()10715 public void testConnectAllowedWithoutPskNetwork() throws Exception { 10716 boolean isWpa2PersonalOnlyNetworkInRange = false; 10717 boolean isWpa2Wpa3PersonalTransitionNetworkInRange = true; 10718 boolean isWpa3PersonalOnlyNetworkInRange = false; 10719 boolean shouldDropRequest = false; 10720 10721 verifyConnectWithDisabledPskType(isWpa2PersonalOnlyNetworkInRange, 10722 isWpa2Wpa3PersonalTransitionNetworkInRange, 10723 isWpa3PersonalOnlyNetworkInRange, shouldDropRequest); 10724 } 10725 10726 @Test testConnectDisabledPskAllowedForNonUserSelectedNetwork()10727 public void testConnectDisabledPskAllowedForNonUserSelectedNetwork() throws Exception { 10728 boolean isWpa2PersonalOnlyNetworkInRange = true; 10729 boolean isWpa2Wpa3PersonalTransitionNetworkInRange = false; 10730 boolean isWpa3PersonalOnlyNetworkInRange = false; 10731 boolean shouldDropRequest = false; 10732 10733 // Only a request from settings or setup wizard are considered a user selected network. 10734 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 10735 when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false); 10736 10737 verifyConnectWithDisabledPskType(isWpa2PersonalOnlyNetworkInRange, 10738 isWpa2Wpa3PersonalTransitionNetworkInRange, 10739 isWpa3PersonalOnlyNetworkInRange, shouldDropRequest); 10740 } 10741 verifyConnectWithDisabledOpenType( boolean isOpenOnlyNetworkInRange, boolean isOpenOweTransitionNetworkInRange, boolean isOweOnlyNetworkInRange, boolean shouldDropRequest)10742 private void verifyConnectWithDisabledOpenType( 10743 boolean isOpenOnlyNetworkInRange, 10744 boolean isOpenOweTransitionNetworkInRange, 10745 boolean isOweOnlyNetworkInRange, boolean shouldDropRequest) 10746 throws Exception { 10747 WifiConfiguration config = WifiConfigurationTestUtil.createOpenOweNetwork(); 10748 config.networkId = TEST_NETWORK_ID; 10749 config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_OPEN, false); 10750 List<ScanResult> results = new ArrayList<>(); 10751 if (isOpenOnlyNetworkInRange) { 10752 results.add(makeScanResult(config.SSID, "")); 10753 } 10754 if (isOpenOweTransitionNetworkInRange) { 10755 results.add(makeScanResult(config.SSID, "[OWE_TRANSITION]")); 10756 } 10757 if (isOweOnlyNetworkInRange) { 10758 results.add(makeScanResult(config.SSID, "[OWE]")); 10759 } 10760 10761 verifyConnectWithDisabledType(config, results, shouldDropRequest); 10762 } 10763 10764 @Test testConnectDropWithOnlyDisabledOpenNetwork()10765 public void testConnectDropWithOnlyDisabledOpenNetwork() throws Exception { 10766 boolean isOpenOnlyNetworkInRange = true; 10767 boolean isOpenOweTransitionNetworkInRange = false; 10768 boolean isOweOnlyNetworkInRange = false; 10769 boolean shouldDropRequest = true; 10770 10771 verifyConnectWithDisabledOpenType(isOpenOnlyNetworkInRange, 10772 isOpenOweTransitionNetworkInRange, 10773 isOweOnlyNetworkInRange, shouldDropRequest); 10774 } 10775 10776 @Test testConnectAllowedWithOpenOweNetwork()10777 public void testConnectAllowedWithOpenOweNetwork() throws Exception { 10778 boolean isOpenOnlyNetworkInRange = true; 10779 boolean isOpenOweTransitionNetworkInRange = true; 10780 boolean isOweOnlyNetworkInRange = false; 10781 boolean shouldDropRequest = false; 10782 10783 verifyConnectWithDisabledOpenType(isOpenOnlyNetworkInRange, 10784 isOpenOweTransitionNetworkInRange, 10785 isOweOnlyNetworkInRange, shouldDropRequest); 10786 } 10787 10788 @Test testConnectAllowedWithOweNetwork()10789 public void testConnectAllowedWithOweNetwork() throws Exception { 10790 boolean isOpenOnlyNetworkInRange = true; 10791 boolean isOpenOweTransitionNetworkInRange = false; 10792 boolean isOweOnlyNetworkInRange = true; 10793 boolean shouldDropRequest = false; 10794 10795 verifyConnectWithDisabledOpenType(isOpenOnlyNetworkInRange, 10796 isOpenOweTransitionNetworkInRange, 10797 isOweOnlyNetworkInRange, shouldDropRequest); 10798 } 10799 10800 @Test testConnectAllowedWithoutOpenNetwork()10801 public void testConnectAllowedWithoutOpenNetwork() throws Exception { 10802 boolean isOpenOnlyNetworkInRange = false; 10803 boolean isOpenOweTransitionNetworkInRange = true; 10804 boolean isOweOnlyNetworkInRange = false; 10805 boolean shouldDropRequest = false; 10806 10807 verifyConnectWithDisabledOpenType(isOpenOnlyNetworkInRange, 10808 isOpenOweTransitionNetworkInRange, 10809 isOweOnlyNetworkInRange, shouldDropRequest); 10810 } 10811 10812 @Test testConnectDisabledOpenAllowedForNonUserSelectedNetwork()10813 public void testConnectDisabledOpenAllowedForNonUserSelectedNetwork() throws Exception { 10814 boolean isOpenOnlyNetworkInRange = true; 10815 boolean isOpenOweTransitionNetworkInRange = false; 10816 boolean isOweOnlyNetworkInRange = false; 10817 boolean shouldDropRequest = false; 10818 10819 // Only a request from settings or setup wizard are considered a user selected network. 10820 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 10821 when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false); 10822 10823 verifyConnectWithDisabledOpenType(isOpenOnlyNetworkInRange, 10824 isOpenOweTransitionNetworkInRange, 10825 isOweOnlyNetworkInRange, shouldDropRequest); 10826 } 10827 verifyConnectWithDisabledWpa2EnterpriseType( boolean isWpa2EnterpriseOnlyNetworkInRange, boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange, boolean isWpa3EnterpriseOnlyNetworkInRange, boolean shouldDropRequest)10828 private void verifyConnectWithDisabledWpa2EnterpriseType( 10829 boolean isWpa2EnterpriseOnlyNetworkInRange, 10830 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10831 boolean isWpa3EnterpriseOnlyNetworkInRange, boolean shouldDropRequest) 10832 throws Exception { 10833 WifiConfiguration config = WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork(); 10834 config.networkId = TEST_NETWORK_ID; 10835 config.setSecurityParamsEnabled(WifiConfiguration.SECURITY_TYPE_EAP, false); 10836 List<ScanResult> results = new ArrayList<>(); 10837 if (isWpa2EnterpriseOnlyNetworkInRange) { 10838 results.add(makeScanResult(config.SSID, "[RSN][EAP/SHA1][MFPC]")); 10839 } 10840 if (isWpa2Wpa3EnterpriseTransitionNetworkInRange) { 10841 results.add(makeScanResult(config.SSID, "[RSN][EAP/SHA1][EAP/SHA256][MFPC]")); 10842 } 10843 if (isWpa3EnterpriseOnlyNetworkInRange) { 10844 results.add(makeScanResult(config.SSID, "[RSN][EAP/SHA256][MFPC][MFPR]")); 10845 } 10846 10847 verifyConnectWithDisabledType(config, results, shouldDropRequest); 10848 } 10849 10850 @Test testConnectDropWithOnlyDisabledWpa2EnterpriseNetwork()10851 public void testConnectDropWithOnlyDisabledWpa2EnterpriseNetwork() throws Exception { 10852 boolean isWpa2EnterpriseOnlyNetworkInRange = true; 10853 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange = false; 10854 boolean isWpa3EnterpriseOnlyNetworkInRange = false; 10855 boolean shouldDropRequest = true; 10856 10857 verifyConnectWithDisabledWpa2EnterpriseType(isWpa2EnterpriseOnlyNetworkInRange, 10858 isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10859 isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest); 10860 } 10861 10862 @Test testConnectAllowedWithWpa2Wpa3EnterpriseNetwork()10863 public void testConnectAllowedWithWpa2Wpa3EnterpriseNetwork() throws Exception { 10864 boolean isWpa2EnterpriseOnlyNetworkInRange = true; 10865 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange = true; 10866 boolean isWpa3EnterpriseOnlyNetworkInRange = false; 10867 boolean shouldDropRequest = false; 10868 10869 verifyConnectWithDisabledWpa2EnterpriseType(isWpa2EnterpriseOnlyNetworkInRange, 10870 isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10871 isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest); 10872 } 10873 10874 @Test testConnectAllowedWithWpa3EnterpriseNetwork()10875 public void testConnectAllowedWithWpa3EnterpriseNetwork() throws Exception { 10876 boolean isWpa2EnterpriseOnlyNetworkInRange = true; 10877 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange = false; 10878 boolean isWpa3EnterpriseOnlyNetworkInRange = true; 10879 boolean shouldDropRequest = false; 10880 10881 verifyConnectWithDisabledWpa2EnterpriseType(isWpa2EnterpriseOnlyNetworkInRange, 10882 isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10883 isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest); 10884 } 10885 10886 @Test testConnectAllowedWithoutWpa2EnterpriseNetwork()10887 public void testConnectAllowedWithoutWpa2EnterpriseNetwork() throws Exception { 10888 boolean isWpa2EnterpriseOnlyNetworkInRange = false; 10889 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange = true; 10890 boolean isWpa3EnterpriseOnlyNetworkInRange = false; 10891 boolean shouldDropRequest = false; 10892 10893 verifyConnectWithDisabledWpa2EnterpriseType(isWpa2EnterpriseOnlyNetworkInRange, 10894 isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10895 isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest); 10896 } 10897 10898 @Test testConnectDisabledWpa2EnterpriseAllowedForNonUserSelectedNetwork()10899 public void testConnectDisabledWpa2EnterpriseAllowedForNonUserSelectedNetwork() 10900 throws Exception { 10901 boolean isWpa2EnterpriseOnlyNetworkInRange = true; 10902 boolean isWpa2Wpa3EnterpriseTransitionNetworkInRange = false; 10903 boolean isWpa3EnterpriseOnlyNetworkInRange = false; 10904 boolean shouldDropRequest = false; 10905 10906 // Only a request from settings or setup wizard are considered a user selected network. 10907 when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); 10908 when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false); 10909 10910 verifyConnectWithDisabledWpa2EnterpriseType(isWpa2EnterpriseOnlyNetworkInRange, 10911 isWpa2Wpa3EnterpriseTransitionNetworkInRange, 10912 isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest); 10913 } 10914 10915 @Test testUpdateAkmByConnectionInfo()10916 public void testUpdateAkmByConnectionInfo() throws Exception { 10917 mConnectedNetwork = spy(WifiConfigurationTestUtil.createPskSaeNetwork()); 10918 10919 triggerConnect(); 10920 10921 // WifiInfo is not updated yet. 10922 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, mWifiInfo.getCurrentSecurityType()); 10923 10924 WifiSsid wifiSsid = WifiSsid.fromBytes( 10925 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID))); 10926 BitSet akm = new BitSet(); 10927 akm.set(WifiConfiguration.KeyMgmt.SAE); 10928 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 10929 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm)); 10930 mLooper.dispatchAll(); 10931 // WifiInfo is updated to the actual used type. 10932 assertEquals(WifiInfo.SECURITY_TYPE_SAE, mWifiInfo.getCurrentSecurityType()); 10933 10934 // Roam to a PSK BSS. 10935 akm.clear(); 10936 akm.set(WifiConfiguration.KeyMgmt.WPA_PSK); 10937 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 10938 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm)); 10939 mLooper.dispatchAll(); 10940 // WifiInfo is updated to the actual used type. 10941 assertEquals(WifiInfo.SECURITY_TYPE_PSK, mWifiInfo.getCurrentSecurityType()); 10942 10943 // Roam back to a SAE BSS. 10944 akm.clear(); 10945 akm.set(WifiConfiguration.KeyMgmt.SAE); 10946 mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 10947 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm)); 10948 mLooper.dispatchAll(); 10949 // WifiInfo is updated to the actual used type. 10950 assertEquals(WifiInfo.SECURITY_TYPE_SAE, mWifiInfo.getCurrentSecurityType()); 10951 } 10952 10953 @Test testUpdateWpa3EnterpriseSecurityTypeByConnectionInfo()10954 public void testUpdateWpa3EnterpriseSecurityTypeByConnectionInfo() throws Exception { 10955 // Create a WifiConfiguration with WPA2 enterprise and WPA3 enterprise security params 10956 WifiConfiguration config = spy(WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork()); 10957 config.networkId = FRAMEWORK_NETWORK_ID; 10958 10959 SecurityParams wpa3EnterpriseParams = 10960 config.getSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE); 10961 assertNotNull(wpa3EnterpriseParams); 10962 // Trigger connection with security params as WPA3 enterprise where PMF is mandatory 10963 config.getNetworkSelectionStatus().setLastUsedSecurityParams(wpa3EnterpriseParams); 10964 setupAndStartConnectSequence(config); 10965 validateSuccessfulConnectSequence(config); 10966 10967 // WifiInfo is not updated yet. 10968 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, mWifiInfo.getCurrentSecurityType()); 10969 10970 WifiSsid wifiSsid = 10971 WifiSsid.fromBytes( 10972 NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(config.SSID))); 10973 10974 BitSet akm = new BitSet(); 10975 akm.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); 10976 // Send network connection event with WPA_EAP_SHA256 AKM 10977 mCmi.sendMessage( 10978 WifiMonitor.NETWORK_CONNECTION_EVENT, 10979 new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm)); 10980 mLooper.dispatchAll(); 10981 // WifiInfo is updated with WPA3-Enterprise security type derived from the AKM sent in 10982 // network connection event and the PMF settings used in connection. 10983 assertEquals( 10984 WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE, mWifiInfo.getCurrentSecurityType()); 10985 } 10986 10987 @Test testEnableTdls()10988 public void testEnableTdls() throws Exception { 10989 connect(); 10990 when(mWifiNative.getMaxSupportedConcurrentTdlsSessions(WIFI_IFACE_NAME)).thenReturn(1); 10991 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)) 10992 .thenReturn(createCapabilityBitset(WifiManager.WIFI_FEATURE_TDLS)); 10993 when(mWifiNative.startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR), anyBoolean())) 10994 .thenReturn(true); 10995 assertEquals(1, mCmi.getMaxSupportedConcurrentTdlsSessions()); 10996 assertTrue(mCmi.isTdlsOperationCurrentlyAvailable()); 10997 assertTrue(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, true)); 10998 assertEquals(1, mCmi.getNumberOfEnabledTdlsSessions()); 10999 verify(mWifiNative).startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR), 11000 eq(true)); 11001 assertFalse(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, true)); 11002 assertTrue(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, false)); 11003 verify(mWifiNative).startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR), 11004 eq(false)); 11005 assertEquals(0, mCmi.getNumberOfEnabledTdlsSessions()); 11006 } 11007 11008 /** 11009 * Verify that the frequency will be updated on receiving BSS_FREQUENCY_CHANGED_EVENT event. 11010 */ 11011 @Test testBssFrequencyChangedUpdatesFrequency()11012 public void testBssFrequencyChangedUpdatesFrequency() throws Exception { 11013 connect(); 11014 assertEquals(sFreq, mWifiInfo.getFrequency()); 11015 mCmi.sendMessage(WifiMonitor.BSS_FREQUENCY_CHANGED_EVENT, sFreq1); 11016 mLooper.dispatchAll(); 11017 assertEquals(sFreq1, mWifiInfo.getFrequency()); 11018 } 11019 11020 /** 11021 * Verify that the frequency is updated on roaming even when the scan result doesn't have the 11022 * roamed BSS scan entry. 11023 */ 11024 @Test testFrequencyUpdateOnRoamWithoutScanResultEntry()11025 public void testFrequencyUpdateOnRoamWithoutScanResultEntry() throws Exception { 11026 // Connect to network with |TEST_BSSID_STR|, |sFreq|. 11027 connect(); 11028 11029 // Return null scan detail cache for roaming target. 11030 when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) 11031 .thenReturn(mScanDetailCache); 11032 when(mScanDetailCache.getScanDetail(TEST_BSSID_STR1)).thenReturn(null); 11033 11034 // This simulates the behavior of roaming to network with |TEST_BSSID_STR1|, |sFreq1|. 11035 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated with new frequency. 11036 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 11037 new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR1, sFreq1, 11038 SupplicantState.COMPLETED)); 11039 mLooper.dispatchAll(); 11040 11041 WifiInfo wifiInfo = mWifiInfo; 11042 assertEquals(sFreq1, wifiInfo.getFrequency()); 11043 } 11044 11045 /** 11046 * Verify that static attributes (channel, state, link id and band) of the affiliated MLO links 11047 * are not changed after signal poll. 11048 */ 11049 @Test testMloLinkAttributesAfterSignalPoll()11050 public void testMloLinkAttributesAfterSignalPoll() throws Exception { 11051 connect(); 11052 setScanResultWithMloInfo(); 11053 11054 // Associate to one link only 11055 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE; 11056 WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo(); 11057 info.links = new WifiNative.ConnectionMloLink[1]; 11058 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 11059 TEST_AP_MLD_MAC_ADDRESS, Byte.MAX_VALUE, Byte.MAX_VALUE, 2437); 11060 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 11061 11062 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 11063 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 11064 SupplicantState.ASSOCIATED)); 11065 mLooper.dispatchAll(); 11066 11067 // Verify the link attributes 11068 List<MloLink> links = mWifiInfo.getAffiliatedMloLinks(); 11069 assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE); 11070 assertEquals(links.get(0).getBand(), WifiScanner.WIFI_BAND_24_GHZ); 11071 assertEquals(links.get(0).getChannel(), TEST_CHANNEL); 11072 assertEquals(links.get(0).getLinkId(), TEST_MLO_LINK_ID); 11073 assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_UNASSOCIATED); 11074 assertEquals(links.get(1).getBand(), WifiScanner.WIFI_BAND_5_GHZ); 11075 assertEquals(links.get(1).getChannel(), TEST_CHANNEL_1); 11076 assertEquals(links.get(1).getLinkId(), TEST_MLO_LINK_ID_1); 11077 11078 // Signal poll for associated link only 11079 final long startMillis = 1_500_000_000_100L; 11080 WifiLinkLayerStats llStats = new WifiLinkLayerStats(); 11081 llStats.txmpdu_be = 1000; 11082 llStats.rxmpdu_bk = 2000; 11083 WifiSignalPollResults signalPollResults = new WifiSignalPollResults(); 11084 signalPollResults.addEntry(TEST_MLO_LINK_ID, -42, 65, 54, sFreq); 11085 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 11086 createCapabilityBitset(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS)); 11087 when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); 11088 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 11089 when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); 11090 mCmi.enableRssiPolling(true); 11091 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 11092 mLooper.dispatchAll(); 11093 11094 // Make sure static link attributes has not changed 11095 links = mWifiInfo.getAffiliatedMloLinks(); 11096 assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE); 11097 assertEquals(links.get(0).getBand(), WifiScanner.WIFI_BAND_24_GHZ); 11098 assertEquals(links.get(0).getChannel(), TEST_CHANNEL); 11099 assertEquals(links.get(0).getLinkId(), TEST_MLO_LINK_ID); 11100 assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_UNASSOCIATED); 11101 assertEquals(links.get(1).getBand(), WifiScanner.WIFI_BAND_5_GHZ); 11102 assertEquals(links.get(1).getChannel(), TEST_CHANNEL_1); 11103 assertEquals(links.get(1).getLinkId(), TEST_MLO_LINK_ID_1); 11104 11105 // Make sure the dynamic attributes (Tx link speed, Rx link speed and RSSI) are matching 11106 // with poll results for associated links. 11107 assertEquals(65, links.get(0).getTxLinkSpeedMbps()); 11108 assertEquals(54, links.get(0).getRxLinkSpeedMbps()); 11109 assertEquals(-42, links.get(0).getRssi()); 11110 11111 // Make sure the RSSI is matching with scan cache for un-associated links 11112 assertEquals(TEST_RSSI, links.get(1).getRssi()); 11113 11114 // Send signal poll for un-associated link 11115 signalPollResults = new WifiSignalPollResults(); 11116 signalPollResults.addEntry(TEST_MLO_LINK_ID_1, -42, 65, 54, sFreq); 11117 when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults); 11118 mCmi.enableRssiPolling(true); 11119 mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); 11120 mLooper.dispatchAll(); 11121 links = mWifiInfo.getAffiliatedMloLinks(); 11122 11123 // Make sure the RSSI is matching with scan result for associated link 11124 assertEquals(TEST_RSSI, links.get(0).getRssi()); 11125 11126 } 11127 11128 /** 11129 * Verify that during DHCP process, 1. If P2P is in disabled state, clientModeImpl doesn't send 11130 * a message to block P2P discovery. 2. If P2P is not in disabled state, clientModeImpl sends a 11131 * message to block P2P discovery. 3. On DHCP completion, clientModeImpl sends a message to 11132 * unblock P2P discovery. 11133 */ 11134 @Test testP2pBlockDiscoveryDuringDhcp()11135 public void testP2pBlockDiscoveryDuringDhcp() throws Exception { 11136 initializeAndAddNetworkAndVerifySuccess(); 11137 11138 startConnectSuccess(); 11139 11140 mCmi.sendMessage( 11141 WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 11142 0, 11143 0, 11144 new StateChangeResult( 11145 0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, SupplicantState.ASSOCIATED)); 11146 mLooper.dispatchAll(); 11147 11148 mCmi.sendMessage( 11149 WifiMonitor.NETWORK_CONNECTION_EVENT, 11150 new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null)); 11151 mLooper.dispatchAll(); 11152 verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID); 11153 11154 mCmi.sendMessage( 11155 WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 11156 0, 11157 0, 11158 new StateChangeResult( 11159 0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, SupplicantState.COMPLETED)); 11160 mLooper.dispatchAll(); 11161 11162 assertEquals("L3ProvisioningState", getCurrentState().getName()); 11163 11164 when(mWifiP2pConnection.isConnected()).thenReturn(true); 11165 when(mWifiP2pConnection.isP2pInDisabledState()).thenReturn(true); 11166 11167 mIpClientCallback.onPreDhcpAction(); 11168 mLooper.dispatchAll(); 11169 verify(mWifiP2pConnection, never()).sendMessage(anyInt(), anyInt(), anyInt()); 11170 verify(mIpClient).completedPreDhcpAction(); 11171 11172 when(mWifiP2pConnection.isConnected()).thenReturn(true); 11173 when(mWifiP2pConnection.isP2pInDisabledState()).thenReturn(false); 11174 11175 mIpClientCallback.onPreDhcpAction(); 11176 mLooper.dispatchAll(); 11177 verify(mWifiP2pConnection) 11178 .sendMessage( 11179 eq(WifiP2pServiceImpl.BLOCK_DISCOVERY), 11180 eq(WifiP2pServiceImpl.ENABLED), 11181 eq(CMD_PRE_DHCP_ACTION_COMPLETE)); 11182 verify(mIpClient).completedPreDhcpAction(); 11183 11184 mIpClientCallback.onPostDhcpAction(); 11185 mLooper.dispatchAll(); 11186 verify(mWifiP2pConnection) 11187 .sendMessage( 11188 eq(WifiP2pServiceImpl.BLOCK_DISCOVERY), eq(WifiP2pServiceImpl.DISABLED)); 11189 } 11190 11191 /** 11192 * Verify that MLO link will be updated on receiving BSS_FREQUENCY_CHANGED_EVENT event. 11193 */ 11194 @Test testBssFrequencyChangedUpdatesMloLink()11195 public void testBssFrequencyChangedUpdatesMloLink() throws Exception { 11196 connect(); 11197 mLooper.dispatchAll(); 11198 11199 mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE; 11200 WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo(); 11201 info.links = new WifiNative.ConnectionMloLink[2]; 11202 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 11203 TEST_AP_MLD_MAC_ADDRESS, Byte.MIN_VALUE, Byte.MAX_VALUE, TEST_MLO_LINK_FREQ); 11204 info.links[1] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID_1, TEST_MLO_LINK_ADDR_1, 11205 TEST_AP_MLD_MAC_ADDRESS, Byte.MAX_VALUE, Byte.MIN_VALUE, TEST_MLO_LINK_FREQ_1); 11206 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 11207 mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 11208 new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq, 11209 SupplicantState.ASSOCIATED)); 11210 mLooper.dispatchAll(); 11211 assertEquals(mWifiInfo.getAssociatedMloLinks().size(), 11212 mWifiInfo.getAffiliatedMloLinks().size()); 11213 11214 info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID, TEST_MLO_LINK_ADDR, 11215 TEST_AP_MLD_MAC_ADDRESS, Byte.MIN_VALUE, Byte.MAX_VALUE, 6215); 11216 when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info); 11217 mCmi.sendMessage(WifiMonitor.BSS_FREQUENCY_CHANGED_EVENT, 6215); 11218 mLooper.dispatchAll(); 11219 List<MloLink> links = mWifiInfo.getAffiliatedMloLinks(); 11220 assertEquals(53, links.get(0).getChannel()); 11221 assertEquals(WifiScanner.WIFI_BAND_6_GHZ, links.get(0).getBand()); 11222 } 11223 11224 /** 11225 * Verify that we disconnect Wi-Fi 7 is toggled. 11226 */ 11227 @Test verifyDisconnectOnTogglingWifi7()11228 public void verifyDisconnectOnTogglingWifi7() throws Exception { 11229 connect(); 11230 11231 WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork); 11232 mConnectedNetwork.setWifi7Enabled(false); 11233 11234 for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor 11235 .getAllValues()) { 11236 listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false); 11237 } 11238 mLooper.dispatchAll(); 11239 verify(mWifiNative).disconnect(WIFI_IFACE_NAME); 11240 verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT), 11241 eq(StaEvent.DISCONNECT_NETWORK_WIFI7_TOGGLED)); 11242 } 11243 testDhcpHostnameSetting( boolean configEnabled, @WifiManager.SendDhcpHostnameRestriction int restriction, int security, int expectedHostnameSetting)11244 private void testDhcpHostnameSetting( 11245 boolean configEnabled, 11246 @WifiManager.SendDhcpHostnameRestriction int restriction, 11247 int security, 11248 int expectedHostnameSetting) throws Exception { 11249 if (!SdkLevel.isAtLeastV()) { 11250 expectedHostnameSetting = IIpClient.HOSTNAME_SETTING_UNSET; 11251 } 11252 when(mWifiGlobals.getSendDhcpHostnameRestriction()).thenReturn(restriction); 11253 mConnectedNetwork.setSecurityParams(security); 11254 mConnectedNetwork.setSendDhcpHostnameEnabled(configEnabled); 11255 connect(); 11256 11257 verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture()); 11258 assertEquals(expectedHostnameSetting, 11259 mProvisioningConfigurationCaptor.getValue().hostnameSetting); 11260 } 11261 11262 @Test testSendDhcpHostnameEnabled()11263 public void testSendDhcpHostnameEnabled() throws Exception { 11264 testDhcpHostnameSetting(true, 0, SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_SEND); 11265 } 11266 11267 @Test testSendDhcpHostnameDisabled()11268 public void testSendDhcpHostnameDisabled() throws Exception { 11269 testDhcpHostnameSetting(false, 0, 11270 SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND); 11271 } 11272 11273 @Test testSendDhcpHostnameEnabledWithOpenRestriction()11274 public void testSendDhcpHostnameEnabledWithOpenRestriction() throws Exception { 11275 testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN, 11276 SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND); 11277 } 11278 11279 @Test testSendDhcpHostnameEnabledWithOpenRestrictionOwe()11280 public void testSendDhcpHostnameEnabledWithOpenRestrictionOwe() throws Exception { 11281 testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN, 11282 SECURITY_TYPE_OWE, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND); 11283 } 11284 11285 @Test testSendDhcpHostnameEnabledWithSecureRestriction()11286 public void testSendDhcpHostnameEnabledWithSecureRestriction() throws Exception { 11287 testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE, 11288 SECURITY_TYPE_PSK, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND); 11289 } 11290 11291 /** 11292 * Verify that the connection failure due to expired certificate status code is captured in the 11293 * connection result metrics failure specific status code. 11294 */ 11295 @Test testConnectionFailureDueToExpiredCertificateStatusCode()11296 public void testConnectionFailureDueToExpiredCertificateStatusCode() throws Exception { 11297 initializeAndAddNetworkAndVerifySuccess(); 11298 11299 startConnectSuccess(); 11300 11301 mCmi.sendMessage(WifiMonitor.AUXILIARY_SUPPLICANT_EVENT, 11302 new SupplicantEventInfo(7, MacAddress.fromString(TEST_BSSID_STR), 11303 "TLS: Certificate verification failed" 11304 + ClientModeImpl.X509_CERTIFICATE_EXPIRED_ERROR_STRING)); 11305 11306 mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT, 11307 new AuthenticationFailureEventInfo(TEST_SSID, MacAddress.fromString(TEST_BSSID_STR), 11308 WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, -1)); 11309 mLooper.dispatchAll(); 11310 11311 verify(mWifiMetrics).endConnectionEvent( 11312 any(), eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE), 11313 eq(WifiMetricsProto.ConnectionEvent.HLF_NONE), 11314 eq(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE), 11315 anyInt(), eq(ClientModeImpl.EAP_FAILURE_CODE_CERTIFICATE_EXPIRED)); 11316 } 11317 11318 /** 11319 * Verify that the Sae H2E Feature is set even though config_wifiSaeH2eSupported 11320 * is not enabled through overlay. 11321 */ 11322 @Test testSaeH2eSetEvenThoughConfigForSaeH2eIsNotTrue()11323 public void testSaeH2eSetEvenThoughConfigForSaeH2eIsNotTrue() throws Exception { 11324 when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(3)).thenReturn(true); 11325 when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn( 11326 createCapabilityBitset(WifiManager.WIFI_FEATURE_WPA3_SAE)); 11327 initializeCmi(); 11328 if (SdkLevel.isAtLeastV()) { 11329 verify(mWifiGlobals).enableWpa3SaeH2eSupport(); 11330 } else { 11331 verify(mWifiGlobals, never()).enableWpa3SaeH2eSupport(); 11332 } 11333 } 11334 11335 @Test testBlockNetwork()11336 public void testBlockNetwork() throws Exception { 11337 connect(); 11338 BlockingOption option = new BlockingOption.Builder(100) 11339 .setBlockingBssidOnly(true).build(); 11340 mCmi.blockNetwork(option); 11341 verify(mWifiBlocklistMonitor).blockBssidForDurationMs(eq(TEST_BSSID_STR), any(), 11342 eq(100 * 1000L), eq(REASON_APP_DISALLOW), eq(0)); 11343 verify(mWifiBlocklistMonitor).updateAndGetBssidBlocklistForSsids(any()); 11344 } 11345 } 11346