1 /* 2 * Copyright (C) 2017 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 package com.android.car.settings.wifi; 17 18 import android.annotation.Nullable; 19 import android.content.Context; 20 import android.net.NetworkInfo; 21 import android.net.wifi.WifiConfiguration; 22 import android.net.wifi.WifiManager; 23 24 import androidx.annotation.UiThread; 25 26 import com.android.settingslib.wifi.AccessPoint; 27 import com.android.settingslib.wifi.WifiTracker; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * Manages Wifi configuration: e.g. monitors wifi states, change wifi setting etc. 34 */ 35 public class CarWifiManager implements WifiTracker.WifiListener { 36 private final Context mContext; 37 private final List<Listener> mListeners = new ArrayList<>(); 38 private boolean mStarted; 39 40 private WifiTracker mWifiTracker; 41 private WifiManager mWifiManager; 42 43 public interface Listener { 44 /** 45 * Something about wifi setting changed. 46 */ onAccessPointsChanged()47 void onAccessPointsChanged(); 48 49 /** 50 * Called when the state of Wifi has changed, the state will be one of 51 * the following. 52 * 53 * <li>{@link WifiManager#WIFI_STATE_DISABLED}</li> 54 * <li>{@link WifiManager#WIFI_STATE_ENABLED}</li> 55 * <li>{@link WifiManager#WIFI_STATE_DISABLING}</li> 56 * <li>{@link WifiManager#WIFI_STATE_ENABLING}</li> 57 * <li>{@link WifiManager#WIFI_STATE_UNKNOWN}</li> 58 * <p> 59 * 60 * @param state The new state of wifi. 61 */ onWifiStateChanged(int state)62 void onWifiStateChanged(int state); 63 } 64 CarWifiManager(Context context)65 public CarWifiManager(Context context) { 66 mContext = context; 67 mWifiManager = mContext.getSystemService(WifiManager.class); 68 mWifiTracker = new WifiTracker(context, this, true, true); 69 } 70 71 /** 72 * Adds {@link Listener}. 73 */ addListener(Listener listener)74 public boolean addListener(Listener listener) { 75 return mListeners.add(listener); 76 } 77 78 /** 79 * Removes {@link Listener}. 80 */ removeListener(Listener listener)81 public boolean removeListener(Listener listener) { 82 return mListeners.remove(listener); 83 } 84 85 /** 86 * Starts {@link CarWifiManager}. 87 * This should be called only from main thread. 88 */ 89 @UiThread start()90 public void start() { 91 if (!mStarted) { 92 mStarted = true; 93 mWifiTracker.onStart(); 94 } 95 } 96 97 /** 98 * Stops {@link CarWifiManager}. 99 * This should be called only from main thread. 100 */ 101 @UiThread stop()102 public void stop() { 103 if (mStarted) { 104 mStarted = false; 105 mWifiTracker.onStop(); 106 } 107 } 108 109 /** 110 * Destroys {@link CarWifiManager} 111 * This should only be called from main thread. 112 */ 113 @UiThread destroy()114 public void destroy() { 115 mWifiTracker.onDestroy(); 116 } 117 118 /** 119 * Returns a list of all reachable access points. 120 */ getAllAccessPoints()121 public List<AccessPoint> getAllAccessPoints() { 122 return getAccessPoints(false); 123 } 124 125 /** 126 * Returns a list of saved access points. 127 */ getSavedAccessPoints()128 public List<AccessPoint> getSavedAccessPoints() { 129 return getAccessPoints(true); 130 } 131 getAccessPoints(boolean saved)132 private List<AccessPoint> getAccessPoints(boolean saved) { 133 List<AccessPoint> accessPoints = new ArrayList<AccessPoint>(); 134 if (mWifiManager.isWifiEnabled()) { 135 for (AccessPoint accessPoint : mWifiTracker.getAccessPoints()) { 136 // ignore out of reach access points. 137 if (shouldIncludeAp(accessPoint, saved)) { 138 accessPoints.add(accessPoint); 139 } 140 } 141 } 142 return accessPoints; 143 } 144 shouldIncludeAp(AccessPoint accessPoint, boolean saved)145 private boolean shouldIncludeAp(AccessPoint accessPoint, boolean saved) { 146 return saved ? accessPoint.isReachable() && accessPoint.isSaved() 147 : accessPoint.isReachable(); 148 } 149 150 @Nullable getConnectedAccessPoint()151 public AccessPoint getConnectedAccessPoint() { 152 for (AccessPoint accessPoint : getAllAccessPoints()) { 153 if (accessPoint.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) { 154 return accessPoint; 155 } 156 } 157 return null; 158 } 159 160 /** 161 * Returns {@code true} if Wifi is enabled 162 */ isWifiEnabled()163 public boolean isWifiEnabled() { 164 return mWifiManager.isWifiEnabled(); 165 } 166 167 /** 168 * Returns {@code true} if Wifi tethering is enabled 169 */ isWifiApEnabled()170 public boolean isWifiApEnabled() { 171 return mWifiManager.isWifiApEnabled(); 172 } 173 174 /** 175 * Gets {@link WifiConfiguration} for tethering 176 */ getWifiApConfig()177 public WifiConfiguration getWifiApConfig() { 178 return mWifiManager.getWifiApConfiguration(); 179 } 180 181 /** 182 * Sets {@link WifiConfiguration} for tethering 183 */ setWifiApConfig(WifiConfiguration config)184 public void setWifiApConfig(WifiConfiguration config) { 185 mWifiManager.setWifiApConfiguration(config); 186 } 187 188 /** 189 * Gets the country code in ISO 3166 format. 190 */ getCountryCode()191 public String getCountryCode() { 192 return mWifiManager.getCountryCode(); 193 } 194 195 /** 196 * Checks if the chipset supports dual frequency band (2.4 GHz and 5 GHz). 197 */ isDualBandSupported()198 public boolean isDualBandSupported() { 199 return mWifiManager.isDualBandSupported(); 200 } 201 202 /** 203 * Check if the chipset requires conversion of 5GHz Only apBand to ANY. 204 * @return {@code true} if required, {@code false} otherwise. 205 */ isDualModeSupported()206 public boolean isDualModeSupported() { 207 return mWifiManager.isDualModeSupported(); 208 } 209 210 /** Gets the wifi state from {@link WifiManager}. */ getWifiState()211 public int getWifiState() { 212 return mWifiManager.getWifiState(); 213 } 214 215 /** Sets whether wifi is enabled. */ setWifiEnabled(boolean enabled)216 public boolean setWifiEnabled(boolean enabled) { 217 return mWifiManager.setWifiEnabled(enabled); 218 } 219 220 /** Connects to an public wifi access point. */ connectToPublicWifi(AccessPoint accessPoint, WifiManager.ActionListener listener)221 public void connectToPublicWifi(AccessPoint accessPoint, WifiManager.ActionListener listener) { 222 accessPoint.generateOpenNetworkConfig(); 223 mWifiManager.connect(accessPoint.getConfig(), listener); 224 } 225 226 /** Connects to a saved access point. */ connectToSavedWifi(AccessPoint accessPoint, WifiManager.ActionListener listener)227 public void connectToSavedWifi(AccessPoint accessPoint, WifiManager.ActionListener listener) { 228 if (accessPoint.isSaved()) { 229 mWifiManager.connect(accessPoint.getConfig(), listener); 230 } 231 } 232 233 @Override onWifiStateChanged(int state)234 public void onWifiStateChanged(int state) { 235 for (Listener listener : mListeners) { 236 listener.onWifiStateChanged(state); 237 } 238 } 239 240 @Override onConnectedChanged()241 public void onConnectedChanged() { 242 } 243 244 @Override onAccessPointsChanged()245 public void onAccessPointsChanged() { 246 for (Listener listener : mListeners) { 247 listener.onAccessPointsChanged(); 248 } 249 } 250 } 251