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