WifiVendorHalTest.java revision af0e32cfa2f7402c60b9df88a0d9bd19f421026c
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 android.app.test.MockAnswerUtil.AnswerWithArguments; 20import android.hardware.wifi.V1_0.IWifiApIface; 21import android.hardware.wifi.V1_0.IWifiChip; 22import android.hardware.wifi.V1_0.IWifiChipEventCallback; 23import android.hardware.wifi.V1_0.IWifiIface; 24import android.hardware.wifi.V1_0.IWifiRttController; 25import android.hardware.wifi.V1_0.IWifiStaIface; 26import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback; 27import android.hardware.wifi.V1_0.RttCapabilities; 28import android.hardware.wifi.V1_0.RttConfig; 29import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities; 30import android.hardware.wifi.V1_0.StaBackgroundScanCapabilities; 31import android.hardware.wifi.V1_0.StaBackgroundScanParameters; 32import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats; 33import android.hardware.wifi.V1_0.StaLinkLayerRadioStats; 34import android.hardware.wifi.V1_0.StaLinkLayerStats; 35import android.hardware.wifi.V1_0.StaScanData; 36import android.hardware.wifi.V1_0.StaScanDataFlagMask; 37import android.hardware.wifi.V1_0.StaScanResult; 38import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats; 39import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType; 40import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags; 41import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus; 42import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel; 43import android.hardware.wifi.V1_0.WifiDebugRxPacketFate; 44import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport; 45import android.hardware.wifi.V1_0.WifiDebugTxPacketFate; 46import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport; 47import android.hardware.wifi.V1_0.WifiInformationElement; 48import android.hardware.wifi.V1_0.WifiStatus; 49import android.hardware.wifi.V1_0.WifiStatusCode; 50import android.net.apf.ApfCapabilities; 51import android.net.wifi.RttManager; 52import android.net.wifi.ScanResult; 53import android.net.wifi.WifiLinkLayerStats; 54import android.net.wifi.WifiManager; 55import android.net.wifi.WifiScanner; 56import android.net.wifi.WifiSsid; 57import android.net.wifi.WifiWakeReasonAndCounts; 58import android.os.HandlerThread; 59import android.os.RemoteException; 60import android.util.Pair; 61 62import com.android.server.connectivity.KeepalivePacketData; 63import com.android.server.wifi.util.NativeUtil; 64 65import static org.junit.Assert.*; 66import static org.mockito.Mockito.*; 67 68import org.junit.Before; 69import org.junit.Test; 70import org.mockito.ArgumentCaptor; 71import org.mockito.Mock; 72import org.mockito.MockitoAnnotations; 73import org.mockito.stubbing.Answer; 74 75import java.net.InetAddress; 76import java.util.ArrayList; 77import java.util.Arrays; 78import java.util.List; 79import java.util.Random; 80 81/** 82 * Unit tests for {@link com.android.server.wifi.WifiVendorHal}. 83 */ 84public class WifiVendorHalTest { 85 86 WifiVendorHal mWifiVendorHal; 87 private WifiStatus mWifiStatusSuccess; 88 private WifiStatus mWifiStatusFailure; 89 WifiLog mWifiLog; 90 @Mock 91 private HalDeviceManager mHalDeviceManager; 92 @Mock 93 private HandlerThread mWifiStateMachineHandlerThread; 94 @Mock 95 private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks; 96 @Mock 97 private IWifiApIface mIWifiApIface; 98 @Mock 99 private IWifiChip mIWifiChip; 100 @Mock 101 private IWifiStaIface mIWifiStaIface; 102 @Mock 103 private IWifiRttController mIWifiRttController; 104 private IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback; 105 private IWifiChipEventCallback mIWifiChipEventCallback; 106 @Mock 107 private WifiNative.VendorHalDeathEventHandler mVendorHalDeathHandler; 108 109 /** 110 * Identity function to supply a type to its argument, which is a lambda 111 */ 112 static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) { 113 return (statusLambda); 114 } 115 116 /** 117 * Sets up for unit test 118 */ 119 @Before 120 public void setUp() throws Exception { 121 MockitoAnnotations.initMocks(this); 122 mWifiLog = new FakeWifiLog(); 123 mWifiStatusSuccess = new WifiStatus(); 124 mWifiStatusSuccess.code = WifiStatusCode.SUCCESS; 125 mWifiStatusFailure = new WifiStatus(); 126 mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN; 127 mWifiStatusFailure.description = "I don't even know what a Mock Turtle is."; 128 when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess); 129 130 // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in 131 // individual tests, if needed. 132 doAnswer(new AnswerWithArguments() { 133 public boolean answer() { 134 when(mHalDeviceManager.isReady()).thenReturn(true); 135 when(mHalDeviceManager.isStarted()).thenReturn(true); 136 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 137 return true; 138 } 139 }).when(mHalDeviceManager).start(); 140 141 doAnswer(new AnswerWithArguments() { 142 public void answer() { 143 when(mHalDeviceManager.isReady()).thenReturn(true); 144 when(mHalDeviceManager.isStarted()).thenReturn(false); 145 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 146 } 147 }).when(mHalDeviceManager).stop(); 148 when(mHalDeviceManager.createStaIface(eq(null), eq(null))) 149 .thenReturn(mIWifiStaIface); 150 when(mHalDeviceManager.createApIface(eq(null), eq(null))) 151 .thenReturn(mIWifiApIface); 152 when(mHalDeviceManager.getChip(any(IWifiIface.class))) 153 .thenReturn(mIWifiChip); 154 when(mHalDeviceManager.createRttController(any(IWifiIface.class))) 155 .thenReturn(mIWifiRttController); 156 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 157 .thenReturn(mWifiStatusSuccess); 158 mIWifiStaIfaceEventCallback = null; 159 when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class))) 160 .thenAnswer(answerWifiStatus((invocation) -> { 161 Object[] args = invocation.getArguments(); 162 mIWifiStaIfaceEventCallback = (IWifiStaIfaceEventCallback) args[0]; 163 return (mWifiStatusSuccess); 164 })); 165 mIWifiChipEventCallback = null; 166 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 167 .thenAnswer(answerWifiStatus((invocation) -> { 168 Object[] args = invocation.getArguments(); 169 mIWifiChipEventCallback = (IWifiChipEventCallback) args[0]; 170 return (mWifiStatusSuccess); 171 })); 172 173 // Create the vendor HAL object under test. 174 mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread); 175 176 // Initialize the vendor HAL to capture the registered callback. 177 mWifiVendorHal.initialize(mVendorHalDeathHandler); 178 ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> hdmCallbackCaptor = 179 ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class); 180 verify(mHalDeviceManager).registerStatusListener(hdmCallbackCaptor.capture(), any()); 181 mHalDeviceManagerStatusCallbacks = hdmCallbackCaptor.getValue(); 182 183 } 184 185 /** 186 * Tests the successful starting of HAL in STA mode using 187 * {@link WifiVendorHal#startVendorHal(boolean)}. 188 */ 189 @Test 190 public void testStartHalSuccessInStaMode() throws Exception { 191 assertTrue(mWifiVendorHal.startVendorHal(true)); 192 assertTrue(mWifiVendorHal.isHalStarted()); 193 194 verify(mHalDeviceManager).start(); 195 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 196 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 197 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 198 verify(mHalDeviceManager).isReady(); 199 verify(mHalDeviceManager).isStarted(); 200 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 201 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 202 203 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 204 } 205 206 /** 207 * Tests the successful starting of HAL in AP mode using 208 * {@link WifiVendorHal#startVendorHal(boolean)}. 209 */ 210 @Test 211 public void testStartHalSuccessInApMode() throws Exception { 212 assertTrue(mWifiVendorHal.startVendorHal(false)); 213 assertTrue(mWifiVendorHal.isHalStarted()); 214 215 verify(mHalDeviceManager).start(); 216 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 217 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 218 verify(mHalDeviceManager).isReady(); 219 verify(mHalDeviceManager).isStarted(); 220 221 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 222 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 223 } 224 225 /** 226 * Tests the failure to start HAL in STA mode using 227 * {@link WifiVendorHal#startVendorHal(boolean)}. 228 */ 229 @Test 230 public void testStartHalFailureInStaMode() throws Exception { 231 // No callbacks are invoked in this case since the start itself failed. So, override 232 // default AnswerWithArguments that we setup. 233 doAnswer(new AnswerWithArguments() { 234 public boolean answer() throws Exception { 235 return false; 236 } 237 }).when(mHalDeviceManager).start(); 238 assertFalse(mWifiVendorHal.startVendorHal(true)); 239 assertFalse(mWifiVendorHal.isHalStarted()); 240 241 verify(mHalDeviceManager).start(); 242 243 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 244 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 245 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 246 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 247 verify(mIWifiStaIface, never()) 248 .registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 249 } 250 251 /** 252 * Tests the failure to start HAL in STA mode using 253 * {@link WifiVendorHal#startVendorHal(boolean)}. 254 */ 255 @Test 256 public void testStartHalFailureInIfaceCreationInStaMode() throws Exception { 257 when(mHalDeviceManager.createStaIface(eq(null), eq(null))).thenReturn(null); 258 assertFalse(mWifiVendorHal.startVendorHal(true)); 259 assertFalse(mWifiVendorHal.isHalStarted()); 260 261 verify(mHalDeviceManager).start(); 262 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 263 verify(mHalDeviceManager).stop(); 264 265 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 266 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 267 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 268 verify(mIWifiStaIface, never()) 269 .registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 270 } 271 272 /** 273 * Tests the failure to start HAL in STA mode using 274 * {@link WifiVendorHal#startVendorHal(boolean)}. 275 */ 276 @Test 277 public void testStartHalFailureInRttControllerCreationInStaMode() throws Exception { 278 when(mHalDeviceManager.createRttController(any(IWifiIface.class))).thenReturn(null); 279 assertFalse(mWifiVendorHal.startVendorHal(true)); 280 assertFalse(mWifiVendorHal.isHalStarted()); 281 282 verify(mHalDeviceManager).start(); 283 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 284 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 285 verify(mHalDeviceManager).stop(); 286 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 287 288 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 289 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 290 } 291 292 /** 293 * Tests the failure to start HAL in STA mode using 294 * {@link WifiVendorHal#startVendorHal(boolean)}. 295 */ 296 @Test 297 public void testStartHalFailureInChipGetInStaMode() throws Exception { 298 when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null); 299 assertFalse(mWifiVendorHal.startVendorHal(true)); 300 assertFalse(mWifiVendorHal.isHalStarted()); 301 302 verify(mHalDeviceManager).start(); 303 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 304 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 305 verify(mHalDeviceManager).getChip(any(IWifiIface.class)); 306 verify(mHalDeviceManager).stop(); 307 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 308 309 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 310 } 311 312 /** 313 * Tests the failure to start HAL in STA mode using 314 * {@link WifiVendorHal#startVendorHal(boolean)}. 315 */ 316 @Test 317 public void testStartHalFailureInStaIfaceCallbackRegistration() throws Exception { 318 when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class))) 319 .thenReturn(mWifiStatusFailure); 320 assertFalse(mWifiVendorHal.startVendorHal(true)); 321 assertFalse(mWifiVendorHal.isHalStarted()); 322 323 verify(mHalDeviceManager).start(); 324 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 325 verify(mHalDeviceManager).stop(); 326 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 327 328 verify(mHalDeviceManager, never()).createRttController(eq(mIWifiStaIface)); 329 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 330 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 331 } 332 333 /** 334 * Tests the failure to start HAL in STA mode using 335 * {@link WifiVendorHal#startVendorHal(boolean)}. 336 */ 337 @Test 338 public void testStartHalFailureInChipCallbackRegistration() throws Exception { 339 when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class))) 340 .thenReturn(mWifiStatusFailure); 341 assertFalse(mWifiVendorHal.startVendorHal(true)); 342 assertFalse(mWifiVendorHal.isHalStarted()); 343 344 verify(mHalDeviceManager).start(); 345 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 346 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 347 verify(mHalDeviceManager).getChip(any(IWifiIface.class)); 348 verify(mHalDeviceManager).stop(); 349 verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class)); 350 verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class)); 351 352 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 353 } 354 355 /** 356 * Tests the failure to start HAL in STA mode using 357 * {@link WifiVendorHal#startVendorHal(boolean)}. 358 */ 359 @Test 360 public void testStartHalFailureInApMode() throws Exception { 361 when(mHalDeviceManager.createApIface(eq(null), eq(null))).thenReturn(null); 362 assertFalse(mWifiVendorHal.startVendorHal(false)); 363 assertFalse(mWifiVendorHal.isHalStarted()); 364 365 verify(mHalDeviceManager).start(); 366 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 367 verify(mHalDeviceManager).stop(); 368 369 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 370 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 371 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 372 } 373 374 /** 375 * Tests the stopping of HAL in STA mode using 376 * {@link WifiVendorHal#stopVendorHal()}. 377 */ 378 @Test 379 public void testStopHalInStaMode() { 380 assertTrue(mWifiVendorHal.startVendorHal(true)); 381 assertTrue(mWifiVendorHal.isHalStarted()); 382 383 mWifiVendorHal.stopVendorHal(); 384 assertFalse(mWifiVendorHal.isHalStarted()); 385 386 verify(mHalDeviceManager).start(); 387 verify(mHalDeviceManager).stop(); 388 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 389 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 390 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 391 verify(mHalDeviceManager, times(2)).isReady(); 392 verify(mHalDeviceManager, times(2)).isStarted(); 393 394 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 395 } 396 397 /** 398 * Tests the stopping of HAL in AP mode using 399 * {@link WifiVendorHal#stopVendorHal()}. 400 */ 401 @Test 402 public void testStopHalInApMode() { 403 assertTrue(mWifiVendorHal.startVendorHal(false)); 404 assertTrue(mWifiVendorHal.isHalStarted()); 405 406 mWifiVendorHal.stopVendorHal(); 407 assertFalse(mWifiVendorHal.isHalStarted()); 408 409 verify(mHalDeviceManager).start(); 410 verify(mHalDeviceManager).stop(); 411 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 412 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 413 verify(mHalDeviceManager, times(2)).isReady(); 414 verify(mHalDeviceManager, times(2)).isStarted(); 415 416 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 417 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 418 } 419 420 /** 421 * Test that enter logs when verbose logging is enabled 422 */ 423 @Test 424 public void testEnterLogging() { 425 mWifiVendorHal.mLog = spy(mWifiLog); 426 mWifiVendorHal.enableVerboseLogging(true); 427 mWifiVendorHal.installPacketFilter(new byte[0]); 428 verify(mWifiVendorHal.mLog).trace(eq("% filter length %")); 429 } 430 431 /** 432 * Test that enter does not log when verbose logging is not enabled 433 */ 434 @Test 435 public void testEnterSilenceWhenNotEnabled() { 436 mWifiVendorHal.mLog = spy(mWifiLog); 437 mWifiVendorHal.installPacketFilter(new byte[0]); 438 mWifiVendorHal.enableVerboseLogging(true); 439 mWifiVendorHal.enableVerboseLogging(false); 440 mWifiVendorHal.installPacketFilter(new byte[0]); 441 verify(mWifiVendorHal.mLog, never()).trace(eq("% filter length %")); 442 } 443 444 /** 445 * Test that boolResult logs a false result 446 */ 447 @Test 448 public void testBoolResultFalse() { 449 mWifiLog = spy(mWifiLog); 450 mWifiVendorHal.mLog = mWifiLog; 451 mWifiVendorHal.mVerboseLog = mWifiLog; 452 assertFalse(mWifiVendorHal.getBgScanCapabilities(new WifiNative.ScanCapabilities())); 453 verify(mWifiLog).err("% returns %"); 454 } 455 456 /** 457 * Test that getBgScanCapabilities is hooked up to the HAL correctly 458 * 459 * A call before the vendor HAL is started should return a non-null result with version 0 460 * 461 * A call after the HAL is started should return the mocked values. 462 */ 463 @Test 464 public void testGetBgScanCapabilities() throws Exception { 465 StaBackgroundScanCapabilities capabilities = new StaBackgroundScanCapabilities(); 466 capabilities.maxCacheSize = 12; 467 capabilities.maxBuckets = 34; 468 capabilities.maxApCachePerScan = 56; 469 capabilities.maxReportingThreshold = 78; 470 471 doAnswer(new AnswerWithArguments() { 472 public void answer(IWifiStaIface.getBackgroundScanCapabilitiesCallback cb) 473 throws RemoteException { 474 cb.onValues(mWifiStatusSuccess, capabilities); 475 } 476 }).when(mIWifiStaIface).getBackgroundScanCapabilities(any( 477 IWifiStaIface.getBackgroundScanCapabilitiesCallback.class)); 478 479 WifiNative.ScanCapabilities result = new WifiNative.ScanCapabilities(); 480 481 assertFalse(mWifiVendorHal.getBgScanCapabilities(result)); // should fail - not started 482 assertTrue(mWifiVendorHal.startVendorHalSta()); // Start the vendor hal 483 assertTrue(mWifiVendorHal.getBgScanCapabilities(result)); // should succeed 484 485 assertEquals(12, result.max_scan_cache_size); 486 assertEquals(34, result.max_scan_buckets); 487 assertEquals(56, result.max_ap_cache_per_scan); 488 assertEquals(78, result.max_scan_reporting_threshold); 489 } 490 491 private void setupValidFrequenciesForBand(ArrayList<Integer> frequencies) throws Exception { 492 493 doAnswer(new AnswerWithArguments() { 494 public void answer(int band, IWifiStaIface.getValidFrequenciesForBandCallback cb) 495 throws RemoteException { 496 cb.onValues(mWifiStatusSuccess, frequencies); 497 } 498 }).when(mIWifiStaIface).getValidFrequenciesForBand(anyInt(), any( 499 IWifiStaIface.getValidFrequenciesForBandCallback.class)); 500 501 doAnswer(new AnswerWithArguments() { 502 public void answer(int band, IWifiApIface.getValidFrequenciesForBandCallback cb) 503 throws RemoteException { 504 cb.onValues(mWifiStatusSuccess, frequencies); 505 } 506 }).when(mIWifiApIface).getValidFrequenciesForBand(anyInt(), any( 507 IWifiApIface.getValidFrequenciesForBandCallback.class)); 508 509 } 510 511 private int[] intArrayFromArrayList(ArrayList<Integer> in) { 512 int[] ans = new int[in.size()]; 513 int i = 0; 514 for (Integer e : in) ans[i++] = e; 515 return ans; 516 } 517 518 /** 519 * Test that isGetChannelsForBandSupported works in STA mode 520 */ 521 @Test 522 public void testGetChannelsForBandSupportedSta() throws Exception { 523 ArrayList<Integer> freq = new ArrayList<>(); 524 freq.add(2405); 525 526 setupValidFrequenciesForBand(freq); 527 528 assertFalse(mWifiVendorHal.isGetChannelsForBandSupported()); 529 530 assertTrue(mWifiVendorHal.startVendorHalSta()); 531 532 assertTrue(mWifiVendorHal.isGetChannelsForBandSupported()); 533 } 534 535 /** 536 * Test that isGetChannelsForBandSupported works in AP mode 537 */ 538 @Test 539 public void testGetChannelsForBandSupportedAp() throws Exception { 540 ArrayList<Integer> freq = new ArrayList<>(); 541 freq.add(2405); 542 543 setupValidFrequenciesForBand(freq); 544 545 assertFalse(mWifiVendorHal.isGetChannelsForBandSupported()); 546 547 assertTrue(mWifiVendorHal.startVendorHalAp()); 548 549 assertTrue(mWifiVendorHal.isGetChannelsForBandSupported()); 550 } 551 552 /** 553 * Test translation to WifiManager.WIFI_FEATURE_* 554 * 555 * Just do a spot-check with a few feature bits here; since the code is table- 556 * driven we don't have to work hard to exercise all of it. 557 */ 558 @Test 559 public void testFeatureMaskTranslation() { 560 int caps = ( 561 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN 562 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS 563 ); 564 int expected = ( 565 WifiManager.WIFI_FEATURE_SCANNER 566 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS); 567 assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps)); 568 } 569 570 /** 571 * Test enablement of link layer stats after startup 572 * 573 * Request link layer stats before HAL start 574 * - should not make it to the HAL layer 575 * Start the HAL in STA mode 576 * Request link layer stats twice more 577 * - enable request should make it to the HAL layer 578 * - HAL layer should have been called to make the requests (i.e., two calls total) 579 */ 580 @Test 581 public void testLinkLayerStatsEnableAfterStartup() throws Exception { 582 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 583 584 assertNull(mWifiVendorHal.getWifiLinkLayerStats()); 585 assertTrue(mWifiVendorHal.startVendorHalSta()); 586 assertTrue(mWifiVendorHal.isHalStarted()); 587 588 verify(mHalDeviceManager).start(); 589 mWifiVendorHal.getWifiLinkLayerStats(); 590 mWifiVendorHal.getWifiLinkLayerStats(); 591 verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug 592 verify(mIWifiStaIface, times(2)).getLinkLayerStats(any()); 593 } 594 595 /** 596 * Test that link layer stats are not enabled and harmless in AP mode 597 * 598 * Start the HAL in AP mode 599 * - stats should not be enabled 600 * Request link layer stats 601 * - HAL layer should have been called to make the request 602 */ 603 @Test 604 public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception { 605 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 606 607 assertTrue(mWifiVendorHal.startVendorHalAp()); 608 assertTrue(mWifiVendorHal.isHalStarted()); 609 assertNull(mWifiVendorHal.getWifiLinkLayerStats()); 610 611 verify(mHalDeviceManager).start(); 612 613 verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false); 614 verify(mIWifiStaIface, never()).getLinkLayerStats(any()); 615 } 616 617 /** 618 * Test that the link layer stats fields are populated correctly. 619 * 620 * This is done by filling with random values and then using toString on the 621 * original and converted values, comparing just the numerics in the result. 622 * This makes the assumption that the fields are in the same order in both string 623 * representations, which is not quite true. So apply some fixups before the final 624 * comparison. 625 */ 626 @Test 627 public void testLinkLayerStatsAssignment() throws Exception { 628 Random r = new Random(1775968256); 629 StaLinkLayerStats stats = new StaLinkLayerStats(); 630 randomizePacketStats(r, stats.iface.wmeBePktStats); 631 randomizePacketStats(r, stats.iface.wmeBkPktStats); 632 randomizePacketStats(r, stats.iface.wmeViPktStats); 633 randomizePacketStats(r, stats.iface.wmeVoPktStats); 634 randomizeRadioStats(r, stats.radios); 635 636 stats.timeStampInMs = 42; // currently dropped in conversion 637 638 String expected = numbersOnly(stats.toString()); 639 640 WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats); 641 642 String actual = numbersOnly(converted.toString()); 643 644 // Do the required fixups to the both expected and actual 645 expected = rmValue(expected, stats.radios.get(0).rxTimeInMs); 646 expected = rmValue(expected, stats.radios.get(0).onTimeInMsForScan); 647 648 actual = rmValue(actual, stats.radios.get(0).rxTimeInMs); 649 actual = rmValue(actual, stats.radios.get(0).onTimeInMsForScan); 650 actual = actual + "42 "; 651 652 // The remaining fields should agree 653 assertEquals(expected, actual); 654 } 655 656 /** Just the digits with delimiting spaces, please */ 657 private static String numbersOnly(String s) { 658 return s.replaceAll("[^0-9]+", " "); 659 } 660 661 /** Remove the given value from the space-delimited string, or die trying. */ 662 private static String rmValue(String s, long value) throws Exception { 663 String ans = s.replaceAll(" " + value + " ", " "); 664 assertNotEquals(s, ans); 665 return ans; 666 } 667 668 /** 669 * Populate packet stats with non-negative random values 670 */ 671 private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) { 672 pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits 673 pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL; 674 pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL; 675 pstats.retries = r.nextLong() & 0xFFFFFFFFFFL; 676 } 677 678 /** 679 * Populate radio stats with non-negative random values 680 */ 681 private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) { 682 StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats(); 683 rstat.onTimeInMs = r.nextInt() & 0xFFFFFF; 684 rstat.txTimeInMs = r.nextInt() & 0xFFFFFF; 685 for (int i = 0; i < 4; i++) { 686 Integer v = r.nextInt() & 0xFFFFFF; 687 rstat.txTimeInMsPerLevel.add(v); 688 } 689 rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF; 690 rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF; 691 rstats.add(rstat); 692 } 693 694 /** 695 * Test that getFirmwareVersion() and getDriverVersion() work 696 * 697 * Calls before the STA is started are expected to return null. 698 */ 699 @Test 700 public void testVersionGetters() throws Exception { 701 String firmwareVersion = "fuzzy"; 702 String driverVersion = "dizzy"; 703 IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo(); 704 chipDebugInfo.firmwareDescription = firmwareVersion; 705 chipDebugInfo.driverDescription = driverVersion; 706 707 doAnswer(new AnswerWithArguments() { 708 public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException { 709 cb.onValues(mWifiStatusSuccess, chipDebugInfo); 710 } 711 }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class)); 712 713 assertNull(mWifiVendorHal.getFirmwareVersion()); 714 assertNull(mWifiVendorHal.getDriverVersion()); 715 716 assertTrue(mWifiVendorHal.startVendorHalSta()); 717 718 assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion()); 719 assertEquals(driverVersion, mWifiVendorHal.getDriverVersion()); 720 } 721 722 /** 723 * For checkRoundTripIntTranslation lambdas 724 */ 725 interface IntForInt { 726 int translate(int value); 727 } 728 729 /** 730 * Checks that translation from x to y and back again is the identity function 731 * 732 * @param xFromY reverse translator 733 * @param yFromX forward translator 734 * @param xLimit non-inclusive upper bound on x (lower bound is zero) 735 */ 736 private void checkRoundTripIntTranslation( 737 IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit) throws Exception { 738 int ex = 0; 739 for (int i = xFirst; i < xLimit; i++) { 740 assertEquals(i, xFromY.translate(yFromX.translate(i))); 741 } 742 try { 743 yFromX.translate(xLimit); 744 assertTrue("expected an exception here", false); 745 } catch (IllegalArgumentException e) { 746 ex++; 747 } 748 try { 749 xFromY.translate(yFromX.translate(xLimit - 1) + 1); 750 assertTrue("expected an exception here", false); 751 } catch (IllegalArgumentException e) { 752 ex++; 753 } 754 assertEquals(2, ex); 755 } 756 757 758 /** 759 * Test translations of RTT type 760 */ 761 @Test 762 public void testRttTypeTranslation() throws Exception { 763 checkRoundTripIntTranslation( 764 (y) -> WifiVendorHal.halRttTypeFromFrameworkRttType(y), 765 (x) -> WifiVendorHal.frameworkRttTypeFromHalRttType(x), 766 1, 3); 767 } 768 769 /** 770 * Test translations of peer type 771 */ 772 @Test 773 public void testPeerTranslation() throws Exception { 774 checkRoundTripIntTranslation( 775 (y) -> WifiVendorHal.halPeerFromFrameworkPeer(y), 776 (x) -> WifiVendorHal.frameworkPeerFromHalPeer(x), 777 1, 6); 778 } 779 780 /** 781 * Test translations of channel width 782 */ 783 @Test 784 public void testChannelWidth() throws Exception { 785 checkRoundTripIntTranslation( 786 (y) -> WifiVendorHal.halChannelWidthFromFrameworkChannelWidth(y), 787 (x) -> WifiVendorHal.frameworkChannelWidthFromHalChannelWidth(x), 788 0, 5); 789 } 790 791 /** 792 * Test translations of preamble type mask 793 */ 794 @Test 795 public void testPreambleTranslation() throws Exception { 796 checkRoundTripIntTranslation( 797 (y) -> WifiVendorHal.halPreambleFromFrameworkPreamble(y), 798 (x) -> WifiVendorHal.frameworkPreambleFromHalPreamble(x), 799 0, 8); 800 } 801 802 /** 803 * Test translations of bandwidth mask 804 */ 805 @Test 806 public void testBandwidthTranslations() throws Exception { 807 checkRoundTripIntTranslation( 808 (y) -> WifiVendorHal.halBwFromFrameworkBw(y), 809 (x) -> WifiVendorHal.frameworkBwFromHalBw(x), 810 0, 64); 811 } 812 813 @Test 814 public void testGetRttStuff() throws Exception { 815 RttManager.RttParams params = new RttManager.RttParams(); 816 //TODO(b/34901744) populate 817 RttConfig config = WifiVendorHal.halRttConfigFromFrameworkRttParams(params); 818 //TODO(b/34901744) check 819 } 820 821 @Test 822 public void testGetRttCapabilities() throws Exception { 823 RttCapabilities capabilities = new RttCapabilities(); 824 //TODO(b/34901744) populate 825 826 doAnswer(new AnswerWithArguments() { 827 public void answer(IWifiRttController.getCapabilitiesCallback cb) 828 throws RemoteException { 829 cb.onValues(mWifiStatusSuccess, capabilities); 830 } 831 }).when(mIWifiRttController).getCapabilities(any( 832 IWifiRttController.getCapabilitiesCallback.class)); 833 834 assertNull(mWifiVendorHal.getRttCapabilities()); 835 836 assertTrue(mWifiVendorHal.startVendorHalSta()); 837 838 RttManager.RttCapabilities actual = mWifiVendorHal.getRttCapabilities(); 839 //TODO(b/34901744) check 840 841 } 842 843 //TODO(b/34901744) negative RTT test cases as well. 844 // e.g. invoke RTT without putting the HAL in the correct mode. 845 846 /** 847 * Test that setScanningMacOui is hooked up to the HAL correctly 848 */ 849 @Test 850 public void testSetScanningMacOui() throws Exception { 851 byte[] oui = NativeUtil.macAddressOuiToByteArray("DA:A1:19"); 852 byte[] zzz = NativeUtil.macAddressOuiToByteArray("00:00:00"); 853 854 when(mIWifiStaIface.setScanningMacOui(any())).thenReturn(mWifiStatusSuccess); 855 856 assertFalse(mWifiVendorHal.setScanningMacOui(oui)); // expect fail - STA not started 857 assertTrue(mWifiVendorHal.startVendorHalSta()); 858 assertFalse(mWifiVendorHal.setScanningMacOui(null)); // expect fail - null 859 assertFalse(mWifiVendorHal.setScanningMacOui(new byte[]{(byte) 1})); // expect fail - len 860 assertTrue(mWifiVendorHal.setScanningMacOui(oui)); 861 assertTrue(mWifiVendorHal.setScanningMacOui(zzz)); 862 863 verify(mIWifiStaIface).setScanningMacOui(eq(oui)); 864 verify(mIWifiStaIface).setScanningMacOui(eq(zzz)); 865 } 866 867 @Test 868 public void testStartSendingOffloadedPacket() throws Exception { 869 byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81"); 870 InetAddress src = InetAddress.parseNumericAddress("192.168.13.13"); 871 InetAddress dst = InetAddress.parseNumericAddress("93.184.216.34"); 872 int slot = 13; 873 int millis = 16000; 874 875 KeepalivePacketData kap = KeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500); 876 877 when(mIWifiStaIface.startSendingKeepAlivePackets( 878 anyInt(), any(), anyShort(), any(), any(), anyInt() 879 )).thenReturn(mWifiStatusSuccess); 880 881 assertTrue(mWifiVendorHal.startVendorHalSta()); 882 assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket(slot, srcMac, kap, millis)); 883 884 verify(mIWifiStaIface).startSendingKeepAlivePackets( 885 eq(slot), any(), anyShort(), any(), any(), eq(millis)); 886 } 887 888 @Test 889 public void testStopSendingOffloadedPacket() throws Exception { 890 int slot = 13; 891 892 when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess); 893 894 assertTrue(mWifiVendorHal.startVendorHalSta()); 895 assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket(slot)); 896 897 verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot)); 898 } 899 900 /** 901 * Test the setup, invocation, and removal of a RSSI event handler 902 * 903 */ 904 @Test 905 public void testRssiMonitoring() throws Exception { 906 when(mIWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt())) 907 .thenReturn(mWifiStatusSuccess); 908 when(mIWifiStaIface.stopRssiMonitoring(anyInt())) 909 .thenReturn(mWifiStatusSuccess); 910 911 ArrayList<Byte> breach = new ArrayList<>(10); 912 byte hi = -21; 913 byte med = -42; 914 byte lo = -84; 915 Byte lower = -88; 916 WifiNative.WifiRssiEventHandler handler; 917 handler = ((cur) -> { 918 breach.add(cur); 919 }); 920 assertEquals(-1, mWifiVendorHal.startRssiMonitoring(hi, lo, handler)); // not started 921 assertEquals(-1, mWifiVendorHal.stopRssiMonitoring()); // not started 922 assertTrue(mWifiVendorHal.startVendorHalSta()); 923 assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler)); 924 int theCmdId = mWifiVendorHal.sRssiMonCmdId; 925 breach.clear(); 926 mIWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower); 927 assertEquals(breach.get(0), lower); 928 assertEquals(0, mWifiVendorHal.stopRssiMonitoring()); 929 assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler)); 930 assertEquals(0, mWifiVendorHal.startRssiMonitoring(med, lo, handler)); // replacing works 931 assertEquals(-1, mWifiVendorHal.startRssiMonitoring(hi, lo, null)); // null handler fails 932 assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler)); 933 assertEquals(-1, mWifiVendorHal.startRssiMonitoring(lo, hi, handler)); // empty range 934 } 935 936 /** 937 * Test that getApfCapabilities is hooked up to the HAL correctly 938 * 939 * A call before the vendor HAL is started should return a non-null result with version 0 940 * 941 * A call after the HAL is started should return the mocked values. 942 */ 943 @Test 944 public void testApfCapabilities() throws Exception { 945 int myVersion = 33; 946 int myMaxSize = 1234; 947 948 StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities(); 949 capabilities.version = myVersion; 950 capabilities.maxLength = myMaxSize; 951 952 doAnswer(new AnswerWithArguments() { 953 public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb) 954 throws RemoteException { 955 cb.onValues(mWifiStatusSuccess, capabilities); 956 } 957 }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any( 958 IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class)); 959 960 961 assertEquals(0, mWifiVendorHal.getApfCapabilities().apfVersionSupported); 962 963 assertTrue(mWifiVendorHal.startVendorHalSta()); 964 965 ApfCapabilities actual = mWifiVendorHal.getApfCapabilities(); 966 967 assertEquals(myVersion, actual.apfVersionSupported); 968 assertEquals(myMaxSize, actual.maximumApfProgramSize); 969 assertEquals(android.system.OsConstants.ARPHRD_ETHER, actual.apfPacketFormat); 970 assertNotEquals(0, actual.apfPacketFormat); 971 } 972 973 /** 974 * Test that an APF program can be installed. 975 */ 976 @Test 977 public void testInstallApf() throws Exception { 978 byte[] filter = new byte[] {19, 53, 10}; 979 980 ArrayList<Byte> expected = new ArrayList<>(3); 981 for (byte b : filter) expected.add(b); 982 983 when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class))) 984 .thenReturn(mWifiStatusSuccess); 985 986 assertTrue(mWifiVendorHal.startVendorHalSta()); 987 assertTrue(mWifiVendorHal.installPacketFilter(filter)); 988 989 verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected)); 990 } 991 992 /** 993 * Test that the country code is set in AP mode (when it should be). 994 */ 995 @Test 996 public void testSetCountryCodeHal() throws Exception { 997 byte[] expected = new byte[]{(byte) 'C', (byte) 'A'}; 998 999 when(mIWifiApIface.setCountryCode(any())) 1000 .thenReturn(mWifiStatusSuccess); 1001 1002 assertTrue(mWifiVendorHal.startVendorHalAp()); 1003 1004 assertFalse(mWifiVendorHal.setCountryCodeHal(null)); 1005 assertFalse(mWifiVendorHal.setCountryCodeHal("")); 1006 assertFalse(mWifiVendorHal.setCountryCodeHal("A")); 1007 assertTrue(mWifiVendorHal.setCountryCodeHal("CA")); // Only one expected to succeed 1008 assertFalse(mWifiVendorHal.setCountryCodeHal("ZZZ")); 1009 1010 verify(mIWifiApIface).setCountryCode(eq(expected)); 1011 } 1012 1013 /** 1014 * Test that RemoteException is caught and logged. 1015 */ 1016 @Test 1017 public void testRemoteExceptionIsHandled() throws Exception { 1018 mWifiLog = spy(mWifiLog); 1019 mWifiVendorHal.mVerboseLog = mWifiLog; 1020 when(mIWifiApIface.setCountryCode(any())) 1021 .thenThrow(new RemoteException("oops")); 1022 assertTrue(mWifiVendorHal.startVendorHalAp()); 1023 assertFalse(mWifiVendorHal.setCountryCodeHal("CA")); 1024 assertFalse(mWifiVendorHal.isHalStarted()); 1025 verify(mWifiLog).err(any()); 1026 } 1027 1028 /** 1029 * Test that startLoggingToDebugRingBuffer is plumbed to chip 1030 * 1031 * A call before the vendor hal is started should just return false. 1032 * After starting in STA mode, the call should succeed, and pass ther right things down. 1033 */ 1034 @Test 1035 public void testStartLoggingRingBuffer() throws Exception { 1036 when(mIWifiChip.startLoggingToDebugRingBuffer( 1037 any(String.class), anyInt(), anyInt(), anyInt() 1038 )).thenReturn(mWifiStatusSuccess); 1039 1040 assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One")); 1041 assertTrue(mWifiVendorHal.startVendorHalSta()); 1042 assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One")); 1043 1044 verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000); 1045 } 1046 1047 /** 1048 * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA. 1049 */ 1050 @Test 1051 public void testStartLoggingRingBufferOnAp() throws Exception { 1052 when(mIWifiChip.startLoggingToDebugRingBuffer( 1053 any(String.class), anyInt(), anyInt(), anyInt() 1054 )).thenReturn(mWifiStatusSuccess); 1055 1056 assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One")); 1057 assertTrue(mWifiVendorHal.startVendorHalAp()); 1058 assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One")); 1059 1060 verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000); 1061 } 1062 1063 /** 1064 * Test that getRingBufferStatus gets and translates its stuff correctly 1065 */ 1066 @Test 1067 public void testRingBufferStatus() throws Exception { 1068 WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus(); 1069 one.ringName = "One"; 1070 one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES; 1071 one.ringId = 5607371; 1072 one.sizeInBytes = 54321; 1073 one.freeSizeInBytes = 42; 1074 one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE; 1075 String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321" 1076 + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0"; 1077 1078 WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus(); 1079 two.ringName = "Two"; 1080 two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES 1081 | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES; 1082 two.ringId = 4512470; 1083 two.sizeInBytes = 300; 1084 two.freeSizeInBytes = 42; 1085 two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT; 1086 1087 ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2); 1088 halBufferStatus.add(one); 1089 halBufferStatus.add(two); 1090 1091 WifiNative.RingBufferStatus[] actual; 1092 1093 doAnswer(new AnswerWithArguments() { 1094 public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb) 1095 throws RemoteException { 1096 cb.onValues(mWifiStatusSuccess, halBufferStatus); 1097 } 1098 }).when(mIWifiChip).getDebugRingBuffersStatus(any( 1099 IWifiChip.getDebugRingBuffersStatusCallback.class)); 1100 1101 assertTrue(mWifiVendorHal.startVendorHalSta()); 1102 actual = mWifiVendorHal.getRingBufferStatus(); 1103 1104 assertEquals(halBufferStatus.size(), actual.length); 1105 assertEquals(oneExpect, actual[0].toString()); 1106 assertEquals(two.ringId, actual[1].ringBufferId); 1107 1108 } 1109 1110 /** 1111 * Test that getRingBufferData calls forceDumpToDebugRingBuffer 1112 * 1113 * Try once before hal start, and twice after (one success, one failure). 1114 */ 1115 @Test 1116 public void testForceRingBufferDump() throws Exception { 1117 when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess); 1118 when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure); 1119 1120 assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started 1121 1122 assertTrue(mWifiVendorHal.startVendorHalSta()); 1123 1124 assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds 1125 assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails 1126 1127 verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk"); 1128 verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop"); 1129 } 1130 1131 /** 1132 * Tests the start of packet fate monitoring. 1133 * 1134 * Try once before hal start, and once after (one success, one failure). 1135 */ 1136 @Test 1137 public void testStartPktFateMonitoring() throws Exception { 1138 when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess); 1139 1140 assertFalse(mWifiVendorHal.startPktFateMonitoring()); 1141 verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring(); 1142 1143 assertTrue(mWifiVendorHal.startVendorHalSta()); 1144 assertTrue(mWifiVendorHal.startPktFateMonitoring()); 1145 verify(mIWifiStaIface).startDebugPacketFateMonitoring(); 1146 } 1147 1148 /** 1149 * Tests the retrieval of tx packet fates. 1150 * 1151 * Try once before hal start, and once after. 1152 */ 1153 @Test 1154 public void testGetTxPktFates() throws Exception { 1155 byte[] frameContentBytes = new byte[30]; 1156 new Random().nextBytes(frameContentBytes); 1157 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 1158 fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED; 1159 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1160 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 1161 fateReport.frameInfo.frameContent.addAll( 1162 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1163 1164 doAnswer(new AnswerWithArguments() { 1165 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 1166 cb.onValues(mWifiStatusSuccess, 1167 new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(fateReport))); 1168 } 1169 }).when(mIWifiStaIface) 1170 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1171 1172 WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1]; 1173 assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates)); 1174 verify(mIWifiStaIface, never()) 1175 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1176 1177 assertTrue(mWifiVendorHal.startVendorHalSta()); 1178 1179 assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates)); 1180 verify(mIWifiStaIface) 1181 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1182 assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFates[0].mFate); 1183 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1184 retrievedFates[0].mDriverTimestampUSec); 1185 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType); 1186 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1187 } 1188 1189 /** 1190 * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the 1191 * input array. 1192 * 1193 * Try once before hal start, and once after. 1194 */ 1195 @Test 1196 public void testGetTxPktFatesExceedsInputArrayLength() throws Exception { 1197 byte[] frameContentBytes = new byte[30]; 1198 new Random().nextBytes(frameContentBytes); 1199 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 1200 fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER; 1201 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1202 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 1203 fateReport.frameInfo.frameContent.addAll( 1204 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1205 1206 doAnswer(new AnswerWithArguments() { 1207 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 1208 cb.onValues(mWifiStatusSuccess, 1209 new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList( 1210 fateReport, fateReport))); 1211 } 1212 }).when(mIWifiStaIface) 1213 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1214 1215 WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1]; 1216 assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates)); 1217 verify(mIWifiStaIface, never()) 1218 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1219 1220 assertTrue(mWifiVendorHal.startVendorHalSta()); 1221 1222 assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates)); 1223 verify(mIWifiStaIface) 1224 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1225 assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFates[0].mFate); 1226 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1227 retrievedFates[0].mDriverTimestampUSec); 1228 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType); 1229 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1230 } 1231 1232 /** 1233 * Tests the retrieval of rx packet fates. 1234 * 1235 * Try once before hal start, and once after. 1236 */ 1237 @Test 1238 public void testGetRxPktFates() throws Exception { 1239 byte[] frameContentBytes = new byte[30]; 1240 new Random().nextBytes(frameContentBytes); 1241 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 1242 fateReport.fate = WifiDebugRxPacketFate.SUCCESS; 1243 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1244 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 1245 fateReport.frameInfo.frameContent.addAll( 1246 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1247 1248 doAnswer(new AnswerWithArguments() { 1249 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 1250 cb.onValues(mWifiStatusSuccess, 1251 new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(fateReport))); 1252 } 1253 }).when(mIWifiStaIface) 1254 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1255 1256 WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1]; 1257 assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates)); 1258 verify(mIWifiStaIface, never()) 1259 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1260 1261 assertTrue(mWifiVendorHal.startVendorHalSta()); 1262 1263 assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates)); 1264 verify(mIWifiStaIface) 1265 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1266 assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFates[0].mFate); 1267 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1268 retrievedFates[0].mDriverTimestampUSec); 1269 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType); 1270 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1271 } 1272 1273 /** 1274 * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the 1275 * input array. 1276 * 1277 * Try once before hal start, and once after. 1278 */ 1279 @Test 1280 public void testGetRxPktFatesExceedsInputArrayLength() throws Exception { 1281 byte[] frameContentBytes = new byte[30]; 1282 new Random().nextBytes(frameContentBytes); 1283 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 1284 fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER; 1285 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 1286 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 1287 fateReport.frameInfo.frameContent.addAll( 1288 NativeUtil.byteArrayToArrayList(frameContentBytes)); 1289 1290 doAnswer(new AnswerWithArguments() { 1291 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 1292 cb.onValues(mWifiStatusSuccess, 1293 new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList( 1294 fateReport, fateReport))); 1295 } 1296 }).when(mIWifiStaIface) 1297 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1298 1299 WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1]; 1300 assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates)); 1301 verify(mIWifiStaIface, never()) 1302 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1303 1304 assertTrue(mWifiVendorHal.startVendorHalSta()); 1305 1306 assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates)); 1307 verify(mIWifiStaIface) 1308 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1309 assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFates[0].mFate); 1310 assertEquals(fateReport.frameInfo.driverTimestampUsec, 1311 retrievedFates[0].mDriverTimestampUSec); 1312 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType); 1313 assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes); 1314 } 1315 1316 /** 1317 * Tests the failure to retrieve tx packet fates when the input array is empty. 1318 */ 1319 @Test 1320 public void testGetTxPktFatesEmptyInputArray() throws Exception { 1321 assertTrue(mWifiVendorHal.startVendorHalSta()); 1322 assertFalse(mWifiVendorHal.getTxPktFates(new WifiNative.TxFateReport[0])); 1323 verify(mIWifiStaIface, never()) 1324 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 1325 } 1326 1327 /** 1328 * Tests the failure to retrieve rx packet fates when the input array is empty. 1329 */ 1330 @Test 1331 public void testGetRxPktFatesEmptyInputArray() throws Exception { 1332 assertTrue(mWifiVendorHal.startVendorHalSta()); 1333 assertFalse(mWifiVendorHal.getRxPktFates(new WifiNative.RxFateReport[0])); 1334 verify(mIWifiStaIface, never()) 1335 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 1336 } 1337 1338 /** 1339 * Tests the nd offload enable/disable. 1340 */ 1341 @Test 1342 public void testEnableDisableNdOffload() throws Exception { 1343 when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess); 1344 1345 assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true)); 1346 verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean()); 1347 1348 assertTrue(mWifiVendorHal.startVendorHalSta()); 1349 1350 assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(true)); 1351 verify(mIWifiStaIface).enableNdOffload(eq(true)); 1352 assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(false)); 1353 verify(mIWifiStaIface).enableNdOffload(eq(false)); 1354 } 1355 1356 /** 1357 * Tests the nd offload enable failure. 1358 */ 1359 @Test 1360 public void testEnableNdOffloadFailure() throws Exception { 1361 when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure); 1362 1363 assertTrue(mWifiVendorHal.startVendorHalSta()); 1364 1365 assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true)); 1366 verify(mIWifiStaIface).enableNdOffload(eq(true)); 1367 } 1368 1369 /** 1370 * Tests the retrieval of wlan wake reason stats. 1371 */ 1372 @Test 1373 public void testGetWlanWakeReasonCount() throws Exception { 1374 WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats(); 1375 Random rand = new Random(); 1376 stats.totalCmdEventWakeCnt = rand.nextInt(); 1377 stats.totalDriverFwLocalWakeCnt = rand.nextInt(); 1378 stats.totalRxPacketWakeCnt = rand.nextInt(); 1379 stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt(); 1380 stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt(); 1381 stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt(); 1382 stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt(); 1383 stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt(); 1384 stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt(); 1385 1386 doAnswer(new AnswerWithArguments() { 1387 public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) { 1388 cb.onValues(mWifiStatusSuccess, stats); 1389 } 1390 }).when(mIWifiChip).getDebugHostWakeReasonStats( 1391 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1392 1393 assertNull(mWifiVendorHal.getWlanWakeReasonCount()); 1394 verify(mIWifiChip, never()) 1395 .getDebugHostWakeReasonStats( 1396 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1397 1398 assertTrue(mWifiVendorHal.startVendorHalSta()); 1399 1400 WifiWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount(); 1401 verify(mIWifiChip).getDebugHostWakeReasonStats( 1402 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1403 assertNotNull(retrievedStats); 1404 assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake); 1405 assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake); 1406 assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake); 1407 assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast); 1408 assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast); 1409 assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp); 1410 assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6); 1411 assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt, 1412 retrievedStats.ipv4RxMulticast); 1413 assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt, 1414 retrievedStats.ipv6Multicast); 1415 } 1416 1417 /** 1418 * Tests the failure in retrieval of wlan wake reason stats. 1419 */ 1420 @Test 1421 public void testGetWlanWakeReasonCountFailure() throws Exception { 1422 doAnswer(new AnswerWithArguments() { 1423 public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) { 1424 cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats()); 1425 } 1426 }).when(mIWifiChip).getDebugHostWakeReasonStats( 1427 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1428 1429 // This should work in both AP & STA mode. 1430 assertTrue(mWifiVendorHal.startVendorHalAp()); 1431 1432 assertNull(mWifiVendorHal.getWlanWakeReasonCount()); 1433 verify(mIWifiChip).getDebugHostWakeReasonStats( 1434 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class)); 1435 } 1436 1437 /** 1438 * Test that getFwMemoryDump is properly plumbed 1439 */ 1440 @Test 1441 public void testGetFwMemoryDump() throws Exception { 1442 byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36"); 1443 ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample); 1444 1445 doAnswer(new AnswerWithArguments() { 1446 public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb) 1447 throws RemoteException { 1448 cb.onValues(mWifiStatusSuccess, halBlob); 1449 } 1450 }).when(mIWifiChip).requestFirmwareDebugDump(any( 1451 IWifiChip.requestFirmwareDebugDumpCallback.class)); 1452 1453 assertTrue(mWifiVendorHal.startVendorHalSta()); 1454 assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump()); 1455 } 1456 1457 /** 1458 * Test that getDriverStateDump is properly plumbed 1459 * 1460 * Just for variety, use AP mode here. 1461 */ 1462 @Test 1463 public void testGetDriverStateDump() throws Exception { 1464 byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f"); 1465 ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample); 1466 1467 doAnswer(new AnswerWithArguments() { 1468 public void answer(IWifiChip.requestDriverDebugDumpCallback cb) 1469 throws RemoteException { 1470 cb.onValues(mWifiStatusSuccess, halBlob); 1471 } 1472 }).when(mIWifiChip).requestDriverDebugDump(any( 1473 IWifiChip.requestDriverDebugDumpCallback.class)); 1474 1475 assertTrue(mWifiVendorHal.startVendorHalAp()); 1476 assertArrayEquals(sample, mWifiVendorHal.getDriverStateDump()); 1477 } 1478 1479 /** 1480 * Test that background scan failure is handled correctly. 1481 */ 1482 @Test 1483 public void testBgScanFailureCallback() throws Exception { 1484 assertTrue(mWifiVendorHal.startVendorHalSta()); 1485 assertNotNull(mIWifiStaIfaceEventCallback); 1486 1487 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1488 startBgScan(eventHandler); 1489 1490 mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId); 1491 verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 1492 } 1493 1494 /** 1495 * Test that background scan failure with wrong id is not reported. 1496 */ 1497 @Test 1498 public void testBgScanFailureCallbackWithInvalidCmdId() throws Exception { 1499 assertTrue(mWifiVendorHal.startVendorHalSta()); 1500 assertNotNull(mIWifiStaIfaceEventCallback); 1501 1502 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1503 startBgScan(eventHandler); 1504 1505 mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1); 1506 verify(eventHandler, never()).onScanStatus(WifiNative.WIFI_SCAN_FAILED); 1507 } 1508 1509 /** 1510 * Test that background scan full results are handled correctly. 1511 */ 1512 @Test 1513 public void testBgScanFullScanResults() throws Exception { 1514 assertTrue(mWifiVendorHal.startVendorHalSta()); 1515 assertNotNull(mIWifiStaIfaceEventCallback); 1516 1517 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1518 startBgScan(eventHandler); 1519 1520 Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(); 1521 mIWifiStaIfaceEventCallback.onBackgroundFullScanResult( 1522 mWifiVendorHal.mScan.cmdId, 5, result.first); 1523 1524 ArgumentCaptor<ScanResult> scanResultCaptor = ArgumentCaptor.forClass(ScanResult.class); 1525 verify(eventHandler).onFullScanResult(scanResultCaptor.capture(), eq(5)); 1526 1527 assertScanResultEqual(result.second, scanResultCaptor.getValue()); 1528 } 1529 1530 /** 1531 * Test that background scan results are handled correctly. 1532 */ 1533 @Test 1534 public void testBgScanScanResults() throws Exception { 1535 assertTrue(mWifiVendorHal.startVendorHalSta()); 1536 assertNotNull(mIWifiStaIfaceEventCallback); 1537 1538 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1539 startBgScan(eventHandler); 1540 1541 Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> data = 1542 createHidlAndFrameworkBgScanDatas(); 1543 mIWifiStaIfaceEventCallback.onBackgroundScanResults( 1544 mWifiVendorHal.mScan.cmdId, data.first); 1545 1546 verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 1547 assertScanDatasEqual( 1548 data.second, Arrays.asList(mWifiVendorHal.mScan.latestScanResults)); 1549 } 1550 1551 /** 1552 * Test that starting a new background scan when one is active will stop the previous one. 1553 */ 1554 @Test 1555 public void testBgScanReplacement() throws Exception { 1556 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1557 assertTrue(mWifiVendorHal.startVendorHalSta()); 1558 assertNotNull(mIWifiStaIfaceEventCallback); 1559 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1560 startBgScan(eventHandler); 1561 int cmdId1 = mWifiVendorHal.mScan.cmdId; 1562 startBgScan(eventHandler); 1563 assertNotEquals(mWifiVendorHal.mScan.cmdId, cmdId1); 1564 verify(mIWifiStaIface, times(2)).startBackgroundScan(anyInt(), any()); 1565 verify(mIWifiStaIface).stopBackgroundScan(cmdId1); 1566 } 1567 1568 /** 1569 * Test stopping a background scan. 1570 */ 1571 @Test 1572 public void testBgScanStop() throws Exception { 1573 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1574 assertTrue(mWifiVendorHal.startVendorHalSta()); 1575 assertNotNull(mIWifiStaIfaceEventCallback); 1576 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1577 startBgScan(eventHandler); 1578 1579 int cmdId = mWifiVendorHal.mScan.cmdId; 1580 1581 mWifiVendorHal.stopBgScan(); 1582 mWifiVendorHal.stopBgScan(); // second call should not do anything 1583 verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once 1584 } 1585 1586 /** 1587 * Test pausing and restarting a background scan. 1588 */ 1589 @Test 1590 public void testBgScanPauseAndRestart() throws Exception { 1591 when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess); 1592 assertTrue(mWifiVendorHal.startVendorHalSta()); 1593 assertNotNull(mIWifiStaIfaceEventCallback); 1594 WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); 1595 startBgScan(eventHandler); 1596 1597 int cmdId = mWifiVendorHal.mScan.cmdId; 1598 1599 mWifiVendorHal.pauseBgScan(); 1600 mWifiVendorHal.restartBgScan(); 1601 verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once 1602 verify(mIWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any()); 1603 } 1604 1605 /** 1606 * Test the handling of log handler set. 1607 */ 1608 @Test 1609 public void testSetLogHandler() throws Exception { 1610 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1611 1612 WifiNative.WifiLoggerEventHandler eventHandler = 1613 mock(WifiNative.WifiLoggerEventHandler.class); 1614 1615 assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1616 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1617 1618 assertTrue(mWifiVendorHal.startVendorHalSta()); 1619 1620 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1621 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 1622 reset(mIWifiChip); 1623 1624 // Second call should fail. 1625 assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1626 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1627 } 1628 1629 /** 1630 * Test the handling of log handler reset. 1631 */ 1632 @Test 1633 public void testResetLogHandler() throws Exception { 1634 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1635 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 1636 1637 assertFalse(mWifiVendorHal.resetLogHandler()); 1638 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1639 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1640 1641 assertTrue(mWifiVendorHal.startVendorHalSta()); 1642 1643 // Not set, so this should fail. 1644 assertFalse(mWifiVendorHal.resetLogHandler()); 1645 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1646 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1647 1648 // Now set and then reset. 1649 assertTrue(mWifiVendorHal.setLoggingEventHandler( 1650 mock(WifiNative.WifiLoggerEventHandler.class))); 1651 assertTrue(mWifiVendorHal.resetLogHandler()); 1652 verify(mIWifiChip).enableDebugErrorAlerts(eq(false)); 1653 verify(mIWifiChip).stopLoggingToDebugRingBuffer(); 1654 reset(mIWifiChip); 1655 1656 // Second reset should fail. 1657 assertFalse(mWifiVendorHal.resetLogHandler()); 1658 verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean()); 1659 verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer(); 1660 } 1661 1662 /** 1663 * Test the handling of alert callback. 1664 */ 1665 @Test 1666 public void testAlertCallback() throws Exception { 1667 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1668 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 1669 1670 assertTrue(mWifiVendorHal.startVendorHalSta()); 1671 assertNotNull(mIWifiChipEventCallback); 1672 1673 int errorCode = 5; 1674 byte[] errorData = new byte[45]; 1675 new Random().nextBytes(errorData); 1676 1677 // Randomly raise the HIDL callback before we register for the log callback. 1678 // This should be ignored. 1679 mIWifiChipEventCallback.onDebugErrorAlert( 1680 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 1681 1682 WifiNative.WifiLoggerEventHandler eventHandler = 1683 mock(WifiNative.WifiLoggerEventHandler.class); 1684 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1685 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 1686 1687 // Now raise the HIDL callback, this should be properly handled. 1688 mIWifiChipEventCallback.onDebugErrorAlert( 1689 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 1690 verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData)); 1691 1692 // Now stop the logging and invoke the callback. This should be ignored. 1693 assertTrue(mWifiVendorHal.resetLogHandler()); 1694 mIWifiChipEventCallback.onDebugErrorAlert( 1695 errorCode, NativeUtil.byteArrayToArrayList(errorData)); 1696 } 1697 1698 /** 1699 * Test the handling of ring buffer callback. 1700 */ 1701 @Test 1702 public void testRingBufferDataCallback() throws Exception { 1703 when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess); 1704 when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess); 1705 1706 assertTrue(mWifiVendorHal.startVendorHalSta()); 1707 assertNotNull(mIWifiChipEventCallback); 1708 1709 byte[] errorData = new byte[45]; 1710 new Random().nextBytes(errorData); 1711 1712 // Randomly raise the HIDL callback before we register for the log callback. 1713 // This should be ignored. 1714 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1715 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1716 1717 WifiNative.WifiLoggerEventHandler eventHandler = 1718 mock(WifiNative.WifiLoggerEventHandler.class); 1719 assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler)); 1720 verify(mIWifiChip).enableDebugErrorAlerts(eq(true)); 1721 1722 // Now raise the HIDL callback, this should be properly handled. 1723 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1724 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1725 verify(eventHandler).onRingBufferData( 1726 any(WifiNative.RingBufferStatus.class), eq(errorData)); 1727 1728 // Now stop the logging and invoke the callback. This should be ignored. 1729 assertTrue(mWifiVendorHal.resetLogHandler()); 1730 mIWifiChipEventCallback.onDebugRingBufferDataAvailable( 1731 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData)); 1732 } 1733 1734 /** 1735 * Test the handling of Vendor HAL death. 1736 */ 1737 @Test 1738 public void testVendorHalDeath() { 1739 // Invoke the HAL device manager status callback with ready set to false to indicate the 1740 // death of the HAL. 1741 when(mHalDeviceManager.isReady()).thenReturn(false); 1742 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 1743 1744 verify(mVendorHalDeathHandler).onDeath(); 1745 } 1746 1747 private void startBgScan(WifiNative.ScanEventHandler eventHandler) throws Exception { 1748 when(mIWifiStaIface.startBackgroundScan( 1749 anyInt(), any(StaBackgroundScanParameters.class))).thenReturn(mWifiStatusSuccess); 1750 WifiNative.ScanSettings settings = new WifiNative.ScanSettings(); 1751 settings.num_buckets = 1; 1752 WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings(); 1753 bucketSettings.bucket = 0; 1754 bucketSettings.period_ms = 16000; 1755 bucketSettings.report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 1756 settings.buckets = new WifiNative.BucketSettings[] {bucketSettings}; 1757 assertTrue(mWifiVendorHal.startBgScan(settings, eventHandler)); 1758 } 1759 1760 // Create a pair of HIDL scan result and its corresponding framework scan result for 1761 // comparison. 1762 private Pair<StaScanResult, ScanResult> createHidlAndFrameworkBgScanResult() { 1763 StaScanResult staScanResult = new StaScanResult(); 1764 Random random = new Random(); 1765 byte[] ssid = new byte[8]; 1766 random.nextBytes(ssid); 1767 staScanResult.ssid.addAll(NativeUtil.byteArrayToArrayList(ssid)); 1768 random.nextBytes(staScanResult.bssid); 1769 staScanResult.frequency = 2432; 1770 staScanResult.rssi = -45; 1771 staScanResult.timeStampInUs = 5; 1772 WifiInformationElement ie1 = new WifiInformationElement(); 1773 byte[] ie1_data = new byte[56]; 1774 random.nextBytes(ie1_data); 1775 ie1.id = 1; 1776 ie1.data.addAll(NativeUtil.byteArrayToArrayList(ie1_data)); 1777 staScanResult.informationElements.add(ie1); 1778 1779 // Now create the corresponding Scan result structure. 1780 ScanResult scanResult = new ScanResult(); 1781 scanResult.SSID = NativeUtil.encodeSsid(staScanResult.ssid); 1782 scanResult.BSSID = NativeUtil.macAddressFromByteArray(staScanResult.bssid); 1783 scanResult.wifiSsid = WifiSsid.createFromByteArray(ssid); 1784 scanResult.frequency = staScanResult.frequency; 1785 scanResult.level = staScanResult.rssi; 1786 scanResult.timestamp = staScanResult.timeStampInUs; 1787 scanResult.bytes = new byte[57]; 1788 scanResult.bytes[0] = ie1.id; 1789 System.arraycopy(ie1_data, 0, scanResult.bytes, 1, ie1_data.length); 1790 1791 return Pair.create(staScanResult, scanResult); 1792 } 1793 1794 // Create a pair of HIDL scan datas and its corresponding framework scan datas for 1795 // comparison. 1796 private Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> 1797 createHidlAndFrameworkBgScanDatas() { 1798 ArrayList<StaScanData> staScanDatas = new ArrayList<>(); 1799 StaScanData staScanData = new StaScanData(); 1800 1801 Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(); 1802 staScanData.results.add(result.first); 1803 staScanData.bucketsScanned = 5; 1804 staScanData.flags = StaScanDataFlagMask.INTERRUPTED; 1805 staScanDatas.add(staScanData); 1806 1807 ArrayList<WifiScanner.ScanData> scanDatas = new ArrayList<>(); 1808 ScanResult[] scanResults = new ScanResult[1]; 1809 scanResults[0] = result.second; 1810 WifiScanner.ScanData scanData = 1811 new WifiScanner.ScanData(mWifiVendorHal.mScan.cmdId, 1, 1812 staScanData.bucketsScanned, false, scanResults); 1813 scanDatas.add(scanData); 1814 return Pair.create(staScanDatas, scanDatas); 1815 } 1816 1817 private void assertScanResultEqual(ScanResult expected, ScanResult actual) { 1818 assertEquals(expected.SSID, actual.SSID); 1819 assertEquals(expected.wifiSsid.getHexString(), actual.wifiSsid.getHexString()); 1820 assertEquals(expected.BSSID, actual.BSSID); 1821 assertEquals(expected.frequency, actual.frequency); 1822 assertEquals(expected.level, actual.level); 1823 assertEquals(expected.timestamp, actual.timestamp); 1824 assertArrayEquals(expected.bytes, actual.bytes); 1825 } 1826 1827 private void assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual) { 1828 assertEquals(expected.length, actual.length); 1829 for (int i = 0; i < expected.length; i++) { 1830 assertScanResultEqual(expected[i], actual[i]); 1831 } 1832 } 1833 1834 private void assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual) { 1835 assertEquals(expected.getId(), actual.getId()); 1836 assertEquals(expected.getFlags(), actual.getFlags()); 1837 assertEquals(expected.getBucketsScanned(), actual.getBucketsScanned()); 1838 assertScanResultsEqual(expected.getResults(), actual.getResults()); 1839 } 1840 1841 private void assertScanDatasEqual( 1842 List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual) { 1843 assertEquals(expected.size(), actual.size()); 1844 for (int i = 0; i < expected.size(); i++) { 1845 assertScanDataEqual(expected.get(i), actual.get(i)); 1846 } 1847 } 1848} 1849