1 /* 2 * Copyright (C) 2016 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 17 package com.android.server.wifi; 18 19 import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ; 20 import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ; 21 22 import static org.junit.Assert.assertArrayEquals; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertNull; 27 import static org.junit.Assert.assertTrue; 28 import static org.junit.Assume.assumeFalse; 29 import static org.junit.Assume.assumeTrue; 30 import static org.mockito.ArgumentMatchers.any; 31 import static org.mockito.ArgumentMatchers.anyString; 32 import static org.mockito.ArgumentMatchers.same; 33 import static org.mockito.Mockito.anyBoolean; 34 import static org.mockito.Mockito.anyInt; 35 import static org.mockito.Mockito.eq; 36 import static org.mockito.Mockito.mock; 37 import static org.mockito.Mockito.never; 38 import static org.mockito.Mockito.times; 39 import static org.mockito.Mockito.verify; 40 import static org.mockito.Mockito.when; 41 42 import android.net.MacAddress; 43 import android.net.wifi.CoexUnsafeChannel; 44 import android.net.wifi.ScanResult; 45 import android.net.wifi.WifiConfiguration; 46 import android.net.wifi.WifiScanner; 47 import android.net.wifi.nl80211.NativeScanResult; 48 import android.net.wifi.nl80211.RadioChainInfo; 49 import android.net.wifi.nl80211.WifiNl80211Manager; 50 import android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback; 51 import android.os.Bundle; 52 import android.os.Handler; 53 import android.os.WorkSource; 54 import android.text.TextUtils; 55 56 import androidx.test.filters.SmallTest; 57 58 import com.android.modules.utils.build.SdkLevel; 59 import com.android.server.wifi.coex.CoexManager; 60 import com.android.server.wifi.util.NativeUtil; 61 import com.android.server.wifi.util.NetdWrapper; 62 63 import org.junit.Before; 64 import org.junit.Test; 65 import org.mockito.AdditionalMatchers; 66 import org.mockito.ArgumentCaptor; 67 import org.mockito.Mock; 68 import org.mockito.MockitoAnnotations; 69 70 import java.util.ArrayList; 71 import java.util.Arrays; 72 import java.util.Collections; 73 import java.util.HashSet; 74 import java.util.List; 75 import java.util.Random; 76 import java.util.Set; 77 import java.util.regex.Pattern; 78 79 /** 80 * Unit tests for {@link com.android.server.wifi.WifiNative}. 81 */ 82 @SmallTest 83 public class WifiNativeTest extends WifiBaseTest { 84 private static final String WIFI_IFACE_NAME = "mockWlan"; 85 private static final long FATE_REPORT_DRIVER_TIMESTAMP_USEC = 12345; 86 private static final byte[] FATE_REPORT_FRAME_BYTES = new byte[] { 87 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0, 1, 2, 3, 4, 5, 6, 7}; 88 private static final WifiNative.TxFateReport TX_FATE_REPORT = new WifiNative.TxFateReport( 89 WifiLoggerHal.TX_PKT_FATE_SENT, 90 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 91 WifiLoggerHal.FRAME_TYPE_ETHERNET_II, 92 FATE_REPORT_FRAME_BYTES 93 ); 94 private static final WifiNative.RxFateReport RX_FATE_REPORT = new WifiNative.RxFateReport( 95 WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, 96 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 97 WifiLoggerHal.FRAME_TYPE_ETHERNET_II, 98 FATE_REPORT_FRAME_BYTES 99 ); 100 private static final FrameTypeMapping[] FRAME_TYPE_MAPPINGS = new FrameTypeMapping[] { 101 new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_UNKNOWN, "unknown", "N/A"), 102 new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, "data", "Ethernet"), 103 new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_80211_MGMT, "802.11 management", 104 "802.11 Mgmt"), 105 new FrameTypeMapping((byte) 42, "42", "N/A") 106 }; 107 private static final FateMapping[] TX_FATE_MAPPINGS = new FateMapping[] { 108 new FateMapping(WifiLoggerHal.TX_PKT_FATE_ACKED, "acked"), 109 new FateMapping(WifiLoggerHal.TX_PKT_FATE_SENT, "sent"), 110 new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_QUEUED, "firmware queued"), 111 new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID, 112 "firmware dropped (invalid frame)"), 113 new FateMapping( 114 WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS, "firmware dropped (no bufs)"), 115 new FateMapping( 116 WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"), 117 new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, "driver queued"), 118 new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID, 119 "driver dropped (invalid frame)"), 120 new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS, 121 "driver dropped (no bufs)"), 122 new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"), 123 new FateMapping((byte) 42, "42") 124 }; 125 private static final FateMapping[] RX_FATE_MAPPINGS = new FateMapping[] { 126 new FateMapping(WifiLoggerHal.RX_PKT_FATE_SUCCESS, "success"), 127 new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_QUEUED, "firmware queued"), 128 new FateMapping( 129 WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, "firmware dropped (filter)"), 130 new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, 131 "firmware dropped (invalid frame)"), 132 new FateMapping( 133 WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS, "firmware dropped (no bufs)"), 134 new FateMapping( 135 WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"), 136 new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED, "driver queued"), 137 new FateMapping( 138 WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER, "driver dropped (filter)"), 139 new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID, 140 "driver dropped (invalid frame)"), 141 new FateMapping( 142 WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS, "driver dropped (no bufs)"), 143 new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"), 144 new FateMapping((byte) 42, "42") 145 }; 146 private static final WifiNl80211Manager.SignalPollResult SIGNAL_POLL_RESULT = 147 new WifiNl80211Manager.SignalPollResult(-60, 12, 6, 5240); 148 149 private static final Set<Integer> SCAN_FREQ_SET = 150 new HashSet<Integer>() {{ 151 add(2410); 152 add(2450); 153 add(5050); 154 add(5200); 155 }}; 156 private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; 157 private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; 158 private static final int[] TEST_FREQUENCIES_1 = {}; 159 private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; 160 private static final List<String> SCAN_HIDDEN_NETWORK_SSID_SET = 161 new ArrayList<String>() {{ 162 add(TEST_QUOTED_SSID_1); 163 add(TEST_QUOTED_SSID_2); 164 }}; 165 private static final List<byte[]> SCAN_HIDDEN_NETWORK_BYTE_SSID_SET = 166 new ArrayList<byte[]>() {{ 167 add(NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); 168 add(NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); 169 }}; 170 171 private static final WifiNative.PnoSettings TEST_PNO_SETTINGS = 172 new WifiNative.PnoSettings() {{ 173 isConnected = false; 174 periodInMs = 6000; 175 networkList = new WifiNative.PnoNetwork[2]; 176 networkList[0] = new WifiNative.PnoNetwork(); 177 networkList[1] = new WifiNative.PnoNetwork(); 178 networkList[0].ssid = TEST_QUOTED_SSID_1; 179 networkList[1].ssid = TEST_QUOTED_SSID_2; 180 networkList[0].frequencies = TEST_FREQUENCIES_1; 181 networkList[1].frequencies = TEST_FREQUENCIES_2; 182 }}; 183 private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92"); 184 185 private static final String TEST_MAC_ADDRESS_STR = "f4:f5:e8:51:9e:09"; 186 private static final String TEST_BSSID_STR = "a8:bd:27:5b:33:72"; 187 private static final int TEST_MCS_RATE = 5; 188 private static final int TEST_SEQUENCE_NUM = 0x66b0; 189 190 private static final byte[] TEST_SSID = 191 new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; 192 private static final byte[] TEST_BSSID = 193 new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, 194 (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; 195 // This the IE buffer which is consistent with TEST_SSID. 196 private static final byte[] TEST_INFO_ELEMENT_SSID = 197 new byte[] { 198 // Element ID for SSID. 199 (byte) 0x00, 200 // Length of the SSID: 0x0b or 11. 201 (byte) 0x0b, 202 // This is string "GoogleGuest" 203 'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; 204 // RSN IE data indicating EAP key management. 205 private static final byte[] TEST_INFO_ELEMENT_RSN = 206 new byte[] { 207 // Element ID for RSN. 208 (byte) 0x30, 209 // Length of the element data. 210 (byte) 0x18, 211 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, 212 (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, 213 (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, (byte) 0x01, (byte) 0x00, 214 (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x01, (byte) 0x00, (byte) 0x00 }; 215 216 private static final int TEST_FREQUENCY = 2456; 217 private static final int TEST_SIGNAL_MBM = -4500; 218 private static final long TEST_TSF = 34455441; 219 private static final int TEST_CAPABILITY = 0b0000_0000_0010_0100; 220 private static final boolean TEST_ASSOCIATED = true; 221 private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT = createMockNativeScanResult(); createMockNativeScanResult()222 private static NativeScanResult createMockNativeScanResult() { 223 NativeScanResult result = new NativeScanResult(); 224 result.ssid = TEST_SSID; 225 result.bssid = TEST_BSSID; 226 result.infoElement = TEST_INFO_ELEMENT_SSID; 227 result.frequency = TEST_FREQUENCY; 228 result.signalMbm = TEST_SIGNAL_MBM; 229 result.tsf = TEST_TSF; 230 result.capability = TEST_CAPABILITY; 231 result.associated = TEST_ASSOCIATED; 232 result.radioChainInfos = new ArrayList<>(); 233 return result; 234 } 235 236 private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_1 = new RadioChainInfo(1, -89); 237 private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_2 = new RadioChainInfo(0, -78); 238 private static final WorkSource TEST_WORKSOURCE = new WorkSource(); 239 private static final WorkSource TEST_WORKSOURCE2 = new WorkSource(); 240 241 @Mock private WifiVendorHal mWifiVendorHal; 242 @Mock private WifiNl80211Manager mWificondControl; 243 @Mock private SupplicantStaIfaceHal mStaIfaceHal; 244 @Mock private HostapdHal mHostapdHal; 245 @Mock private WifiMonitor mWifiMonitor; 246 @Mock private PropertyService mPropertyService; 247 @Mock private WifiMetrics mWifiMetrics; 248 @Mock private Handler mHandler; 249 @Mock private SendMgmtFrameCallback mSendMgmtFrameCallback; 250 @Mock private Random mRandom; 251 @Mock private WifiInjector mWifiInjector; 252 @Mock private NetdWrapper mNetdWrapper; 253 @Mock private CoexManager mCoexManager; 254 @Mock BuildProperties mBuildProperties; 255 @Mock private WifiNative.InterfaceCallback mInterfaceCallback; 256 @Mock private WifiCountryCode.ChangeListener mWifiCountryCodeChangeListener; 257 258 ArgumentCaptor<WifiNl80211Manager.ScanEventCallback> mScanCallbackCaptor = 259 ArgumentCaptor.forClass(WifiNl80211Manager.ScanEventCallback.class); 260 261 private WifiNative mWifiNative; 262 263 @Before setUp()264 public void setUp() throws Exception { 265 MockitoAnnotations.initMocks(this); 266 267 when(mWifiVendorHal.initialize(any())).thenReturn(true); 268 when(mWifiVendorHal.isVendorHalSupported()).thenReturn(true); 269 when(mWifiVendorHal.startVendorHal()).thenReturn(true); 270 when(mWifiVendorHal.startVendorHalSta()).thenReturn(true); 271 when(mWifiVendorHal.startVendorHalAp()).thenReturn(true); 272 when(mWifiVendorHal.createStaIface(any(), any())).thenReturn(WIFI_IFACE_NAME); 273 274 when(mBuildProperties.isEngBuild()).thenReturn(false); 275 when(mBuildProperties.isUserdebugBuild()).thenReturn(false); 276 when(mBuildProperties.isUserBuild()).thenReturn(true); 277 278 when(mWificondControl.setupInterfaceForClientMode(any(), any(), any(), any())).thenReturn( 279 true); 280 281 when(mStaIfaceHal.registerDeathHandler(any())).thenReturn(true); 282 when(mStaIfaceHal.isInitializationComplete()).thenReturn(true); 283 when(mStaIfaceHal.initialize()).thenReturn(true); 284 when(mStaIfaceHal.startDaemon()).thenReturn(true); 285 when(mStaIfaceHal.setupIface(any())).thenReturn(true); 286 287 when(mWifiInjector.makeNetdWrapper()).thenReturn(mNetdWrapper); 288 when(mWifiInjector.getCoexManager()).thenReturn(mCoexManager); 289 290 mWifiNative = new WifiNative( 291 mWifiVendorHal, mStaIfaceHal, mHostapdHal, mWificondControl, 292 mWifiMonitor, mPropertyService, mWifiMetrics, 293 mHandler, mRandom, mBuildProperties, mWifiInjector); 294 mWifiNative.initialize(); 295 } 296 297 /** 298 * Verifies that TxFateReport's constructor sets all of the TxFateReport fields. 299 */ 300 @Test testTxFateReportCtorSetsFields()301 public void testTxFateReportCtorSetsFields() { 302 WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport( 303 WifiLoggerHal.TX_PKT_FATE_SENT, // non-zero value 304 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 305 WifiLoggerHal.FRAME_TYPE_ETHERNET_II, // non-zero value 306 FATE_REPORT_FRAME_BYTES 307 ); 308 assertEquals(WifiLoggerHal.TX_PKT_FATE_SENT, fateReport.mFate); 309 assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec); 310 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType); 311 assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes); 312 } 313 314 /** 315 * Verifies that RxFateReport's constructor sets all of the RxFateReport fields. 316 */ 317 @Test testRxFateReportCtorSetsFields()318 public void testRxFateReportCtorSetsFields() { 319 WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport( 320 WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, // non-zero value 321 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 322 WifiLoggerHal.FRAME_TYPE_ETHERNET_II, // non-zero value 323 FATE_REPORT_FRAME_BYTES 324 ); 325 assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, fateReport.mFate); 326 assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec); 327 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType); 328 assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes); 329 } 330 331 /** 332 * Verifies the hashCode methods for HiddenNetwork and PnoNetwork classes 333 */ 334 @Test testHashCode()335 public void testHashCode() { 336 WifiNative.HiddenNetwork hiddenNet1 = new WifiNative.HiddenNetwork(); 337 hiddenNet1.ssid = new String("sametext"); 338 339 WifiNative.HiddenNetwork hiddenNet2 = new WifiNative.HiddenNetwork(); 340 hiddenNet2.ssid = new String("sametext"); 341 342 assertTrue(hiddenNet1.equals(hiddenNet2)); 343 assertEquals(hiddenNet1.hashCode(), hiddenNet2.hashCode()); 344 345 WifiNative.PnoNetwork pnoNet1 = new WifiNative.PnoNetwork(); 346 pnoNet1.ssid = new String("sametext"); 347 pnoNet1.flags = 2; 348 pnoNet1.auth_bit_field = 4; 349 pnoNet1.frequencies = TEST_FREQUENCIES_2; 350 351 WifiNative.PnoNetwork pnoNet2 = new WifiNative.PnoNetwork(); 352 pnoNet2.ssid = new String("sametext"); 353 pnoNet2.flags = 2; 354 pnoNet2.auth_bit_field = 4; 355 pnoNet2.frequencies = TEST_FREQUENCIES_2; 356 357 assertTrue(pnoNet1.equals(pnoNet2)); 358 assertEquals(pnoNet1.hashCode(), pnoNet2.hashCode()); 359 } 360 361 // Support classes for test{Tx,Rx}FateReportToString. 362 private static class FrameTypeMapping { 363 byte mTypeNumber; 364 String mExpectedTypeText; 365 String mExpectedProtocolText; FrameTypeMapping(byte typeNumber, String expectedTypeText, String expectedProtocolText)366 FrameTypeMapping(byte typeNumber, String expectedTypeText, String expectedProtocolText) { 367 this.mTypeNumber = typeNumber; 368 this.mExpectedTypeText = expectedTypeText; 369 this.mExpectedProtocolText = expectedProtocolText; 370 } 371 } 372 private static class FateMapping { 373 byte mFateNumber; 374 String mExpectedText; FateMapping(byte fateNumber, String expectedText)375 FateMapping(byte fateNumber, String expectedText) { 376 this.mFateNumber = fateNumber; 377 this.mExpectedText = expectedText; 378 } 379 } 380 381 /** 382 * Verifies that FateReport.getTableHeader() prints the right header. 383 */ 384 @Test testFateReportTableHeader()385 public void testFateReportTableHeader() { 386 final String header = WifiNative.FateReport.getTableHeader(); 387 assertEquals( 388 "\nTime usec Walltime Direction Fate " 389 + "Protocol Type Result\n" 390 + "--------- -------- --------- ---- " 391 + "-------- ---- ------\n", header); 392 } 393 394 /** 395 * Verifies that TxFateReport.toTableRowString() includes the information we care about. 396 */ 397 @Test testTxFateReportToTableRowString()398 public void testTxFateReportToTableRowString() { 399 WifiNative.TxFateReport fateReport = TX_FATE_REPORT; 400 assertTrue( 401 fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches( 402 FATE_REPORT_DRIVER_TIMESTAMP_USEC + " " // timestamp 403 + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} " // walltime 404 + "TX " // direction 405 + "sent " // fate 406 + "Ethernet " // type 407 + "N/A " // protocol 408 + "N/A" // result 409 ) 410 ); 411 412 for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) { 413 fateReport = new WifiNative.TxFateReport( 414 WifiLoggerHal.TX_PKT_FATE_SENT, 415 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 416 frameTypeMapping.mTypeNumber, 417 FATE_REPORT_FRAME_BYTES 418 ); 419 assertTrue( 420 fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches( 421 FATE_REPORT_DRIVER_TIMESTAMP_USEC + " " // timestamp 422 + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} " // walltime 423 + "TX " // direction 424 + "sent " // fate 425 + frameTypeMapping.mExpectedProtocolText + " " // type 426 + "N/A " // protocol 427 + "N/A" // result 428 ) 429 ); 430 } 431 432 for (FateMapping fateMapping : TX_FATE_MAPPINGS) { 433 fateReport = new WifiNative.TxFateReport( 434 fateMapping.mFateNumber, 435 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 436 WifiLoggerHal.FRAME_TYPE_80211_MGMT, 437 FATE_REPORT_FRAME_BYTES 438 ); 439 assertTrue( 440 fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches( 441 FATE_REPORT_DRIVER_TIMESTAMP_USEC + " " // timestamp 442 + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} " // walltime 443 + "TX " // direction 444 + Pattern.quote(fateMapping.mExpectedText) + " " // fate 445 + "802.11 Mgmt " // type 446 + "N/A " // protocol 447 + "N/A" // result 448 ) 449 ); 450 } 451 } 452 453 /** 454 * Verifies that TxFateReport.toVerboseStringWithPiiAllowed() includes the information we care 455 * about. 456 */ 457 @Test testTxFateReportToVerboseStringWithPiiAllowed()458 public void testTxFateReportToVerboseStringWithPiiAllowed() { 459 WifiNative.TxFateReport fateReport = TX_FATE_REPORT; 460 461 String verboseFateString = fateReport.toVerboseStringWithPiiAllowed(); 462 assertTrue(verboseFateString.contains("Frame direction: TX")); 463 assertTrue(verboseFateString.contains("Frame timestamp: 12345")); 464 assertTrue(verboseFateString.contains("Frame fate: sent")); 465 assertTrue(verboseFateString.contains("Frame type: data")); 466 assertTrue(verboseFateString.contains("Frame protocol: Ethernet")); 467 assertTrue(verboseFateString.contains("Frame protocol type: N/A")); 468 assertTrue(verboseFateString.contains("Frame length: 16")); 469 assertTrue(verboseFateString.contains( 470 "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump 471 // TODO(quiche): uncomment this, once b/27975149 is fixed. 472 // assertTrue(verboseFateString.contains("abcdefgh........")); // hex dump 473 474 for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) { 475 fateReport = new WifiNative.TxFateReport( 476 WifiLoggerHal.TX_PKT_FATE_SENT, 477 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 478 frameTypeMapping.mTypeNumber, 479 FATE_REPORT_FRAME_BYTES 480 ); 481 verboseFateString = fateReport.toVerboseStringWithPiiAllowed(); 482 assertTrue(verboseFateString.contains("Frame type: " 483 + frameTypeMapping.mExpectedTypeText)); 484 } 485 486 for (FateMapping fateMapping : TX_FATE_MAPPINGS) { 487 fateReport = new WifiNative.TxFateReport( 488 fateMapping.mFateNumber, 489 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 490 WifiLoggerHal.FRAME_TYPE_80211_MGMT, 491 FATE_REPORT_FRAME_BYTES 492 ); 493 verboseFateString = fateReport.toVerboseStringWithPiiAllowed(); 494 assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText)); 495 } 496 } 497 498 /** 499 * Verifies that RxFateReport.toTableRowString() includes the information we care about. 500 */ 501 @Test testRxFateReportToTableRowString()502 public void testRxFateReportToTableRowString() { 503 WifiNative.RxFateReport fateReport = RX_FATE_REPORT; 504 assertTrue( 505 fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches( 506 FATE_REPORT_DRIVER_TIMESTAMP_USEC + " " // timestamp 507 + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} " // walltime 508 + "RX " // direction 509 + Pattern.quote("firmware dropped (invalid frame) ") // fate 510 + "Ethernet " // type 511 + "N/A " // protocol 512 + "N/A" // result 513 ) 514 ); 515 516 // FrameTypeMappings omitted, as they're the same as for TX. 517 518 for (FateMapping fateMapping : RX_FATE_MAPPINGS) { 519 fateReport = new WifiNative.RxFateReport( 520 fateMapping.mFateNumber, 521 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 522 WifiLoggerHal.FRAME_TYPE_80211_MGMT, 523 FATE_REPORT_FRAME_BYTES 524 ); 525 assertTrue( 526 fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches( 527 FATE_REPORT_DRIVER_TIMESTAMP_USEC + " " // timestamp 528 + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} " // walltime 529 + "RX " // direction 530 + Pattern.quote(fateMapping.mExpectedText) + " " // fate 531 + "802.11 Mgmt " // type 532 + "N/A " // protocol 533 + "N/A" // result 534 ) 535 ); 536 } 537 } 538 539 /** 540 * Verifies that RxFateReport.toVerboseStringWithPiiAllowed() includes the information we care 541 * about. 542 */ 543 @Test testRxFateReportToVerboseStringWithPiiAllowed()544 public void testRxFateReportToVerboseStringWithPiiAllowed() { 545 WifiNative.RxFateReport fateReport = RX_FATE_REPORT; 546 547 String verboseFateString = fateReport.toVerboseStringWithPiiAllowed(); 548 assertTrue(verboseFateString.contains("Frame direction: RX")); 549 assertTrue(verboseFateString.contains("Frame timestamp: 12345")); 550 assertTrue(verboseFateString.contains("Frame fate: firmware dropped (invalid frame)")); 551 assertTrue(verboseFateString.contains("Frame type: data")); 552 assertTrue(verboseFateString.contains("Frame protocol: Ethernet")); 553 assertTrue(verboseFateString.contains("Frame protocol type: N/A")); 554 assertTrue(verboseFateString.contains("Frame length: 16")); 555 assertTrue(verboseFateString.contains( 556 "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump 557 // TODO(quiche): uncomment this, once b/27975149 is fixed. 558 // assertTrue(verboseFateString.contains("abcdefgh........")); // hex dump 559 560 // FrameTypeMappings omitted, as they're the same as for TX. 561 562 for (FateMapping fateMapping : RX_FATE_MAPPINGS) { 563 fateReport = new WifiNative.RxFateReport( 564 fateMapping.mFateNumber, 565 FATE_REPORT_DRIVER_TIMESTAMP_USEC, 566 WifiLoggerHal.FRAME_TYPE_80211_MGMT, 567 FATE_REPORT_FRAME_BYTES 568 ); 569 verboseFateString = fateReport.toVerboseStringWithPiiAllowed(); 570 assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText)); 571 } 572 } 573 574 /** 575 * Verifies that startPktFateMonitoring returns false when HAL is not started. 576 */ 577 @Test testStartPktFateMonitoringReturnsFalseWhenHalIsNotStarted()578 public void testStartPktFateMonitoringReturnsFalseWhenHalIsNotStarted() { 579 assertFalse(mWifiNative.isHalStarted()); 580 assertFalse(mWifiNative.startPktFateMonitoring(WIFI_IFACE_NAME)); 581 } 582 583 /** 584 * Verifies that getTxPktFates returns error when HAL is not started. 585 */ 586 @Test testGetTxPktFatesReturnsErrorWhenHalIsNotStarted()587 public void testGetTxPktFatesReturnsErrorWhenHalIsNotStarted() { 588 assertFalse(mWifiNative.isHalStarted()); 589 assertEquals(0, mWifiNative.getTxPktFates(WIFI_IFACE_NAME).size()); 590 } 591 592 /** 593 * Verifies that getRxPktFates returns error when HAL is not started. 594 */ 595 @Test testGetRxPktFatesReturnsErrorWhenHalIsNotStarted()596 public void testGetRxPktFatesReturnsErrorWhenHalIsNotStarted() { 597 assertFalse(mWifiNative.isHalStarted()); 598 assertEquals(0, mWifiNative.getRxPktFates(WIFI_IFACE_NAME).size()); 599 } 600 601 // TODO(quiche): Add tests for the success cases (when HAL has been started). Specifically: 602 // - testStartPktFateMonitoringCallsHalIfHalIsStarted() 603 // - testGetTxPktFatesCallsHalIfHalIsStarted() 604 // - testGetRxPktFatesCallsHalIfHalIsStarted() 605 // 606 // Adding these tests is difficult to do at the moment, because we can't mock out the HAL 607 // itself. Also, we can't mock out the native methods, because those methods are private. 608 // b/28005116. 609 610 /** Verifies that getDriverStateDumpNative returns null when HAL is not started. */ 611 @Test testGetDriverStateDumpReturnsNullWhenHalIsNotStarted()612 public void testGetDriverStateDumpReturnsNullWhenHalIsNotStarted() { 613 assertEquals(null, mWifiNative.getDriverStateDump()); 614 } 615 616 // TODO(b/28005116): Add test for the success case of getDriverStateDump(). 617 618 /** 619 * Verifies client mode + scan success. 620 */ 621 @Test testClientModeScanSuccess()622 public void testClientModeScanSuccess() { 623 mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE); 624 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 625 mScanCallbackCaptor.capture(), any()); 626 627 mScanCallbackCaptor.getValue().onScanResultReady(); 628 verify(mWifiMonitor).broadcastScanResultEvent(WIFI_IFACE_NAME); 629 } 630 631 /** 632 * Verifies client mode + scan failure. 633 */ 634 @Test testClientModeScanFailure()635 public void testClientModeScanFailure() { 636 mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE); 637 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 638 mScanCallbackCaptor.capture(), any()); 639 640 mScanCallbackCaptor.getValue().onScanFailed(); 641 verify(mWifiMonitor).broadcastScanFailedEvent(WIFI_IFACE_NAME); 642 } 643 644 /** 645 * Verifies client mode + PNO scan success. 646 */ 647 @Test testClientModePnoScanSuccess()648 public void testClientModePnoScanSuccess() { 649 mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE); 650 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 651 any(), mScanCallbackCaptor.capture()); 652 653 mScanCallbackCaptor.getValue().onScanResultReady(); 654 verify(mWifiMonitor).broadcastPnoScanResultEvent(WIFI_IFACE_NAME); 655 verify(mWifiMetrics).incrementPnoFoundNetworkEventCount(); 656 } 657 658 /** 659 * Verifies client mode + PNO scan failure. 660 */ 661 @Test testClientModePnoScanFailure()662 public void testClientModePnoScanFailure() { 663 mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE); 664 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 665 any(), mScanCallbackCaptor.capture()); 666 667 mScanCallbackCaptor.getValue().onScanFailed(); 668 verify(mWifiMetrics).incrementPnoScanFailedCount(); 669 } 670 671 /** 672 * Verifies scan mode + scan success. 673 */ 674 @Test testScanModeScanSuccess()675 public void testScanModeScanSuccess() { 676 mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE); 677 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 678 mScanCallbackCaptor.capture(), any()); 679 680 mScanCallbackCaptor.getValue().onScanResultReady(); 681 verify(mWifiMonitor).broadcastScanResultEvent(WIFI_IFACE_NAME); 682 } 683 684 /** 685 * Verifies scan mode + scan failure. 686 */ 687 @Test testScanModeScanFailure()688 public void testScanModeScanFailure() { 689 mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE); 690 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 691 mScanCallbackCaptor.capture(), any()); 692 693 mScanCallbackCaptor.getValue().onScanFailed(); 694 verify(mWifiMonitor).broadcastScanFailedEvent(WIFI_IFACE_NAME); 695 } 696 697 /** 698 * Verifies scan mode + PNO scan success. 699 */ 700 @Test testScanModePnoScanSuccess()701 public void testScanModePnoScanSuccess() { 702 mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE); 703 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 704 any(), mScanCallbackCaptor.capture()); 705 706 mScanCallbackCaptor.getValue().onScanResultReady(); 707 verify(mWifiMonitor).broadcastPnoScanResultEvent(WIFI_IFACE_NAME); 708 verify(mWifiMetrics).incrementPnoFoundNetworkEventCount(); 709 } 710 711 /** 712 * Verifies scan mode + PNO scan failure. 713 */ 714 @Test testScanModePnoScanFailure()715 public void testScanModePnoScanFailure() { 716 mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE); 717 verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(), 718 any(), mScanCallbackCaptor.capture()); 719 720 mScanCallbackCaptor.getValue().onScanFailed(); 721 verify(mWifiMetrics).incrementPnoScanFailedCount(); 722 } 723 724 /** 725 * Verifies starting the hal results in coex unsafe channels being updated with cached values. 726 */ 727 @Test testStartHalUpdatesCoexUnsafeChannels()728 public void testStartHalUpdatesCoexUnsafeChannels() { 729 assumeTrue(SdkLevel.isAtLeastS()); 730 final List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>(); 731 unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6)); 732 unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_5_GHZ, 36)); 733 final int restrictions = 0; 734 when(mCoexManager.getCoexUnsafeChannels()).thenReturn(unsafeChannels); 735 when(mCoexManager.getCoexRestrictions()).thenReturn(restrictions); 736 mWifiNative.setCoexUnsafeChannels(unsafeChannels, restrictions); 737 738 mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE); 739 verify(mWifiVendorHal, times(2)).setCoexUnsafeChannels(unsafeChannels, restrictions); 740 741 mWifiNative.teardownAllInterfaces(); 742 mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE); 743 verify(mWifiVendorHal, times(3)).setCoexUnsafeChannels(unsafeChannels, restrictions); 744 745 mWifiNative.teardownAllInterfaces(); 746 mWifiNative.setupInterfaceForSoftApMode(null, TEST_WORKSOURCE, WIFI_BAND_24_GHZ, false); 747 verify(mWifiVendorHal, times(4)).setCoexUnsafeChannels(unsafeChannels, restrictions); 748 } 749 750 /** 751 * Verifies that signalPoll() calls underlying WificondControl. 752 */ 753 @Test testSignalPoll()754 public void testSignalPoll() throws Exception { 755 when(mWificondControl.signalPoll(WIFI_IFACE_NAME)) 756 .thenReturn(SIGNAL_POLL_RESULT); 757 758 WifiNl80211Manager.SignalPollResult pollResult = mWifiNative.signalPoll(WIFI_IFACE_NAME); 759 assertEquals(SIGNAL_POLL_RESULT.currentRssiDbm, pollResult.currentRssiDbm); 760 assertEquals(SIGNAL_POLL_RESULT.txBitrateMbps, pollResult.txBitrateMbps); 761 assertEquals(SIGNAL_POLL_RESULT.associationFrequencyMHz, 762 pollResult.associationFrequencyMHz); 763 assertEquals(SIGNAL_POLL_RESULT.rxBitrateMbps, pollResult.rxBitrateMbps); 764 765 verify(mWificondControl).signalPoll(WIFI_IFACE_NAME); 766 } 767 768 /** 769 * Verifies that scan() calls underlying WificondControl. 770 */ 771 @Test testScan()772 public void testScan() throws Exception { 773 // This test will not run if the device has SDK level S or later 774 assumeFalse(SdkLevel.isAtLeastS()); 775 mWifiNative.scan(WIFI_IFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, SCAN_FREQ_SET, 776 SCAN_HIDDEN_NETWORK_SSID_SET, false); 777 ArgumentCaptor<List<byte[]>> ssidSetCaptor = ArgumentCaptor.forClass(List.class); 778 verify(mWificondControl).startScan( 779 eq(WIFI_IFACE_NAME), eq(WifiScanner.SCAN_TYPE_HIGH_ACCURACY), 780 eq(SCAN_FREQ_SET), ssidSetCaptor.capture()); 781 List<byte[]> ssidSet = ssidSetCaptor.getValue(); 782 assertArrayEquals(ssidSet.toArray(), SCAN_HIDDEN_NETWORK_BYTE_SSID_SET.toArray()); 783 } 784 785 /** 786 * Verifies that scan() calls the new startScan API with a Bundle when the Sdk level 787 * is S or above. 788 */ 789 @Test testScanWithBundle()790 public void testScanWithBundle() throws Exception { 791 // This test will only run if the device has SDK level S and later. 792 assumeTrue(SdkLevel.isAtLeastS()); 793 mWifiNative.scan(WIFI_IFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, SCAN_FREQ_SET, 794 SCAN_HIDDEN_NETWORK_SSID_SET, true); 795 ArgumentCaptor<List<byte[]>> ssidSetCaptor = ArgumentCaptor.forClass(List.class); 796 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 797 verify(mWificondControl).startScan( 798 eq(WIFI_IFACE_NAME), eq(WifiScanner.SCAN_TYPE_HIGH_ACCURACY), 799 eq(SCAN_FREQ_SET), ssidSetCaptor.capture(), bundleCaptor.capture()); 800 List<byte[]> ssidSet = ssidSetCaptor.getValue(); 801 assertArrayEquals(ssidSet.toArray(), SCAN_HIDDEN_NETWORK_BYTE_SSID_SET.toArray()); 802 Bundle bundle = bundleCaptor.getValue(); 803 assertTrue(bundle.getBoolean(WifiNl80211Manager.SCANNING_PARAM_ENABLE_6GHZ_RNR)); 804 } 805 806 /** 807 * Verifies that startPnoscan() calls underlying WificondControl. 808 */ 809 @Test testStartPnoScanOnRequestProcessed()810 public void testStartPnoScanOnRequestProcessed() throws Exception { 811 mWifiNative.startPnoScan(WIFI_IFACE_NAME, TEST_PNO_SETTINGS); 812 813 ArgumentCaptor<WifiNl80211Manager.PnoScanRequestCallback> captor = 814 ArgumentCaptor.forClass(WifiNl80211Manager.PnoScanRequestCallback.class); 815 verify(mWificondControl).startPnoScan(eq(WIFI_IFACE_NAME), 816 eq(TEST_PNO_SETTINGS.toNativePnoSettings()), any(), captor.capture()); 817 captor.getValue().onPnoRequestSucceeded(); 818 verify(mWifiMetrics).incrementPnoScanStartAttemptCount(); 819 } 820 821 /** 822 * Verifies that startPnoscan() calls underlying WificondControl. 823 */ 824 @Test testStartPnoScanOnRequestFailed()825 public void testStartPnoScanOnRequestFailed() throws Exception { 826 mWifiNative.startPnoScan(WIFI_IFACE_NAME, TEST_PNO_SETTINGS); 827 828 ArgumentCaptor<WifiNl80211Manager.PnoScanRequestCallback> captor = 829 ArgumentCaptor.forClass(WifiNl80211Manager.PnoScanRequestCallback.class); 830 verify(mWificondControl).startPnoScan(eq(WIFI_IFACE_NAME), 831 eq(TEST_PNO_SETTINGS.toNativePnoSettings()), any(), captor.capture()); 832 captor.getValue().onPnoRequestFailed(); 833 verify(mWifiMetrics).incrementPnoScanStartAttemptCount(); 834 verify(mWifiMetrics).incrementPnoScanFailedCount(); 835 } 836 837 /** 838 * Verifies that stopPnoscan() calls underlying WificondControl. 839 */ 840 @Test testStopPnoScan()841 public void testStopPnoScan() throws Exception { 842 mWifiNative.stopPnoScan(WIFI_IFACE_NAME); 843 verify(mWificondControl).stopPnoScan(WIFI_IFACE_NAME); 844 } 845 846 /** 847 * Verifies that getScanResults() can parse NativeScanResult from wificond correctly, 848 */ 849 @Test testGetScanResults()850 public void testGetScanResults() { 851 // Mock the returned array of NativeScanResult. 852 List<NativeScanResult> mockScanResults = Arrays.asList(MOCK_NATIVE_SCAN_RESULT); 853 when(mWificondControl.getScanResults(anyString(), anyInt())).thenReturn(mockScanResults); 854 855 ArrayList<ScanDetail> returnedScanResults = mWifiNative.getScanResults(WIFI_IFACE_NAME); 856 assertEquals(mockScanResults.size(), returnedScanResults.size()); 857 // Since NativeScanResult is organized differently from ScanResult, this only checks 858 // a few fields. 859 for (int i = 0; i < mockScanResults.size(); i++) { 860 assertArrayEquals(mockScanResults.get(i).getSsid(), 861 returnedScanResults.get(i).getScanResult().SSID.getBytes()); 862 assertEquals(mockScanResults.get(i).getFrequencyMhz(), 863 returnedScanResults.get(i).getScanResult().frequency); 864 assertEquals(mockScanResults.get(i).getTsf(), 865 returnedScanResults.get(i).getScanResult().timestamp); 866 } 867 } 868 869 /** 870 * Verifies that getScanResults() can parse NativeScanResult from wificond correctly, 871 * when there is radio chain info. 872 */ 873 @Test testGetScanResultsWithRadioChainInfo()874 public void testGetScanResultsWithRadioChainInfo() throws Exception { 875 // Mock the returned array of NativeScanResult. 876 NativeScanResult nativeScanResult = createMockNativeScanResult(); 877 // Add radio chain info 878 List<RadioChainInfo> nativeRadioChainInfos = Arrays.asList( 879 MOCK_NATIVE_RADIO_CHAIN_INFO_1, MOCK_NATIVE_RADIO_CHAIN_INFO_2); 880 nativeScanResult.radioChainInfos = nativeRadioChainInfos; 881 List<NativeScanResult> mockScanResults = Arrays.asList(nativeScanResult); 882 883 when(mWificondControl.getScanResults(anyString(), anyInt())).thenReturn(mockScanResults); 884 885 ArrayList<ScanDetail> returnedScanResults = mWifiNative.getScanResults(WIFI_IFACE_NAME); 886 assertEquals(mockScanResults.size(), returnedScanResults.size()); 887 // Since NativeScanResult is organized differently from ScanResult, this only checks 888 // a few fields. 889 for (int i = 0; i < mockScanResults.size(); i++) { 890 assertArrayEquals(mockScanResults.get(i).getSsid(), 891 returnedScanResults.get(i).getScanResult().SSID.getBytes()); 892 assertEquals(mockScanResults.get(i).getFrequencyMhz(), 893 returnedScanResults.get(i).getScanResult().frequency); 894 assertEquals(mockScanResults.get(i).getTsf(), 895 returnedScanResults.get(i).getScanResult().timestamp); 896 ScanResult.RadioChainInfo[] scanRcis = returnedScanResults.get( 897 i).getScanResult().radioChainInfos; 898 assertEquals(nativeRadioChainInfos.size(), scanRcis.length); 899 for (int j = 0; j < scanRcis.length; ++j) { 900 assertEquals(nativeRadioChainInfos.get(j).getChainId(), scanRcis[j].id); 901 assertEquals(nativeRadioChainInfos.get(j).getLevelDbm(), scanRcis[j].level); 902 } 903 } 904 } 905 906 /** 907 * Verifies that connectToNetwork() calls underlying WificondControl and SupplicantStaIfaceHal. 908 */ 909 @Test testConnectToNetwork()910 public void testConnectToNetwork() throws Exception { 911 WifiConfiguration config = mock(WifiConfiguration.class); 912 mWifiNative.connectToNetwork(WIFI_IFACE_NAME, config); 913 // connectToNetwork() should abort ongoing scan before connection. 914 verify(mWificondControl).abortScan(WIFI_IFACE_NAME); 915 verify(mStaIfaceHal).connectToNetwork(WIFI_IFACE_NAME, config); 916 } 917 918 /** 919 * Verifies that roamToNetwork() calls underlying WificondControl and SupplicantStaIfaceHal. 920 */ 921 @Test testRoamToNetwork()922 public void testRoamToNetwork() throws Exception { 923 WifiConfiguration config = mock(WifiConfiguration.class); 924 mWifiNative.roamToNetwork(WIFI_IFACE_NAME, config); 925 // roamToNetwork() should abort ongoing scan before connection. 926 verify(mWificondControl).abortScan(WIFI_IFACE_NAME); 927 verify(mStaIfaceHal).roamToNetwork(WIFI_IFACE_NAME, config); 928 } 929 930 /** 931 * Verifies that removeIfaceInstanceFromBridgedApIface() calls underlying WifiVendorHal. 932 */ 933 @Test testRemoveIfaceInstanceFromBridgedApIface()934 public void testRemoveIfaceInstanceFromBridgedApIface() throws Exception { 935 mWifiNative.removeIfaceInstanceFromBridgedApIface( 936 "br_" + WIFI_IFACE_NAME, WIFI_IFACE_NAME); 937 verify(mWifiVendorHal).removeIfaceInstanceFromBridgedApIface( 938 "br_" + WIFI_IFACE_NAME, WIFI_IFACE_NAME); 939 } 940 941 /** 942 * Verifies that setMacAddress() calls underlying WifiVendorHal. 943 */ 944 @Test testStaSetMacAddress()945 public void testStaSetMacAddress() throws Exception { 946 mWifiNative.setStaMacAddress(WIFI_IFACE_NAME, TEST_MAC_ADDRESS); 947 verify(mStaIfaceHal).disconnect(WIFI_IFACE_NAME); 948 verify(mWifiVendorHal).setStaMacAddress(WIFI_IFACE_NAME, TEST_MAC_ADDRESS); 949 } 950 951 /** 952 * Verifies that setMacAddress() calls underlying WifiVendorHal. 953 */ 954 @Test testApSetMacAddress()955 public void testApSetMacAddress() throws Exception { 956 mWifiNative.setApMacAddress(WIFI_IFACE_NAME, TEST_MAC_ADDRESS); 957 verify(mWifiVendorHal).setApMacAddress(WIFI_IFACE_NAME, TEST_MAC_ADDRESS); 958 } 959 960 /** 961 * Verifies that resetApMacToFactoryMacAddress() calls underlying WifiVendorHal. 962 */ 963 @Test testResetApMacToFactoryMacAddress()964 public void testResetApMacToFactoryMacAddress() throws Exception { 965 mWifiNative.resetApMacToFactoryMacAddress(WIFI_IFACE_NAME); 966 verify(mWifiVendorHal).resetApMacToFactoryMacAddress(WIFI_IFACE_NAME); 967 } 968 969 /** 970 * Verifies that setCoexUnsafeChannels() calls underlying WifiVendorHal. 971 */ 972 @Test testSetCoexUnsafeChannels()973 public void testSetCoexUnsafeChannels() throws Exception { 974 assumeTrue(SdkLevel.isAtLeastS()); 975 mWifiNative.setCoexUnsafeChannels(Collections.emptyList(), 0); 976 verify(mWifiVendorHal).setCoexUnsafeChannels(Collections.emptyList(), 0); 977 } 978 979 /** 980 * Verifies that isSetMacAddressSupported() calls underlying WifiVendorHal. 981 */ 982 @Test testIsStaSetMacAddressSupported()983 public void testIsStaSetMacAddressSupported() throws Exception { 984 mWifiNative.isStaSetMacAddressSupported(WIFI_IFACE_NAME); 985 verify(mWifiVendorHal).isStaSetMacAddressSupported(WIFI_IFACE_NAME); 986 } 987 988 /** 989 * Verifies that isSetMacAddressSupported() calls underlying WifiVendorHal. 990 */ 991 @Test testIsApSetMacAddressSupported()992 public void testIsApSetMacAddressSupported() throws Exception { 993 mWifiNative.isApSetMacAddressSupported(WIFI_IFACE_NAME); 994 verify(mWifiVendorHal).isApSetMacAddressSupported(WIFI_IFACE_NAME); 995 } 996 997 /** 998 * Test that selectTxPowerScenario() calls into WifiVendorHal (success case) 999 */ 1000 @Test testSelectTxPowerScenario_success()1001 public void testSelectTxPowerScenario_success() throws Exception { 1002 when(mWifiVendorHal.selectTxPowerScenario(any(SarInfo.class))).thenReturn(true); 1003 SarInfo sarInfo = new SarInfo(); 1004 assertTrue(mWifiNative.selectTxPowerScenario(sarInfo)); 1005 verify(mWifiVendorHal).selectTxPowerScenario(sarInfo); 1006 } 1007 1008 /** 1009 * Test that selectTxPowerScenario() calls into WifiVendorHal (failure case) 1010 */ 1011 @Test testSelectTxPowerScenario_failure()1012 public void testSelectTxPowerScenario_failure() throws Exception { 1013 when(mWifiVendorHal.selectTxPowerScenario(any(SarInfo.class))).thenReturn(false); 1014 SarInfo sarInfo = new SarInfo(); 1015 assertFalse(mWifiNative.selectTxPowerScenario(sarInfo)); 1016 verify(mWifiVendorHal).selectTxPowerScenario(sarInfo); 1017 } 1018 1019 /** 1020 * Test that setPowerSave() with true, results in calling into SupplicantStaIfaceHal 1021 */ 1022 @Test testSetPowerSaveTrue()1023 public void testSetPowerSaveTrue() throws Exception { 1024 mWifiNative.setPowerSave(WIFI_IFACE_NAME, true); 1025 verify(mStaIfaceHal).setPowerSave(WIFI_IFACE_NAME, true); 1026 } 1027 1028 /** 1029 * Test that setPowerSave() with false, results in calling into SupplicantStaIfaceHal 1030 */ 1031 @Test testSetPowerSaveFalse()1032 public void testSetPowerSaveFalse() throws Exception { 1033 mWifiNative.setPowerSave(WIFI_IFACE_NAME, false); 1034 verify(mStaIfaceHal).setPowerSave(WIFI_IFACE_NAME, false); 1035 } 1036 1037 /** 1038 * Test that setLowLatencyMode() with true, results in calling into WifiVendorHal 1039 */ 1040 @Test testLowLatencyModeTrue()1041 public void testLowLatencyModeTrue() throws Exception { 1042 when(mWifiVendorHal.setLowLatencyMode(anyBoolean())).thenReturn(true); 1043 assertTrue(mWifiNative.setLowLatencyMode(true)); 1044 verify(mWifiVendorHal).setLowLatencyMode(true); 1045 } 1046 1047 /** 1048 * Test that setLowLatencyMode() with false, results in calling into WifiVendorHal 1049 */ 1050 @Test testLowLatencyModeFalse()1051 public void testLowLatencyModeFalse() throws Exception { 1052 when(mWifiVendorHal.setLowLatencyMode(anyBoolean())).thenReturn(true); 1053 assertTrue(mWifiNative.setLowLatencyMode(false)); 1054 verify(mWifiVendorHal).setLowLatencyMode(false); 1055 } 1056 1057 /** 1058 * Test that setLowLatencyMode() returns with failure when WifiVendorHal fails. 1059 */ 1060 @Test testSetLowLatencyModeFail()1061 public void testSetLowLatencyModeFail() throws Exception { 1062 final boolean lowLatencyMode = true; 1063 when(mWifiVendorHal.setLowLatencyMode(anyBoolean())).thenReturn(false); 1064 assertFalse(mWifiNative.setLowLatencyMode(lowLatencyMode)); 1065 verify(mWifiVendorHal).setLowLatencyMode(lowLatencyMode); 1066 } 1067 1068 @Test testStaGetFactoryMacAddress()1069 public void testStaGetFactoryMacAddress() throws Exception { 1070 when(mWifiVendorHal.getStaFactoryMacAddress(any())) 1071 .thenReturn(MacAddress.BROADCAST_ADDRESS); 1072 assertNotNull(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)); 1073 verify(mWifiVendorHal).getStaFactoryMacAddress(any()); 1074 } 1075 1076 1077 @Test testGetApFactoryMacAddress()1078 public void testGetApFactoryMacAddress() throws Exception { 1079 when(mWifiVendorHal.getApFactoryMacAddress(any())).thenReturn(MacAddress.BROADCAST_ADDRESS); 1080 assertNotNull(mWifiNative.getApFactoryMacAddress(WIFI_IFACE_NAME)); 1081 verify(mWifiVendorHal).getApFactoryMacAddress(any()); 1082 } 1083 1084 /** 1085 * Test that flushRingBufferData(), results in calling into WifiVendorHal 1086 */ 1087 @Test testFlushRingBufferDataTrue()1088 public void testFlushRingBufferDataTrue() throws Exception { 1089 when(mWifiVendorHal.flushRingBufferData()).thenReturn(true); 1090 assertTrue(mWifiNative.flushRingBufferData()); 1091 verify(mWifiVendorHal).flushRingBufferData(); 1092 } 1093 1094 /** 1095 * Tests that WifiNative#sendMgmtFrame() calls WificondControl#sendMgmtFrame() 1096 */ 1097 @Test testSendMgmtFrame()1098 public void testSendMgmtFrame() { 1099 mWifiNative.sendMgmtFrame(WIFI_IFACE_NAME, FATE_REPORT_FRAME_BYTES, 1100 mSendMgmtFrameCallback, TEST_MCS_RATE); 1101 1102 verify(mWificondControl).sendMgmtFrame(eq(WIFI_IFACE_NAME), 1103 AdditionalMatchers.aryEq(FATE_REPORT_FRAME_BYTES), eq(TEST_MCS_RATE), 1104 any(), eq(mSendMgmtFrameCallback)); 1105 } 1106 1107 /** 1108 * Tests that probeLink() generates the correct frame and calls WificondControl#sendMgmtFrame(). 1109 */ 1110 @Test testProbeLinkSuccess()1111 public void testProbeLinkSuccess() { 1112 byte[] expectedFrame = { 1113 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 1114 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, 1115 (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, 1116 0x00, 0x00 1117 }; 1118 1119 when(mStaIfaceHal.getMacAddress(WIFI_IFACE_NAME)).thenReturn(TEST_MAC_ADDRESS_STR); 1120 1121 when(mRandom.nextInt()).thenReturn(TEST_SEQUENCE_NUM); 1122 1123 mWifiNative.probeLink(WIFI_IFACE_NAME, MacAddress.fromString(TEST_BSSID_STR), 1124 mSendMgmtFrameCallback, TEST_MCS_RATE); 1125 1126 verify(mSendMgmtFrameCallback, never()).onFailure(anyInt()); 1127 verify(mWificondControl).sendMgmtFrame(eq(WIFI_IFACE_NAME), 1128 AdditionalMatchers.aryEq(expectedFrame), eq(TEST_MCS_RATE), 1129 any(), eq(mSendMgmtFrameCallback)); 1130 } 1131 1132 /** 1133 * Tests that probeLink() triggers the failure callback when it cannot get the sender MAC 1134 * address. 1135 */ 1136 @Test testProbeLinkFailureCannotGetSenderMac()1137 public void testProbeLinkFailureCannotGetSenderMac() { 1138 when(mStaIfaceHal.getMacAddress(WIFI_IFACE_NAME)).thenReturn(null); 1139 1140 mWifiNative.probeLink(WIFI_IFACE_NAME, MacAddress.fromString(TEST_BSSID_STR), 1141 mSendMgmtFrameCallback, TEST_MCS_RATE); 1142 1143 verify(mSendMgmtFrameCallback).onFailure( 1144 WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); 1145 verify(mWificondControl, never()).sendMgmtFrame(any(), any(), anyInt(), any(), any()); 1146 } 1147 1148 /** 1149 * Tests that probeLink() triggers the failure callback when it cannot get the BSSID. 1150 */ 1151 @Test testProbeLinkFailureCannotGetBssid()1152 public void testProbeLinkFailureCannotGetBssid() { 1153 when(mStaIfaceHal.getMacAddress(WIFI_IFACE_NAME)).thenReturn(TEST_MAC_ADDRESS_STR); 1154 1155 mWifiNative.probeLink(WIFI_IFACE_NAME, null, mSendMgmtFrameCallback, TEST_MCS_RATE); 1156 1157 verify(mSendMgmtFrameCallback).onFailure( 1158 WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); 1159 verify(mWificondControl, never()).sendMgmtFrame(any(), any(), anyInt(), any(), any()); 1160 } 1161 1162 /** 1163 * Tests that WifiNative#addHlpReq() calls 1164 * SupplicantStaIfaceHal#addHlpReq() 1165 */ 1166 @Test testaddHlpReq()1167 public void testaddHlpReq() { 1168 byte[] hlpPacket = { 1169 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 1170 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, 1171 (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, 1172 0x00, 0x00 1173 }; 1174 mWifiNative.addHlpReq(WIFI_IFACE_NAME, TEST_MAC_ADDRESS, hlpPacket); 1175 1176 verify(mStaIfaceHal).addHlpReq(eq(WIFI_IFACE_NAME), 1177 eq(TEST_MAC_ADDRESS.toByteArray()), eq(hlpPacket)); 1178 } 1179 1180 /** 1181 * Tests that WifiNative#flushAllHlp() calls 1182 * SupplicantStaIfaceHal#flushAllHlp() 1183 */ 1184 @Test testflushAllHlp()1185 public void testflushAllHlp() { 1186 mWifiNative.flushAllHlp(WIFI_IFACE_NAME); 1187 1188 verify(mStaIfaceHal).flushAllHlp(eq(WIFI_IFACE_NAME)); 1189 } 1190 1191 @Test testIsItPossibleToCreateIface()1192 public void testIsItPossibleToCreateIface() { 1193 when(mWifiVendorHal.isItPossibleToCreateApIface(any())).thenReturn(true); 1194 assertTrue(mWifiNative.isItPossibleToCreateApIface(new WorkSource())); 1195 1196 when(mWifiVendorHal.isItPossibleToCreateStaIface(any())).thenReturn(true); 1197 assertTrue(mWifiNative.isItPossibleToCreateStaIface(new WorkSource())); 1198 } 1199 1200 @Test testReplaceStaIfaceRequestorWs()1201 public void testReplaceStaIfaceRequestorWs() { 1202 assertEquals(WIFI_IFACE_NAME, 1203 mWifiNative.setupInterfaceForClientInConnectivityMode( 1204 mInterfaceCallback, TEST_WORKSOURCE)); 1205 when(mWifiVendorHal.replaceStaIfaceRequestorWs(WIFI_IFACE_NAME, TEST_WORKSOURCE2)) 1206 .thenReturn(true); 1207 1208 assertTrue(mWifiNative.replaceStaIfaceRequestorWs(WIFI_IFACE_NAME, TEST_WORKSOURCE2)); 1209 verify(mWifiVendorHal).replaceStaIfaceRequestorWs( 1210 eq(WIFI_IFACE_NAME), same(TEST_WORKSOURCE2)); 1211 } 1212 1213 /** 1214 * Verifies that updateLinkedNetworks() calls underlying SupplicantStaIfaceHal. 1215 */ 1216 @Test testUpdateLinkedNetworks()1217 public void testUpdateLinkedNetworks() { 1218 when(mStaIfaceHal.updateLinkedNetworks(any(), anyInt(), any())).thenReturn(true); 1219 1220 assertTrue(mWifiNative.updateLinkedNetworks(WIFI_IFACE_NAME, 0, null)); 1221 verify(mStaIfaceHal).updateLinkedNetworks(WIFI_IFACE_NAME, 0, null); 1222 } 1223 1224 /** 1225 * Verifies that getEapAnonymousIdentity() works as expected. 1226 */ 1227 @Test testGetEapAnonymousIdentity()1228 public void testGetEapAnonymousIdentity() { 1229 // Verify the empty use case 1230 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1231 .thenReturn(""); 1232 assertTrue(TextUtils.isEmpty(mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME))); 1233 1234 // Verify with an anonymous identity 1235 final String anonymousId = "anonymous@homerealm.example.org"; 1236 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1237 .thenReturn(anonymousId); 1238 assertEquals(anonymousId, mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME)); 1239 1240 // Verify with a pseudonym identity 1241 final String pseudonymId = "a4624bc22490da3@homerealm.example.org"; 1242 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1243 .thenReturn(pseudonymId); 1244 assertEquals(pseudonymId, mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME)); 1245 1246 // Verify that decorated anonymous identity is truncated 1247 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1248 .thenReturn("otherrealm.example.net!" + anonymousId); 1249 assertEquals(anonymousId, mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME)); 1250 1251 // Verify that recursive decorated anonymous identity is truncated 1252 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1253 .thenReturn("proxyrealm.example.com!otherrealm.example.net!" + anonymousId); 1254 assertEquals(anonymousId, mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME)); 1255 1256 // Verify an invalid decoration with no identity use cases 1257 when(mStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(WIFI_IFACE_NAME)) 1258 .thenReturn("otherrealm.example.net!"); 1259 assertNull(mWifiNative.getEapAnonymousIdentity(WIFI_IFACE_NAME)); 1260 } 1261 1262 1263 @Test testCountryCodeChangedListener()1264 public void testCountryCodeChangedListener() { 1265 assumeTrue(SdkLevel.isAtLeastS()); 1266 final String testCountryCode = "US"; 1267 ArgumentCaptor<WifiNl80211Manager.CountryCodeChangedListener> 1268 mCountryCodeChangedListenerCaptor = ArgumentCaptor.forClass( 1269 WifiNl80211Manager.CountryCodeChangedListener.class); 1270 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1271 verify(mWificondControl).registerCountryCodeChangedListener(any(), 1272 mCountryCodeChangedListenerCaptor.capture()); 1273 mCountryCodeChangedListenerCaptor.getValue().onCountryCodeChanged(testCountryCode); 1274 verify(mWifiCountryCodeChangeListener).onDriverCountryCodeChanged(testCountryCode); 1275 } 1276 1277 @Test testSetStaCountryCodeSuccessful()1278 public void testSetStaCountryCodeSuccessful() { 1279 when(mStaIfaceHal.setCountryCode(any(), any())).thenReturn(true); 1280 final String testCountryCode = "US"; 1281 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1282 mWifiNative.setStaCountryCode(WIFI_IFACE_NAME, testCountryCode); 1283 verify(mStaIfaceHal).setCountryCode(WIFI_IFACE_NAME, testCountryCode); 1284 if (SdkLevel.isAtLeastS()) { 1285 verify(mWifiCountryCodeChangeListener).onSetCountryCodeSucceeded(testCountryCode); 1286 } 1287 } 1288 1289 @Test testSetStaCountryCodeFailure()1290 public void testSetStaCountryCodeFailure() { 1291 when(mStaIfaceHal.setCountryCode(any(), any())).thenReturn(false); 1292 final String testCountryCode = "US"; 1293 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1294 mWifiNative.setStaCountryCode(WIFI_IFACE_NAME, testCountryCode); 1295 verify(mStaIfaceHal).setCountryCode(WIFI_IFACE_NAME, testCountryCode); 1296 if (SdkLevel.isAtLeastS()) { 1297 verify(mWifiCountryCodeChangeListener, never()) 1298 .onSetCountryCodeSucceeded(testCountryCode); 1299 } 1300 } 1301 1302 @Test testSetApCountryCodeSuccessful()1303 public void testSetApCountryCodeSuccessful() { 1304 when(mWifiVendorHal.setApCountryCode(any(), any())).thenReturn(true); 1305 final String testCountryCode = "US"; 1306 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1307 mWifiNative.setApCountryCode(WIFI_IFACE_NAME, testCountryCode); 1308 verify(mWifiVendorHal).setApCountryCode(WIFI_IFACE_NAME, testCountryCode); 1309 if (SdkLevel.isAtLeastS()) { 1310 verify(mWifiCountryCodeChangeListener).onSetCountryCodeSucceeded(testCountryCode); 1311 } 1312 } 1313 1314 @Test testSetApCountryCodeFailure()1315 public void testSetApCountryCodeFailure() { 1316 when(mWifiVendorHal.setApCountryCode(any(), any())).thenReturn(false); 1317 final String testCountryCode = "US"; 1318 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1319 mWifiNative.setApCountryCode(WIFI_IFACE_NAME, testCountryCode); 1320 verify(mWifiVendorHal).setApCountryCode(WIFI_IFACE_NAME, testCountryCode); 1321 if (SdkLevel.isAtLeastS()) { 1322 verify(mWifiCountryCodeChangeListener, never()) 1323 .onSetCountryCodeSucceeded(testCountryCode); 1324 } 1325 } 1326 1327 @Test testSetChipCountryCodeSuccessful()1328 public void testSetChipCountryCodeSuccessful() { 1329 when(mWifiVendorHal.setChipCountryCode(any())).thenReturn(true); 1330 final String testCountryCode = "US"; 1331 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1332 mWifiNative.setChipCountryCode(testCountryCode); 1333 verify(mWifiVendorHal).setChipCountryCode(testCountryCode); 1334 if (SdkLevel.isAtLeastS()) { 1335 verify(mWifiCountryCodeChangeListener).onSetCountryCodeSucceeded(testCountryCode); 1336 } 1337 } 1338 1339 @Test testSetChipCountryCodeFailure()1340 public void testSetChipCountryCodeFailure() { 1341 when(mWifiVendorHal.setChipCountryCode(any())).thenReturn(false); 1342 final String testCountryCode = "US"; 1343 mWifiNative.registerCountryCodeEventListener(mWifiCountryCodeChangeListener); 1344 mWifiNative.setChipCountryCode(testCountryCode); 1345 verify(mWifiVendorHal).setChipCountryCode(testCountryCode); 1346 if (SdkLevel.isAtLeastS()) { 1347 verify(mWifiCountryCodeChangeListener, never()) 1348 .onSetCountryCodeSucceeded(testCountryCode); 1349 } 1350 } 1351 } 1352