1 /* 2 * Copyright (C) 2015 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 com.android.server.wifi.scanner.WifiScanningServiceImpl.getVendorIesBytesFromVendorIesList; 20 21 import static org.junit.Assert.*; 22 import static org.junit.Assume.*; 23 import static org.mockito.Mockito.*; 24 25 import android.net.wifi.ScanResult; 26 import android.net.wifi.WifiScanner; 27 import android.net.wifi.WifiScanner.ScanData; 28 import android.net.wifi.WifiSsid; 29 30 import com.android.modules.utils.build.SdkLevel; 31 import com.android.net.module.util.MacAddressUtils; 32 import com.android.server.wifi.scanner.ChannelHelper; 33 import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; 34 35 import org.hamcrest.Description; 36 import org.hamcrest.Matcher; 37 import org.hamcrest.TypeSafeDiagnosingMatcher; 38 39 import java.util.Arrays; 40 import java.util.Comparator; 41 import java.util.HashSet; 42 import java.util.List; 43 import java.util.Set; 44 45 /** 46 * Utilities for testing Wifi Scanning 47 */ 48 public class ScanTestUtil { 49 setupMockChannels(WifiNative wifiNative, int[] channels24, int[] channels5, int[] channelsDfs, int[] channels6, int[] channels60)50 public static void setupMockChannels(WifiNative wifiNative, int[] channels24, int[] channels5, 51 int[] channelsDfs, int[] channels6, int[] channels60) throws Exception { 52 when(wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ)) 53 .thenReturn(channels24); 54 when(wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)) 55 .thenReturn(channels5); 56 when(wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY)) 57 .thenReturn(channelsDfs); 58 when(wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ)) 59 .thenReturn(channels6); 60 when(wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ)) 61 .thenReturn(channels60); 62 } 63 createRequest(WifiScanner.ChannelSpec[] channels, int period, int batch, int bssidsPerScan, int reportEvents)64 public static WifiScanner.ScanSettings createRequest(WifiScanner.ChannelSpec[] channels, 65 int period, int batch, int bssidsPerScan, int reportEvents) { 66 WifiScanner.ScanSettings request = new WifiScanner.ScanSettings(); 67 request.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 68 request.channels = channels; 69 request.periodInMs = period; 70 request.numBssidsPerScan = bssidsPerScan; 71 request.maxScansToCache = batch; 72 request.reportEvents = reportEvents; 73 return request; 74 } 75 createRequest(int type, int band, int period, int batch, int bssidsPerScan, int reportEvents)76 public static WifiScanner.ScanSettings createRequest(int type, int band, int period, int batch, 77 int bssidsPerScan, int reportEvents) { 78 return createRequest(WifiScanner.SCAN_TYPE_HIGH_ACCURACY, band, period, 0, 0, 79 batch, bssidsPerScan, reportEvents); 80 } 81 createRequest(int band, int period, int batch, int bssidsPerScan, int reportEvents)82 public static WifiScanner.ScanSettings createRequest(int band, int period, int batch, 83 int bssidsPerScan, int reportEvents) { 84 return createRequest(WifiScanner.SCAN_TYPE_HIGH_ACCURACY, band, period, 0, 0, batch, 85 bssidsPerScan, reportEvents); 86 } 87 88 /** 89 * Create an exponential back off scan request if maxPeriod != period && maxPeriod != 0. 90 */ createRequest(int type, int band, int period, int maxPeriod, int stepCount, int batch, int bssidsPerScan, int reportEvents)91 public static WifiScanner.ScanSettings createRequest(int type, int band, int period, 92 int maxPeriod, int stepCount, int batch, int bssidsPerScan, int reportEvents) { 93 WifiScanner.ScanSettings request = new WifiScanner.ScanSettings(); 94 request.type = type; 95 request.band = band; 96 request.channels = null; 97 request.periodInMs = period; 98 request.maxPeriodInMs = maxPeriod; 99 request.stepCount = stepCount; 100 request.numBssidsPerScan = bssidsPerScan; 101 request.maxScansToCache = batch; 102 request.reportEvents = reportEvents; 103 return request; 104 } 105 106 /** 107 * Builder to create WifiNative.ScanSettings objects for testing 108 */ 109 public static class NativeScanSettingsBuilder { 110 private final WifiNative.ScanSettings mSettings = new WifiNative.ScanSettings(); NativeScanSettingsBuilder()111 public NativeScanSettingsBuilder() { 112 mSettings.scanType = WifiScanner.SCAN_TYPE_LOW_LATENCY; 113 mSettings.buckets = new WifiNative.BucketSettings[0]; 114 mSettings.num_buckets = 0; 115 mSettings.report_threshold_percent = 100; 116 } 117 withType(int type)118 public NativeScanSettingsBuilder withType(int type) { 119 mSettings.scanType = type; 120 return this; 121 } withBasePeriod(int basePeriod)122 public NativeScanSettingsBuilder withBasePeriod(int basePeriod) { 123 mSettings.base_period_ms = basePeriod; 124 return this; 125 } withMaxApPerScan(int maxAp)126 public NativeScanSettingsBuilder withMaxApPerScan(int maxAp) { 127 mSettings.max_ap_per_scan = maxAp; 128 return this; 129 } withMaxScansToCache(int maxScans)130 public NativeScanSettingsBuilder withMaxScansToCache(int maxScans) { 131 mSettings.report_threshold_num_scans = maxScans; 132 return this; 133 } withMaxPercentToCache(int percent)134 public NativeScanSettingsBuilder withMaxPercentToCache(int percent) { 135 mSettings.report_threshold_percent = percent; 136 return this; 137 } withEnable6GhzRnr(boolean enable)138 public NativeScanSettingsBuilder withEnable6GhzRnr(boolean enable) { 139 mSettings.enable6GhzRnr = enable; 140 return this; 141 } withVendorIes(byte[] vendorIes)142 public NativeScanSettingsBuilder withVendorIes(byte[] vendorIes) { 143 if (vendorIes == null) { 144 mSettings.vendorIes = null; 145 } else { 146 mSettings.vendorIes = Arrays.copyOf(vendorIes, vendorIes.length); 147 } 148 return this; 149 } 150 151 /** 152 * Add the provided hidden network SSIDs to scan request. 153 * @param networkSSIDs List of hidden network SSIDs 154 * @return builder object 155 */ withHiddenNetworkSSIDs(String[] networkSSIDs)156 public NativeScanSettingsBuilder withHiddenNetworkSSIDs(String[] networkSSIDs) { 157 mSettings.hiddenNetworks = new WifiNative.HiddenNetwork[networkSSIDs.length]; 158 for (int i = 0; i < networkSSIDs.length; i++) { 159 mSettings.hiddenNetworks[i] = new WifiNative.HiddenNetwork(); 160 mSettings.hiddenNetworks[i].ssid = networkSSIDs[i]; 161 } 162 return this; 163 } 164 addBucketWithChannelCollection( int period, int reportEvents, ChannelCollection channelCollection)165 public NativeScanSettingsBuilder addBucketWithChannelCollection( 166 int period, int reportEvents, ChannelCollection channelCollection) { 167 WifiNative.BucketSettings bucket = new WifiNative.BucketSettings(); 168 bucket.bucket = mSettings.num_buckets; 169 bucket.period_ms = period; 170 bucket.report_events = reportEvents; 171 channelCollection.fillBucketSettings(bucket, Integer.MAX_VALUE); 172 return addBucket(bucket); 173 } 174 addBucketWithBand( int period, int reportEvents, int band)175 public NativeScanSettingsBuilder addBucketWithBand( 176 int period, int reportEvents, int band) { 177 WifiNative.BucketSettings bucket = new WifiNative.BucketSettings(); 178 bucket.bucket = mSettings.num_buckets; 179 bucket.band = band; 180 bucket.period_ms = period; 181 bucket.report_events = reportEvents; 182 return addBucket(bucket); 183 } 184 addBucketWithChannels( int period, int reportEvents, WifiScanner.ChannelSpec... channels)185 public NativeScanSettingsBuilder addBucketWithChannels( 186 int period, int reportEvents, WifiScanner.ChannelSpec... channels) { 187 int[] channelFreqs = new int[channels.length]; 188 for (int i = 0; i < channels.length; ++i) { 189 channelFreqs[i] = channels[i].frequency; 190 } 191 return addBucketWithChannels(period, reportEvents, channelFreqs); 192 } 193 addBucketWithChannels( int period, int reportEvents, int... channels)194 public NativeScanSettingsBuilder addBucketWithChannels( 195 int period, int reportEvents, int... channels) { 196 WifiNative.BucketSettings bucket = new WifiNative.BucketSettings(); 197 bucket.bucket = mSettings.num_buckets; 198 bucket.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 199 bucket.num_channels = channels.length; 200 bucket.channels = channelsToNativeSettings(channels); 201 bucket.period_ms = period; 202 bucket.report_events = reportEvents; 203 return addBucket(bucket); 204 } 205 addBucket(WifiNative.BucketSettings bucket)206 public NativeScanSettingsBuilder addBucket(WifiNative.BucketSettings bucket) { 207 mSettings.buckets = Arrays.copyOf(mSettings.buckets, mSettings.num_buckets + 1); 208 mSettings.buckets[mSettings.num_buckets] = bucket; 209 mSettings.num_buckets = mSettings.num_buckets + 1; 210 return this; 211 } 212 build()213 public WifiNative.ScanSettings build() { 214 return mSettings; 215 } 216 217 } 218 219 /** 220 * Compute the expected native scan settings that are expected for the given 221 * WifiScanner.ScanSettings using the given ChannelHelper. 222 * This method is created to test 6Ghz PSC scanning. 223 */ computeSingleScanNativeSettingsWithChannelHelper( WifiScanner.ScanSettings requestSettings, ChannelHelper channelHelper)224 public static WifiNative.ScanSettings computeSingleScanNativeSettingsWithChannelHelper( 225 WifiScanner.ScanSettings requestSettings, ChannelHelper channelHelper) { 226 int reportEvents = requestSettings.reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 227 NativeScanSettingsBuilder builder = new NativeScanSettingsBuilder() 228 .withBasePeriod(0) 229 .withMaxApPerScan(0) 230 .withMaxPercentToCache(0) 231 .withMaxScansToCache(0) 232 .withType(requestSettings.type); 233 if (SdkLevel.isAtLeastS()) { 234 builder.withEnable6GhzRnr(requestSettings.getRnrSetting() 235 == WifiScanner.WIFI_RNR_ENABLED 236 || (requestSettings.getRnrSetting() 237 == WifiScanner.WIFI_RNR_ENABLED_IF_WIFI_BAND_6_GHZ_SCANNED 238 && ChannelHelper.is6GhzBandIncluded(requestSettings.band))); 239 } 240 ChannelCollection channelCollection = channelHelper.createChannelCollection(); 241 channelCollection.addChannels(requestSettings); 242 builder.addBucketWithChannelCollection(0, reportEvents, channelCollection); 243 return builder.build(); 244 } 245 246 /** 247 * Compute the expected native scan settings that are expected for the given 248 * WifiScanner.ScanSettings. 249 */ computeSingleScanNativeSettings( WifiScanner.ScanSettings requestSettings)250 public static WifiNative.ScanSettings computeSingleScanNativeSettings( 251 WifiScanner.ScanSettings requestSettings) { 252 int reportEvents = requestSettings.reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 253 NativeScanSettingsBuilder builder = new NativeScanSettingsBuilder() 254 .withBasePeriod(0) 255 .withMaxApPerScan(0) 256 .withMaxPercentToCache(0) 257 .withMaxScansToCache(0) 258 .withType(requestSettings.type); 259 if (SdkLevel.isAtLeastS()) { 260 builder.withEnable6GhzRnr(requestSettings.getRnrSetting() 261 == WifiScanner.WIFI_RNR_ENABLED 262 || (requestSettings.getRnrSetting() 263 == WifiScanner.WIFI_RNR_ENABLED_IF_WIFI_BAND_6_GHZ_SCANNED 264 && ChannelHelper.is6GhzBandIncluded(requestSettings.band))); 265 } 266 if (requestSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 267 builder.addBucketWithChannels(0, reportEvents, requestSettings.channels); 268 } else { 269 builder.addBucketWithBand(0, reportEvents, requestSettings.band); 270 } 271 if (SdkLevel.isAtLeastU()) { 272 List<ScanResult.InformationElement> vendorIesList = requestSettings.getVendorIes(); 273 byte[] nativeSettingsVendorIes = getVendorIesBytesFromVendorIesList(vendorIesList); 274 builder.withVendorIes(nativeSettingsVendorIes); 275 } 276 277 return builder.build(); 278 } 279 280 /** 281 * Compute the expected native scan settings that are expected for the given channels. 282 */ createSingleScanNativeSettingsForChannels( int reportEvents, WifiScanner.ChannelSpec... channels)283 public static WifiNative.ScanSettings createSingleScanNativeSettingsForChannels( 284 int reportEvents, WifiScanner.ChannelSpec... channels) { 285 return createSingleScanNativeSettingsForChannels( 286 WifiScanner.SCAN_TYPE_LOW_LATENCY, reportEvents, channels); 287 } 288 289 /** 290 * Compute the expected native scan settings that are expected for the given channels & type. 291 */ createSingleScanNativeSettingsForChannels( int nativeScanType, int reportEvents, WifiScanner.ChannelSpec... channels)292 public static WifiNative.ScanSettings createSingleScanNativeSettingsForChannels( 293 int nativeScanType, int reportEvents, WifiScanner.ChannelSpec... channels) { 294 int actualReportEvents = reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 295 return new NativeScanSettingsBuilder() 296 .withBasePeriod(0) 297 .withMaxApPerScan(0) 298 .withMaxPercentToCache(0) 299 .withMaxScansToCache(0) 300 .addBucketWithChannels(0, actualReportEvents, channels) 301 .withType(nativeScanType) 302 .build(); 303 } 304 createFreqSet(int... elements)305 public static Set<Integer> createFreqSet(int... elements) { 306 Set<Integer> set = new HashSet<>(); 307 for (int e : elements) { 308 set.add(e); 309 } 310 return set; 311 } 312 createScanResult(int freq)313 public static ScanResult createScanResult(int freq) { 314 return new ScanResult(WifiSsid.fromUtf8Text("AN SSID"), 315 MacAddressUtils.createRandomUnicastAddress().toString(), 0L, 316 -1, null, "", 0, freq, 0); 317 } 318 createScanData(int[] freqs, int bucketsScanned, int bandScanned)319 private static ScanData createScanData(int[] freqs, int bucketsScanned, int bandScanned) { 320 ScanResult[] results = new ScanResult[freqs.length]; 321 for (int i = 0; i < freqs.length; ++i) { 322 results[i] = createScanResult(freqs[i]); 323 } 324 return new ScanData(0, 0, bucketsScanned, bandScanned, results); 325 } 326 createScanData(int[] freqs, int bucketsScanned)327 private static ScanData createScanData(int[] freqs, int bucketsScanned) { 328 return createScanData(freqs, bucketsScanned, WifiScanner.WIFI_BAND_UNSPECIFIED); 329 } 330 createScanDatas( int[][] freqs, int[] bucketsScanned, int[] bandsScanned)331 public static ScanData[] createScanDatas( 332 int[][] freqs, int[] bucketsScanned, int[] bandsScanned) { 333 assumeTrue(freqs.length == bucketsScanned.length); 334 assumeTrue(freqs.length == bandsScanned.length); 335 ScanData[] data = new ScanData[freqs.length]; 336 for (int i = 0; i < freqs.length; ++i) { 337 data[i] = createScanData(freqs[i], bucketsScanned[i], bandsScanned[i]); 338 } 339 return data; 340 } 341 createScanDatas(int[][] freqs, int[] bucketsScanned)342 public static ScanData[] createScanDatas(int[][] freqs, int[] bucketsScanned) { 343 assumeTrue(freqs.length == bucketsScanned.length); 344 ScanData[] data = new ScanData[freqs.length]; 345 for (int i = 0; i < freqs.length; ++i) { 346 data[i] = createScanData(freqs[i], bucketsScanned[i]); 347 } 348 return data; 349 } 350 createScanDatas(int[][] freqs)351 public static ScanData[] createScanDatas(int[][] freqs) { 352 return createScanDatas(freqs, new int[freqs.length] /* defaults all 0 */); 353 } 354 assertScanResultEquals( String prefix, ScanResult expected, ScanResult actual)355 private static void assertScanResultEquals( 356 String prefix, ScanResult expected, ScanResult actual) { 357 assertEquals(prefix + "SSID", expected.SSID, actual.SSID); 358 assertEquals(prefix + "wifiSsid", expected.wifiSsid.toString(), actual.wifiSsid.toString()); 359 assertEquals(prefix + "BSSID", expected.BSSID, actual.BSSID); 360 assertEquals(prefix + "capabilities", expected.capabilities, actual.capabilities); 361 assertEquals(prefix + "level", expected.level, actual.level); 362 assertEquals(prefix + "frequency", expected.frequency, actual.frequency); 363 assertEquals(prefix + "timestamp", expected.timestamp, actual.timestamp); 364 assertEquals(prefix + "seen", expected.seen, actual.seen); 365 } 366 assertScanResultsEquals(String prefix, ScanResult[] expected, ScanResult[] actual)367 private static void assertScanResultsEquals(String prefix, ScanResult[] expected, 368 ScanResult[] actual) { 369 assertNotNull(prefix + "expected ScanResults was null", expected); 370 assertNotNull(prefix + "actual ScanResults was null", actual); 371 assertEquals(prefix + "results.length", expected.length, actual.length); 372 for (int j = 0; j < expected.length; ++j) { 373 ScanResult expectedResult = expected[j]; 374 ScanResult actualResult = actual[j]; 375 assertScanResultEquals(prefix + "results[" + j + "]", actualResult, expectedResult); 376 } 377 } 378 assertScanResultsEqualsAnyOrder(String prefix, ScanResult[] expected, ScanResult[] actual)379 private static void assertScanResultsEqualsAnyOrder(String prefix, ScanResult[] expected, 380 ScanResult[] actual) { 381 assertNotNull(prefix + "expected ScanResults was null", expected); 382 assertNotNull(prefix + "actual ScanResults was null", actual); 383 assertEquals(prefix + "results.length", expected.length, actual.length); 384 385 // Sort using the bssids. 386 ScanResult[] sortedExpected = Arrays 387 .stream(expected) 388 .sorted(Comparator.comparing(s -> s.BSSID)) 389 .toArray(ScanResult[]::new); 390 ScanResult[] sortedActual = Arrays 391 .stream(actual) 392 .sorted(Comparator.comparing(s -> s.BSSID)) 393 .toArray(ScanResult[]::new); 394 assertScanResultsEquals(prefix, sortedExpected, sortedActual); 395 } 396 397 /** 398 * Asserts if the provided scan results are the same. 399 */ assertScanResultEquals(ScanResult expected, ScanResult actual)400 public static void assertScanResultEquals(ScanResult expected, ScanResult actual) { 401 assertScanResultEquals("", expected, actual); 402 } 403 404 /** 405 * Asserts if the provided scan result arrays are the same. 406 */ assertScanResultsEquals(ScanResult[] expected, ScanResult[] actual)407 public static void assertScanResultsEquals(ScanResult[] expected, ScanResult[] actual) { 408 assertScanResultsEquals("", expected, actual); 409 } 410 411 /** 412 * Asserts if the provided scan result arrays are the same. 413 */ assertScanResultsEqualsAnyOrder(ScanResult[] expected, ScanResult[] actual)414 public static void assertScanResultsEqualsAnyOrder(ScanResult[] expected, ScanResult[] actual) { 415 assertScanResultsEqualsAnyOrder("", expected, actual); 416 } 417 assertScanDataEquals(String prefix, ScanData expected, ScanData actual)418 private static void assertScanDataEquals(String prefix, ScanData expected, ScanData actual) { 419 assertNotNull(prefix + "expected ScanData was null", expected); 420 assertNotNull(prefix + "actual ScanData was null", actual); 421 assertEquals(prefix + "id", expected.getId(), actual.getId()); 422 assertEquals(prefix + "flags", expected.getFlags(), actual.getFlags()); 423 assertEquals(prefix + "band", expected.getScannedBandsInternal(), 424 actual.getScannedBandsInternal()); 425 assertScanResultsEquals(prefix, expected.getResults(), actual.getResults()); 426 } 427 assertScanDataEquals(ScanData expected, ScanData actual)428 public static void assertScanDataEquals(ScanData expected, ScanData actual) { 429 assertScanDataEquals("", expected, actual); 430 } 431 assertScanDatasEquals(String prefix, ScanData[] expected, ScanData[] actual)432 public static void assertScanDatasEquals(String prefix, ScanData[] expected, ScanData[] actual) { 433 assertNotNull("expected " + prefix + "ScanData[] was null", expected); 434 assertNotNull("actaul " + prefix + "ScanData[] was null", actual); 435 assertEquals(prefix + "ScanData.length", expected.length, actual.length); 436 for (int i = 0; i < expected.length; ++i) { 437 assertScanDataEquals(prefix + "ScanData[" + i + "].", expected[i], actual[i]); 438 } 439 } 440 assertScanDatasEquals(ScanData[] expected, ScanData[] actual)441 public static void assertScanDatasEquals(ScanData[] expected, ScanData[] actual) { 442 assertScanDatasEquals("", expected, actual); 443 } 444 channelsToSpec(int... channels)445 public static WifiScanner.ChannelSpec[] channelsToSpec(int... channels) { 446 WifiScanner.ChannelSpec[] channelSpecs = new WifiScanner.ChannelSpec[channels.length]; 447 for (int i = 0; i < channels.length; ++i) { 448 channelSpecs[i] = new WifiScanner.ChannelSpec(channels[i]); 449 } 450 return channelSpecs; 451 } 452 assertNativeScanSettingsEquals(WifiNative.ScanSettings expected, WifiNative.ScanSettings actual)453 public static void assertNativeScanSettingsEquals(WifiNative.ScanSettings expected, 454 WifiNative.ScanSettings actual) { 455 assertEquals("scan type", expected.scanType, actual.scanType); 456 assertEquals("bssids per scan", expected.max_ap_per_scan, actual.max_ap_per_scan); 457 assertEquals("scans to cache", expected.report_threshold_num_scans, 458 actual.report_threshold_num_scans); 459 assertEquals("percent to cache", expected.report_threshold_percent, 460 actual.report_threshold_percent); 461 assertEquals("base period", expected.base_period_ms, actual.base_period_ms); 462 assertEquals("enable 6Ghz RNR", expected.enable6GhzRnr, actual.enable6GhzRnr); 463 assertArrayEquals("vendor IEs", expected.vendorIes, actual.vendorIes); 464 465 assertEquals("number of buckets", expected.num_buckets, actual.num_buckets); 466 assertNotNull("buckets was null", actual.buckets); 467 for (int i = 0; i < expected.buckets.length; ++i) { 468 assertNotNull("buckets[" + i + "] was null", actual.buckets[i]); 469 assertEquals("buckets[" + i + "].period", 470 expected.buckets[i].period_ms, actual.buckets[i].period_ms); 471 assertEquals("buckets[" + i + "].reportEvents", 472 expected.buckets[i].report_events, actual.buckets[i].report_events); 473 474 assertEquals("buckets[" + i + "].band", 475 expected.buckets[i].band, actual.buckets[i].band); 476 if (expected.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 477 Set<Integer> expectedChannels = new HashSet<>(); 478 for (WifiNative.ChannelSettings channel : expected.buckets[i].channels) { 479 expectedChannels.add(channel.frequency); 480 } 481 Set<Integer> actualChannels = new HashSet<>(); 482 for (WifiNative.ChannelSettings channel : actual.buckets[i].channels) { 483 actualChannels.add(channel.frequency); 484 } 485 assertEquals("channels", expectedChannels, actualChannels); 486 } else { 487 // since num_channels and channels are ignored when band is not 488 // WifiScanner.WIFI_BAND_UNSPECIFIED just assert that there are no channels 489 // the band equality was already checked above 490 assertEquals("buckets[" + i + "].num_channels not 0", 0, 491 actual.buckets[i].num_channels); 492 assertTrue("buckets[" + i + "].channels not null or empty", 493 actual.buckets[i].channels == null 494 || actual.buckets[i].channels.length == 0); 495 } 496 } 497 } 498 499 /** 500 * Asserts if the provided pno settings are the same. 501 */ assertNativePnoSettingsEquals(WifiNative.PnoSettings expected, WifiNative.PnoSettings actual)502 public static void assertNativePnoSettingsEquals(WifiNative.PnoSettings expected, 503 WifiNative.PnoSettings actual) { 504 assertNotNull("expected was null", expected); 505 assertNotNull("actaul was null", actual); 506 assertEquals("min5GHzRssi", expected.min5GHzRssi, actual.min5GHzRssi); 507 assertEquals("min24GHzRssi", expected.min24GHzRssi, actual.min24GHzRssi); 508 assertEquals("min6GHzRssi", expected.min6GHzRssi, actual.min6GHzRssi); 509 assertEquals("isConnected", expected.isConnected, actual.isConnected); 510 assertNotNull("expected networkList was null", expected.networkList); 511 assertNotNull("actual networkList was null", actual.networkList); 512 assertEquals("networkList.length", expected.networkList.length, actual.networkList.length); 513 for (int i = 0; i < expected.networkList.length; i++) { 514 assertEquals("networkList[" + i + "].ssid", 515 expected.networkList[i].ssid, actual.networkList[i].ssid); 516 assertEquals("networkList[" + i + "].flags", 517 expected.networkList[i].flags, actual.networkList[i].flags); 518 assertEquals("networkList[" + i + "].auth_bit_field", 519 expected.networkList[i].auth_bit_field, actual.networkList[i].auth_bit_field); 520 } 521 } 522 523 /** 524 * Convert a list of channel frequencies to an array of equivalent WifiNative.ChannelSettings 525 */ channelsToNativeSettings(int... channels)526 public static WifiNative.ChannelSettings[] channelsToNativeSettings(int... channels) { 527 WifiNative.ChannelSettings[] channelSpecs = new WifiNative.ChannelSettings[channels.length]; 528 for (int i = 0; i < channels.length; ++i) { 529 channelSpecs[i] = new WifiNative.ChannelSettings(); 530 channelSpecs[i].frequency = channels[i]; 531 } 532 return channelSpecs; 533 } 534 535 /** 536 * Matcher to check that a BucketSettings has the given band 537 */ bandIs(final int expectedBand)538 public static Matcher<WifiNative.BucketSettings> bandIs(final int expectedBand) { 539 return new TypeSafeDiagnosingMatcher<WifiNative.BucketSettings>() { 540 @Override 541 public boolean matchesSafely(WifiNative.BucketSettings bucketSettings, 542 Description mismatchDescription) { 543 if (bucketSettings.band != expectedBand) { 544 mismatchDescription 545 .appendText("did not have expected band ").appendValue(expectedBand) 546 .appendText(", was ").appendValue(bucketSettings.band); 547 return false; 548 } else { 549 return true; 550 } 551 } 552 553 @Override 554 public void describeTo(final Description description) { 555 description.appendText("bucket band is ").appendValue(expectedBand); 556 } 557 }; 558 } 559 560 /** 561 * Matcher to check that a BucketSettings has exactly the given channels 562 */ 563 public static Matcher<WifiNative.BucketSettings> channelsAre(final int... expectedChannels) { 564 return new TypeSafeDiagnosingMatcher<WifiNative.BucketSettings>() { 565 @Override 566 public boolean matchesSafely(WifiNative.BucketSettings bucketSettings, 567 Description mismatchDescription) { 568 if (bucketSettings.band != WifiScanner.WIFI_BAND_UNSPECIFIED) { 569 mismatchDescription.appendText("did not have expected unspecified band, was ") 570 .appendValue(bucketSettings.band); 571 return false; 572 } else if (bucketSettings.num_channels != expectedChannels.length) { 573 mismatchDescription 574 .appendText("did not have expected num_channels ") 575 .appendValue(expectedChannels.length) 576 .appendText(", was ").appendValue(bucketSettings.num_channels); 577 return false; 578 } else if (bucketSettings.channels == null) { 579 mismatchDescription.appendText("had null channels array"); 580 return false; 581 } else if (bucketSettings.channels.length != expectedChannels.length) { 582 mismatchDescription 583 .appendText("did not have channels array length matching excepted ") 584 .appendValue(expectedChannels.length) 585 .appendText(", was ").appendValue(bucketSettings.channels.length); 586 return false; 587 } else { 588 Set<Integer> foundChannelsSet = new HashSet<>(); 589 for (int i = 0; i < bucketSettings.channels.length; ++i) { 590 foundChannelsSet.add(bucketSettings.channels[i].frequency); 591 } 592 Set<Integer> expectedChannelsSet = new HashSet<>(); 593 for (int i = 0; i < expectedChannels.length; ++i) { 594 expectedChannelsSet.add(expectedChannels[i]); 595 } 596 597 if (!foundChannelsSet.containsAll(expectedChannelsSet) 598 || foundChannelsSet.size() != expectedChannelsSet.size()) { 599 Set<Integer> extraChannelsSet = new HashSet<>(foundChannelsSet); 600 extraChannelsSet.removeAll(expectedChannelsSet); 601 expectedChannelsSet.removeAll(foundChannelsSet); 602 mismatchDescription 603 .appendText("does not contain expected channels ") 604 .appendValue(expectedChannelsSet); 605 if (extraChannelsSet.size() > 0) { 606 mismatchDescription 607 .appendText(", but contains extra channels ") 608 .appendValue(extraChannelsSet); 609 } 610 return false; 611 } else { 612 return true; 613 } 614 } 615 } 616 617 @Override 618 public void describeTo(final Description description) { 619 description.appendText("bucket channels are ").appendValue(expectedChannels); 620 } 621 }; 622 } 623 } 624