• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.car.settings.wifi;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.net.wifi.SoftApConfiguration;
22 import android.net.wifi.WifiManager;
23 import android.os.Handler;
24 import android.os.HandlerThread;
25 import android.os.Looper;
26 
27 import androidx.annotation.MainThread;
28 import androidx.lifecycle.Lifecycle;
29 import androidx.lifecycle.LifecycleObserver;
30 import androidx.lifecycle.OnLifecycleEvent;
31 
32 import com.android.wifitrackerlib.WifiEntry;
33 import com.android.wifitrackerlib.WifiPickerTracker;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.concurrent.Executor;
38 
39 /**
40  * Manages Wifi configuration: e.g. monitors wifi states, change wifi setting etc.
41  */
42 public class CarWifiManager implements WifiPickerTracker.WifiPickerTrackerCallback,
43         LifecycleObserver {
44     private static final String TAG = "CarWifiManager";
45 
46     private final Context mContext;
47     private final Lifecycle mLifecycle;
48     private final List<Listener> mListeners = new ArrayList<>();
49 
50     private HandlerThread mWorkerThread;
51     private WifiPickerTracker mWifiTracker;
52     private WifiManager mWifiManager;
53 
54     public interface Listener {
55         /**
56          * Something about wifi setting changed.
57          */
onWifiEntriesChanged()58         void onWifiEntriesChanged();
59 
60         /**
61          * Called when the state of Wifi has changed, the state will be one of
62          * the following.
63          *
64          * <li>{@link WifiManager#WIFI_STATE_DISABLED}</li>
65          * <li>{@link WifiManager#WIFI_STATE_ENABLED}</li>
66          * <li>{@link WifiManager#WIFI_STATE_DISABLING}</li>
67          * <li>{@link WifiManager#WIFI_STATE_ENABLING}</li>
68          * <li>{@link WifiManager#WIFI_STATE_UNKNOWN}</li>
69          * <p>
70          *
71          * @param state The new state of wifi.
72          */
onWifiStateChanged(int state)73         void onWifiStateChanged(int state);
74     }
75 
CarWifiManager(Context context, Lifecycle lifecycle)76     public CarWifiManager(Context context, Lifecycle lifecycle) {
77         mContext = context;
78         mLifecycle = lifecycle;
79         mLifecycle.addObserver(this);
80         mWifiManager = mContext.getSystemService(WifiManager.class);
81         mWorkerThread = new HandlerThread(TAG
82                 + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
83                 android.os.Process.THREAD_PRIORITY_BACKGROUND);
84         mWorkerThread.start();
85         mWifiTracker = WifiUtil.createWifiPickerTracker(lifecycle, context,
86                 new Handler(Looper.getMainLooper()), mWorkerThread.getThreadHandler(),
87                 /* listener= */ this);
88     }
89 
90     /**
91      * Lifecycle method to clean up worker thread on destroy.
92      */
93     @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
94     @MainThread
onDestroy()95     public void onDestroy() {
96         if (mWorkerThread != null) {
97             mWorkerThread.quit();
98         }
99         mLifecycle.removeObserver(this);
100     }
101 
102     /**
103      * Adds {@link Listener}.
104      */
addListener(Listener listener)105     public boolean addListener(Listener listener) {
106         return mListeners.add(listener);
107     }
108 
109     /**
110      * Removes {@link Listener}.
111      */
removeListener(Listener listener)112     public boolean removeListener(Listener listener) {
113         return mListeners.remove(listener);
114     }
115 
116     /**
117      * Returns the currently connected Wi-Fi entry or {@code null} if there is no Wi-Fi
118      * network connected.
119      */
120     @Nullable
getConnectedWifiEntry()121     public WifiEntry getConnectedWifiEntry() {
122         if (mWifiManager.isWifiEnabled()) {
123             return mWifiTracker.getConnectedWifiEntry();
124         }
125         return null;
126     }
127 
128     /**
129      * Returns a list of all reachable Wi-Fi entries, not including the connected Wi-Fi entry.
130      */
getAllWifiEntries()131     public List<WifiEntry> getAllWifiEntries() {
132         return getWifiEntries(false);
133     }
134 
135     /**
136      * Returns a list of saved Wi-Fi entries, not including the connected Wi-Fi entry.
137      */
getSavedWifiEntries()138     public List<WifiEntry> getSavedWifiEntries() {
139         return getWifiEntries(true);
140     }
141 
getWifiEntries(boolean onlySaved)142     private List<WifiEntry> getWifiEntries(boolean onlySaved) {
143         List<WifiEntry> wifiEntries = new ArrayList<WifiEntry>();
144         if (mWifiManager.isWifiEnabled()) {
145             for (WifiEntry wifiEntry : mWifiTracker.getWifiEntries()) {
146                 // ignore out of reach Wi-Fi entries.
147                 if (shouldIncludeWifiEntry(wifiEntry, onlySaved)) {
148                     wifiEntries.add(wifiEntry);
149                 }
150             }
151         }
152         return wifiEntries;
153     }
154 
shouldIncludeWifiEntry(WifiEntry wifiEntry, boolean onlySaved)155     private boolean shouldIncludeWifiEntry(WifiEntry wifiEntry, boolean onlySaved) {
156         boolean reachable = wifiEntry.getLevel() != WifiEntry.WIFI_LEVEL_UNREACHABLE;
157         return onlySaved
158                 ? reachable && wifiEntry.isSaved()
159                 : reachable;
160     }
161 
162     /**
163      * Returns {@code true} if Wifi is enabled
164      */
isWifiEnabled()165     public boolean isWifiEnabled() {
166         return mWifiManager.isWifiEnabled();
167     }
168 
169     /**
170      * Returns {@code true} if Wifi tethering is enabled
171      */
isWifiApEnabled()172     public boolean isWifiApEnabled() {
173         return mWifiManager.isWifiApEnabled();
174     }
175 
176     /**
177      * Gets {@link SoftApConfiguration} for tethering
178      */
getSoftApConfig()179     public SoftApConfiguration getSoftApConfig() {
180         return mWifiManager.getSoftApConfiguration();
181     }
182 
183     /**
184      * Sets {@link SoftApConfiguration} for tethering
185      */
setSoftApConfig(SoftApConfiguration config)186     public void setSoftApConfig(SoftApConfiguration config) {
187         mWifiManager.setSoftApConfiguration(config);
188     }
189 
190     /**
191      * Gets the country code in ISO 3166 format.
192      */
getCountryCode()193     public String getCountryCode() {
194         return mWifiManager.getCountryCode();
195     }
196 
197     /**
198      * Checks if the chipset supports 5GHz frequency band.
199      */
is5GhzBandSupported()200     public boolean is5GhzBandSupported() {
201         return mWifiManager.is5GHzBandSupported();
202     }
203 
204     /** Gets the wifi state from {@link WifiManager}. */
getWifiState()205     public int getWifiState() {
206         return mWifiManager.getWifiState();
207     }
208 
209     /** Sets whether wifi is enabled. */
setWifiEnabled(boolean enabled)210     public boolean setWifiEnabled(boolean enabled) {
211         return mWifiManager.setWifiEnabled(enabled);
212     }
213 
214     /** Adds callback for Soft AP */
registerSoftApCallback(Executor executor, WifiManager.SoftApCallback callback)215     public void registerSoftApCallback(Executor executor, WifiManager.SoftApCallback callback) {
216         mWifiManager.registerSoftApCallback(executor, callback);
217     }
218 
219     /** Removes callback for Soft AP */
unregisterSoftApCallback(WifiManager.SoftApCallback callback)220     public void unregisterSoftApCallback(WifiManager.SoftApCallback callback) {
221         mWifiManager.unregisterSoftApCallback(callback);
222     }
223 
224     @Override
onWifiEntriesChanged()225     public void onWifiEntriesChanged() {
226         for (Listener listener : mListeners) {
227             listener.onWifiEntriesChanged();
228         }
229     }
230 
231     @Override
onNumSavedNetworksChanged()232     public void onNumSavedNetworksChanged() {
233     }
234 
235     @Override
onNumSavedSubscriptionsChanged()236     public void onNumSavedSubscriptionsChanged() {
237     }
238 
239     @Override
onWifiStateChanged()240     public void onWifiStateChanged() {
241         int state = mWifiTracker.getWifiState();
242         for (Listener listener : mListeners) {
243             listener.onWifiStateChanged(state);
244         }
245     }
246 }
247