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 supplicant 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 void clear() { 116 mAllChannels = false; 117 mChannels.clear(); 118 } 119 120 @Override 121 public Set<Integer> getMissingChannelsFromBand(int band) { 122 // We don't need to partially collapse settings in supplicant scanner because we 123 // don't have any limitation on the number of channels that can be scanned. We also 124 // don't currently keep track of bands very well in NoBandChannelHelper. 125 return new ArraySet<Integer>(); 126 } 127 128 @Override 129 public Set<Integer> getContainingChannelsFromBand(int band) { 130 // We don't need to partially collapse settings in supplicant scanner because we 131 // don't have any limitation on the number of channels that can be scanned. We also 132 // don't currently keep track of bands very well in NoBandChannelHelper. 133 return new ArraySet<Integer>(); 134 } 135 136 @Override 137 public Set<Integer> getChannelSet() { 138 if (!isEmpty() && !mAllChannels) { 139 return mChannels; 140 } else { 141 return new ArraySet<>(); 142 } 143 } 144 145 @Override 146 public void fillBucketSettings(WifiNative.BucketSettings bucketSettings, int maxChannels) { 147 if (mAllChannels || mChannels.size() > maxChannels) { 148 bucketSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; 149 bucketSettings.num_channels = 0; 150 bucketSettings.channels = null; 151 } else { 152 bucketSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 153 bucketSettings.num_channels = mChannels.size(); 154 bucketSettings.channels = new WifiNative.ChannelSettings[mChannels.size()]; 155 for (int i = 0; i < mChannels.size(); ++i) { 156 WifiNative.ChannelSettings channelSettings = new WifiNative.ChannelSettings(); 157 channelSettings.frequency = mChannels.valueAt(i); 158 bucketSettings.channels[i] = channelSettings; 159 } 160 } 161 } 162 163 @Override 164 public Set<Integer> getSupplicantScanFreqs() { 165 if (mAllChannels) { 166 return null; 167 } else { 168 return new ArraySet<Integer>(mChannels); 169 } 170 } 171 } 172 173 @Override 174 public ChannelCollection createChannelCollection() { 175 return new NoBandChannelCollection(); 176 } 177} 178