1712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills/*
2712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * Copyright (C) 2016 The Android Open Source Project
3712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills *
4712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * Licensed under the Apache License, Version 2.0 (the "License");
5712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * you may not use this file except in compliance with the License.
6712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * You may obtain a copy of the License at
7712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills *
8712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills *      http://www.apache.org/licenses/LICENSE-2.0
9712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills *
10712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * Unless required by applicable law or agreed to in writing, software
11712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * distributed under the License is distributed on an "AS IS" BASIS,
12712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * See the License for the specific language governing permissions and
14712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * limitations under the License.
15712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills */
16712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
17712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Willspackage com.android.server.wifi.scanner;
18712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
19712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Willsimport android.net.wifi.WifiScanner;
20712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Willsimport android.util.ArraySet;
21712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
22712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Willsimport com.android.server.wifi.WifiNative;
23712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
2439175cc807488dd849e2c530f8be30dd674fbd9fMitchell Willsimport java.util.Set;
2539175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills
26712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills/**
27712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * ChannelHelper that offers channel manipulation utilities when the channels in a band are known.
28712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills * This allows more fine operations on channels than if band channels are not known.
29712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills */
30712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Willspublic class KnownBandsChannelHelper extends ChannelHelper {
31712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
32712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    private WifiScanner.ChannelSpec[][] mBandsToChannels;
33712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
34e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills    protected void setBandChannels(int[] channels2G, int[] channels5G, int[] channelsDfs) {
35712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels = new WifiScanner.ChannelSpec[8][];
36712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
37712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[0] = NO_CHANNELS;
38712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
39712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[1] = new WifiScanner.ChannelSpec[channels2G.length];
40712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[1], 0, channels2G);
41712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
42712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[2] = new WifiScanner.ChannelSpec[channels5G.length];
43712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[2], 0, channels5G);
44712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
45712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[3] = new WifiScanner.ChannelSpec[channels2G.length + channels5G.length];
46712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[3], 0, channels2G);
47712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[3], channels2G.length, channels5G);
48712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
49712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[4] = new WifiScanner.ChannelSpec[channelsDfs.length];
50712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[4], 0, channelsDfs);
51712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
52712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[5] = new WifiScanner.ChannelSpec[channels2G.length + channelsDfs.length];
53712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[5], 0, channels2G);
54712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[5], channels2G.length, channelsDfs);
55712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
56712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[6] = new WifiScanner.ChannelSpec[channels5G.length + channelsDfs.length];
57712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[6], 0, channels5G);
58712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[6], channels5G.length, channelsDfs);
59712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
60712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        mBandsToChannels[7] = new WifiScanner.ChannelSpec[
61712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                channels2G.length + channels5G.length + channelsDfs.length];
62712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[7], 0, channels2G);
63712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[7], channels2G.length, channels5G);
64712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        copyChannels(mBandsToChannels[7], channels2G.length + channels5G.length, channelsDfs);
65712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
66712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
67712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    private static void copyChannels(
68712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            WifiScanner.ChannelSpec[] channelSpec, int offset, int[] channels) {
69712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        for (int i = 0; i < channels.length; i++) {
70712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            channelSpec[offset + i] = new WifiScanner.ChannelSpec(channels[i]);
71712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
72712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
73712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
74798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills    @Override
75798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills    public WifiScanner.ChannelSpec[] getAvailableScanChannels(int band) {
76712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        if (band < WifiScanner.WIFI_BAND_24_GHZ || band > WifiScanner.WIFI_BAND_BOTH_WITH_DFS) {
77712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            // invalid value for band
78712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return NO_CHANNELS;
79712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        } else {
80712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return mBandsToChannels[band];
81712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
82712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
83712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
84798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills    @Override
85798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills    public int estimateScanDuration(WifiScanner.ScanSettings settings) {
86798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills        if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
87798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills            return settings.channels.length * SCAN_PERIOD_PER_CHANNEL_MS;
88798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills        } else {
89798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills            return getAvailableScanChannels(settings.band).length * SCAN_PERIOD_PER_CHANNEL_MS;
90798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills        }
91798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills    }
92798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills
93712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    private boolean isDfsChannel(int frequency) {
94712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        for (WifiScanner.ChannelSpec dfsChannel :
95712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                mBandsToChannels[WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY]) {
96712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            if (frequency == dfsChannel.frequency) {
97712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                return true;
98712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            }
99712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
100712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        return false;
101712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
102712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
10339175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills    // TODO this should be rewritten to be based on the input data instead of hardcoded ranges
104712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    private int getBandFromChannel(int frequency) {
105712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        if (2400 <= frequency && frequency < 2500) {
106712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return WifiScanner.WIFI_BAND_24_GHZ;
107712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        } else if (isDfsChannel(frequency)) {
108712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
109712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        } else if (5100 <= frequency && frequency < 6000) {
110712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return WifiScanner.WIFI_BAND_5_GHZ;
111712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        } else {
112712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            return WifiScanner.WIFI_BAND_UNSPECIFIED;
113712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
114712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
115712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
11639175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills    @Override
11739175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills    public boolean settingsContainChannel(WifiScanner.ScanSettings settings, int channel) {
11839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        WifiScanner.ChannelSpec[] settingsChannels;
11939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
12039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            settingsChannels = settings.channels;
12139175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        } else {
122798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills            settingsChannels = getAvailableScanChannels(settings.band);
12339175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        }
12439175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        for (int i = 0; i < settingsChannels.length; ++i) {
12539175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            if (settingsChannels[i].frequency == channel) {
12639175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills                return true;
12739175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            }
12839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        }
12939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        return false;
13039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills    }
13139175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills
132712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    /**
133712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills     * ChannelCollection that merges channels so that the optimal schedule will be generated.
134712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills     * When the max channels value is satisfied this implementation will always create a channel
135712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills     * list that includes no more than the added channels.
136712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills     */
137712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    public class KnownBandsChannelCollection extends ChannelCollection {
13839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        /**
13939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         * Stores all channels, including those that belong to added bands.
14039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         */
141712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        private final ArraySet<Integer> mChannels = new ArraySet<Integer>();
14239175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        /**
14339175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         * Contains only the bands that were explicitly added as bands.
14439175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         */
145712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        private int mExactBands = 0;
14639175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        /**
14739175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         * Contains all bands, including those that were added because an added channel was in that
14839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         * band.
14939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills         */
150712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        private int mAllBands = 0;
151712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
152712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        @Override
153712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public void addChannel(int frequency) {
154712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mChannels.add(frequency);
155712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mAllBands |= getBandFromChannel(frequency);
156712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
157712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
158712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        @Override
159712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public void addBand(int band) {
160712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mExactBands |= band;
161712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mAllBands |= band;
162798a997d2e5bf8b3278bfeaa7ca841394e2db4b9Mitchell Wills            WifiScanner.ChannelSpec[] bandChannels = getAvailableScanChannels(band);
163712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            for (int i = 0; i < bandChannels.length; ++i) {
164712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                mChannels.add(bandChannels[i].frequency);
165712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            }
166712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
167712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
168712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        @Override
16939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        public boolean containsChannel(int channel) {
17039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            return mChannels.contains(channel);
17139175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        }
17239175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills
17339175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        @Override
174216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        public boolean containsBand(int band) {
175216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            WifiScanner.ChannelSpec[] bandChannels = getAvailableScanChannels(band);
176216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            for (int i = 0; i < bandChannels.length; ++i) {
177216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                if (!mChannels.contains(bandChannels[i].frequency)) {
178216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                    return false;
179216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                }
180216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            }
181216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            return true;
182216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
183216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
184216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        @Override
185216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        public boolean partiallyContainsBand(int band) {
186216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            WifiScanner.ChannelSpec[] bandChannels = getAvailableScanChannels(band);
187216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            for (int i = 0; i < bandChannels.length; ++i) {
188216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                if (mChannels.contains(bandChannels[i].frequency)) {
189216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                    return true;
190216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                }
191216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            }
192216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            return false;
193216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
194216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
195216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        @Override
19639175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        public boolean isEmpty() {
19739175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            return mChannels.isEmpty();
19839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        }
19939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills
20039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        @Override
2013219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        public boolean isAllChannels() {
2023219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills            return getAvailableScanChannels(WifiScanner.WIFI_BAND_BOTH_WITH_DFS).length ==
2033219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                    mChannels.size();
2043219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        }
2053219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills
2063219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        @Override
207712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public void clear() {
208712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mAllBands = 0;
209712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mExactBands = 0;
210712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            mChannels.clear();
211712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
212712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
213712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        @Override
214216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        public Set<Integer> getMissingChannelsFromBand(int band) {
215216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            ArraySet<Integer> missingChannels = new ArraySet<>();
216216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            WifiScanner.ChannelSpec[] bandChannels = getAvailableScanChannels(band);
217216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            for (int i = 0; i < bandChannels.length; ++i) {
218216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                if (!mChannels.contains(bandChannels[i].frequency)) {
219216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                    missingChannels.add(bandChannels[i].frequency);
220216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                }
221216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            }
222216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            return missingChannels;
223216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
224216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
225216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        @Override
226216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        public Set<Integer> getContainingChannelsFromBand(int band) {
227216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            ArraySet<Integer> containingChannels = new ArraySet<>();
228216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            WifiScanner.ChannelSpec[] bandChannels = getAvailableScanChannels(band);
229216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            for (int i = 0; i < bandChannels.length; ++i) {
230216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                if (mChannels.contains(bandChannels[i].frequency)) {
231216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                    containingChannels.add(bandChannels[i].frequency);
232216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                }
233216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            }
234216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            return containingChannels;
235216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
236216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
237216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        @Override
238216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        public Set<Integer> getChannelSet() {
239216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            if (!isEmpty() && mAllBands != mExactBands) {
240216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                return mChannels;
241216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            } else {
242216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius                return new ArraySet<>();
243216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius            }
244216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        }
245216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius
246216eb45e7fb44a1ba8edc156d08b532a17219f66Roshan Pius        @Override
247712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public void fillBucketSettings(WifiNative.BucketSettings bucketSettings, int maxChannels) {
248712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            if ((mChannels.size() > maxChannels || mAllBands == mExactBands)
249712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                    && mAllBands != 0) {
250712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.band = mAllBands;
251712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.num_channels = 0;
252712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.channels = null;
253712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            } else {
254712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
255712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.num_channels = mChannels.size();
256712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                bucketSettings.channels = new WifiNative.ChannelSettings[mChannels.size()];
257712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                for (int i = 0; i < mChannels.size(); ++i) {
258712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                    WifiNative.ChannelSettings channelSettings = new WifiNative.ChannelSettings();
259712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                    channelSettings.frequency = mChannels.valueAt(i);
260712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                    bucketSettings.channels[i] = channelSettings;
261712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills                }
262712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills            }
263712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        }
26439175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills
26539175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        @Override
2669dc9a8750ecd1ab25c5b4c7d17c8930ca2ffb6c3Ningyuan Wang        public Set<Integer> getScanFreqs() {
2677e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills            if (mExactBands == WifiScanner.WIFI_BAND_BOTH_WITH_DFS) {
26839175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills                return null;
26939175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            } else {
27039175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills                return new ArraySet<Integer>(mChannels);
27139175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills            }
27239175cc807488dd849e2c530f8be30dd674fbd9fMitchell Wills        }
2737e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
2747e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        public Set<Integer> getAllChannels() {
2757e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills            return new ArraySet<Integer>(mChannels);
2767e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        }
277712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
278712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills
279712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    @Override
2807e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills
2817e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills    public KnownBandsChannelCollection createChannelCollection() {
282712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        return new KnownBandsChannelCollection();
283712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills    }
284712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills}
285