WifiStateMachineTest.java revision 54a43675ba622c77dbbcc4ff12fa2c4a92578683
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 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertFalse; 21import static org.junit.Assert.assertNull; 22import static org.junit.Assert.assertTrue; 23import static org.mockito.Mockito.*; 24 25import android.app.ActivityManager; 26import android.app.test.MockAnswerUtil.AnswerWithArguments; 27import android.app.test.TestAlarmManager; 28import android.content.Context; 29import android.content.Intent; 30import android.content.pm.PackageManager; 31import android.content.pm.UserInfo; 32import android.content.res.Resources; 33import android.net.ConnectivityManager; 34import android.net.DhcpResults; 35import android.net.LinkProperties; 36import android.net.dhcp.DhcpClient; 37import android.net.ip.IpManager; 38import android.net.wifi.IApInterface; 39import android.net.wifi.IClientInterface; 40import android.net.wifi.IWificond; 41import android.net.wifi.ScanResult; 42import android.net.wifi.SupplicantState; 43import android.net.wifi.WifiConfiguration; 44import android.net.wifi.WifiInfo; 45import android.net.wifi.WifiManager; 46import android.net.wifi.WifiScanner; 47import android.net.wifi.WifiSsid; 48import android.net.wifi.WpsInfo; 49import android.net.wifi.hotspot2.PasspointConfiguration; 50import android.net.wifi.hotspot2.pps.HomeSp; 51import android.net.wifi.p2p.IWifiP2pManager; 52import android.os.BatteryStats; 53import android.os.Binder; 54import android.os.Bundle; 55import android.os.Handler; 56import android.os.HandlerThread; 57import android.os.IBinder; 58import android.os.IInterface; 59import android.os.INetworkManagementService; 60import android.os.IPowerManager; 61import android.os.Looper; 62import android.os.Message; 63import android.os.Messenger; 64import android.os.PowerManager; 65import android.os.RemoteException; 66import android.os.UserHandle; 67import android.os.UserManager; 68import android.os.test.TestLooper; 69import android.provider.Settings; 70import android.security.KeyStore; 71import android.test.mock.MockContentProvider; 72import android.test.mock.MockContentResolver; 73import android.test.suitebuilder.annotation.SmallTest; 74import android.util.Log; 75import android.util.SparseArray; 76 77import com.android.internal.R; 78import com.android.internal.app.IBatteryStats; 79import com.android.internal.util.AsyncChannel; 80import com.android.internal.util.IState; 81import com.android.internal.util.StateMachine; 82import com.android.server.wifi.hotspot2.NetworkDetail; 83import com.android.server.wifi.hotspot2.PasspointManager; 84import com.android.server.wifi.p2p.WifiP2pServiceImpl; 85 86import org.junit.After; 87import org.junit.Before; 88import org.junit.Test; 89import org.mockito.ArgumentCaptor; 90import org.mockito.ArgumentMatcher; 91import org.mockito.InOrder; 92import org.mockito.Mock; 93import org.mockito.MockitoAnnotations; 94 95import java.io.ByteArrayOutputStream; 96import java.io.PrintWriter; 97import java.lang.reflect.Field; 98import java.lang.reflect.InvocationTargetException; 99import java.lang.reflect.Method; 100import java.util.ArrayList; 101import java.util.Arrays; 102import java.util.HashSet; 103import java.util.List; 104import java.util.Map; 105import java.util.Set; 106import java.util.concurrent.CountDownLatch; 107 108/** 109 * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. 110 */ 111@SmallTest 112public class WifiStateMachineTest { 113 public static final String TAG = "WifiStateMachineTest"; 114 115 private static final int MANAGED_PROFILE_UID = 1100000; 116 private static final int OTHER_USER_UID = 1200000; 117 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE = 118 (ActivityManager.isLowRamDeviceStatic() 119 ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY 120 : WifiStateMachine.NUM_LOG_RECS_VERBOSE); 121 private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; 122 123 private long mBinderToken; 124 125 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 126 return mock(class1, withSettings().extraInterfaces(interfaces)); 127 } 128 129 private static <T, I> IBinder mockService(Class<T> class1, Class<I> iface) { 130 T tImpl = mockWithInterfaces(class1, iface); 131 IBinder binder = mock(IBinder.class); 132 when(((IInterface) tImpl).asBinder()).thenReturn(binder); 133 when(binder.queryLocalInterface(iface.getCanonicalName())) 134 .thenReturn((IInterface) tImpl); 135 return binder; 136 } 137 138 private void enableDebugLogs() { 139 mWsm.enableVerboseLogging(1); 140 } 141 142 private class TestIpManager extends IpManager { 143 TestIpManager(Context context, String ifname, IpManager.Callback callback) { 144 // Call dependency-injection superclass constructor. 145 super(context, ifname, callback, mock(INetworkManagementService.class)); 146 } 147 148 @Override 149 public void startProvisioning(IpManager.ProvisioningConfiguration config) {} 150 151 @Override 152 public void stop() {} 153 154 @Override 155 public void confirmConfiguration() {} 156 157 void injectDhcpSuccess(DhcpResults dhcpResults) { 158 mCallback.onNewDhcpResults(dhcpResults); 159 mCallback.onProvisioningSuccess(new LinkProperties()); 160 } 161 162 void injectDhcpFailure() { 163 mCallback.onNewDhcpResults(null); 164 mCallback.onProvisioningFailure(new LinkProperties()); 165 } 166 } 167 168 private FrameworkFacade getFrameworkFacade() throws Exception { 169 FrameworkFacade facade = mock(FrameworkFacade.class); 170 171 when(facade.getService(Context.NETWORKMANAGEMENT_SERVICE)).thenReturn( 172 mockWithInterfaces(IBinder.class, INetworkManagementService.class)); 173 174 IBinder p2pBinder = mockService(WifiP2pServiceImpl.class, IWifiP2pManager.class); 175 when(facade.getService(Context.WIFI_P2P_SERVICE)).thenReturn(p2pBinder); 176 177 WifiP2pServiceImpl p2pm = (WifiP2pServiceImpl) p2pBinder.queryLocalInterface( 178 IWifiP2pManager.class.getCanonicalName()); 179 180 final CountDownLatch untilDone = new CountDownLatch(1); 181 mP2pThread = new HandlerThread("WifiP2pMockThread") { 182 @Override 183 protected void onLooperPrepared() { 184 untilDone.countDown(); 185 } 186 }; 187 188 mP2pThread.start(); 189 untilDone.await(); 190 191 Handler handler = new Handler(mP2pThread.getLooper()); 192 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 193 194 IBinder batteryStatsBinder = mockService(BatteryStats.class, IBatteryStats.class); 195 when(facade.getService(BatteryStats.SERVICE_NAME)).thenReturn(batteryStatsBinder); 196 197 when(facade.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class))) 198 .then(new AnswerWithArguments() { 199 public IpManager answer( 200 Context context, String ifname, IpManager.Callback callback) { 201 mTestIpManager = new TestIpManager(context, ifname, callback); 202 return mTestIpManager; 203 } 204 }); 205 206 return facade; 207 } 208 209 private Context getContext() throws Exception { 210 PackageManager pkgMgr = mock(PackageManager.class); 211 when(pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 212 213 Context context = mock(Context.class); 214 when(context.getPackageManager()).thenReturn(pkgMgr); 215 216 MockResources resources = new com.android.server.wifi.MockResources(); 217 when(context.getResources()).thenReturn(resources); 218 219 MockContentResolver mockContentResolver = new MockContentResolver(); 220 mockContentResolver.addProvider(Settings.AUTHORITY, 221 new MockContentProvider(context) { 222 @Override 223 public Bundle call(String method, String arg, Bundle extras) { 224 return new Bundle(); 225 } 226 }); 227 when(context.getContentResolver()).thenReturn(mockContentResolver); 228 229 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn( 230 new PowerManager(context, mock(IPowerManager.class), new Handler())); 231 232 mAlarmManager = new TestAlarmManager(); 233 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 234 mAlarmManager.getAlarmManager()); 235 236 when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( 237 mock(ConnectivityManager.class)); 238 239 return context; 240 } 241 242 private Resources getMockResources() { 243 MockResources resources = new MockResources(); 244 resources.setBoolean(R.bool.config_wifi_enable_wifi_firmware_debugging, false); 245 return resources; 246 } 247 248 private IState getCurrentState() throws 249 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 250 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 251 method.setAccessible(true); 252 return (IState) method.invoke(mWsm); 253 } 254 255 private static HandlerThread getWsmHandlerThread(WifiStateMachine wsm) throws 256 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 257 Field field = StateMachine.class.getDeclaredField("mSmThread"); 258 field.setAccessible(true); 259 return (HandlerThread) field.get(wsm); 260 } 261 262 private static void stopLooper(final Looper looper) throws Exception { 263 new Handler(looper).post(new Runnable() { 264 @Override 265 public void run() { 266 looper.quitSafely(); 267 } 268 }); 269 } 270 271 private void dumpState() { 272 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 273 PrintWriter writer = new PrintWriter(stream); 274 mWsm.dump(null, writer, null); 275 writer.flush(); 276 Log.d(TAG, "WifiStateMachine state -" + stream.toString()); 277 } 278 279 private static ScanDetail getGoogleGuestScanDetail(int rssi) { 280 ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; 281 ie[0] = ScanResults.generateSsidIe(sSSID); 282 NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq); 283 ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, 284 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 285 there older than scan start */ 286 ie, new ArrayList<String>()); 287 return detail; 288 } 289 290 private ArrayList<ScanDetail> getMockScanResults() { 291 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 292 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 293 294 int rssi = -65; 295 list.add(getGoogleGuestScanDetail(rssi)); 296 return list; 297 } 298 299 static final String sSSID = "\"GoogleGuest\""; 300 static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID); 301 static final String sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", ""); 302 static final String sBSSID = "01:02:03:04:05:06"; 303 static final int sFreq = 2437; 304 305 WifiStateMachine mWsm; 306 HandlerThread mWsmThread; 307 HandlerThread mP2pThread; 308 HandlerThread mSyncThread; 309 AsyncChannel mWsmAsyncChannel; 310 TestAlarmManager mAlarmManager; 311 MockWifiMonitor mWifiMonitor; 312 TestIpManager mTestIpManager; 313 TestLooper mLooper; 314 Context mContext; 315 316 @Mock WifiScanner mWifiScanner; 317 @Mock SupplicantStateTracker mSupplicantStateTracker; 318 @Mock WifiMetrics mWifiMetrics; 319 @Mock UserManager mUserManager; 320 @Mock WifiApConfigStore mApConfigStore; 321 @Mock BackupManagerProxy mBackupManagerProxy; 322 @Mock WifiCountryCode mCountryCode; 323 @Mock WifiInjector mWifiInjector; 324 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 325 @Mock PropertyService mPropertyService; 326 @Mock BuildProperties mBuildProperties; 327 @Mock IWificond mWificond; 328 @Mock IApInterface mApInterface; 329 @Mock IClientInterface mClientInterface; 330 @Mock IBinder mApInterfaceBinder; 331 @Mock IBinder mClientInterfaceBinder; 332 @Mock WifiConfigManager mWifiConfigManager; 333 @Mock WifiNative mWifiNative; 334 @Mock WifiConnectivityManager mWifiConnectivityManager; 335 @Mock SoftApManager mSoftApManager; 336 @Mock WifiStateTracker mWifiStateTracker; 337 @Mock PasspointManager mPasspointManager; 338 @Mock SelfRecovery mSelfRecovery; 339 340 public WifiStateMachineTest() throws Exception { 341 } 342 343 @Before 344 public void setUp() throws Exception { 345 Log.d(TAG, "Setting up ..."); 346 347 // Ensure looper exists 348 mLooper = new TestLooper(); 349 350 MockitoAnnotations.initMocks(this); 351 352 /** uncomment this to enable logs from WifiStateMachines */ 353 // enableDebugLogs(); 354 355 mWifiMonitor = new MockWifiMonitor(); 356 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 357 when(mWifiInjector.getClock()).thenReturn(new Clock()); 358 when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog); 359 when(mWifiInjector.getPropertyService()).thenReturn(mPropertyService); 360 when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties); 361 when(mWifiInjector.getKeyStore()).thenReturn(mock(KeyStore.class)); 362 when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class)); 363 when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn( 364 mock(BaseWifiDiagnostics.class)); 365 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 366 when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager); 367 when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); 368 when(mWifiInjector.makeWifiConnectivityManager(any(WifiInfo.class), anyBoolean())) 369 .thenReturn(mWifiConnectivityManager); 370 when(mWifiInjector.makeSoftApManager(any(INetworkManagementService.class), 371 any(SoftApManager.Listener.class), any(IApInterface.class), 372 any(WifiConfiguration.class))) 373 .thenReturn(mSoftApManager); 374 when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager); 375 when(mWifiInjector.getWifiStateTracker()).thenReturn(mWifiStateTracker); 376 when(mWifiInjector.getWifiMonitor()).thenReturn(mWifiMonitor); 377 when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative); 378 when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); 379 380 when(mWifiNative.setupForClientMode()).thenReturn(mClientInterface); 381 when(mWifiNative.setupForSoftApMode()).thenReturn(mApInterface); 382 when(mWifiNative.getInterfaceName()).thenReturn("mockWlan"); 383 when(mWifiNative.enableSupplicant()).thenReturn(true); 384 when(mWifiNative.disableSupplicant()).thenReturn(true); 385 when(mWifiNative.getFrameworkNetworkId(anyInt())).thenReturn(0); 386 387 388 FrameworkFacade factory = getFrameworkFacade(); 389 mContext = getContext(); 390 391 Resources resources = getMockResources(); 392 when(mContext.getResources()).thenReturn(resources); 393 394 when(factory.getIntegerSetting(mContext, 395 Settings.Global.WIFI_FREQUENCY_BAND, 396 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 397 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 398 399 when(factory.makeApConfigStore(eq(mContext), eq(mBackupManagerProxy))) 400 .thenReturn(mApConfigStore); 401 402 when(factory.makeSupplicantStateTracker( 403 any(Context.class), any(WifiConfigManager.class), 404 any(Handler.class))).thenReturn(mSupplicantStateTracker); 405 406 when(mUserManager.getProfileParent(11)) 407 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "owner", 0)); 408 when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(Arrays.asList( 409 new UserInfo(UserHandle.USER_SYSTEM, "owner", 0), 410 new UserInfo(11, "managed profile", 0))); 411 412 when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder); 413 when(mClientInterface.asBinder()).thenReturn(mClientInterfaceBinder); 414 415 mWsm = new WifiStateMachine(mContext, factory, mLooper.getLooper(), 416 mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative); 417 mWsmThread = getWsmHandlerThread(mWsm); 418 419 final AsyncChannel channel = new AsyncChannel(); 420 Handler handler = new Handler(mLooper.getLooper()) { 421 @Override 422 public void handleMessage(Message msg) { 423 switch (msg.what) { 424 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 425 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 426 mWsmAsyncChannel = channel; 427 } else { 428 Log.d(TAG, "Failed to connect Command channel " + this); 429 } 430 break; 431 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 432 Log.d(TAG, "Command channel disconnected" + this); 433 break; 434 } 435 } 436 }; 437 438 channel.connect(mContext, handler, mWsm.getMessenger()); 439 mLooper.dispatchAll(); 440 /* Now channel is supposed to be connected */ 441 442 mBinderToken = Binder.clearCallingIdentity(); 443 } 444 445 @After 446 public void cleanUp() throws Exception { 447 Binder.restoreCallingIdentity(mBinderToken); 448 449 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 450 if (mWsmThread != null) stopLooper(mWsmThread.getLooper()); 451 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 452 453 mWsmThread = null; 454 mP2pThread = null; 455 mSyncThread = null; 456 mWsmAsyncChannel = null; 457 mWsm = null; 458 } 459 460 @Test 461 public void createNew() throws Exception { 462 assertEquals("InitialState", getCurrentState().getName()); 463 464 mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); 465 mLooper.dispatchAll(); 466 assertEquals("InitialState", getCurrentState().getName()); 467 } 468 469 @Test 470 public void loadComponentsInStaMode() throws Exception { 471 startSupplicantAndDispatchMessages(); 472 473 verify(mContext).sendStickyBroadcastAsUser( 474 (Intent) argThat(new WifiEnablingStateIntentMatcher()), eq(UserHandle.ALL)); 475 476 assertEquals("DisconnectedState", getCurrentState().getName()); 477 } 478 479 @Test 480 public void loadComponentsInApMode() throws Exception { 481 mWsm.setHostApRunning(new WifiConfiguration(), true); 482 mLooper.dispatchAll(); 483 484 assertEquals("SoftApState", getCurrentState().getName()); 485 486 verify(mSoftApManager).start(); 487 } 488 489 @Test 490 public void shouldRequireSupplicantStartupToLeaveInitialState() throws Exception { 491 when(mWifiNative.enableSupplicant()).thenReturn(false); 492 mWsm.setSupplicantRunning(true); 493 mLooper.dispatchAll(); 494 assertEquals("InitialState", getCurrentState().getName()); 495 // we should not be sending a wifi enabling update 496 verify(mContext, never()).sendStickyBroadcastAsUser( 497 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 498 } 499 500 @Test 501 public void shouldRequireWificondToLeaveInitialState() throws Exception { 502 // We start out with valid default values, break them going backwards so that 503 // we test all the bailout cases. 504 505 // ClientInterface dies after creation. 506 doThrow(new RemoteException()).when(mClientInterfaceBinder).linkToDeath(any(), anyInt()); 507 mWsm.setSupplicantRunning(true); 508 mLooper.dispatchAll(); 509 assertEquals("InitialState", getCurrentState().getName()); 510 511 // Failed to even create the client interface. 512 when(mWificond.createClientInterface()).thenReturn(null); 513 mWsm.setSupplicantRunning(true); 514 mLooper.dispatchAll(); 515 assertEquals("InitialState", getCurrentState().getName()); 516 517 // Failed to get wificond proxy. 518 when(mWifiInjector.makeWificond()).thenReturn(null); 519 mWsm.setSupplicantRunning(true); 520 mLooper.dispatchAll(); 521 assertEquals("InitialState", getCurrentState().getName()); 522 } 523 524 @Test 525 public void loadComponentsFailure() throws Exception { 526 when(mWifiNative.enableSupplicant()).thenReturn(false); 527 528 mWsm.setSupplicantRunning(true); 529 mLooper.dispatchAll(); 530 assertEquals("InitialState", getCurrentState().getName()); 531 532 mWsm.setSupplicantRunning(true); 533 mLooper.dispatchAll(); 534 assertEquals("InitialState", getCurrentState().getName()); 535 } 536 537 @Test 538 public void checkInitialStateStickyWhenDisabledMode() throws Exception { 539 mLooper.dispatchAll(); 540 assertEquals("InitialState", getCurrentState().getName()); 541 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 542 543 mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE); 544 mLooper.dispatchAll(); 545 assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest()); 546 assertEquals("InitialState", getCurrentState().getName()); 547 } 548 549 @Test 550 public void shouldStartSupplicantWhenConnectModeRequested() throws Exception { 551 // The first time we start out in InitialState, we sit around here. 552 mLooper.dispatchAll(); 553 assertEquals("InitialState", getCurrentState().getName()); 554 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 555 556 // But if someone tells us to enter connect mode, we start up supplicant 557 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 558 mLooper.dispatchAll(); 559 assertEquals("SupplicantStartingState", getCurrentState().getName()); 560 } 561 562 /** 563 * Test that mode changes accurately reflect the value for isWifiEnabled. 564 */ 565 @Test 566 public void checkIsWifiEnabledForModeChanges() throws Exception { 567 // Check initial state 568 mLooper.dispatchAll(); 569 assertEquals("InitialState", getCurrentState().getName()); 570 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 571 572 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 573 startSupplicantAndDispatchMessages(); 574 mWsm.setSupplicantRunning(true); 575 mLooper.dispatchAll(); 576 assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest()); 577 assertEquals("ScanModeState", getCurrentState().getName()); 578 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 579 verify(mContext, never()).sendStickyBroadcastAsUser( 580 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 581 582 583 // switch to connect mode and verify wifi is reported as enabled 584 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 585 mLooper.dispatchAll(); 586 assertEquals("DisconnectedState", getCurrentState().getName()); 587 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 588 assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState()); 589 verify(mContext).sendStickyBroadcastAsUser( 590 (Intent) argThat(new WifiEnablingStateIntentMatcher()), eq(UserHandle.ALL)); 591 592 // reset the expectations on mContext since we did get an expected broadcast, but we should 593 // not on the next transition 594 reset(mContext); 595 596 // now go back to scan mode with "wifi disabled" to verify the reported wifi state. 597 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE); 598 mLooper.dispatchAll(); 599 assertEquals(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE, 600 mWsm.getOperationalModeForTest()); 601 assertEquals("ScanModeState", getCurrentState().getName()); 602 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 603 verify(mContext, never()).sendStickyBroadcastAsUser( 604 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 605 606 // now go to AP mode 607 mWsm.setSupplicantRunning(false); 608 mWsm.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP); 609 mWsm.sendMessage(WifiMonitor.SUP_DISCONNECTION_EVENT); 610 mWsm.setHostApRunning(new WifiConfiguration(), true); 611 mLooper.dispatchAll(); 612 assertEquals("SoftApState", getCurrentState().getName()); 613 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 614 verify(mContext, never()).sendStickyBroadcastAsUser( 615 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 616 } 617 618 private class WifiEnablingStateIntentMatcher implements ArgumentMatcher<Intent> { 619 @Override 620 public boolean matches(Intent intent) { 621 if (WifiManager.WIFI_STATE_CHANGED_ACTION != intent.getAction()) { 622 // not the correct type 623 return false; 624 } 625 return WifiManager.WIFI_STATE_ENABLING 626 == intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 627 WifiManager.WIFI_STATE_DISABLED); 628 } 629 } 630 631 /** 632 * Test that mode changes for WifiStateMachine in the InitialState are realized when supplicant 633 * is started. 634 */ 635 @Test 636 public void checkStartInCorrectStateAfterChangingInitialState() throws Exception { 637 // Check initial state 638 mLooper.dispatchAll(); 639 assertEquals("InitialState", getCurrentState().getName()); 640 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 641 642 // Update the mode 643 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 644 mLooper.dispatchAll(); 645 assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest()); 646 647 // Start supplicant so we move to the next state 648 startSupplicantAndDispatchMessages(); 649 650 assertEquals("ScanModeState", getCurrentState().getName()); 651 verify(mContext, never()).sendStickyBroadcastAsUser( 652 (Intent) argThat(new WifiEnablingStateIntentMatcher()), any()); 653 } 654 655 /** 656 * Verifies that configs can be removed when in client mode. 657 */ 658 @Test 659 public void canRemoveNetworkConfigInClientMode() throws Exception { 660 boolean result; 661 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 662 initializeAndAddNetworkAndVerifySuccess(); 663 mLooper.startAutoDispatch(); 664 result = mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0); 665 mLooper.stopAutoDispatch(); 666 assertTrue(result); 667 } 668 669 /** 670 * Verifies that configs can be removed when not in client mode. 671 */ 672 @Test 673 public void canRemoveNetworkConfigWhenWifiDisabled() { 674 boolean result; 675 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 676 mLooper.startAutoDispatch(); 677 result = mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0); 678 mLooper.stopAutoDispatch(); 679 680 assertTrue(result); 681 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 682 } 683 684 /** 685 * Verifies that configs can be forgotten when in client mode. 686 */ 687 @Test 688 public void canForgetNetworkConfigInClientMode() throws Exception { 689 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 690 initializeAndAddNetworkAndVerifySuccess(); 691 mWsm.sendMessage(WifiManager.FORGET_NETWORK, 0, MANAGED_PROFILE_UID); 692 mLooper.dispatchAll(); 693 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 694 } 695 696 /** 697 * Verifies that configs can be removed when not in client mode. 698 */ 699 @Test 700 public void canForgetNetworkConfigWhenWifiDisabled() throws Exception { 701 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 702 mWsm.sendMessage(WifiManager.FORGET_NETWORK, 0, MANAGED_PROFILE_UID); 703 mLooper.dispatchAll(); 704 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 705 } 706 707 /** 708 * Helper method to move through SupplicantStarting and SupplicantStarted states. 709 */ 710 private void startSupplicantAndDispatchMessages() throws Exception { 711 mWsm.setSupplicantRunning(true); 712 mLooper.dispatchAll(); 713 714 assertEquals("SupplicantStartingState", getCurrentState().getName()); 715 716 when(mWifiNative.setDeviceName(anyString())).thenReturn(true); 717 when(mWifiNative.setManufacturer(anyString())).thenReturn(true); 718 when(mWifiNative.setModelName(anyString())).thenReturn(true); 719 when(mWifiNative.setModelNumber(anyString())).thenReturn(true); 720 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 721 when(mWifiNative.setConfigMethods(anyString())).thenReturn(true); 722 when(mWifiNative.setDeviceType(anyString())).thenReturn(true); 723 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 724 when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true); 725 726 mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); 727 mLooper.dispatchAll(); 728 } 729 730 private void addNetworkAndVerifySuccess(boolean isHidden) throws Exception { 731 WifiConfiguration config = new WifiConfiguration(); 732 config.SSID = sSSID; 733 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 734 config.hiddenSSID = isHidden; 735 736 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 737 .thenReturn(new NetworkUpdateResult(0)); 738 when(mWifiConfigManager.getSavedNetworks()).thenReturn(Arrays.asList(config)); 739 when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config); 740 741 mLooper.startAutoDispatch(); 742 mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config); 743 mLooper.stopAutoDispatch(); 744 745 verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt()); 746 747 mLooper.startAutoDispatch(); 748 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 749 mLooper.stopAutoDispatch(); 750 assertEquals(1, configs.size()); 751 752 WifiConfiguration config2 = configs.get(0); 753 assertEquals("\"GoogleGuest\"", config2.SSID); 754 assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); 755 } 756 757 private void initializeAndAddNetworkAndVerifySuccess() throws Exception { 758 initializeAndAddNetworkAndVerifySuccess(false); 759 } 760 761 private void initializeAndAddNetworkAndVerifySuccess(boolean isHidden) throws Exception { 762 loadComponentsInStaMode(); 763 addNetworkAndVerifySuccess(isHidden); 764 } 765 766 /** 767 * Helper method to retrieve WifiConfiguration by SSID. 768 * 769 * Returns the associated WifiConfiguration if it is found, null otherwise. 770 */ 771 private WifiConfiguration getWifiConfigurationForNetwork(String ssid) { 772 mLooper.startAutoDispatch(); 773 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 774 mLooper.stopAutoDispatch(); 775 776 for (WifiConfiguration checkConfig : configs) { 777 if (checkConfig.SSID.equals(ssid)) { 778 return checkConfig; 779 } 780 } 781 return null; 782 } 783 784 private void verifyScan(int band, int reportEvents, Set<String> hiddenNetworkSSIDSet) { 785 ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor = 786 ArgumentCaptor.forClass(WifiScanner.ScanSettings.class); 787 ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor = 788 ArgumentCaptor.forClass(WifiScanner.ScanListener.class); 789 verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture(), 790 eq(null)); 791 WifiScanner.ScanSettings actualSettings = scanSettingsCaptor.getValue(); 792 assertEquals("band", band, actualSettings.band); 793 assertEquals("reportEvents", reportEvents, actualSettings.reportEvents); 794 795 if (hiddenNetworkSSIDSet == null) { 796 hiddenNetworkSSIDSet = new HashSet<>(); 797 } 798 Set<String> actualHiddenNetworkSSIDSet = new HashSet<>(); 799 if (actualSettings.hiddenNetworks != null) { 800 for (int i = 0; i < actualSettings.hiddenNetworks.length; ++i) { 801 actualHiddenNetworkSSIDSet.add(actualSettings.hiddenNetworks[i].ssid); 802 } 803 } 804 assertEquals("hidden networks", hiddenNetworkSSIDSet, actualHiddenNetworkSSIDSet); 805 806 when(mWifiNative.getScanResults()).thenReturn(getMockScanResults()); 807 mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT); 808 809 mLooper.dispatchAll(); 810 811 List<ScanResult> reportedResults = mWsm.syncGetScanResultsList(); 812 assertEquals(8, reportedResults.size()); 813 } 814 815 @Test 816 public void scan() throws Exception { 817 initializeAndAddNetworkAndVerifySuccess(); 818 819 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 820 mWsm.startScan(-1, 0, null, null); 821 mLooper.dispatchAll(); 822 823 verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 824 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 825 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, null); 826 } 827 828 @Test 829 public void scanWithHiddenNetwork() throws Exception { 830 initializeAndAddNetworkAndVerifySuccess(true); 831 832 Set<String> hiddenNetworkSet = new HashSet<>(); 833 hiddenNetworkSet.add(sSSID); 834 List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworkList = new ArrayList<>(); 835 hiddenNetworkList.add(new WifiScanner.ScanSettings.HiddenNetwork(sSSID)); 836 when(mWifiConfigManager.retrieveHiddenNetworkList()).thenReturn(hiddenNetworkList); 837 838 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 839 mWsm.startScan(-1, 0, null, null); 840 mLooper.dispatchAll(); 841 842 verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 843 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 844 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 845 hiddenNetworkSet); 846 } 847 848 @Test 849 public void connect() throws Exception { 850 initializeAndAddNetworkAndVerifySuccess(); 851 when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt())).thenReturn(true); 852 when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(0), anyInt())).thenReturn(true); 853 854 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 855 mLooper.dispatchAll(); 856 verify(mWifiNative).removeAllNetworks(); 857 858 mLooper.startAutoDispatch(); 859 assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); 860 mLooper.stopAutoDispatch(); 861 862 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 863 verify(mWifiConnectivityManager).setUserConnectChoice(eq(0)); 864 865 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 866 mLooper.dispatchAll(); 867 868 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 869 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 870 mLooper.dispatchAll(); 871 872 assertEquals("ObtainingIpState", getCurrentState().getName()); 873 874 DhcpResults dhcpResults = new DhcpResults(); 875 dhcpResults.setGateway("1.2.3.4"); 876 dhcpResults.setIpAddress("192.168.1.100", 0); 877 dhcpResults.addDns("8.8.8.8"); 878 dhcpResults.setLeaseDuration(3600); 879 880 mTestIpManager.injectDhcpSuccess(dhcpResults); 881 mLooper.dispatchAll(); 882 883 assertEquals("ConnectedState", getCurrentState().getName()); 884 } 885 886 @Test 887 public void connectWithNoEnablePermission() throws Exception { 888 initializeAndAddNetworkAndVerifySuccess(); 889 when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt())).thenReturn(false); 890 when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(0), anyInt())).thenReturn(false); 891 892 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 893 mLooper.dispatchAll(); 894 verify(mWifiNative).removeAllNetworks(); 895 896 mLooper.startAutoDispatch(); 897 assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); 898 mLooper.stopAutoDispatch(); 899 900 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 901 verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(0)); 902 903 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 904 mLooper.dispatchAll(); 905 906 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 907 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 908 mLooper.dispatchAll(); 909 910 assertEquals("ObtainingIpState", getCurrentState().getName()); 911 912 DhcpResults dhcpResults = new DhcpResults(); 913 dhcpResults.setGateway("1.2.3.4"); 914 dhcpResults.setIpAddress("192.168.1.100", 0); 915 dhcpResults.addDns("8.8.8.8"); 916 dhcpResults.setLeaseDuration(3600); 917 918 mTestIpManager.injectDhcpSuccess(dhcpResults); 919 mLooper.dispatchAll(); 920 921 assertEquals("ConnectedState", getCurrentState().getName()); 922 } 923 924 @Test 925 public void enableWithInvalidNetworkId() throws Exception { 926 initializeAndAddNetworkAndVerifySuccess(); 927 when(mWifiConfigManager.getConfiguredNetwork(eq(0))).thenReturn(null); 928 929 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 930 mLooper.dispatchAll(); 931 verify(mWifiNative).removeAllNetworks(); 932 933 mLooper.startAutoDispatch(); 934 assertFalse(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); 935 mLooper.stopAutoDispatch(); 936 937 verify(mWifiConfigManager, never()).enableNetwork(eq(0), eq(true), anyInt()); 938 verify(mWifiConfigManager, never()).checkAndUpdateLastConnectUid(eq(0), anyInt()); 939 } 940 941 /** 942 * If caller tries to connect to a network that is already connected, the connection request 943 * should succeed. 944 * 945 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 946 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 947 */ 948 @Test 949 public void reconnectToConnectedNetwork() throws Exception { 950 initializeAndAddNetworkAndVerifySuccess(); 951 952 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 953 mLooper.dispatchAll(); 954 verify(mWifiNative).removeAllNetworks(); 955 956 mLooper.startAutoDispatch(); 957 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 958 mLooper.stopAutoDispatch(); 959 960 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 961 962 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 963 mLooper.dispatchAll(); 964 965 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 966 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 967 mLooper.dispatchAll(); 968 969 assertEquals("ObtainingIpState", getCurrentState().getName()); 970 971 // try to reconnect 972 mLooper.startAutoDispatch(); 973 Message reply = mWsmAsyncChannel.sendMessageSynchronously(WifiManager.CONNECT_NETWORK, 0); 974 mLooper.stopAutoDispatch(); 975 976 assertEquals(WifiManager.CONNECT_NETWORK_SUCCEEDED, reply.what); 977 } 978 979 @Test 980 public void testDhcpFailure() throws Exception { 981 initializeAndAddNetworkAndVerifySuccess(); 982 983 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 984 mLooper.dispatchAll(); 985 986 mLooper.startAutoDispatch(); 987 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 988 mLooper.stopAutoDispatch(); 989 990 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 991 992 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 993 mLooper.dispatchAll(); 994 995 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 996 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 997 mLooper.dispatchAll(); 998 999 assertEquals("ObtainingIpState", getCurrentState().getName()); 1000 1001 mTestIpManager.injectDhcpFailure(); 1002 mLooper.dispatchAll(); 1003 1004 assertEquals("DisconnectingState", getCurrentState().getName()); 1005 } 1006 1007 @Test 1008 public void testBadNetworkEvent() throws Exception { 1009 initializeAndAddNetworkAndVerifySuccess(); 1010 1011 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1012 mLooper.dispatchAll(); 1013 1014 mLooper.startAutoDispatch(); 1015 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 1016 mLooper.stopAutoDispatch(); 1017 1018 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 1019 1020 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 1021 mLooper.dispatchAll(); 1022 1023 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1024 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1025 mLooper.dispatchAll(); 1026 1027 assertEquals("DisconnectedState", getCurrentState().getName()); 1028 } 1029 1030 1031 @Test 1032 public void smToString() throws Exception { 1033 assertEquals("CMD_CHANNEL_HALF_CONNECTED", mWsm.smToString( 1034 AsyncChannel.CMD_CHANNEL_HALF_CONNECTED)); 1035 assertEquals("CMD_PRE_DHCP_ACTION", mWsm.smToString( 1036 DhcpClient.CMD_PRE_DHCP_ACTION)); 1037 assertEquals("CMD_IP_REACHABILITY_LOST", mWsm.smToString( 1038 WifiStateMachine.CMD_IP_REACHABILITY_LOST)); 1039 } 1040 1041 @Test 1042 public void disconnect() throws Exception { 1043 connect(); 1044 1045 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06"); 1046 mLooper.dispatchAll(); 1047 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1048 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 1049 mLooper.dispatchAll(); 1050 1051 assertEquals("DisconnectedState", getCurrentState().getName()); 1052 } 1053 1054 /** 1055 * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected 1056 * to true. 1057 * 1058 * Test: Successfully create and connect to a network. Check the config and verify 1059 * WifiConfiguration.getHasEverConnected() is true. 1060 */ 1061 @Test 1062 public void setHasEverConnectedTrueOnConnect() throws Exception { 1063 connect(); 1064 verify(mWifiConfigManager, atLeastOnce()).updateNetworkAfterConnect(0); 1065 } 1066 1067 /** 1068 * Fail network connection attempt and verify HasEverConnected remains false. 1069 * 1070 * Test: Successfully create a network but fail when connecting. Check the config and verify 1071 * WifiConfiguration.getHasEverConnected() is false. 1072 */ 1073 @Test 1074 public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception { 1075 testDhcpFailure(); 1076 verify(mWifiConfigManager, never()).updateNetworkAfterConnect(0); 1077 } 1078 1079 @Test 1080 public void iconQueryTest() throws Exception { 1081 // TODO(b/31065385): Passpoint config management. 1082 } 1083 1084 @Test 1085 public void verboseLogRecSizeIsGreaterThanNormalSize() { 1086 assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > WifiStateMachine.NUM_LOG_RECS_NORMAL); 1087 } 1088 1089 /** 1090 * Verifies that, by default, we allow only the "normal" number of log records. 1091 */ 1092 @Test 1093 public void normalLogRecSizeIsUsedByDefault() { 1094 assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecMaxSize()); 1095 } 1096 1097 /** 1098 * Verifies that, in verbose mode, we allow a larger number of log records. 1099 */ 1100 @Test 1101 public void enablingVerboseLoggingUpdatesLogRecSize() { 1102 mWsm.enableVerboseLogging(1); 1103 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mWsm.getLogRecMaxSize()); 1104 } 1105 1106 @Test 1107 public void disablingVerboseLoggingClearsRecords() { 1108 mWsm.sendMessage(WifiStateMachine.CMD_DISCONNECT); 1109 mLooper.dispatchAll(); 1110 assertTrue(mWsm.getLogRecSize() >= 1); 1111 1112 mWsm.enableVerboseLogging(0); 1113 assertEquals(0, mWsm.getLogRecSize()); 1114 } 1115 1116 @Test 1117 public void disablingVerboseLoggingUpdatesLogRecSize() { 1118 mWsm.enableVerboseLogging(1); 1119 mWsm.enableVerboseLogging(0); 1120 assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecMaxSize()); 1121 } 1122 1123 @Test 1124 public void logRecsIncludeDisconnectCommand() { 1125 // There's nothing special about the DISCONNECT command. It's just representative of 1126 // "normal" commands. 1127 mWsm.sendMessage(WifiStateMachine.CMD_DISCONNECT); 1128 mLooper.dispatchAll(); 1129 assertEquals(1, mWsm.copyLogRecs() 1130 .stream() 1131 .filter(logRec -> logRec.getWhat() == WifiStateMachine.CMD_DISCONNECT) 1132 .count()); 1133 } 1134 1135 @Test 1136 public void logRecsExcludeRssiPollCommandByDefault() { 1137 mWsm.sendMessage(WifiStateMachine.CMD_RSSI_POLL); 1138 mLooper.dispatchAll(); 1139 assertEquals(0, mWsm.copyLogRecs() 1140 .stream() 1141 .filter(logRec -> logRec.getWhat() == WifiStateMachine.CMD_RSSI_POLL) 1142 .count()); 1143 } 1144 1145 @Test 1146 public void logRecsIncludeRssiPollCommandWhenVerboseLoggingIsEnabled() { 1147 mWsm.enableVerboseLogging(1); 1148 mWsm.sendMessage(WifiStateMachine.CMD_RSSI_POLL); 1149 mLooper.dispatchAll(); 1150 assertEquals(1, mWsm.copyLogRecs() 1151 .stream() 1152 .filter(logRec -> logRec.getWhat() == WifiStateMachine.CMD_RSSI_POLL) 1153 .count()); 1154 } 1155 1156 /** Verifies that enabling verbose logging sets the hal log property in eng builds. */ 1157 @Test 1158 public void enablingVerboseLoggingSetsHalLogPropertyInEngBuilds() { 1159 reset(mPropertyService); // Ignore calls made in setUp() 1160 when(mBuildProperties.isEngBuild()).thenReturn(true); 1161 when(mBuildProperties.isUserdebugBuild()).thenReturn(false); 1162 when(mBuildProperties.isUserBuild()).thenReturn(false); 1163 mWsm.enableVerboseLogging(1); 1164 verify(mPropertyService).set("log.tag.WifiHAL", "V"); 1165 } 1166 1167 /** Verifies that enabling verbose logging sets the hal log property in userdebug builds. */ 1168 @Test 1169 public void enablingVerboseLoggingSetsHalLogPropertyInUserdebugBuilds() { 1170 reset(mPropertyService); // Ignore calls made in setUp() 1171 when(mBuildProperties.isUserdebugBuild()).thenReturn(true); 1172 when(mBuildProperties.isEngBuild()).thenReturn(false); 1173 when(mBuildProperties.isUserBuild()).thenReturn(false); 1174 mWsm.enableVerboseLogging(1); 1175 verify(mPropertyService).set("log.tag.WifiHAL", "V"); 1176 } 1177 1178 /** Verifies that enabling verbose logging does NOT set the hal log property in user builds. */ 1179 @Test 1180 public void enablingVerboseLoggingDoeNotSetHalLogPropertyInUserBuilds() { 1181 reset(mPropertyService); // Ignore calls made in setUp() 1182 when(mBuildProperties.isUserBuild()).thenReturn(true); 1183 when(mBuildProperties.isEngBuild()).thenReturn(false); 1184 when(mBuildProperties.isUserdebugBuild()).thenReturn(false); 1185 mWsm.enableVerboseLogging(1); 1186 verify(mPropertyService, never()).set(anyString(), anyString()); 1187 } 1188 1189 private int testGetSupportedFeaturesCase(int supportedFeatures, boolean rttConfigured) { 1190 AsyncChannel channel = mock(AsyncChannel.class); 1191 Message reply = Message.obtain(); 1192 reply.arg1 = supportedFeatures; 1193 reset(mPropertyService); // Ignore calls made in setUp() 1194 when(channel.sendMessageSynchronously(WifiStateMachine.CMD_GET_SUPPORTED_FEATURES)) 1195 .thenReturn(reply); 1196 when(mPropertyService.getBoolean("config.disable_rtt", false)) 1197 .thenReturn(rttConfigured); 1198 return mWsm.syncGetSupportedFeatures(channel); 1199 } 1200 1201 /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */ 1202 @Test 1203 public void syncGetSupportedFeatures() { 1204 final int featureAware = WifiManager.WIFI_FEATURE_AWARE; 1205 final int featureInfra = WifiManager.WIFI_FEATURE_INFRA; 1206 final int featureD2dRtt = WifiManager.WIFI_FEATURE_D2D_RTT; 1207 final int featureD2apRtt = WifiManager.WIFI_FEATURE_D2AP_RTT; 1208 1209 assertEquals(0, testGetSupportedFeaturesCase(0, false)); 1210 assertEquals(0, testGetSupportedFeaturesCase(0, true)); 1211 assertEquals(featureAware | featureInfra, 1212 testGetSupportedFeaturesCase(featureAware | featureInfra, false)); 1213 assertEquals(featureAware | featureInfra, 1214 testGetSupportedFeaturesCase(featureAware | featureInfra, true)); 1215 assertEquals(featureInfra | featureD2dRtt, 1216 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt, false)); 1217 assertEquals(featureInfra, 1218 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt, true)); 1219 assertEquals(featureInfra | featureD2apRtt, 1220 testGetSupportedFeaturesCase(featureInfra | featureD2apRtt, false)); 1221 assertEquals(featureInfra, 1222 testGetSupportedFeaturesCase(featureInfra | featureD2apRtt, true)); 1223 assertEquals(featureInfra | featureD2dRtt | featureD2apRtt, 1224 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt | featureD2apRtt, false)); 1225 assertEquals(featureInfra, 1226 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt | featureD2apRtt, true)); 1227 } 1228 1229 /** 1230 * Verify that syncAddOrUpdatePasspointConfig will redirect calls to {@link PasspointManager} 1231 * and returning the result that's returned from {@link PasspointManager}. 1232 */ 1233 @Test 1234 public void syncAddOrUpdatePasspointConfig() throws Exception { 1235 PasspointConfiguration config = new PasspointConfiguration(); 1236 HomeSp homeSp = new HomeSp(); 1237 homeSp.setFqdn("test.com"); 1238 config.setHomeSp(homeSp); 1239 1240 when(mPasspointManager.addOrUpdateProvider(config, MANAGED_PROFILE_UID)).thenReturn(true); 1241 mLooper.startAutoDispatch(); 1242 assertTrue(mWsm.syncAddOrUpdatePasspointConfig( 1243 mWsmAsyncChannel, config, MANAGED_PROFILE_UID)); 1244 mLooper.stopAutoDispatch(); 1245 reset(mPasspointManager); 1246 1247 when(mPasspointManager.addOrUpdateProvider(config, MANAGED_PROFILE_UID)).thenReturn(false); 1248 mLooper.startAutoDispatch(); 1249 assertFalse(mWsm.syncAddOrUpdatePasspointConfig( 1250 mWsmAsyncChannel, config, MANAGED_PROFILE_UID)); 1251 mLooper.stopAutoDispatch(); 1252 } 1253 1254 /** 1255 * Verify that syncAddOrUpdatePasspointConfig will redirect calls to {@link PasspointManager} 1256 * and returning the result that's returned from {@link PasspointManager} when in client mode. 1257 */ 1258 @Test 1259 public void syncAddOrUpdatePasspointConfigInClientMode() throws Exception { 1260 loadComponentsInStaMode(); 1261 syncAddOrUpdatePasspointConfig(); 1262 } 1263 1264 /** 1265 * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager} 1266 * and returning the result that's returned from {@link PasspointManager}. 1267 */ 1268 @Test 1269 public void syncRemovePasspointConfig() throws Exception { 1270 String fqdn = "test.com"; 1271 when(mPasspointManager.removeProvider(fqdn)).thenReturn(true); 1272 mLooper.startAutoDispatch(); 1273 assertTrue(mWsm.syncRemovePasspointConfig(mWsmAsyncChannel, fqdn)); 1274 mLooper.stopAutoDispatch(); 1275 reset(mPasspointManager); 1276 1277 when(mPasspointManager.removeProvider(fqdn)).thenReturn(false); 1278 mLooper.startAutoDispatch(); 1279 assertFalse(mWsm.syncRemovePasspointConfig(mWsmAsyncChannel, fqdn)); 1280 mLooper.stopAutoDispatch(); 1281 } 1282 1283 /** 1284 * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager} 1285 * and returning the result that's returned from {@link PasspointManager} when in client mode. 1286 */ 1287 @Test 1288 public void syncRemovePasspointConfigInClientMode() throws Exception { 1289 loadComponentsInStaMode(); 1290 syncRemovePasspointConfig(); 1291 } 1292 1293 /** 1294 * Verify that syncGetPasspointConfigs will redirect calls to {@link PasspointManager} 1295 * and returning the result that's returned from {@link PasspointManager}. 1296 */ 1297 @Test 1298 public void syncGetPasspointConfigs() throws Exception { 1299 // Setup expected configs. 1300 List<PasspointConfiguration> expectedConfigs = new ArrayList<>(); 1301 PasspointConfiguration config = new PasspointConfiguration(); 1302 HomeSp homeSp = new HomeSp(); 1303 homeSp.setFqdn("test.com"); 1304 config.setHomeSp(homeSp); 1305 expectedConfigs.add(config); 1306 1307 when(mPasspointManager.getProviderConfigs()).thenReturn(expectedConfigs); 1308 mLooper.startAutoDispatch(); 1309 assertEquals(expectedConfigs, mWsm.syncGetPasspointConfigs(mWsmAsyncChannel)); 1310 mLooper.stopAutoDispatch(); 1311 reset(mPasspointManager); 1312 1313 when(mPasspointManager.getProviderConfigs()) 1314 .thenReturn(new ArrayList<PasspointConfiguration>()); 1315 mLooper.startAutoDispatch(); 1316 assertTrue(mWsm.syncGetPasspointConfigs(mWsmAsyncChannel).isEmpty()); 1317 mLooper.stopAutoDispatch(); 1318 } 1319 1320 /** 1321 * Verify that syncGetMatchingWifiConfig will redirect calls to {@link PasspointManager} 1322 * with expected {@link WifiConfiguration} being returned when in client mode. 1323 * 1324 * @throws Exception 1325 */ 1326 @Test 1327 public void syncGetMatchingWifiConfigInClientMode() throws Exception { 1328 loadComponentsInStaMode(); 1329 1330 when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))).thenReturn(null); 1331 mLooper.startAutoDispatch(); 1332 assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); 1333 mLooper.stopAutoDispatch(); 1334 reset(mPasspointManager); 1335 1336 WifiConfiguration expectedConfig = new WifiConfiguration(); 1337 expectedConfig.SSID = "TestSSID"; 1338 when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))) 1339 .thenReturn(expectedConfig); 1340 mLooper.startAutoDispatch(); 1341 WifiConfiguration actualConfig = mWsm.syncGetMatchingWifiConfig(new ScanResult(), 1342 mWsmAsyncChannel); 1343 mLooper.stopAutoDispatch(); 1344 assertEquals(expectedConfig.SSID, actualConfig.SSID); 1345 } 1346 1347 /** 1348 * Verify that syncGetMatchingWifiConfig will be a no-op and return {@code null} when not in 1349 * client mode. 1350 * 1351 * @throws Exception 1352 */ 1353 @Test 1354 public void syncGetMatchingWifiConfigInNonClientMode() throws Exception { 1355 mLooper.startAutoDispatch(); 1356 assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); 1357 mLooper.stopAutoDispatch(); 1358 verify(mPasspointManager, never()).getMatchingWifiConfig(any(ScanResult.class)); 1359 } 1360 1361 /** 1362 * Verify successful Wps PBC network connection. 1363 */ 1364 @Test 1365 public void wpsPbcConnectSuccess() throws Exception { 1366 loadComponentsInStaMode(); 1367 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1368 mLooper.dispatchAll(); 1369 1370 when(mWifiNative.startWpsPbc(eq(sBSSID))).thenReturn(true); 1371 WpsInfo wpsInfo = new WpsInfo(); 1372 wpsInfo.setup = WpsInfo.PBC; 1373 wpsInfo.BSSID = sBSSID; 1374 1375 mWsm.sendMessage(WifiManager.START_WPS, 0, 0, wpsInfo); 1376 mLooper.dispatchAll(); 1377 verify(mWifiNative).startWpsPbc(eq(sBSSID)); 1378 1379 assertEquals("WpsRunningState", getCurrentState().getName()); 1380 1381 setupMocksForWpsNetworkMigration(); 1382 1383 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null); 1384 mLooper.dispatchAll(); 1385 1386 assertEquals("DisconnectedState", getCurrentState().getName()); 1387 } 1388 1389 /** 1390 * Verify failure in starting Wps PBC network connection. 1391 */ 1392 @Test 1393 public void wpsPbcConnectFailure() throws Exception { 1394 loadComponentsInStaMode(); 1395 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1396 mLooper.dispatchAll(); 1397 1398 when(mWifiNative.startWpsPbc(eq(sBSSID))).thenReturn(false); 1399 WpsInfo wpsInfo = new WpsInfo(); 1400 wpsInfo.setup = WpsInfo.PBC; 1401 wpsInfo.BSSID = sBSSID; 1402 1403 mWsm.sendMessage(WifiManager.START_WPS, 0, 0, wpsInfo); 1404 mLooper.dispatchAll(); 1405 verify(mWifiNative).startWpsPbc(eq(sBSSID)); 1406 1407 assertFalse("WpsRunningState".equals(getCurrentState().getName())); 1408 } 1409 1410 /** 1411 * Verify successful Wps Pin Display network connection. 1412 */ 1413 @Test 1414 public void wpsPinDisplayConnectSuccess() throws Exception { 1415 loadComponentsInStaMode(); 1416 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1417 mLooper.dispatchAll(); 1418 1419 when(mWifiNative.startWpsPinDisplay(eq(sBSSID))).thenReturn("34545434"); 1420 WpsInfo wpsInfo = new WpsInfo(); 1421 wpsInfo.setup = WpsInfo.DISPLAY; 1422 wpsInfo.BSSID = sBSSID; 1423 1424 mWsm.sendMessage(WifiManager.START_WPS, 0, 0, wpsInfo); 1425 mLooper.dispatchAll(); 1426 verify(mWifiNative).startWpsPinDisplay(eq(sBSSID)); 1427 1428 assertEquals("WpsRunningState", getCurrentState().getName()); 1429 1430 setupMocksForWpsNetworkMigration(); 1431 1432 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null); 1433 mLooper.dispatchAll(); 1434 1435 assertEquals("DisconnectedState", getCurrentState().getName()); 1436 } 1437 1438 /** 1439 * Verify failure in Wps Pin Display network connection. 1440 */ 1441 @Test 1442 public void wpsPinDisplayConnectFailure() throws Exception { 1443 loadComponentsInStaMode(); 1444 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1445 mLooper.dispatchAll(); 1446 1447 when(mWifiNative.startWpsPinDisplay(eq(sBSSID))).thenReturn(null); 1448 WpsInfo wpsInfo = new WpsInfo(); 1449 wpsInfo.setup = WpsInfo.DISPLAY; 1450 wpsInfo.BSSID = sBSSID; 1451 1452 mWsm.sendMessage(WifiManager.START_WPS, 0, 0, wpsInfo); 1453 mLooper.dispatchAll(); 1454 verify(mWifiNative).startWpsPinDisplay(eq(sBSSID)); 1455 1456 assertFalse("WpsRunningState".equals(getCurrentState().getName())); 1457 } 1458 1459 @Test 1460 public void handleVendorHalDeath() throws Exception { 1461 ArgumentCaptor<WifiNative.VendorHalDeathEventHandler> deathHandlerCapturer = 1462 ArgumentCaptor.forClass(WifiNative.VendorHalDeathEventHandler.class); 1463 when(mWifiNative.initializeVendorHal(deathHandlerCapturer.capture())).thenReturn(true); 1464 1465 // Trigger initialize to capture the death handler registration. 1466 mLooper.startAutoDispatch(); 1467 assertTrue(mWsm.syncInitialize(mWsmAsyncChannel)); 1468 mLooper.stopAutoDispatch(); 1469 1470 verify(mWifiNative).initializeVendorHal(any(WifiNative.VendorHalDeathEventHandler.class)); 1471 WifiNative.VendorHalDeathEventHandler deathHandler = deathHandlerCapturer.getValue(); 1472 1473 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1474 mLooper.dispatchAll(); 1475 1476 // Now trigger the death notification. 1477 deathHandler.onDeath(); 1478 mLooper.dispatchAll(); 1479 1480 verify(mWifiMetrics).incrementNumHalCrashes(); 1481 verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_HAL_CRASH)); 1482 } 1483 1484 @Test 1485 public void handleWificondDeath() throws Exception { 1486 ArgumentCaptor<StateMachineDeathRecipient> deathHandlerCapturer = 1487 ArgumentCaptor.forClass(StateMachineDeathRecipient.class); 1488 1489 // Trigger initialize to capture the death handler registration. 1490 loadComponentsInStaMode(); 1491 1492 verify(mClientInterfaceBinder).linkToDeath(deathHandlerCapturer.capture(), anyInt()); 1493 StateMachineDeathRecipient deathHandler = deathHandlerCapturer.getValue(); 1494 1495 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1496 mLooper.dispatchAll(); 1497 1498 // Now trigger the death notification. 1499 deathHandler.binderDied(); 1500 mLooper.dispatchAll(); 1501 1502 verify(mWifiMetrics).incrementNumWificondCrashes(); 1503 verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFICOND_CRASH)); 1504 } 1505 1506 private void setupMocksForWpsNetworkMigration() { 1507 int newNetworkId = 5; 1508 // Now trigger the network connection event for adding the WPS network. 1509 doAnswer(new AnswerWithArguments() { 1510 public boolean answer(Map<String, WifiConfiguration> configs, 1511 SparseArray<Map<String, String>> networkExtras) throws Exception { 1512 configs.put("dummy", new WifiConfiguration()); 1513 return true; 1514 } 1515 }).when(mWifiNative).migrateNetworksFromSupplicant(any(Map.class), any(SparseArray.class)); 1516 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 1517 .thenReturn(new NetworkUpdateResult(newNetworkId)); 1518 when(mWifiConfigManager.enableNetwork(eq(newNetworkId), anyBoolean(), anyInt())) 1519 .thenReturn(true); 1520 } 1521 1522 /** 1523 * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not 1524 * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState. 1525 * This protects WifiStateMachine from getting into a bad state where WifiInfo says wifi is 1526 * already Connected or Connecting, (when it is in-fact Disconnected), so 1527 * WifiConnectivityManager does not attempt any new Connections, freezing wifi. 1528 */ 1529 @Test 1530 public void testWifiInfoCleanedUpEnteringExitingConnectModeState() throws Exception { 1531 InOrder inOrder = inOrder(mWifiConnectivityManager); 1532 Log.i(TAG, mWsm.getCurrentState().getName()); 1533 String initialBSSID = "aa:bb:cc:dd:ee:ff"; 1534 WifiInfo wifiInfo = mWsm.getWifiInfo(); 1535 wifiInfo.setBSSID(initialBSSID); 1536 1537 // Set WSM to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager 1538 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1539 startSupplicantAndDispatchMessages(); 1540 mWsm.setSupplicantRunning(true); 1541 mLooper.dispatchAll(); 1542 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 1543 assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState()); 1544 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); 1545 assertNull(wifiInfo.getBSSID()); 1546 1547 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated 1548 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1549 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1550 mLooper.dispatchAll(); 1551 assertEquals(sBSSID, wifiInfo.getBSSID()); 1552 assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); 1553 1554 // Set WSM to SCAN_ONLY_MODE, verify state and wifi disabled in ConnectivityManager, and 1555 // WifiInfo is reset() and state set to DISCONNECTED 1556 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 1557 mLooper.dispatchAll(); 1558 assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest()); 1559 assertEquals("ScanModeState", getCurrentState().getName()); 1560 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 1561 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false)); 1562 assertNull(wifiInfo.getBSSID()); 1563 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 1564 1565 // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated 1566 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 1567 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 1568 mLooper.dispatchAll(); 1569 assertNull(wifiInfo.getBSSID()); 1570 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 1571 1572 // Set the bssid to something, so we can verify it is cleared (just in case) 1573 wifiInfo.setBSSID(initialBSSID); 1574 1575 // Set WSM to CONNECT_MODE and verify state, and wifi enabled in ConnectivityManager, 1576 // and WifiInfo has been reset 1577 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1578 mLooper.dispatchAll(); 1579 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 1580 assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState()); 1581 inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); 1582 assertEquals("DisconnectedState", getCurrentState().getName()); 1583 assertEquals(SupplicantState.DISCONNECTED, wifiInfo.getSupplicantState()); 1584 assertNull(wifiInfo.getBSSID()); 1585 } 1586 1587 /** 1588 * Adds the network without putting WifiStateMachine into ConnectMode. 1589 */ 1590 @Test 1591 public void addNetworkInInitialState() throws Exception { 1592 // We should not be in initial state now. 1593 assertTrue("InitialState".equals(getCurrentState().getName())); 1594 addNetworkAndVerifySuccess(false); 1595 verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(0)); 1596 } 1597 1598 /** 1599 * Test START_WPS with a null wpsInfo object fails gracefully (No NPE) 1600 */ 1601 @Test 1602 public void testStartWps_nullWpsInfo() throws Exception { 1603 loadComponentsInStaMode(); 1604 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1605 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 1606 assertEquals("DisconnectedState", getCurrentState().getName()); 1607 mLooper.startAutoDispatch(); 1608 Message reply = mWsmAsyncChannel.sendMessageSynchronously(WifiManager.START_WPS, 0, 0, 1609 null); 1610 mLooper.stopAutoDispatch(); 1611 assertEquals(WifiManager.WPS_FAILED, reply.what); 1612 } 1613 1614 /** 1615 * Test that DISABLE_NETWORK returns failure to public API when WifiConfigManager returns 1616 * failure. 1617 */ 1618 @Test 1619 public void testSyncDisableNetwork_failure() throws Exception { 1620 loadComponentsInStaMode(); 1621 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 1622 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 1623 assertEquals("DisconnectedState", getCurrentState().getName()); 1624 when(mWifiConfigManager.disableNetwork(anyInt(), anyInt())).thenReturn(false); 1625 1626 mLooper.startAutoDispatch(); 1627 boolean succeeded = mWsm.syncDisableNetwork(mWsmAsyncChannel, 0); 1628 mLooper.stopAutoDispatch(); 1629 assertFalse(succeeded); 1630 } 1631} 1632