WifiVendorHalTest.java revision 7e7e2e3fd4da1f5ccda2f03dcdb321654e9f6ff8
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.IWifiIface; 23import android.hardware.wifi.V1_0.IWifiRttController; 24import android.hardware.wifi.V1_0.IWifiStaIface; 25import android.hardware.wifi.V1_0.WifiStatus; 26import android.hardware.wifi.V1_0.WifiStatusCode; 27import android.net.wifi.WifiManager; 28 29 30import static org.junit.Assert.*; 31import static org.mockito.Mockito.*; 32 33import android.os.HandlerThread; 34import android.os.Looper; 35import android.os.RemoteException; 36 37import org.junit.Assert; 38import org.junit.Before; 39import org.junit.Test; 40import org.mockito.ArgumentCaptor; 41import org.mockito.Mock; 42import org.mockito.MockitoAnnotations; 43 44/** 45 * Unit tests for {@link com.android.server.wifi.WifiVendorHal}. 46 */ 47public class WifiVendorHalTest { 48 49 WifiVendorHal mWifiVendorHal; 50 private WifiStatus mWifiStatusSuccess; 51 private WifiStatus mWifiStatusFailure; 52 @Mock 53 private HalDeviceManager mHalDeviceManager; 54 @Mock 55 private HandlerThread mWifiStateMachineHandlerThread; 56 @Mock 57 private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks; 58 @Mock 59 private IWifiApIface mIWifiApIface; 60 @Mock 61 private IWifiChip mIWifiChip; 62 @Mock 63 private IWifiStaIface mIWifiStaIface; 64 @Mock 65 private IWifiRttController mIWifiRttController; 66 67 /** 68 * Sets up for unit test 69 */ 70 @Before 71 public void setUp() throws Exception { 72 MockitoAnnotations.initMocks(this); 73 mWifiStatusSuccess = new WifiStatus(); 74 mWifiStatusSuccess.code = WifiStatusCode.SUCCESS; 75 mWifiStatusFailure = new WifiStatus(); 76 mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN; 77 mWifiStatusFailure.description = "I don't even know what a Mock Turtle is."; 78 when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess); 79 80 81 // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in 82 // individual tests, if needed. 83 doAnswer(new AnswerWithArguments() { 84 public boolean answer() { 85 when(mHalDeviceManager.isReady()).thenReturn(true); 86 when(mHalDeviceManager.isStarted()).thenReturn(true); 87 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 88 return true; 89 } 90 }).when(mHalDeviceManager).start(); 91 92 doAnswer(new AnswerWithArguments() { 93 public void answer() { 94 when(mHalDeviceManager.isReady()).thenReturn(true); 95 when(mHalDeviceManager.isStarted()).thenReturn(false); 96 mHalDeviceManagerStatusCallbacks.onStatusChanged(); 97 } 98 }).when(mHalDeviceManager).stop(); 99 when(mHalDeviceManager.createStaIface(eq(null), eq(null))) 100 .thenReturn(mIWifiStaIface); 101 when(mHalDeviceManager.createApIface(eq(null), eq(null))) 102 .thenReturn(mIWifiApIface); 103 when(mHalDeviceManager.getChip(any(IWifiIface.class))) 104 .thenReturn(mIWifiChip); 105 when(mHalDeviceManager.createRttController(any(IWifiIface.class))) 106 .thenReturn(mIWifiRttController); 107 108 // Create the vendor HAL object under test. 109 mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread); 110 111 // Initialize the vendor HAL to capture the registered callback. 112 mWifiVendorHal.initialize(); 113 ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> callbackCaptor = 114 ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class); 115 verify(mHalDeviceManager).registerStatusListener( 116 callbackCaptor.capture(), any(Looper.class)); 117 mHalDeviceManagerStatusCallbacks = callbackCaptor.getValue(); 118 } 119 120 /** 121 * Test that parsing a typical colon-delimited MAC adddress works 122 */ 123 @Test 124 public void testTypicalHexParse() throws Exception { 125 byte[] sixBytes = new byte[6]; 126 mWifiVendorHal.parseUnquotedMacStrToByteArray("61:52:43:34:25:16", sixBytes); 127 Assert.assertArrayEquals(new byte[]{0x61, 0x52, 0x43, 0x34, 0x25, 0x16}, sixBytes); 128 } 129 130 /** 131 * Tests the successful starting of HAL in STA mode using 132 * {@link WifiVendorHal#startVendorHal(boolean)}. 133 */ 134 @Test 135 public void testStartHalSuccessInStaMode() { 136 assertTrue(mWifiVendorHal.startVendorHal(true)); 137 assertTrue(mWifiVendorHal.isHalStarted()); 138 139 verify(mHalDeviceManager).start(); 140 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 141 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 142 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 143 verify(mHalDeviceManager).isReady(); 144 verify(mHalDeviceManager).isStarted(); 145 146 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 147 } 148 149 /** 150 * Tests the successful starting of HAL in AP mode using 151 * {@link WifiVendorHal#startVendorHal(boolean)}. 152 */ 153 @Test 154 public void testStartHalSuccessInApMode() { 155 assertTrue(mWifiVendorHal.startVendorHal(false)); 156 assertTrue(mWifiVendorHal.isHalStarted()); 157 158 verify(mHalDeviceManager).start(); 159 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 160 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 161 verify(mHalDeviceManager).isReady(); 162 verify(mHalDeviceManager).isStarted(); 163 164 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 165 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 166 } 167 168 /** 169 * Tests the failure to start HAL in STA mode using 170 * {@link WifiVendorHal#startVendorHal(boolean)}. 171 */ 172 @Test 173 public void testStartHalFailureInStaMode() { 174 // No callbacks are invoked in this case since the start itself failed. So, override 175 // default AnswerWithArguments that we setup. 176 doAnswer(new AnswerWithArguments() { 177 public boolean answer() { 178 return false; 179 } 180 }).when(mHalDeviceManager).start(); 181 assertFalse(mWifiVendorHal.startVendorHal(true)); 182 assertFalse(mWifiVendorHal.isHalStarted()); 183 184 verify(mHalDeviceManager).start(); 185 186 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 187 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 188 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 189 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 190 } 191 192 /** 193 * Tests the failure to start HAL in STA mode using 194 * {@link WifiVendorHal#startVendorHal(boolean)}. 195 */ 196 @Test 197 public void testStartHalFailureInIfaceCreationInStaMode() { 198 when(mHalDeviceManager.createStaIface(eq(null), eq(null))).thenReturn(null); 199 assertFalse(mWifiVendorHal.startVendorHal(true)); 200 assertFalse(mWifiVendorHal.isHalStarted()); 201 202 verify(mHalDeviceManager).start(); 203 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 204 verify(mHalDeviceManager).stop(); 205 206 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 207 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 208 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 209 } 210 211 /** 212 * Tests the failure to start HAL in STA mode using 213 * {@link WifiVendorHal#startVendorHal(boolean)}. 214 */ 215 @Test 216 public void testStartHalFailureInRttControllerCreationInStaMode() { 217 when(mHalDeviceManager.createRttController(any(IWifiIface.class))).thenReturn(null); 218 assertFalse(mWifiVendorHal.startVendorHal(true)); 219 assertFalse(mWifiVendorHal.isHalStarted()); 220 221 verify(mHalDeviceManager).start(); 222 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 223 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 224 verify(mHalDeviceManager).stop(); 225 226 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 227 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 228 } 229 230 /** 231 * Tests the failure to start HAL in STA mode using 232 * {@link WifiVendorHal#startVendorHal(boolean)}. 233 */ 234 @Test 235 public void testStartHalFailureInChipGetInStaMode() { 236 when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null); 237 assertFalse(mWifiVendorHal.startVendorHal(true)); 238 assertFalse(mWifiVendorHal.isHalStarted()); 239 240 verify(mHalDeviceManager).start(); 241 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 242 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 243 verify(mHalDeviceManager).getChip(any(IWifiIface.class)); 244 verify(mHalDeviceManager).stop(); 245 246 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 247 } 248 249 /** 250 * Tests the failure to start HAL in STA mode using 251 * {@link WifiVendorHal#startVendorHal(boolean)}. 252 */ 253 @Test 254 public void testStartHalFailureInApMode() { 255 when(mHalDeviceManager.createApIface(eq(null), eq(null))).thenReturn(null); 256 assertFalse(mWifiVendorHal.startVendorHal(false)); 257 assertFalse(mWifiVendorHal.isHalStarted()); 258 259 verify(mHalDeviceManager).start(); 260 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 261 verify(mHalDeviceManager).stop(); 262 263 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 264 verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class)); 265 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 266 } 267 268 /** 269 * Tests the stopping of HAL in STA mode using 270 * {@link WifiVendorHal#stopVendorHal()}. 271 */ 272 @Test 273 public void testStopHalInStaMode() { 274 assertTrue(mWifiVendorHal.startVendorHal(true)); 275 assertTrue(mWifiVendorHal.isHalStarted()); 276 277 mWifiVendorHal.stopVendorHal(); 278 assertFalse(mWifiVendorHal.isHalStarted()); 279 280 verify(mHalDeviceManager).start(); 281 verify(mHalDeviceManager).stop(); 282 verify(mHalDeviceManager).createStaIface(eq(null), eq(null)); 283 verify(mHalDeviceManager).getChip(eq(mIWifiStaIface)); 284 verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface)); 285 verify(mHalDeviceManager, times(2)).isReady(); 286 verify(mHalDeviceManager, times(2)).isStarted(); 287 288 verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null)); 289 } 290 291 /** 292 * Tests the stopping of HAL in AP mode using 293 * {@link WifiVendorHal#stopVendorHal()}. 294 */ 295 @Test 296 public void testStopHalInApMode() { 297 assertTrue(mWifiVendorHal.startVendorHal(false)); 298 assertTrue(mWifiVendorHal.isHalStarted()); 299 300 mWifiVendorHal.stopVendorHal(); 301 assertFalse(mWifiVendorHal.isHalStarted()); 302 303 verify(mHalDeviceManager).start(); 304 verify(mHalDeviceManager).stop(); 305 verify(mHalDeviceManager).createApIface(eq(null), eq(null)); 306 verify(mHalDeviceManager).getChip(eq(mIWifiApIface)); 307 verify(mHalDeviceManager, times(2)).isReady(); 308 verify(mHalDeviceManager, times(2)).isStarted(); 309 310 verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null)); 311 verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class)); 312 } 313 314 /** 315 * Test translation to WifiManager.WIFI_FEATURE_* 316 * 317 * Just do a spot-check with a few feature bits here; since the code is table- 318 * driven we don't have to work hard to exercise all of it. 319 */ 320 @Test 321 public void testFeatureMaskTranslation() { 322 int caps = ( 323 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN 324 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS 325 ); 326 int expected = ( 327 WifiManager.WIFI_FEATURE_INFRA 328 | WifiManager.WIFI_FEATURE_SCANNER 329 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS); 330 assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps)); 331 } 332 333 /** 334 * Test enablement of link layer stats after startup 335 * <p> 336 * Request link layer stats before HAL start 337 * - should not make it to the HAL layer 338 * Start the HAL in STA mode 339 * Request link layer stats twice more 340 * - enable request should make it to the HAL layer 341 * - HAL layer should have been called to make the requests (i.e., two calls total) 342 */ 343 @Test 344 public void testLinkLayerStatsEnableAfterStartup() throws Exception { 345 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 346 347 assertNull(mWifiVendorHal.getWifiLinkLayerStats()); 348 assertTrue(mWifiVendorHal.startVendorHalSta()); 349 assertTrue(mWifiVendorHal.isHalStarted()); 350 351 verify(mHalDeviceManager).start(); 352 mWifiVendorHal.getWifiLinkLayerStats(); 353 mWifiVendorHal.getWifiLinkLayerStats(); 354 verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug 355 verify(mIWifiStaIface, times(2)).getLinkLayerStats(any()); 356 } 357 358 /** 359 * Test that link layer stats are not enabled and harmless in AP mode 360 * <p> 361 * Start the HAL in AP mode 362 * - stats should not be enabled 363 * Request link layer stats 364 * - HAL layer should have been called to make the request 365 */ 366 @Test 367 public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception { 368 doNothing().when(mIWifiStaIface).getLinkLayerStats(any()); 369 370 assertTrue(mWifiVendorHal.startVendorHalAp()); 371 assertTrue(mWifiVendorHal.isHalStarted()); 372 assertNull(mWifiVendorHal.getWifiLinkLayerStats()); 373 374 verify(mHalDeviceManager).start(); 375 376 verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false); 377 verify(mIWifiStaIface, never()).getLinkLayerStats(any()); 378 } 379 380 // TODO(b/34900534) add test for correct MOVE CORRESPONDING of fields 381 382 /** 383 * Test that getFirmwareVersion() and getDriverVersion() work 384 * 385 * Calls before the STA is started are expected to return null. 386 */ 387 @Test 388 public void testVersionGetters() throws Exception { 389 String firmwareVersion = "fuzzy"; 390 String driverVersion = "dizzy"; 391 IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo(); 392 chipDebugInfo.firmwareDescription = firmwareVersion; 393 chipDebugInfo.driverDescription = driverVersion; 394 395 doAnswer(new AnswerWithArguments() { 396 public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException { 397 cb.onValues(mWifiStatusSuccess, chipDebugInfo); 398 } 399 }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class)); 400 401 assertNull(mWifiVendorHal.getFirmwareVersion()); 402 assertNull(mWifiVendorHal.getDriverVersion()); 403 404 assertTrue(mWifiVendorHal.startVendorHalSta()); 405 406 assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion()); 407 assertEquals(driverVersion, mWifiVendorHal.getDriverVersion()); 408 } 409} 410