BackgroundScanSchedulerTest.java revision 297c3acabe7a85eb87240fe3ccf772e57ce6aef7
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
25297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static org.junit.Assert.*;
26297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport static org.mockito.Mockito.mock;
27297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
28297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner;
29297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner.ChannelSpec;
30297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.net.wifi.WifiScanner.ScanSettings;
31297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport android.test.suitebuilder.annotation.SmallTest;
32297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
33297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport com.android.server.wifi.WifiNative.BucketSettings;
34297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
35297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Before;
36297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport org.junit.Test;
37297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
38297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.lang.reflect.Field;
39297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.ArrayList;
40297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collection;
41297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Collections;
42297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.HashSet;
43297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willsimport java.util.Set;
44297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
45297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills/**
46297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills * Unit tests for {@link com.android.server.wifi.MultiClientScheduler}.
47297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills */
48297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills@SmallTest
49297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Willspublic class MultiClientSchedulerTest {
50297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
51297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int DEFAULT_MAX_BUCKETS = 8;
52297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int DEFAULT_MAX_CHANNELS = 8;
53297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int DEFAULT_MAX_BATCH = 10;
54297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int DEFAULT_MAX_AP_PER_SCAN = 11;
55297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
56297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private WifiNative mWifiNative;
57297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private MultiClientScheduler mScheduler;
58297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
59297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Before
60297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void setUp() throws Exception {
61297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mWifiNative = mock(WifiNative.class);
62297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        setupMockChannels(mWifiNative,
63297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{2400, 2450},
64297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5150, 5175},
65297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                new int[]{5600, 5650, 5660});
66297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        installWlanWifiNative(mWifiNative);
67297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
68297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler = new MultiClientScheduler();
69297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(DEFAULT_MAX_BUCKETS);
70297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(DEFAULT_MAX_CHANNELS);
71297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(DEFAULT_MAX_BATCH);
72297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxApPerScan(DEFAULT_MAX_AP_PER_SCAN);
73297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
74297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
75297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
76297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void noRequest() {
77297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.emptyList();
78297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
79297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
80297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
81297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
82297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals(60000, schedule.base_period_ms);
83297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 0);
84297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
85297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
86297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
87297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequest() {
88297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
89297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
90297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
91297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
92297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
93297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
94297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
95297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
96297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals(30000, schedule.base_period_ms);
97297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
98297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
99297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
100297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
101297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
102297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
103297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
104297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void singleRequestWithoutPredefinedBucket() {
105297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = Collections.singleton(createRequest(
106297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.WIFI_BAND_BOTH, 7500, 0, 20,
107297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
108297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ));
109297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
110297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
111297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
112297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
113297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
114297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
115297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
116297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
117297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
118297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
119297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
120297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
121297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void fewRequests() {
122297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
123297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
124297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
125297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 14000, 0, 20,
126297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
127297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
128297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
129297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
130297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
131297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
132297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
133297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
134297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
135297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
136297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
137297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
138297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
139297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequests() {
140297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
141297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
142297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
143297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 20000, 0, 20,
144297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
145297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 0, 20,
146297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
147297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
148297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
149297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
150297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
151297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
152297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
153297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
154297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, false);
155297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
156297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
157297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
158297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
159297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void requestsWithNoPeriodCommonDenominator() {
160297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
161297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_BOTH, 299999, 0, 20,
162297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
163297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10500, 0, 20,
164297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
165297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
166297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
167297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
168297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
169297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
170297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
171297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
172297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
173297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
174297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
175297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
176297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
177297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void manyRequestsDifferentReportScans() {
178297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
179297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 0, 20,
180297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
181297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30000, 0, 20,
182297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
183297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 30000, 0, 20,
184297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
185297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 30000, 0, 20,
186297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_NO_BATCH));
187297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
188297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
189297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
190297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
191297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
192297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
193297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
194297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
195297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
196297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
197297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
198297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
199297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exceedMaxBatch() {
200297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
201297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 30000, 10, 20,
202297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
203297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
204297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBatch(5);
205297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
206297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
207297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
208297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
209297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
210297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
211297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, false, true);
212297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
213297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("maxScansToCache", 5, schedule.report_threshold_num_scans);
214297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
215297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
216297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
217297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets() {
218297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
219297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30000, 0, 20,
220297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
221297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 10000, 0, 20,
222297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
223297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 60000, 0, 20,
224297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
225297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
226297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
227297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
228297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
229297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
230297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
231297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
232297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
233297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
234297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
235297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
236297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
237297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
238297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBuckets2() {
239297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
240297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 30000, 0, 20,
241297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
242297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 60000, 0, 20,
243297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
244297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 3600000, 0, 20,
245297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
246297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
247297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
248297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
249297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
250297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
251297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
252297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 2);
253297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
254297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
255297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
256297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
257297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
258297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    /**
259297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * Ensure that a channel request is placed in the bucket closest to the original
260297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * period and not the bucket it is initially placed in. Here the 21 min period is
261297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * initially placed in the 15 min bucket, but that bucket is eliminated because it
262297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * would be a 7th bucket. This test ensures that the request is placed in the 30 min
263297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     * bucket and not the 10 min bucket.
264297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills     */
265297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
266297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsNumberOfAvailableBucketsClosestToOriginal() {
267297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
268297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400), 60 * 1000, 0, 20,
269297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
270297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2450), 30 * 1000, 0, 20,
271297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
272297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5150), 300 * 1000, 0, 20,
273297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
274297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5175), 600 * 1000, 0, 20,
275297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
276297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5600), 10 * 1000, 0, 20,
277297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
278297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5650), 1800 * 1000, 0, 20,
279297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
280297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
281297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(5660), 1260 * 1000, 0, 20, // 21 min
282297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
283297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
284297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(6);
285297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
286297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
287297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
288297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 10000, schedule.base_period_ms);
289297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 6);
290297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
291297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
292297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
293297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
294297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
295297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
296297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsMaxChennelsOnSingleBand() {
297297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
298297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450), 30000, 0, 20,
299297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
300297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
301297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
302297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(1);
303297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
304297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
305297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
306297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
307297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
308297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
309297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
310297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
311297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
312297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
313297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
314297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void optimalScheduleExceedsMaxChennelsOnMultipleBands() {
315297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        ArrayList<ScanSettings> requests = new ArrayList<>();
316297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(createRequest(channelsToSpec(2400, 2450, 5150), 30000, 0, 20,
317297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
318297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
319297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxBuckets(2);
320297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.setMaxChannels(2);
321297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
322297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
323297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
324297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", 30000, schedule.base_period_ms);
325297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
326297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ScanSettings request : requests) {
327297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertSettingsSatisfied(schedule, request, true, true);
328297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
329297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
330297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
331297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    @Test
332297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void exactRequests() {
333297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0,
334297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                20, WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL));
335297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ, 60000, 3,
336297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                13, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN));
337297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, 10000, 2,
338297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT));
339297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 0,
340297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                10, WifiScanner.REPORT_EVENT_NO_BATCH));
341297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        scheduleAndTestExactRequest(createRequest(WifiScanner.WIFI_BAND_BOTH, 25000, 3,
342297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                0, WifiScanner.REPORT_EVENT_NO_BATCH));
343297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
344297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
345297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    public void scheduleAndTestExactRequest(ScanSettings settings) {
346297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Collection<ScanSettings> requests = new ArrayList<>();
347297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        requests.add(settings);
348297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
349297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        mScheduler.updateSchedule(requests);
350297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        WifiNative.ScanSettings schedule = mScheduler.getSchedule();
351297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
352297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("base_period_ms", computeExpectedPeriod(settings.periodInMs),
353297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.base_period_ms);
354297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertBuckets(schedule, 1);
355297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
356297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.numBssidsPerScan == 0) {
357297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertEquals("bssids per scan", DEFAULT_MAX_AP_PER_SCAN, schedule.max_ap_per_scan);
358297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } else {
359297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertEquals("bssids per scan", settings.numBssidsPerScan, schedule.max_ap_per_scan);
360297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
361297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.maxScansToCache == 0) {
362297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertEquals("scans to cache", DEFAULT_MAX_BATCH,
363297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    schedule.report_threshold_num_scans);
364297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } else {
365297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertEquals("scans to cache", settings.maxScansToCache,
366297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    schedule.report_threshold_num_scans);
367297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
368297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("reportEvents", settings.reportEvents, schedule.buckets[0].report_events);
369297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("period", computeExpectedPeriod(settings.periodInMs),
370297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.buckets[0].period_ms);
371297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Set<Integer> expectedChannels = new HashSet<>();
372297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ChannelSpec channel : getAllChannels(settings)) {
373297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            expectedChannels.add(channel.frequency);
374297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
375297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        Set<Integer> actualChannels = new HashSet<>();
376297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ChannelSpec channel : getAllChannels(schedule.buckets[0])) {
377297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            actualChannels.add(channel.frequency);
378297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
379297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("channels", expectedChannels, actualChannels);
380297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
381297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
382297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) {
383297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets", numBuckets, schedule.num_buckets);
384297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertNotNull("buckets was null", schedule.buckets);
385297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertEquals("num_buckets and actual buckets", schedule.num_buckets,
386297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                schedule.buckets.length);
387297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < numBuckets; i++) {
388297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertNotNull("bucket[" + i + "] was null", schedule.buckets[i]);
389297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (schedule.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
390297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("num channels <= 0", schedule.buckets[i].num_channels > 0);
391297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("bucket channels > max channels",
392297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        schedule.buckets[i].num_channels <= mScheduler.getMaxChannels());
393297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertNotNull("Channels was null", schedule.buckets[i].channels);
394297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                for (int c = 0; c < schedule.buckets[i].num_channels; c++) {
395297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    assertNotNull("Channel was null", schedule.buckets[i].channels[c]);
396297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
397297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
398297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                assertTrue("Invalid band: " + schedule.buckets[i].band,
399297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                           schedule.buckets[i].band > WifiScanner.WIFI_BAND_UNSPECIFIED &&
400297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                           schedule.buckets[i].band <= WifiScanner.WIFI_BAND_BOTH_WITH_DFS);
401297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
402297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
403297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
404297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
405297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static void assertSettingsSatisfied(WifiNative.ScanSettings schedule,
406297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            ScanSettings settings, boolean bucketsLimited, boolean exactPeriod) {
407297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertTrue("bssids per scan: " + schedule.max_ap_per_scan + " /<= " +
408297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                   settings.numBssidsPerScan,
409297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                   schedule.max_ap_per_scan <= settings.numBssidsPerScan);
410297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
411297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        if (settings.maxScansToCache > 0) {
412297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            assertTrue("scans to cache: " + schedule.report_threshold_num_scans + " /<= " +
413297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                       settings.maxScansToCache,
414297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                       schedule.report_threshold_num_scans <= settings.maxScansToCache);
415297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
416297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
417297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        HashSet<Integer> channelSet = new HashSet<>();
418297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (ChannelSpec channel : getAllChannels(settings)) {
419297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            channelSet.add(channel.frequency);
420297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
421297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
422297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        StringBuilder ignoreString = new StringBuilder();
423297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
424297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        HashSet<Integer> scheduleChannelSet = new HashSet<>();
425297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int b = 0; b < schedule.num_buckets; b++) {
426297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            BucketSettings bucket = schedule.buckets[b];
427297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0) {
428297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) == 0) {
429297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
430297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
431297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
432297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=after_each_scan:")
433297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)
434297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
435297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
436297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
437297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
438297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
439297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
440297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) == 0) {
441297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
442297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
443297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
444297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=full_result:")
445297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)
446297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
447297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT);
448297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
449297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
450297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
451297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if ((settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) {
452297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if ((bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH) != 0) {
453297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
454297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(" ")
455297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(WifiChannelHelper.toString(getAllChannels(bucket)))
456297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("=no_batch:")
457297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(bucket.report_events & WifiScanner.REPORT_EVENT_NO_BATCH)
458297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append("!=")
459297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                        .append(settings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH);
460297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
461297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
462297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
463297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int expectedPeriod;
464297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (bucketsLimited) {
465297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                expectedPeriod = computeExpectedPeriod(settings.periodInMs, schedule);
466297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
467297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                expectedPeriod = computeExpectedPeriod(settings.periodInMs);
468297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
469297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
470297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (exactPeriod) {
471297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms != expectedPeriod) {
472297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
473297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
474297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(WifiChannelHelper.toString(getAllChannels(bucket)))
475297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
476297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
477297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("!=")
478297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
479297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
480297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
481297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            } else {
482297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                if (bucket.period_ms > expectedPeriod) {
483297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    ignoreString
484297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(" ")
485297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(WifiChannelHelper.toString(getAllChannels(bucket)))
486297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append("=period:")
487297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(bucket.period_ms)
488297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(">")
489297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                            .append(settings.periodInMs);
490297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                    continue;
491297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                }
492297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
493297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            for (ChannelSpec channel : getAllChannels(bucket)) {
494297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                scheduleChannelSet.add(channel.frequency);
495297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
496297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
497297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
498297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        assertTrue("expected that " + scheduleChannelSet + " contained " + channelSet +
499297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                   ", Channel ignore reasons:" + ignoreString.toString(),
500297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                   scheduleChannelSet.containsAll(channelSet));
501297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
502297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
503297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int[] getPredefinedBuckets() {
504297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        try {
505297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            Field f = MultiClientScheduler.class.getDeclaredField("PREDEFINED_BUCKET_PERIODS");
506297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            f.setAccessible(true);
507297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            return (int[]) f.get(null);
508297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        } catch (Exception e) {
509297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            throw new RuntimeException("Could not get predefined buckets", e);
510297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
511297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
512297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static final int[] PREDEFINED_BUCKET_PERIODS = getPredefinedBuckets();
513297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
514297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period
515297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod) {
516297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
517297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
518297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int bucketPeriod : PREDEFINED_BUCKET_PERIODS) {
519297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
520297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
521297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
522297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
523297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
524297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
525297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
526297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
527297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills
528297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    // find closest bucket period to the requested period that exists in the schedule
529297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    private static int computeExpectedPeriod(int requestedPeriod,
530297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            WifiNative.ScanSettings schedule) {
531297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int period = 0;
532297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        int minDiff = Integer.MAX_VALUE;
533297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        for (int i = 0; i < schedule.num_buckets; ++i) {
534297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int bucketPeriod = schedule.buckets[i].period_ms;
535297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            int diff = Math.abs(bucketPeriod - requestedPeriod);
536297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            if (diff < minDiff) {
537297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                minDiff = diff;
538297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills                period = bucketPeriod;
539297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills            }
540297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        }
541297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        return period;
542297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills    }
543297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills}
544