WifiStateMachineTest.java revision 9bd76b7c0afc90d800066397497b5947916b90fa
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.assertTrue; 21import static org.mockito.Mockito.any; 22import static org.mockito.Mockito.anyBoolean; 23import static org.mockito.Mockito.anyInt; 24import static org.mockito.Mockito.anyObject; 25import static org.mockito.Mockito.anyString; 26import static org.mockito.Mockito.mock; 27import static org.mockito.Mockito.verify; 28import static org.mockito.Mockito.when; 29import static org.mockito.Mockito.withSettings; 30 31import android.content.ContentResolver; 32import android.content.Context; 33import android.content.pm.PackageManager; 34import android.content.res.Resources; 35import android.net.BaseDhcpStateMachine; 36import android.net.ConnectivityManager; 37import android.net.DhcpResults; 38import android.net.DhcpStateMachine; 39import android.net.ip.IpManager; 40import android.net.wifi.ScanResult; 41import android.net.wifi.SupplicantState; 42import android.net.wifi.WifiConfiguration; 43import android.net.wifi.WifiManager; 44import android.net.wifi.WifiScanner; 45import android.net.wifi.WifiSsid; 46import android.net.wifi.p2p.IWifiP2pManager; 47import android.os.BatteryStats; 48import android.os.Handler; 49import android.os.HandlerThread; 50import android.os.IBinder; 51import android.os.IInterface; 52import android.os.INetworkManagementService; 53import android.os.IPowerManager; 54import android.os.Looper; 55import android.os.Message; 56import android.os.Messenger; 57import android.os.PowerManager; 58import android.os.UserHandle; 59import android.provider.Settings; 60import android.test.suitebuilder.annotation.SmallTest; 61import android.util.Log; 62 63import com.android.internal.R; 64import com.android.internal.app.IBatteryStats; 65import com.android.internal.util.AsyncChannel; 66import com.android.internal.util.IState; 67import com.android.internal.util.StateMachine; 68import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments; 69import com.android.server.wifi.hotspot2.NetworkDetail; 70import com.android.server.wifi.hotspot2.SupplicantBridge; 71import com.android.server.wifi.hotspot2.omadm.MOManager; 72import com.android.server.wifi.hotspot2.osu.OSUManager; 73import com.android.server.wifi.p2p.WifiP2pServiceImpl; 74 75import org.junit.After; 76import org.junit.Before; 77import org.junit.Test; 78import org.mockito.ArgumentCaptor; 79import org.mockito.Mock; 80import org.mockito.Mockito; 81import org.mockito.MockitoAnnotations; 82 83import java.io.ByteArrayOutputStream; 84import java.io.PrintWriter; 85import java.lang.reflect.Field; 86import java.lang.reflect.InvocationTargetException; 87import java.lang.reflect.Method; 88import java.util.ArrayList; 89import java.util.Arrays; 90import java.util.HashMap; 91import java.util.List; 92import java.util.Map; 93 94/** 95 * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. 96 */ 97@SmallTest 98public class WifiStateMachineTest { 99 public static final String TAG = "WifiStateMachineTest"; 100 101 private static final String IFNAME = "wlan0"; 102 103 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 104 return mock(class1, withSettings().extraInterfaces(interfaces)); 105 } 106 107 private static <T, I> IBinder mockService(Class<T> class1, Class<I> iface) { 108 T tImpl = mockWithInterfaces(class1, iface); 109 IBinder binder = mock(IBinder.class); 110 when(((IInterface) tImpl).asBinder()).thenReturn(binder); 111 when(binder.queryLocalInterface(iface.getCanonicalName())) 112 .thenReturn((IInterface) tImpl); 113 return binder; 114 } 115 116 private void enableDebugLogs() { 117 mWsm.enableVerboseLogging(1); 118 } 119 120 private static void installWlanWifiNative(WifiNative wifiNative) throws Exception { 121 Field field = WifiNative.class.getDeclaredField("wlanNativeInterface"); 122 field.setAccessible(true); 123 field.set(null, wifiNative); 124 125 when(wifiNative.getInterfaceName()).thenReturn(IFNAME); 126 } 127 128 private class TestIpManager extends IpManager { 129 TestIpManager(Context context, String ifname, IpManager.Callback callback) { 130 // Call test-only superclass constructor. 131 super(ifname, callback); 132 } 133 134 @Override 135 public void startProvisioning() {} 136 137 @Override 138 public void stop() {} 139 140 @Override 141 public void confirmConfiguration() {} 142 143 @Override 144 public void updateWithDhcpResults(DhcpResults dhcpResults, int reason) { 145 if (dhcpResults != null) { 146 mCallback.onIPv4ProvisioningSuccess(dhcpResults, reason); 147 } else { 148 mCallback.onIPv4ProvisioningFailure(reason); 149 } 150 } 151 } 152 153 private FrameworkFacade getFrameworkFacade() throws InterruptedException { 154 FrameworkFacade facade = mock(FrameworkFacade.class); 155 156 when(facade.makeBaseLogger()).thenReturn(mock(BaseWifiLogger.class)); 157 when(facade.getService(Context.NETWORKMANAGEMENT_SERVICE)).thenReturn( 158 mockWithInterfaces(IBinder.class, INetworkManagementService.class)); 159 160 IBinder p2pBinder = mockService(WifiP2pServiceImpl.class, IWifiP2pManager.class); 161 when(facade.getService(Context.WIFI_P2P_SERVICE)).thenReturn(p2pBinder); 162 163 WifiP2pServiceImpl p2pm = (WifiP2pServiceImpl) p2pBinder.queryLocalInterface( 164 IWifiP2pManager.class.getCanonicalName()); 165 166 final Object sync = new Object(); 167 synchronized (sync) { 168 mP2pThread = new HandlerThread("WifiP2pMockThread") { 169 @Override 170 protected void onLooperPrepared() { 171 synchronized (sync) { 172 sync.notifyAll(); 173 } 174 } 175 }; 176 177 mP2pThread.start(); 178 sync.wait(); 179 } 180 181 Handler handler = new Handler(mP2pThread.getLooper()); 182 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 183 184 IBinder batteryStatsBinder = mockService(BatteryStats.class, IBatteryStats.class); 185 when(facade.getService(BatteryStats.SERVICE_NAME)).thenReturn(batteryStatsBinder); 186 187 when(facade.makeOsuManager(any(WifiConfigStore.class), any(Context.class), any( 188 SupplicantBridge.class), any(MOManager.class), any(WifiStateMachine.class))) 189 .thenReturn(mock(OSUManager.class)); 190 191 when(facade.makeDhcpStateMachine( 192 any(Context.class), any(StateMachine.class), any(String.class))).thenReturn( 193 mock(BaseDhcpStateMachine.class)); 194 195 when(facade.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class))) 196 .then(new AnswerWithArguments<IpManager>() { 197 public IpManager answer( 198 Context context, String ifname, IpManager.Callback callback) { 199 return new TestIpManager(context, ifname, callback); 200 } 201 }); 202 203 return facade; 204 } 205 206 private Context getContext() throws Exception { 207 PackageManager pkgMgr = mock(PackageManager.class); 208 when(pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 209 210 Context context = mock(Context.class); 211 when(context.getPackageManager()).thenReturn(pkgMgr); 212 when(context.getContentResolver()).thenReturn(mock(ContentResolver.class)); 213 214 MockResources resources = new com.android.server.wifi.MockResources(); 215 when(context.getResources()).thenReturn(resources); 216 217 ContentResolver cr = mock(ContentResolver.class); 218 when(context.getContentResolver()).thenReturn(cr); 219 220 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn( 221 new PowerManager(context, mock(IPowerManager.class), new Handler())); 222 223 mAlarmManager = new MockAlarmManager(); 224 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 225 mAlarmManager.getAlarmManager()); 226 227 when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( 228 mock(ConnectivityManager.class)); 229 230 when(context.getSystemService(Context.WIFI_SCANNING_SERVICE)).thenReturn(mWifiScanner); 231 232 return context; 233 } 234 235 private Resources getMockResources() { 236 MockResources resources = new MockResources(); 237 resources.setBoolean(R.bool.config_wifi_enable_wifi_firmware_debugging, false); 238 return resources; 239 } 240 241 private IState getCurrentState() throws 242 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 243 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 244 method.setAccessible(true); 245 return (IState) method.invoke(mWsm); 246 } 247 248 private static HandlerThread getWsmHandlerThread(WifiStateMachine wsm) throws 249 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 250 Field field = StateMachine.class.getDeclaredField("mSmThread"); 251 field.setAccessible(true); 252 return (HandlerThread) field.get(wsm); 253 } 254 255 private static void stopLooper(final Looper looper) throws Exception { 256 new Handler(looper).post(new Runnable() { 257 @Override 258 public void run() { 259 looper.quitSafely(); 260 } 261 }); 262 } 263 264 private void wait(int delayInMs) throws InterruptedException { 265 Looper looper = mWsmThread.getLooper(); 266 final Handler handler = new Handler(looper); 267 synchronized (handler) { 268 handler.postDelayed(new Runnable() { 269 @Override 270 public void run() { 271 synchronized (handler) { 272 handler.notifyAll(); 273 } 274 } 275 }, delayInMs); 276 277 handler.wait(); 278 } 279 } 280 281 private void dumpState() { 282 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 283 PrintWriter writer = new PrintWriter(stream); 284 mWsm.dump(null, writer, null); 285 writer.flush(); 286 Log.d(TAG, "WifiStateMachine state -" + stream.toString()); 287 } 288 289 private static ScanDetail getGoogleGuestScanDetail(int rssi) { 290 ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; 291 ie[0] = ScanResults.generateSsidIe(sSSID); 292 NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq); 293 ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, 294 Long.MAX_VALUE /* needed so that scan results aren't rejected because 295 there older than scan start */); 296 detail.getScanResult().informationElements = ie; 297 detail.getScanResult().anqpLines = new ArrayList<String>(); 298 return detail; 299 } 300 301 private ScanResult[] getMockScanResults() { 302 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 303 // copy generated results and add space on the end for one more 304 ScanResult[] results = Arrays.copyOf(sr.getScanData().getResults(), 305 sr.getScanData().getResults().length + 1); 306 307 int rssi = -65; 308 results[results.length - 1] = getGoogleGuestScanDetail(rssi).getScanResult(); 309 return results; 310 } 311 312 static final String sSSID = "\"GoogleGuest\""; 313 static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID); 314 static final String sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", ""); 315 static final String sBSSID = "01:02:03:04:05:06"; 316 static final int sFreq = 2437; 317 318 WifiStateMachine mWsm; 319 HandlerThread mWsmThread; 320 HandlerThread mP2pThread; 321 HandlerThread mSyncThread; 322 AsyncChannel mWsmAsyncChannel; 323 MockAlarmManager mAlarmManager; 324 MockWifiMonitor mWifiMonitor; 325 326 @Mock WifiNative mWifiNative; 327 @Mock WifiScanner mWifiScanner; 328 @Mock SupplicantStateTracker mSupplicantStateTracker; 329 @Mock WifiMetrics mWifiMetrics; 330 331 public WifiStateMachineTest() throws Exception { 332 } 333 334 @Before 335 public void setUp() throws Exception { 336 Log.d(TAG, "Setting up ..."); 337 338 // Ensure looper exists 339 MockLooper looper = new MockLooper(); 340 341 MockitoAnnotations.initMocks(this); 342 343 /** uncomment this to enable logs from WifiStateMachines */ 344 // enableDebugLogs(); 345 346 installWlanWifiNative(mWifiNative); 347 mWifiMonitor = new MockWifiMonitor(); 348 mWifiMetrics = mock(WifiMetrics.class); 349 FrameworkFacade factory = getFrameworkFacade(); 350 Context context = getContext(); 351 352 Resources resources = getMockResources(); 353 when(context.getResources()).thenReturn(resources); 354 355 when(factory.getIntegerSetting(context, 356 Settings.Global.WIFI_FREQUENCY_BAND, 357 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 358 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 359 360 when(factory.makeApConfigStore(Mockito.eq(context), any(Handler.class))) 361 .thenCallRealMethod(); 362 363 when(factory.makeSupplicantStateTracker( 364 any(Context.class), any(WifiStateMachine.class), any(WifiConfigStore.class), 365 any(Handler.class))).thenReturn(mSupplicantStateTracker); 366 367 mWsm = new WifiStateMachine(context, null, factory, mWifiMetrics); 368 mWsmThread = getWsmHandlerThread(mWsm); 369 370 final Object sync = new Object(); 371 synchronized (sync) { 372 mSyncThread = new HandlerThread("SynchronizationThread"); 373 final AsyncChannel channel = new AsyncChannel(); 374 mSyncThread.start(); 375 Handler handler = new Handler(mSyncThread.getLooper()) { 376 @Override 377 public void handleMessage(Message msg) { 378 switch (msg.what) { 379 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 380 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 381 mWsmAsyncChannel = channel; 382 synchronized (sync) { 383 sync.notifyAll(); 384 Log.d(TAG, "Successfully connected " + this); 385 } 386 } else { 387 Log.d(TAG, "Failed to connect Command channel " + this); 388 } 389 break; 390 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 391 Log.d(TAG, "Command channel disconnected" + this); 392 break; 393 } 394 } 395 }; 396 397 channel.connect(context, handler, mWsm.getMessenger()); 398 sync.wait(); 399 } 400 401 /* Now channel is supposed to be connected */ 402 } 403 404 @After 405 public void cleanUp() throws Exception { 406 407 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 408 if (mWsmThread != null) stopLooper(mWsmThread.getLooper()); 409 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 410 411 mWsmThread = null; 412 mP2pThread = null; 413 mSyncThread = null; 414 mWsmAsyncChannel = null; 415 mWsm = null; 416 } 417 418 @Test 419 public void createNew() throws Exception { 420 assertEquals("InitialState", getCurrentState().getName()); 421 422 mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); 423 wait(200); 424 assertEquals("InitialState", getCurrentState().getName()); 425 } 426 427 @Test 428 public void loadComponents() throws Exception { 429 430 when(mWifiNative.loadDriver()).thenReturn(true); 431 when(mWifiNative.startHal()).thenReturn(true); 432 when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(true); 433 434 mWsm.setSupplicantRunning(true); 435 wait(200); 436 assertEquals("SupplicantStartingState", getCurrentState().getName()); 437 438 when(mWifiNative.setBand(anyInt())).thenReturn(true); 439 when(mWifiNative.setDeviceName(anyString())).thenReturn(true); 440 when(mWifiNative.setManufacturer(anyString())).thenReturn(true); 441 when(mWifiNative.setModelName(anyString())).thenReturn(true); 442 when(mWifiNative.setModelNumber(anyString())).thenReturn(true); 443 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 444 when(mWifiNative.setConfigMethods(anyString())).thenReturn(true); 445 when(mWifiNative.setDeviceType(anyString())).thenReturn(true); 446 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 447 when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true); 448 when(mWifiNative.enableBackgroundScan(anyBoolean())).thenReturn(true); 449 450 mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); 451 wait(200); 452 assertEquals("DisconnectedState", getCurrentState().getName()); 453 } 454 455 @Test 456 public void loadComponentsFailure() throws Exception { 457 when(mWifiNative.loadDriver()).thenReturn(false); 458 when(mWifiNative.startHal()).thenReturn(false); 459 when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(false); 460 461 mWsm.setSupplicantRunning(true); 462 wait(200); 463 assertEquals("InitialState", getCurrentState().getName()); 464 465 when(mWifiNative.loadDriver()).thenReturn(true); 466 mWsm.setSupplicantRunning(true); 467 wait(200); 468 assertEquals("InitialState", getCurrentState().getName()); 469 470 when(mWifiNative.startHal()).thenReturn(true); 471 mWsm.setSupplicantRunning(true); 472 wait(200); 473 assertEquals("InitialState", getCurrentState().getName()); 474 } 475 476 @Test 477 public void addNetwork() throws Exception { 478 479 loadComponents(); 480 481 final HashMap<String, String> nameToValue = new HashMap<String, String>(); 482 483 when(mWifiNative.addNetwork()).thenReturn(0); 484 when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())) 485 .then(new AnswerWithArguments<Boolean>() { 486 public boolean answer(int netId, String name, String value) { 487 if (netId != 0) { 488 Log.d(TAG, "Can't set var " + name + " for " + netId); 489 return false; 490 } 491 492 Log.d(TAG, "Setting var " + name + " to " + value + " for " + netId); 493 nameToValue.put(name, value); 494 return true; 495 } 496 }); 497 498 when(mWifiNative.setNetworkExtra(anyInt(), anyString(), (Map<String, String>) anyObject())) 499 .then(new AnswerWithArguments<Boolean>() { 500 public boolean answer(int netId, String name, Map<String, String> values) { 501 if (netId != 0) { 502 Log.d(TAG, "Can't set extra " + name + " for " + netId); 503 return false; 504 } 505 506 Log.d(TAG, "Setting extra for " + netId); 507 return true; 508 } 509 }); 510 511 when(mWifiNative.getNetworkVariable(anyInt(), anyString())) 512 .then(new AnswerWithArguments<String>() { 513 public String answer(int netId, String name) throws Throwable { 514 if (netId != 0) { 515 Log.d(TAG, "Can't find var " + name + " for " + netId); 516 return null; 517 } 518 String value = nameToValue.get(name); 519 if (value != null) { 520 Log.d(TAG, "Returning var " + name + " to " + value + " for " + netId); 521 } else { 522 Log.d(TAG, "Can't find var " + name + " for " + netId); 523 } 524 return value; 525 } 526 }); 527 528 WifiConfiguration config = new WifiConfiguration(); 529 config.SSID = sSSID; 530 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 531 mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config); 532 wait(200); 533 534 verify(mWifiNative).addNetwork(); 535 verify(mWifiNative).setNetworkVariable(0, "ssid", sHexSSID); 536 537 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 538 assertEquals(1, configs.size()); 539 540 WifiConfiguration config2 = configs.get(0); 541 assertEquals("\"GoogleGuest\"", config2.SSID); 542 assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); 543 } 544 545 @Test 546 public void scan() throws Exception { 547 548 addNetwork(); 549 550 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 551 552 mWsm.startScan(-1, 0, null, null); 553 wait(200); 554 555 ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor = 556 ArgumentCaptor.forClass(WifiScanner.ScanSettings.class); 557 ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor = 558 ArgumentCaptor.forClass(WifiScanner.ScanListener.class); 559 verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture()); 560 assertEquals("band", WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 561 scanSettingsCaptor.getValue().band); 562 assertEquals("reportEvents", WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 563 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 564 scanSettingsCaptor.getValue().reportEvents); 565 566 ScanResult[] results = getMockScanResults(); 567 for (ScanResult result : results) { 568 scanListenerCaptor.getValue().onFullResult(result); 569 } 570 scanListenerCaptor.getValue().onResults( 571 new WifiScanner.ScanData[] {new WifiScanner.ScanData(0, 0, results)}); 572 573 wait(200); 574 List<ScanResult> reportedResults = mWsm.syncGetScanResultsList(); 575 assertEquals(8, reportedResults.size()); 576 } 577 578 @Test 579 public void connect() throws Exception { 580 581 addNetwork(); 582 583 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 584 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 585 wait(200); 586 587 verify(mWifiNative).enableNetwork(0, true); 588 589 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 590 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 591 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 592 wait(200); 593 594 assertEquals("ObtainingIpState", getCurrentState().getName()); 595 596 DhcpResults dhcpResults = new DhcpResults(); 597 dhcpResults.setGateway("1.2.3.4"); 598 dhcpResults.setIpAddress("192.168.1.100", 0); 599 dhcpResults.addDns("8.8.8.8"); 600 dhcpResults.setLeaseDuration(3600); 601 602 mWsm.sendMessage(DhcpStateMachine.CMD_POST_DHCP_ACTION, DhcpStateMachine.DHCP_SUCCESS, 0, 603 dhcpResults); 604 wait(200); 605 606 assertEquals("ConnectedState", getCurrentState().getName()); 607 } 608 609 @Test 610 public void disconnect() throws Exception { 611 connect(); 612 613 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06"); 614 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 615 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 616 wait(200); 617 618 assertEquals("DisconnectedState", getCurrentState().getName()); 619 } 620 621 @Test 622 public void handleUserSwitch() throws Exception { 623 assertEquals(UserHandle.USER_SYSTEM, mWsm.getCurrentUserId()); 624 625 mWsm.handleUserSwitch(10); 626 wait(200); 627 628 assertEquals(10, mWsm.getCurrentUserId()); 629 } 630} 631