From c4f23cbd6de85cbffcd91b398e51eff106ef08d4 Mon Sep 17 00:00:00 2001 From: Mitchell Wills Date: Fri, 25 Mar 2016 17:56:04 -0700 Subject: Use buckets scanned field when delivering scan results Fixes: 27506257 Change-Id: I224b78a89dfde54ef4f3dae37f1bb10d2a12b78e --- .../server/wifi/WifiScanningServiceImpl.java | 4 +- .../wifi/scanner/BackgroundScanScheduler.java | 82 +++++++++++++-------- .../server/wifi/scanner/ScanScheduleUtil.java | 85 +++++++++++++++++----- 3 files changed, 121 insertions(+), 50 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java index 0586c70f1..b8eda73cb 100644 --- a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java @@ -638,7 +638,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { int handler = entry.getKey().second; ScanSettings settings = entry.getValue(); if (ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, - result, settings)) { + result, bucketsScanned, settings, -1)) { ci.sendMessage(WifiScanner.CMD_FULL_SCAN_RESULT, 0, handler, result); } } @@ -659,7 +659,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { ScanSettings settings = entry.getValue(); ScanData[] resultsArray = new ScanData[] {results}; ScanData[] resultsToDeliver = ScanScheduleUtil.filterResultsForSettings( - mChannelHelper, resultsArray, settings); + mChannelHelper, resultsArray, settings, -1); WifiScanner.ParcelableScanData parcelableScanData = new WifiScanner.ParcelableScanData(resultsToDeliver); logCallback("singleScanResults", ci, handler); diff --git a/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java b/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java index 33e1914c9..949e7a0ad 100644 --- a/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java +++ b/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java @@ -32,8 +32,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; /** *

This class takes a series of scan requests and formulates the best hardware level scanning @@ -291,11 +293,12 @@ public class BackgroundScanScheduler { private final ChannelHelper mChannelHelper; private final ChannelCollection mChannelCollection; private WifiNative.ScanSettings mSchedule; + private final Map mSettingsToScheduledBucket = new HashMap<>(); public BackgroundScanScheduler(ChannelHelper channelHelper) { mChannelHelper = channelHelper; mChannelCollection = mChannelHelper.createChannelCollection(); - mSchedule = createSchedule(Collections.emptyList()); + createSchedule(); } /** @@ -310,7 +313,7 @@ public class BackgroundScanScheduler { compactBuckets(getMaxBuckets()); - mSchedule = createSchedule(requests); + createSchedule(); } /** @@ -327,7 +330,7 @@ public class BackgroundScanScheduler { public boolean shouldReportFullScanResultForSettings(@NonNull ScanResult result, int bucketsScanned, @NonNull ScanSettings settings) { return ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper, - result, settings); + result, bucketsScanned, settings, getScheduledBucket(settings)); } /** @@ -336,48 +339,67 @@ public class BackgroundScanScheduler { */ public @Nullable ScanData[] filterResultsForSettings(@NonNull ScanData[] scanDatas, @NonNull ScanSettings settings) { - return ScanScheduleUtil.filterResultsForSettings(mChannelHelper, scanDatas, settings); + return ScanScheduleUtil.filterResultsForSettings(mChannelHelper, scanDatas, settings, + getScheduledBucket(settings)); } - // creates a schedule for the given buckets and requests - private WifiNative.ScanSettings createSchedule(Collection requests) { + private int getScheduledBucket(ScanSettings settings) { + Integer scheduledBucket = mSettingsToScheduledBucket.get(settings); + if (scheduledBucket != null) { + return scheduledBucket; + } else { + Slog.wtf(TAG, "No bucket found for settings"); + return -1; + } + } + + /** + * creates a schedule for the current buckets + */ + private void createSchedule() { + mSettingsToScheduledBucket.clear(); WifiNative.ScanSettings schedule = new WifiNative.ScanSettings(); schedule.num_buckets = mBuckets.getActiveCount(); schedule.buckets = new WifiNative.BucketSettings[mBuckets.getActiveCount()]; + schedule.max_ap_per_scan = 0; + schedule.report_threshold_num_scans = getMaxBatch(); + HashSet hiddenNetworkIdSet = new HashSet<>(); + // set all buckets in schedule int bucketId = 0; for (int i = 0; i < mBuckets.size(); ++i) { if (mBuckets.isActive(i)) { - schedule.buckets[bucketId++] = + schedule.buckets[bucketId] = mBuckets.get(i).createBucketSettings(bucketId, getMaxChannels()); + + for (ScanSettings settings : mBuckets.get(i).settings) { + mSettingsToScheduledBucket.put(settings, bucketId); + + // set APs per scan + if (settings.numBssidsPerScan > schedule.max_ap_per_scan) { + schedule.max_ap_per_scan = settings.numBssidsPerScan; + } + + // set batching + if (settings.maxScansToCache != 0 + && settings.maxScansToCache < schedule.report_threshold_num_scans) { + schedule.report_threshold_num_scans = settings.maxScansToCache; + } + + // note hidden networks + if (settings.hiddenNetworkIds != null) { + for (int j = 0; j < settings.hiddenNetworkIds.length; j++) { + hiddenNetworkIdSet.add(settings.hiddenNetworkIds[j]); + } + } + } + bucketId++; } } schedule.report_threshold_percent = DEFAULT_REPORT_THRESHOLD_PERCENTAGE; - // update batching settings - schedule.max_ap_per_scan = 0; - schedule.report_threshold_num_scans = getMaxBatch(); - HashSet hiddenNetworkIdSet = new HashSet<>(); - for (ScanSettings settings : requests) { - // set APs per scan - if (settings.numBssidsPerScan > schedule.max_ap_per_scan) { - schedule.max_ap_per_scan = settings.numBssidsPerScan; - } - - // set batching - if (settings.maxScansToCache != 0 - && settings.maxScansToCache < schedule.report_threshold_num_scans) { - schedule.report_threshold_num_scans = settings.maxScansToCache; - } - - if (settings.hiddenNetworkIds != null) { - for (int i = 0; i < settings.hiddenNetworkIds.length; i++) { - hiddenNetworkIdSet.add(settings.hiddenNetworkIds[i]); - } - } - } if (schedule.max_ap_per_scan == 0 || schedule.max_ap_per_scan > getMaxApPerScan()) { schedule.max_ap_per_scan = getMaxApPerScan(); } @@ -406,7 +428,7 @@ public class BackgroundScanScheduler { schedule.base_period_ms = DEFAULT_PERIOD_MS; } - return schedule; + mSchedule = schedule; } /** diff --git a/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java b/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java index aa0228ac6..01418b91c 100644 --- a/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java +++ b/service/java/com/android/server/wifi/scanner/ScanScheduleUtil.java @@ -90,42 +90,91 @@ public class ScanScheduleUtil { return true; } + /** + * Check if the specified bucket was scanned. If not all information is available then this + * method will return true. + * + * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if unavailable + * @param bucketsScannedBitSet The bitset of all buckets scanned, 0 if unavailable + */ + private static boolean isBucketMaybeScanned(int scheduledBucket, int bucketsScannedBitSet) { + if (bucketsScannedBitSet == 0 || scheduledBucket < 0) { + return true; + } else { + return (bucketsScannedBitSet & (1 << scheduledBucket)) != 0; + } + } + + /** + * Check if the specified bucket was scanned. If not all information is available then this + * method will return false. + * + * @param scheduledBucket Index of the bucket to check for, zero indexed, or -1 if unavailable + * @param bucketsScannedBitSet The bitset of all buckets scanned, 0 if unavailable + */ + private static boolean isBucketDefinitlyScanned(int scheduledBucket, int bucketsScannedBitSet) { + if (bucketsScannedBitSet == 0 || scheduledBucket < 0) { + return false; + } else { + return (bucketsScannedBitSet & (1 << scheduledBucket)) != 0; + } + } + /** * Returns true if the given scan result should be reported to a listener with the given * settings. */ public static boolean shouldReportFullScanResultForSettings(ChannelHelper channelHelper, - ScanResult result, ScanSettings settings) { - return channelHelper.settingsContainChannel(settings, result.frequency); + ScanResult result, int bucketsScanned, ScanSettings settings, int scheduledBucket) { + if (isBucketMaybeScanned(scheduledBucket, bucketsScanned)) { + return channelHelper.settingsContainChannel(settings, result.frequency); + } else { + return false; + } } /** * Returns a filtered version of the scan results from the chip that represents only the data * requested in the settings. Will return null if the result should not be reported. + * + * If a ScanData indicates that the bucket the settings were placed in was scanned then it + * will always be included (filtered to only include requested channels). If it indicates that + * the bucket was definitely not scanned then the scan data will not be reported. + * If it is not possible to determine if the settings bucket was scanned or not then a + * ScanData will be included if the scan was empty or there was at least one scan result that + * matches a requested channel (again the results will be filtered to only include requested + * channels. */ public static ScanData[] filterResultsForSettings(ChannelHelper channelHelper, - ScanData[] scanDatas, ScanSettings settings) { + ScanData[] scanDatas, ScanSettings settings, int scheduledBucket) { List filteredScanDatas = new ArrayList<>(scanDatas.length); List filteredResults = new ArrayList<>(); for (ScanData scanData : scanDatas) { - filteredResults.clear(); - for (ScanResult scanResult : scanData.getResults()) { - if (channelHelper.settingsContainChannel(settings, scanResult.frequency)) { - filteredResults.add(scanResult); + // only report ScanData if the settings bucket could have been scanned + if (isBucketMaybeScanned(scheduledBucket, scanData.getBucketsScanned())) { + filteredResults.clear(); + for (ScanResult scanResult : scanData.getResults()) { + if (channelHelper.settingsContainChannel(settings, scanResult.frequency)) { + filteredResults.add(scanResult); + } + if (settings.numBssidsPerScan > 0 + && filteredResults.size() >= settings.numBssidsPerScan) { + break; + } } - if (settings.numBssidsPerScan > 0 - && filteredResults.size() >= settings.numBssidsPerScan) { - break; + // will include scan results if the scan was empty, there was at least one + // one result that matched the scan request or we are sure that all the requested + // channels were scanned. + if (filteredResults.size() == scanData.getResults().length) { + filteredScanDatas.add(scanData); + } else if (filteredResults.size() > 0 || isBucketDefinitlyScanned(scheduledBucket, + scanData.getBucketsScanned())) { + filteredScanDatas.add(new ScanData(scanData.getId(), + scanData.getFlags(), + filteredResults.toArray( + new ScanResult[filteredResults.size()]))); } } - if (filteredResults.size() == scanData.getResults().length) { - filteredScanDatas.add(scanData); - } else if (filteredResults.size() > 0) { - filteredScanDatas.add(new ScanData(scanData.getId(), - scanData.getFlags(), - filteredResults.toArray( - new ScanResult[filteredResults.size()]))); - } } if (filteredScanDatas.size() == 0) { return null; -- cgit v1.2.3