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.Builder(WifiSsid.fromUtf8Text("AN SSID"), 315 MacAddressUtils.createRandomUnicastAddress().toString()) 316 .setCaps("") 317 .setFrequency(freq) 318 .build(); 319 } 320 createScanData(int[] freqs, int bucketsScanned, int bandScanned)321 private static ScanData createScanData(int[] freqs, int bucketsScanned, int bandScanned) { 322 ScanResult[] results = new ScanResult[freqs.length]; 323 for (int i = 0; i < freqs.length; ++i) { 324 results[i] = createScanResult(freqs[i]); 325 } 326 return new ScanData(0, 0, bucketsScanned, bandScanned, results); 327 } 328 createScanData(int[] freqs, int bucketsScanned)329 private static ScanData createScanData(int[] freqs, int bucketsScanned) { 330 return createScanData(freqs, bucketsScanned, WifiScanner.WIFI_BAND_UNSPECIFIED); 331 } 332 createScanDatas( int[][] freqs, int[] bucketsScanned, int[] bandsScanned)333 public static ScanData[] createScanDatas( 334 int[][] freqs, int[] bucketsScanned, int[] bandsScanned) { 335 assumeTrue(freqs.length == bucketsScanned.length); 336 assumeTrue(freqs.length == bandsScanned.length); 337 ScanData[] data = new ScanData[freqs.length]; 338 for (int i = 0; i < freqs.length; ++i) { 339 data[i] = createScanData(freqs[i], bucketsScanned[i], bandsScanned[i]); 340 } 341 return data; 342 } 343 createScanDatas(int[][] freqs, int[] bucketsScanned)344 public static ScanData[] createScanDatas(int[][] freqs, int[] bucketsScanned) { 345 assumeTrue(freqs.length == bucketsScanned.length); 346 ScanData[] data = new ScanData[freqs.length]; 347 for (int i = 0; i < freqs.length; ++i) { 348 data[i] = createScanData(freqs[i], bucketsScanned[i]); 349 } 350 return data; 351 } 352 createScanDatas(int[][] freqs)353 public static ScanData[] createScanDatas(int[][] freqs) { 354 return createScanDatas(freqs, new int[freqs.length] /* defaults all 0 */); 355 } 356 assertScanResultEquals( String prefix, ScanResult expected, ScanResult actual)357 private static void assertScanResultEquals( 358 String prefix, ScanResult expected, ScanResult actual) { 359 assertEquals(prefix + "SSID", expected.SSID, actual.SSID); 360 assertEquals(prefix + "wifiSsid", expected.wifiSsid.toString(), actual.wifiSsid.toString()); 361 assertEquals(prefix + "BSSID", expected.BSSID, actual.BSSID); 362 assertEquals(prefix + "capabilities", expected.capabilities, actual.capabilities); 363 assertEquals(prefix + "level", expected.level, actual.level); 364 assertEquals(prefix + "frequency", expected.frequency, actual.frequency); 365 assertEquals(prefix + "timestamp", expected.timestamp, actual.timestamp); 366 assertEquals(prefix + "seen", expected.seen, actual.seen); 367 } 368 assertScanResultsEquals(String prefix, ScanResult[] expected, ScanResult[] actual)369 private static void assertScanResultsEquals(String prefix, ScanResult[] expected, 370 ScanResult[] actual) { 371 assertNotNull(prefix + "expected ScanResults was null", expected); 372 assertNotNull(prefix + "actual ScanResults was null", actual); 373 assertEquals(prefix + "results.length", expected.length, actual.length); 374 for (int j = 0; j < expected.length; ++j) { 375 ScanResult expectedResult = expected[j]; 376 ScanResult actualResult = actual[j]; 377 assertScanResultEquals(prefix + "results[" + j + "]", actualResult, expectedResult); 378 } 379 } 380 assertScanResultsEqualsAnyOrder(String prefix, ScanResult[] expected, ScanResult[] actual)381 private static void assertScanResultsEqualsAnyOrder(String prefix, ScanResult[] expected, 382 ScanResult[] actual) { 383 assertNotNull(prefix + "expected ScanResults was null", expected); 384 assertNotNull(prefix + "actual ScanResults was null", actual); 385 assertEquals(prefix + "results.length", expected.length, actual.length); 386 387 // Sort using the bssids. 388 ScanResult[] sortedExpected = Arrays 389 .stream(expected) 390 .sorted(Comparator.comparing(s -> s.BSSID)) 391 .toArray(ScanResult[]::new); 392 ScanResult[] sortedActual = Arrays 393 .stream(actual) 394 .sorted(Comparator.comparing(s -> s.BSSID)) 395 .toArray(ScanResult[]::new); 396 assertScanResultsEquals(prefix, sortedExpected, sortedActual); 397 } 398 399 /** 400 * Asserts if the provided scan results are the same. 401 */ assertScanResultEquals(ScanResult expected, ScanResult actual)402 public static void assertScanResultEquals(ScanResult expected, ScanResult actual) { 403 assertScanResultEquals("", expected, actual); 404 } 405 406 /** 407 * Asserts if the provided scan result arrays are the same. 408 */ assertScanResultsEquals(ScanResult[] expected, ScanResult[] actual)409 public static void assertScanResultsEquals(ScanResult[] expected, ScanResult[] actual) { 410 assertScanResultsEquals("", expected, actual); 411 } 412 413 /** 414 * Asserts if the provided scan result arrays are the same. 415 */ assertScanResultsEqualsAnyOrder(ScanResult[] expected, ScanResult[] actual)416 public static void assertScanResultsEqualsAnyOrder(ScanResult[] expected, ScanResult[] actual) { 417 assertScanResultsEqualsAnyOrder("", expected, actual); 418 } 419 assertScanDataEquals(String prefix, ScanData expected, ScanData actual)420 private static void assertScanDataEquals(String prefix, ScanData expected, ScanData actual) { 421 assertNotNull(prefix + "expected ScanData was null", expected); 422 assertNotNull(prefix + "actual ScanData was null", actual); 423 assertEquals(prefix + "id", expected.getId(), actual.getId()); 424 assertEquals(prefix + "flags", expected.getFlags(), actual.getFlags()); 425 assertEquals(prefix + "band", expected.getScannedBandsInternal(), 426 actual.getScannedBandsInternal()); 427 assertScanResultsEquals(prefix, expected.getResults(), actual.getResults()); 428 } 429 assertScanDataEquals(ScanData expected, ScanData actual)430 public static void assertScanDataEquals(ScanData expected, ScanData actual) { 431 assertScanDataEquals("", expected, actual); 432 } 433 assertScanDatasEquals(String prefix, ScanData[] expected, ScanData[] actual)434 public static void assertScanDatasEquals(String prefix, ScanData[] expected, ScanData[] actual) { 435 assertNotNull("expected " + prefix + "ScanData[] was null", expected); 436 assertNotNull("actaul " + prefix + "ScanData[] was null", actual); 437 assertEquals(prefix + "ScanData.length", expected.length, actual.length); 438 for (int i = 0; i < expected.length; ++i) { 439 assertScanDataEquals(prefix + "ScanData[" + i + "].", expected[i], actual[i]); 440 } 441 } 442 assertScanDatasEquals(ScanData[] expected, ScanData[] actual)443 public static void assertScanDatasEquals(ScanData[] expected, ScanData[] actual) { 444 assertScanDatasEquals("", expected, actual); 445 } 446 channelsToSpec(int... channels)447 public static WifiScanner.ChannelSpec[] channelsToSpec(int... channels) { 448 WifiScanner.ChannelSpec[] channelSpecs = new WifiScanner.ChannelSpec[channels.length]; 449 for (int i = 0; i < channels.length; ++i) { 450 channelSpecs[i] = new WifiScanner.ChannelSpec(channels[i]); 451 } 452 return channelSpecs; 453 } 454 assertNativeScanSettingsEquals(WifiNative.ScanSettings expected, WifiNative.ScanSettings actual)455 public static void assertNativeScanSettingsEquals(WifiNative.ScanSettings expected, 456 WifiNative.ScanSettings actual) { 457 assertEquals("scan type", expected.scanType, actual.scanType); 458 assertEquals("bssids per scan", expected.max_ap_per_scan, actual.max_ap_per_scan); 459 assertEquals("scans to cache", expected.report_threshold_num_scans, 460 actual.report_threshold_num_scans); 461 assertEquals("percent to cache", expected.report_threshold_percent, 462 actual.report_threshold_percent); 463 assertEquals("base period", expected.base_period_ms, actual.base_period_ms); 464 assertEquals("enable 6Ghz RNR", expected.enable6GhzRnr, actual.enable6GhzRnr); 465 assertArrayEquals("vendor IEs", expected.vendorIes, actual.vendorIes); 466 467 assertEquals("number of buckets", expected.num_buckets, actual.num_buckets); 468 assertNotNull("buckets was null", actual.buckets); 469 for (int i = 0; i < expected.buckets.length; ++i) { 470 assertNotNull("buckets[" + i + "] was null", actual.buckets[i]); 471 assertEquals("buckets[" + i + "].period", 472 expected.buckets[i].period_ms, actual.buckets[i].period_ms); 473 assertEquals("buckets[" + i + "].reportEvents", 474 expected.buckets[i].report_events, actual.buckets[i].report_events); 475 476 assertEquals("buckets[" + i + "].band", 477 expected.buckets[i].band, actual.buckets[i].band); 478 if (expected.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 479 Set<Integer> expectedChannels = new HashSet<>(); 480 for (WifiNative.ChannelSettings channel : expected.buckets[i].channels) { 481 expectedChannels.add(channel.frequency); 482 } 483 Set<Integer> actualChannels = new HashSet<>(); 484 for (WifiNative.ChannelSettings channel : actual.buckets[i].channels) { 485 actualChannels.add(channel.frequency); 486 } 487 assertEquals("channels", expectedChannels, actualChannels); 488 } else { 489 // since num_channels and channels are ignored when band is not 490 // WifiScanner.WIFI_BAND_UNSPECIFIED just assert that there are no channels 491 // the band equality was already checked above 492 assertEquals("buckets[" + i + "].num_channels not 0", 0, 493 actual.buckets[i].num_channels); 494 assertTrue("buckets[" + i + "].channels not null or empty", 495 actual.buckets[i].channels == null 496 || actual.buckets[i].channels.length == 0); 497 } 498 } 499 } 500 501 /** 502 * Asserts if the provided pno settings are the same. 503 */ assertNativePnoSettingsEquals(WifiNative.PnoSettings expected, WifiNative.PnoSettings actual)504 public static void assertNativePnoSettingsEquals(WifiNative.PnoSettings expected, 505 WifiNative.PnoSettings actual) { 506 assertNotNull("expected was null", expected); 507 assertNotNull("actaul was null", actual); 508 assertEquals("min5GHzRssi", expected.min5GHzRssi, actual.min5GHzRssi); 509 assertEquals("min24GHzRssi", expected.min24GHzRssi, actual.min24GHzRssi); 510 assertEquals("min6GHzRssi", expected.min6GHzRssi, actual.min6GHzRssi); 511 assertEquals("isConnected", expected.isConnected, actual.isConnected); 512 assertNotNull("expected networkList was null", expected.networkList); 513 assertNotNull("actual networkList was null", actual.networkList); 514 assertEquals("networkList.length", expected.networkList.length, actual.networkList.length); 515 for (int i = 0; i < expected.networkList.length; i++) { 516 assertEquals("networkList[" + i + "].ssid", 517 expected.networkList[i].ssid, actual.networkList[i].ssid); 518 assertEquals("networkList[" + i + "].flags", 519 expected.networkList[i].flags, actual.networkList[i].flags); 520 assertEquals("networkList[" + i + "].auth_bit_field", 521 expected.networkList[i].auth_bit_field, actual.networkList[i].auth_bit_field); 522 } 523 } 524 525 /** 526 * Convert a list of channel frequencies to an array of equivalent WifiNative.ChannelSettings 527 */ channelsToNativeSettings(int... channels)528 public static WifiNative.ChannelSettings[] channelsToNativeSettings(int... channels) { 529 WifiNative.ChannelSettings[] channelSpecs = new WifiNative.ChannelSettings[channels.length]; 530 for (int i = 0; i < channels.length; ++i) { 531 channelSpecs[i] = new WifiNative.ChannelSettings(); 532 channelSpecs[i].frequency = channels[i]; 533 } 534 return channelSpecs; 535 } 536 537 /** 538 * Matcher to check that a BucketSettings has the given band 539 */ bandIs(final int expectedBand)540 public static Matcher<WifiNative.BucketSettings> bandIs(final int expectedBand) { 541 return new TypeSafeDiagnosingMatcher<WifiNative.BucketSettings>() { 542 @Override 543 public boolean matchesSafely(WifiNative.BucketSettings bucketSettings, 544 Description mismatchDescription) { 545 if (bucketSettings.band != expectedBand) { 546 mismatchDescription 547 .appendText("did not have expected band ").appendValue(expectedBand) 548 .appendText(", was ").appendValue(bucketSettings.band); 549 return false; 550 } else { 551 return true; 552 } 553 } 554 555 @Override 556 public void describeTo(final Description description) { 557 description.appendText("bucket band is ").appendValue(expectedBand); 558 } 559 }; 560 } 561 562 /** 563 * Matcher to check that a BucketSettings has exactly the given channels 564 */ 565 public static Matcher<WifiNative.BucketSettings> channelsAre(final int... expectedChannels) { 566 return new TypeSafeDiagnosingMatcher<WifiNative.BucketSettings>() { 567 @Override 568 public boolean matchesSafely(WifiNative.BucketSettings bucketSettings, 569 Description mismatchDescription) { 570 if (bucketSettings.band != WifiScanner.WIFI_BAND_UNSPECIFIED) { 571 mismatchDescription.appendText("did not have expected unspecified band, was ") 572 .appendValue(bucketSettings.band); 573 return false; 574 } else if (bucketSettings.num_channels != expectedChannels.length) { 575 mismatchDescription 576 .appendText("did not have expected num_channels ") 577 .appendValue(expectedChannels.length) 578 .appendText(", was ").appendValue(bucketSettings.num_channels); 579 return false; 580 } else if (bucketSettings.channels == null) { 581 mismatchDescription.appendText("had null channels array"); 582 return false; 583 } else if (bucketSettings.channels.length != expectedChannels.length) { 584 mismatchDescription 585 .appendText("did not have channels array length matching excepted ") 586 .appendValue(expectedChannels.length) 587 .appendText(", was ").appendValue(bucketSettings.channels.length); 588 return false; 589 } else { 590 Set<Integer> foundChannelsSet = new HashSet<>(); 591 for (int i = 0; i < bucketSettings.channels.length; ++i) { 592 foundChannelsSet.add(bucketSettings.channels[i].frequency); 593 } 594 Set<Integer> expectedChannelsSet = new HashSet<>(); 595 for (int i = 0; i < expectedChannels.length; ++i) { 596 expectedChannelsSet.add(expectedChannels[i]); 597 } 598 599 if (!foundChannelsSet.containsAll(expectedChannelsSet) 600 || foundChannelsSet.size() != expectedChannelsSet.size()) { 601 Set<Integer> extraChannelsSet = new HashSet<>(foundChannelsSet); 602 extraChannelsSet.removeAll(expectedChannelsSet); 603 expectedChannelsSet.removeAll(foundChannelsSet); 604 mismatchDescription 605 .appendText("does not contain expected channels ") 606 .appendValue(expectedChannelsSet); 607 if (extraChannelsSet.size() > 0) { 608 mismatchDescription 609 .appendText(", but contains extra channels ") 610 .appendValue(extraChannelsSet); 611 } 612 return false; 613 } else { 614 return true; 615 } 616 } 617 } 618 619 @Override 620 public void describeTo(final Description description) { 621 description.appendText("bucket channels are ").appendValue(expectedChannels); 622 } 623 }; 624 } 625 } 626