BackgroundScanSchedulerTest.java revision 3fdceeaa74e21c0ca4da52deeeef6571e7e2a6cd
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
14297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * limitations under the License
15297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
16297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
17297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willspackage com.android.server.wifi;
18297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
19297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.channelsToSpec;
20297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.createRequest;
21297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.getAllChannels;
22297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.installWlanWifiNative;
23297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.setupMockChannels;
24297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
2572c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertEquals;
2672c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertNotNull;
2772c639e8b97067e948eca8be50dfea3173121090Mitchell Willsimport static org.junit.Assert.assertTrue;
28297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static org.mockito.Mockito.mock;
2994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport static org.mockito.Mockito.validateMockitoUsage;
30297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
31297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner;
32297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner.ChannelSpec;
33297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner.ScanSettings;
34297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.test.suitebuilder.annotation.SmallTest;
35297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
36297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport com.android.server.wifi.WifiNative.BucketSettings;
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;
46297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.HashSet;
473fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Willsimport java.util.Set;
48297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
49297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills/**
50297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * Unit tests for {@link com.android.server.wifi.MultiClientScheduler}.
51297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
52297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills@SmallTest
53297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willspublic class MultiClientSchedulerTest {
54297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
551a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BUCKETS = 9;
561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_CHANNELS = 23;
571a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_BATCH = 11;
581a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    private static final int DEFAULT_MAX_AP_PER_SCAN = 33;
59297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
60297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private WifiNative mWifiNative;
61297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private MultiClientScheduler mScheduler;
62297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
63297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Before
64297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void setUp() throws Exception {
65297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mWifiNative = mock(WifiNative.class);
66297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        setupMockChannels(mWifiNative,
67297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{2400, 2450},
68297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5150, 5175},
69297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5600, 5650, 5660});
70297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        installWlanWifiNative(mWifiNative);
71297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
72297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler = new MultiClientScheduler();
73297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(DEFAULT_MAX_BUCKETS);
74297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(DEFAULT_MAX_CHANNELS);
75297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(DEFAULT_MAX_BATCH);
76297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxApPerScan(DEFAULT_MAX_AP_PER_SCAN);
77297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
78297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
7994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @After
8094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void cleanup() {
8194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        validateMockitoUsage();
8294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
8394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
84297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
85297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void noRequest() {
86297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.emptyList();
87297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
88297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
89297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
90297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
9178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals(40000, schedule.base_period_ms);
92297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 0);
93297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
94297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
95297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
96297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequest() {
97297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
9878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan                WifiScanner.WIFI_BAND_BOTH, 20000, 0, 20,
99297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
100297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
101297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
102297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
103297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
104297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
10578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals(20000, schedule.base_period_ms);
106297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
107297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
108297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
109297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
110297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
111297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
112297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
113297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequestWithoutPredefinedBucket() {
114297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
115297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 7500, 0, 20,
116297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
117297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
118297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
119297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
120297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
121297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
122297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
123297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
124297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
125297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
126297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
127297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
128297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
129297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
130297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void fewRequests() {
131297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
132297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
133297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
134297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 14000, 0, 20,
135297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
136297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
137297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
138297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
139297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
140297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
141297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
142297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
143297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
144297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
145297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
146297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
147297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
148297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequests() {
149297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
15078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 0, 20,
151297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
15278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 15000, 0, 20,
153297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
154297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 0, 20,
155297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
156297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
157297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
158297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
159297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
160297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
161297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
162297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
163297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, false);
164297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
165297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
166297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
167297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
168297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void requestsWithNoPeriodCommonDenominator() {
169297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
170297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 299999, 0, 20,
171297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
172297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10500, 0, 20,
173297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
174297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
175297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
176297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
177297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
178297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
179297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
180297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
181297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
182297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
183297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
184297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
185297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
186297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequestsDifferentReportScans() {
187297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
18878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 40000, 0, 20,
189297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
19078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 40000, 0, 20,
191297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
19278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 40000, 0, 20,
193297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
19478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 40000, 0, 20,
195297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_NO_BATCH));
196297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
197297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
198297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
199297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
20078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 40000, schedule.base_period_ms);
201297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
202297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
203297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
204297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
205297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
206297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
207297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
208297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exceedMaxBatch() {
209297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
21078c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 20000, 10, 20,
211297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
212297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
213297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(5);
214297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
215297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
216297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
21778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
218297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
219297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
220297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
221297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
222297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.report_threshold_num_scans);
223297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
224297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
225297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
2261a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxBatch() {
2271a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
22878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 40000, 0, 20,
2291a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
2301a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2311a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBatch(6);
2321a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2331a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2341a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
23578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 40000, schedule.base_period_ms);
2361a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertBuckets(schedule, 1);
2371a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
2381a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
2391a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
2401a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 6, schedule.report_threshold_num_scans);
2411a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2421a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2431a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2441a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void exceedMaxAps() {
2451a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2461a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 20,
2471a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2481a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2491a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(5);
2501a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2511a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2521a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2531a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.max_ap_per_scan);
2541a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2551a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2561a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
2571a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void defaultMaxAps() {
2581a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
2591a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 0,
2601a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
2611a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2621a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxApPerScan(8);
2631a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
2641a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
2651a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2661a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertEquals("maxApsPerScan", 8, schedule.max_ap_per_scan);
2671a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
2681a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
2691a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
270297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets() {
271297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
27278c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 20000, 0, 20,
273297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
274297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 10000, 0, 20,
275297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
27678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 40000, 0, 20,
277297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
278297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
279297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
280297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
281297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
282297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
28378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
284297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
285297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
286297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
287297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
288297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
289297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
290297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
291297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets2() {
292297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
29378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 20000, 0, 20,
294297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
29578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 40000, 0, 20,
296297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
29778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 2560000, 0, 20,
298297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
299297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
300297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
301297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
302297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
303297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
30478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
305297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
306297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
307297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
308297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
309297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
310297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
311297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    /**
312297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * Ensure that a channel request is placed in the bucket closest to the original
31378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * period and not the bucket it is initially placed in. Here the 12 min period is
31478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * initially placed in the 640s bucket, but that bucket is eliminated because it
31578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * would be a 7th bucket. This test ensures that the request is placed in the 1280s
31678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan     * bucket and not the 320s bucket.
317297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     */
318297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
319297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBucketsClosestToOriginal() {
320297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
32178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400), 40 * 1000, 0, 20,
322297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32378c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2450), 20 * 1000, 0, 20,
324297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32578c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5150), 160 * 1000, 0, 20,
326297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
32778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5175), 320 * 1000, 0, 20,
328297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
329297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5600), 10 * 1000, 0, 20,
330297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
33178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5650), 1280 * 1000, 0, 20,
332297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
333297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
33478c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(5660), 720 * 1000, 0, 20, // 12 min
335297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
336297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
337297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(6);
338297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
339297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
340297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
341297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
342297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 6);
343297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
344297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
345297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
346297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
347297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
348297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3491a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnSingleBand() {
350297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
35178c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450), 20000, 0, 20,
352297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
353297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
354297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
355297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(1);
356297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
357297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
358297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
35978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
360297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
361297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
362297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
363297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
364297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
365297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
366297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3671a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBands() {
368297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
36978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450, 5150), 20000, 0, 20,
370297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
371297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
372297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
373297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(2);
374297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
375297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
376297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
37778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
378297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
379297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
380297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
381297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
382297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
383297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
384297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
3851a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    public void optimalScheduleExceedsMaxChannelsOnMultipleBandsFromMultipleRequests() {
3861a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
38778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(channelsToSpec(2400, 2450), 20000, 0, 20,
3881a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
38978c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 20000, 0, 20,
3901a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
3911a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
3921a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxBuckets(2);
3931a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.setMaxChannels(2);
3941a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        mScheduler.updateSchedule(requests);
3951a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
3961a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
39778c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
3981a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        assertBuckets(schedule, 1);
3991a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        for (ScanSettings request : requests) {
4001a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
4011a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        }
4021a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    }
4031a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills
4041a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills    @Test
405297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exactRequests() {
40678c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 0,
407297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                20, WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
40878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 40000, 3,
409297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                13, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
410297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 2,
411297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
412297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 0,
413297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_NO_BATCH));
414297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 3,
415297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
4161a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills        scheduleAndTestExactRequest(createRequest(channelsToSpec(2400, 5175, 5650) , 25000, 3,
4171a16020f8d611c94797884b212ee6a26817fad82Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
418297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
419297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
420f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
421f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void singleExponentialBackOffRequest() {
422f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = Collections.singleton(createRequest(
423f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.WIFI_BAND_BOTH, 20000, 160000, 2, 0, 20,
424f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
425f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        ));
426f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
427f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
428f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
429f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
430f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertEquals(20000, schedule.base_period_ms);
431f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 1);
432f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
433f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
434f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
435f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
436f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
437f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    @Test
438f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    public void exponentialBackOffAndRegularRequests() {
439f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        Collection<ScanSettings> requests = new ArrayList<>();
440f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, 200000, 1,
441f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
442f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        requests.add(createRequest(channelsToSpec(5175), 30000, 0, 20,
443f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
444f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
445f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        mScheduler.updateSchedule(requests);
446f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
447f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
44878c66a6fa8ac2f6c9d3fa74313a4ac8c3585cb18Randy Pan        assertEquals("base_period_ms", 20000, schedule.base_period_ms);
449f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        assertBuckets(schedule, 2);
450f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        for (ScanSettings request : requests) {
451f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            assertSettingsSatisfied(schedule, request, false, true);
452f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan        }
453f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan    }
454f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
455297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void scheduleAndTestExactRequest(ScanSettings settings) {
456297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
457297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(settings);
458297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
459297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
460297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
461297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
4623fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        assertEquals("base_period_ms", computeExpectedPeriod(settings.periodInMs),
4633fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                schedule.base_period_ms);
4643fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        assertBuckets(schedule, 1);
465297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
4663fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        if (settings.numBssidsPerScan == 0) {
4673fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("bssids per scan", DEFAULT_MAX_AP_PER_SCAN, schedule.max_ap_per_scan);
4683fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        } else {
4693fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("bssids per scan", settings.numBssidsPerScan, schedule.max_ap_per_scan);
4703fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        }
4713fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        if (settings.maxScansToCache == 0) {
4723fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("scans to cache", DEFAULT_MAX_BATCH,
4733fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                    schedule.report_threshold_num_scans);
474772124d1f1ddb2b9537de5efc748943808dafe80Mitchell Wills        } else {
4753fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("scans to cache", settings.maxScansToCache,
4763fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                    schedule.report_threshold_num_scans);
4773fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        }
4783fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        assertEquals("reportEvents", settings.reportEvents, schedule.buckets[0].report_events);
4793fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        assertEquals("period", computeExpectedPeriod(settings.periodInMs),
4803fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                schedule.buckets[0].period_ms);
4813fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
4823fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("band", settings.band, schedule.buckets[0].band);
4833fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            Set<Integer> expectedChannels = new HashSet<>();
4843fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            for (ChannelSpec channel : getAllChannels(settings)) {
4853fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                expectedChannels.add(channel.frequency);
4863fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            }
4873fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            Set<Integer> actualChannels = new HashSet<>();
4883fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            for (ChannelSpec channel : getAllChannels(schedule.buckets[0])) {
4893fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                actualChannels.add(channel.frequency);
4903fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            }
4913fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("channels", expectedChannels, actualChannels);
4923fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        }
4933fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills        else {
4943fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("band", settings.band, schedule.buckets[0].band);
4953fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertEquals("num_channels", 0, schedule.buckets[0].num_channels);
4963fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills            assertTrue("channels", schedule.buckets[0].channels == null
4973fdceeaa74e21c0ca4da52deeeef6571e7e2a6cdMitchell Wills                    || schedule.buckets[0].channels.length == 0);
498297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
499297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
500297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
501297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) {
502297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets", numBuckets, schedule.num_buckets);
503297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertNotNull("buckets was null", schedule.buckets);
504297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets and actual buckets", schedule.num_buckets,
505297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.buckets.length);
506297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < numBuckets; i++) {
507297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertNotNull("bucket[" + i + "] was null", schedule.buckets[i]);
508297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (schedule.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
509297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("num channels <= 0", schedule.buckets[i].num_channels > 0);
510297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("bucket channels > max channels",
511297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        schedule.buckets[i].num_channels <= mScheduler.getMaxChannels());
512297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertNotNull("Channels was null", schedule.buckets[i].channels);
513297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                for (int c = 0; c < schedule.buckets[i].num_channels; c++) {
514297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    assertNotNull("Channel was null", schedule.buckets[i].channels[c]);
515297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
516297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
517297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("Invalid band: " + schedule.buckets[i].band,
51872c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        schedule.buckets[i].band > WifiScanner.WIFI_BAND_UNSPECIFIED
51972c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                        && schedule.buckets[i].band <= WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
520297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
521297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
522297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
523297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
524297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static void assertSettingsSatisfied(WifiNative.ScanSettings schedule,
525297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            ScanSettings settings, boolean bucketsLimited, boolean exactPeriod) {
52672c639e8b97067e948eca8be50dfea3173121090Mitchell Wills        assertTrue("bssids per scan: " + schedule.max_ap_per_scan + " /<= "
52772c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                + settings.numBssidsPerScan,
52872c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                schedule.max_ap_per_scan <= settings.numBssidsPerScan);
529297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
530297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.maxScansToCache > 0) {
53172c639e8b97067e948eca8be50dfea3173121090Mitchell Wills            assertTrue("scans to cache: " + schedule.report_threshold_num_scans + " /<= "
53272c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    + settings.maxScansToCache,
53372c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                    schedule.report_threshold_num_scans <= settings.maxScansToCache);
534297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
535297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
536297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        HashSet<Integer> channelSet = new HashSet<>();
537297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ChannelSpec channel : getAllChannels(settings)) {
538297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            channelSet.add(channel.frequency);
539297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
540297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
541297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        StringBuilder ignoreString = new StringBuilder();
542297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
543297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        HashSet<Integer> scheduleChannelSet = new HashSet<>();
544297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int b = 0; b < schedule.num_buckets; b++) {
545297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            BucketSettings bucket = schedule.buckets[b];
546297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0) {
547297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) == 0) {
548297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
549297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
550297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
551297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=after_each_scan:")
552297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)
553297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
554297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
555297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
556297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
557297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
558297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
559297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) == 0) {
560297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
561297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
562297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
563297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=full_result:")
564297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)
565297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
566297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT);
567297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
568297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
569297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
570297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) {
571297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH) != 0) {
572297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
573297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
574297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
575297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=no_batch:")
576297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH)
577297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
578297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH);
579297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
580297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
581297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
582297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int expectedPeriod;
583f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan
584f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan            if (settings.maxPeriodInMs != 0 && settings.periodInMs != settings.maxPeriodInMs) {
585f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                // exponential back off scan
586f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                expectedPeriod = settings.periodInMs;
587297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
588f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                if (bucketsLimited) {
589f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs, schedule);
590f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                } else {
591f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                    expectedPeriod = computeExpectedPeriod(settings.periodInMs);
592f935e529bdcc150dc57641f5f2ab10cd69f2e3e9Randy Pan                }
593297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
594297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
595297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (exactPeriod) {
596297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms != expectedPeriod) {
597297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
598297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
599297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(WifiChannelHelper.toString(getAllChannels(bucket)))
600297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
601297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
602297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("!=")
603297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
604297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
605297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
606297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
607297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms > expectedPeriod) {
608297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
609297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
610297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(WifiChannelHelper.toString(getAllChannels(bucket)))
611297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
612297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
613297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(">")
614297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
615297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
616297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
617297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
618297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            for (ChannelSpec channel : getAllChannels(bucket)) {
619297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                scheduleChannelSet.add(channel.frequency);
620297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
621297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
622297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
62372c639e8b97067e948eca8be50dfea3173121090Mitchell Wills        assertTrue("expected that " + scheduleChannelSet + " contained " + channelSet
62472c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                + ", Channel ignore reasons:" + ignoreString.toString(),
62572c639e8b97067e948eca8be50dfea3173121090Mitchell Wills                scheduleChannelSet.containsAll(channelSet));
626297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
627297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
628297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int[] getPredefinedBuckets() {
629297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        try {
630297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            Field f = MultiClientScheduler.class.getDeclaredField("PREDEFINED_BUCKET_PERIODS");
631297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            f.setAccessible(true);
632297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            return (int[]) f.get(null);
633297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } catch (Exception e) {
634297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            throw new RuntimeException("Could not get predefined buckets", e);
635297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
636297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
637297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int[] PREDEFINED_BUCKET_PERIODS = getPredefinedBuckets();
638297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
639297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period
640297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod) {
641297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
642297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
643297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int bucketPeriod : PREDEFINED_BUCKET_PERIODS) {
644297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
645297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
646297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
647297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
648297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
649297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
650297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
651297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
652297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
653297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period that exists in the schedule
654297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod,
655297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            WifiNative.ScanSettings schedule) {
656297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
657297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
658297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < schedule.num_buckets; ++i) {
659297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int bucketPeriod = schedule.buckets[i].period_ms;
660297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
661297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
662297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
663297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
664297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
665297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
666297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
667297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
668297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills}
669