1/* 2 * Copyright (C) 2017 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 */ 16package com.android.server.wifi; 17 18import static org.junit.Assert.*; 19import static org.mockito.Matchers.any; 20import static org.mockito.Matchers.anyBoolean; 21import static org.mockito.Matchers.anyInt; 22import static org.mockito.Matchers.anyLong; 23import static org.mockito.Matchers.anyShort; 24import static org.mockito.Matchers.anyString; 25import static org.mockito.Matchers.eq; 26import static org.mockito.Mockito.*; 27 28import android.app.test.MockAnswerUtil; 29import android.content.Context; 30import android.hardware.wifi.supplicant.V1_0.ISupplicant; 31import android.hardware.wifi.supplicant.V1_0.ISupplicantIface; 32import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface; 33import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 34import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason; 35import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; 36import android.hardware.wifi.supplicant.V1_0.IfaceType; 37import android.hardware.wifi.supplicant.V1_0.SupplicantStatus; 38import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; 39import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods; 40import android.hidl.manager.V1_0.IServiceManager; 41import android.hidl.manager.V1_0.IServiceNotification; 42import android.net.IpConfiguration; 43import android.net.wifi.SupplicantState; 44import android.net.wifi.WifiConfiguration; 45import android.net.wifi.WifiManager; 46import android.net.wifi.WifiSsid; 47import android.os.IHwBinder; 48import android.os.RemoteException; 49import android.text.TextUtils; 50import android.util.SparseArray; 51 52import com.android.server.wifi.hotspot2.AnqpEvent; 53import com.android.server.wifi.hotspot2.IconEvent; 54import com.android.server.wifi.hotspot2.WnmData; 55import com.android.server.wifi.util.NativeUtil; 56 57import libcore.util.NonNull; 58 59import org.junit.Before; 60import org.junit.Test; 61import org.mockito.ArgumentCaptor; 62import org.mockito.InOrder; 63import org.mockito.Mock; 64import org.mockito.MockitoAnnotations; 65 66import java.nio.ByteBuffer; 67import java.nio.ByteOrder; 68import java.util.ArrayList; 69import java.util.Arrays; 70import java.util.HashMap; 71import java.util.Map; 72import java.util.Random; 73 74/** 75 * Unit tests for SupplicantStaIfaceHal 76 */ 77public class SupplicantStaIfaceHalTest { 78 private static final String TAG = "SupplicantStaIfaceHalTest"; 79 private static final Map<Integer, String> NETWORK_ID_TO_SSID = new HashMap<Integer, String>() {{ 80 put(1, "\"ssid1\""); 81 put(2, "\"ssid2\""); 82 put(3, "\"ssid3\""); 83 }}; 84 private static final int SUPPLICANT_NETWORK_ID = 2; 85 private static final String SUPPLICANT_SSID = NETWORK_ID_TO_SSID.get(SUPPLICANT_NETWORK_ID); 86 private static final int ROAM_NETWORK_ID = 4; 87 private static final String BSSID = "fa:45:23:23:12:12"; 88 private static final String WLAN0_IFACE_NAME = "wlan0"; 89 private static final String WLAN1_IFACE_NAME = "wlan1"; 90 private static final String P2P_IFACE_NAME = "p2p0"; 91 private static final String ICON_FILE_NAME = "blahblah"; 92 private static final int ICON_FILE_SIZE = 72; 93 private static final String HS20_URL = "http://blahblah"; 94 95 private @Mock IServiceManager mServiceManagerMock; 96 private @Mock ISupplicant mISupplicantMock; 97 private android.hardware.wifi.supplicant.V1_1.ISupplicant mISupplicantMockV1_1; 98 private @Mock ISupplicantIface mISupplicantIfaceMock; 99 private @Mock ISupplicantStaIface mISupplicantStaIfaceMock; 100 private @Mock android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface 101 mISupplicantStaIfaceMockV1_1; 102 private @Mock Context mContext; 103 private @Mock WifiMonitor mWifiMonitor; 104 private @Mock SupplicantStaNetworkHal mSupplicantStaNetworkMock; 105 private @Mock WifiNative.SupplicantDeathEventHandler mSupplicantHalDeathHandler; 106 SupplicantStatus mStatusSuccess; 107 SupplicantStatus mStatusFailure; 108 ISupplicant.IfaceInfo mStaIface0; 109 ISupplicant.IfaceInfo mStaIface1; 110 ISupplicant.IfaceInfo mP2pIface; 111 ArrayList<ISupplicant.IfaceInfo> mIfaceInfoList; 112 ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback; 113 android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback 114 mISupplicantStaIfaceCallbackV1_1; 115 private SupplicantStaIfaceHal mDut; 116 private ArgumentCaptor<IHwBinder.DeathRecipient> mServiceManagerDeathCaptor = 117 ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class); 118 private ArgumentCaptor<IHwBinder.DeathRecipient> mSupplicantDeathCaptor = 119 ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class); 120 private ArgumentCaptor<IHwBinder.DeathRecipient> mSupplicantStaIfaceDeathCaptor = 121 ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class); 122 private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor = 123 ArgumentCaptor.forClass(IServiceNotification.Stub.class); 124 private InOrder mInOrder; 125 126 private class SupplicantStaIfaceHalSpy extends SupplicantStaIfaceHal { 127 SupplicantStaIfaceHalSpy(Context context, WifiMonitor monitor) { 128 super(context, monitor); 129 } 130 131 @Override 132 protected IServiceManager getServiceManagerMockable() throws RemoteException { 133 return mServiceManagerMock; 134 } 135 136 @Override 137 protected ISupplicant getSupplicantMockable() throws RemoteException { 138 return mISupplicantMock; 139 } 140 141 @Override 142 protected android.hardware.wifi.supplicant.V1_1.ISupplicant getSupplicantMockableV1_1() 143 throws RemoteException { 144 return mISupplicantMockV1_1; 145 } 146 147 @Override 148 protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) { 149 return mISupplicantStaIfaceMock; 150 } 151 152 @Override 153 protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface 154 getStaIfaceMockableV1_1(ISupplicantIface iface) { 155 return mISupplicantStaIfaceMockV1_1; 156 } 157 158 @Override 159 protected SupplicantStaNetworkHal getStaNetworkMockable( 160 @NonNull String ifaceName, 161 ISupplicantStaNetwork iSupplicantStaNetwork) { 162 return mSupplicantStaNetworkMock; 163 } 164 } 165 166 @Before 167 public void setUp() throws Exception { 168 MockitoAnnotations.initMocks(this); 169 mStatusSuccess = createSupplicantStatus(SupplicantStatusCode.SUCCESS); 170 mStatusFailure = createSupplicantStatus(SupplicantStatusCode.FAILURE_UNKNOWN); 171 mStaIface0 = createIfaceInfo(IfaceType.STA, WLAN0_IFACE_NAME); 172 mStaIface1 = createIfaceInfo(IfaceType.STA, WLAN1_IFACE_NAME); 173 mP2pIface = createIfaceInfo(IfaceType.P2P, P2P_IFACE_NAME); 174 175 mIfaceInfoList = new ArrayList<>(); 176 mIfaceInfoList.add(mStaIface0); 177 mIfaceInfoList.add(mStaIface1); 178 mIfaceInfoList.add(mP2pIface); 179 180 when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class), 181 anyLong())).thenReturn(true); 182 when(mServiceManagerMock.registerForNotifications(anyString(), anyString(), 183 any(IServiceNotification.Stub.class))).thenReturn(true); 184 when(mISupplicantMock.linkToDeath(any(IHwBinder.DeathRecipient.class), 185 anyLong())).thenReturn(true); 186 mDut = new SupplicantStaIfaceHalSpy(mContext, mWifiMonitor); 187 } 188 189 /** 190 * Sunny day scenario for SupplicantStaIfaceHal initialization 191 * Asserts successful initialization 192 */ 193 @Test 194 public void testInitialize_success() throws Exception { 195 executeAndValidateInitializationSequence(false, false, false, false); 196 } 197 198 /** 199 * Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called 200 * Ensures initialization fails. 201 */ 202 @Test 203 public void testInitialize_remoteExceptionFailure() throws Exception { 204 executeAndValidateInitializationSequence(true, false, false, false); 205 } 206 207 /** 208 * Tests the initialization flow, with listInterfaces returning 0 interfaces. 209 * Ensures failure 210 */ 211 @Test 212 public void testInitialize_zeroInterfacesFailure() throws Exception { 213 executeAndValidateInitializationSequence(false, true, false, false); 214 } 215 216 /** 217 * Tests the initialization flow, with a null interface being returned by getInterface. 218 * Ensures initialization fails. 219 */ 220 @Test 221 public void testInitialize_nullInterfaceFailure() throws Exception { 222 executeAndValidateInitializationSequence(false, false, true, false); 223 } 224 225 /** 226 * Tests the initialization flow, with a callback registration failure. 227 * Ensures initialization fails. 228 */ 229 @Test 230 public void testInitialize_callbackRegistrationFailure() throws Exception { 231 executeAndValidateInitializationSequence(false, false, false, true); 232 } 233 234 /** 235 * Sunny day scenario for SupplicantStaIfaceHal initialization 236 * Asserts successful initialization 237 */ 238 @Test 239 public void testInitialize_successV1_1() throws Exception { 240 mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class); 241 executeAndValidateInitializationSequenceV1_1(false, false); 242 } 243 244 /** 245 * Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called 246 * Ensures initialization fails. 247 */ 248 @Test 249 public void testInitialize_remoteExceptionFailureV1_1() throws Exception { 250 mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class); 251 executeAndValidateInitializationSequenceV1_1(true, false); 252 } 253 254 /** 255 * Tests the initialization flow, with a null interface being returned by getInterface. 256 * Ensures initialization fails. 257 */ 258 @Test 259 public void testInitialize_nullInterfaceFailureV1_1() throws Exception { 260 mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class); 261 executeAndValidateInitializationSequenceV1_1(false, true); 262 } 263 264 /** 265 * Ensures that we do not allow operations on an interface until it's setup. 266 */ 267 @Test 268 public void testEnsureOperationFailsUntilSetupInterfaces() throws Exception { 269 executeAndValidateInitializationSequence(false, false, false, false); 270 271 // Ensure that the cancel wps operation is failed because wlan1 interface is not yet setup. 272 assertFalse(mDut.cancelWps(WLAN1_IFACE_NAME)); 273 verify(mISupplicantStaIfaceMock, never()).cancelWps(); 274 275 // Now setup the wlan1 interface and Ensure that the cancel wps operation is successful. 276 assertTrue(mDut.setupIface(WLAN1_IFACE_NAME)); 277 when(mISupplicantStaIfaceMock.cancelWps()).thenReturn(mStatusSuccess); 278 assertTrue(mDut.cancelWps(WLAN1_IFACE_NAME)); 279 verify(mISupplicantStaIfaceMock).cancelWps(); 280 } 281 282 /** 283 * Ensures that reject addition of an existing iface. 284 */ 285 @Test 286 public void testDuplicateSetupIfaceV1_1_Fails() throws Exception { 287 mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class); 288 executeAndValidateInitializationSequenceV1_1(false, false); 289 290 // Trying setting up the wlan0 interface again & ensure it fails. 291 assertFalse(mDut.setupIface(WLAN0_IFACE_NAME)); 292 verifyNoMoreInteractions(mISupplicantMockV1_1); 293 } 294 295 /** 296 * Sunny day scenario for SupplicantStaIfaceHal interface teardown. 297 */ 298 @Test 299 public void testTeardownInterface() throws Exception { 300 testInitialize_success(); 301 assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME)); 302 303 // Ensure that the cancel wps operation is failed because there are no interfaces setup. 304 assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME)); 305 verify(mISupplicantStaIfaceMock, never()).cancelWps(); 306 } 307 308 /** 309 * Sunny day scenario for SupplicantStaIfaceHal interface teardown. 310 */ 311 @Test 312 public void testTeardownInterfaceV1_1() throws Exception { 313 testInitialize_successV1_1(); 314 315 when(mISupplicantMockV1_1.removeInterface(any())).thenReturn(mStatusSuccess); 316 assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME)); 317 verify(mISupplicantMockV1_1).removeInterface(any()); 318 319 // Ensure that the cancel wps operation is failed because there are no interfaces setup. 320 assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME)); 321 verify(mISupplicantStaIfaceMock, never()).cancelWps(); 322 } 323 324 /** 325 * Ensures that we reject removal of an invalid iface. 326 */ 327 @Test 328 public void testInvalidTeardownInterfaceV1_1_Fails() throws Exception { 329 assertFalse(mDut.teardownIface(WLAN0_IFACE_NAME)); 330 verifyNoMoreInteractions(mISupplicantMock); 331 } 332 333 /** 334 * Sunny day scenario for SupplicantStaIfaceHal initialization 335 * Asserts successful initialization of second interface 336 */ 337 @Test 338 public void testSetupTwoInterfaces() throws Exception { 339 executeAndValidateInitializationSequence(false, false, false, false); 340 assertTrue(mDut.setupIface(WLAN1_IFACE_NAME)); 341 } 342 343 /** 344 * Sunny day scenario for SupplicantStaIfaceHal interface teardown. 345 * Asserts successful initialization of second interface 346 */ 347 @Test 348 public void testTeardownTwoInterfaces() throws Exception { 349 testSetupTwoInterfaces(); 350 assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME)); 351 assertTrue(mDut.teardownIface(WLAN1_IFACE_NAME)); 352 353 // Ensure that the cancel wps operation is failed because there are no interfaces setup. 354 assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME)); 355 verify(mISupplicantStaIfaceMock, never()).cancelWps(); 356 } 357 358 359 /** 360 * Tests the loading of networks using {@link SupplicantStaNetworkHal}. 361 * Fills up only the SSID field of configs and uses it as a configKey as well. 362 */ 363 @Test 364 public void testLoadNetworks() throws Exception { 365 executeAndValidateInitializationSequence(); 366 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 367 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 368 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 369 } 370 }).when(mISupplicantStaIfaceMock) 371 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 372 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 373 public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) { 374 // Reset the |mSupplicantStaNetwork| mock for each network. 375 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 376 public boolean answer( 377 WifiConfiguration config, Map<String, String> networkExtra) { 378 config.SSID = NETWORK_ID_TO_SSID.get(networkId); 379 config.networkId = networkId; 380 networkExtra.put( 381 SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY, config.SSID); 382 return true; 383 } 384 }).when(mSupplicantStaNetworkMock) 385 .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class)); 386 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class)); 387 return; 388 } 389 }).when(mISupplicantStaIfaceMock) 390 .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class)); 391 392 Map<String, WifiConfiguration> configs = new HashMap<>(); 393 SparseArray<Map<String, String>> extras = new SparseArray<>(); 394 assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 395 396 assertEquals(3, configs.size()); 397 assertEquals(3, extras.size()); 398 for (Map.Entry<Integer, String> network : NETWORK_ID_TO_SSID.entrySet()) { 399 WifiConfiguration config = configs.get(network.getValue()); 400 assertTrue(config != null); 401 assertEquals(network.getKey(), Integer.valueOf(config.networkId)); 402 assertEquals(network.getValue(), config.SSID); 403 assertEquals(IpConfiguration.IpAssignment.DHCP, config.getIpAssignment()); 404 assertEquals(IpConfiguration.ProxySettings.NONE, config.getProxySettings()); 405 } 406 } 407 408 /** 409 * Tests the loading of networks using {@link SupplicantStaNetworkHal} removes any networks 410 * with duplicate config key. 411 * Fills up only the SSID field of configs and uses it as a configKey as well. 412 */ 413 @Test 414 public void testLoadNetworksRemovesDuplicates() throws Exception { 415 // Network ID which will have the same config key as the previous one. 416 final int duplicateNetworkId = 2; 417 final int toRemoveNetworkId = duplicateNetworkId - 1; 418 executeAndValidateInitializationSequence(); 419 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 420 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 421 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 422 } 423 }).when(mISupplicantStaIfaceMock) 424 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 425 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 426 public SupplicantStatus answer(int id) { 427 return mStatusSuccess; 428 } 429 }).when(mISupplicantStaIfaceMock).removeNetwork(eq(toRemoveNetworkId)); 430 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 431 public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) { 432 // Reset the |mSupplicantStaNetwork| mock for each network. 433 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 434 public boolean answer( 435 WifiConfiguration config, Map<String, String> networkExtra) { 436 config.SSID = NETWORK_ID_TO_SSID.get(networkId); 437 config.networkId = networkId; 438 // Duplicate network gets the same config key as the to removed one. 439 if (networkId == duplicateNetworkId) { 440 networkExtra.put( 441 SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY, 442 NETWORK_ID_TO_SSID.get(toRemoveNetworkId)); 443 } else { 444 networkExtra.put( 445 SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY, 446 NETWORK_ID_TO_SSID.get(networkId)); 447 } 448 return true; 449 } 450 }).when(mSupplicantStaNetworkMock) 451 .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class)); 452 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class)); 453 return; 454 } 455 }).when(mISupplicantStaIfaceMock) 456 .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class)); 457 458 Map<String, WifiConfiguration> configs = new HashMap<>(); 459 SparseArray<Map<String, String>> extras = new SparseArray<>(); 460 assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 461 462 assertEquals(2, configs.size()); 463 assertEquals(2, extras.size()); 464 for (Map.Entry<Integer, String> network : NETWORK_ID_TO_SSID.entrySet()) { 465 if (network.getKey() == toRemoveNetworkId) { 466 continue; 467 } 468 WifiConfiguration config; 469 // Duplicate network gets the same config key as the to removed one. So, use that to 470 // lookup the map. 471 if (network.getKey() == duplicateNetworkId) { 472 config = configs.get(NETWORK_ID_TO_SSID.get(toRemoveNetworkId)); 473 } else { 474 config = configs.get(network.getValue()); 475 } 476 assertTrue(config != null); 477 assertEquals(network.getKey(), Integer.valueOf(config.networkId)); 478 assertEquals(network.getValue(), config.SSID); 479 assertEquals(IpConfiguration.IpAssignment.DHCP, config.getIpAssignment()); 480 assertEquals(IpConfiguration.ProxySettings.NONE, config.getProxySettings()); 481 } 482 } 483 484 /** 485 * Tests the failure to load networks because of listNetworks failure. 486 */ 487 @Test 488 public void testLoadNetworksFailedDueToListNetworks() throws Exception { 489 executeAndValidateInitializationSequence(); 490 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 491 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 492 cb.onValues(mStatusFailure, null); 493 } 494 }).when(mISupplicantStaIfaceMock) 495 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 496 497 Map<String, WifiConfiguration> configs = new HashMap<>(); 498 SparseArray<Map<String, String>> extras = new SparseArray<>(); 499 assertFalse(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 500 } 501 502 /** 503 * Tests the failure to load networks because of getNetwork failure. 504 */ 505 @Test 506 public void testLoadNetworksFailedDueToGetNetwork() throws Exception { 507 executeAndValidateInitializationSequence(); 508 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 509 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 510 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 511 } 512 }).when(mISupplicantStaIfaceMock) 513 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 514 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 515 public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) { 516 cb.onValues(mStatusFailure, mock(ISupplicantStaNetwork.class)); 517 return; 518 } 519 }).when(mISupplicantStaIfaceMock) 520 .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class)); 521 522 Map<String, WifiConfiguration> configs = new HashMap<>(); 523 SparseArray<Map<String, String>> extras = new SparseArray<>(); 524 assertFalse(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 525 } 526 527 /** 528 * Tests the failure to load networks because of loadWifiConfiguration failure. 529 */ 530 @Test 531 public void testLoadNetworksFailedDueToLoadWifiConfiguration() throws Exception { 532 executeAndValidateInitializationSequence(); 533 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 534 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 535 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 536 } 537 }).when(mISupplicantStaIfaceMock) 538 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 539 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 540 public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) { 541 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class)); 542 return; 543 } 544 }).when(mISupplicantStaIfaceMock) 545 .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class)); 546 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 547 public boolean answer(WifiConfiguration config, Map<String, String> networkExtra) { 548 return false; 549 } 550 }).when(mSupplicantStaNetworkMock) 551 .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class)); 552 553 Map<String, WifiConfiguration> configs = new HashMap<>(); 554 SparseArray<Map<String, String>> extras = new SparseArray<>(); 555 assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 556 assertTrue(configs.isEmpty()); 557 } 558 559 /** 560 * Tests the failure to load networks because of loadWifiConfiguration exception. 561 */ 562 @Test 563 public void testLoadNetworksFailedDueToExceptionInLoadWifiConfiguration() throws Exception { 564 executeAndValidateInitializationSequence(); 565 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 566 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 567 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 568 } 569 }).when(mISupplicantStaIfaceMock) 570 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 571 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 572 public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) { 573 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class)); 574 return; 575 } 576 }).when(mISupplicantStaIfaceMock) 577 .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class)); 578 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 579 public boolean answer(WifiConfiguration config, Map<String, String> networkExtra) 580 throws Exception { 581 throw new IllegalArgumentException(); 582 } 583 }).when(mSupplicantStaNetworkMock) 584 .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class)); 585 586 Map<String, WifiConfiguration> configs = new HashMap<>(); 587 SparseArray<Map<String, String>> extras = new SparseArray<>(); 588 assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras)); 589 assertTrue(configs.isEmpty()); 590 } 591 592 /** 593 * Tests connection to a specified network with empty existing network. 594 */ 595 @Test 596 public void testConnectWithEmptyExistingNetwork() throws Exception { 597 executeAndValidateInitializationSequence(); 598 executeAndValidateConnectSequence(0, false); 599 } 600 601 @Test 602 public void testConnectToNetworkWithDifferentConfigReplacesNetworkInSupplicant() 603 throws Exception { 604 executeAndValidateInitializationSequence(); 605 WifiConfiguration config = executeAndValidateConnectSequence( 606 SUPPLICANT_NETWORK_ID, false); 607 // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection. 608 reset(mISupplicantStaIfaceMock); 609 setupMocksForConnectSequence(true /*haveExistingNetwork*/); 610 // Make this network different by changing SSID. 611 config.SSID = "AnDifferentSSID"; 612 assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config)); 613 verify(mISupplicantStaIfaceMock).removeNetwork(SUPPLICANT_NETWORK_ID); 614 verify(mISupplicantStaIfaceMock) 615 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class)); 616 } 617 618 @Test 619 public void connectToNetworkWithSameNetworkDoesNotRemoveNetworkFromSupplicant() 620 throws Exception { 621 executeAndValidateInitializationSequence(); 622 WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false); 623 // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection. 624 reset(mISupplicantStaIfaceMock); 625 setupMocksForConnectSequence(true /*haveExistingNetwork*/); 626 assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config)); 627 verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt()); 628 verify(mISupplicantStaIfaceMock, never()) 629 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class)); 630 } 631 632 @Test 633 public void connectToNetworkWithSameNetworkButDifferentBssidUpdatesNetworkFromSupplicant() 634 throws Exception { 635 executeAndValidateInitializationSequence(); 636 WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false); 637 String testBssid = "11:22:33:44:55:66"; 638 when(mSupplicantStaNetworkMock.setBssid(eq(testBssid))).thenReturn(true); 639 640 // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection. 641 reset(mISupplicantStaIfaceMock); 642 setupMocksForConnectSequence(true /*haveExistingNetwork*/); 643 // Change the BSSID and connect to the same network. 644 assertFalse(TextUtils.equals( 645 testBssid, config.getNetworkSelectionStatus().getNetworkSelectionBSSID())); 646 config.getNetworkSelectionStatus().setNetworkSelectionBSSID(testBssid); 647 assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config)); 648 verify(mSupplicantStaNetworkMock).setBssid(eq(testBssid)); 649 verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt()); 650 verify(mISupplicantStaIfaceMock, never()) 651 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class)); 652 } 653 654 /** 655 * Tests connection to a specified network failure due to network add. 656 */ 657 @Test 658 public void testConnectFailureDueToNetworkAddFailure() throws Exception { 659 executeAndValidateInitializationSequence(); 660 setupMocksForConnectSequence(false); 661 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 662 public void answer(ISupplicantStaIface.addNetworkCallback cb) throws RemoteException { 663 cb.onValues(mStatusFailure, mock(ISupplicantStaNetwork.class)); 664 return; 665 } 666 }).when(mISupplicantStaIfaceMock).addNetwork( 667 any(ISupplicantStaIface.addNetworkCallback.class)); 668 669 assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration())); 670 } 671 672 /** 673 * Tests connection to a specified network failure due to network save. 674 */ 675 @Test 676 public void testConnectFailureDueToNetworkSaveFailure() throws Exception { 677 executeAndValidateInitializationSequence(); 678 setupMocksForConnectSequence(true); 679 680 when(mSupplicantStaNetworkMock.saveWifiConfiguration(any(WifiConfiguration.class))) 681 .thenReturn(false); 682 683 assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration())); 684 // We should have removed the existing network once before connection and once more 685 // on failure to save network configuration. 686 verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt()); 687 } 688 689 /** 690 * Tests connection to a specified network failure due to exception in network save. 691 */ 692 @Test 693 public void testConnectFailureDueToNetworkSaveException() throws Exception { 694 executeAndValidateInitializationSequence(); 695 setupMocksForConnectSequence(true); 696 697 doThrow(new IllegalArgumentException("Some error!!!")) 698 .when(mSupplicantStaNetworkMock).saveWifiConfiguration( 699 any(WifiConfiguration.class)); 700 701 assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration())); 702 // We should have removed the existing network once before connection and once more 703 // on failure to save network configuration. 704 verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt()); 705 } 706 707 /** 708 * Tests connection to a specified network failure due to network select. 709 */ 710 @Test 711 public void testConnectFailureDueToNetworkSelectFailure() throws Exception { 712 executeAndValidateInitializationSequence(); 713 setupMocksForConnectSequence(false); 714 715 when(mSupplicantStaNetworkMock.select()).thenReturn(false); 716 717 assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration())); 718 } 719 720 /** 721 * Tests roaming to the same network as the currently connected one. 722 */ 723 @Test 724 public void testRoamToSameNetwork() throws Exception { 725 executeAndValidateInitializationSequence(); 726 executeAndValidateRoamSequence(true); 727 assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration())); 728 } 729 730 /** 731 * Tests roaming to a different network. 732 */ 733 @Test 734 public void testRoamToDifferentNetwork() throws Exception { 735 executeAndValidateInitializationSequence(); 736 executeAndValidateRoamSequence(false); 737 } 738 739 /** 740 * Tests roaming failure because of unable to set bssid. 741 */ 742 @Test 743 public void testRoamFailureDueToBssidSet() throws Exception { 744 executeAndValidateInitializationSequence(); 745 int connectedNetworkId = 5; 746 executeAndValidateConnectSequence(connectedNetworkId, false); 747 when(mSupplicantStaNetworkMock.setBssid(anyString())).thenReturn(false); 748 749 WifiConfiguration roamingConfig = new WifiConfiguration(); 750 roamingConfig.networkId = connectedNetworkId; 751 roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID("45:34:23:23:ab:ed"); 752 assertFalse(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig)); 753 } 754 755 /** 756 * Tests removal of all configured networks from wpa_supplicant. 757 */ 758 @Test 759 public void testRemoveAllNetworks() throws Exception { 760 executeAndValidateInitializationSequence(); 761 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 762 public void answer(ISupplicantStaIface.listNetworksCallback cb) { 763 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet())); 764 } 765 }).when(mISupplicantStaIfaceMock) 766 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 767 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 768 public SupplicantStatus answer(int id) { 769 assertTrue(NETWORK_ID_TO_SSID.containsKey(id)); 770 return mStatusSuccess; 771 } 772 }).when(mISupplicantStaIfaceMock).removeNetwork(anyInt()); 773 774 assertTrue(mDut.removeAllNetworks(WLAN0_IFACE_NAME)); 775 verify(mISupplicantStaIfaceMock, times(NETWORK_ID_TO_SSID.size())).removeNetwork(anyInt()); 776 } 777 778 /** 779 * Remove all networks while connected, verify that the current network info is resetted. 780 */ 781 @Test 782 public void testRemoveAllNetworksWhileConnected() throws Exception { 783 String testBssid = "11:22:33:44:55:66"; 784 when(mSupplicantStaNetworkMock.setBssid(eq(testBssid))).thenReturn(true); 785 786 executeAndValidateInitializationSequence(); 787 788 // Connect to a network and verify current network is set. 789 executeAndValidateConnectSequence(4, false); 790 assertTrue(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, testBssid)); 791 verify(mSupplicantStaNetworkMock).setBssid(eq(testBssid)); 792 reset(mSupplicantStaNetworkMock); 793 794 // Remove all networks and verify current network info is resetted. 795 assertTrue(mDut.removeAllNetworks(WLAN0_IFACE_NAME)); 796 assertFalse(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, testBssid)); 797 verify(mSupplicantStaNetworkMock, never()).setBssid(eq(testBssid)); 798 } 799 800 /** 801 * Tests roaming failure because of unable to reassociate. 802 */ 803 @Test 804 public void testRoamFailureDueToReassociate() throws Exception { 805 executeAndValidateInitializationSequence(); 806 int connectedNetworkId = 5; 807 executeAndValidateConnectSequence(connectedNetworkId, false); 808 809 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 810 public SupplicantStatus answer() throws RemoteException { 811 return mStatusFailure; 812 } 813 }).when(mISupplicantStaIfaceMock).reassociate(); 814 when(mSupplicantStaNetworkMock.setBssid(anyString())).thenReturn(true); 815 816 WifiConfiguration roamingConfig = new WifiConfiguration(); 817 roamingConfig.networkId = connectedNetworkId; 818 roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID("45:34:23:23:ab:ed"); 819 assertFalse(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig)); 820 } 821 822 /** 823 * Tests the retrieval of WPS NFC token. 824 */ 825 @Test 826 public void testGetCurrentNetworkWpsNfcConfigurationToken() throws Exception { 827 String token = "45adbc1"; 828 when(mSupplicantStaNetworkMock.getWpsNfcConfigurationToken()).thenReturn(token); 829 830 executeAndValidateInitializationSequence(); 831 // Return null when not connected to the network. 832 assertTrue(mDut.getCurrentNetworkWpsNfcConfigurationToken(WLAN0_IFACE_NAME) == null); 833 verify(mSupplicantStaNetworkMock, never()).getWpsNfcConfigurationToken(); 834 executeAndValidateConnectSequence(4, false); 835 assertEquals(token, mDut.getCurrentNetworkWpsNfcConfigurationToken(WLAN0_IFACE_NAME)); 836 verify(mSupplicantStaNetworkMock).getWpsNfcConfigurationToken(); 837 } 838 839 /** 840 * Tests the setting of BSSID. 841 */ 842 @Test 843 public void testSetCurrentNetworkBssid() throws Exception { 844 String bssidStr = "34:34:12:12:12:90"; 845 when(mSupplicantStaNetworkMock.setBssid(eq(bssidStr))).thenReturn(true); 846 847 executeAndValidateInitializationSequence(); 848 // Fail when not connected to a network. 849 assertFalse(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, bssidStr)); 850 verify(mSupplicantStaNetworkMock, never()).setBssid(eq(bssidStr)); 851 executeAndValidateConnectSequence(4, false); 852 assertTrue(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, bssidStr)); 853 verify(mSupplicantStaNetworkMock).setBssid(eq(bssidStr)); 854 } 855 856 /** 857 * Tests the sending identity response for the current network. 858 */ 859 @Test 860 public void testSetCurrentNetworkEapIdentityResponse() throws Exception { 861 String identity = "blah@blah.com"; 862 String encryptedIdentity = "blah2@blah.com"; 863 when(mSupplicantStaNetworkMock.sendNetworkEapIdentityResponse(eq(identity), 864 eq(encryptedIdentity))) 865 .thenReturn(true); 866 867 executeAndValidateInitializationSequence(); 868 // Fail when not connected to a network. 869 assertFalse(mDut.sendCurrentNetworkEapIdentityResponse(WLAN0_IFACE_NAME, identity, 870 encryptedIdentity)); 871 verify(mSupplicantStaNetworkMock, never()).sendNetworkEapIdentityResponse(eq(identity), 872 eq(encryptedIdentity)); 873 executeAndValidateConnectSequence(4, false); 874 assertTrue(mDut.sendCurrentNetworkEapIdentityResponse(WLAN0_IFACE_NAME, identity, 875 encryptedIdentity)); 876 verify(mSupplicantStaNetworkMock).sendNetworkEapIdentityResponse(eq(identity), 877 eq(encryptedIdentity)); 878 } 879 880 /** 881 * Tests the getting of anonymous identity for the current network. 882 */ 883 @Test 884 public void testGetCurrentNetworkEapAnonymousIdentity() throws Exception { 885 String anonymousIdentity = "aaa@bbb.ccc"; 886 when(mSupplicantStaNetworkMock.fetchEapAnonymousIdentity()) 887 .thenReturn(anonymousIdentity); 888 executeAndValidateInitializationSequence(); 889 890 // Return null when not connected to the network. 891 assertEquals(null, mDut.getCurrentNetworkEapAnonymousIdentity(WLAN0_IFACE_NAME)); 892 executeAndValidateConnectSequence(4, false); 893 // Return anonymous identity for the current network. 894 assertEquals( 895 anonymousIdentity, mDut.getCurrentNetworkEapAnonymousIdentity(WLAN0_IFACE_NAME)); 896 } 897 898 /** 899 * Tests the sending gsm auth response for the current network. 900 */ 901 @Test 902 public void testSetCurrentNetworkEapSimGsmAuthResponse() throws Exception { 903 String params = "test"; 904 when(mSupplicantStaNetworkMock.sendNetworkEapSimGsmAuthResponse(eq(params))) 905 .thenReturn(true); 906 907 executeAndValidateInitializationSequence(); 908 // Fail when not connected to a network. 909 assertFalse(mDut.sendCurrentNetworkEapSimGsmAuthResponse(WLAN0_IFACE_NAME, params)); 910 verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimGsmAuthResponse(eq(params)); 911 executeAndValidateConnectSequence(4, false); 912 assertTrue(mDut.sendCurrentNetworkEapSimGsmAuthResponse(WLAN0_IFACE_NAME, params)); 913 verify(mSupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(eq(params)); 914 } 915 916 /** 917 * Tests the sending umts auth response for the current network. 918 */ 919 @Test 920 public void testSetCurrentNetworkEapSimUmtsAuthResponse() throws Exception { 921 String params = "test"; 922 when(mSupplicantStaNetworkMock.sendNetworkEapSimUmtsAuthResponse(eq(params))) 923 .thenReturn(true); 924 925 executeAndValidateInitializationSequence(); 926 // Fail when not connected to a network. 927 assertFalse(mDut.sendCurrentNetworkEapSimUmtsAuthResponse(WLAN0_IFACE_NAME, params)); 928 verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimUmtsAuthResponse(eq(params)); 929 executeAndValidateConnectSequence(4, false); 930 assertTrue(mDut.sendCurrentNetworkEapSimUmtsAuthResponse(WLAN0_IFACE_NAME, params)); 931 verify(mSupplicantStaNetworkMock).sendNetworkEapSimUmtsAuthResponse(eq(params)); 932 } 933 934 /** 935 * Tests the sending umts auts response for the current network. 936 */ 937 @Test 938 public void testSetCurrentNetworkEapSimUmtsAutsResponse() throws Exception { 939 String params = "test"; 940 when(mSupplicantStaNetworkMock.sendNetworkEapSimUmtsAutsResponse(eq(params))) 941 .thenReturn(true); 942 943 executeAndValidateInitializationSequence(); 944 // Fail when not connected to a network. 945 assertFalse(mDut.sendCurrentNetworkEapSimUmtsAutsResponse(WLAN0_IFACE_NAME, params)); 946 verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimUmtsAutsResponse(eq(params)); 947 executeAndValidateConnectSequence(4, false); 948 assertTrue(mDut.sendCurrentNetworkEapSimUmtsAutsResponse(WLAN0_IFACE_NAME, params)); 949 verify(mSupplicantStaNetworkMock).sendNetworkEapSimUmtsAutsResponse(eq(params)); 950 } 951 952 /** 953 * Tests the setting of WPS device type. 954 */ 955 @Test 956 public void testSetWpsDeviceType() throws Exception { 957 String validDeviceTypeStr = "10-0050F204-5"; 958 byte[] expectedDeviceType = { 0x0, 0xa, 0x0, 0x50, (byte) 0xf2, 0x04, 0x0, 0x05}; 959 String invalidDeviceType1Str = "10-02050F204-5"; 960 String invalidDeviceType2Str = "10-0050F204-534"; 961 when(mISupplicantStaIfaceMock.setWpsDeviceType(any(byte[].class))) 962 .thenReturn(mStatusSuccess); 963 964 executeAndValidateInitializationSequence(); 965 966 // This should work. 967 assertTrue(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, validDeviceTypeStr)); 968 verify(mISupplicantStaIfaceMock).setWpsDeviceType(eq(expectedDeviceType)); 969 970 // This should not work 971 assertFalse(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, invalidDeviceType1Str)); 972 // This should not work 973 assertFalse(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, invalidDeviceType2Str)); 974 } 975 976 /** 977 * Tests the setting of WPS config methods. 978 */ 979 @Test 980 public void testSetWpsConfigMethods() throws Exception { 981 String validConfigMethodsStr = "physical_display virtual_push_button"; 982 Short expectedConfigMethods = 983 WpsConfigMethods.PHY_DISPLAY | WpsConfigMethods.VIRT_PUSHBUTTON; 984 String invalidConfigMethodsStr = "physical_display virtual_push_button test"; 985 when(mISupplicantStaIfaceMock.setWpsConfigMethods(anyShort())).thenReturn(mStatusSuccess); 986 987 executeAndValidateInitializationSequence(); 988 989 // This should work. 990 assertTrue(mDut.setWpsConfigMethods(WLAN0_IFACE_NAME, validConfigMethodsStr)); 991 verify(mISupplicantStaIfaceMock).setWpsConfigMethods(eq(expectedConfigMethods)); 992 993 // This should throw an illegal argument exception. 994 try { 995 assertFalse(mDut.setWpsConfigMethods(WLAN0_IFACE_NAME, invalidConfigMethodsStr)); 996 } catch (IllegalArgumentException e) { 997 return; 998 } 999 assertTrue(false); 1000 } 1001 1002 /** 1003 * Tests the handling of ANQP done callback. 1004 * Note: Since the ANQP element parsing methods are static, this can only test the negative test 1005 * where all the parsing fails because the data is empty. It'll be non-trivial and unnecessary 1006 * to test out the parsing logic here. 1007 */ 1008 @Test 1009 public void testAnqpDoneCallback() throws Exception { 1010 executeAndValidateInitializationSequence(); 1011 assertNotNull(mISupplicantStaIfaceCallback); 1012 byte[] bssid = NativeUtil.macAddressToByteArray(BSSID); 1013 mISupplicantStaIfaceCallback.onAnqpQueryDone( 1014 bssid, new ISupplicantStaIfaceCallback.AnqpData(), 1015 new ISupplicantStaIfaceCallback.Hs20AnqpData()); 1016 1017 ArgumentCaptor<AnqpEvent> anqpEventCaptor = ArgumentCaptor.forClass(AnqpEvent.class); 1018 verify(mWifiMonitor).broadcastAnqpDoneEvent( 1019 eq(WLAN0_IFACE_NAME), anqpEventCaptor.capture()); 1020 assertEquals( 1021 ByteBufferReader.readInteger( 1022 ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length), 1023 anqpEventCaptor.getValue().getBssid()); 1024 } 1025 1026 /** 1027 * Tests the handling of Icon done callback. 1028 */ 1029 @Test 1030 public void testIconDoneCallback() throws Exception { 1031 executeAndValidateInitializationSequence(); 1032 assertNotNull(mISupplicantStaIfaceCallback); 1033 1034 byte[] bssid = NativeUtil.macAddressToByteArray(BSSID); 1035 byte[] iconData = new byte[ICON_FILE_SIZE]; 1036 new Random().nextBytes(iconData); 1037 mISupplicantStaIfaceCallback.onHs20IconQueryDone( 1038 bssid, ICON_FILE_NAME, NativeUtil.byteArrayToArrayList(iconData)); 1039 1040 ArgumentCaptor<IconEvent> iconEventCaptor = ArgumentCaptor.forClass(IconEvent.class); 1041 verify(mWifiMonitor).broadcastIconDoneEvent( 1042 eq(WLAN0_IFACE_NAME), iconEventCaptor.capture()); 1043 assertEquals( 1044 ByteBufferReader.readInteger( 1045 ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length), 1046 iconEventCaptor.getValue().getBSSID()); 1047 assertEquals(ICON_FILE_NAME, iconEventCaptor.getValue().getFileName()); 1048 assertArrayEquals(iconData, iconEventCaptor.getValue().getData()); 1049 } 1050 1051 /** 1052 * Tests the handling of HS20 subscription remediation callback. 1053 */ 1054 @Test 1055 public void testHs20SubscriptionRemediationCallback() throws Exception { 1056 executeAndValidateInitializationSequence(); 1057 assertNotNull(mISupplicantStaIfaceCallback); 1058 1059 byte[] bssid = NativeUtil.macAddressToByteArray(BSSID); 1060 byte osuMethod = ISupplicantStaIfaceCallback.OsuMethod.OMA_DM; 1061 mISupplicantStaIfaceCallback.onHs20SubscriptionRemediation( 1062 bssid, osuMethod, HS20_URL); 1063 1064 ArgumentCaptor<WnmData> wnmDataCaptor = ArgumentCaptor.forClass(WnmData.class); 1065 verify(mWifiMonitor).broadcastWnmEvent(eq(WLAN0_IFACE_NAME), wnmDataCaptor.capture()); 1066 assertEquals( 1067 ByteBufferReader.readInteger( 1068 ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length), 1069 wnmDataCaptor.getValue().getBssid()); 1070 assertEquals(osuMethod, wnmDataCaptor.getValue().getMethod()); 1071 assertEquals(HS20_URL, wnmDataCaptor.getValue().getUrl()); 1072 } 1073 1074 /** 1075 * Tests the handling of HS20 deauth imminent callback. 1076 */ 1077 @Test 1078 public void testHs20DeauthImminentCallbackWithEssReasonCode() throws Exception { 1079 executeAndValidateHs20DeauthImminentCallback(true); 1080 } 1081 1082 /** 1083 * Tests the handling of HS20 deauth imminent callback. 1084 */ 1085 @Test 1086 public void testHs20DeauthImminentCallbackWithNonEssReasonCode() throws Exception { 1087 executeAndValidateHs20DeauthImminentCallback(false); 1088 1089 } 1090 1091 /** 1092 * Tests the handling of state change notification without any configured network. 1093 */ 1094 @Test 1095 public void testStateChangeCallbackWithNoConfiguredNetwork() throws Exception { 1096 executeAndValidateInitializationSequence(); 1097 assertNotNull(mISupplicantStaIfaceCallback); 1098 1099 mISupplicantStaIfaceCallback.onStateChanged( 1100 ISupplicantStaIfaceCallback.State.INACTIVE, 1101 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID, 1102 NativeUtil.decodeSsid(SUPPLICANT_SSID)); 1103 1104 // Can't compare WifiSsid instances because they lack an equals. 1105 verify(mWifiMonitor).broadcastSupplicantStateChangeEvent( 1106 eq(WLAN0_IFACE_NAME), eq(WifiConfiguration.INVALID_NETWORK_ID), 1107 any(WifiSsid.class), eq(BSSID), eq(SupplicantState.INACTIVE)); 1108 } 1109 1110 /** 1111 * Tests the handling of state change notification to associated after configuring a network. 1112 */ 1113 @Test 1114 public void testStateChangeToAssociatedCallback() throws Exception { 1115 executeAndValidateInitializationSequence(); 1116 int frameworkNetworkId = 6; 1117 executeAndValidateConnectSequence(frameworkNetworkId, false); 1118 assertNotNull(mISupplicantStaIfaceCallback); 1119 1120 mISupplicantStaIfaceCallback.onStateChanged( 1121 ISupplicantStaIfaceCallback.State.ASSOCIATED, 1122 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID, 1123 NativeUtil.decodeSsid(SUPPLICANT_SSID)); 1124 1125 verify(mWifiMonitor).broadcastSupplicantStateChangeEvent( 1126 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), 1127 any(WifiSsid.class), eq(BSSID), eq(SupplicantState.ASSOCIATED)); 1128 } 1129 1130 /** 1131 * Tests the handling of state change notification to completed after configuring a network. 1132 */ 1133 @Test 1134 public void testStateChangeToCompletedCallback() throws Exception { 1135 InOrder wifiMonitorInOrder = inOrder(mWifiMonitor); 1136 executeAndValidateInitializationSequence(); 1137 int frameworkNetworkId = 6; 1138 executeAndValidateConnectSequence(frameworkNetworkId, false); 1139 assertNotNull(mISupplicantStaIfaceCallback); 1140 1141 mISupplicantStaIfaceCallback.onStateChanged( 1142 ISupplicantStaIfaceCallback.State.COMPLETED, 1143 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID, 1144 NativeUtil.decodeSsid(SUPPLICANT_SSID)); 1145 1146 wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent( 1147 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(BSSID)); 1148 wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent( 1149 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), 1150 any(WifiSsid.class), eq(BSSID), eq(SupplicantState.COMPLETED)); 1151 } 1152 1153 /** 1154 * Tests the handling of network disconnected notification. 1155 */ 1156 @Test 1157 public void testDisconnectedCallback() throws Exception { 1158 executeAndValidateInitializationSequence(); 1159 assertNotNull(mISupplicantStaIfaceCallback); 1160 1161 int reasonCode = 5; 1162 mISupplicantStaIfaceCallback.onDisconnected( 1163 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); 1164 verify(mWifiMonitor).broadcastNetworkDisconnectionEvent( 1165 eq(WLAN0_IFACE_NAME), eq(1), eq(reasonCode), eq(BSSID)); 1166 1167 mISupplicantStaIfaceCallback.onDisconnected( 1168 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); 1169 verify(mWifiMonitor).broadcastNetworkDisconnectionEvent( 1170 eq(WLAN0_IFACE_NAME), eq(0), eq(reasonCode), eq(BSSID)); 1171 } 1172 1173 /** 1174 * Tests the handling of incorrect network passwords. 1175 */ 1176 @Test 1177 public void testAuthFailurePassword() throws Exception { 1178 executeAndValidateInitializationSequence(); 1179 assertNotNull(mISupplicantStaIfaceCallback); 1180 1181 int reasonCode = 3; 1182 mISupplicantStaIfaceCallback.onDisconnected( 1183 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); 1184 verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt()); 1185 1186 mISupplicantStaIfaceCallback.onDisconnected( 1187 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); 1188 verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt()); 1189 1190 mISupplicantStaIfaceCallback.onStateChanged( 1191 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE, 1192 NativeUtil.macAddressToByteArray(BSSID), 1193 SUPPLICANT_NETWORK_ID, 1194 NativeUtil.decodeSsid(SUPPLICANT_SSID)); 1195 mISupplicantStaIfaceCallback.onDisconnected( 1196 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); 1197 mISupplicantStaIfaceCallback.onDisconnected( 1198 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); 1199 1200 verify(mWifiMonitor, times(2)).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME), 1201 eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1)); 1202 } 1203 1204 /** 1205 * Tests the handling of incorrect network passwords, edge case. 1206 * 1207 * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch. 1208 */ 1209 @Test 1210 public void testIeDiffers() throws Exception { 1211 executeAndValidateInitializationSequence(); 1212 assertNotNull(mISupplicantStaIfaceCallback); 1213 1214 int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS; 1215 1216 mISupplicantStaIfaceCallback.onStateChanged( 1217 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE, 1218 NativeUtil.macAddressToByteArray(BSSID), 1219 SUPPLICANT_NETWORK_ID, 1220 NativeUtil.decodeSsid(SUPPLICANT_SSID)); 1221 mISupplicantStaIfaceCallback.onDisconnected( 1222 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode); 1223 verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(), 1224 anyInt()); 1225 } 1226 1227 /** 1228 * Tests the handling of eap failure during disconnect. 1229 */ 1230 @Test 1231 public void testEapFailure() throws Exception { 1232 executeAndValidateInitializationSequence(); 1233 assertNotNull(mISupplicantStaIfaceCallback); 1234 1235 int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IEEE_802_1X_AUTH_FAILED; 1236 mISupplicantStaIfaceCallback.onDisconnected( 1237 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode); 1238 verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(), 1239 anyInt()); 1240 } 1241 1242 /** 1243 * Tests the handling of association rejection notification. 1244 */ 1245 @Test 1246 public void testAssociationRejectionCallback() throws Exception { 1247 executeAndValidateInitializationSequence(); 1248 assertNotNull(mISupplicantStaIfaceCallback); 1249 1250 int statusCode = 7; 1251 mISupplicantStaIfaceCallback.onAssociationRejected( 1252 NativeUtil.macAddressToByteArray(BSSID), statusCode, false); 1253 verify(mWifiMonitor).broadcastAssociationRejectionEvent( 1254 eq(WLAN0_IFACE_NAME), eq(statusCode), eq(false), eq(BSSID)); 1255 } 1256 1257 /** 1258 * Tests the handling of authentification timeout notification. 1259 */ 1260 @Test 1261 public void testAuthenticationTimeoutCallback() throws Exception { 1262 executeAndValidateInitializationSequence(); 1263 assertNotNull(mISupplicantStaIfaceCallback); 1264 1265 mISupplicantStaIfaceCallback.onAuthenticationTimeout( 1266 NativeUtil.macAddressToByteArray(BSSID)); 1267 verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME), 1268 eq(WifiManager.ERROR_AUTH_FAILURE_TIMEOUT), eq(-1)); 1269 } 1270 1271 /** 1272 * Tests the handling of bssid change notification. 1273 */ 1274 @Test 1275 public void testBssidChangedCallback() throws Exception { 1276 executeAndValidateInitializationSequence(); 1277 assertNotNull(mISupplicantStaIfaceCallback); 1278 1279 mISupplicantStaIfaceCallback.onBssidChanged( 1280 BssidChangeReason.ASSOC_START, NativeUtil.macAddressToByteArray(BSSID)); 1281 verify(mWifiMonitor).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID)); 1282 verify(mWifiMonitor, never()).broadcastAssociatedBssidEvent( 1283 eq(WLAN0_IFACE_NAME), eq(BSSID)); 1284 1285 reset(mWifiMonitor); 1286 mISupplicantStaIfaceCallback.onBssidChanged( 1287 BssidChangeReason.ASSOC_COMPLETE, NativeUtil.macAddressToByteArray(BSSID)); 1288 verify(mWifiMonitor, never()).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID)); 1289 verify(mWifiMonitor).broadcastAssociatedBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID)); 1290 1291 reset(mWifiMonitor); 1292 mISupplicantStaIfaceCallback.onBssidChanged( 1293 BssidChangeReason.DISASSOC, NativeUtil.macAddressToByteArray(BSSID)); 1294 verify(mWifiMonitor, never()).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID)); 1295 verify(mWifiMonitor, never()).broadcastAssociatedBssidEvent( 1296 eq(WLAN0_IFACE_NAME), eq(BSSID)); 1297 } 1298 1299 /** 1300 * Tests the handling of EAP failure notification. 1301 */ 1302 @Test 1303 public void testEapFailureCallback() throws Exception { 1304 int eapFailureCode = WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED; 1305 testInitialize_successV1_1(); 1306 assertNotNull(mISupplicantStaIfaceCallbackV1_1); 1307 1308 mISupplicantStaIfaceCallbackV1_1.onEapFailure_1_1(eapFailureCode); 1309 verify(mWifiMonitor).broadcastAuthenticationFailureEvent( 1310 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE), 1311 eq(eapFailureCode)); 1312 } 1313 1314 /** 1315 * Tests the handling of Wps success notification. 1316 */ 1317 @Test 1318 public void testWpsSuccessCallback() throws Exception { 1319 executeAndValidateInitializationSequence(); 1320 assertNotNull(mISupplicantStaIfaceCallback); 1321 1322 mISupplicantStaIfaceCallback.onWpsEventSuccess(); 1323 verify(mWifiMonitor).broadcastWpsSuccessEvent(eq(WLAN0_IFACE_NAME)); 1324 } 1325 1326 /** 1327 * Tests the handling of Wps fail notification. 1328 */ 1329 @Test 1330 public void testWpsFailureCallback() throws Exception { 1331 executeAndValidateInitializationSequence(); 1332 assertNotNull(mISupplicantStaIfaceCallback); 1333 1334 short cfgError = ISupplicantStaIfaceCallback.WpsConfigError.MULTIPLE_PBC_DETECTED; 1335 short errorInd = ISupplicantStaIfaceCallback.WpsErrorIndication.SECURITY_WEP_PROHIBITED; 1336 mISupplicantStaIfaceCallback.onWpsEventFail( 1337 NativeUtil.macAddressToByteArray(BSSID), cfgError, errorInd); 1338 verify(mWifiMonitor).broadcastWpsFailEvent(eq(WLAN0_IFACE_NAME), 1339 eq((int) cfgError), eq((int) errorInd)); 1340 } 1341 1342 /** 1343 * Tests the handling of Wps fail notification. 1344 */ 1345 @Test 1346 public void testWpsTimeoutCallback() throws Exception { 1347 executeAndValidateInitializationSequence(); 1348 assertNotNull(mISupplicantStaIfaceCallback); 1349 1350 short cfgError = ISupplicantStaIfaceCallback.WpsConfigError.MSG_TIMEOUT; 1351 short errorInd = ISupplicantStaIfaceCallback.WpsErrorIndication.NO_ERROR; 1352 mISupplicantStaIfaceCallback.onWpsEventFail( 1353 NativeUtil.macAddressToByteArray(BSSID), cfgError, errorInd); 1354 verify(mWifiMonitor).broadcastWpsTimeoutEvent(eq(WLAN0_IFACE_NAME)); 1355 } 1356 1357 /** 1358 * Tests the handling of Wps pbc overlap notification. 1359 */ 1360 @Test 1361 public void testWpsPbcOverlapCallback() throws Exception { 1362 executeAndValidateInitializationSequence(); 1363 assertNotNull(mISupplicantStaIfaceCallback); 1364 1365 mISupplicantStaIfaceCallback.onWpsEventPbcOverlap(); 1366 verify(mWifiMonitor).broadcastWpsOverlapEvent(eq(WLAN0_IFACE_NAME)); 1367 } 1368 1369 /** 1370 * Tests the handling of service manager death notification. 1371 */ 1372 @Test 1373 public void testServiceManagerDeathCallback() throws Exception { 1374 executeAndValidateInitializationSequence(); 1375 assertNotNull(mServiceManagerDeathCaptor.getValue()); 1376 assertTrue(mDut.isInitializationComplete()); 1377 assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler)); 1378 1379 mServiceManagerDeathCaptor.getValue().serviceDied(5L); 1380 1381 assertFalse(mDut.isInitializationComplete()); 1382 verify(mWifiMonitor).broadcastSupplicantDisconnectionEvent(eq(WLAN0_IFACE_NAME)); 1383 verify(mSupplicantHalDeathHandler).onDeath(); 1384 } 1385 1386 /** 1387 * Tests the handling of supplicant death notification. 1388 */ 1389 @Test 1390 public void testSupplicantDeathCallback() throws Exception { 1391 executeAndValidateInitializationSequence(); 1392 assertNotNull(mSupplicantDeathCaptor.getValue()); 1393 assertTrue(mDut.isInitializationComplete()); 1394 assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler)); 1395 1396 mSupplicantDeathCaptor.getValue().serviceDied(5L); 1397 1398 assertFalse(mDut.isInitializationComplete()); 1399 verify(mWifiMonitor).broadcastSupplicantDisconnectionEvent(eq(WLAN0_IFACE_NAME)); 1400 verify(mSupplicantHalDeathHandler).onDeath(); 1401 } 1402 1403 /** 1404 * When wpa_supplicant is dead, we could end up getting a remote exception on a hwbinder call 1405 * and then the death notification. 1406 */ 1407 @Test 1408 public void testHandleRemoteExceptonAndDeathNotification() throws Exception { 1409 executeAndValidateInitializationSequence(); 1410 assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler)); 1411 assertTrue(mDut.isInitializationComplete()); 1412 1413 // Throw remote exception on hwbinder call. 1414 when(mISupplicantStaIfaceMock.setPowerSave(anyBoolean())) 1415 .thenThrow(new RemoteException()); 1416 assertFalse(mDut.setPowerSave(WLAN0_IFACE_NAME, true)); 1417 verify(mISupplicantStaIfaceMock).setPowerSave(true); 1418 1419 // Check that remote exception cleared all internal state. 1420 assertFalse(mDut.isInitializationComplete()); 1421 1422 // Ensure that futher calls fail because the remote exception clears any state. 1423 assertFalse(mDut.setPowerSave(WLAN0_IFACE_NAME, true)); 1424 //.. No call to ISupplicantStaIface object 1425 1426 // Now trigger a death notification and ensure it's handled. 1427 assertNotNull(mSupplicantDeathCaptor.getValue()); 1428 mSupplicantDeathCaptor.getValue().serviceDied(5L); 1429 1430 // External death notification fires only once! 1431 verify(mSupplicantHalDeathHandler).onDeath(); 1432 } 1433 1434 /** 1435 * Tests the setting of log level. 1436 */ 1437 @Test 1438 public void testSetLogLevel() throws Exception { 1439 when(mISupplicantMock.setDebugParams(anyInt(), anyBoolean(), anyBoolean())) 1440 .thenReturn(mStatusSuccess); 1441 1442 // Fail before initialization is performed. 1443 assertFalse(mDut.setLogLevel(true)); 1444 1445 executeAndValidateInitializationSequence(); 1446 1447 // This should work. 1448 assertTrue(mDut.setLogLevel(true)); 1449 verify(mISupplicantMock) 1450 .setDebugParams(eq(ISupplicant.DebugLevel.DEBUG), eq(false), eq(false)); 1451 } 1452 1453 /** 1454 * Tests the setting of concurrency priority. 1455 */ 1456 @Test 1457 public void testConcurrencyPriority() throws Exception { 1458 when(mISupplicantMock.setConcurrencyPriority(anyInt())).thenReturn(mStatusSuccess); 1459 1460 // Fail before initialization is performed. 1461 assertFalse(mDut.setConcurrencyPriority(false)); 1462 1463 executeAndValidateInitializationSequence(); 1464 1465 // This should work. 1466 assertTrue(mDut.setConcurrencyPriority(false)); 1467 verify(mISupplicantMock).setConcurrencyPriority(eq(IfaceType.P2P)); 1468 assertTrue(mDut.setConcurrencyPriority(true)); 1469 verify(mISupplicantMock).setConcurrencyPriority(eq(IfaceType.STA)); 1470 } 1471 1472 /** 1473 * Tests the start of wps registrar. 1474 */ 1475 @Test 1476 public void testStartWpsRegistrar() throws Exception { 1477 when(mISupplicantStaIfaceMock.startWpsRegistrar(any(byte[].class), anyString())) 1478 .thenReturn(mStatusSuccess); 1479 1480 // Fail before initialization is performed. 1481 assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, null, null)); 1482 1483 executeAndValidateInitializationSequence(); 1484 1485 assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, null, null)); 1486 verify(mISupplicantStaIfaceMock, never()).startWpsRegistrar(any(byte[].class), anyString()); 1487 1488 assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, new String(), "452233")); 1489 verify(mISupplicantStaIfaceMock, never()).startWpsRegistrar(any(byte[].class), anyString()); 1490 1491 assertTrue(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, "45:23:12:12:12:98", "562535")); 1492 verify(mISupplicantStaIfaceMock).startWpsRegistrar(any(byte[].class), anyString()); 1493 } 1494 1495 /** 1496 * Tests the start of wps PBC. 1497 */ 1498 @Test 1499 public void testStartWpsPbc() throws Exception { 1500 when(mISupplicantStaIfaceMock.startWpsPbc(any(byte[].class))).thenReturn(mStatusSuccess); 1501 String bssid = "45:23:12:12:12:98"; 1502 byte[] bssidBytes = {0x45, 0x23, 0x12, 0x12, 0x12, (byte) 0x98}; 1503 byte[] anyBssidBytes = {0, 0, 0, 0, 0, 0}; 1504 1505 // Fail before initialization is performed. 1506 assertFalse(mDut.startWpsPbc(WLAN0_IFACE_NAME, bssid)); 1507 verify(mISupplicantStaIfaceMock, never()).startWpsPbc(any(byte[].class)); 1508 1509 executeAndValidateInitializationSequence(); 1510 1511 assertTrue(mDut.startWpsPbc(WLAN0_IFACE_NAME, bssid)); 1512 verify(mISupplicantStaIfaceMock).startWpsPbc(eq(bssidBytes)); 1513 1514 assertTrue(mDut.startWpsPbc(WLAN0_IFACE_NAME, null)); 1515 verify(mISupplicantStaIfaceMock).startWpsPbc(eq(anyBssidBytes)); 1516 } 1517 1518 private WifiConfiguration createTestWifiConfiguration() { 1519 WifiConfiguration config = new WifiConfiguration(); 1520 config.networkId = SUPPLICANT_NETWORK_ID; 1521 return config; 1522 } 1523 1524 private void executeAndValidateHs20DeauthImminentCallback(boolean isEss) throws Exception { 1525 executeAndValidateInitializationSequence(); 1526 assertNotNull(mISupplicantStaIfaceCallback); 1527 1528 byte[] bssid = NativeUtil.macAddressToByteArray(BSSID); 1529 int reasonCode = isEss ? WnmData.ESS : WnmData.ESS + 1; 1530 int reauthDelay = 5; 1531 mISupplicantStaIfaceCallback.onHs20DeauthImminentNotice( 1532 bssid, reasonCode, reauthDelay, HS20_URL); 1533 1534 ArgumentCaptor<WnmData> wnmDataCaptor = ArgumentCaptor.forClass(WnmData.class); 1535 verify(mWifiMonitor).broadcastWnmEvent(eq(WLAN0_IFACE_NAME), wnmDataCaptor.capture()); 1536 assertEquals( 1537 ByteBufferReader.readInteger( 1538 ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length), 1539 wnmDataCaptor.getValue().getBssid()); 1540 assertEquals(isEss, wnmDataCaptor.getValue().isEss()); 1541 assertEquals(reauthDelay, wnmDataCaptor.getValue().getDelay()); 1542 assertEquals(HS20_URL, wnmDataCaptor.getValue().getUrl()); 1543 } 1544 1545 private void executeAndValidateInitializationSequence() throws Exception { 1546 executeAndValidateInitializationSequence(false, false, false, false); 1547 } 1548 1549 /** 1550 * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the 1551 * expected result. Verifies if ISupplicantStaIface manager is initialized or reset. 1552 * Each of the arguments will cause a different failure mode when set true. 1553 */ 1554 private void executeAndValidateInitializationSequence(boolean causeRemoteException, 1555 boolean getZeroInterfaces, 1556 boolean getNullInterface, 1557 boolean causeCallbackRegFailure) 1558 throws Exception { 1559 boolean shouldSucceed = 1560 !causeRemoteException && !getZeroInterfaces && !getNullInterface 1561 && !causeCallbackRegFailure; 1562 // Setup callback mock answers 1563 ArrayList<ISupplicant.IfaceInfo> interfaces; 1564 if (getZeroInterfaces) { 1565 interfaces = new ArrayList<>(); 1566 } else { 1567 interfaces = mIfaceInfoList; 1568 } 1569 doAnswer(new GetListInterfacesAnswer(interfaces)).when(mISupplicantMock) 1570 .listInterfaces(any(ISupplicant.listInterfacesCallback.class)); 1571 if (causeRemoteException) { 1572 doThrow(new RemoteException("Some error!!!")) 1573 .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class), 1574 any(ISupplicant.getInterfaceCallback.class)); 1575 } else { 1576 doAnswer(new GetGetInterfaceAnswer(getNullInterface)) 1577 .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class), 1578 any(ISupplicant.getInterfaceCallback.class)); 1579 } 1580 /** Callback registeration */ 1581 if (causeCallbackRegFailure) { 1582 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1583 public SupplicantStatus answer(ISupplicantStaIfaceCallback cb) 1584 throws RemoteException { 1585 return mStatusFailure; 1586 } 1587 }).when(mISupplicantStaIfaceMock) 1588 .registerCallback(any(ISupplicantStaIfaceCallback.class)); 1589 } else { 1590 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1591 public SupplicantStatus answer(ISupplicantStaIfaceCallback cb) 1592 throws RemoteException { 1593 mISupplicantStaIfaceCallback = cb; 1594 return mStatusSuccess; 1595 } 1596 }).when(mISupplicantStaIfaceMock) 1597 .registerCallback(any(ISupplicantStaIfaceCallback.class)); 1598 } 1599 1600 mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantStaIfaceMock, 1601 mWifiMonitor); 1602 // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications 1603 assertTrue(mDut.initialize()); 1604 // verify: service manager initialization sequence 1605 mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(), 1606 anyLong()); 1607 mInOrder.verify(mServiceManagerMock).registerForNotifications( 1608 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture()); 1609 // act: cause the onRegistration(...) callback to execute 1610 mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true); 1611 1612 assertTrue(mDut.isInitializationComplete()); 1613 assertTrue(mDut.setupIface(WLAN0_IFACE_NAME) == shouldSucceed); 1614 mInOrder.verify(mISupplicantMock).linkToDeath(mSupplicantDeathCaptor.capture(), 1615 anyLong()); 1616 // verify: listInterfaces is called 1617 mInOrder.verify(mISupplicantMock).listInterfaces( 1618 any(ISupplicant.listInterfacesCallback.class)); 1619 if (!getZeroInterfaces) { 1620 mInOrder.verify(mISupplicantMock) 1621 .getInterface(any(ISupplicant.IfaceInfo.class), 1622 any(ISupplicant.getInterfaceCallback.class)); 1623 } 1624 if (!causeRemoteException && !getZeroInterfaces && !getNullInterface) { 1625 mInOrder.verify(mISupplicantStaIfaceMock) 1626 .registerCallback(any(ISupplicantStaIfaceCallback.class)); 1627 } 1628 } 1629 1630 /** 1631 * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the 1632 * expected result. Verifies if ISupplicantStaIface manager is initialized or reset. 1633 * Each of the arguments will cause a different failure mode when set true. 1634 */ 1635 private void executeAndValidateInitializationSequenceV1_1(boolean causeRemoteException, 1636 boolean getNullInterface) 1637 throws Exception { 1638 boolean shouldSucceed = !causeRemoteException && !getNullInterface; 1639 // Setup callback mock answers 1640 if (causeRemoteException) { 1641 doThrow(new RemoteException("Some error!!!")) 1642 .when(mISupplicantMockV1_1).addInterface(any(ISupplicant.IfaceInfo.class), 1643 any(android.hardware.wifi.supplicant.V1_1.ISupplicant 1644 .addInterfaceCallback.class)); 1645 } else { 1646 doAnswer(new GetAddInterfaceAnswer(getNullInterface)) 1647 .when(mISupplicantMockV1_1).addInterface(any(ISupplicant.IfaceInfo.class), 1648 any(android.hardware.wifi.supplicant.V1_1.ISupplicant 1649 .addInterfaceCallback.class)); 1650 } 1651 /** Callback registeration */ 1652 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1653 public SupplicantStatus answer( 1654 android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback cb) 1655 throws RemoteException { 1656 mISupplicantStaIfaceCallbackV1_1 = cb; 1657 return mStatusSuccess; 1658 } 1659 }).when(mISupplicantStaIfaceMockV1_1) 1660 .registerCallback_1_1( 1661 any(android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.class)); 1662 1663 mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV1_1, 1664 mISupplicantStaIfaceMockV1_1, mWifiMonitor); 1665 // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications 1666 assertTrue(mDut.initialize()); 1667 // verify: service manager initialization sequence 1668 mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(), 1669 anyLong()); 1670 mInOrder.verify(mServiceManagerMock).registerForNotifications( 1671 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture()); 1672 // act: cause the onRegistration(...) callback to execute 1673 mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true); 1674 1675 assertTrue(mDut.isInitializationComplete()); 1676 assertTrue(mDut.setupIface(WLAN0_IFACE_NAME) == shouldSucceed); 1677 mInOrder.verify(mISupplicantMock).linkToDeath(mSupplicantDeathCaptor.capture(), 1678 anyLong()); 1679 // verify: addInterface is called 1680 mInOrder.verify(mISupplicantMockV1_1) 1681 .addInterface(any(ISupplicant.IfaceInfo.class), 1682 any(android.hardware.wifi.supplicant.V1_1.ISupplicant 1683 .addInterfaceCallback.class)); 1684 if (!causeRemoteException && !getNullInterface) { 1685 mInOrder.verify(mISupplicantStaIfaceMockV1_1) 1686 .registerCallback_1_1( 1687 any(android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.class)); 1688 } 1689 1690 // Ensure we don't try to use the listInterfaces method from 1.0 version. 1691 verify(mISupplicantMock, never()).listInterfaces( 1692 any(ISupplicant.listInterfacesCallback.class)); 1693 verify(mISupplicantMock, never()).getInterface(any(ISupplicant.IfaceInfo.class), 1694 any(ISupplicant.getInterfaceCallback.class)); 1695 } 1696 1697 private SupplicantStatus createSupplicantStatus(int code) { 1698 SupplicantStatus status = new SupplicantStatus(); 1699 status.code = code; 1700 return status; 1701 } 1702 1703 /** 1704 * Create an IfaceInfo with given type and name 1705 */ 1706 private ISupplicant.IfaceInfo createIfaceInfo(int type, String name) { 1707 ISupplicant.IfaceInfo info = new ISupplicant.IfaceInfo(); 1708 info.type = type; 1709 info.name = name; 1710 return info; 1711 } 1712 1713 private class GetListInterfacesAnswer extends MockAnswerUtil.AnswerWithArguments { 1714 private ArrayList<ISupplicant.IfaceInfo> mInterfaceList; 1715 1716 GetListInterfacesAnswer(ArrayList<ISupplicant.IfaceInfo> ifaces) { 1717 mInterfaceList = ifaces; 1718 } 1719 1720 public void answer(ISupplicant.listInterfacesCallback cb) { 1721 cb.onValues(mStatusSuccess, mInterfaceList); 1722 } 1723 } 1724 1725 private class GetGetInterfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1726 boolean mGetNullInterface; 1727 1728 GetGetInterfaceAnswer(boolean getNullInterface) { 1729 mGetNullInterface = getNullInterface; 1730 } 1731 1732 public void answer(ISupplicant.IfaceInfo iface, ISupplicant.getInterfaceCallback cb) { 1733 if (mGetNullInterface) { 1734 cb.onValues(mStatusSuccess, null); 1735 } else { 1736 cb.onValues(mStatusSuccess, mISupplicantIfaceMock); 1737 } 1738 } 1739 } 1740 1741 private class GetAddInterfaceAnswer extends MockAnswerUtil.AnswerWithArguments { 1742 boolean mGetNullInterface; 1743 1744 GetAddInterfaceAnswer(boolean getNullInterface) { 1745 mGetNullInterface = getNullInterface; 1746 } 1747 1748 public void answer(ISupplicant.IfaceInfo iface, 1749 android.hardware.wifi.supplicant.V1_1.ISupplicant 1750 .addInterfaceCallback cb) { 1751 if (mGetNullInterface) { 1752 cb.onValues(mStatusSuccess, null); 1753 } else { 1754 cb.onValues(mStatusSuccess, mISupplicantIfaceMock); 1755 } 1756 } 1757 } 1758 1759 /** 1760 * Setup mocks for connect sequence. 1761 */ 1762 private void setupMocksForConnectSequence(final boolean haveExistingNetwork) throws Exception { 1763 final int existingNetworkId = SUPPLICANT_NETWORK_ID; 1764 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1765 public SupplicantStatus answer() throws RemoteException { 1766 return mStatusSuccess; 1767 } 1768 }).when(mISupplicantStaIfaceMock).disconnect(); 1769 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1770 public void answer(ISupplicantStaIface.listNetworksCallback cb) throws RemoteException { 1771 if (haveExistingNetwork) { 1772 cb.onValues(mStatusSuccess, new ArrayList<>(Arrays.asList(existingNetworkId))); 1773 } else { 1774 cb.onValues(mStatusSuccess, new ArrayList<>()); 1775 } 1776 } 1777 }).when(mISupplicantStaIfaceMock) 1778 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class)); 1779 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1780 public SupplicantStatus answer(int id) throws RemoteException { 1781 return mStatusSuccess; 1782 } 1783 }).when(mISupplicantStaIfaceMock).removeNetwork(eq(existingNetworkId)); 1784 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1785 public void answer(ISupplicantStaIface.addNetworkCallback cb) throws RemoteException { 1786 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class)); 1787 return; 1788 } 1789 }).when(mISupplicantStaIfaceMock).addNetwork( 1790 any(ISupplicantStaIface.addNetworkCallback.class)); 1791 when(mSupplicantStaNetworkMock.saveWifiConfiguration(any(WifiConfiguration.class))) 1792 .thenReturn(true); 1793 when(mSupplicantStaNetworkMock.select()).thenReturn(true); 1794 } 1795 1796 /** 1797 * Helper function to validate the connect sequence. 1798 */ 1799 private void validateConnectSequence( 1800 final boolean haveExistingNetwork, int numNetworkAdditions) throws Exception { 1801 if (haveExistingNetwork) { 1802 verify(mISupplicantStaIfaceMock).removeNetwork(anyInt()); 1803 } 1804 verify(mISupplicantStaIfaceMock, times(numNetworkAdditions)) 1805 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class)); 1806 verify(mSupplicantStaNetworkMock, times(numNetworkAdditions)) 1807 .saveWifiConfiguration(any(WifiConfiguration.class)); 1808 verify(mSupplicantStaNetworkMock, times(numNetworkAdditions)).select(); 1809 } 1810 1811 /** 1812 * Helper function to execute all the actions to perform connection to the network. 1813 * 1814 * @param newFrameworkNetworkId Framework Network Id of the new network to connect. 1815 * @param haveExistingNetwork Removes the existing network. 1816 * @return the WifiConfiguration object of the new network to connect. 1817 */ 1818 private WifiConfiguration executeAndValidateConnectSequence( 1819 final int newFrameworkNetworkId, final boolean haveExistingNetwork) throws Exception { 1820 setupMocksForConnectSequence(haveExistingNetwork); 1821 WifiConfiguration config = new WifiConfiguration(); 1822 config.networkId = newFrameworkNetworkId; 1823 assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config)); 1824 validateConnectSequence(haveExistingNetwork, 1); 1825 return config; 1826 } 1827 1828 /** 1829 * Setup mocks for roam sequence. 1830 */ 1831 private void setupMocksForRoamSequence(String roamBssid) throws Exception { 1832 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 1833 public SupplicantStatus answer() throws RemoteException { 1834 return mStatusSuccess; 1835 } 1836 }).when(mISupplicantStaIfaceMock).reassociate(); 1837 when(mSupplicantStaNetworkMock.setBssid(eq(roamBssid))).thenReturn(true); 1838 } 1839 1840 /** 1841 * Helper function to execute all the actions to perform roaming to the network. 1842 * 1843 * @param sameNetwork Roam to the same network or not. 1844 */ 1845 private void executeAndValidateRoamSequence(boolean sameNetwork) throws Exception { 1846 int connectedNetworkId = ROAM_NETWORK_ID; 1847 String roamBssid = BSSID; 1848 int roamNetworkId; 1849 if (sameNetwork) { 1850 roamNetworkId = connectedNetworkId; 1851 } else { 1852 roamNetworkId = connectedNetworkId + 1; 1853 } 1854 executeAndValidateConnectSequence(connectedNetworkId, false); 1855 setupMocksForRoamSequence(roamBssid); 1856 1857 WifiConfiguration roamingConfig = new WifiConfiguration(); 1858 roamingConfig.networkId = roamNetworkId; 1859 roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID(roamBssid); 1860 assertTrue(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig)); 1861 1862 if (!sameNetwork) { 1863 validateConnectSequence(false, 2); 1864 verify(mSupplicantStaNetworkMock, never()).setBssid(anyString()); 1865 verify(mISupplicantStaIfaceMock, never()).reassociate(); 1866 } else { 1867 verify(mSupplicantStaNetworkMock).setBssid(eq(roamBssid)); 1868 verify(mISupplicantStaIfaceMock).reassociate(); 1869 } 1870 } 1871} 1872