1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.scanner; 18 19import android.net.wifi.WifiScanner; 20import android.util.ArraySet; 21 22import com.android.server.wifi.WifiNative; 23 24import java.util.Set; 25 26/** 27 * ChannelHelper that offers channel manipulation utilities when the channels in a band are not 28 * known. Operations performed may simplify any band to include all channels. 29 */ 30public class NoBandChannelHelper extends ChannelHelper { 31 32 /** 33 * These parameters are used to estimate the scan duration. 34 * This is a guess at the number of channels the device supports for use when a ScanSettings 35 * specifies a band instead of a list of channels. 36 */ 37 private static final int ALL_BAND_CHANNEL_COUNT_ESTIMATE = 36; 38 39 @Override 40 public boolean settingsContainChannel(WifiScanner.ScanSettings settings, int channel) { 41 if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 42 for (int i = 0; i < settings.channels.length; ++i) { 43 if (settings.channels[i].frequency == channel) { 44 return true; 45 } 46 } 47 return false; 48 } else { 49 return true; 50 } 51 } 52 53 @Override 54 public WifiScanner.ChannelSpec[] getAvailableScanChannels(int band) { 55 return NO_CHANNELS; // not supported 56 } 57 58 @Override 59 public int estimateScanDuration(WifiScanner.ScanSettings settings) { 60 if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 61 return settings.channels.length * SCAN_PERIOD_PER_CHANNEL_MS; 62 } else { 63 return ALL_BAND_CHANNEL_COUNT_ESTIMATE * SCAN_PERIOD_PER_CHANNEL_MS; 64 } 65 } 66 67 /** 68 * ChannelCollection that merges channels without knowing which channels are in each band. In 69 * order to do this if any band is added or the maxChannels is exceeded then all channels will 70 * be included. 71 */ 72 public class NoBandChannelCollection extends ChannelCollection { 73 private final ArraySet<Integer> mChannels = new ArraySet<Integer>(); 74 private boolean mAllChannels = false; 75 76 @Override 77 public void addChannel(int frequency) { 78 mChannels.add(frequency); 79 } 80 81 @Override 82 public void addBand(int band) { 83 if (band != WifiScanner.WIFI_BAND_UNSPECIFIED) { 84 mAllChannels = true; 85 } 86 } 87 88 @Override 89 public boolean containsChannel(int channel) { 90 return mAllChannels || mChannels.contains(channel); 91 } 92 93 @Override 94 public boolean containsBand(int band) { 95 if (band != WifiScanner.WIFI_BAND_UNSPECIFIED) { 96 return mAllChannels; 97 } 98 return false; 99 } 100 101 @Override 102 public boolean partiallyContainsBand(int band) { 103 // We don't need to partially collapse settings in wificond scanner because we 104 // don't have any limitation on the number of channels that can be scanned. We also 105 // don't currently keep track of bands very well in NoBandChannelHelper. 106 return false; 107 } 108 109 @Override 110 public boolean isEmpty() { 111 return !mAllChannels && mChannels.isEmpty(); 112 } 113 114 @Override 115 public boolean isAllChannels() { 116 return mAllChannels; 117 } 118 119 @Override 120 public void clear() { 121 mAllChannels = false; 122 mChannels.clear(); 123 } 124 125 @Override 126 public Set<Integer> getMissingChannelsFromBand(int band) { 127 // We don't need to partially collapse settings in wificond scanner because we 128 // don't have any limitation on the number of channels that can be scanned. We also 129 // don't currently keep track of bands very well in NoBandChannelHelper. 130 return new ArraySet<Integer>(); 131 } 132 133 @Override 134 public Set<Integer> getContainingChannelsFromBand(int band) { 135 // We don't need to partially collapse settings in wificond scanner because we 136 // don't have any limitation on the number of channels that can be scanned. We also 137 // don't currently keep track of bands very well in NoBandChannelHelper. 138 return new ArraySet<Integer>(); 139 } 140 141 @Override 142 public Set<Integer> getChannelSet() { 143 if (!isEmpty() && !mAllChannels) { 144 return mChannels; 145 } else { 146 return new ArraySet<>(); 147 } 148 } 149 150 @Override 151 public void fillBucketSettings(WifiNative.BucketSettings bucketSettings, int maxChannels) { 152 if (mAllChannels || mChannels.size() > maxChannels) { 153 bucketSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; 154 bucketSettings.num_channels = 0; 155 bucketSettings.channels = null; 156 } else { 157 bucketSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 158 bucketSettings.num_channels = mChannels.size(); 159 bucketSettings.channels = new WifiNative.ChannelSettings[mChannels.size()]; 160 for (int i = 0; i < mChannels.size(); ++i) { 161 WifiNative.ChannelSettings channelSettings = new WifiNative.ChannelSettings(); 162 channelSettings.frequency = mChannels.valueAt(i); 163 bucketSettings.channels[i] = channelSettings; 164 } 165 } 166 } 167 168 @Override 169 public Set<Integer> getScanFreqs() { 170 if (mAllChannels) { 171 return null; 172 } else { 173 return new ArraySet<Integer>(mChannels); 174 } 175 } 176 } 177 178 @Override 179 public ChannelCollection createChannelCollection() { 180 return new NoBandChannelCollection(); 181 } 182} 183