WifiStateMachineTest.java revision be6cb1df0c221f72d09fc0ab6f5c45b0949c9a88
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.assertTrue; 22import static org.mockito.Mockito.any; 23import static org.mockito.Mockito.anyBoolean; 24import static org.mockito.Mockito.anyInt; 25import static org.mockito.Mockito.anyObject; 26import static org.mockito.Mockito.anyString; 27import static org.mockito.Mockito.eq; 28import static org.mockito.Mockito.mock; 29import static org.mockito.Mockito.never; 30import static org.mockito.Mockito.verify; 31import static org.mockito.Mockito.when; 32import static org.mockito.Mockito.withSettings; 33 34import android.content.ContentResolver; 35import android.content.Context; 36import android.content.pm.PackageManager; 37import android.content.pm.UserInfo; 38import android.content.res.Resources; 39import android.net.ConnectivityManager; 40import android.net.DhcpResults; 41import android.net.LinkProperties; 42import android.net.dhcp.DhcpClient; 43import android.net.ip.IpManager; 44import android.net.wifi.ScanResult; 45import android.net.wifi.SupplicantState; 46import android.net.wifi.WifiConfiguration; 47import android.net.wifi.WifiManager; 48import android.net.wifi.WifiSsid; 49import android.net.wifi.p2p.IWifiP2pManager; 50import android.os.BatteryStats; 51import android.os.Binder; 52import android.os.Handler; 53import android.os.HandlerThread; 54import android.os.IBinder; 55import android.os.IInterface; 56import android.os.INetworkManagementService; 57import android.os.IPowerManager; 58import android.os.Looper; 59import android.os.Message; 60import android.os.Messenger; 61import android.os.PowerManager; 62import android.os.UserHandle; 63import android.os.UserManager; 64import android.provider.Settings; 65import android.telephony.TelephonyManager; 66import android.test.suitebuilder.annotation.SmallTest; 67import android.util.Base64; 68import android.util.Log; 69 70import com.android.internal.R; 71import com.android.internal.app.IBatteryStats; 72import com.android.internal.util.AsyncChannel; 73import com.android.internal.util.IState; 74import com.android.internal.util.StateMachine; 75import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments; 76import com.android.server.wifi.hotspot2.NetworkDetail; 77import com.android.server.wifi.hotspot2.Utils; 78import com.android.server.wifi.p2p.WifiP2pServiceImpl; 79 80import org.junit.After; 81import org.junit.Before; 82import org.junit.Test; 83import org.mockito.Mock; 84import org.mockito.Mockito; 85import org.mockito.MockitoAnnotations; 86 87import java.io.ByteArrayOutputStream; 88import java.io.PrintWriter; 89import java.lang.reflect.Field; 90import java.lang.reflect.InvocationTargetException; 91import java.lang.reflect.Method; 92import java.util.ArrayList; 93import java.util.Arrays; 94import java.util.HashMap; 95import java.util.List; 96import java.util.Map; 97 98/** 99 * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. 100 */ 101@SmallTest 102public class WifiStateMachineTest { 103 public static final String TAG = "WifiStateMachineTest"; 104 105 private static final int MANAGED_PROFILE_UID = 1100000; 106 private static final int OTHER_USER_UID = 1200000; 107 108 private long mBinderToken; 109 110 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 111 return mock(class1, withSettings().extraInterfaces(interfaces)); 112 } 113 114 private static <T, I> IBinder mockService(Class<T> class1, Class<I> iface) { 115 T tImpl = mockWithInterfaces(class1, iface); 116 IBinder binder = mock(IBinder.class); 117 when(((IInterface) tImpl).asBinder()).thenReturn(binder); 118 when(binder.queryLocalInterface(iface.getCanonicalName())) 119 .thenReturn((IInterface) tImpl); 120 return binder; 121 } 122 123 private void enableDebugLogs() { 124 mWsm.enableVerboseLogging(1); 125 } 126 127 private class TestIpManager extends IpManager { 128 TestIpManager(Context context, String ifname, IpManager.Callback callback) { 129 // Call test-only superclass constructor. 130 super(ifname, callback); 131 } 132 133 @Override 134 public void startProvisioning(IpManager.ProvisioningConfiguration config) {} 135 136 @Override 137 public void stop() {} 138 139 @Override 140 public void confirmConfiguration() {} 141 142 void injectDhcpSuccess(DhcpResults dhcpResults) { 143 mCallback.onNewDhcpResults(dhcpResults); 144 mCallback.onProvisioningSuccess(new LinkProperties()); 145 } 146 147 void injectDhcpFailure() { 148 mCallback.onNewDhcpResults(null); 149 mCallback.onProvisioningFailure(new LinkProperties()); 150 } 151 } 152 153 private FrameworkFacade getFrameworkFacade() throws Exception { 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.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class))) 188 .then(new AnswerWithArguments() { 189 public IpManager answer( 190 Context context, String ifname, IpManager.Callback callback) { 191 mTestIpManager = new TestIpManager(context, ifname, callback); 192 return mTestIpManager; 193 } 194 }); 195 196 when(facade.checkUidPermission(eq(android.Manifest.permission.OVERRIDE_WIFI_CONFIG), 197 anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); 198 199 return facade; 200 } 201 202 private Context getContext() throws Exception { 203 PackageManager pkgMgr = mock(PackageManager.class); 204 when(pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 205 206 Context context = mock(Context.class); 207 when(context.getPackageManager()).thenReturn(pkgMgr); 208 when(context.getContentResolver()).thenReturn(mock(ContentResolver.class)); 209 210 MockResources resources = new com.android.server.wifi.MockResources(); 211 when(context.getResources()).thenReturn(resources); 212 213 ContentResolver cr = mock(ContentResolver.class); 214 when(context.getContentResolver()).thenReturn(cr); 215 216 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn( 217 new PowerManager(context, mock(IPowerManager.class), new Handler())); 218 219 mAlarmManager = new MockAlarmManager(); 220 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 221 mAlarmManager.getAlarmManager()); 222 223 when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( 224 mock(ConnectivityManager.class)); 225 226 return context; 227 } 228 229 private Resources getMockResources() { 230 MockResources resources = new MockResources(); 231 resources.setBoolean(R.bool.config_wifi_enable_wifi_firmware_debugging, false); 232 return resources; 233 } 234 235 private IState getCurrentState() throws 236 NoSuchMethodException, InvocationTargetException, IllegalAccessException { 237 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 238 method.setAccessible(true); 239 return (IState) method.invoke(mWsm); 240 } 241 242 private static HandlerThread getWsmHandlerThread(WifiStateMachine wsm) throws 243 NoSuchFieldException, InvocationTargetException, IllegalAccessException { 244 Field field = StateMachine.class.getDeclaredField("mSmThread"); 245 field.setAccessible(true); 246 return (HandlerThread) field.get(wsm); 247 } 248 249 private static void stopLooper(final Looper looper) throws Exception { 250 new Handler(looper).post(new Runnable() { 251 @Override 252 public void run() { 253 looper.quitSafely(); 254 } 255 }); 256 } 257 258 private void wait(int delayInMs) throws InterruptedException { 259 Looper looper = mWsmThread.getLooper(); 260 final Handler handler = new Handler(looper); 261 synchronized (handler) { 262 handler.postDelayed(new Runnable() { 263 @Override 264 public void run() { 265 synchronized (handler) { 266 handler.notifyAll(); 267 } 268 } 269 }, delayInMs); 270 271 handler.wait(); 272 } 273 } 274 275 private void dumpState() { 276 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 277 PrintWriter writer = new PrintWriter(stream); 278 mWsm.dump(null, writer, null); 279 writer.flush(); 280 Log.d(TAG, "WifiStateMachine state -" + stream.toString()); 281 } 282 283 private static ScanDetail getGoogleGuestScanDetail(int rssi) { 284 ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; 285 ie[0] = ScanResults.generateSsidIe(sSSID); 286 NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq); 287 ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, 288 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 289 there older than scan start */ 290 null, null); 291 return detail; 292 } 293 294 private ArrayList<ScanDetail> getMockScanResults() { 295 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 296 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 297 298 int rssi = -65; 299 list.add(getGoogleGuestScanDetail(rssi)); 300 return list; 301 } 302 303 static final String sSSID = "\"GoogleGuest\""; 304 static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID); 305 static final String sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", ""); 306 static final String sBSSID = "01:02:03:04:05:06"; 307 static final int sFreq = 2437; 308 309 WifiStateMachine mWsm; 310 HandlerThread mWsmThread; 311 HandlerThread mP2pThread; 312 HandlerThread mSyncThread; 313 AsyncChannel mWsmAsyncChannel; 314 MockAlarmManager mAlarmManager; 315 MockWifiMonitor mWifiMonitor; 316 TestIpManager mTestIpManager; 317 318 @Mock WifiNative mWifiNative; 319 @Mock SupplicantStateTracker mSupplicantStateTracker; 320 @Mock WifiMetrics mWifiMetrics; 321 @Mock UserManager mUserManager; 322 323 public WifiStateMachineTest() throws Exception { 324 } 325 326 @Before 327 public void setUp() throws Exception { 328 Log.d(TAG, "Setting up ..."); 329 330 // Ensure looper exists 331 MockLooper looper = new MockLooper(); 332 333 MockitoAnnotations.initMocks(this); 334 335 /** uncomment this to enable logs from WifiStateMachines */ 336 // enableDebugLogs(); 337 338 TestUtil.installWlanWifiNative(mWifiNative); 339 mWifiMonitor = new MockWifiMonitor(); 340 mWifiMetrics = mock(WifiMetrics.class); 341 FrameworkFacade factory = getFrameworkFacade(); 342 Context context = getContext(); 343 344 Resources resources = getMockResources(); 345 when(context.getResources()).thenReturn(resources); 346 347 when(factory.getIntegerSetting(context, 348 Settings.Global.WIFI_FREQUENCY_BAND, 349 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 350 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 351 352 when(factory.makeApConfigStore(Mockito.eq(context))) 353 .thenCallRealMethod(); 354 355 when(factory.makeSupplicantStateTracker( 356 any(Context.class), any(WifiStateMachine.class), any(WifiConfigStore.class), 357 any(Handler.class))).thenReturn(mSupplicantStateTracker); 358 359 when(mUserManager.getProfileParent(11)) 360 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "owner", 0)); 361 when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(Arrays.asList( 362 new UserInfo(UserHandle.USER_SYSTEM, "owner", 0), 363 new UserInfo(11, "managed profile", 0))); 364 365 mWsm = new WifiStateMachine(context, null, factory, mWifiMetrics, mUserManager); 366 mWsmThread = getWsmHandlerThread(mWsm); 367 368 final Object sync = new Object(); 369 synchronized (sync) { 370 mSyncThread = new HandlerThread("SynchronizationThread"); 371 final AsyncChannel channel = new AsyncChannel(); 372 mSyncThread.start(); 373 Handler handler = new Handler(mSyncThread.getLooper()) { 374 @Override 375 public void handleMessage(Message msg) { 376 switch (msg.what) { 377 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 378 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 379 mWsmAsyncChannel = channel; 380 synchronized (sync) { 381 sync.notifyAll(); 382 Log.d(TAG, "Successfully connected " + this); 383 } 384 } else { 385 Log.d(TAG, "Failed to connect Command channel " + this); 386 } 387 break; 388 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 389 Log.d(TAG, "Command channel disconnected" + this); 390 break; 391 } 392 } 393 }; 394 395 channel.connect(context, handler, mWsm.getMessenger()); 396 sync.wait(); 397 } 398 399 /* Now channel is supposed to be connected */ 400 401 mBinderToken = Binder.clearCallingIdentity(); 402 } 403 404 @After 405 public void cleanUp() throws Exception { 406 Binder.restoreCallingIdentity(mBinderToken); 407 408 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 409 if (mWsmThread != null) stopLooper(mWsmThread.getLooper()); 410 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 411 412 mWsmThread = null; 413 mP2pThread = null; 414 mSyncThread = null; 415 mWsmAsyncChannel = null; 416 mWsm = null; 417 } 418 419 @Test 420 public void createNew() throws Exception { 421 assertEquals("InitialState", getCurrentState().getName()); 422 423 mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); 424 wait(200); 425 assertEquals("InitialState", getCurrentState().getName()); 426 } 427 428 @Test 429 public void loadComponents() throws Exception { 430 431 when(mWifiNative.loadDriver()).thenReturn(true); 432 when(mWifiNative.startHal()).thenReturn(true); 433 when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(true); 434 435 mWsm.setSupplicantRunning(true); 436 wait(200); 437 assertEquals("SupplicantStartingState", getCurrentState().getName()); 438 439 when(mWifiNative.setBand(anyInt())).thenReturn(true); 440 when(mWifiNative.setDeviceName(anyString())).thenReturn(true); 441 when(mWifiNative.setManufacturer(anyString())).thenReturn(true); 442 when(mWifiNative.setModelName(anyString())).thenReturn(true); 443 when(mWifiNative.setModelNumber(anyString())).thenReturn(true); 444 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 445 when(mWifiNative.setConfigMethods(anyString())).thenReturn(true); 446 when(mWifiNative.setDeviceType(anyString())).thenReturn(true); 447 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 448 when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true); 449 when(mWifiNative.enableBackgroundScan(anyBoolean(), 450 any(ArrayList.class))).thenReturn(true); 451 452 mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); 453 wait(200); 454 assertEquals("DisconnectedState", getCurrentState().getName()); 455 } 456 457 @Test 458 public void loadComponentsFailure() throws Exception { 459 when(mWifiNative.loadDriver()).thenReturn(false); 460 when(mWifiNative.startHal()).thenReturn(false); 461 when(mWifiNative.startSupplicant(anyBoolean())).thenReturn(false); 462 463 mWsm.setSupplicantRunning(true); 464 wait(200); 465 assertEquals("InitialState", getCurrentState().getName()); 466 467 when(mWifiNative.loadDriver()).thenReturn(true); 468 mWsm.setSupplicantRunning(true); 469 wait(200); 470 assertEquals("InitialState", getCurrentState().getName()); 471 472 when(mWifiNative.startHal()).thenReturn(true); 473 mWsm.setSupplicantRunning(true); 474 wait(200); 475 assertEquals("InitialState", getCurrentState().getName()); 476 } 477 478 private void addNetworkAndVerifySuccess() throws Exception { 479 480 loadComponents(); 481 482 final HashMap<String, String> nameToValue = new HashMap<String, String>(); 483 484 when(mWifiNative.addNetwork()).thenReturn(0); 485 when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())) 486 .then(new AnswerWithArguments() { 487 public boolean answer(int netId, String name, String value) { 488 if (netId != 0) { 489 Log.d(TAG, "Can't set var " + name + " for " + netId); 490 return false; 491 } 492 493 Log.d(TAG, "Setting var " + name + " to " + value + " for " + netId); 494 nameToValue.put(name, value); 495 return true; 496 } 497 }); 498 499 when(mWifiNative.setNetworkExtra(anyInt(), anyString(), (Map<String, String>) anyObject())) 500 .then(new AnswerWithArguments() { 501 public boolean answer(int netId, String name, Map<String, String> values) { 502 if (netId != 0) { 503 Log.d(TAG, "Can't set extra " + name + " for " + netId); 504 return false; 505 } 506 507 Log.d(TAG, "Setting extra for " + netId); 508 return true; 509 } 510 }); 511 512 when(mWifiNative.getNetworkVariable(anyInt(), anyString())) 513 .then(new AnswerWithArguments() { 514 public String answer(int netId, String name) throws Throwable { 515 if (netId != 0) { 516 Log.d(TAG, "Can't find var " + name + " for " + netId); 517 return null; 518 } 519 String value = nameToValue.get(name); 520 if (value != null) { 521 Log.d(TAG, "Returning var " + name + " to " + value + " for " + netId); 522 } else { 523 Log.d(TAG, "Can't find var " + name + " for " + netId); 524 } 525 return value; 526 } 527 }); 528 529 WifiConfiguration config = new WifiConfiguration(); 530 config.SSID = sSSID; 531 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 532 mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config); 533 wait(200); 534 535 verify(mWifiNative).addNetwork(); 536 verify(mWifiNative).setNetworkVariable(0, "ssid", sHexSSID); 537 538 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 539 assertEquals(1, configs.size()); 540 541 WifiConfiguration config2 = configs.get(0); 542 assertEquals("\"GoogleGuest\"", config2.SSID); 543 assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); 544 } 545 546 private void addNetworkAndVerifyFailure() throws Exception { 547 loadComponents(); 548 549 final WifiConfiguration config = new WifiConfiguration(); 550 config.SSID = sSSID; 551 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 552 553 mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config); 554 wait(200); 555 556 verify(mWifiNative, never()).addNetwork(); 557 verify(mWifiNative, never()).setNetworkVariable(anyInt(), anyString(), anyString()); 558 559 assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty()); 560 } 561 562 /** 563 * Verifies that the current foreground user is allowed to add a network. 564 */ 565 @Test 566 public void addNetworkAsCurrentUser() throws Exception { 567 addNetworkAndVerifySuccess(); 568 } 569 570 /** 571 * Verifies that a managed profile of the current foreground user is allowed to add a network. 572 */ 573 @Test 574 public void addNetworkAsCurrentUsersManagedProfile() throws Exception { 575 BinderUtil.setUid(MANAGED_PROFILE_UID); 576 addNetworkAndVerifySuccess(); 577 } 578 579 /** 580 * Verifies that a background user is not allowed to add a network. 581 */ 582 @Test 583 public void addNetworkAsOtherUser() throws Exception { 584 BinderUtil.setUid(OTHER_USER_UID); 585 addNetworkAndVerifyFailure(); 586 } 587 588 private void removeNetworkAndVerifySuccess() throws Exception { 589 when(mWifiNative.removeNetwork(0)).thenReturn(true); 590 assertTrue(mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0)); 591 wait(200); 592 assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty()); 593 } 594 595 private void removeNetworkAndVerifyFailure() throws Exception { 596 assertFalse(mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0)); 597 wait(200); 598 assertEquals(1, mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).size()); 599 verify(mWifiNative, never()).removeNetwork(anyInt()); 600 } 601 602 /** 603 * Verifies that the current foreground user is allowed to remove a network. 604 */ 605 @Test 606 public void removeNetworkAsCurrentUser() throws Exception { 607 addNetworkAndVerifySuccess(); 608 removeNetworkAndVerifySuccess(); 609 } 610 611 /** 612 * Verifies that a managed profile of the current foreground user is allowed to remove a 613 * network. 614 */ 615 @Test 616 public void removeNetworkAsCurrentUsersManagedProfile() throws Exception { 617 addNetworkAndVerifySuccess(); 618 BinderUtil.setUid(MANAGED_PROFILE_UID); 619 removeNetworkAndVerifySuccess(); 620 } 621 622 /** 623 * Verifies that a background user is not allowed to remove a network. 624 */ 625 @Test 626 public void removeNetworkAsOtherUser() throws Exception { 627 addNetworkAndVerifySuccess(); 628 BinderUtil.setUid(OTHER_USER_UID); 629 removeNetworkAndVerifyFailure(); 630 } 631 632 private void enableNetworkAndVerifySuccess() throws Exception { 633 when(mWifiNative.enableNetwork(0, true)).thenReturn(true); 634 assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); 635 wait(200); 636 verify(mWifiNative).enableNetwork(0, true); 637 } 638 639 private void enableNetworkAndVerifyFailure() throws Exception { 640 assertFalse(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); 641 wait(200); 642 verify(mWifiNative, never()).enableNetwork(anyInt(), anyBoolean()); 643 } 644 645 /** 646 * Verifies that the current foreground user is allowed to enable a network. 647 */ 648 @Test 649 public void enableNetworkAsCurrentUser() throws Exception { 650 addNetworkAndVerifySuccess(); 651 enableNetworkAndVerifySuccess(); 652 } 653 654 /** 655 * Verifies that a managed profile of the current foreground user is allowed to enable a 656 * network. 657 */ 658 @Test 659 public void enableNetworkAsCurrentUsersManagedProfile() throws Exception { 660 addNetworkAndVerifySuccess(); 661 BinderUtil.setUid(MANAGED_PROFILE_UID); 662 enableNetworkAndVerifySuccess(); 663 } 664 665 /** 666 * Verifies that a background user is not allowed to enable a network. 667 */ 668 @Test 669 public void enableNetworkAsOtherUser() throws Exception { 670 addNetworkAndVerifySuccess(); 671 BinderUtil.setUid(OTHER_USER_UID); 672 enableNetworkAndVerifyFailure(); 673 } 674 675 private void forgetNetworkAndVerifySuccess() throws Exception { 676 when(mWifiNative.removeNetwork(0)).thenReturn(true); 677 final Message result = 678 mWsmAsyncChannel.sendMessageSynchronously(WifiManager.FORGET_NETWORK, 0); 679 assertEquals(WifiManager.FORGET_NETWORK_SUCCEEDED, result.what); 680 result.recycle(); 681 wait(200); 682 assertTrue(mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).isEmpty()); 683 } 684 685 private void forgetNetworkAndVerifyFailure() throws Exception { 686 final Message result = 687 mWsmAsyncChannel.sendMessageSynchronously(WifiManager.FORGET_NETWORK, 0); 688 assertEquals(WifiManager.FORGET_NETWORK_FAILED, result.what); 689 result.recycle(); 690 wait(200); 691 assertEquals(1, mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel).size()); 692 verify(mWifiNative, never()).removeNetwork(anyInt()); 693 } 694 695 /** 696 * Verifies that the current foreground user is allowed to forget a network. 697 */ 698 @Test 699 public void forgetNetworkAsCurrentUser() throws Exception { 700 addNetworkAndVerifySuccess(); 701 forgetNetworkAndVerifySuccess(); 702 } 703 704 /** 705 * Verifies that a managed profile of the current foreground user is allowed to forget a 706 * network. 707 */ 708 @Test 709 public void forgetNetworkAsCurrentUsersManagedProfile() throws Exception { 710 addNetworkAndVerifySuccess(); 711 BinderUtil.setUid(MANAGED_PROFILE_UID); 712 forgetNetworkAndVerifySuccess(); 713 } 714 715 /** 716 * Verifies that a background user is not allowed to forget a network. 717 */ 718 @Test 719 public void forgetNetworkAsOtherUser() throws Exception { 720 addNetworkAndVerifySuccess(); 721 BinderUtil.setUid(OTHER_USER_UID); 722 forgetNetworkAndVerifyFailure(); 723 } 724 725 @Test 726 public void scan() throws Exception { 727 728 addNetworkAndVerifySuccess(); 729 730 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 731 732 mWsm.startScan(-1, 0, null, null); 733 wait(200); 734 735 verify(mWifiNative).scan(null); 736 737 when(mWifiNative.getScanResults()).thenReturn(getMockScanResults()); 738 mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT); 739 740 wait(200); 741 List<ScanResult> results = mWsm.syncGetScanResultsList(); 742 assertEquals(8, results.size()); 743 } 744 745 @Test 746 public void connect() throws Exception { 747 748 addNetworkAndVerifySuccess(); 749 750 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 751 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 752 wait(200); 753 754 verify(mWifiNative).enableNetwork(0, true); 755 756 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 757 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 758 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 759 wait(200); 760 761 assertEquals("ObtainingIpState", getCurrentState().getName()); 762 763 DhcpResults dhcpResults = new DhcpResults(); 764 dhcpResults.setGateway("1.2.3.4"); 765 dhcpResults.setIpAddress("192.168.1.100", 0); 766 dhcpResults.addDns("8.8.8.8"); 767 dhcpResults.setLeaseDuration(3600); 768 769 mTestIpManager.injectDhcpSuccess(dhcpResults); 770 wait(200); 771 772 assertEquals("ConnectedState", getCurrentState().getName()); 773 } 774 775 @Test 776 public void testDhcpFailure() throws Exception { 777 addNetworkAndVerifySuccess(); 778 779 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 780 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 781 wait(200); 782 783 verify(mWifiNative).enableNetwork(0, true); 784 785 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 786 787 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 788 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 789 wait(200); 790 791 assertEquals("ObtainingIpState", getCurrentState().getName()); 792 793 mTestIpManager.injectDhcpFailure(); 794 wait(200); 795 796 assertEquals("DisconnectingState", getCurrentState().getName()); 797 } 798 799 @Test 800 public void testBadNetworkEvent() throws Exception { 801 addNetworkAndVerifySuccess(); 802 803 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 804 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 805 wait(200); 806 807 verify(mWifiNative).enableNetwork(0, true); 808 809 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 810 811 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 812 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 813 wait(200); 814 815 assertEquals("DisconnectedState", getCurrentState().getName()); 816 } 817 818 819 @Test 820 public void smToString() throws Exception { 821 assertEquals("CMD_CHANNEL_HALF_CONNECTED", mWsm.smToString( 822 AsyncChannel.CMD_CHANNEL_HALF_CONNECTED)); 823 assertEquals("CMD_PRE_DHCP_ACTION", mWsm.smToString( 824 DhcpClient.CMD_PRE_DHCP_ACTION)); 825 assertEquals("CMD_IP_REACHABILITY_LOST", mWsm.smToString( 826 WifiStateMachine.CMD_IP_REACHABILITY_LOST)); 827 } 828 829 @Test 830 public void disconnect() throws Exception { 831 connect(); 832 833 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06"); 834 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 835 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 836 wait(200); 837 838 assertEquals("DisconnectedState", getCurrentState().getName()); 839 } 840 841 @Test 842 public void handleUserSwitch() throws Exception { 843 assertEquals(UserHandle.USER_SYSTEM, mWsm.getCurrentUserId()); 844 845 mWsm.handleUserSwitch(10); 846 wait(200); 847 848 assertEquals(10, mWsm.getCurrentUserId()); 849 } 850 851 @Test 852 public void iconQueryTest() throws Exception { 853 /* enable wi-fi */ 854 addNetworkAndVerifySuccess(); 855 856 long bssid = 0x1234567800FFL; 857 String filename = "iconFileName.png"; 858 String command = "REQ_HS20_ICON " + Utils.macToString(bssid) + " " + filename; 859 860 when(mWifiNative.doCustomSupplicantCommand(command)).thenReturn("OK"); 861 862 boolean result = mWsm.syncQueryPasspointIcon(mWsmAsyncChannel, bssid, filename); 863 864 verify(mWifiNative).doCustomSupplicantCommand(command); 865 assertEquals(true, result); 866 } 867 868 private String createSimChallengeRequest(byte[] challengeValue) { 869 // Produce a base64 encoded length byte + data. 870 byte[] challengeLengthAndValue = new byte[challengeValue.length + 1]; 871 challengeLengthAndValue[0] = (byte) challengeValue.length; 872 for (int i = 0; i < challengeValue.length; ++i) { 873 challengeLengthAndValue[i + 1] = challengeValue[i]; 874 } 875 return Base64.encodeToString(challengeLengthAndValue, android.util.Base64.NO_WRAP); 876 } 877 878 private String createSimAuthResponse(byte[] sresValue, byte[] kcValue) { 879 // Produce a base64 encoded sres length byte + sres + kc length byte + kc. 880 int overallLength = sresValue.length + kcValue.length + 2; 881 byte[] result = new byte[sresValue.length + kcValue.length + 2]; 882 int idx = 0; 883 result[idx++] = (byte) sresValue.length; 884 for (int i = 0; i < sresValue.length; ++i) { 885 result[idx++] = sresValue[i]; 886 } 887 result[idx++] = (byte) kcValue.length; 888 for (int i = 0; i < kcValue.length; ++i) { 889 result[idx++] = kcValue[i]; 890 } 891 return Base64.encodeToString(result, Base64.NO_WRAP); 892 } 893 894 /** Verifies function getGsmSimAuthResponse method. */ 895 @Test 896 public void getGsmSimAuthResponseTest() throws Exception { 897 TelephonyManager tm = mock(TelephonyManager.class); 898 final String[] invalidRequests = { null, "", "XXXX" }; 899 assertEquals("", mWsm.getGsmSimAuthResponse(invalidRequests, tm)); 900 901 final String[] failedRequests = { "5E5F" }; 902 when(tm.getIccSimChallengeResponse(anyInt(), 903 eq(createSimChallengeRequest(new byte[] { 0x5e, 0x5f })))).thenReturn(null); 904 assertEquals(null, mWsm.getGsmSimAuthResponse(failedRequests, tm)); 905 906 when(tm.getIccSimChallengeResponse(2, createSimChallengeRequest(new byte[] { 0x1a, 0x2b }))) 907 .thenReturn(null); 908 when(tm.getIccSimChallengeResponse(1, createSimChallengeRequest(new byte[] { 0x1a, 0x2b }))) 909 .thenReturn(createSimAuthResponse(new byte[] { 0x1D, 0x2C }, 910 new byte[] { 0x3B, 0x4A })); 911 when(tm.getIccSimChallengeResponse(1, createSimChallengeRequest(new byte[] { 0x01, 0x23 }))) 912 .thenReturn(createSimAuthResponse(new byte[] { 0x33, 0x22 }, 913 new byte[] { 0x11, 0x00 })); 914 assertEquals(":3b4a:1d2c:1100:3322", mWsm.getGsmSimAuthResponse( 915 new String[] { "1A2B", "0123" }, tm)); 916 } 917} 918