From 362fad8eddd674d7cf19ffcc1fec38d2d2ee2f53 Mon Sep 17 00:00:00 2001
From: Roshan Pius <rpius@google.com>
Date: Fri, 6 May 2016 10:13:36 -0700
Subject: SupplicantScanner: Truncate hidden network list

Truncate the hidden network id list if it goes beyond wpa_supplicant's
max value. wpa_supplicant has a hard coded value of 16 for the max
number of networks that can be specified for each scan.

There is currently no way to query this value from wpa_supplicant, so
hardcoding this value in SupplicantScanner.

BUG: 28632556
Change-Id: I31a338b91c221c1686437b738894e13abb897474
TEST: Compiles & unit-test passes
---
 .../wifi/scanner/SupplicantWifiScannerImpl.java    | 10 ++++++++--
 .../wifi/scanner/BaseWifiScannerImplTest.java      | 23 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java b/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
index c4e19f5a5..4b2d68fce 100644
--- a/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
@@ -51,6 +51,8 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle
 
     public static final String BACKGROUND_PERIOD_ALARM_TAG = TAG + " Background Scan Period";
     public static final String TIMEOUT_ALARM_TAG = TAG + " Scan Timeout";
+    // Max number of networks that can be specified to wpa_supplicant per scan request
+    public static final int MAX_HIDDEN_NETWORK_IDS_PER_SCAN = 16;
 
     private static final int SCAN_BUFFER_CAPACITY = 10;
     private static final int MAX_APS_PER_SCAN = 32;
@@ -383,7 +385,9 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle
 
                         int[] hiddenNetworkIds = mBackgroundScanSettings.hiddenNetworkIds;
                         if (hiddenNetworkIds != null) {
-                            for (int i = 0; i < hiddenNetworkIds.length; i++) {
+                            int numHiddenNetworkIds = Math.min(hiddenNetworkIds.length,
+                                    MAX_HIDDEN_NETWORK_IDS_PER_SCAN);
+                            for (int i = 0; i < numHiddenNetworkIds; i++) {
                                 hiddenNetworkIdSet.add(hiddenNetworkIds[i]);
                             }
                         }
@@ -414,7 +418,9 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle
                         mPendingSingleScanEventHandler);
                 int[] hiddenNetworkIds = mPendingSingleScanSettings.hiddenNetworkIds;
                 if (hiddenNetworkIds != null) {
-                    for (int i = 0; i < hiddenNetworkIds.length; i++) {
+                    int numHiddenNetworkIds = Math.min(hiddenNetworkIds.length,
+                            MAX_HIDDEN_NETWORK_IDS_PER_SCAN);
+                    for (int i = 0; i < numHiddenNetworkIds; i++) {
                         hiddenNetworkIdSet.add(hiddenNetworkIds[i]);
                     }
                 }
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
index 04684d932..15d1465f0 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
@@ -167,6 +167,29 @@ public abstract class BaseWifiScannerImplTest {
                 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
     }
 
+    /**
+     * Tests whether the provided hidden networkId's in scan settings is truncated to max size
+     * supported by wpa_supplicant when invoking native scan.
+     */
+    @Test
+    public void singleScanSuccessWithTruncatedHiddenNetworkIds() {
+        int[] hiddenNetworkIds = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+        WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
+                .withBasePeriod(10000)
+                .withMaxApPerScan(10)
+                .withHiddenNetworkIds(hiddenNetworkIds)
+                .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650)
+                .build();
+
+        Set<Integer> hiddenNetworkIdSet = new HashSet<Integer>();
+        for (int i = 0; i < SupplicantWifiScannerImpl.MAX_HIDDEN_NETWORK_IDS_PER_SCAN; i++) {
+            hiddenNetworkIdSet.add(hiddenNetworkIds[i]);
+        }
+        doSuccessfulSingleScanTest(settings, createFreqSet(5650),
+                hiddenNetworkIdSet,
+                ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
+    }
+
     @Test
     public void overlappingSingleScanFails() {
         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
-- 
cgit v1.2.3