1 /* 2 * Copyright (C) 2022 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.hal; 18 19 import static com.android.server.wifi.TestUtil.createCapabilityBitset; 20 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertTrue; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.anyByte; 29 import static org.mockito.Mockito.doAnswer; 30 import static org.mockito.Mockito.doThrow; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.when; 33 34 import android.app.test.MockAnswerUtil; 35 import android.content.Context; 36 import android.content.res.Resources; 37 import android.hardware.wifi.V1_0.IWifiStaIface; 38 import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats; 39 import android.hardware.wifi.V1_0.StaLinkLayerIfaceStats; 40 import android.hardware.wifi.V1_0.StaLinkLayerRadioStats; 41 import android.hardware.wifi.V1_0.StaLinkLayerStats; 42 import android.hardware.wifi.V1_0.StaRoamingCapabilities; 43 import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType; 44 import android.hardware.wifi.V1_0.WifiDebugRxPacketFate; 45 import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport; 46 import android.hardware.wifi.V1_0.WifiDebugTxPacketFate; 47 import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport; 48 import android.hardware.wifi.V1_0.WifiStatus; 49 import android.hardware.wifi.V1_0.WifiStatusCode; 50 import android.hardware.wifi.V1_3.WifiChannelStats; 51 import android.hardware.wifi.V1_5.StaLinkLayerIfaceContentionTimeStats; 52 import android.hardware.wifi.V1_5.StaPeerInfo; 53 import android.hardware.wifi.V1_5.StaRateStat; 54 import android.net.MacAddress; 55 import android.net.wifi.WifiManager; 56 import android.os.RemoteException; 57 58 import com.android.server.wifi.SsidTranslator; 59 import com.android.server.wifi.WifiBaseTest; 60 import com.android.server.wifi.WifiLinkLayerStats; 61 import com.android.server.wifi.WifiLoggerHal; 62 import com.android.server.wifi.WifiNative; 63 import com.android.server.wifi.util.NativeUtil; 64 import com.android.wifi.resources.R; 65 66 import org.junit.Before; 67 import org.junit.Test; 68 import org.mockito.Mock; 69 import org.mockito.MockitoAnnotations; 70 71 import java.util.ArrayList; 72 import java.util.Arrays; 73 import java.util.BitSet; 74 import java.util.Collections; 75 import java.util.List; 76 import java.util.Random; 77 78 public class WifiStaIfaceHidlImplTest extends WifiBaseTest { 79 private static final int[] TEST_FREQUENCIES = {2412, 2417, 2422, 2427, 2432, 2437}; 80 private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92"); 81 82 private WifiStaIfaceHidlImpl mDut; 83 private WifiStatus mWifiStatusSuccess; 84 private WifiStatus mWifiStatusFailure; 85 private WifiStatus mWifiStatusBusy; 86 87 @Mock private IWifiStaIface mIWifiStaIfaceMock; 88 @Mock private android.hardware.wifi.V1_2.IWifiStaIface mIWifiStaIfaceMockV12; 89 @Mock private android.hardware.wifi.V1_3.IWifiStaIface mIWifiStaIfaceMockV13; 90 @Mock private android.hardware.wifi.V1_5.IWifiStaIface mIWifiStaIfaceMockV15; 91 @Mock private Context mContextMock; 92 @Mock private Resources mResourcesMock; 93 @Mock private SsidTranslator mSsidTranslatorMock; 94 95 private class WifiStaIfaceHidlImplSpy extends WifiStaIfaceHidlImpl { 96 private int mVersion; 97 WifiStaIfaceHidlImplSpy(int hidlVersion)98 WifiStaIfaceHidlImplSpy(int hidlVersion) { 99 super(mIWifiStaIfaceMock, mContextMock, mSsidTranslatorMock); 100 mVersion = hidlVersion; 101 } 102 103 @Override getWifiStaIfaceV1_2Mockable()104 protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceV1_2Mockable() { 105 return mVersion >= 2 ? mIWifiStaIfaceMockV12 : null; 106 } 107 108 @Override getWifiStaIfaceV1_3Mockable()109 protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceV1_3Mockable() { 110 return mVersion >= 3 ? mIWifiStaIfaceMockV13 : null; 111 } 112 113 @Override getWifiStaIfaceV1_5Mockable()114 protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceV1_5Mockable() { 115 return mVersion >= 5 ? mIWifiStaIfaceMockV15 : null; 116 } 117 118 @Override getWifiStaIfaceV1_6Mockable()119 protected android.hardware.wifi.V1_6.IWifiStaIface getWifiStaIfaceV1_6Mockable() { 120 return null; 121 } 122 } 123 124 @Before setUp()125 public void setUp() throws Exception { 126 MockitoAnnotations.initMocks(this); 127 when(mContextMock.getResources()).thenReturn(mResourcesMock); 128 mDut = new WifiStaIfaceHidlImplSpy(0); 129 130 mWifiStatusSuccess = new WifiStatus(); 131 mWifiStatusSuccess.code = WifiStatusCode.SUCCESS; 132 mWifiStatusFailure = new WifiStatus(); 133 mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN; 134 mWifiStatusFailure.description = "I don't even know what a Mock Turtle is."; 135 mWifiStatusBusy = new WifiStatus(); 136 mWifiStatusBusy.code = WifiStatusCode.ERROR_BUSY; 137 mWifiStatusBusy.description = "Don't bother me, kid"; 138 } 139 140 /** 141 * Test translation to WifiManager.WIFI_FEATURE_* 142 */ 143 @Test testStaIfaceFeatureMaskTranslation()144 public void testStaIfaceFeatureMaskTranslation() { 145 int caps = ( 146 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN 147 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS 148 ); 149 BitSet expected = createCapabilityBitset( 150 WifiManager.WIFI_FEATURE_SCANNER, WifiManager.WIFI_FEATURE_LINK_LAYER_STATS); 151 assertTrue(expected.equals(mDut.halToFrameworkStaIfaceCapability(caps))); 152 } 153 154 /** 155 * Test that getFactoryMacAddress gets called when the HAL version is V1_3. 156 */ 157 @Test testGetStaFactoryMacWithHalV1_3()158 public void testGetStaFactoryMacWithHalV1_3() throws Exception { 159 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 160 public void answer( 161 android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback cb) 162 throws RemoteException { 163 cb.onValues(mWifiStatusSuccess, MacAddress.BROADCAST_ADDRESS.toByteArray()); 164 } 165 }).when(mIWifiStaIfaceMockV13).getFactoryMacAddress(any( 166 android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback.class)); 167 mDut = new WifiStaIfaceHidlImplSpy(3); 168 assertEquals(MacAddress.BROADCAST_ADDRESS, mDut.getFactoryMacAddress()); 169 } 170 171 /** 172 * Test that getLinkLayerStats_1_3 gets called when the HAL version is V1_3. 173 */ 174 @Test testLinkLayerStatsCorrectVersionWithHalV1_3()175 public void testLinkLayerStatsCorrectVersionWithHalV1_3() throws Exception { 176 mDut = new WifiStaIfaceHidlImplSpy(3); 177 mDut.getLinkLayerStats(); 178 verify(mIWifiStaIfaceMockV13).getLinkLayerStats_1_3(any()); 179 } 180 181 /** 182 * Test getLinkLayerStats_1_5 gets called when the hal version is V1_5. 183 */ 184 @Test testLinkLayerStatsCorrectVersionWithHalV1_5()185 public void testLinkLayerStatsCorrectVersionWithHalV1_5() throws Exception { 186 mDut = new WifiStaIfaceHidlImplSpy(5); 187 mDut.getLinkLayerStats(); 188 verify(mIWifiStaIfaceMockV15).getLinkLayerStats_1_5(any()); 189 } 190 191 /** 192 * Populate packet stats with non-negative random values. 193 */ randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats)194 private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) { 195 pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits 196 pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL; 197 pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL; 198 pstats.retries = r.nextLong() & 0xFFFFFFFFFFL; 199 } 200 201 /** 202 * Populate contention time stats with non-negative random values. 203 */ randomizeContentionTimeStats(Random r, StaLinkLayerIfaceContentionTimeStats cstats)204 private static void randomizeContentionTimeStats(Random r, 205 StaLinkLayerIfaceContentionTimeStats cstats) { 206 cstats.contentionTimeMinInUsec = r.nextInt() & 0x7FFFFFFF; 207 cstats.contentionTimeMaxInUsec = r.nextInt() & 0x7FFFFFFF; 208 cstats.contentionTimeAvgInUsec = r.nextInt() & 0x7FFFFFFF; 209 cstats.contentionNumSamples = r.nextInt() & 0x7FFFFFFF; 210 } 211 212 /** 213 * Populate radio stats with non-negative random values. 214 */ randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats)215 private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) { 216 StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats(); 217 rstat.onTimeInMs = r.nextInt() & 0xFFFFFF; 218 rstat.txTimeInMs = r.nextInt() & 0xFFFFFF; 219 for (int i = 0; i < 4; i++) { 220 Integer v = r.nextInt() & 0xFFFFFF; 221 rstat.txTimeInMsPerLevel.add(v); 222 } 223 rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF; 224 rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF; 225 rstats.add(rstat); 226 } 227 228 /** 229 * Populate radio stats V1_3 with non-negative random values. 230 */ randomizeRadioStats_1_3(Random r, android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat)231 private static void randomizeRadioStats_1_3(Random r, 232 android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat) { 233 rstat.V1_0.onTimeInMs = r.nextInt() & 0xFFFFFF; 234 rstat.V1_0.txTimeInMs = r.nextInt() & 0xFFFFFF; 235 for (int j = 0; j < 4; j++) { 236 Integer v = r.nextInt() & 0xFFFFFF; 237 rstat.V1_0.txTimeInMsPerLevel.add(v); 238 } 239 rstat.V1_0.rxTimeInMs = r.nextInt() & 0xFFFFFF; 240 rstat.V1_0.onTimeInMsForScan = r.nextInt() & 0xFFFFFF; 241 rstat.onTimeInMsForNanScan = r.nextInt() & 0xFFFFFF; 242 rstat.onTimeInMsForBgScan = r.nextInt() & 0xFFFFFF; 243 rstat.onTimeInMsForRoamScan = r.nextInt() & 0xFFFFFF; 244 rstat.onTimeInMsForPnoScan = r.nextInt() & 0xFFFFFF; 245 rstat.onTimeInMsForHs20Scan = r.nextInt() & 0xFFFFFF; 246 for (int k = 0; k < TEST_FREQUENCIES.length; k++) { 247 WifiChannelStats channelStats = new WifiChannelStats(); 248 channelStats.channel.centerFreq = TEST_FREQUENCIES[k]; 249 channelStats.onTimeInMs = r.nextInt() & 0xFFFFFF; 250 channelStats.ccaBusyTimeInMs = r.nextInt() & 0xFFFFFF; 251 rstat.channelStats.add(channelStats); 252 } 253 } 254 255 /** 256 * Populate radio stats V1_5 with non-negative random values. 257 */ randomizeRadioStats_1_5(Random r, android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat)258 private static void randomizeRadioStats_1_5(Random r, 259 android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat) { 260 rstat.radioId = r.nextInt() & 0xFFFFFF; 261 randomizeRadioStats_1_3(r, rstat.V1_3); 262 } 263 264 /** 265 * Populate peer info stats with non-negative random values. 266 */ randomizePeerInfoStats(Random r, ArrayList<StaPeerInfo> pstats)267 private static void randomizePeerInfoStats(Random r, ArrayList<StaPeerInfo> pstats) { 268 StaPeerInfo pstat = new StaPeerInfo(); 269 pstat.staCount = 2; 270 pstat.chanUtil = 90; 271 pstat.rateStats = new ArrayList<StaRateStat>(); 272 StaRateStat rateStat = new StaRateStat(); 273 rateStat.rateInfo.preamble = r.nextInt() & 0x7FFFFFFF; 274 rateStat.rateInfo.nss = r.nextInt() & 0x7FFFFFFF; 275 rateStat.rateInfo.bw = r.nextInt() & 0x7FFFFFFF; 276 rateStat.rateInfo.rateMcsIdx = 9; 277 rateStat.rateInfo.bitRateInKbps = 101; 278 rateStat.txMpdu = r.nextInt() & 0x7FFFFFFF; 279 rateStat.rxMpdu = r.nextInt() & 0x7FFFFFFF; 280 rateStat.mpduLost = r.nextInt() & 0x7FFFFFFF; 281 rateStat.retries = r.nextInt() & 0x7FFFFFFF; 282 pstat.rateStats.add(rateStat); 283 pstats.add(pstat); 284 } 285 verifyIfaceStats(StaLinkLayerIfaceStats iface, WifiLinkLayerStats wifiLinkLayerStats)286 private void verifyIfaceStats(StaLinkLayerIfaceStats iface, 287 WifiLinkLayerStats wifiLinkLayerStats) { 288 assertEquals(iface.beaconRx, wifiLinkLayerStats.links[0].beacon_rx); 289 assertEquals(iface.avgRssiMgmt, wifiLinkLayerStats.links[0].rssi_mgmt); 290 291 assertEquals(iface.wmeBePktStats.rxMpdu, wifiLinkLayerStats.links[0].rxmpdu_be); 292 assertEquals(iface.wmeBePktStats.txMpdu, wifiLinkLayerStats.links[0].txmpdu_be); 293 assertEquals(iface.wmeBePktStats.lostMpdu, wifiLinkLayerStats.links[0].lostmpdu_be); 294 assertEquals(iface.wmeBePktStats.retries, wifiLinkLayerStats.links[0].retries_be); 295 296 assertEquals(iface.wmeBkPktStats.rxMpdu, wifiLinkLayerStats.links[0].rxmpdu_bk); 297 assertEquals(iface.wmeBkPktStats.txMpdu, wifiLinkLayerStats.links[0].txmpdu_bk); 298 assertEquals(iface.wmeBkPktStats.lostMpdu, wifiLinkLayerStats.links[0].lostmpdu_bk); 299 assertEquals(iface.wmeBkPktStats.retries, wifiLinkLayerStats.links[0].retries_bk); 300 301 assertEquals(iface.wmeViPktStats.rxMpdu, wifiLinkLayerStats.links[0].rxmpdu_vi); 302 assertEquals(iface.wmeViPktStats.txMpdu, wifiLinkLayerStats.links[0].txmpdu_vi); 303 assertEquals(iface.wmeViPktStats.lostMpdu, wifiLinkLayerStats.links[0].lostmpdu_vi); 304 assertEquals(iface.wmeViPktStats.retries, wifiLinkLayerStats.links[0].retries_vi); 305 306 assertEquals(iface.wmeVoPktStats.rxMpdu, wifiLinkLayerStats.links[0].rxmpdu_vo); 307 assertEquals(iface.wmeVoPktStats.txMpdu, wifiLinkLayerStats.links[0].txmpdu_vo); 308 assertEquals(iface.wmeVoPktStats.lostMpdu, wifiLinkLayerStats.links[0].lostmpdu_vo); 309 assertEquals(iface.wmeVoPktStats.retries, wifiLinkLayerStats.links[0].retries_vo); 310 } 311 verifyIfaceStats_1_5(android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface, WifiLinkLayerStats wifiLinkLayerStats)312 private void verifyIfaceStats_1_5(android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface, 313 WifiLinkLayerStats wifiLinkLayerStats) { 314 assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMinInUsec, 315 wifiLinkLayerStats.links[0].contentionTimeMinBeInUsec); 316 assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec, 317 wifiLinkLayerStats.links[0].contentionTimeMaxBeInUsec); 318 assertEquals(iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec, 319 wifiLinkLayerStats.links[0].contentionTimeAvgBeInUsec); 320 assertEquals(iface.wmeBeContentionTimeStats.contentionNumSamples, 321 wifiLinkLayerStats.links[0].contentionNumSamplesBe); 322 323 assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMinInUsec, 324 wifiLinkLayerStats.links[0].contentionTimeMinBkInUsec); 325 assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec, 326 wifiLinkLayerStats.links[0].contentionTimeMaxBkInUsec); 327 assertEquals(iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec, 328 wifiLinkLayerStats.links[0].contentionTimeAvgBkInUsec); 329 assertEquals(iface.wmeBkContentionTimeStats.contentionNumSamples, 330 wifiLinkLayerStats.links[0].contentionNumSamplesBk); 331 332 assertEquals(iface.wmeViContentionTimeStats.contentionTimeMinInUsec, 333 wifiLinkLayerStats.links[0].contentionTimeMinViInUsec); 334 assertEquals(iface.wmeViContentionTimeStats.contentionTimeMaxInUsec, 335 wifiLinkLayerStats.links[0].contentionTimeMaxViInUsec); 336 assertEquals(iface.wmeViContentionTimeStats.contentionTimeAvgInUsec, 337 wifiLinkLayerStats.links[0].contentionTimeAvgViInUsec); 338 assertEquals(iface.wmeViContentionTimeStats.contentionNumSamples, 339 wifiLinkLayerStats.links[0].contentionNumSamplesVi); 340 341 assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMinInUsec, 342 wifiLinkLayerStats.links[0].contentionTimeMinVoInUsec); 343 assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec, 344 wifiLinkLayerStats.links[0].contentionTimeMaxVoInUsec); 345 assertEquals(iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec, 346 wifiLinkLayerStats.links[0].contentionTimeAvgVoInUsec); 347 assertEquals(iface.wmeVoContentionTimeStats.contentionNumSamples, 348 wifiLinkLayerStats.links[0].contentionNumSamplesVo); 349 350 for (int i = 0; i < iface.peers.size(); i++) { 351 assertEquals(iface.peers.get(i).staCount, wifiLinkLayerStats.links[0] 352 .peerInfo[i].staCount); 353 assertEquals(iface.peers.get(i).chanUtil, wifiLinkLayerStats.links[0] 354 .peerInfo[i].chanUtil); 355 for (int j = 0; j < iface.peers.get(i).rateStats.size(); j++) { 356 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.preamble, 357 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].preamble); 358 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.nss, 359 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].nss); 360 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bw, 361 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].bw); 362 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.rateMcsIdx, 363 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].rateMcsIdx); 364 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bitRateInKbps, 365 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].bitRateInKbps); 366 assertEquals(iface.peers.get(i).rateStats.get(j).txMpdu, 367 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].txMpdu); 368 assertEquals(iface.peers.get(i).rateStats.get(j).rxMpdu, 369 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].rxMpdu); 370 assertEquals(iface.peers.get(i).rateStats.get(j).mpduLost, 371 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].mpduLost); 372 assertEquals(iface.peers.get(i).rateStats.get(j).retries, 373 wifiLinkLayerStats.links[0].peerInfo[i].rateStats[j].retries); 374 } 375 } 376 } 377 verifyRadioStats(List<StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)378 private void verifyRadioStats(List<StaLinkLayerRadioStats> radios, 379 WifiLinkLayerStats wifiLinkLayerStats) { 380 StaLinkLayerRadioStats radio = radios.get(0); 381 assertEquals(radio.onTimeInMs, wifiLinkLayerStats.on_time); 382 assertEquals(radio.txTimeInMs, wifiLinkLayerStats.tx_time); 383 assertEquals(radio.rxTimeInMs, wifiLinkLayerStats.rx_time); 384 assertEquals(radio.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan); 385 assertEquals(radio.txTimeInMsPerLevel.size(), 386 wifiLinkLayerStats.tx_time_per_level.length); 387 for (int i = 0; i < radio.txTimeInMsPerLevel.size(); i++) { 388 assertEquals((int) radio.txTimeInMsPerLevel.get(i), 389 wifiLinkLayerStats.tx_time_per_level[i]); 390 } 391 } 392 verifyRadioStats_1_3( android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio, WifiLinkLayerStats wifiLinkLayerStats)393 private void verifyRadioStats_1_3( 394 android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio, 395 WifiLinkLayerStats wifiLinkLayerStats) { 396 assertEquals(radio.V1_0.onTimeInMs, wifiLinkLayerStats.on_time); 397 assertEquals(radio.V1_0.txTimeInMs, wifiLinkLayerStats.tx_time); 398 assertEquals(radio.V1_0.rxTimeInMs, wifiLinkLayerStats.rx_time); 399 assertEquals(radio.V1_0.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan); 400 assertEquals(radio.V1_0.txTimeInMsPerLevel.size(), 401 wifiLinkLayerStats.tx_time_per_level.length); 402 for (int i = 0; i < radio.V1_0.txTimeInMsPerLevel.size(); i++) { 403 assertEquals((int) radio.V1_0.txTimeInMsPerLevel.get(i), 404 wifiLinkLayerStats.tx_time_per_level[i]); 405 } 406 assertEquals(radio.onTimeInMsForNanScan, wifiLinkLayerStats.on_time_nan_scan); 407 assertEquals(radio.onTimeInMsForBgScan, wifiLinkLayerStats.on_time_background_scan); 408 assertEquals(radio.onTimeInMsForRoamScan, wifiLinkLayerStats.on_time_roam_scan); 409 assertEquals(radio.onTimeInMsForPnoScan, wifiLinkLayerStats.on_time_pno_scan); 410 assertEquals(radio.onTimeInMsForHs20Scan, wifiLinkLayerStats.on_time_hs20_scan); 411 assertEquals(radio.channelStats.size(), 412 wifiLinkLayerStats.channelStatsMap.size()); 413 for (int j = 0; j < radio.channelStats.size(); j++) { 414 WifiChannelStats channelStats = radio.channelStats.get(j); 415 WifiLinkLayerStats.ChannelStats retrievedChannelStats = 416 wifiLinkLayerStats.channelStatsMap.get(channelStats.channel.centerFreq); 417 assertNotNull(retrievedChannelStats); 418 assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency); 419 assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs); 420 assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs); 421 } 422 } 423 verifyPerRadioStats(List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)424 private void verifyPerRadioStats(List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, 425 WifiLinkLayerStats wifiLinkLayerStats) { 426 assertEquals(radios.size(), 427 wifiLinkLayerStats.radioStats.length); 428 for (int i = 0; i < radios.size(); i++) { 429 android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio = radios.get(i); 430 WifiLinkLayerStats.RadioStat radioStat = wifiLinkLayerStats.radioStats[i]; 431 assertEquals(radio.radioId, radioStat.radio_id); 432 assertEquals(radio.V1_3.V1_0.onTimeInMs, radioStat.on_time); 433 assertEquals(radio.V1_3.V1_0.txTimeInMs, radioStat.tx_time); 434 assertEquals(radio.V1_3.V1_0.rxTimeInMs, radioStat.rx_time); 435 assertEquals(radio.V1_3.V1_0.onTimeInMsForScan, radioStat.on_time_scan); 436 assertEquals(radio.V1_3.onTimeInMsForNanScan, radioStat.on_time_nan_scan); 437 assertEquals(radio.V1_3.onTimeInMsForBgScan, radioStat.on_time_background_scan); 438 assertEquals(radio.V1_3.onTimeInMsForRoamScan, radioStat.on_time_roam_scan); 439 assertEquals(radio.V1_3.onTimeInMsForPnoScan, radioStat.on_time_pno_scan); 440 assertEquals(radio.V1_3.onTimeInMsForHs20Scan, radioStat.on_time_hs20_scan); 441 442 assertEquals(radio.V1_3.channelStats.size(), 443 radioStat.channelStatsMap.size()); 444 for (int j = 0; j < radio.V1_3.channelStats.size(); j++) { 445 WifiChannelStats channelStats = radio.V1_3.channelStats.get(j); 446 WifiLinkLayerStats.ChannelStats retrievedChannelStats = 447 radioStat.channelStatsMap.get(channelStats.channel.centerFreq); 448 assertNotNull(retrievedChannelStats); 449 assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency); 450 assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs); 451 assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs); 452 } 453 } 454 455 } 456 verifyRadioStats_1_5( android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio, WifiLinkLayerStats wifiLinkLayerStats)457 private void verifyRadioStats_1_5( 458 android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio, 459 WifiLinkLayerStats wifiLinkLayerStats) { 460 verifyRadioStats_1_3(radio.V1_3, wifiLinkLayerStats); 461 } 462 verifyTwoRadioStatsAggregation( android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0, android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1, WifiLinkLayerStats wifiLinkLayerStats)463 private void verifyTwoRadioStatsAggregation( 464 android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0, 465 android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1, 466 WifiLinkLayerStats wifiLinkLayerStats) { 467 assertEquals(radio0.V1_0.onTimeInMs + radio1.V1_0.onTimeInMs, 468 wifiLinkLayerStats.on_time); 469 assertEquals(radio0.V1_0.txTimeInMs + radio1.V1_0.txTimeInMs, 470 wifiLinkLayerStats.tx_time); 471 assertEquals(radio0.V1_0.rxTimeInMs + radio1.V1_0.rxTimeInMs, 472 wifiLinkLayerStats.rx_time); 473 assertEquals(radio0.V1_0.onTimeInMsForScan + radio1.V1_0.onTimeInMsForScan, 474 wifiLinkLayerStats.on_time_scan); 475 assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(), 476 radio1.V1_0.txTimeInMsPerLevel.size()); 477 assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(), 478 wifiLinkLayerStats.tx_time_per_level.length); 479 for (int i = 0; i < radio0.V1_0.txTimeInMsPerLevel.size(); i++) { 480 assertEquals((int) radio0.V1_0.txTimeInMsPerLevel.get(i) 481 + (int) radio1.V1_0.txTimeInMsPerLevel.get(i), 482 wifiLinkLayerStats.tx_time_per_level[i]); 483 } 484 assertEquals(radio0.onTimeInMsForNanScan + radio1.onTimeInMsForNanScan, 485 wifiLinkLayerStats.on_time_nan_scan); 486 assertEquals(radio0.onTimeInMsForBgScan + radio1.onTimeInMsForBgScan, 487 wifiLinkLayerStats.on_time_background_scan); 488 assertEquals(radio0.onTimeInMsForRoamScan + radio1.onTimeInMsForRoamScan, 489 wifiLinkLayerStats.on_time_roam_scan); 490 assertEquals(radio0.onTimeInMsForPnoScan + radio1.onTimeInMsForPnoScan, 491 wifiLinkLayerStats.on_time_pno_scan); 492 assertEquals(radio0.onTimeInMsForHs20Scan + radio1.onTimeInMsForHs20Scan, 493 wifiLinkLayerStats.on_time_hs20_scan); 494 assertEquals(radio0.channelStats.size(), radio1.channelStats.size()); 495 assertEquals(radio0.channelStats.size(), 496 wifiLinkLayerStats.channelStatsMap.size()); 497 for (int j = 0; j < radio0.channelStats.size(); j++) { 498 WifiChannelStats radio0ChannelStats = radio0.channelStats.get(j); 499 WifiChannelStats radio1ChannelStats = radio1.channelStats.get(j); 500 WifiLinkLayerStats.ChannelStats retrievedChannelStats = 501 wifiLinkLayerStats.channelStatsMap.get(radio0ChannelStats.channel.centerFreq); 502 assertNotNull(retrievedChannelStats); 503 assertEquals(radio0ChannelStats.channel.centerFreq, retrievedChannelStats.frequency); 504 assertEquals(radio1ChannelStats.channel.centerFreq, retrievedChannelStats.frequency); 505 assertEquals(radio0ChannelStats.onTimeInMs + radio1ChannelStats.onTimeInMs, 506 retrievedChannelStats.radioOnTimeMs); 507 assertEquals(radio0ChannelStats.ccaBusyTimeInMs 508 + radio1ChannelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs); 509 } 510 } 511 verifyTwoRadioStatsAggregation_1_3( List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)512 private void verifyTwoRadioStatsAggregation_1_3( 513 List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios, 514 WifiLinkLayerStats wifiLinkLayerStats) { 515 assertEquals(2, radios.size()); 516 android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0 = radios.get(0); 517 android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1 = radios.get(1); 518 verifyTwoRadioStatsAggregation(radio0, radio1, wifiLinkLayerStats); 519 } 520 verifyTwoRadioStatsAggregation_1_5( List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)521 private void verifyTwoRadioStatsAggregation_1_5( 522 List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, 523 WifiLinkLayerStats wifiLinkLayerStats) { 524 assertEquals(2, radios.size()); 525 android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio0 = radios.get(0); 526 android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio1 = radios.get(1); 527 verifyTwoRadioStatsAggregation(radio0.V1_3, radio1.V1_3, wifiLinkLayerStats); 528 } 529 530 /** 531 * Test that the link layer stats fields are populated correctly. 532 */ 533 @Test testLinkLayerStatsAssignment()534 public void testLinkLayerStatsAssignment() throws Exception { 535 Random r = new Random(1775968256); 536 StaLinkLayerStats stats = new StaLinkLayerStats(); 537 randomizePacketStats(r, stats.iface.wmeBePktStats); 538 randomizePacketStats(r, stats.iface.wmeBkPktStats); 539 randomizePacketStats(r, stats.iface.wmeViPktStats); 540 randomizePacketStats(r, stats.iface.wmeVoPktStats); 541 randomizeRadioStats(r, stats.radios); 542 stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL; 543 544 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats(stats); 545 546 verifyIfaceStats(stats.iface, converted); 547 verifyRadioStats(stats.radios, converted); 548 assertEquals(stats.timeStampInMs, converted.timeStampInMs); 549 assertEquals(WifiLinkLayerStats.V1_0, converted.version); 550 } 551 552 /** 553 * Test that the link layer stats V1_3 fields are populated correctly. 554 */ 555 @Test testLinkLayerStatsAssignment_1_3()556 public void testLinkLayerStatsAssignment_1_3() throws Exception { 557 Random r = new Random(1775968256); 558 android.hardware.wifi.V1_3.StaLinkLayerStats stats = 559 new android.hardware.wifi.V1_3.StaLinkLayerStats(); 560 randomizePacketStats(r, stats.iface.wmeBePktStats); 561 randomizePacketStats(r, stats.iface.wmeBkPktStats); 562 randomizePacketStats(r, stats.iface.wmeViPktStats); 563 randomizePacketStats(r, stats.iface.wmeVoPktStats); 564 android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat = 565 new android.hardware.wifi.V1_3.StaLinkLayerRadioStats(); 566 randomizeRadioStats_1_3(r, rstat); 567 stats.radios.add(rstat); 568 stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL; 569 570 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_3(stats); 571 572 verifyIfaceStats(stats.iface, converted); 573 verifyRadioStats_1_3(stats.radios.get(0), converted); 574 assertEquals(stats.timeStampInMs, converted.timeStampInMs); 575 assertEquals(WifiLinkLayerStats.V1_3, converted.version); 576 assertEquals(1, converted.numRadios); 577 } 578 579 /** 580 * Test that the link layer stats V1_5 fields are populated correctly. 581 */ 582 @Test testLinkLayerStatsAssignment_1_5()583 public void testLinkLayerStatsAssignment_1_5() throws Exception { 584 Random r = new Random(1775968256); 585 android.hardware.wifi.V1_5.StaLinkLayerStats stats = 586 new android.hardware.wifi.V1_5.StaLinkLayerStats(); 587 randomizePacketStats(r, stats.iface.V1_0.wmeBePktStats); 588 randomizePacketStats(r, stats.iface.V1_0.wmeBkPktStats); 589 randomizePacketStats(r, stats.iface.V1_0.wmeViPktStats); 590 randomizePacketStats(r, stats.iface.V1_0.wmeVoPktStats); 591 android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat = 592 new android.hardware.wifi.V1_5.StaLinkLayerRadioStats(); 593 randomizeRadioStats_1_5(r, rstat); 594 stats.radios.add(rstat); 595 stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL; 596 randomizeContentionTimeStats(r, stats.iface.wmeBeContentionTimeStats); 597 randomizeContentionTimeStats(r, stats.iface.wmeBkContentionTimeStats); 598 randomizeContentionTimeStats(r, stats.iface.wmeViContentionTimeStats); 599 randomizeContentionTimeStats(r, stats.iface.wmeVoContentionTimeStats); 600 randomizePeerInfoStats(r, stats.iface.peers); 601 602 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_5(stats); 603 604 verifyIfaceStats(stats.iface.V1_0, converted); 605 verifyIfaceStats_1_5(stats.iface, converted); 606 verifyPerRadioStats(stats.radios, converted); 607 verifyRadioStats_1_5(stats.radios.get(0), converted); 608 assertEquals(stats.timeStampInMs, converted.timeStampInMs); 609 assertEquals(WifiLinkLayerStats.V1_5, converted.version); 610 assertEquals(1, converted.numRadios); 611 } 612 613 /** 614 * Test that the link layer stats V1_3 fields are aggregated correctly for two radios. 615 */ 616 @Test testTwoRadioStatsAggregation_1_3()617 public void testTwoRadioStatsAggregation_1_3() throws Exception { 618 when(mResourcesMock.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)) 619 .thenReturn(true); 620 mDut = new WifiStaIfaceHidlImplSpy(0); 621 Random r = new Random(245786856); 622 android.hardware.wifi.V1_3.StaLinkLayerStats stats = 623 new android.hardware.wifi.V1_3.StaLinkLayerStats(); 624 // Fill stats in two radios 625 for (int i = 0; i < 2; i++) { 626 android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat = 627 new android.hardware.wifi.V1_3.StaLinkLayerRadioStats(); 628 randomizeRadioStats_1_3(r, rstat); 629 stats.radios.add(rstat); 630 } 631 632 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_3(stats); 633 verifyTwoRadioStatsAggregation_1_3(stats.radios, converted); 634 assertEquals(2, converted.numRadios); 635 } 636 637 /** 638 * Test that the link layer stats V1_3 fields are not aggregated on setting 639 * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false (default value). 640 */ 641 @Test testRadioStatsAggregationDisabled_1_3()642 public void testRadioStatsAggregationDisabled_1_3() throws Exception { 643 Random r = new Random(245786856); 644 android.hardware.wifi.V1_3.StaLinkLayerStats stats = 645 new android.hardware.wifi.V1_3.StaLinkLayerStats(); 646 // Fill stats in two radios 647 for (int i = 0; i < 2; i++) { 648 android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat = 649 new android.hardware.wifi.V1_3.StaLinkLayerRadioStats(); 650 randomizeRadioStats_1_3(r, rstat); 651 stats.radios.add(rstat); 652 } 653 654 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_3(stats); 655 verifyRadioStats_1_3(stats.radios.get(0), converted); 656 assertEquals(1, converted.numRadios); 657 } 658 659 /** 660 * Test that the link layer stats V1_5 fields are aggregated correctly for two radios. 661 */ 662 @Test testTwoRadioStatsAggregation_1_5()663 public void testTwoRadioStatsAggregation_1_5() throws Exception { 664 when(mResourcesMock.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)) 665 .thenReturn(true); 666 mDut = new WifiStaIfaceHidlImplSpy(0); 667 Random r = new Random(245786856); 668 android.hardware.wifi.V1_5.StaLinkLayerStats stats = 669 new android.hardware.wifi.V1_5.StaLinkLayerStats(); 670 // Fill stats in two radios 671 for (int i = 0; i < 2; i++) { 672 android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat = 673 new android.hardware.wifi.V1_5.StaLinkLayerRadioStats(); 674 randomizeRadioStats_1_5(r, rstat); 675 stats.radios.add(rstat); 676 } 677 678 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_5(stats); 679 verifyPerRadioStats(stats.radios, converted); 680 verifyTwoRadioStatsAggregation_1_5(stats.radios, converted); 681 assertEquals(2, converted.numRadios); 682 } 683 684 /** 685 * Test that the link layer stats V1_5 fields are not aggregated on setting 686 * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false (default value). 687 */ 688 @Test testRadioStatsAggregationDisabled_1_5()689 public void testRadioStatsAggregationDisabled_1_5() throws Exception { 690 Random r = new Random(245786856); 691 android.hardware.wifi.V1_5.StaLinkLayerStats stats = 692 new android.hardware.wifi.V1_5.StaLinkLayerStats(); 693 // Fill stats in two radios 694 for (int i = 0; i < 2; i++) { 695 android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat = 696 new android.hardware.wifi.V1_5.StaLinkLayerRadioStats(); 697 randomizeRadioStats_1_5(r, rstat); 698 stats.radios.add(rstat); 699 } 700 701 WifiLinkLayerStats converted = mDut.frameworkFromHalLinkLayerStats_1_5(stats); 702 verifyPerRadioStats(stats.radios, converted); 703 verifyRadioStats_1_5(stats.radios.get(0), converted); 704 assertEquals(1, converted.numRadios); 705 } 706 707 /** 708 * Tests the retrieval of tx packet fates. 709 */ 710 @Test testGetTxPktFates()711 public void testGetTxPktFates() throws Exception { 712 byte[] frameContentBytes = new byte[30]; 713 new Random().nextBytes(frameContentBytes); 714 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 715 fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED; 716 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 717 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 718 fateReport.frameInfo.frameContent.addAll( 719 NativeUtil.byteArrayToArrayList(frameContentBytes)); 720 721 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 722 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 723 cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport))); 724 } 725 }).when(mIWifiStaIfaceMock) 726 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 727 728 List<WifiNative.TxFateReport> retrievedFates = mDut.getDebugTxPacketFates(); 729 assertEquals(1, retrievedFates.size()); 730 WifiNative.TxFateReport retrievedFate = retrievedFates.get(0); 731 verify(mIWifiStaIfaceMock) 732 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 733 assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFate.mFate); 734 assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec); 735 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType); 736 assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes); 737 } 738 739 /** 740 * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the 741 * maximum number of packet fates fetched ({@link WifiLoggerHal#MAX_FATE_LOG_LEN}). 742 */ 743 @Test testGetTxPktFatesExceedsInputArrayLength()744 public void testGetTxPktFatesExceedsInputArrayLength() throws Exception { 745 byte[] frameContentBytes = new byte[30]; 746 new Random().nextBytes(frameContentBytes); 747 WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport(); 748 fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER; 749 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 750 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 751 fateReport.frameInfo.frameContent.addAll( 752 NativeUtil.byteArrayToArrayList(frameContentBytes)); 753 754 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 755 public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) { 756 cb.onValues(mWifiStatusSuccess, new ArrayList<>( 757 // create twice as many as the max size 758 Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport))); 759 } 760 }).when(mIWifiStaIfaceMock) 761 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 762 763 List<WifiNative.TxFateReport> retrievedFates = mDut.getDebugTxPacketFates(); 764 // assert that at most WifiLoggerHal.MAX_FATE_LOG_LEN is retrieved 765 assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size()); 766 WifiNative.TxFateReport retrievedFate = retrievedFates.get(0); 767 verify(mIWifiStaIfaceMock) 768 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class)); 769 assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFate.mFate); 770 assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec); 771 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType); 772 assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes); 773 } 774 775 /** 776 * Tests the retrieval of rx packet fates. 777 */ 778 @Test testGetRxPktFates()779 public void testGetRxPktFates() throws Exception { 780 byte[] frameContentBytes = new byte[30]; 781 new Random().nextBytes(frameContentBytes); 782 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 783 fateReport.fate = WifiDebugRxPacketFate.SUCCESS; 784 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 785 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II; 786 fateReport.frameInfo.frameContent.addAll( 787 NativeUtil.byteArrayToArrayList(frameContentBytes)); 788 789 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 790 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 791 cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport))); 792 } 793 }).when(mIWifiStaIfaceMock) 794 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 795 796 List<WifiNative.RxFateReport> retrievedFates = mDut.getDebugRxPacketFates(); 797 assertEquals(1, retrievedFates.size()); 798 WifiNative.RxFateReport retrievedFate = retrievedFates.get(0); 799 verify(mIWifiStaIfaceMock) 800 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 801 assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFate.mFate); 802 assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec); 803 assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType); 804 assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes); 805 } 806 807 /** 808 * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the 809 * maximum number of packet fates fetched ({@link WifiLoggerHal#MAX_FATE_LOG_LEN}). 810 */ 811 @Test testGetRxPktFatesExceedsInputArrayLength()812 public void testGetRxPktFatesExceedsInputArrayLength() throws Exception { 813 byte[] frameContentBytes = new byte[30]; 814 new Random().nextBytes(frameContentBytes); 815 WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport(); 816 fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER; 817 fateReport.frameInfo.driverTimestampUsec = new Random().nextLong(); 818 fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211; 819 fateReport.frameInfo.frameContent.addAll( 820 NativeUtil.byteArrayToArrayList(frameContentBytes)); 821 822 doAnswer(new MockAnswerUtil.AnswerWithArguments() { 823 public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) { 824 cb.onValues(mWifiStatusSuccess, new ArrayList<>( 825 // create twice as many as the max size 826 Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport))); 827 } 828 }).when(mIWifiStaIfaceMock) 829 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 830 831 List<WifiNative.RxFateReport> retrievedFates = mDut.getDebugRxPacketFates(); 832 assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size()); 833 verify(mIWifiStaIfaceMock) 834 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class)); 835 WifiNative.RxFateReport retrievedFate = retrievedFates.get(0); 836 assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFate.mFate); 837 assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec); 838 assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType); 839 assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes); 840 } 841 842 /** 843 * Helper class for mocking the getRoamingCapabilities callback. 844 */ 845 private class GetRoamingCapabilitiesAnswer extends MockAnswerUtil.AnswerWithArguments { 846 private final WifiStatus mStatus; 847 private final StaRoamingCapabilities mCaps; 848 GetRoamingCapabilitiesAnswer(WifiStatus status, StaRoamingCapabilities caps)849 GetRoamingCapabilitiesAnswer(WifiStatus status, StaRoamingCapabilities caps) { 850 mStatus = status; 851 mCaps = caps; 852 } 853 answer(IWifiStaIface.getRoamingCapabilitiesCallback cb)854 public void answer(IWifiStaIface.getRoamingCapabilitiesCallback cb) { 855 cb.onValues(mStatus, mCaps); 856 } 857 } 858 859 /** 860 * Tests the retrieval of firmware roaming capabilities. 861 */ 862 @Test testFirmwareRoamingCapabilityRetrieval()863 public void testFirmwareRoamingCapabilityRetrieval() throws Exception { 864 for (int i = 0; i < 4; i++) { 865 int blocklistSize = i + 10; 866 int allowlistSize = i * 3; 867 StaRoamingCapabilities caps = new StaRoamingCapabilities(); 868 caps.maxBlacklistSize = blocklistSize; 869 caps.maxWhitelistSize = allowlistSize; 870 doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusSuccess, caps)) 871 .when(mIWifiStaIfaceMock).getRoamingCapabilities( 872 any(IWifiStaIface.getRoamingCapabilitiesCallback.class)); 873 WifiNative.RoamingCapabilities roamCap = mDut.getRoamingCapabilities(); 874 assertNotNull(roamCap); 875 assertEquals(blocklistSize, roamCap.maxBlocklistSize); 876 assertEquals(allowlistSize, roamCap.maxAllowlistSize); 877 } 878 } 879 880 /** 881 * Tests the unsuccessful retrieval of firmware roaming capabilities. 882 */ 883 @Test testUnsuccessfulFirmwareRoamingCapabilityRetrieval()884 public void testUnsuccessfulFirmwareRoamingCapabilityRetrieval() throws Exception { 885 StaRoamingCapabilities caps = new StaRoamingCapabilities(); 886 caps.maxBlacklistSize = 43; 887 caps.maxWhitelistSize = 18; 888 889 // HAL returns a failure status 890 doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, null)) 891 .when(mIWifiStaIfaceMock).getRoamingCapabilities( 892 any(IWifiStaIface.getRoamingCapabilitiesCallback.class)); 893 assertNull(mDut.getRoamingCapabilities()); 894 895 // HAL returns failure status, but supplies caps anyway 896 doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, caps)) 897 .when(mIWifiStaIfaceMock).getRoamingCapabilities( 898 any(IWifiStaIface.getRoamingCapabilitiesCallback.class)); 899 assertNull(mDut.getRoamingCapabilities()); 900 901 // lost connection 902 doThrow(new RemoteException()) 903 .when(mIWifiStaIfaceMock).getRoamingCapabilities( 904 any(IWifiStaIface.getRoamingCapabilitiesCallback.class)); 905 assertNull(mDut.getRoamingCapabilities()); 906 } 907 908 /** 909 * Tests enableFirmwareRoaming failure case due to an invalid argument. 910 */ 911 @Test testEnableFirmwareRoamingFailureInvalidArgument()912 public void testEnableFirmwareRoamingFailureInvalidArgument() throws Exception { 913 final int badState = WifiNative.DISABLE_FIRMWARE_ROAMING 914 + WifiNative.ENABLE_FIRMWARE_ROAMING + 1; 915 assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE, mDut.setRoamingState(badState)); 916 } 917 918 /** 919 * Tests that setRoamingState can handle a remote exception. 920 */ 921 @Test testEnableFirmwareRoamingException()922 public void testEnableFirmwareRoamingException() throws Exception { 923 doThrow(new RemoteException()).when(mIWifiStaIfaceMock).setRoamingState(anyByte()); 924 assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE, 925 mDut.setRoamingState(WifiNative.ENABLE_FIRMWARE_ROAMING)); 926 } 927 928 /** 929 * Verifies setMacAddress() success. 930 */ 931 @Test testSetMacAddressSuccess()932 public void testSetMacAddressSuccess() throws Exception { 933 // Expose the 1.2 IWifiStaIface. 934 mDut = new WifiStaIfaceHidlImplSpy(2); 935 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 936 when(mIWifiStaIfaceMockV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess); 937 938 assertTrue(mDut.setMacAddress(TEST_MAC_ADDRESS)); 939 verify(mIWifiStaIfaceMockV12).setMacAddress(macByteArray); 940 } 941 942 /** 943 * Verifies that setMacAddress() can handle a failure status. 944 */ 945 @Test testSetMacAddressFailDueToStatusFailure()946 public void testSetMacAddressFailDueToStatusFailure() throws Exception { 947 // Expose the 1.2 IWifiStaIface. 948 mDut = new WifiStaIfaceHidlImplSpy(2); 949 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 950 when(mIWifiStaIfaceMockV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure); 951 952 assertFalse(mDut.setMacAddress(TEST_MAC_ADDRESS)); 953 verify(mIWifiStaIfaceMockV12).setMacAddress(macByteArray); 954 } 955 956 /** 957 * Verifies that setMacAddress() can handle a RemoteException. 958 */ 959 @Test testSetMacAddressFailDueToRemoteException()960 public void testSetMacAddressFailDueToRemoteException() throws Exception { 961 // Expose the 1.2 IWifiStaIface. 962 mDut = new WifiStaIfaceHidlImplSpy(2); 963 byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray(); 964 doThrow(new RemoteException()).when(mIWifiStaIfaceMockV12).setMacAddress(macByteArray); 965 966 assertFalse(mDut.setMacAddress(TEST_MAC_ADDRESS)); 967 verify(mIWifiStaIfaceMockV12).setMacAddress(macByteArray); 968 } 969 } 970