BackgroundScanSchedulerTest.java revision 95984d1af44a00183a4b0e0ed61417583096ff90
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;
32297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
3395984d1af44a00183a4b0e0ed61417583096ff90Mitchell Willsimport com.android.server.wifi.WifiNative;
34297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport com.android.server.wifi.WifiNative.BucketSettings;
357e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Willsimport com.android.server.wifi.scanner.KnownBandsChannelHelper.KnownBandsChannelCollection;
36297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
3794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.After;
38297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Before;
39297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Test;
40297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
41297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.lang.reflect.Field;
42297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.ArrayList;
43297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collection;
44297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collections;
453fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Willsimport java.util.Set;
46297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
47297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills/**
4895984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills * Unit tests for {@link com.android.server.wifi.scanner.BackgroundScanScheduler}.
49297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
50297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills@SmallTest
5195984d1af44a00183a4b0e0ed61417583096ff90Mitchell Willspublic class BackgroundScanSchedulerTest {
52297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
531a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BUCKETS = 9;
541a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_CHANNELS = 23;
551a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BATCH = 11;
561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_AP_PER_SCAN = 33;
57297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
587e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    private KnownBandsChannelHelper mChannelHelper;
5995984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills    private BackgroundScanScheduler mScheduler;
60297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
61297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Before
62297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void setUp() throws Exception {
63e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills        mChannelHelper = new PresetKnownBandsChannelHelper(
64297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{2400, 2450},
65297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5150, 5175},
66297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5600, 5650, 5660});
6795984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills        mScheduler = new BackgroundScanScheduler(mChannelHelper);
68297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(DEFAULT_MAX_BUCKETS);
69297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(DEFAULT_MAX_CHANNELS);
70297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(DEFAULT_MAX_BATCH);
71297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxApPerScan(DEFAULT_MAX_AP_PER_SCAN);
72297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
73297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
7494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @After
7594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void cleanup() {
7694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        validateMockitoUsage();
7794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
7894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
79297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
80297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void noRequest() {
81297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.emptyList();
82297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
83297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
84297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
85297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
8678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals(40000, schedule.base_period_ms);
87297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 0);
88297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
89297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
90297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
91297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequest() {
92297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
9378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan                WifiScanner.WIFI_BAND_BOTH, 20000, 0, 20,
94297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
95297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
96297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
97297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
98297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
99297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
10078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals(20000, schedule.base_period_ms);
101297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
102297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
103297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
104297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
105297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
106297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
107297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
108297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequestWithoutPredefinedBucket() {
109297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
110297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 7500, 0, 20,
111297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
112297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
113297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
114297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
115297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
116297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
117297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
118297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
119297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
120297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
121297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
122297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
123297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
124297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
125297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void fewRequests() {
126297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
127297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
128297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
129297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 14000, 0, 20,
130297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
131297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
132297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
133297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
134297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
135297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
136297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
137297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
138297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
139297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
140297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
141297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
142297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
143297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequests() {
144297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
14578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 0, 20,
146297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
14778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 15000, 0, 20,
148297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
149297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 0, 20,
150297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
151297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
152297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
153297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
154297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
155297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
156297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
157297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
158297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, false);
159297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
160297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
161297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
162297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
163297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void requestsWithNoPeriodCommonDenominator() {
164297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
165297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 299999, 0, 20,
166297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
167297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10500, 0, 20,
168297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
169297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
170297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
171297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
172297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
173297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
174297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
175297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
176297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
177297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
178297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
179297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
180297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
181297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequestsDifferentReportScans() {
182297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
18378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 40000, 0, 20,
184297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
18578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 40000, 0, 20,
186297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
18778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 40000, 0, 20,
188297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
18978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 40000, 0, 20,
190297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_NO_BATCH));
191297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
192297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
193297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
194297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
19578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 40000, schedule.base_period_ms);
196297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
197297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
198297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
199297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
200297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
201297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
202297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
203297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exceedMaxBatch() {
204297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
20578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 20000, 10, 20,
206297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
207297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
208297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(5);
209297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
210297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
211297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
21278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
213297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
214297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
215297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
216297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
217297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.report_threshold_num_scans);
218297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
219297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
220297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
2211a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxBatch() {
2221a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
22378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 40000, 0, 20,
2241a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
2251a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2261a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBatch(6);
2271a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2281a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2291a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
23078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 40000, schedule.base_period_ms);
2311a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertBuckets(schedule, 1);
2321a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
2331a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
2341a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
2351a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 6, schedule.report_threshold_num_scans);
2361a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2371a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2381a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2391a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void exceedMaxAps() {
2401a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2411a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 20,
2421a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2431a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2441a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(5);
2451a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2461a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2471a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2481a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.max_ap_per_scan);
2491a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2501a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2511a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2521a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxAps() {
2531a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2541a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 0,
2551a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2571a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(8);
2581a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2591a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2601a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2611a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxApsPerScan", 8, schedule.max_ap_per_scan);
2621a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2631a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2641a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
265297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets() {
266297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
26778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 20000, 0, 20,
268297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
269297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 10000, 0, 20,
270297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
27178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 40000, 0, 20,
272297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
273297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
274297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
275297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
276297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
277297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
27878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
279297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
280297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
281297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
282297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
283297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
284297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
285297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
286297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets2() {
287297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
28878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 20000, 0, 20,
289297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
29078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 40000, 0, 20,
291297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
29278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 2560000, 0, 20,
293297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
294297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
295297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
296297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
297297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
298297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
29978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
300297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
301297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
302297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
303297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
304297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
305297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
306297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    /**
307297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * Ensure that a channel request is placed in the bucket closest to the original
30878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * period and not the bucket it is initially placed in. Here the 12 min period is
30978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * initially placed in the 640s bucket, but that bucket is eliminated because it
31078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * would be a 7th bucket. This test ensures that the request is placed in the 1280s
31178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * bucket and not the 320s bucket.
312297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     */
313297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
314297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBucketsClosestToOriginal() {
315297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
31678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 40 * 1000, 0, 20,
317297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
31878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 20 * 1000, 0, 20,
319297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 160 * 1000, 0, 20,
321297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 320 * 1000, 0, 20,
323297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
324297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5600), 10 * 1000, 0, 20,
325297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5650), 1280 * 1000, 0, 20,
327297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
328297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
32978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5660), 720 * 1000, 0, 20, // 12 min
330297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
331297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
332297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(6);
333297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
334297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
335297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
336297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
337297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 6);
338297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
339297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
340297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
341297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
342297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
343297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3441a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnSingleBand() {
345297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
34678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450), 20000, 0, 20,
347297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
348297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
349297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
350297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(1);
351297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
352297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
353297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
35478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
355297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
356297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
357297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
358297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
359297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
360297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
361297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3621a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBands() {
363297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
36478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450, 5150), 20000, 0, 20,
365297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
366297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
367297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
368297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(2);
369297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
370297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
371297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
37278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
373297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
374297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
375297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
376297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
377297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
378297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
379297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3801a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBandsFromMultipleRequests() {
3811a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
38278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450), 20000, 0, 20,
3831a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
38478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 20000, 0, 20,
3851a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
3861a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
3871a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBuckets(2);
3881a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxChannels(2);
3891a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
3901a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
3911a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
39278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
3931a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertBuckets(schedule, 1);
3941a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
3951a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
3961a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
3971a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
3981a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
3991a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
400297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exactRequests() {
40178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 0,
402297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                20, WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
40378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 40000, 3,
404297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                13, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
405297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 2,
406297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
407297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 0,
408297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_NO_BATCH));
409297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 3,
410297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
4111a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        scheduleAndTestExactRequest(createRequest(channelsToSpec(2400, 5175, 5650) , 25000, 3,
4121a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
413297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
414297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
415f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
416f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void singleExponentialBackOffRequest() {
417f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = Collections.singleton(createRequest(
418f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.WIFI_BAND_BOTH, 20000, 160000, 2, 0, 20,
419f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
420f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        ));
421f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
422f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
423f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
424f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
425f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertEquals(20000, schedule.base_period_ms);
426f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 1);
427f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
428f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
429f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
430f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
431f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
432f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
433f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void exponentialBackOffAndRegularRequests() {
434f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = new ArrayList<>();
435f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 200000, 1,
436f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
437f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        requests.add(createRequest(channelsToSpec(5175), 30000, 0, 20,
438f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
439f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
440f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
441f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
442f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
44378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
444f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 2);
445f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
446f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
447f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
448f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
449f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
4507e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    protected Set<Integer> getAllChannels(BucketSettings bucket) {
4517e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
4527e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        collection.addChannels(bucket);
4537e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        return collection.getAllChannels();
4547e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    }
4557e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
4567e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    protected Set<Integer> getAllChannels(WifiScanner.ScanSettings settings) {
4577e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection collection = mChannelHelper.createChannelCollection();
4587e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        collection.addChannels(settings);
4597e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        return collection.getAllChannels();
4607e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    }
4617e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
462297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void scheduleAndTestExactRequest(ScanSettings settings) {
463297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
464297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(settings);
465297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
466297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
467297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
468297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
4698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int expectedPeriod = computeExpectedPeriod(settings.periodInMs);
4708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        NativeScanSettingsBuilder expectedBuilder = new NativeScanSettingsBuilder()
4718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withBasePeriod(expectedPeriod)
4728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(settings.numBssidsPerScan == 0
4738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        ? DEFAULT_MAX_AP_PER_SCAN
4748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        : settings.numBssidsPerScan)
4758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxScansToCache(settings.maxScansToCache == 0
4768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        ? DEFAULT_MAX_BATCH
4778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        : settings.maxScansToCache);
478297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
4793fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
4808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            expectedBuilder.addBucketWithChannels(expectedPeriod, settings.reportEvents,
4818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                    settings.channels);
4828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        } else {
4838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            expectedBuilder.addBucketWithBand(expectedPeriod, settings.reportEvents, settings.band);
484297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
4858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertNativeScanSettingsEquals(expectedBuilder.build(), schedule);
486297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
487297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
488297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) {
489297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets", numBuckets, schedule.num_buckets);
490297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertNotNull("buckets was null", schedule.buckets);
491297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets and actual buckets", schedule.num_buckets,
492297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.buckets.length);
493297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < numBuckets; i++) {
494297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertNotNull("bucket[" + i + "] was null", schedule.buckets[i]);
495297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (schedule.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
496297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("num channels <= 0", schedule.buckets[i].num_channels > 0);
497297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("bucket channels > max channels",
498297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        schedule.buckets[i].num_channels <= mScheduler.getMaxChannels());
499297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertNotNull("Channels was null", schedule.buckets[i].channels);
500297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                for (int c = 0; c < schedule.buckets[i].num_channels; c++) {
501297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    assertNotNull("Channel was null", schedule.buckets[i].channels[c]);
502297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
503297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
504297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("Invalid band: " + schedule.buckets[i].band,
50572c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        schedule.buckets[i].band > WifiScanner.WIFI_BAND_UNSPECIFIED
50672c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        && schedule.buckets[i].band <= WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
507297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
508297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
509297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
510297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
5117e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    private void assertSettingsSatisfied(WifiNative.ScanSettings schedule,
512297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            ScanSettings settings, boolean bucketsLimited, boolean exactPeriod) {
51372c639e8b97067e948eca8be50dfea3173121090Mitchell Wills        assertTrue("bssids per scan: " + schedule.max_ap_per_scan + " /<= "
51472c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                + settings.numBssidsPerScan,
51572c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                schedule.max_ap_per_scan <= settings.numBssidsPerScan);
516297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
517297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.maxScansToCache > 0) {
51872c639e8b97067e948eca8be50dfea3173121090Mitchell Wills            assertTrue("scans to cache: " + schedule.report_threshold_num_scans + " /<= "
51972c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    + settings.maxScansToCache,
52072c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    schedule.report_threshold_num_scans <= settings.maxScansToCache);
521297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
522297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
5237e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        Set<Integer> channelSet = getAllChannels(settings);
524297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
525297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        StringBuilder ignoreString = new StringBuilder();
526297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
5277e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        KnownBandsChannelCollection scheduleChannels = mChannelHelper.createChannelCollection();
528297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int b = 0; b < schedule.num_buckets; b++) {
529297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            BucketSettings bucket = schedule.buckets[b];
530297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0) {
531297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) == 0) {
532297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
53354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
5347e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
53554e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=after_each_scan:")
53654e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)
53754e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
53854e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents
53954e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
540297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
541297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
542297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
543297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
544297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) == 0) {
545297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
54654e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
5477e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
54854e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=full_result:")
54954e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events
55054e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)
55154e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
55254e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents
55354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                                    & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT);
554297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
555297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
556297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
557297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) {
558297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH) != 0) {
559297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
56054e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(" ")
5617e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
56254e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("=no_batch:")
56354e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH)
56454e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append("!=")
56554e2c84547e22622ba4a08bddd1c632d1d937be3Mitchell Wills                            .append(settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH);
566297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
567297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
568297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
569297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int expectedPeriod;
570f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
571f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            if (settings.maxPeriodInMs != 0 && settings.periodInMs != settings.maxPeriodInMs) {
572f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                // exponential back off scan
573f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                expectedPeriod = settings.periodInMs;
574297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
575f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                if (bucketsLimited) {
576f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs, schedule);
577f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                } else {
578f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs);
579f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                }
580297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
581297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
582297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (exactPeriod) {
583297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms != expectedPeriod) {
584297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
585297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
5867e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
587297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
588297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
589297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("!=")
590297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
591297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
592297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
593297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
594297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms > expectedPeriod) {
595297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
596297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
5977e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                            .append(getAllChannels(bucket))
598297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
599297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
600297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(">")
601297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
602297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
603297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
604297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
6057e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills            scheduleChannels.addChannels(bucket);
606297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
607297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
6087e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        assertTrue("expected that " + scheduleChannels.getAllChannels() + " contained "
6097e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                + channelSet + ", Channel ignore reasons:" + ignoreString.toString(),
6107e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills                scheduleChannels.getAllChannels().containsAll(channelSet));
611297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
612297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
613297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int[] getPredefinedBuckets() {
614297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        try {
61595984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills            Field f = BackgroundScanScheduler.class.getDeclaredField("PREDEFINED_BUCKET_PERIODS");
616297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            f.setAccessible(true);
617297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            return (int[]) f.get(null);
618297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } catch (Exception e) {
619297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            throw new RuntimeException("Could not get predefined buckets", e);
620297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
621297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
622297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int[] PREDEFINED_BUCKET_PERIODS = getPredefinedBuckets();
623297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
624297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period
625297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod) {
626297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
627297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
628297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int bucketPeriod : PREDEFINED_BUCKET_PERIODS) {
629297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
630297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
631297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
632297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
633297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
634297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
635297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
636297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
637297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
638297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period that exists in the schedule
639297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod,
640297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            WifiNative.ScanSettings schedule) {
641297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
642297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
643297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < schedule.num_buckets; ++i) {
644297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int bucketPeriod = schedule.buckets[i].period_ms;
645297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
646297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
647297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
648297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
649297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
650297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
651297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
652297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
653297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills}
654