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