1297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills/*
2297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * Copyright (C) 2015 The Android Open Source Project
3297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills *
4297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * Licensed under the Apache License, Version 2.0 (the "License");
5297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * you may not use this file except in compliance with the License.
6297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * You may obtain a copy of the License at
7297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills *
8297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills *      http://www.apache.org/licenses/LICENSE-2.0
9297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills *
10297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * Unless required by applicable law or agreed to in writing, software
11297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * distributed under the License is distributed on an "AS IS" BASIS,
12297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * See the License for the specific language governing permissions and
1495984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills * limitations under the License.
15297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
16297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
1795984d1af44a00183a4b0e0ed61417583096ff90Mitchell Willspackage com.android.server.wifi.scanner;
18297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Willsimport static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Willsimport static com.android.server.wifi.ScanTestUtil.assertNativeScanSettingsEquals;
21297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.channelsToSpec;
22297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.createRequest;
23297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
2472c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertEquals;
2572c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertNotNull;
2672c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertTrue;
2794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport static org.mockito.Mockito.validateMockitoUsage;
28297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
29297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner;
30297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner.ScanSettings;
31297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.test.suitebuilder.annotation.SmallTest;
32216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Piusimport android.util.ArraySet;
33297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
3495984d1af44a00183a4b0e0ed61417583096ff90Mitchell Willsimport com.android.server.wifi.WifiNative;
35297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport com.android.server.wifi.WifiNative.BucketSettings;
367e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Willsimport com.android.server.wifi.scanner.KnownBandsChannelHelper.KnownBandsChannelCollection;
37297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
3894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.After;
39297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Before;
40297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Test;
41297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
42297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.lang.reflect.Field;
43297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.ArrayList;
44297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collection;
45297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collections;
463fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Willsimport java.util.Set;
47297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
48297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills/**
4995984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills * Unit tests for {@link com.android.server.wifi.scanner.BackgroundScanScheduler}.
50297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
51297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills@SmallTest
5295984d1af44a00183a4b0e0ed61417583096ff90Mitchell Willspublic class BackgroundScanSchedulerTest {
53297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
541a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BUCKETS = 9;
55216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    private static final int DEFAULT_MAX_CHANNELS_PER_BUCKET = 23;
561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BATCH = 11;
571a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_AP_PER_SCAN = 33;
58297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
597e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    private KnownBandsChannelHelper mChannelHelper;
6095984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills    private BackgroundScanScheduler mScheduler;
61297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
62297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Before
63297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void setUp() throws Exception {
64e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills        mChannelHelper = new PresetKnownBandsChannelHelper(
65297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{2400, 2450},
66297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5150, 5175},
67297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5600, 5650, 5660});
6895984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills        mScheduler = new BackgroundScanScheduler(mChannelHelper);
69297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(DEFAULT_MAX_BUCKETS);
70216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(DEFAULT_MAX_CHANNELS_PER_BUCKET);
71297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(DEFAULT_MAX_BATCH);
72297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxApPerScan(DEFAULT_MAX_AP_PER_SCAN);
73297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
74297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
7594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @After
7694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void cleanup() {
7794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        validateMockitoUsage();
7894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
7994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
80297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
81297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void noRequest() {
82297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.emptyList();
83297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
84297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
85297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
86297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
87e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals(30000, schedule.base_period_ms);
88297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 0);
89297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
90297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
91297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
92297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequest() {
93297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
94e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
95297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
96297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
97297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
98297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
99297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
100297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
101e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals(30000, schedule.base_period_ms);
102297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
103297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
104297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
105297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
106297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
107297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
108297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
109297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequestWithoutPredefinedBucket() {
110297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
111297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 7500, 0, 20,
112297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
113297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
114297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
115297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
116297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
117297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
118297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
119297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
120297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
121297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
122297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
123297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
124297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
125297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
126297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void fewRequests() {
127297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
128297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
129297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
130297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 14000, 0, 20,
131297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
132297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
133297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
134297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
135297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
136297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
137297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
138297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
139297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
140297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
141297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
142297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
143297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
144297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequests() {
145297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
146e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
147297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
14878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 15000, 0, 20,
149297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
150297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 0, 20,
151297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
152297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
153297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
154297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
155297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
156297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
157297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
158297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
159297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, false);
160297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
161297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
162297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
163297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
164297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void requestsWithNoPeriodCommonDenominator() {
165297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
166297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 299999, 0, 20,
167297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
168297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10500, 0, 20,
169297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
170297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
171297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
172297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
173297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
174297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
175297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
176297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
177297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
178297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
179297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
180297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
181297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
182297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequestsDifferentReportScans() {
183297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
184e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 60000, 0, 20,
185297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
186e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 60000, 0, 20,
187297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
188e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 60000, 0, 20,
189297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
190e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 60000, 0, 20,
191297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_NO_BATCH));
192297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
193297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
194297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
195297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
196e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 60000, schedule.base_period_ms);
197297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
198297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
199297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
200297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
201297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
202297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
203297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
204297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exceedMaxBatch() {
205297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
206e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 20,
207297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
208297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
209297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(5);
210297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
211297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
212297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
213e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
214297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
215297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
216297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
217297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
218297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.report_threshold_num_scans);
219297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
220297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
221297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
2221a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxBatch() {
2231a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
224e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 60000, 0, 20,
2251a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
2261a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2271a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBatch(6);
2281a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2291a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2301a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
231e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 60000, schedule.base_period_ms);
2321a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertBuckets(schedule, 1);
2331a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
2341a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
2351a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
2361a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 6, schedule.report_threshold_num_scans);
2371a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2381a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2391a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2401a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void exceedMaxAps() {
2411a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2421a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 20,
2431a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2441a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2451a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(5);
2461a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2471a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2481a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2491a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.max_ap_per_scan);
2501a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2511a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2521a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2531a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxAps() {
2541a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2551a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 0,
2561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2571a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2581a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(8);
2591a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2601a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2611a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2621a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxApsPerScan", 8, schedule.max_ap_per_scan);
2631a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2641a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2651a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
266297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets() {
267297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
268e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30000, 0, 20,
269297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
270297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 10000, 0, 20,
271297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
272e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 120000, 0, 20,
273297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
274297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
275297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
276297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
277297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
278297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
279e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
280297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
281297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
282297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
283297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
284297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
285297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
286297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
287297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets2() {
288297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
289e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30000, 0, 20,
290297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
291e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 60000, 0, 20,
292297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
293e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 3840000, 0, 20,
294297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
295297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
296297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
297297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
298297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
299297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
300e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
301297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
302297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
303297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
304297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
305297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
306297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
307297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    /**
308297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * Ensure that a channel request is placed in the bucket closest to the original
309e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills     * period and not the bucket it is initially placed in. Here the 5 min period is
310e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills     * initially placed in the 240s bucket, but that bucket is eliminated because it
311e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills     * would be a 7th bucket. This test ensures that the request is placed in the 480s
312e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills     * bucket and not the 120s bucket.
313297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     */
314297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
315297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBucketsClosestToOriginal() {
316297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
317e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30 * 1000, 0, 20,
318297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
319e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 120 * 1000, 0, 20,
320297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
321e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 480 * 1000, 0, 20,
322297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
323e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 10 * 1000, 0, 20,
324297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
325e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5600), 60 * 1000, 0, 20,
326297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
327e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5650), 1920 * 1000, 0, 20,
328297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
329297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
330e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5660), 300 * 1000, 0, 20, // 5 min
331297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
332297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
333297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(6);
334297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
335297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
336297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
337297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
338297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 6);
339297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
340297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
341297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
342297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
343297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
344297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3451a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnSingleBand() {
346297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
347e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450), 30000, 0, 20,
348297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
349297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
350297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
351216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(1);
352297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
353297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
354297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
355e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
356216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 2);
357297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
358297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
359297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
360297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
361297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
362297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3631a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBands() {
364297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
365e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5150), 30000, 0, 20,
366297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
367297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
368297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
369216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
370297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
371297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
372297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
373e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
374216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 2);
375297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
376297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
377297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
378297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
379297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
380297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3811a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBandsFromMultipleRequests() {
3821a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
383e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450), 30000, 0, 20,
3841a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
385e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 30000, 0, 20,
3861a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
3871a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
3881a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBuckets(2);
389216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
3901a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
3911a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
3921a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
393e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
394216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 2);
3951a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
3961a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
3971a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
3981a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
3991a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
4001a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
401297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exactRequests() {
402e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0,
403297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                20, WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
404e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 60000, 3,
405297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                13, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
406297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 2,
407297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
408297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 0,
409297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_NO_BATCH));
410297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 3,
411297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
4121a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        scheduleAndTestExactRequest(createRequest(channelsToSpec(2400, 5175, 5650) , 25000, 3,
4131a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
414297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
415297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
416f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
417f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void singleExponentialBackOffRequest() {
418f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = Collections.singleton(createRequest(
419e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 30000, 160000, 2, 0, 20,
420f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
421f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        ));
422f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
423f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
424f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
425f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
426e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals(30000, schedule.base_period_ms);
427f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 1);
428f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
429f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
430f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
431f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
432f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
433f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
434f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void exponentialBackOffAndRegularRequests() {
435f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = new ArrayList<>();
436e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 200000, 1,
437f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
438f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        requests.add(createRequest(channelsToSpec(5175), 30000, 0, 20,
439f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
440f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
441f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
442f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
443f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
444e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
445f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 2);
446f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
447f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
448f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
449f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
450f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
451216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
452216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
453216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is totally contained in the other setting. Ensure that the requests are collapsed into a
454216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * common bucket with the lower time period setting.
455216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
456216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
457216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalScheduleFullyCollapsesDuplicateChannelsInBand() {
458216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
459e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450), 240000, 0, 20,
460216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
461216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(WifiScanner.WIFI_BAND_24_GHZ, 10000, 0, 20,
462216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
463216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
464216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxBuckets(2);
465216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
466216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.updateSchedule(requests);
467216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
468216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
469216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
470216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 1);
471216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        for (ScanSettings request : requests) {
472216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            assertSettingsSatisfied(schedule, request, false, false);
473216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
474216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
475216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(0)));
476216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(1)));
477216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
478216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
479216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        collection.addBand(WifiScanner.WIFI_BAND_24_GHZ);
480216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = collection.getAllChannels();
481216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
482216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
483216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
484216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
485216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
486216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is totally contained in the other setting. Ensure that the requests are collapsed into a
487216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * common bucket with the lower time period setting.
488216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
489216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
490216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalScheduleFullyCollapsesDuplicateChannels() {
491216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
492e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450), 240000, 0, 20,
493216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
494216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
495216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
496216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
497216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxBuckets(2);
498216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
499216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.updateSchedule(requests);
500216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
501216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
502216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
503216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 1);
504216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        for (ScanSettings request : requests) {
505216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            assertSettingsSatisfied(schedule, request, false, false);
506216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
507216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
508216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(0)));
509216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(1)));
510216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
511216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
512216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
513216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
514216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
515216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
516216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
517216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
518216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
519216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is partially contained in the other setting. Ensure that the requests are partially split
520216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * across the lower time period bucket.
521216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
522216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
523216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalSchedulePartiallyCollapsesDuplicateChannels() {
524216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
525216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
526216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
527e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5175), 240000, 0, 20,
528216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
529216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
530216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxBuckets(2);
531216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
532216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.updateSchedule(requests);
533216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
534216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
535216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
536216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 2);
537216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        for (ScanSettings request : requests) {
538216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            assertSettingsSatisfied(schedule, request, false, false);
539216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
540216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
541216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(0)));
542216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 1, mScheduler.getScheduledBucket(requests.get(1)));
543216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
544216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
545216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
546216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
547216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
548216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
549216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
550216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5175);
551216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[1], expectedBucketChannelSet);
552216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
553216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
554216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
555216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
556216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is partially contained in the 2 other settings. Ensure that the requests are partially split
557216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * across the lower time period buckets.
558216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
559216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
560216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalSchedulePartiallyCollapsesDuplicateChannelsAcrossMultipleBuckets() {
561216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
562216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
563216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
564e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5175), 30000, 0, 20,
565216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
566e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 240000, 0, 20,
567216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
568216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
569216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxBuckets(3);
570216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.updateSchedule(requests);
571216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
572216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
573216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
574216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 3);
575216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        for (ScanSettings request : requests) {
576216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            assertSettingsSatisfied(schedule, request, false, false);
577216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
578216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
579216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(0)));
580216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 1, mScheduler.getScheduledBucket(requests.get(1)));
581216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 2, mScheduler.getScheduledBucket(requests.get(2)));
582216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
583216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
584216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
585216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
586216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
587216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
588216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
589216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5175);
590216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[1], expectedBucketChannelSet);
591216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
592216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
593216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        collection.addBand(WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
594216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet = collection.getAllChannels();
595216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(5175);
596216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(2400);
597216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(2450);
598216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[2], expectedBucketChannelSet);
599216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
600216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
601216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
602216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
603216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is partially contained in the 2 other settings. Ensure that the requests are partially split
604216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * across the lower time period buckets and the last bucket is split into 2 because the
605216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * channel list does not fit into a single bucket.
606216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
607216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
608216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalSchedulePartiallyCollapsesDuplicateChannelsWithSplitBuckets() {
609216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
610216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
611216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
612e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5175), 30000, 0, 20,
613216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
614e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 240000, 0, 20,
615216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
616216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
617216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxBuckets(5);
618216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.setMaxChannelsPerBucket(2);
619216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        mScheduler.updateSchedule(requests);
620216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
621216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
622216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
623216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 4);
624216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        for (ScanSettings request : requests) {
625216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            assertSettingsSatisfied(schedule, request, false, false);
626216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
627216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
628216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, mScheduler.getScheduledBucket(requests.get(0)));
629216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 1, mScheduler.getScheduledBucket(requests.get(1)));
630216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 2, mScheduler.getScheduledBucket(requests.get(2)));
631216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
632216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
633216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
634216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
635216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
636216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
637216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
638216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5175);
639216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[1], expectedBucketChannelSet);
640216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
641216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
642216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        collection.addBand(WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
643216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet = collection.getAllChannels();
644216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(5175);
645216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(2400);
646216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.remove(2450);
647216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        // Check if the combined channel set matches what we expect
648216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> combinedBucketChannelSet = getAllChannels(schedule.buckets[2]);
649216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        combinedBucketChannelSet.addAll(getAllChannels(schedule.buckets[3]));
650216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertChannels(combinedBucketChannelSet, expectedBucketChannelSet);
651216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
652216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
653216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
654216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
655216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is totally contained in the other setting. Ensure that the requests are collapsed into a
656216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * common bucket with the lower time period setting.
657216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * This is done with NoBandChannelHelper.
658216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
659216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
660216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalScheduleFullyCollapsesDuplicateChannelsInBandWithNoBandChannelHelper() {
661216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        BackgroundScanScheduler scheduler = createSchedulerWithNoBandChannelHelper();
662216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
663216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
664216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 160000, 0, 20,
665216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
666216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 10000, 0, 20,
667216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
668216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
669216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxBuckets(2);
670216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxChannelsPerBucket(2);
671216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.updateSchedule(requests);
672216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = scheduler.getSchedule();
673216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
674216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
675216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 1);
676216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
677216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, scheduler.getScheduledBucket(requests.get(0)));
678216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, scheduler.getScheduledBucket(requests.get(1)));
679216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
680216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("band", schedule.buckets[0].band, WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
681216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
682216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
683216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
684216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with different time intervals, but one of the setting channels
685216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * is partially contained in the other setting. Ensure that the requests are partially split
686216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * across the lower time period bucket.
687216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
688216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
689216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalSchedulePartiallyCollapsesDuplicateChannelsWithNoBandChannelHelper() {
690216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        BackgroundScanScheduler scheduler = createSchedulerWithNoBandChannelHelper();
691216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
692216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
693216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
694216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
695e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5175), 240000, 0, 20,
696216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
697216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
698216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxBuckets(2);
699216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxChannelsPerBucket(3);
700216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.updateSchedule(requests);
701216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = scheduler.getSchedule();
702216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
703216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
704216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 2);
705216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
706216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, scheduler.getScheduledBucket(requests.get(0)));
707216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 1, scheduler.getScheduledBucket(requests.get(1)));
708216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
709216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
710216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
711216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
712216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
713216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
714216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
715216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5175);
716216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[1], expectedBucketChannelSet);
717216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
718216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
719216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    /**
720216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * Add 2 background scan requests with the second scan request having channels more than the
721216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     * max, ensure that the last bucket is split.
722216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius     */
723216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    @Test
724216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    public void optimalScheduleShouldSplitBucketsWithNoBandChannelHelper() {
725216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        BackgroundScanScheduler scheduler = createSchedulerWithNoBandChannelHelper();
726216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
727216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        ArrayList<ScanSettings> requests = new ArrayList<>();
728216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        requests.add(createRequest(channelsToSpec(2400, 2450), 10000, 0, 20,
729216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
730e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        requests.add(createRequest(channelsToSpec(5150, 5175, 5600, 5650), 240000, 0, 20,
731216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
732216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
733216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxBuckets(3);
734216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxChannelsPerBucket(2);
735216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.updateSchedule(requests);
736216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        WifiNative.ScanSettings schedule = scheduler.getSchedule();
737216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
738216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
739216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBuckets(schedule, 3);
740216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
741216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 0, scheduler.getScheduledBucket(requests.get(0)));
742216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertEquals("scheduled bucket", 1, scheduler.getScheduledBucket(requests.get(1)));
743216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
744216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> expectedBucketChannelSet = new ArraySet<>();
745216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2400);
746216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(2450);
747216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[0], expectedBucketChannelSet);
748216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
749216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
750216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5150);
751216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5175);
752216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[1], expectedBucketChannelSet);
753216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
754216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.clear();
755216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5600);
756216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        expectedBucketChannelSet.add(5650);
757216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertBucketChannels(schedule.buckets[2], expectedBucketChannelSet);
758216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
759216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
7607e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    protected Set<Integer> getAllChannels(BucketSettings bucket) {
7617e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
7627e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        collection.addChannels(bucket);
7637e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        return collection.getAllChannels();
7647e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    }
7657e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
7667e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    protected Set<Integer> getAllChannels(WifiScanner.ScanSettings settings) {
7677e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
7687e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        collection.addChannels(settings);
7697e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        return collection.getAllChannels();
7707e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    }
7717e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
772297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void scheduleAndTestExactRequest(ScanSettings settings) {
773297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
774297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(settings);
775297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
776297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
777297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
778297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
7798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int expectedPeriod = computeExpectedPeriod(settings.periodInMs);
7808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        NativeScanSettingsBuilder expectedBuilder = new NativeScanSettingsBuilder()
7818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withBasePeriod(expectedPeriod)
7828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(settings.numBssidsPerScan == 0
7838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        ? DEFAULT_MAX_AP_PER_SCAN
7848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        : settings.numBssidsPerScan)
7858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxScansToCache(settings.maxScansToCache == 0
7868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        ? DEFAULT_MAX_BATCH
7878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        : settings.maxScansToCache);
788297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
7893fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
7908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            expectedBuilder.addBucketWithChannels(expectedPeriod, settings.reportEvents,
7918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                    settings.channels);
7928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        } else {
7938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            expectedBuilder.addBucketWithBand(expectedPeriod, settings.reportEvents, settings.band);
794297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
7958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertNativeScanSettingsEquals(expectedBuilder.build(), schedule);
796297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
797297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
798297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) {
799297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets", numBuckets, schedule.num_buckets);
800297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertNotNull("buckets was null", schedule.buckets);
801297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets and actual buckets", schedule.num_buckets,
802297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.buckets.length);
803297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < numBuckets; i++) {
804297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertNotNull("bucket[" + i + "] was null", schedule.buckets[i]);
805297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (schedule.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
806297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("num channels <= 0", schedule.buckets[i].num_channels > 0);
807297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("bucket channels > max channels",
808216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                        schedule.buckets[i].num_channels <= mScheduler.getMaxChannelsPerBucket());
809297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertNotNull("Channels was null", schedule.buckets[i].channels);
810297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                for (int c = 0; c < schedule.buckets[i].num_channels; c++) {
811297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    assertNotNull("Channel was null", schedule.buckets[i].channels[c]);
812297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
813297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
814297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("Invalid band: " + schedule.buckets[i].band,
81572c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        schedule.buckets[i].band > WifiScanner.WIFI_BAND_UNSPECIFIED
81672c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        && schedule.buckets[i].band <= WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
817297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
818297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
819297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
820297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
8217e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    private void assertSettingsSatisfied(WifiNative.ScanSettings schedule,
822297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            ScanSettings settings, boolean bucketsLimited, boolean exactPeriod) {
82372c639e8b97067e948eca8be50dfea3173121090Mitchell Wills        assertTrue("bssids per scan: " + schedule.max_ap_per_scan + " /<= "
82472c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                + settings.numBssidsPerScan,
82572c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                schedule.max_ap_per_scan <= settings.numBssidsPerScan);
826297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
827297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.maxScansToCache > 0) {
82872c639e8b97067e948eca8be50dfea3173121090Mitchell Wills            assertTrue("scans to cache: " + schedule.report_threshold_num_scans + " /<= "
82972c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    + settings.maxScansToCache,
83072c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    schedule.report_threshold_num_scans <= settings.maxScansToCache);
831297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
832297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
8337e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        Set<Integer> channelSet = getAllChannels(settings);
834297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
835297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        StringBuilder ignoreString = new StringBuilder();
836297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
8377e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection scheduleChannels = mChannelHelper.createChannelCollection();
838297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int b = 0; b < schedule.num_buckets; b++) {
839297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            BucketSettings bucket = schedule.buckets[b];
840297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0) {
841297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) == 0) {
842297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
84354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
8447e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
84554e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=after_each_scan:")
84654e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)
84754e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
84854e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents
84954e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
850297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
851297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
852297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
853297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
854297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) == 0) {
855297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
85654e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
8577e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
85854e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=full_result:")
85954e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events
86054e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)
86154e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
86254e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents
86354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT);
864297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
865297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
866297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
867297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) {
868297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH) != 0) {
869297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
87054e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
8717e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
87254e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=no_batch:")
87354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH)
87454e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
87554e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH);
876297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
877297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
878297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
879297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int expectedPeriod;
880f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
881f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            if (settings.maxPeriodInMs != 0 && settings.periodInMs != settings.maxPeriodInMs) {
882f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                // exponential back off scan
883f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                expectedPeriod = settings.periodInMs;
884297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
885f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                if (bucketsLimited) {
886f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs, schedule);
887f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                } else {
888f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs);
889f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                }
890297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
891297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
892297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (exactPeriod) {
893297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms != expectedPeriod) {
894297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
895297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
8967e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
897297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
898297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
899297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("!=")
900297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
901297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
902297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
903297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
904297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms > expectedPeriod) {
905297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
906297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
9077e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
908297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
909297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
910297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(">")
911297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
912297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
913297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
914297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
9157e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills            scheduleChannels.addChannels(bucket);
916297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
917297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
9187e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        assertTrue("expected that " + scheduleChannels.getAllChannels() + " contained "
9197e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                + channelSet + ", Channel ignore reasons:" + ignoreString.toString(),
9207e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                scheduleChannels.getAllChannels().containsAll(channelSet));
921297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
922297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
923216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    private void assertBucketChannels(BucketSettings bucket, Set<Integer> expectedChannelSet) {
924216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        Set<Integer> bucketChannelSet = getAllChannels(bucket);
925216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertChannels(bucketChannelSet, expectedChannelSet);
926216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
927216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
928216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    private void assertChannels(Set<Integer> channelSet, Set<Integer> expectedChannelSet) {
929216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        assertTrue("expected that " + channelSet + " contained "
930216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                + expectedChannelSet, channelSet.containsAll(expectedChannelSet));
931216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
932216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
933216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    private BackgroundScanScheduler createSchedulerWithNoBandChannelHelper() {
934216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        NoBandChannelHelper channelHelper = new NoBandChannelHelper();
935216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        BackgroundScanScheduler scheduler = new BackgroundScanScheduler(channelHelper);
936216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxBuckets(DEFAULT_MAX_BUCKETS);
937216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxChannelsPerBucket(DEFAULT_MAX_CHANNELS_PER_BUCKET);
938216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxBatch(DEFAULT_MAX_BATCH);
939216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        scheduler.setMaxApPerScan(DEFAULT_MAX_AP_PER_SCAN);
940216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        return scheduler;
941216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius    }
942216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
943297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int[] getPredefinedBuckets() {
944297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        try {
94595984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills            Field f = BackgroundScanScheduler.class.getDeclaredField("PREDEFINED_BUCKET_PERIODS");
946297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            f.setAccessible(true);
947297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            return (int[]) f.get(null);
948297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } catch (Exception e) {
949297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            throw new RuntimeException("Could not get predefined buckets", e);
950297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
951297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
952297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int[] PREDEFINED_BUCKET_PERIODS = getPredefinedBuckets();
953297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
954297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period
955297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod) {
956297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
957297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
958297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int bucketPeriod : PREDEFINED_BUCKET_PERIODS) {
959297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
960297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
961297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
962297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
963297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
964297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
965297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
966297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
967297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
968297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period that exists in the schedule
969297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod,
970297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            WifiNative.ScanSettings schedule) {
971297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
972297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
973297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < schedule.num_buckets; ++i) {
974297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int bucketPeriod = schedule.buckets[i].period_ms;
975297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
976297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
977297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
978297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
979297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
980297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
981297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
982297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
983297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills}
984