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