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 */ 16 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertArrayEquals; 20import static org.junit.Assert.assertEquals; 21import static org.junit.Assert.assertFalse; 22import static org.junit.Assert.assertNotEquals; 23import static org.junit.Assert.assertNotNull; 24import static org.junit.Assert.assertNull; 25import static org.junit.Assert.assertTrue; 26import static org.mockito.Mockito.any; 27import static org.mockito.Mockito.anyBoolean; 28import static org.mockito.Mockito.anyInt; 29import static org.mockito.Mockito.anyObject; 30import static org.mockito.Mockito.anyShort; 31import static org.mockito.Mockito.doAnswer; 32import static org.mockito.Mockito.doNothing; 33import static org.mockito.Mockito.doThrow; 34import static org.mockito.Mockito.eq; 35import static org.mockito.Mockito.mock; 36import static org.mockito.Mockito.never; 37import static org.mockito.Mockito.reset; 38import static org.mockito.Mockito.spy; 39import static org.mockito.Mockito.times; 40import static org.mockito.Mockito.verify; 41import static org.mockito.Mockito.verifyNoMoreInteractions; 42import static org.mockito.Mockito.when; 43 44import android.app.test.MockAnswerUtil.AnswerWithArguments; 45import android.hardware.wifi.V1_0.IWifiApIface; 46import android.hardware.wifi.V1_0.IWifiChip; 47import android.hardware.wifi.V1_0.IWifiChipEventCallback; 48import android.hardware.wifi.V1_0.IWifiIface; 49import android.hardware.wifi.V1_0.IWifiRttController; 50import android.hardware.wifi.V1_0.IWifiRttControllerEventCallback; 51import android.hardware.wifi.V1_0.IWifiStaIface; 52import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback; 53import android.hardware.wifi.V1_0.IfaceType; 54import android.hardware.wifi.V1_0.RttBw; 55import android.hardware.wifi.V1_0.RttCapabilities; 56import android.hardware.wifi.V1_0.RttConfig; 57import android.hardware.wifi.V1_0.RttPreamble; 58import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities; 59import android.hardware.wifi.V1_0.StaBackgroundScanCapabilities; 60import android.hardware.wifi.V1_0.StaBackgroundScanParameters; 61import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats; 62import android.hardware.wifi.V1_0.StaLinkLayerRadioStats; 63import android.hardware.wifi.V1_0.StaLinkLayerStats; 64import android.hardware.wifi.V1_0.StaScanData; 65import android.hardware.wifi.V1_0.StaScanDataFlagMask; 66import android.hardware.wifi.V1_0.StaScanResult; 67import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats; 68import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType; 69import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags; 70import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus; 71import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel; 72import android.hardware.wifi.V1_0.WifiDebugRxPacketFate; 73import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport; 74import android.hardware.wifi.V1_0.WifiDebugTxPacketFate; 75import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport; 76import android.hardware.wifi.V1_0.WifiInformationElement; 77import android.hardware.wifi.V1_0.WifiStatus; 78import android.hardware.wifi.V1_0.WifiStatusCode; 79import android.hardware.wifi.V1_2.IWifiChipEventCallback.IfaceInfo; 80import android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo; 81import android.net.KeepalivePacketData; 82import android.net.MacAddress; 83import android.net.apf.ApfCapabilities; 84import android.net.wifi.RttManager; 85import android.net.wifi.ScanResult; 86import android.net.wifi.WifiManager; 87import android.net.wifi.WifiScanner; 88import android.net.wifi.WifiSsid; 89import android.net.wifi.WifiWakeReasonAndCounts; 90import android.os.Looper; 91import android.os.RemoteException; 92import android.os.test.TestLooper; 93import android.system.OsConstants; 94import android.util.Pair; 95 96import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener; 97import com.android.server.wifi.util.NativeUtil; 98 99import org.junit.Before; 100import org.junit.Test; 101import org.mockito.ArgumentCaptor; 102import org.mockito.Mock; 103import org.mockito.MockitoAnnotations; 104import org.mockito.stubbing.Answer; 105 106import java.net.InetAddress; 107import java.util.ArrayList; 108import java.util.Arrays; 109import java.util.HashSet; 110import java.util.List; 111import java.util.Random; 112import java.util.Set; 113 114/** 115 * Unit tests for {@link com.android.server.wifi.WifiVendorHal}. 116 */ 117public class WifiVendorHalTest { 118 119 private static final String TEST_IFACE_NAME = "wlan0"; 120 private static final String TEST_IFACE_NAME_1 = "wlan1"; 121 private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92"); 122 123 WifiVendorHal mWifiVendorHal; 124 private WifiStatus mWifiStatusSuccess; 125 private WifiStatus mWifiStatusFailure; 126 WifiLog mWifiLog; 127 @Mock 128 private HalDeviceManager mHalDeviceManager; 129 @Mock 130 private TestLooper mLooper; 131 @Mock 132 private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks; 133 @Mock 134 private IWifiApIface mIWifiApIface; 135 @Mock 136 private IWifiChip mIWifiChip; 137 @Mock 138 private android.hardware.wifi.V1_1.IWifiChip mIWifiChipV11; 139 @Mock 140 private android.hardware.wifi.V1_2.IWifiChip mIWifiChipV12; 141 @Mock 142 private IWifiStaIface mIWifiStaIface; 143 @Mock 144 private android.hardware.wifi.V1_2.IWifiStaIface mIWifiStaIfaceV12; 145 @Mock 146 private IWifiRttController mIWifiRttController; 147 private IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback; 148 private IWifiChipEventCallback mIWifiChipEventCallback; 149 private android.hardware.wifi.V1_2.IWifiChipEventCallback mIWifiChipEventCallbackV12; 150 @Mock 151 private WifiNative.VendorHalDeathEventHandler mVendorHalDeathHandler; 152 @Mock 153 private WifiNative.VendorHalRadioModeChangeEventHandler mVendorHalRadioModeChangeHandler; 154 155 /** 156 * Spy used to return the V1_1 IWifiChip mock object to simulate the 1.1 HAL running on the 157 * device. 158 */ 159 private class WifiVendorHalSpyV1_1 extends WifiVendorHal { 160 WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Looper looper) { 161 super(halDeviceManager, looper); 162 } 163 164 @Override 165 protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() { 166 return mIWifiChipV11; 167 } 168 169 @Override 170 protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() { 171 return null; 172 } 173 174 @Override 175 protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable( 176 String ifaceName) { 177 return null; 178 } 179 } 180 181 /** 182 * Spy used to return the V1_2 IWifiChip and IWifiStaIface mock objects to simulate 183 * the 1.2 HAL running on the device. 184 */ 185 private class WifiVendorHalSpyV1_2 extends WifiVendorHal { 186 WifiVendorHalSpyV1_2(HalDeviceManager halDeviceManager, Looper looper) { 187 super(halDeviceManager, looper); 188 } 189 190 @Override 191 protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() { 192 return null; 193 } 194 195 @Override 196 protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() { 197 return mIWifiChipV12; 198 } 199 200 @Override 201 protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable( 202 String ifaceName) { 203 return mIWifiStaIfaceV12; 204 } 205 } 206 207 /** 208 * Identity function to supply a type to its argument, which is a lambda 209 */ 210 static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) { 211 return (statusLambda); 212 } 213 214 /** 215 * Sets up for unit test 216 */ 217 @Before 218 public void setUp() throws Exception { 219 MockitoAnnotations.initMocks(this); 220 mWifiLog = new FakeWifiLog(); 221 mLooper = new TestLooper(); 222 mWifiStatusSuccess = new WifiStatus(); 223 mWifiStatusSuccess.code = WifiStatusCode.SUCCESS; 224 mWifiStatusFailure = new WifiStatus(); 225 mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN; 226 mWifiStatusFailure.description = "I don't even know what a Mock Turtle is."; 227 when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess); 228 229 // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in 230 // individual tests, if needed. 231 doAnswer(new AnswerWithArguments() { 232 public boolean answer() { 233 when(mHalDeviceManager.isReady()).thenReturn(true); 234 when(mHalDeviceManager.isStarted()).thenReturn(true); 235 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 236 return true; 237 } 238 }).when(mHalDeviceManager).start(); 239 240 doAnswer(new AnswerWithArguments() { 241 public void answer() { 242 when(mHalDeviceManager.isReady()).thenReturn(true); 243 when(mHalDeviceManager.isStarted()).thenReturn(false); 244 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 245 } 246 }).when(mHalDeviceManager).stop(); 247 when(mHalDeviceManager.createStaIface(anyBoolean(), any(), eq(null))) 248 .thenReturn(mIWifiStaIface); 249 when(mHalDeviceManager.createApIface(any(), eq(null))) 250 .thenReturn(mIWifiApIface); 251 when(mHalDeviceManager.removeIface(any())).thenReturn(true); 252 when(mHalDeviceManager.getChip(any(IWifiIface.class))) 253 .thenReturn(mIWifiChip); 254 when(mHalDeviceManager.createRttController()).thenReturn(mIWifiRttController); 255 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 256 .thenReturn(mWifiStatusSuccess); 257 mIWifiStaIfaceEventCallback = null; 258 when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class))) 259 .thenAnswer(answerWifiStatus((invocation) -> { 260 Object[] args = invocation.getArguments(); 261 mIWifiStaIfaceEventCallback = (IWifiStaIfaceEventCallback) args[0]; 262 return (mWifiStatusSuccess); 263 })); 264 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 265 .thenAnswer(answerWifiStatus((invocation) -> { 266 Object[] args = invocation.getArguments(); 267 mIWifiChipEventCallback = (IWifiChipEventCallback) args[0]; 268 return (mWifiStatusSuccess); 269 })); 270 when(mIWifiChipV12.registerEventCallback_1_2( 271 any(android.hardware.wifi.V1_2.IWifiChipEventCallback.class))) 272 .thenAnswer(answerWifiStatus((invocation) -> { 273 Object[] args = invocation.getArguments(); 274 mIWifiChipEventCallbackV12 = 275 (android.hardware.wifi.V1_2.IWifiChipEventCallback) args[0]; 276 return (mWifiStatusSuccess); 277 })); 278 279 when(mIWifiRttController.registerEventCallback(any(IWifiRttControllerEventCallback.class))) 280 .thenReturn(mWifiStatusSuccess); 281 282 doAnswer(new AnswerWithArguments() { 283 public void answer(IWifiIface.getNameCallback cb) 284 throws RemoteException { 285 cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME); 286 } 287 }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class)); 288 doAnswer(new AnswerWithArguments() { 289 public void answer(IWifiIface.getNameCallback cb) 290 throws RemoteException { 291 cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME); 292 } 293 }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class)); 294 295 // Create the vendor HAL object under test. 296 mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mLooper.getLooper()); 297 298 // Initialize the vendor HAL to capture the registered callback. 299 mWifiVendorHal.initialize(mVendorHalDeathHandler); 300 ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> hdmCallbackCaptor = 301 ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class); 302 verify(mHalDeviceManager).registerStatusListener(hdmCallbackCaptor.capture(), eq(null)); 303 mHalDeviceManagerStatusCallbacks = hdmCallbackCaptor.getValue(); 304 305 } 306 307 /** 308 * Tests the successful starting of HAL in STA mode using 309 * {@link WifiVendorHal#startVendorHalSta()}. 310 */ 311 @Test 312 public void testStartHalSuccessInStaMode() throws Exception { 313 assertTrue(mWifiVendorHal.startVendorHalSta()); 314 assertTrue(mWifiVendorHal.isHalStarted()); 315 316 verify(mHalDeviceManager).start(); 317 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 318 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 319 verify(mHalDeviceManager).createRttController(); 320 verify(mHalDeviceManager).isReady(); 321 verify(mHalDeviceManager).isStarted(); 322 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 323 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 324 325 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 326 } 327 328 /** 329 * Tests the successful starting of HAL in AP mode using 330 * {@link WifiVendorHal#startVendorHalAp()}. 331 */ 332 @Test 333 public void testStartHalSuccessInApMode() throws Exception { 334 assertTrue(mWifiVendorHal.startVendorHalAp()); 335 assertTrue(mWifiVendorHal.isHalStarted()); 336 337 verify(mHalDeviceManager).start(); 338 verify(mHalDeviceManager).createApIface(any(), eq(null)); 339 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 340 verify(mHalDeviceManager).isReady(); 341 verify(mHalDeviceManager).isStarted(); 342 343 verify(mHalDeviceManager, never()).createStaIface(anyBoolean(), any(), eq(null)); 344 verify(mHalDeviceManager, never()).createRttController(); 345 } 346 347 /** 348 * Tests the failure to start HAL in STA mode using 349 * {@link WifiVendorHal#startVendorHalSta()}. 350 */ 351 @Test 352 public void testStartHalFailureInStaMode() throws Exception { 353 // No callbacks are invoked in this case since the start itself failed. So, override 354 // default AnswerWithArguments that we setup. 355 doAnswer(new AnswerWithArguments() { 356 public boolean answer() throws Exception { 357 return false; 358 } 359 }).when(mHalDeviceManager).start(); 360 assertFalse(mWifiVendorHal.startVendorHalSta()); 361 assertFalse(mWifiVendorHal.isHalStarted()); 362 363 verify(mHalDeviceManager).start(); 364 365 verify(mHalDeviceManager, never()).createStaIface(anyBoolean(), any(), eq(null)); 366 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 367 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 368 verify(mHalDeviceManager, never()).createRttController(); 369 verify(mIWifiStaIface, never()) 370 .registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 371 } 372 373 /** 374 * Tests the failure to start HAL in STA mode using 375 * {@link WifiVendorHal#startVendorHalSta()}. 376 */ 377 @Test 378 public void testStartHalFailureInIfaceCreationInStaMode() throws Exception { 379 when(mHalDeviceManager.createStaIface(anyBoolean(), any(), eq(null))).thenReturn(null); 380 assertFalse(mWifiVendorHal.startVendorHalSta()); 381 assertFalse(mWifiVendorHal.isHalStarted()); 382 383 verify(mHalDeviceManager).start(); 384 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 385 verify(mHalDeviceManager).stop(); 386 387 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 388 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 389 verify(mHalDeviceManager, never()).createRttController(); 390 verify(mIWifiStaIface, never()) 391 .registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 392 } 393 394 /** 395 * Tests the failure to start HAL in STA mode using 396 * {@link WifiVendorHal#startVendorHalSta()}. 397 */ 398 @Test 399 public void testStartHalFailureInRttControllerCreationInStaMode() throws Exception { 400 when(mHalDeviceManager.createRttController()).thenReturn(null); 401 assertFalse(mWifiVendorHal.startVendorHalSta()); 402 assertFalse(mWifiVendorHal.isHalStarted()); 403 404 verify(mHalDeviceManager).start(); 405 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 406 verify(mHalDeviceManager).createRttController(); 407 verify(mHalDeviceManager).stop(); 408 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 409 410 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 411 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 412 } 413 414 /** 415 * Tests the failure to start HAL in STA mode using 416 * {@link WifiVendorHal#startVendorHalSta()}. 417 */ 418 @Test 419 public void testStartHalFailureInChipGetInStaMode() throws Exception { 420 when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null); 421 assertFalse(mWifiVendorHal.startVendorHalSta()); 422 assertFalse(mWifiVendorHal.isHalStarted()); 423 424 verify(mHalDeviceManager).start(); 425 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 426 verify(mHalDeviceManager).createRttController(); 427 verify(mHalDeviceManager).getChip(any(IWifiIface.class)); 428 verify(mHalDeviceManager).stop(); 429 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 430 431 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 432 } 433 434 /** 435 * Tests the failure to start HAL in STA mode using 436 * {@link WifiVendorHal#startVendorHalSta()}. 437 */ 438 @Test 439 public void testStartHalFailureInStaIfaceCallbackRegistration() throws Exception { 440 when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class))) 441 .thenReturn(mWifiStatusFailure); 442 assertFalse(mWifiVendorHal.startVendorHalSta()); 443 assertFalse(mWifiVendorHal.isHalStarted()); 444 445 verify(mHalDeviceManager).start(); 446 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 447 verify(mHalDeviceManager).stop(); 448 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 449 450 verify(mHalDeviceManager, never()).createRttController(); 451 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 452 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 453 } 454 455 /** 456 * Tests the failure to start HAL in STA mode using 457 * {@link WifiVendorHal#startVendorHalSta()}. 458 */ 459 @Test 460 public void testStartHalFailureInChipCallbackRegistration() throws Exception { 461 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 462 .thenReturn(mWifiStatusFailure); 463 assertFalse(mWifiVendorHal.startVendorHalSta()); 464 assertFalse(mWifiVendorHal.isHalStarted()); 465 466 verify(mHalDeviceManager).start(); 467 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 468 verify(mHalDeviceManager).createRttController(); 469 verify(mHalDeviceManager).getChip(any(IWifiIface.class)); 470 verify(mHalDeviceManager).stop(); 471 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 472 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 473 474 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 475 } 476 477 /** 478 * Tests the failure to start HAL in AP mode using 479 * {@link WifiVendorHal#startVendorHalAp()}. 480 */ 481 @Test 482 public void testStartHalFailureInApMode() throws Exception { 483 when(mHalDeviceManager.createApIface(any(), eq(null))).thenReturn(null); 484 assertFalse(mWifiVendorHal.startVendorHalAp()); 485 assertFalse(mWifiVendorHal.isHalStarted()); 486 487 verify(mHalDeviceManager).start(); 488 verify(mHalDeviceManager).createApIface(any(), eq(null)); 489 verify(mHalDeviceManager).stop(); 490 491 verify(mHalDeviceManager, never()).createStaIface(anyBoolean(), any(), eq(null)); 492 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 493 verify(mHalDeviceManager, never()).createRttController(); 494 } 495 496 /** 497 * Tests the stopping of HAL in STA mode using 498 * {@link WifiVendorHal#stopVendorHal()}. 499 */ 500 @Test 501 public void testStopHalInStaMode() { 502 assertTrue(mWifiVendorHal.startVendorHalSta()); 503 assertTrue(mWifiVendorHal.isHalStarted()); 504 505 mWifiVendorHal.stopVendorHal(); 506 assertFalse(mWifiVendorHal.isHalStarted()); 507 508 verify(mHalDeviceManager).start(); 509 verify(mHalDeviceManager).stop(); 510 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 511 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 512 verify(mHalDeviceManager).createRttController(); 513 verify(mHalDeviceManager, times(2)).isReady(); 514 verify(mHalDeviceManager, times(2)).isStarted(); 515 516 verify(mHalDeviceManager, never()).createApIface(any(), eq(null)); 517 } 518 519 /** 520 * Tests the stopping of HAL in AP mode using 521 * {@link WifiVendorHal#stopVendorHal()}. 522 */ 523 @Test 524 public void testStopHalInApMode() { 525 assertTrue(mWifiVendorHal.startVendorHalAp()); 526 assertTrue(mWifiVendorHal.isHalStarted()); 527 528 mWifiVendorHal.stopVendorHal(); 529 assertFalse(mWifiVendorHal.isHalStarted()); 530 531 verify(mHalDeviceManager).start(); 532 verify(mHalDeviceManager).stop(); 533 verify(mHalDeviceManager).createApIface(any(), eq(null)); 534 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 535 verify(mHalDeviceManager, times(2)).isReady(); 536 verify(mHalDeviceManager, times(2)).isStarted(); 537 538 verify(mHalDeviceManager, never()).createStaIface(anyBoolean(), any(), eq(null)); 539 verify(mHalDeviceManager, never()).createRttController(); 540 } 541 542 /** 543 * Tests the handling of interface destroyed callback from HalDeviceManager. 544 */ 545 @Test 546 public void testStaInterfaceDestroyedHandling() throws Exception { 547 ArgumentCaptor<InterfaceDestroyedListener> internalListenerCaptor = 548 ArgumentCaptor.forClass(InterfaceDestroyedListener.class); 549 InterfaceDestroyedListener externalLister = mock(InterfaceDestroyedListener.class); 550 551 assertTrue(mWifiVendorHal.startVendorHal()); 552 assertNotNull(mWifiVendorHal.createStaIface(false, externalLister)); 553 assertTrue(mWifiVendorHal.isHalStarted()); 554 555 verify(mHalDeviceManager).start(); 556 verify(mHalDeviceManager).createStaIface(eq(false), internalListenerCaptor.capture(), 557 eq(null)); 558 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 559 verify(mHalDeviceManager).createRttController(); 560 verify(mHalDeviceManager).isReady(); 561 verify(mHalDeviceManager).isStarted(); 562 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 563 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 564 565 // Now trigger the interface destroyed callback from HalDeviceManager and ensure the 566 // external listener is invoked and iface removed from internal database. 567 internalListenerCaptor.getValue().onDestroyed(TEST_IFACE_NAME); 568 verify(externalLister).onDestroyed(TEST_IFACE_NAME); 569 570 // This should fail now, since the interface was already destroyed. 571 assertFalse(mWifiVendorHal.removeStaIface(TEST_IFACE_NAME)); 572 verify(mHalDeviceManager, never()).removeIface(any()); 573 } 574 575 /** 576 * Tests the handling of interface destroyed callback from HalDeviceManager. 577 */ 578 @Test 579 public void testApInterfaceDestroyedHandling() throws Exception { 580 ArgumentCaptor<InterfaceDestroyedListener> internalListenerCaptor = 581 ArgumentCaptor.forClass(InterfaceDestroyedListener.class); 582 InterfaceDestroyedListener externalLister = mock(InterfaceDestroyedListener.class); 583 584 assertTrue(mWifiVendorHal.startVendorHal()); 585 assertNotNull(mWifiVendorHal.createApIface(externalLister)); 586 assertTrue(mWifiVendorHal.isHalStarted()); 587 588 verify(mHalDeviceManager).start(); 589 verify(mHalDeviceManager).createApIface(internalListenerCaptor.capture(), eq(null)); 590 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 591 verify(mHalDeviceManager).isReady(); 592 verify(mHalDeviceManager).isStarted(); 593 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 594 595 // Now trigger the interface destroyed callback from HalDeviceManager and ensure the 596 // external listener is invoked and iface removed from internal database. 597 internalListenerCaptor.getValue().onDestroyed(TEST_IFACE_NAME); 598 verify(externalLister).onDestroyed(TEST_IFACE_NAME); 599 600 // This should fail now, since the interface was already destroyed. 601 assertFalse(mWifiVendorHal.removeApIface(TEST_IFACE_NAME)); 602 verify(mHalDeviceManager, never()).removeIface(any()); 603 } 604 605 /** 606 * Test that enter logs when verbose logging is enabled 607 */ 608 @Test 609 public void testEnterLogging() { 610 mWifiVendorHal.mLog = spy(mWifiLog); 611 mWifiVendorHal.enableVerboseLogging(true); 612 mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]); 613 verify(mWifiVendorHal.mLog).trace(eq("filter length %"), eq(1)); 614 } 615 616 /** 617 * Test that enter does not log when verbose logging is not enabled 618 */ 619 @Test 620 public void testEnterSilenceWhenNotEnabled() { 621 mWifiVendorHal.mLog = spy(mWifiLog); 622 mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]); 623 mWifiVendorHal.enableVerboseLogging(true); 624 mWifiVendorHal.enableVerboseLogging(false); 625 mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]); 626 verify(mWifiVendorHal.mLog, never()).trace(eq("filter length %"), anyInt()); 627 } 628 629 /** 630 * Test that boolResult logs a false result 631 */ 632 @Test 633 public void testBoolResultFalse() { 634 mWifiLog = spy(mWifiLog); 635 mWifiVendorHal.mLog = mWifiLog; 636 mWifiVendorHal.mVerboseLog = mWifiLog; 637 assertFalse(mWifiVendorHal.getBgScanCapabilities( 638 TEST_IFACE_NAME, new WifiNative.ScanCapabilities())); 639 verify(mWifiLog).err("% returns %"); 640 } 641 642 /** 643 * Test that getBgScanCapabilities is hooked up to the HAL correctly 644 * 645 * A call before the vendor HAL is started should return a non-null result with version 0 646 * 647 * A call after the HAL is started should return the mocked values. 648 */ 649 @Test 650 public void testGetBgScanCapabilities() throws Exception { 651 StaBackgroundScanCapabilities capabilities = new StaBackgroundScanCapabilities(); 652 capabilities.maxCacheSize = 12; 653 capabilities.maxBuckets = 34; 654 capabilities.maxApCachePerScan = 56; 655 capabilities.maxReportingThreshold = 78; 656 657 doAnswer(new AnswerWithArguments() { 658 public void answer(IWifiStaIface.getBackgroundScanCapabilitiesCallback cb) 659 throws RemoteException { 660 cb.onValues(mWifiStatusSuccess, capabilities); 661 } 662 }).when(mIWifiStaIface).getBackgroundScanCapabilities(any( 663 IWifiStaIface.getBackgroundScanCapabilitiesCallback.class)); 664 665 WifiNative.ScanCapabilities result = new WifiNative.ScanCapabilities(); 666 667 // should fail - not started 668 assertFalse(mWifiVendorHal.getBgScanCapabilities(TEST_IFACE_NAME, result)); 669 // Start the vendor hal 670 assertTrue(mWifiVendorHal.startVendorHalSta()); 671 // should succeed 672 assertTrue(mWifiVendorHal.getBgScanCapabilities(TEST_IFACE_NAME, result)); 673 674 assertEquals(12, result.max_scan_cache_size); 675 assertEquals(34, result.max_scan_buckets); 676 assertEquals(56, result.max_ap_cache_per_scan); 677 assertEquals(78, result.max_scan_reporting_threshold); 678 } 679 680 /** 681 * Test translation to WifiManager.WIFI_FEATURE_* 682 * 683 * Just do a spot-check with a few feature bits here; since the code is table- 684 * driven we don't have to work hard to exercise all of it. 685 */ 686 @Test 687 public void testStaIfaceFeatureMaskTranslation() { 688 int caps = ( 689 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN 690 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS 691 ); 692 int expected = ( 693 WifiManager.WIFI_FEATURE_SCANNER 694 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS); 695 assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps)); 696 } 697 698 /** 699 * Test translation to WifiManager.WIFI_FEATURE_* 700 * 701 * Just do a spot-check with a few feature bits here; since the code is table- 702 * driven we don't have to work hard to exercise all of it. 703 */ 704 @Test 705 public void testChipFeatureMaskTranslation() { 706 int caps = ( 707 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT 708 | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT 709 | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT 710 ); 711 int expected = ( 712 WifiManager.WIFI_FEATURE_TX_POWER_LIMIT 713 | WifiManager.WIFI_FEATURE_D2D_RTT 714 | WifiManager.WIFI_FEATURE_D2AP_RTT 715 ); 716 assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities(caps)); 717 } 718 719 /** 720 * Test get supported features. Tests whether we coalesce information from different sources 721 * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features 722 * correctly. 723 */ 724 @Test 725 public void testGetSupportedFeatures() throws Exception { 726 assertTrue(mWifiVendorHal.startVendorHalSta()); 727 728 int staIfaceHidlCaps = ( 729 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN 730 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS 731 ); 732 int chipHidlCaps = 733 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT; 734 Set<Integer> halDeviceManagerSupportedIfaces = new HashSet<Integer>() {{ 735 add(IfaceType.STA); 736 add(IfaceType.P2P); 737 }}; 738 int expectedFeatureSet = ( 739 WifiManager.WIFI_FEATURE_SCANNER 740 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS 741 | WifiManager.WIFI_FEATURE_TX_POWER_LIMIT 742 | WifiManager.WIFI_FEATURE_INFRA 743 | WifiManager.WIFI_FEATURE_P2P 744 ); 745 746 doAnswer(new AnswerWithArguments() { 747 public void answer(IWifiStaIface.getCapabilitiesCallback cb) throws RemoteException { 748 cb.onValues(mWifiStatusSuccess, staIfaceHidlCaps); 749 } 750 }).when(mIWifiStaIface).getCapabilities(any(IWifiStaIface.getCapabilitiesCallback.class)); 751 doAnswer(new AnswerWithArguments() { 752 public void answer(IWifiChip.getCapabilitiesCallback cb) throws RemoteException { 753 cb.onValues(mWifiStatusSuccess, chipHidlCaps); 754 } 755 }).when(mIWifiChip).getCapabilities(any(IWifiChip.getCapabilitiesCallback.class)); 756 when(mHalDeviceManager.getSupportedIfaceTypes()) 757 .thenReturn(halDeviceManagerSupportedIfaces); 758 759 assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME)); 760 } 761 762 /** 763 * Test enablement of link layer stats after startup 764 * 765 * Request link layer stats before HAL start 766 * - should not make it to the HAL layer 767 * Start the HAL in STA mode 768 * Request link layer stats twice more 769 * - enable request should make it to the HAL layer 770 * - HAL layer should have been called to make the requests (i.e., two calls total) 771 */ 772 @Test 773 public void testLinkLayerStatsEnableAfterStartup() throws Exception { 774 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 775 776 assertNull(mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME)); 777 assertTrue(mWifiVendorHal.startVendorHalSta()); 778 assertTrue(mWifiVendorHal.isHalStarted()); 779 780 verify(mHalDeviceManager).start(); 781 mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME); 782 mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME); 783 verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug 784 verify(mIWifiStaIface, times(2)).getLinkLayerStats(any()); 785 } 786 787 /** 788 * Test that link layer stats are not enabled and harmless in AP mode 789 * 790 * Start the HAL in AP mode 791 * - stats should not be enabled 792 * Request link layer stats 793 * - HAL layer should have been called to make the request 794 */ 795 @Test 796 public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception { 797 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 798 799 assertTrue(mWifiVendorHal.startVendorHalAp()); 800 assertTrue(mWifiVendorHal.isHalStarted()); 801 assertNull(mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME)); 802 803 verify(mHalDeviceManager).start(); 804 805 verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false); 806 verify(mIWifiStaIface, never()).getLinkLayerStats(any()); 807 } 808 809 /** 810 * Test that the link layer stats fields are populated correctly. 811 * 812 * This is done by filling with random values and then using toString on the 813 * original and converted values, comparing just the numerics in the result. 814 * This makes the assumption that the fields are in the same order in both string 815 * representations, which is not quite true. So apply some fixups before the final 816 * comparison. 817 */ 818 @Test 819 public void testLinkLayerStatsAssignment() throws Exception { 820 Random r = new Random(1775968256); 821 StaLinkLayerStats stats = new StaLinkLayerStats(); 822 randomizePacketStats(r, stats.iface.wmeBePktStats); 823 randomizePacketStats(r, stats.iface.wmeBkPktStats); 824 randomizePacketStats(r, stats.iface.wmeViPktStats); 825 randomizePacketStats(r, stats.iface.wmeVoPktStats); 826 randomizeRadioStats(r, stats.radios); 827 828 stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL; 829 830 String expected = numbersOnly(stats.toString() + " "); 831 832 WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats); 833 834 String actual = numbersOnly(converted.toString() + " "); 835 836 // Do the required fixups to the both expected and actual 837 expected = rmValue(expected, stats.radios.get(0).rxTimeInMs); 838 expected = rmValue(expected, stats.radios.get(0).onTimeInMsForScan); 839 840 actual = rmValue(actual, stats.radios.get(0).rxTimeInMs); 841 actual = rmValue(actual, stats.radios.get(0).onTimeInMsForScan); 842 843 // The remaining fields should agree 844 assertEquals(expected, actual); 845 } 846 847 /** Just the digits with delimiting spaces, please */ 848 private static String numbersOnly(String s) { 849 return s.replaceAll("[^0-9]+", " "); 850 } 851 852 /** Remove the given value from the space-delimited string, or die trying. */ 853 private static String rmValue(String s, long value) throws Exception { 854 String ans = s.replaceAll(" " + value + " ", " "); 855 assertNotEquals(s, ans); 856 return ans; 857 } 858 859 /** 860 * Populate packet stats with non-negative random values 861 */ 862 private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) { 863 pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits 864 pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL; 865 pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL; 866 pstats.retries = r.nextLong() & 0xFFFFFFFFFFL; 867 } 868 869 /** 870 * Populate radio stats with non-negative random values 871 */ 872 private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) { 873 StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats(); 874 rstat.onTimeInMs = r.nextInt() & 0xFFFFFF; 875 rstat.txTimeInMs = r.nextInt() & 0xFFFFFF; 876 for (int i = 0; i < 4; i++) { 877 Integer v = r.nextInt() & 0xFFFFFF; 878 rstat.txTimeInMsPerLevel.add(v); 879 } 880 rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF; 881 rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF; 882 rstats.add(rstat); 883 } 884 885 /** 886 * Test that getFirmwareVersion() and getDriverVersion() work 887 * 888 * Calls before the STA is started are expected to return null. 889 */ 890 @Test 891 public void testVersionGetters() throws Exception { 892 String firmwareVersion = "fuzzy"; 893 String driverVersion = "dizzy"; 894 IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo(); 895 chipDebugInfo.firmwareDescription = firmwareVersion; 896 chipDebugInfo.driverDescription = driverVersion; 897 898 doAnswer(new AnswerWithArguments() { 899 public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException { 900 cb.onValues(mWifiStatusSuccess, chipDebugInfo); 901 } 902 }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class)); 903 904 assertNull(mWifiVendorHal.getFirmwareVersion()); 905 assertNull(mWifiVendorHal.getDriverVersion()); 906 907 assertTrue(mWifiVendorHal.startVendorHalSta()); 908 909 assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion()); 910 assertEquals(driverVersion, mWifiVendorHal.getDriverVersion()); 911 } 912 913 /** 914 * For checkRoundTripIntTranslation lambdas 915 */ 916 interface IntForInt { 917 int translate(int value); 918 } 919 920 /** 921 * Checks that translation from x to y and back again is the identity function 922 * 923 * @param xFromY reverse translator 924 * @param yFromX forward translator 925 * @param xLimit non-inclusive upper bound on x (lower bound is zero) 926 */ 927 private void checkRoundTripIntTranslation( 928 IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit) throws Exception { 929 int ex = 0; 930 for (int i = xFirst; i < xLimit; i++) { 931 assertEquals(i, xFromY.translate(yFromX.translate(i))); 932 } 933 try { 934 yFromX.translate(xLimit); 935 assertTrue("expected an exception here", false); 936 } catch (IllegalArgumentException e) { 937 ex++; 938 } 939 try { 940 xFromY.translate(yFromX.translate(xLimit - 1) + 1); 941 assertTrue("expected an exception here", false); 942 } catch (IllegalArgumentException e) { 943 ex++; 944 } 945 assertEquals(2, ex); 946 } 947 948 949 /** 950 * Test translations of RTT type 951 */ 952 @Test 953 public void testRttTypeTranslation() throws Exception { 954 checkRoundTripIntTranslation( 955 (y) -> WifiVendorHal.halRttTypeFromFrameworkRttType(y), 956 (x) -> WifiVendorHal.frameworkRttTypeFromHalRttType(x), 957 1, 3); 958 } 959 960 /** 961 * Test translations of peer type 962 */ 963 @Test 964 public void testPeerTranslation() throws Exception { 965 checkRoundTripIntTranslation( 966 (y) -> WifiVendorHal.halPeerFromFrameworkPeer(y), 967 (x) -> WifiVendorHal.frameworkPeerFromHalPeer(x), 968 1, 6); 969 } 970 971 /** 972 * Test translations of channel width 973 */ 974 @Test 975 public void testChannelWidth() throws Exception { 976 checkRoundTripIntTranslation( 977 (y) -> WifiVendorHal.halChannelWidthFromFrameworkChannelWidth(y), 978 (x) -> WifiVendorHal.frameworkChannelWidthFromHalChannelWidth(x), 979 0, 5); 980 } 981 982 /** 983 * Test translations of preamble type mask 984 */ 985 @Test 986 public void testPreambleTranslation() throws Exception { 987 checkRoundTripIntTranslation( 988 (y) -> WifiVendorHal.halPreambleFromFrameworkPreamble(y), 989 (x) -> WifiVendorHal.frameworkPreambleFromHalPreamble(x), 990 0, 8); 991 } 992 993 /** 994 * Test translations of bandwidth mask 995 */ 996 @Test 997 public void testBandwidthTranslations() throws Exception { 998 checkRoundTripIntTranslation( 999 (y) -> WifiVendorHal.halBwFromFrameworkBw(y), 1000 (x) -> WifiVendorHal.frameworkBwFromHalBw(x), 1001 0, 64); 1002 } 1003 1004 /** 1005 * Test translation of framwork RttParams to hal RttConfig 1006 */ 1007 @Test 1008 public void testGetRttStuff() throws Exception { 1009 RttManager.RttParams params = new RttManager.RttParams(); 1010 params.bssid = "03:01:04:01:05:09"; 1011 params.frequency = 2420; 1012 params.channelWidth = ScanResult.CHANNEL_WIDTH_40MHZ; 1013 params.centerFreq0 = 2440; 1014 params.centerFreq1 = 1; 1015 params.num_samples = 2; 1016 params.num_retries = 3; 1017 params.numberBurst = 4; 1018 params.interval = 5; 1019 params.numSamplesPerBurst = 8; 1020 params.numRetriesPerMeasurementFrame = 6; 1021 params.numRetriesPerFTMR = 7; 1022 params.LCIRequest = false; 1023 params.LCRRequest = false; 1024 params.burstTimeout = 15; 1025 String frameish = params.toString(); 1026 assertFalse(frameish.contains("=0,")); // make sure all fields are initialized 1027 RttConfig config = WifiVendorHal.halRttConfigFromFrameworkRttParams(params); 1028 String halish = config.toString(); 1029 StringBuffer expect = new StringBuffer(200); 1030 expect.append("{.addr = [3, 1, 4, 1, 5, 9], .type = ONE_SIDED, .peer = AP, "); 1031 expect.append(".channel = {.width = WIDTH_40, .centerFreq = 2420, "); 1032 expect.append(".centerFreq0 = 2440, .centerFreq1 = 1}, "); 1033 expect.append(".burstPeriod = 5, .numBurst = 4, .numFramesPerBurst = 8, "); 1034 expect.append(".numRetriesPerRttFrame = 6, .numRetriesPerFtmr = 7, "); 1035 expect.append(".mustRequestLci = false, .mustRequestLcr = false, .burstDuration = 15, "); 1036 expect.append(".preamble = HT, .bw = BW_20MHZ}"); 1037 assertEquals(expect.toString(), halish); 1038 } 1039 1040 /** 1041 * Test that RTT capabilities are plumbed through 1042 */ 1043 @Test 1044 public void testGetRttCapabilities() throws Exception { 1045 RttCapabilities capabilities = new RttCapabilities(); 1046 capabilities.lcrSupported = true; 1047 capabilities.preambleSupport = RttPreamble.LEGACY | RttPreamble.VHT; 1048 capabilities.bwSupport = RttBw.BW_5MHZ | RttBw.BW_20MHZ; 1049 capabilities.mcVersion = 43; 1050 doAnswer(new AnswerWithArguments() { 1051 public void answer(IWifiRttController.getCapabilitiesCallback cb) 1052 throws RemoteException { 1053 cb.onValues(mWifiStatusSuccess, capabilities); 1054 } 1055 }).when(mIWifiRttController).getCapabilities(any( 1056 IWifiRttController.getCapabilitiesCallback.class)); 1057 1058 assertNull(mWifiVendorHal.getRttCapabilities()); 1059 1060 assertTrue(mWifiVendorHal.startVendorHalSta()); 1061 1062 RttManager.RttCapabilities actual = mWifiVendorHal.getRttCapabilities(); 1063 assertTrue(actual.lcrSupported); 1064 assertEquals(RttManager.PREAMBLE_LEGACY | RttManager.PREAMBLE_VHT, 1065 actual.preambleSupported); 1066 assertEquals(RttManager.RTT_BW_5_SUPPORT | RttManager.RTT_BW_20_SUPPORT, 1067 actual.bwSupported); 1068 assertEquals(43, (int) capabilities.mcVersion); 1069 } 1070 1071 /** 1072 * Negative test of disableRttResponder 1073 */ 1074 @Test 1075 public void testDisableOfUnstartedRtt() throws Exception { 1076 assertFalse(mWifiVendorHal.disableRttResponder()); 1077 } 1078 1079 /** 1080 * Test that setScanningMacOui is hooked up to the HAL correctly 1081 */ 1082 @Test 1083 public void testSetScanningMacOui() throws Exception { 1084 byte[] oui = NativeUtil.macAddressOuiToByteArray("DA:A1:19"); 1085 byte[] zzz = NativeUtil.macAddressOuiToByteArray("00:00:00"); 1086 1087 when(mIWifiStaIface.setScanningMacOui(any())).thenReturn(mWifiStatusSuccess); 1088 1089 // expect fail - STA not started 1090 assertFalse(mWifiVendorHal.setScanningMacOui(TEST_IFACE_NAME, oui)); 1091 assertTrue(mWifiVendorHal.startVendorHalSta()); 1092 // expect fail - null 1093 assertFalse(mWifiVendorHal.setScanningMacOui(TEST_IFACE_NAME, null)); 1094 // expect fail - len 1095 assertFalse(mWifiVendorHal.setScanningMacOui(TEST_IFACE_NAME, new byte[]{(byte) 1})); 1096 assertTrue(mWifiVendorHal.setScanningMacOui(TEST_IFACE_NAME, oui)); 1097 assertTrue(mWifiVendorHal.setScanningMacOui(TEST_IFACE_NAME, zzz)); 1098 1099 verify(mIWifiStaIface).setScanningMacOui(eq(oui)); 1100 verify(mIWifiStaIface).setScanningMacOui(eq(zzz)); 1101 } 1102 1103 @Test 1104 public void testStartSendingOffloadedPacket() throws Exception { 1105 byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81"); 1106 byte[] dstMac = NativeUtil.macAddressToByteArray("4007b8675309"); 1107 InetAddress src = InetAddress.parseNumericAddress("192.168.13.13"); 1108 InetAddress dst = InetAddress.parseNumericAddress("93.184.216.34"); 1109 int slot = 13; 1110 int millis = 16000; 1111 1112 KeepalivePacketData kap = KeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500); 1113 1114 when(mIWifiStaIface.startSendingKeepAlivePackets( 1115 anyInt(), any(), anyShort(), any(), any(), anyInt() 1116 )).thenReturn(mWifiStatusSuccess); 1117 1118 assertTrue(mWifiVendorHal.startVendorHalSta()); 1119 assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket( 1120 TEST_IFACE_NAME, slot, srcMac, dstMac, kap.getPacket(), 1121 OsConstants.ETH_P_IPV6, millis)); 1122 1123 verify(mIWifiStaIface).startSendingKeepAlivePackets( 1124 eq(slot), any(), anyShort(), any(), any(), eq(millis)); 1125 } 1126 1127 @Test 1128 public void testStopSendingOffloadedPacket() throws Exception { 1129 int slot = 13; 1130 1131 when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess); 1132 1133 assertTrue(mWifiVendorHal.startVendorHalSta()); 1134 assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket( 1135 TEST_IFACE_NAME, slot)); 1136 1137 verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot)); 1138 } 1139 1140 /** 1141 * Test the setup, invocation, and removal of a RSSI event handler 1142 * 1143 */ 1144 @Test 1145 public void testRssiMonitoring() throws Exception { 1146 when(mIWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt())) 1147 .thenReturn(mWifiStatusSuccess); 1148 when(mIWifiStaIface.stopRssiMonitoring(anyInt())) 1149 .thenReturn(mWifiStatusSuccess); 1150 1151 ArrayList<Byte> breach = new ArrayList<>(10); 1152 byte hi = -21; 1153 byte med = -42; 1154 byte lo = -84; 1155 Byte lower = -88; 1156 WifiNative.WifiRssiEventHandler handler; 1157 handler = ((cur) -> { 1158 breach.add(cur); 1159 }); 1160 // not started 1161 assertEquals(-1, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler)); 1162 // not started 1163 assertEquals(-1, mWifiVendorHal.stopRssiMonitoring(TEST_IFACE_NAME)); 1164 assertTrue(mWifiVendorHal.startVendorHalSta()); 1165 assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler)); 1166 int theCmdId = mWifiVendorHal.sRssiMonCmdId; 1167 breach.clear(); 1168 mIWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower); 1169 assertEquals(breach.get(0), lower); 1170 assertEquals(0, mWifiVendorHal.stopRssiMonitoring(TEST_IFACE_NAME)); 1171 assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler)); 1172 // replacing works 1173 assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, med, lo, handler)); 1174 // null handler fails 1175 assertEquals(-1, mWifiVendorHal.startRssiMonitoring( 1176 TEST_IFACE_NAME, hi, lo, null)); 1177 assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler)); 1178 // empty range 1179 assertEquals(-1, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, lo, hi, handler)); 1180 } 1181 1182 /** 1183 * Test that getApfCapabilities is hooked up to the HAL correctly 1184 * 1185 * A call before the vendor HAL is started should return a non-null result with version 0 1186 * 1187 * A call after the HAL is started should return the mocked values. 1188 */ 1189 @Test 1190 public void testApfCapabilities() throws Exception { 1191 int myVersion = 33; 1192 int myMaxSize = 1234; 1193 1194 StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities(); 1195 capabilities.version = myVersion; 1196 capabilities.maxLength = myMaxSize; 1197 1198 doAnswer(new AnswerWithArguments() { 1199 public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb) 1200 throws RemoteException { 1201 cb.onValues(mWifiStatusSuccess, capabilities); 1202 } 1203 }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any( 1204 IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class)); 1205 1206 1207 assertEquals(0, mWifiVendorHal.getApfCapabilities(TEST_IFACE_NAME) 1208 .apfVersionSupported); 1209 1210 assertTrue(mWifiVendorHal.startVendorHalSta()); 1211 1212 ApfCapabilities actual = mWifiVendorHal.getApfCapabilities(TEST_IFACE_NAME); 1213 1214 assertEquals(myVersion, actual.apfVersionSupported); 1215 assertEquals(myMaxSize, actual.maximumApfProgramSize); 1216 assertEquals(android.system.OsConstants.ARPHRD_ETHER, actual.apfPacketFormat); 1217 assertNotEquals(0, actual.apfPacketFormat); 1218 } 1219 1220 /** 1221 * Test that an APF program can be installed. 1222 */ 1223 @Test 1224 public void testInstallApf() throws Exception { 1225 byte[] filter = new byte[] {19, 53, 10}; 1226 1227 ArrayList<Byte> expected = new ArrayList<>(3); 1228 for (byte b : filter) expected.add(b); 1229 1230 when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class))) 1231 .thenReturn(mWifiStatusSuccess); 1232 1233 assertTrue(mWifiVendorHal.startVendorHalSta()); 1234 assertTrue(mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, filter)); 1235 1236 verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected)); 1237 } 1238 1239 /** 1240 * Test that an APF program and data buffer can be read back. 1241 */ 1242 @Test 1243 public void testReadApf() throws Exception { 1244 // Expose the 1.2 IWifiStaIface. 1245 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 1246 1247 byte[] program = new byte[] {65, 66, 67}; 1248 ArrayList<Byte> expected = new ArrayList<>(3); 1249 for (byte b : program) expected.add(b); 1250 1251 doAnswer(new AnswerWithArguments() { 1252 public void answer( 1253 android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback cb) 1254 throws RemoteException { 1255 cb.onValues(mWifiStatusSuccess, expected); 1256 } 1257 }).when(mIWifiStaIfaceV12).readApfPacketFilterData(any( 1258 android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback.class)); 1259 1260 assertTrue(mWifiVendorHal.startVendorHalSta()); 1261 assertArrayEquals(program, mWifiVendorHal.readPacketFilter(TEST_IFACE_NAME)); 1262 } 1263 1264 /** 1265 * Test that the country code is set in AP mode (when it should be). 1266 */ 1267 @Test 1268 public void testSetCountryCodeHal() throws Exception { 1269 byte[] expected = new byte[]{(byte) 'C', (byte) 'A'}; 1270 1271 when(mIWifiApIface.setCountryCode(any())) 1272 .thenReturn(mWifiStatusSuccess); 1273 1274 assertTrue(mWifiVendorHal.startVendorHalAp()); 1275 1276 assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, null)); 1277 assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "")); 1278 assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "A")); 1279 // Only one expected to succeed 1280 assertTrue(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "CA")); 1281 assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "ZZZ")); 1282 1283 verify(mIWifiApIface).setCountryCode(eq(expected)); 1284 } 1285 1286 /** 1287 * Test that RemoteException is caught and logged. 1288 */ 1289 @Test 1290 public void testRemoteExceptionIsHandled() throws Exception { 1291 mWifiLog = spy(mWifiLog); 1292 mWifiVendorHal.mVerboseLog = mWifiLog; 1293 when(mIWifiApIface.setCountryCode(any())) 1294 .thenThrow(new RemoteException("oops")); 1295 assertTrue(mWifiVendorHal.startVendorHalAp()); 1296 assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "CA")); 1297 assertFalse(mWifiVendorHal.isHalStarted()); 1298 verify(mWifiLog).err("% RemoteException in HIDL call %"); 1299 } 1300 1301 /** 1302 * Test that startLoggingToDebugRingBuffer is plumbed to chip 1303 * 1304 * A call before the vendor hal is started should just return false. 1305 * After starting in STA mode, the call should succeed, and pass ther right things down. 1306 */ 1307 @Test 1308 public void testStartLoggingRingBuffer() throws Exception { 1309 when(mIWifiChip.startLoggingToDebugRingBuffer( 1310 any(String.class), anyInt(), anyInt(), anyInt() 1311 )).thenReturn(mWifiStatusSuccess); 1312 1313 assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One")); 1314 assertTrue(mWifiVendorHal.startVendorHalSta()); 1315 assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One")); 1316 1317 verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000); 1318 } 1319 1320 /** 1321 * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA. 1322 */ 1323 @Test 1324 public void testStartLoggingRingBufferOnAp() throws Exception { 1325 when(mIWifiChip.startLoggingToDebugRingBuffer( 1326 any(String.class), anyInt(), anyInt(), anyInt() 1327 )).thenReturn(mWifiStatusSuccess); 1328 1329 assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One")); 1330 assertTrue(mWifiVendorHal.startVendorHalAp()); 1331 assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One")); 1332 1333 verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000); 1334 } 1335 1336 /** 1337 * Test that getRingBufferStatus gets and translates its stuff correctly 1338 */ 1339 @Test 1340 public void testRingBufferStatus() throws Exception { 1341 WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus(); 1342 one.ringName = "One"; 1343 one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES; 1344 one.ringId = 5607371; 1345 one.sizeInBytes = 54321; 1346 one.freeSizeInBytes = 42; 1347 one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE; 1348 String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321" 1349 + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0"; 1350 1351 WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus(); 1352 two.ringName = "Two"; 1353 two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES 1354 | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES; 1355 two.ringId = 4512470; 1356 two.sizeInBytes = 300; 1357 two.freeSizeInBytes = 42; 1358 two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT; 1359 1360 ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2); 1361 halBufferStatus.add(one); 1362 halBufferStatus.add(two); 1363 1364 WifiNative.RingBufferStatus[] actual; 1365 1366 doAnswer(new AnswerWithArguments() { 1367 public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb) 1368 throws RemoteException { 1369 cb.onValues(mWifiStatusSuccess, halBufferStatus); 1370 } 1371 }).when(mIWifiChip).getDebugRingBuffersStatus(any( 1372 IWifiChip.getDebugRingBuffersStatusCallback.class)); 1373 1374 assertTrue(mWifiVendorHal.startVendorHalSta()); 1375 actual = mWifiVendorHal.getRingBufferStatus(); 1376 1377 assertEquals(halBufferStatus.size(), actual.length); 1378 assertEquals(oneExpect, actual[0].toString()); 1379 assertEquals(two.ringId, actual[1].ringBufferId); 1380 } 1381 1382 /** 1383 * Test that getRingBufferData calls forceDumpToDebugRingBuffer 1384 * 1385 * Try once before hal start, and twice after (one success, one failure). 1386 */ 1387 @Test 1388 public void testForceRingBufferDump() throws Exception { 1389 when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess); 1390 when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure); 1391 1392 assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started 1393 1394 assertTrue(mWifiVendorHal.startVendorHalSta()); 1395 1396 assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds 1397 assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails 1398 1399 verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk"); 1400 verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop"); 1401 } 1402 1403 /** 1404 * Tests the start of packet fate monitoring. 1405 * 1406 * Try once before hal start, and once after (one success, one failure). 1407 */ 1408 @Test 1409 public void testStartPktFateMonitoring() throws Exception { 1410 when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess); 1411 1412 assertFalse(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME)); 1413 verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring(); 1414 1415 assertTrue(mWifiVendorHal.startVendorHalSta()); 1416 assertTrue(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME)); 1417 verify(mIWifiStaIface).startDebugPacketFateMonitoring(); 1418 } 1419 1420 /** 1421 * Tests the retrieval of tx packet fates. 1422 * 1423 * Try once before hal start, and once after. 1424 */ 1425 @Test 1426 public void testGetTxPktFates() throws Exception { 1427 byte[] frameContentBytes = new byte[30]; 1428 new Random().nextBytes(frameContentBytes); 1429 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 1430 fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED; 1431 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1432 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 1433 fateReport.frameInfo.frameContent.addAll( 1434 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1435 1436 doAnswer(new AnswerWithArguments() { 1437 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 1438 cb.onValues(mWifiStatusSuccess, 1439 new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(fateReport))); 1440 } 1441 }).when(mIWifiStaIface) 1442 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1443 1444 WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1]; 1445 assertFalse(mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME, retrievedFates)); 1446 verify(mIWifiStaIface, never()) 1447 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1448 1449 assertTrue(mWifiVendorHal.startVendorHalSta()); 1450 1451 assertTrue(mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME, retrievedFates)); 1452 verify(mIWifiStaIface) 1453 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1454 assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFates[0].mFate); 1455 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1456 retrievedFates[0].mDriverTimestampUSec); 1457 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType); 1458 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1459 } 1460 1461 /** 1462 * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the 1463 * input array. 1464 * 1465 * Try once before hal start, and once after. 1466 */ 1467 @Test 1468 public void testGetTxPktFatesExceedsInputArrayLength() throws Exception { 1469 byte[] frameContentBytes = new byte[30]; 1470 new Random().nextBytes(frameContentBytes); 1471 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 1472 fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER; 1473 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1474 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 1475 fateReport.frameInfo.frameContent.addAll( 1476 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1477 1478 doAnswer(new AnswerWithArguments() { 1479 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 1480 cb.onValues(mWifiStatusSuccess, 1481 new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList( 1482 fateReport, fateReport))); 1483 } 1484 }).when(mIWifiStaIface) 1485 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1486 1487 WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1]; 1488 assertFalse(mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME, retrievedFates)); 1489 verify(mIWifiStaIface, never()) 1490 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1491 1492 assertTrue(mWifiVendorHal.startVendorHalSta()); 1493 1494 assertTrue(mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME, retrievedFates)); 1495 verify(mIWifiStaIface) 1496 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1497 assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFates[0].mFate); 1498 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1499 retrievedFates[0].mDriverTimestampUSec); 1500 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType); 1501 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1502 } 1503 1504 /** 1505 * Tests the retrieval of rx packet fates. 1506 * 1507 * Try once before hal start, and once after. 1508 */ 1509 @Test 1510 public void testGetRxPktFates() throws Exception { 1511 byte[] frameContentBytes = new byte[30]; 1512 new Random().nextBytes(frameContentBytes); 1513 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 1514 fateReport.fate = WifiDebugRxPacketFate.SUCCESS; 1515 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1516 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 1517 fateReport.frameInfo.frameContent.addAll( 1518 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1519 1520 doAnswer(new AnswerWithArguments() { 1521 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 1522 cb.onValues(mWifiStatusSuccess, 1523 new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(fateReport))); 1524 } 1525 }).when(mIWifiStaIface) 1526 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1527 1528 WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1]; 1529 assertFalse(mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME, retrievedFates)); 1530 verify(mIWifiStaIface, never()) 1531 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1532 1533 assertTrue(mWifiVendorHal.startVendorHalSta()); 1534 1535 assertTrue(mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME, retrievedFates)); 1536 verify(mIWifiStaIface) 1537 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1538 assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFates[0].mFate); 1539 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1540 retrievedFates[0].mDriverTimestampUSec); 1541 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType); 1542 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1543 } 1544 1545 /** 1546 * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the 1547 * input array. 1548 * 1549 * Try once before hal start, and once after. 1550 */ 1551 @Test 1552 public void testGetRxPktFatesExceedsInputArrayLength() throws Exception { 1553 byte[] frameContentBytes = new byte[30]; 1554 new Random().nextBytes(frameContentBytes); 1555 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 1556 fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER; 1557 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1558 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 1559 fateReport.frameInfo.frameContent.addAll( 1560 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1561 1562 doAnswer(new AnswerWithArguments() { 1563 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 1564 cb.onValues(mWifiStatusSuccess, 1565 new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList( 1566 fateReport, fateReport))); 1567 } 1568 }).when(mIWifiStaIface) 1569 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1570 1571 WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1]; 1572 assertFalse(mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME, retrievedFates)); 1573 verify(mIWifiStaIface, never()) 1574 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1575 1576 assertTrue(mWifiVendorHal.startVendorHalSta()); 1577 1578 assertTrue(mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME, retrievedFates)); 1579 verify(mIWifiStaIface) 1580 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1581 assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFates[0].mFate); 1582 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1583 retrievedFates[0].mDriverTimestampUSec); 1584 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType); 1585 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1586 } 1587 1588 /** 1589 * Tests the failure to retrieve tx packet fates when the input array is empty. 1590 */ 1591 @Test 1592 public void testGetTxPktFatesEmptyInputArray() throws Exception { 1593 assertTrue(mWifiVendorHal.startVendorHalSta()); 1594 assertFalse(mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME, new WifiNative.TxFateReport[0])); 1595 verify(mIWifiStaIface, never()) 1596 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1597 } 1598 1599 /** 1600 * Tests the failure to retrieve rx packet fates when the input array is empty. 1601 */ 1602 @Test 1603 public void testGetRxPktFatesEmptyInputArray() throws Exception { 1604 assertTrue(mWifiVendorHal.startVendorHalSta()); 1605 assertFalse(mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME, new WifiNative.RxFateReport[0])); 1606 verify(mIWifiStaIface, never()) 1607 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1608 } 1609 1610 /** 1611 * Tests the nd offload enable/disable. 1612 */ 1613 @Test 1614 public void testEnableDisableNdOffload() throws Exception { 1615 when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess); 1616 1617 assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true)); 1618 verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean()); 1619 1620 assertTrue(mWifiVendorHal.startVendorHalSta()); 1621 1622 assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true)); 1623 verify(mIWifiStaIface).enableNdOffload(eq(true)); 1624 assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, false)); 1625 verify(mIWifiStaIface).enableNdOffload(eq(false)); 1626 } 1627 1628 /** 1629 * Tests the nd offload enable failure. 1630 */ 1631 @Test 1632 public void testEnableNdOffloadFailure() throws Exception { 1633 when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure); 1634 1635 assertTrue(mWifiVendorHal.startVendorHalSta()); 1636 1637 assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true)); 1638 verify(mIWifiStaIface).enableNdOffload(eq(true)); 1639 } 1640 1641 /** 1642 * Tests the retrieval of wlan wake reason stats. 1643 */ 1644 @Test 1645 public void testGetWlanWakeReasonCount() throws Exception { 1646 WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats(); 1647 Random rand = new Random(); 1648 stats.totalCmdEventWakeCnt = rand.nextInt(); 1649 stats.totalDriverFwLocalWakeCnt = rand.nextInt(); 1650 stats.totalRxPacketWakeCnt = rand.nextInt(); 1651 stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt(); 1652 stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt(); 1653 stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt(); 1654 stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt(); 1655 stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt(); 1656 stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt(); 1657 1658 doAnswer(new AnswerWithArguments() { 1659 public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) { 1660 cb.onValues(mWifiStatusSuccess, stats); 1661 } 1662 }).when(mIWifiChip).getDebugHostWakeReasonStats( 1663 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1664 1665 assertNull(mWifiVendorHal.getWlanWakeReasonCount()); 1666 verify(mIWifiChip, never()) 1667 .getDebugHostWakeReasonStats( 1668 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1669 1670 assertTrue(mWifiVendorHal.startVendorHalSta()); 1671 1672 WifiWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount(); 1673 verify(mIWifiChip).getDebugHostWakeReasonStats( 1674 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1675 assertNotNull(retrievedStats); 1676 assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake); 1677 assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake); 1678 assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake); 1679 assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast); 1680 assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast); 1681 assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp); 1682 assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6); 1683 assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt, 1684 retrievedStats.ipv4RxMulticast); 1685 assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt, 1686 retrievedStats.ipv6Multicast); 1687 } 1688 1689 /** 1690 * Tests the failure in retrieval of wlan wake reason stats. 1691 */ 1692 @Test 1693 public void testGetWlanWakeReasonCountFailure() throws Exception { 1694 doAnswer(new AnswerWithArguments() { 1695 public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) { 1696 cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats()); 1697 } 1698 }).when(mIWifiChip).getDebugHostWakeReasonStats( 1699 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1700 1701 // This should work in both AP & STA mode. 1702 assertTrue(mWifiVendorHal.startVendorHalAp()); 1703 1704 assertNull(mWifiVendorHal.getWlanWakeReasonCount()); 1705 verify(mIWifiChip).getDebugHostWakeReasonStats( 1706 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1707 } 1708 1709 /** 1710 * Test that getFwMemoryDump is properly plumbed 1711 */ 1712 @Test 1713 public void testGetFwMemoryDump() throws Exception { 1714 byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36"); 1715 ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample); 1716 1717 doAnswer(new AnswerWithArguments() { 1718 public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb) 1719 throws RemoteException { 1720 cb.onValues(mWifiStatusSuccess, halBlob); 1721 } 1722 }).when(mIWifiChip).requestFirmwareDebugDump(any( 1723 IWifiChip.requestFirmwareDebugDumpCallback.class)); 1724 1725 assertTrue(mWifiVendorHal.startVendorHalSta()); 1726 assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump()); 1727 } 1728 1729 /** 1730 * Test that getDriverStateDump is properly plumbed 1731 * 1732 * Just for variety, use AP mode here. 1733 */ 1734 @Test 1735 public void testGetDriverStateDump() throws Exception { 1736 byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f"); 1737 ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample); 1738 1739 doAnswer(new AnswerWithArguments() { 1740 public void answer(IWifiChip.requestDriverDebugDumpCallback cb) 1741 throws RemoteException { 1742 cb.onValues(mWifiStatusSuccess, halBlob); 1743 } 1744 }).when(mIWifiChip).requestDriverDebugDump(any( 1745 IWifiChip.requestDriverDebugDumpCallback.class)); 1746 1747 assertTrue(mWifiVendorHal.startVendorHalAp()); 1748 assertArrayEquals(sample, mWifiVendorHal.getDriverStateDump()); 1749 } 1750 1751 /** 1752 * Test that background scan failure is handled correctly. 1753 */ 1754 @Test 1755 public void testBgScanFailureCallback() throws Exception { 1756 assertTrue(mWifiVendorHal.startVendorHalSta()); 1757 assertNotNull(mIWifiStaIfaceEventCallback); 1758 1759 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1760 startBgScan(eventHandler); 1761 1762 mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId); 1763 verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 1764 } 1765 1766 /** 1767 * Test that background scan failure with wrong id is not reported. 1768 */ 1769 @Test 1770 public void testBgScanFailureCallbackWithInvalidCmdId() throws Exception { 1771 assertTrue(mWifiVendorHal.startVendorHalSta()); 1772 assertNotNull(mIWifiStaIfaceEventCallback); 1773 1774 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1775 startBgScan(eventHandler); 1776 1777 mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1); 1778 verify(eventHandler, never()).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 1779 } 1780 1781 /** 1782 * Test that background scan full results are handled correctly. 1783 */ 1784 @Test 1785 public void testBgScanFullScanResults() throws Exception { 1786 assertTrue(mWifiVendorHal.startVendorHalSta()); 1787 assertNotNull(mIWifiStaIfaceEventCallback); 1788 1789 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1790 startBgScan(eventHandler); 1791 1792 Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(); 1793 mIWifiStaIfaceEventCallback.onBackgroundFullScanResult( 1794 mWifiVendorHal.mScan.cmdId, 5, result.first); 1795 1796 ArgumentCaptor<ScanResult> scanResultCaptor = ArgumentCaptor.forClass(ScanResult.class); 1797 verify(eventHandler).onFullScanResult(scanResultCaptor.capture(), eq(5)); 1798 1799 assertScanResultEqual(result.second, scanResultCaptor.getValue()); 1800 } 1801 1802 /** 1803 * Test that background scan results are handled correctly. 1804 */ 1805 @Test 1806 public void testBgScanScanResults() throws Exception { 1807 assertTrue(mWifiVendorHal.startVendorHalSta()); 1808 assertNotNull(mIWifiStaIfaceEventCallback); 1809 1810 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1811 startBgScan(eventHandler); 1812 1813 Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> data = 1814 createHidlAndFrameworkBgScanDatas(); 1815 mIWifiStaIfaceEventCallback.onBackgroundScanResults( 1816 mWifiVendorHal.mScan.cmdId, data.first); 1817 1818 verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1819 assertScanDatasEqual( 1820 data.second, Arrays.asList(mWifiVendorHal.mScan.latestScanResults)); 1821 } 1822 1823 /** 1824 * Test that starting a new background scan when one is active will stop the previous one. 1825 */ 1826 @Test 1827 public void testBgScanReplacement() throws Exception { 1828 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1829 assertTrue(mWifiVendorHal.startVendorHalSta()); 1830 assertNotNull(mIWifiStaIfaceEventCallback); 1831 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1832 startBgScan(eventHandler); 1833 int cmdId1 = mWifiVendorHal.mScan.cmdId; 1834 startBgScan(eventHandler); 1835 assertNotEquals(mWifiVendorHal.mScan.cmdId, cmdId1); 1836 verify(mIWifiStaIface, times(2)).startBackgroundScan(anyInt(), any()); 1837 verify(mIWifiStaIface).stopBackgroundScan(cmdId1); 1838 } 1839 1840 /** 1841 * Test stopping a background scan. 1842 */ 1843 @Test 1844 public void testBgScanStop() throws Exception { 1845 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1846 assertTrue(mWifiVendorHal.startVendorHalSta()); 1847 assertNotNull(mIWifiStaIfaceEventCallback); 1848 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1849 startBgScan(eventHandler); 1850 1851 int cmdId = mWifiVendorHal.mScan.cmdId; 1852 1853 mWifiVendorHal.stopBgScan(TEST_IFACE_NAME); 1854 mWifiVendorHal.stopBgScan(TEST_IFACE_NAME); // second call should not do anything 1855 verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once 1856 } 1857 1858 /** 1859 * Test pausing and restarting a background scan. 1860 */ 1861 @Test 1862 public void testBgScanPauseAndRestart() throws Exception { 1863 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1864 assertTrue(mWifiVendorHal.startVendorHalSta()); 1865 assertNotNull(mIWifiStaIfaceEventCallback); 1866 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1867 startBgScan(eventHandler); 1868 1869 int cmdId = mWifiVendorHal.mScan.cmdId; 1870 1871 mWifiVendorHal.pauseBgScan(TEST_IFACE_NAME); 1872 mWifiVendorHal.restartBgScan(TEST_IFACE_NAME); 1873 verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once 1874 verify(mIWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any()); 1875 } 1876 1877 /** 1878 * Test the handling of log handler set. 1879 */ 1880 @Test 1881 public void testSetLogHandler() throws Exception { 1882 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1883 1884 WifiNative.WifiLoggerEventHandler eventHandler = 1885 mock(WifiNative.WifiLoggerEventHandler.class); 1886 1887 assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1888 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1889 1890 assertTrue(mWifiVendorHal.startVendorHalSta()); 1891 1892 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1893 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 1894 reset(mIWifiChip); 1895 1896 // Second call should fail. 1897 assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1898 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1899 } 1900 1901 /** 1902 * Test the handling of log handler reset. 1903 */ 1904 @Test 1905 public void testResetLogHandler() throws Exception { 1906 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1907 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 1908 1909 assertFalse(mWifiVendorHal.resetLogHandler()); 1910 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1911 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1912 1913 assertTrue(mWifiVendorHal.startVendorHalSta()); 1914 1915 // Not set, so this should fail. 1916 assertFalse(mWifiVendorHal.resetLogHandler()); 1917 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1918 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1919 1920 // Now set and then reset. 1921 assertTrue(mWifiVendorHal.setLoggingEventHandler( 1922 mock(WifiNative.WifiLoggerEventHandler.class))); 1923 assertTrue(mWifiVendorHal.resetLogHandler()); 1924 verify(mIWifiChip).enableDebugErrorAlerts(eq(false)); 1925 verify(mIWifiChip).stopLoggingToDebugRingBuffer(); 1926 reset(mIWifiChip); 1927 1928 // Second reset should fail. 1929 assertFalse(mWifiVendorHal.resetLogHandler()); 1930 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1931 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1932 } 1933 1934 /** 1935 * Test the handling of alert callback. 1936 */ 1937 @Test 1938 public void testAlertCallback() throws Exception { 1939 assertTrue(mWifiVendorHal.startVendorHalSta()); 1940 assertNotNull(mIWifiChipEventCallback); 1941 1942 testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallback); 1943 } 1944 1945 /** 1946 * Test the handling of ring buffer callback. 1947 */ 1948 @Test 1949 public void testRingBufferDataCallback() throws Exception { 1950 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1951 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 1952 1953 assertTrue(mWifiVendorHal.startVendorHalSta()); 1954 assertNotNull(mIWifiChipEventCallback); 1955 1956 byte[] errorData = new byte[45]; 1957 new Random().nextBytes(errorData); 1958 1959 // Randomly raise the HIDL callback before we register for the log callback. 1960 // This should be safely ignored. (Not trigger NPE.) 1961 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1962 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1963 mLooper.dispatchAll(); 1964 1965 WifiNative.WifiLoggerEventHandler eventHandler = 1966 mock(WifiNative.WifiLoggerEventHandler.class); 1967 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1968 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 1969 1970 // Now raise the HIDL callback, this should be properly handled. 1971 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1972 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1973 mLooper.dispatchAll(); 1974 verify(eventHandler).onRingBufferData( 1975 any(WifiNative.RingBufferStatus.class), eq(errorData)); 1976 1977 // Now stop the logging and invoke the callback. This should be ignored. 1978 reset(eventHandler); 1979 assertTrue(mWifiVendorHal.resetLogHandler()); 1980 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1981 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1982 mLooper.dispatchAll(); 1983 verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject()); 1984 } 1985 1986 /** 1987 * Test the handling of Vendor HAL death. 1988 */ 1989 @Test 1990 public void testVendorHalDeath() { 1991 // Invoke the HAL device manager status callback with ready set to false to indicate the 1992 // death of the HAL. 1993 when(mHalDeviceManager.isReady()).thenReturn(false); 1994 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 1995 1996 verify(mVendorHalDeathHandler).onDeath(); 1997 } 1998 1999 /** 2000 * Test the new selectTxPowerScenario HIDL method invocation. This should return failure if the 2001 * HAL service is exposing the 1.0 interface. 2002 */ 2003 @Test 2004 public void testSelectTxPowerScenario() throws RemoteException { 2005 assertTrue(mWifiVendorHal.startVendorHalSta()); 2006 // Should fail because we exposed the 1.0 IWifiChip. 2007 assertFalse( 2008 mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); 2009 verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); 2010 mWifiVendorHal.stopVendorHal(); 2011 2012 // Now expose the 1.1 IWifiChip. 2013 mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); 2014 when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess); 2015 2016 assertTrue(mWifiVendorHal.startVendorHalSta()); 2017 assertTrue( 2018 mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); 2019 verify(mIWifiChipV11).selectTxPowerScenario( 2020 eq(android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL)); 2021 verify(mIWifiChipV11, never()).resetTxPowerScenario(); 2022 mWifiVendorHal.stopVendorHal(); 2023 } 2024 2025 /** 2026 * Test the new resetTxPowerScenario HIDL method invocation. This should return failure if the 2027 * HAL service is exposing the 1.0 interface. 2028 */ 2029 @Test 2030 public void testResetTxPowerScenario() throws RemoteException { 2031 assertTrue(mWifiVendorHal.startVendorHalSta()); 2032 // Should fail because we exposed the 1.0 IWifiChip. 2033 assertFalse(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL)); 2034 verify(mIWifiChipV11, never()).resetTxPowerScenario(); 2035 mWifiVendorHal.stopVendorHal(); 2036 2037 // Now expose the 1.1 IWifiChip. 2038 mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); 2039 when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess); 2040 2041 assertTrue(mWifiVendorHal.startVendorHalSta()); 2042 assertTrue(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL)); 2043 verify(mIWifiChipV11).resetTxPowerScenario(); 2044 verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); 2045 mWifiVendorHal.stopVendorHal(); 2046 } 2047 2048 /** 2049 * Test the new selectTxPowerScenario HIDL method invocation with a bad scenario index. 2050 */ 2051 @Test 2052 public void testInvalidSelectTxPowerScenario() throws RemoteException { 2053 // Expose the 1.1 IWifiChip. 2054 mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); 2055 when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess); 2056 2057 assertTrue(mWifiVendorHal.startVendorHalSta()); 2058 assertFalse(mWifiVendorHal.selectTxPowerScenario(-6)); 2059 verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); 2060 verify(mIWifiChipV11, never()).resetTxPowerScenario(); 2061 mWifiVendorHal.stopVendorHal(); 2062 } 2063 2064 /** 2065 * Test the STA Iface creation failure due to iface name retrieval failure. 2066 */ 2067 @Test 2068 public void testCreateStaIfaceFailureInIfaceName() throws RemoteException { 2069 doAnswer(new AnswerWithArguments() { 2070 public void answer(IWifiIface.getNameCallback cb) 2071 throws RemoteException { 2072 cb.onValues(mWifiStatusFailure, "wlan0"); 2073 } 2074 }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class)); 2075 2076 assertTrue(mWifiVendorHal.startVendorHal()); 2077 assertNull(mWifiVendorHal.createStaIface(true, null)); 2078 verify(mHalDeviceManager).createStaIface(eq(true), any(), eq(null)); 2079 } 2080 2081 /** 2082 * Test the STA Iface creation failure due to iface name retrieval failure. 2083 */ 2084 @Test 2085 public void testCreateApIfaceFailureInIfaceName() throws RemoteException { 2086 doAnswer(new AnswerWithArguments() { 2087 public void answer(IWifiIface.getNameCallback cb) 2088 throws RemoteException { 2089 cb.onValues(mWifiStatusFailure, "wlan0"); 2090 } 2091 }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class)); 2092 2093 assertTrue(mWifiVendorHal.startVendorHal()); 2094 assertNull(mWifiVendorHal.createApIface(null)); 2095 verify(mHalDeviceManager).createApIface(any(), eq(null)); 2096 } 2097 2098 /** 2099 * Test the creation and removal of STA Iface. 2100 */ 2101 @Test 2102 public void testCreateRemoveStaIface() throws RemoteException { 2103 assertTrue(mWifiVendorHal.startVendorHal()); 2104 String ifaceName = mWifiVendorHal.createStaIface(false, null); 2105 verify(mHalDeviceManager).createStaIface(eq(false), any(), eq(null)); 2106 assertEquals(TEST_IFACE_NAME, ifaceName); 2107 assertTrue(mWifiVendorHal.removeStaIface(ifaceName)); 2108 verify(mHalDeviceManager).removeIface(eq(mIWifiStaIface)); 2109 } 2110 2111 /** 2112 * Test the creation and removal of Ap Iface. 2113 */ 2114 @Test 2115 public void testCreateRemoveApIface() throws RemoteException { 2116 assertTrue(mWifiVendorHal.startVendorHal()); 2117 String ifaceName = mWifiVendorHal.createApIface(null); 2118 verify(mHalDeviceManager).createApIface(any(), eq(null)); 2119 assertEquals(TEST_IFACE_NAME, ifaceName); 2120 assertTrue(mWifiVendorHal.removeApIface(ifaceName)); 2121 verify(mHalDeviceManager).removeIface(eq(mIWifiApIface)); 2122 } 2123 2124 /** 2125 * Test the callback handling for the 1.2 HAL. 2126 */ 2127 @Test 2128 public void testAlertCallbackUsing_1_2_EventCallback() throws Exception { 2129 // Expose the 1.2 IWifiChip. 2130 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 2131 2132 assertTrue(mWifiVendorHal.startVendorHalSta()); 2133 assertNotNull(mIWifiChipEventCallbackV12); 2134 2135 testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallbackV12); 2136 } 2137 2138 /** 2139 * Verifies setMacAddress() success. 2140 */ 2141 @Test 2142 public void testSetMacAddressSuccess() throws Exception { 2143 // Expose the 1.2 IWifiStaIface. 2144 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 2145 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 2146 when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess); 2147 2148 assertTrue(mWifiVendorHal.setMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS)); 2149 verify(mIWifiStaIfaceV12).setMacAddress(macByteArray); 2150 } 2151 2152 /** 2153 * Verifies setMacAddress() can handle failure status. 2154 */ 2155 @Test 2156 public void testSetMacAddressFailDueToStatusFailure() throws Exception { 2157 // Expose the 1.2 IWifiStaIface. 2158 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 2159 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 2160 when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure); 2161 2162 assertFalse(mWifiVendorHal.setMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS)); 2163 verify(mIWifiStaIfaceV12).setMacAddress(macByteArray); 2164 } 2165 2166 /** 2167 * Verifies setMacAddress() can handle RemoteException. 2168 */ 2169 @Test 2170 public void testSetMacAddressFailDueToRemoteException() throws Exception { 2171 // Expose the 1.2 IWifiStaIface. 2172 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 2173 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 2174 doThrow(new RemoteException()).when(mIWifiStaIfaceV12).setMacAddress(macByteArray); 2175 2176 assertFalse(mWifiVendorHal.setMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS)); 2177 verify(mIWifiStaIfaceV12).setMacAddress(macByteArray); 2178 } 2179 2180 /** 2181 * Verifies setMacAddress() does not crash with older HALs. 2182 */ 2183 @Test 2184 public void testSetMacAddressDoesNotCrashOnOlderHal() throws Exception { 2185 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 2186 assertFalse(mWifiVendorHal.setMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS)); 2187 } 2188 2189 /** 2190 * Verifies radio mode change callback to indicate DBS mode. 2191 */ 2192 @Test 2193 public void testRadioModeChangeCallbackToDbsMode() throws Exception { 2194 startHalInStaModeAndRegisterRadioModeChangeCallback(); 2195 2196 RadioModeInfo radioModeInfo0 = new RadioModeInfo(); 2197 radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ; 2198 RadioModeInfo radioModeInfo1 = new RadioModeInfo(); 2199 radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_24_GHZ; 2200 2201 IfaceInfo ifaceInfo0 = new IfaceInfo(); 2202 ifaceInfo0.name = TEST_IFACE_NAME; 2203 ifaceInfo0.channel = 34; 2204 IfaceInfo ifaceInfo1 = new IfaceInfo(); 2205 ifaceInfo1.name = TEST_IFACE_NAME_1; 2206 ifaceInfo1.channel = 1; 2207 2208 radioModeInfo0.ifaceInfos.add(ifaceInfo0); 2209 radioModeInfo1.ifaceInfos.add(ifaceInfo1); 2210 2211 ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>(); 2212 radioModeInfos.add(radioModeInfo0); 2213 radioModeInfos.add(radioModeInfo1); 2214 2215 mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos); 2216 verify(mVendorHalRadioModeChangeHandler).onDbs(); 2217 2218 verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler); 2219 } 2220 2221 /** 2222 * Verifies radio mode change callback to indicate SBS mode. 2223 */ 2224 @Test 2225 public void testRadioModeChangeCallbackToSbsMode() throws Exception { 2226 startHalInStaModeAndRegisterRadioModeChangeCallback(); 2227 2228 RadioModeInfo radioModeInfo0 = new RadioModeInfo(); 2229 radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ; 2230 RadioModeInfo radioModeInfo1 = new RadioModeInfo(); 2231 radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ; 2232 2233 IfaceInfo ifaceInfo0 = new IfaceInfo(); 2234 ifaceInfo0.name = TEST_IFACE_NAME; 2235 ifaceInfo0.channel = 34; 2236 IfaceInfo ifaceInfo1 = new IfaceInfo(); 2237 ifaceInfo1.name = TEST_IFACE_NAME_1; 2238 ifaceInfo1.channel = 36; 2239 2240 radioModeInfo0.ifaceInfos.add(ifaceInfo0); 2241 radioModeInfo1.ifaceInfos.add(ifaceInfo1); 2242 2243 ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>(); 2244 radioModeInfos.add(radioModeInfo0); 2245 radioModeInfos.add(radioModeInfo1); 2246 2247 mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos); 2248 verify(mVendorHalRadioModeChangeHandler).onSbs(WifiScanner.WIFI_BAND_5_GHZ); 2249 2250 verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler); 2251 } 2252 2253 /** 2254 * Verifies radio mode change callback to indicate SCC mode. 2255 */ 2256 @Test 2257 public void testRadioModeChangeCallbackToSccMode() throws Exception { 2258 startHalInStaModeAndRegisterRadioModeChangeCallback(); 2259 2260 RadioModeInfo radioModeInfo0 = new RadioModeInfo(); 2261 radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ; 2262 2263 IfaceInfo ifaceInfo0 = new IfaceInfo(); 2264 ifaceInfo0.name = TEST_IFACE_NAME; 2265 ifaceInfo0.channel = 34; 2266 IfaceInfo ifaceInfo1 = new IfaceInfo(); 2267 ifaceInfo1.name = TEST_IFACE_NAME_1; 2268 ifaceInfo1.channel = 34; 2269 2270 radioModeInfo0.ifaceInfos.add(ifaceInfo0); 2271 radioModeInfo0.ifaceInfos.add(ifaceInfo1); 2272 2273 ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>(); 2274 radioModeInfos.add(radioModeInfo0); 2275 2276 mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos); 2277 verify(mVendorHalRadioModeChangeHandler).onScc(WifiScanner.WIFI_BAND_5_GHZ); 2278 2279 verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler); 2280 } 2281 2282 /** 2283 * Verifies radio mode change callback to indicate MCC mode. 2284 */ 2285 @Test 2286 public void testRadioModeChangeCallbackToMccMode() throws Exception { 2287 startHalInStaModeAndRegisterRadioModeChangeCallback(); 2288 2289 RadioModeInfo radioModeInfo0 = new RadioModeInfo(); 2290 radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_BOTH; 2291 2292 IfaceInfo ifaceInfo0 = new IfaceInfo(); 2293 ifaceInfo0.name = TEST_IFACE_NAME; 2294 ifaceInfo0.channel = 1; 2295 IfaceInfo ifaceInfo1 = new IfaceInfo(); 2296 ifaceInfo1.name = TEST_IFACE_NAME_1; 2297 ifaceInfo1.channel = 36; 2298 2299 radioModeInfo0.ifaceInfos.add(ifaceInfo0); 2300 radioModeInfo0.ifaceInfos.add(ifaceInfo1); 2301 2302 ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>(); 2303 radioModeInfos.add(radioModeInfo0); 2304 2305 mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos); 2306 verify(mVendorHalRadioModeChangeHandler).onMcc(WifiScanner.WIFI_BAND_BOTH); 2307 2308 verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler); 2309 } 2310 2311 /** 2312 * Verifies radio mode change callback error cases. 2313 */ 2314 @Test 2315 public void testRadioModeChangeCallbackErrorSimultaneousWithSameIfaceOnBothRadios() 2316 throws Exception { 2317 startHalInStaModeAndRegisterRadioModeChangeCallback(); 2318 2319 RadioModeInfo radioModeInfo0 = new RadioModeInfo(); 2320 radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_24_GHZ; 2321 RadioModeInfo radioModeInfo1 = new RadioModeInfo(); 2322 radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ; 2323 2324 IfaceInfo ifaceInfo0 = new IfaceInfo(); 2325 ifaceInfo0.name = TEST_IFACE_NAME; 2326 ifaceInfo0.channel = 34; 2327 2328 radioModeInfo0.ifaceInfos.add(ifaceInfo0); 2329 radioModeInfo1.ifaceInfos.add(ifaceInfo0); 2330 2331 ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>(); 2332 radioModeInfos.add(radioModeInfo0); 2333 radioModeInfos.add(radioModeInfo1); 2334 2335 mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos); 2336 // Ignored.... 2337 2338 verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler); 2339 } 2340 2341 private void startHalInStaModeAndRegisterRadioModeChangeCallback() { 2342 // Expose the 1.2 IWifiChip. 2343 mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); 2344 mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler); 2345 assertTrue(mWifiVendorHal.startVendorHalSta()); 2346 assertNotNull(mIWifiChipEventCallbackV12); 2347 } 2348 2349 private void testAlertCallbackUsingProvidedCallback(IWifiChipEventCallback chipCallback) 2350 throws Exception { 2351 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 2352 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 2353 2354 int errorCode = 5; 2355 byte[] errorData = new byte[45]; 2356 new Random().nextBytes(errorData); 2357 2358 // Randomly raise the HIDL callback before we register for the log callback. 2359 // This should be safely ignored. (Not trigger NPE.) 2360 chipCallback.onDebugErrorAlert( 2361 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 2362 mLooper.dispatchAll(); 2363 2364 WifiNative.WifiLoggerEventHandler eventHandler = 2365 mock(WifiNative.WifiLoggerEventHandler.class); 2366 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 2367 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 2368 2369 // Now raise the HIDL callback, this should be properly handled. 2370 chipCallback.onDebugErrorAlert( 2371 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 2372 mLooper.dispatchAll(); 2373 verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData)); 2374 2375 // Now stop the logging and invoke the callback. This should be ignored. 2376 reset(eventHandler); 2377 assertTrue(mWifiVendorHal.resetLogHandler()); 2378 chipCallback.onDebugErrorAlert( 2379 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 2380 mLooper.dispatchAll(); 2381 verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject()); 2382 } 2383 2384 private void startBgScan(WifiNative.ScanEventHandler eventHandler) throws Exception { 2385 when(mIWifiStaIface.startBackgroundScan( 2386 anyInt(), any(StaBackgroundScanParameters.class))).thenReturn(mWifiStatusSuccess); 2387 WifiNative.ScanSettings settings = new WifiNative.ScanSettings(); 2388 settings.num_buckets = 1; 2389 WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings(); 2390 bucketSettings.bucket = 0; 2391 bucketSettings.period_ms = 16000; 2392 bucketSettings.report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 2393 settings.buckets = new WifiNative.BucketSettings[] {bucketSettings}; 2394 assertTrue(mWifiVendorHal.startBgScan(TEST_IFACE_NAME, settings, eventHandler)); 2395 } 2396 2397 // Create a pair of HIDL scan result and its corresponding framework scan result for 2398 // comparison. 2399 private Pair<StaScanResult, ScanResult> createHidlAndFrameworkBgScanResult() { 2400 StaScanResult staScanResult = new StaScanResult(); 2401 Random random = new Random(); 2402 byte[] ssid = new byte[8]; 2403 random.nextBytes(ssid); 2404 staScanResult.ssid.addAll(NativeUtil.byteArrayToArrayList(ssid)); 2405 random.nextBytes(staScanResult.bssid); 2406 staScanResult.frequency = 2432; 2407 staScanResult.rssi = -45; 2408 staScanResult.timeStampInUs = 5; 2409 WifiInformationElement ie1 = new WifiInformationElement(); 2410 byte[] ie1_data = new byte[56]; 2411 random.nextBytes(ie1_data); 2412 ie1.id = 1; 2413 ie1.data.addAll(NativeUtil.byteArrayToArrayList(ie1_data)); 2414 staScanResult.informationElements.add(ie1); 2415 2416 // Now create the corresponding Scan result structure. 2417 ScanResult scanResult = new ScanResult(); 2418 scanResult.SSID = NativeUtil.encodeSsid(staScanResult.ssid); 2419 scanResult.BSSID = NativeUtil.macAddressFromByteArray(staScanResult.bssid); 2420 scanResult.wifiSsid = WifiSsid.createFromByteArray(ssid); 2421 scanResult.frequency = staScanResult.frequency; 2422 scanResult.level = staScanResult.rssi; 2423 scanResult.timestamp = staScanResult.timeStampInUs; 2424 2425 return Pair.create(staScanResult, scanResult); 2426 } 2427 2428 // Create a pair of HIDL scan datas and its corresponding framework scan datas for 2429 // comparison. 2430 private Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> 2431 createHidlAndFrameworkBgScanDatas() { 2432 ArrayList<StaScanData> staScanDatas = new ArrayList<>(); 2433 StaScanData staScanData = new StaScanData(); 2434 2435 Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(); 2436 staScanData.results.add(result.first); 2437 staScanData.bucketsScanned = 5; 2438 staScanData.flags = StaScanDataFlagMask.INTERRUPTED; 2439 staScanDatas.add(staScanData); 2440 2441 ArrayList<WifiScanner.ScanData> scanDatas = new ArrayList<>(); 2442 ScanResult[] scanResults = new ScanResult[1]; 2443 scanResults[0] = result.second; 2444 WifiScanner.ScanData scanData = 2445 new WifiScanner.ScanData(mWifiVendorHal.mScan.cmdId, 1, 2446 staScanData.bucketsScanned, false, scanResults); 2447 scanDatas.add(scanData); 2448 return Pair.create(staScanDatas, scanDatas); 2449 } 2450 2451 private void assertScanResultEqual(ScanResult expected, ScanResult actual) { 2452 assertEquals(expected.SSID, actual.SSID); 2453 assertEquals(expected.wifiSsid.getHexString(), actual.wifiSsid.getHexString()); 2454 assertEquals(expected.BSSID, actual.BSSID); 2455 assertEquals(expected.frequency, actual.frequency); 2456 assertEquals(expected.level, actual.level); 2457 assertEquals(expected.timestamp, actual.timestamp); 2458 } 2459 2460 private void assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual) { 2461 assertEquals(expected.length, actual.length); 2462 for (int i = 0; i < expected.length; i++) { 2463 assertScanResultEqual(expected[i], actual[i]); 2464 } 2465 } 2466 2467 private void assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual) { 2468 assertEquals(expected.getId(), actual.getId()); 2469 assertEquals(expected.getFlags(), actual.getFlags()); 2470 assertEquals(expected.getBucketsScanned(), actual.getBucketsScanned()); 2471 assertScanResultsEqual(expected.getResults(), actual.getResults()); 2472 } 2473 2474 private void assertScanDatasEqual( 2475 List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual) { 2476 assertEquals(expected.size(), actual.size()); 2477 for (int i = 0; i < expected.size(); i++) { 2478 assertScanDataEqual(expected.get(i), actual.get(i)); 2479 } 2480 } 2481} 2482