WifiStateMachineTest.java revision 835e781643b79c30fabbab5595770cf01b5861fb
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.*; 23 24import android.app.ActivityManager; 25import android.app.test.MockAnswerUtil.AnswerWithArguments; 26import android.app.test.TestAlarmManager; 27import android.content.Context; 28import android.content.pm.PackageManager; 29import android.content.pm.UserInfo; 30import android.content.res.Resources; 31import android.net.ConnectivityManager; 32import android.net.DhcpResults; 33import android.net.LinkProperties; 34import android.net.dhcp.DhcpClient; 35import android.net.ip.IpManager; 36import android.net.wifi.IApInterface; 37import android.net.wifi.IClientInterface; 38import android.net.wifi.IWificond; 39import android.net.wifi.ScanResult; 40import android.net.wifi.SupplicantState; 41import android.net.wifi.WifiConfiguration; 42import android.net.wifi.WifiInfo; 43import android.net.wifi.WifiManager; 44import android.net.wifi.WifiScanner; 45import android.net.wifi.WifiSsid; 46import android.net.wifi.hotspot2.PasspointConfiguration; 47import android.net.wifi.hotspot2.pps.HomeSp; 48import android.net.wifi.p2p.IWifiP2pManager; 49import android.os.BatteryStats; 50import android.os.Binder; 51import android.os.Bundle; 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.RemoteException; 63import android.os.UserHandle; 64import android.os.UserManager; 65import android.os.test.TestLooper; 66import android.provider.Settings; 67import android.security.KeyStore; 68import android.test.mock.MockContentProvider; 69import android.test.mock.MockContentResolver; 70import android.test.suitebuilder.annotation.SmallTest; 71import android.util.Log; 72 73import com.android.internal.R; 74import com.android.internal.app.IBatteryStats; 75import com.android.internal.util.AsyncChannel; 76import com.android.internal.util.IState; 77import com.android.internal.util.StateMachine; 78import com.android.server.wifi.hotspot2.NetworkDetail; 79import com.android.server.wifi.hotspot2.PasspointManager; 80import com.android.server.wifi.p2p.WifiP2pServiceImpl; 81 82import org.junit.After; 83import org.junit.Before; 84import org.junit.Test; 85import org.mockito.ArgumentCaptor; 86import org.mockito.Mock; 87import org.mockito.MockitoAnnotations; 88 89import java.io.ByteArrayOutputStream; 90import java.io.PrintWriter; 91import java.lang.reflect.Field; 92import java.lang.reflect.InvocationTargetException; 93import java.lang.reflect.Method; 94import java.util.ArrayList; 95import java.util.Arrays; 96import java.util.HashSet; 97import java.util.List; 98import java.util.Set; 99import java.util.concurrent.CountDownLatch; 100 101/** 102 * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. 103 */ 104@SmallTest 105public class WifiStateMachineTest { 106 public static final String TAG = "WifiStateMachineTest"; 107 108 private static final int MANAGED_PROFILE_UID = 1100000; 109 private static final int OTHER_USER_UID = 1200000; 110 private static final int LOG_REC_LIMIT_IN_VERBOSE_MODE = 111 (ActivityManager.isLowRamDeviceStatic() 112 ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY 113 : WifiStateMachine.NUM_LOG_RECS_VERBOSE); 114 private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; 115 116 private long mBinderToken; 117 118 private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) { 119 return mock(class1, withSettings().extraInterfaces(interfaces)); 120 } 121 122 private static <T, I> IBinder mockService(Class<T> class1, Class<I> iface) { 123 T tImpl = mockWithInterfaces(class1, iface); 124 IBinder binder = mock(IBinder.class); 125 when(((IInterface) tImpl).asBinder()).thenReturn(binder); 126 when(binder.queryLocalInterface(iface.getCanonicalName())) 127 .thenReturn((IInterface) tImpl); 128 return binder; 129 } 130 131 private void enableDebugLogs() { 132 mWsm.enableVerboseLogging(1); 133 } 134 135 private class TestIpManager extends IpManager { 136 TestIpManager(Context context, String ifname, IpManager.Callback callback) { 137 // Call dependency-injection superclass constructor. 138 super(context, ifname, callback, mock(INetworkManagementService.class)); 139 } 140 141 @Override 142 public void startProvisioning(IpManager.ProvisioningConfiguration config) {} 143 144 @Override 145 public void stop() {} 146 147 @Override 148 public void confirmConfiguration() {} 149 150 void injectDhcpSuccess(DhcpResults dhcpResults) { 151 mCallback.onNewDhcpResults(dhcpResults); 152 mCallback.onProvisioningSuccess(new LinkProperties()); 153 } 154 155 void injectDhcpFailure() { 156 mCallback.onNewDhcpResults(null); 157 mCallback.onProvisioningFailure(new LinkProperties()); 158 } 159 } 160 161 private FrameworkFacade getFrameworkFacade() throws Exception { 162 FrameworkFacade facade = mock(FrameworkFacade.class); 163 164 when(facade.getService(Context.NETWORKMANAGEMENT_SERVICE)).thenReturn( 165 mockWithInterfaces(IBinder.class, INetworkManagementService.class)); 166 167 IBinder p2pBinder = mockService(WifiP2pServiceImpl.class, IWifiP2pManager.class); 168 when(facade.getService(Context.WIFI_P2P_SERVICE)).thenReturn(p2pBinder); 169 170 WifiP2pServiceImpl p2pm = (WifiP2pServiceImpl) p2pBinder.queryLocalInterface( 171 IWifiP2pManager.class.getCanonicalName()); 172 173 final CountDownLatch untilDone = new CountDownLatch(1); 174 mP2pThread = new HandlerThread("WifiP2pMockThread") { 175 @Override 176 protected void onLooperPrepared() { 177 untilDone.countDown(); 178 } 179 }; 180 181 mP2pThread.start(); 182 untilDone.await(); 183 184 Handler handler = new Handler(mP2pThread.getLooper()); 185 when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler)); 186 187 IBinder batteryStatsBinder = mockService(BatteryStats.class, IBatteryStats.class); 188 when(facade.getService(BatteryStats.SERVICE_NAME)).thenReturn(batteryStatsBinder); 189 190 when(facade.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class))) 191 .then(new AnswerWithArguments() { 192 public IpManager answer( 193 Context context, String ifname, IpManager.Callback callback) { 194 mTestIpManager = new TestIpManager(context, ifname, callback); 195 return mTestIpManager; 196 } 197 }); 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 209 MockResources resources = new com.android.server.wifi.MockResources(); 210 when(context.getResources()).thenReturn(resources); 211 212 MockContentResolver mockContentResolver = new MockContentResolver(); 213 mockContentResolver.addProvider(Settings.AUTHORITY, 214 new MockContentProvider(context) { 215 @Override 216 public Bundle call(String method, String arg, Bundle extras) { 217 return new Bundle(); 218 } 219 }); 220 when(context.getContentResolver()).thenReturn(mockContentResolver); 221 222 when(context.getSystemService(Context.POWER_SERVICE)).thenReturn( 223 new PowerManager(context, mock(IPowerManager.class), new Handler())); 224 225 mAlarmManager = new TestAlarmManager(); 226 when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 227 mAlarmManager.getAlarmManager()); 228 229 when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( 230 mock(ConnectivityManager.class)); 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 dumpState() { 265 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 266 PrintWriter writer = new PrintWriter(stream); 267 mWsm.dump(null, writer, null); 268 writer.flush(); 269 Log.d(TAG, "WifiStateMachine state -" + stream.toString()); 270 } 271 272 private static ScanDetail getGoogleGuestScanDetail(int rssi) { 273 ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; 274 ie[0] = ScanResults.generateSsidIe(sSSID); 275 NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList<String>(), sFreq); 276 ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, 277 Long.MAX_VALUE, /* needed so that scan results aren't rejected because 278 there older than scan start */ 279 ie, new ArrayList<String>()); 280 return detail; 281 } 282 283 private ArrayList<ScanDetail> getMockScanResults() { 284 ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); 285 ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); 286 287 int rssi = -65; 288 list.add(getGoogleGuestScanDetail(rssi)); 289 return list; 290 } 291 292 static final String sSSID = "\"GoogleGuest\""; 293 static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID); 294 static final String sHexSSID = sWifiSsid.getHexString().replace("0x", "").replace("22", ""); 295 static final String sBSSID = "01:02:03:04:05:06"; 296 static final int sFreq = 2437; 297 298 WifiStateMachine mWsm; 299 HandlerThread mWsmThread; 300 HandlerThread mP2pThread; 301 HandlerThread mSyncThread; 302 AsyncChannel mWsmAsyncChannel; 303 TestAlarmManager mAlarmManager; 304 MockWifiMonitor mWifiMonitor; 305 TestIpManager mTestIpManager; 306 TestLooper mLooper; 307 308 @Mock WifiScanner mWifiScanner; 309 @Mock SupplicantStateTracker mSupplicantStateTracker; 310 @Mock WifiMetrics mWifiMetrics; 311 @Mock UserManager mUserManager; 312 @Mock WifiApConfigStore mApConfigStore; 313 @Mock BackupManagerProxy mBackupManagerProxy; 314 @Mock WifiCountryCode mCountryCode; 315 @Mock WifiInjector mWifiInjector; 316 @Mock WifiLastResortWatchdog mWifiLastResortWatchdog; 317 @Mock PropertyService mPropertyService; 318 @Mock BuildProperties mBuildProperties; 319 @Mock IWificond mWificond; 320 @Mock IApInterface mApInterface; 321 @Mock IClientInterface mClientInterface; 322 @Mock IBinder mApInterfaceBinder; 323 @Mock IBinder mClientInterfaceBinder; 324 @Mock WifiConfigManager mWifiConfigManager; 325 @Mock WifiNative mWifiNative; 326 @Mock WifiConnectivityManager mWifiConnectivityManager; 327 @Mock SoftApManager mSoftApManager; 328 @Mock WifiStateTracker mWifiStateTracker; 329 @Mock PasspointManager mPasspointManager; 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 mLooper = new TestLooper(); 340 341 MockitoAnnotations.initMocks(this); 342 343 /** uncomment this to enable logs from WifiStateMachines */ 344 // enableDebugLogs(); 345 346 mWifiMonitor = new MockWifiMonitor(); 347 when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); 348 when(mWifiInjector.getClock()).thenReturn(new Clock()); 349 when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog); 350 when(mWifiInjector.getPropertyService()).thenReturn(mPropertyService); 351 when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties); 352 when(mWifiInjector.getKeyStore()).thenReturn(mock(KeyStore.class)); 353 when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class)); 354 when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn( 355 mock(BaseWifiDiagnostics.class)); 356 when(mWifiInjector.makeWificond()).thenReturn(mWificond); 357 when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager); 358 when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); 359 when(mWifiInjector.getWifiNetworkSelector()).thenReturn(mock(WifiNetworkSelector.class)); 360 when(mWifiInjector.makeWifiConnectivityManager(any(WifiInfo.class), anyBoolean())) 361 .thenReturn(mWifiConnectivityManager); 362 when(mWifiInjector.makeSoftApManager(any(INetworkManagementService.class), 363 any(SoftApManager.Listener.class), any(IApInterface.class), 364 any(WifiConfiguration.class))) 365 .thenReturn(mSoftApManager); 366 when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager); 367 368 when(mWifiNative.setupForClientMode()).thenReturn(mClientInterface); 369 when(mWifiNative.setupForSoftApMode()).thenReturn(mApInterface); 370 when(mWifiInjector.getWifiStateTracker()).thenReturn(mWifiStateTracker); 371 when(mWifiNative.getInterfaceName()).thenReturn("mockWlan"); 372 when(mWifiNative.enableSupplicant()).thenReturn(true); 373 when(mWifiNative.disableSupplicant()).thenReturn(true); 374 when(mWifiNative.getFrameworkNetworkId(anyInt())).thenReturn(0); 375 376 377 FrameworkFacade factory = getFrameworkFacade(); 378 Context context = getContext(); 379 380 Resources resources = getMockResources(); 381 when(context.getResources()).thenReturn(resources); 382 383 when(factory.getIntegerSetting(context, 384 Settings.Global.WIFI_FREQUENCY_BAND, 385 WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn( 386 WifiManager.WIFI_FREQUENCY_BAND_AUTO); 387 388 when(factory.makeApConfigStore(eq(context), eq(mBackupManagerProxy))) 389 .thenReturn(mApConfigStore); 390 391 when(factory.makeSupplicantStateTracker( 392 any(Context.class), any(WifiConfigManager.class), 393 any(Handler.class))).thenReturn(mSupplicantStateTracker); 394 395 when(mUserManager.getProfileParent(11)) 396 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "owner", 0)); 397 when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(Arrays.asList( 398 new UserInfo(UserHandle.USER_SYSTEM, "owner", 0), 399 new UserInfo(11, "managed profile", 0))); 400 401 when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder); 402 when(mClientInterface.asBinder()).thenReturn(mClientInterfaceBinder); 403 404 mWsm = new WifiStateMachine(context, factory, mLooper.getLooper(), 405 mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative); 406 mWsmThread = getWsmHandlerThread(mWsm); 407 408 final AsyncChannel channel = new AsyncChannel(); 409 Handler handler = new Handler(mLooper.getLooper()) { 410 @Override 411 public void handleMessage(Message msg) { 412 switch (msg.what) { 413 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 414 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 415 mWsmAsyncChannel = channel; 416 } else { 417 Log.d(TAG, "Failed to connect Command channel " + this); 418 } 419 break; 420 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 421 Log.d(TAG, "Command channel disconnected" + this); 422 break; 423 } 424 } 425 }; 426 427 channel.connect(context, handler, mWsm.getMessenger()); 428 mLooper.dispatchAll(); 429 /* Now channel is supposed to be connected */ 430 431 mBinderToken = Binder.clearCallingIdentity(); 432 } 433 434 @After 435 public void cleanUp() throws Exception { 436 Binder.restoreCallingIdentity(mBinderToken); 437 438 if (mSyncThread != null) stopLooper(mSyncThread.getLooper()); 439 if (mWsmThread != null) stopLooper(mWsmThread.getLooper()); 440 if (mP2pThread != null) stopLooper(mP2pThread.getLooper()); 441 442 mWsmThread = null; 443 mP2pThread = null; 444 mSyncThread = null; 445 mWsmAsyncChannel = null; 446 mWsm = null; 447 } 448 449 @Test 450 public void createNew() throws Exception { 451 assertEquals("InitialState", getCurrentState().getName()); 452 453 mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); 454 mLooper.dispatchAll(); 455 assertEquals("InitialState", getCurrentState().getName()); 456 } 457 458 @Test 459 public void loadComponentsInStaMode() throws Exception { 460 startSupplicantAndDispatchMessages(); 461 462 assertEquals("DisconnectedState", getCurrentState().getName()); 463 } 464 465 @Test 466 public void loadComponentsInApMode() throws Exception { 467 mWsm.setHostApRunning(new WifiConfiguration(), true); 468 mLooper.dispatchAll(); 469 470 assertEquals("SoftApState", getCurrentState().getName()); 471 472 verify(mSoftApManager).start(); 473 } 474 475 @Test 476 public void shouldRequireSupplicantStartupToLeaveInitialState() throws Exception { 477 when(mWifiNative.enableSupplicant()).thenReturn(false); 478 mWsm.setSupplicantRunning(true); 479 mLooper.dispatchAll(); 480 assertEquals("InitialState", getCurrentState().getName()); 481 } 482 483 @Test 484 public void shouldRequireWificondToLeaveInitialState() throws Exception { 485 // We start out with valid default values, break them going backwards so that 486 // we test all the bailout cases. 487 488 // ClientInterface dies after creation. 489 doThrow(new RemoteException()).when(mClientInterfaceBinder).linkToDeath(any(), anyInt()); 490 mWsm.setSupplicantRunning(true); 491 mLooper.dispatchAll(); 492 assertEquals("InitialState", getCurrentState().getName()); 493 494 // Failed to even create the client interface. 495 when(mWificond.createClientInterface()).thenReturn(null); 496 mWsm.setSupplicantRunning(true); 497 mLooper.dispatchAll(); 498 assertEquals("InitialState", getCurrentState().getName()); 499 500 // Failed to get wificond proxy. 501 when(mWifiInjector.makeWificond()).thenReturn(null); 502 mWsm.setSupplicantRunning(true); 503 mLooper.dispatchAll(); 504 assertEquals("InitialState", getCurrentState().getName()); 505 } 506 507 @Test 508 public void loadComponentsFailure() throws Exception { 509 when(mWifiNative.startHal(anyBoolean())).thenReturn(false); 510 when(mWifiNative.enableSupplicant()).thenReturn(false); 511 512 mWsm.setSupplicantRunning(true); 513 mLooper.dispatchAll(); 514 assertEquals("InitialState", getCurrentState().getName()); 515 516 when(mWifiNative.startHal(anyBoolean())).thenReturn(true); 517 mWsm.setSupplicantRunning(true); 518 mLooper.dispatchAll(); 519 assertEquals("InitialState", getCurrentState().getName()); 520 } 521 522 @Test 523 public void checkInitialStateStickyWhenDisabledMode() throws Exception { 524 mLooper.dispatchAll(); 525 assertEquals("InitialState", getCurrentState().getName()); 526 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 527 528 mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE); 529 mLooper.dispatchAll(); 530 assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest()); 531 assertEquals("InitialState", getCurrentState().getName()); 532 } 533 534 @Test 535 public void shouldStartSupplicantWhenConnectModeRequested() throws Exception { 536 when(mWifiNative.startHal(anyBoolean())).thenReturn(true); 537 538 // The first time we start out in InitialState, we sit around here. 539 mLooper.dispatchAll(); 540 assertEquals("InitialState", getCurrentState().getName()); 541 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 542 543 // But if someone tells us to enter connect mode, we start up supplicant 544 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 545 mLooper.dispatchAll(); 546 assertEquals("SupplicantStartingState", getCurrentState().getName()); 547 } 548 549 /** 550 * Test that mode changes accurately reflect the value for isWifiEnabled. 551 */ 552 @Test 553 public void checkIsWifiEnabledForModeChanges() throws Exception { 554 when(mWifiNative.startHal(anyBoolean())).thenReturn(true); 555 556 // Check initial state 557 mLooper.dispatchAll(); 558 assertEquals("InitialState", getCurrentState().getName()); 559 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 560 561 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 562 startSupplicantAndDispatchMessages(); 563 mWsm.setSupplicantRunning(true); 564 mLooper.dispatchAll(); 565 assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest()); 566 assertEquals("ScanModeState", getCurrentState().getName()); 567 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 568 569 // switch to connect mode and verify wifi is reported as enabled 570 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 571 mLooper.dispatchAll(); 572 assertEquals("DisconnectedState", getCurrentState().getName()); 573 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 574 assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState()); 575 576 // now go back to scan mode with "wifi disabled" to verify the reported wifi state. 577 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE); 578 mLooper.dispatchAll(); 579 assertEquals(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE, 580 mWsm.getOperationalModeForTest()); 581 assertEquals("ScanModeState", getCurrentState().getName()); 582 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 583 584 // now go to AP mode 585 mWsm.setSupplicantRunning(false); 586 mWsm.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP); 587 mWsm.sendMessage(WifiMonitor.SUP_DISCONNECTION_EVENT); 588 mWsm.setHostApRunning(new WifiConfiguration(), true); 589 mLooper.dispatchAll(); 590 assertEquals("SoftApState", getCurrentState().getName()); 591 assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState()); 592 } 593 594 595 /** 596 * Test that mode changes for WifiStateMachine in the InitialState are realized when supplicant 597 * is started. 598 */ 599 @Test 600 public void checkStartInCorrectStateAfterChangingInitialState() throws Exception { 601 when(mWifiNative.startHal(anyBoolean())).thenReturn(true); 602 603 // Check initial state 604 mLooper.dispatchAll(); 605 assertEquals("InitialState", getCurrentState().getName()); 606 assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); 607 608 // Update the mode 609 mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE); 610 mLooper.dispatchAll(); 611 assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest()); 612 613 // Start supplicant so we move to the next state 614 startSupplicantAndDispatchMessages(); 615 616 assertEquals("ScanModeState", getCurrentState().getName()); 617 } 618 619 /** 620 * Verifies that configs can be removed when in client mode. 621 */ 622 @Test 623 public void canRemoveNetworkConfigInClientMode() throws Exception { 624 boolean result; 625 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 626 addNetworkAndVerifySuccess(); 627 mLooper.startAutoDispatch(); 628 result = mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0); 629 mLooper.stopAutoDispatch(); 630 assertTrue(result); 631 } 632 633 /** 634 * Verifies that configs can be removed when not in client mode. 635 */ 636 @Test 637 public void canRemoveNetworkConfigWhenWifiDisabled() { 638 boolean result; 639 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 640 mLooper.startAutoDispatch(); 641 result = mWsm.syncRemoveNetwork(mWsmAsyncChannel, 0); 642 mLooper.stopAutoDispatch(); 643 644 assertTrue(result); 645 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 646 } 647 648 /** 649 * Verifies that configs can be forgotten when in client mode. 650 */ 651 @Test 652 public void canForgetNetworkConfigInClientMode() throws Exception { 653 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 654 addNetworkAndVerifySuccess(); 655 mWsm.sendMessage(WifiManager.FORGET_NETWORK, 0, MANAGED_PROFILE_UID); 656 mLooper.dispatchAll(); 657 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 658 } 659 660 /** 661 * Verifies that configs can be removed when not in client mode. 662 */ 663 @Test 664 public void canForgetNetworkConfigWhenWifiDisabled() throws Exception { 665 when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true); 666 mWsm.sendMessage(WifiManager.FORGET_NETWORK, 0, MANAGED_PROFILE_UID); 667 mLooper.dispatchAll(); 668 verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt()); 669 } 670 671 /** 672 * Helper method to move through SupplicantStarting and SupplicantStarted states. 673 */ 674 private void startSupplicantAndDispatchMessages() throws Exception { 675 mWsm.setSupplicantRunning(true); 676 mLooper.dispatchAll(); 677 678 assertEquals("SupplicantStartingState", getCurrentState().getName()); 679 680 when(mWifiNative.setDeviceName(anyString())).thenReturn(true); 681 when(mWifiNative.setManufacturer(anyString())).thenReturn(true); 682 when(mWifiNative.setModelName(anyString())).thenReturn(true); 683 when(mWifiNative.setModelNumber(anyString())).thenReturn(true); 684 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 685 when(mWifiNative.setConfigMethods(anyString())).thenReturn(true); 686 when(mWifiNative.setDeviceType(anyString())).thenReturn(true); 687 when(mWifiNative.setSerialNumber(anyString())).thenReturn(true); 688 when(mWifiNative.setScanningMacOui(any(byte[].class))).thenReturn(true); 689 690 mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); 691 mLooper.dispatchAll(); 692 } 693 694 private void addNetworkAndVerifySuccess() throws Exception { 695 addNetworkAndVerifySuccess(false); 696 } 697 698 private void addNetworkAndVerifySuccess(boolean isHidden) throws Exception { 699 loadComponentsInStaMode(); 700 701 WifiConfiguration config = new WifiConfiguration(); 702 config.SSID = sSSID; 703 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 704 config.hiddenSSID = isHidden; 705 706 when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) 707 .thenReturn(new NetworkUpdateResult(0)); 708 when(mWifiConfigManager.getSavedNetworks()).thenReturn(Arrays.asList(config)); 709 when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config); 710 711 mLooper.startAutoDispatch(); 712 mWsm.syncAddOrUpdateNetwork(mWsmAsyncChannel, config); 713 mLooper.stopAutoDispatch(); 714 715 verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt()); 716 717 mLooper.startAutoDispatch(); 718 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 719 mLooper.stopAutoDispatch(); 720 assertEquals(1, configs.size()); 721 722 WifiConfiguration config2 = configs.get(0); 723 assertEquals("\"GoogleGuest\"", config2.SSID); 724 assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); 725 } 726 727 /** 728 * Helper method to retrieve WifiConfiguration by SSID. 729 * 730 * Returns the associated WifiConfiguration if it is found, null otherwise. 731 */ 732 private WifiConfiguration getWifiConfigurationForNetwork(String ssid) { 733 mLooper.startAutoDispatch(); 734 List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel); 735 mLooper.stopAutoDispatch(); 736 737 for (WifiConfiguration checkConfig : configs) { 738 if (checkConfig.SSID.equals(ssid)) { 739 return checkConfig; 740 } 741 } 742 return null; 743 } 744 745 private void verifyScan(int band, int reportEvents, Set<String> hiddenNetworkSSIDSet) { 746 ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor = 747 ArgumentCaptor.forClass(WifiScanner.ScanSettings.class); 748 ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor = 749 ArgumentCaptor.forClass(WifiScanner.ScanListener.class); 750 verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture(), 751 eq(null)); 752 WifiScanner.ScanSettings actualSettings = scanSettingsCaptor.getValue(); 753 assertEquals("band", band, actualSettings.band); 754 assertEquals("reportEvents", reportEvents, actualSettings.reportEvents); 755 756 if (hiddenNetworkSSIDSet == null) { 757 hiddenNetworkSSIDSet = new HashSet<>(); 758 } 759 Set<String> actualHiddenNetworkSSIDSet = new HashSet<>(); 760 if (actualSettings.hiddenNetworks != null) { 761 for (int i = 0; i < actualSettings.hiddenNetworks.length; ++i) { 762 actualHiddenNetworkSSIDSet.add(actualSettings.hiddenNetworks[i].ssid); 763 } 764 } 765 assertEquals("hidden networks", hiddenNetworkSSIDSet, actualHiddenNetworkSSIDSet); 766 767 when(mWifiNative.getScanResults()).thenReturn(getMockScanResults()); 768 mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT); 769 770 mLooper.dispatchAll(); 771 772 List<ScanResult> reportedResults = mWsm.syncGetScanResultsList(); 773 assertEquals(8, reportedResults.size()); 774 } 775 776 @Test 777 public void scan() throws Exception { 778 addNetworkAndVerifySuccess(); 779 780 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 781 mWsm.startScan(-1, 0, null, null); 782 mLooper.dispatchAll(); 783 784 verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 785 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 786 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, null); 787 } 788 789 @Test 790 public void scanWithHiddenNetwork() throws Exception { 791 addNetworkAndVerifySuccess(true); 792 793 Set<String> hiddenNetworkSet = new HashSet<>(); 794 hiddenNetworkSet.add(sSSID); 795 List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworkList = new ArrayList<>(); 796 hiddenNetworkList.add(new WifiScanner.ScanSettings.HiddenNetwork(sSSID)); 797 when(mWifiConfigManager.retrieveHiddenNetworkList()).thenReturn(hiddenNetworkList); 798 799 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 800 mWsm.startScan(-1, 0, null, null); 801 mLooper.dispatchAll(); 802 803 verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 804 WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN 805 | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, 806 hiddenNetworkSet); 807 } 808 809 @Test 810 public void connect() throws Exception { 811 addNetworkAndVerifySuccess(); 812 813 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 814 mLooper.dispatchAll(); 815 816 mLooper.startAutoDispatch(); 817 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 818 mLooper.stopAutoDispatch(); 819 820 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 821 822 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 823 mLooper.dispatchAll(); 824 825 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 826 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 827 mLooper.dispatchAll(); 828 829 assertEquals("ObtainingIpState", getCurrentState().getName()); 830 831 DhcpResults dhcpResults = new DhcpResults(); 832 dhcpResults.setGateway("1.2.3.4"); 833 dhcpResults.setIpAddress("192.168.1.100", 0); 834 dhcpResults.addDns("8.8.8.8"); 835 dhcpResults.setLeaseDuration(3600); 836 837 mTestIpManager.injectDhcpSuccess(dhcpResults); 838 mLooper.dispatchAll(); 839 840 assertEquals("ConnectedState", getCurrentState().getName()); 841 } 842 843 /** 844 * If caller tries to connect to a network that is already connected, the connection request 845 * should succeed. 846 * 847 * Test: Create and connect to a network, then try to reconnect to the same network. Verify 848 * that connection request returns with CONNECT_NETWORK_SUCCEEDED. 849 */ 850 @Test 851 public void reconnectToConnectedNetwork() throws Exception { 852 addNetworkAndVerifySuccess(); 853 854 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 855 mLooper.dispatchAll(); 856 857 mLooper.startAutoDispatch(); 858 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 859 mLooper.stopAutoDispatch(); 860 861 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 862 863 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 864 mLooper.dispatchAll(); 865 866 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 867 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 868 mLooper.dispatchAll(); 869 870 assertEquals("ObtainingIpState", getCurrentState().getName()); 871 872 // try to reconnect 873 mLooper.startAutoDispatch(); 874 Message reply = mWsmAsyncChannel.sendMessageSynchronously(WifiManager.CONNECT_NETWORK, 0); 875 mLooper.stopAutoDispatch(); 876 877 assertEquals(WifiManager.CONNECT_NETWORK_SUCCEEDED, reply.what); 878 } 879 880 @Test 881 public void testDhcpFailure() throws Exception { 882 addNetworkAndVerifySuccess(); 883 884 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 885 mLooper.dispatchAll(); 886 887 mLooper.startAutoDispatch(); 888 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 889 mLooper.stopAutoDispatch(); 890 891 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 892 893 mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); 894 mLooper.dispatchAll(); 895 896 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 897 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 898 mLooper.dispatchAll(); 899 900 assertEquals("ObtainingIpState", getCurrentState().getName()); 901 902 mTestIpManager.injectDhcpFailure(); 903 mLooper.dispatchAll(); 904 905 assertEquals("DisconnectingState", getCurrentState().getName()); 906 } 907 908 @Test 909 public void testBadNetworkEvent() throws Exception { 910 addNetworkAndVerifySuccess(); 911 912 mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); 913 mLooper.dispatchAll(); 914 915 mLooper.startAutoDispatch(); 916 mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true); 917 mLooper.stopAutoDispatch(); 918 919 verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); 920 921 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID); 922 mLooper.dispatchAll(); 923 924 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 925 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED)); 926 mLooper.dispatchAll(); 927 928 assertEquals("DisconnectedState", getCurrentState().getName()); 929 } 930 931 932 @Test 933 public void smToString() throws Exception { 934 assertEquals("CMD_CHANNEL_HALF_CONNECTED", mWsm.smToString( 935 AsyncChannel.CMD_CHANNEL_HALF_CONNECTED)); 936 assertEquals("CMD_PRE_DHCP_ACTION", mWsm.smToString( 937 DhcpClient.CMD_PRE_DHCP_ACTION)); 938 assertEquals("CMD_IP_REACHABILITY_LOST", mWsm.smToString( 939 WifiStateMachine.CMD_IP_REACHABILITY_LOST)); 940 } 941 942 @Test 943 public void disconnect() throws Exception { 944 connect(); 945 946 mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06"); 947 mLooper.dispatchAll(); 948 mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, 949 new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); 950 mLooper.dispatchAll(); 951 952 assertEquals("DisconnectedState", getCurrentState().getName()); 953 } 954 955 /** 956 * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected 957 * to true. 958 * 959 * Test: Successfully create and connect to a network. Check the config and verify 960 * WifiConfiguration.getHasEverConnected() is true. 961 */ 962 @Test 963 public void setHasEverConnectedTrueOnConnect() throws Exception { 964 connect(); 965 verify(mWifiConfigManager, atLeastOnce()).updateNetworkAfterConnect(0); 966 } 967 968 /** 969 * Fail network connection attempt and verify HasEverConnected remains false. 970 * 971 * Test: Successfully create a network but fail when connecting. Check the config and verify 972 * WifiConfiguration.getHasEverConnected() is false. 973 */ 974 @Test 975 public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception { 976 testDhcpFailure(); 977 verify(mWifiConfigManager, never()).updateNetworkAfterConnect(0); 978 } 979 980 @Test 981 public void iconQueryTest() throws Exception { 982 // TODO(b/31065385): Passpoint config management. 983 } 984 985 @Test 986 public void verboseLogRecSizeIsGreaterThanNormalSize() { 987 assertTrue(LOG_REC_LIMIT_IN_VERBOSE_MODE > WifiStateMachine.NUM_LOG_RECS_NORMAL); 988 } 989 990 /** 991 * Verifies that, by default, we allow only the "normal" number of log records. 992 */ 993 @Test 994 public void normalLogRecSizeIsUsedByDefault() { 995 assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecMaxSize()); 996 } 997 998 /** 999 * Verifies that, in verbose mode, we allow a larger number of log records. 1000 */ 1001 @Test 1002 public void enablingVerboseLoggingUpdatesLogRecSize() { 1003 mWsm.enableVerboseLogging(1); 1004 assertEquals(LOG_REC_LIMIT_IN_VERBOSE_MODE, mWsm.getLogRecMaxSize()); 1005 } 1006 1007 @Test 1008 public void disablingVerboseLoggingClearsRecords() { 1009 mWsm.sendMessage(WifiStateMachine.CMD_DISCONNECT); 1010 mLooper.dispatchAll(); 1011 assertTrue(mWsm.getLogRecSize() >= 1); 1012 1013 mWsm.enableVerboseLogging(0); 1014 assertEquals(0, mWsm.getLogRecSize()); 1015 } 1016 1017 @Test 1018 public void disablingVerboseLoggingUpdatesLogRecSize() { 1019 mWsm.enableVerboseLogging(1); 1020 mWsm.enableVerboseLogging(0); 1021 assertEquals(WifiStateMachine.NUM_LOG_RECS_NORMAL, mWsm.getLogRecMaxSize()); 1022 } 1023 1024 /** Verifies that enabling verbose logging sets the hal log property in eng builds. */ 1025 @Test 1026 public void enablingVerboseLoggingSetsHalLogPropertyInEngBuilds() { 1027 reset(mPropertyService); // Ignore calls made in setUp() 1028 when(mBuildProperties.isEngBuild()).thenReturn(true); 1029 when(mBuildProperties.isUserdebugBuild()).thenReturn(false); 1030 when(mBuildProperties.isUserBuild()).thenReturn(false); 1031 mWsm.enableVerboseLogging(1); 1032 verify(mPropertyService).set("log.tag.WifiHAL", "V"); 1033 } 1034 1035 /** Verifies that enabling verbose logging sets the hal log property in userdebug builds. */ 1036 @Test 1037 public void enablingVerboseLoggingSetsHalLogPropertyInUserdebugBuilds() { 1038 reset(mPropertyService); // Ignore calls made in setUp() 1039 when(mBuildProperties.isUserdebugBuild()).thenReturn(true); 1040 when(mBuildProperties.isEngBuild()).thenReturn(false); 1041 when(mBuildProperties.isUserBuild()).thenReturn(false); 1042 mWsm.enableVerboseLogging(1); 1043 verify(mPropertyService).set("log.tag.WifiHAL", "V"); 1044 } 1045 1046 /** Verifies that enabling verbose logging does NOT set the hal log property in user builds. */ 1047 @Test 1048 public void enablingVerboseLoggingDoeNotSetHalLogPropertyInUserBuilds() { 1049 reset(mPropertyService); // Ignore calls made in setUp() 1050 when(mBuildProperties.isUserBuild()).thenReturn(true); 1051 when(mBuildProperties.isEngBuild()).thenReturn(false); 1052 when(mBuildProperties.isUserdebugBuild()).thenReturn(false); 1053 mWsm.enableVerboseLogging(1); 1054 verify(mPropertyService, never()).set(anyString(), anyString()); 1055 } 1056 1057 private int testGetSupportedFeaturesCase(int supportedFeatures, boolean rttConfigured) { 1058 AsyncChannel channel = mock(AsyncChannel.class); 1059 Message reply = Message.obtain(); 1060 reply.arg1 = supportedFeatures; 1061 reset(mPropertyService); // Ignore calls made in setUp() 1062 when(channel.sendMessageSynchronously(WifiStateMachine.CMD_GET_SUPPORTED_FEATURES)) 1063 .thenReturn(reply); 1064 when(mPropertyService.getBoolean("config.disable_rtt", false)) 1065 .thenReturn(rttConfigured); 1066 return mWsm.syncGetSupportedFeatures(channel); 1067 } 1068 1069 /** Verifies that syncGetSupportedFeatures() masks out capabilities based on system flags. */ 1070 @Test 1071 public void syncGetSupportedFeatures() { 1072 final int featureAware = WifiManager.WIFI_FEATURE_AWARE; 1073 final int featureInfra = WifiManager.WIFI_FEATURE_INFRA; 1074 final int featureD2dRtt = WifiManager.WIFI_FEATURE_D2D_RTT; 1075 final int featureD2apRtt = WifiManager.WIFI_FEATURE_D2AP_RTT; 1076 1077 assertEquals(0, testGetSupportedFeaturesCase(0, false)); 1078 assertEquals(0, testGetSupportedFeaturesCase(0, true)); 1079 assertEquals(featureAware | featureInfra, 1080 testGetSupportedFeaturesCase(featureAware | featureInfra, false)); 1081 assertEquals(featureAware | featureInfra, 1082 testGetSupportedFeaturesCase(featureAware | featureInfra, true)); 1083 assertEquals(featureInfra | featureD2dRtt, 1084 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt, false)); 1085 assertEquals(featureInfra, 1086 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt, true)); 1087 assertEquals(featureInfra | featureD2apRtt, 1088 testGetSupportedFeaturesCase(featureInfra | featureD2apRtt, false)); 1089 assertEquals(featureInfra, 1090 testGetSupportedFeaturesCase(featureInfra | featureD2apRtt, true)); 1091 assertEquals(featureInfra | featureD2dRtt | featureD2apRtt, 1092 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt | featureD2apRtt, false)); 1093 assertEquals(featureInfra, 1094 testGetSupportedFeaturesCase(featureInfra | featureD2dRtt | featureD2apRtt, true)); 1095 } 1096 1097 /** 1098 * Verify that syncAddOrUpdatePasspointConfig will redirect calls to {@link PasspointManager} 1099 * and returning the result that's returned from {@link PasspointManager}. 1100 */ 1101 @Test 1102 public void syncAddOrUpdatePasspointConfig() throws Exception { 1103 when(mPasspointManager.addOrUpdateProvider(any(PasspointConfiguration.class))) 1104 .thenReturn(true); 1105 mLooper.startAutoDispatch(); 1106 assertTrue(mWsm.syncAddOrUpdatePasspointConfig(mWsmAsyncChannel, 1107 new PasspointConfiguration())); 1108 mLooper.stopAutoDispatch(); 1109 reset(mPasspointManager); 1110 1111 when(mPasspointManager.addOrUpdateProvider(any(PasspointConfiguration.class))) 1112 .thenReturn(false); 1113 mLooper.startAutoDispatch(); 1114 assertFalse(mWsm.syncAddOrUpdatePasspointConfig(mWsmAsyncChannel, 1115 new PasspointConfiguration())); 1116 mLooper.stopAutoDispatch(); 1117 } 1118 1119 /** 1120 * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager} 1121 * and returning the result that's returned from {@link PasspointManager}. 1122 */ 1123 @Test 1124 public void syncRemovePasspointConfig() throws Exception { 1125 String fqdn = "test.com"; 1126 when(mPasspointManager.removeProvider(fqdn)).thenReturn(true); 1127 mLooper.startAutoDispatch(); 1128 assertTrue(mWsm.syncRemovePasspointConfig(mWsmAsyncChannel, fqdn)); 1129 mLooper.stopAutoDispatch(); 1130 reset(mPasspointManager); 1131 1132 when(mPasspointManager.removeProvider(fqdn)).thenReturn(false); 1133 mLooper.startAutoDispatch(); 1134 assertFalse(mWsm.syncRemovePasspointConfig(mWsmAsyncChannel, fqdn)); 1135 mLooper.stopAutoDispatch(); 1136 } 1137 1138 /** 1139 * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager} 1140 * and returning the result that's returned from {@link PasspointManager} when in client mode. 1141 */ 1142 @Test 1143 public void syncRemovePasspointConfigInClientMode() throws Exception { 1144 loadComponentsInStaMode(); 1145 syncRemovePasspointConfig(); 1146 } 1147 1148 /** 1149 * Verify that syncGetPasspointConfigs will redirect calls to {@link PasspointManager} 1150 * and returning the result that's returned from {@link PasspointManager}. 1151 */ 1152 @Test 1153 public void syncGetPasspointConfigs() throws Exception { 1154 // Setup expected configs. 1155 List<PasspointConfiguration> expectedConfigs = new ArrayList<>(); 1156 PasspointConfiguration config = new PasspointConfiguration(); 1157 HomeSp homeSp = new HomeSp(); 1158 homeSp.setFqdn("test.com"); 1159 config.setHomeSp(homeSp); 1160 expectedConfigs.add(config); 1161 1162 when(mPasspointManager.getProviderConfigs()).thenReturn(expectedConfigs); 1163 mLooper.startAutoDispatch(); 1164 assertEquals(expectedConfigs, mWsm.syncGetPasspointConfigs(mWsmAsyncChannel)); 1165 mLooper.stopAutoDispatch(); 1166 reset(mPasspointManager); 1167 1168 when(mPasspointManager.getProviderConfigs()) 1169 .thenReturn(new ArrayList<PasspointConfiguration>()); 1170 mLooper.startAutoDispatch(); 1171 assertTrue(mWsm.syncGetPasspointConfigs(mWsmAsyncChannel).isEmpty()); 1172 mLooper.stopAutoDispatch(); 1173 } 1174} 1175