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