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