WifiInjector.java revision fe3e7f39c4acf1517b31d6ff7123d075c1e6de25
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;
18
19import android.content.Context;
20import android.net.ConnectivityManager;
21import android.net.wifi.IApInterface;
22import android.net.wifi.IWifiScanner;
23import android.net.wifi.IWificond;
24import android.net.wifi.WifiScanner;
25import android.os.HandlerThread;
26import android.os.IBinder;
27import android.os.INetworkManagementService;
28import android.os.ServiceManager;
29import android.os.SystemProperties;
30import android.os.UserHandle;
31import android.os.UserManager;
32import android.provider.Settings;
33import android.security.KeyStore;
34import android.telephony.TelephonyManager;
35
36import com.android.internal.R;
37import com.android.server.am.BatteryStatsService;
38import com.android.server.net.DelayedDiskWrite;
39import com.android.server.net.IpConfigStore;
40
41import java.util.ArrayList;
42
43/**
44 *  WiFi dependency injector. To be used for accessing various WiFi class instances and as a
45 *  handle for mock injection.
46 *
47 *  Some WiFi class instances currently depend on having a Looper from a HandlerThread that has
48 *  been started. To accommodate this, we have a two-phased approach to initialize and retrieve
49 *  an instance of the WifiInjector.
50 */
51public class WifiInjector {
52    private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
53    private static final String WIFICOND_SERVICE_NAME = "wificond";
54
55    static WifiInjector sWifiInjector = null;
56
57    private final Context mContext;
58    private final FrameworkFacade mFrameworkFacade = new FrameworkFacade();
59    private final HandlerThread mWifiServiceHandlerThread;
60    private final HandlerThread mWifiStateMachineHandlerThread;
61    private final WifiTrafficPoller mTrafficPoller;
62    private final WifiCountryCode mCountryCode;
63    private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy();
64    private final WifiNative mWifiNative;
65    private final WifiStateMachine mWifiStateMachine;
66    private final WifiSettingsStore mSettingsStore;
67    private final WifiCertManager mCertManager;
68    private final WifiNotificationController mNotificationController;
69    private final WifiLockManager mLockManager;
70    private final WifiController mWifiController;
71    private final Clock mClock = new Clock();
72    private final WifiMetrics mWifiMetrics = new WifiMetrics(mClock);
73    private final WifiLastResortWatchdog mWifiLastResortWatchdog;
74    private final PropertyService mPropertyService = new SystemPropertyService();
75    private final BuildProperties mBuildProperties = new SystemBuildProperties();
76    private final KeyStore mKeyStore = KeyStore.getInstance();
77    private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
78    private final WifiMulticastLockManager mWifiMulticastLockManager;
79    private final WifiConfigStore mWifiConfigStore;
80    private final WifiKeyStore mWifiKeyStore;
81    private final WifiNetworkHistory mWifiNetworkHistory;
82    private final WifiSupplicantControl mWifiSupplicantControl;
83    private final IpConfigStore mIpConfigStore;
84    private final WifiConfigStoreLegacy mWifiConfigStoreLegacy;
85    private final WifiConfigManager mWifiConfigManager;
86    private final WifiNetworkSelector mWifiNetworkSelector;
87    private WifiScanner mWifiScanner;
88
89    private final boolean mUseRealLogger;
90
91    public WifiInjector(Context context) {
92        if (context == null) {
93            throw new IllegalStateException(
94                    "WifiInjector should not be initialized with a null Context.");
95        }
96
97        if (sWifiInjector != null) {
98            throw new IllegalStateException(
99                    "WifiInjector was already created, use getInstance instead.");
100        }
101
102        sWifiInjector = this;
103
104        mContext = context;
105        mUseRealLogger = mContext.getResources().getBoolean(
106                R.bool.config_wifi_enable_wifi_firmware_debugging);
107
108        // Now create and start handler threads
109        mWifiServiceHandlerThread = new HandlerThread("WifiService");
110        mWifiServiceHandlerThread.start();
111        mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
112        mWifiStateMachineHandlerThread.start();
113
114        // Now get instances of all the objects that depend on the HandlerThreads
115        mTrafficPoller =  new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
116                WifiNative.getWlanNativeInterface().getInterfaceName());
117        mCountryCode = new WifiCountryCode(WifiNative.getWlanNativeInterface(),
118                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
119                mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
120                mContext.getResources()
121                        .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
122        mWifiNative = WifiNative.getWlanNativeInterface();
123
124        // WifiConfigManager/Store objects and their dependencies.
125        // New config store
126        mWifiKeyStore = new WifiKeyStore(mKeyStore);
127        mWifiConfigStore = new WifiConfigStore(
128                mContext, mWifiStateMachineHandlerThread.getLooper(), mClock,
129                WifiConfigStore.createSharedFile(),
130                WifiConfigStore.createUserFile(UserHandle.USER_SYSTEM));
131        // Legacy config store
132        DelayedDiskWrite writer = new DelayedDiskWrite();
133        mWifiNetworkHistory = new WifiNetworkHistory(mContext, mWifiNative.getLocalLog(), writer);
134        mWifiSupplicantControl = new WifiSupplicantControl(
135                TelephonyManager.from(mContext), mWifiNative, mWifiNative.getLocalLog());
136        mIpConfigStore = new IpConfigStore(writer);
137        mWifiConfigStoreLegacy = new WifiConfigStoreLegacy(
138                mWifiNetworkHistory, mWifiSupplicantControl, mIpConfigStore);
139        // Config Manager
140        mWifiConfigManager = new WifiConfigManager(mContext, mFrameworkFacade, mClock,
141                UserManager.get(mContext), TelephonyManager.from(mContext),
142                mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy);
143        mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiConfigManager, mClock);
144
145        mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade,
146                mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext),
147                this, mBackupManagerProxy, mCountryCode, mWifiNative);
148        mSettingsStore = new WifiSettingsStore(mContext);
149        mCertManager = new WifiCertManager(mContext);
150        mNotificationController = new WifiNotificationController(mContext,
151                mWifiServiceHandlerThread.getLooper(), mWifiStateMachine,
152                mFrameworkFacade, null, this);
153        mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
154        mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
155                mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
156        mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
157        mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine,
158                BatteryStatsService.getService());
159    }
160
161    /**
162     *  Obtain an instance of the WifiInjector class.
163     *
164     *  This is the generic method to get an instance of the class. The first instance should be
165     *  retrieved using the getInstanceWithContext method.
166     */
167    public static WifiInjector getInstance() {
168        if (sWifiInjector == null) {
169            throw new IllegalStateException(
170                    "Attempted to retrieve a WifiInjector instance before constructor was called.");
171        }
172        return sWifiInjector;
173    }
174
175    public WifiMetrics getWifiMetrics() {
176        return mWifiMetrics;
177    }
178
179    public BackupManagerProxy getBackupManagerProxy() {
180        return mBackupManagerProxy;
181    }
182
183    public FrameworkFacade getFrameworkFacade() {
184        return mFrameworkFacade;
185    }
186
187    public HandlerThread getWifiServiceHandlerThread() {
188        return mWifiServiceHandlerThread;
189    }
190
191    public HandlerThread getWifiStateMachineHandlerThread() {
192        return mWifiStateMachineHandlerThread;
193    }
194
195    public WifiTrafficPoller getWifiTrafficPoller() {
196        return mTrafficPoller;
197    }
198
199    public WifiCountryCode getWifiCountryCode() {
200        return mCountryCode;
201    }
202
203    public WifiStateMachine getWifiStateMachine() {
204        return mWifiStateMachine;
205    }
206
207    public WifiSettingsStore getWifiSettingsStore() {
208        return mSettingsStore;
209    }
210
211    public WifiCertManager getWifiCertManager() {
212        return mCertManager;
213    }
214
215    public WifiNotificationController getWifiNotificationController() {
216        return mNotificationController;
217    }
218
219    public WifiLockManager getWifiLockManager() {
220        return mLockManager;
221    }
222
223    public WifiController getWifiController() {
224        return mWifiController;
225    }
226
227    public WifiLastResortWatchdog getWifiLastResortWatchdog() {
228        return mWifiLastResortWatchdog;
229    }
230
231    public Clock getClock() {
232        return mClock;
233    }
234
235    public PropertyService getPropertyService() {
236        return mPropertyService;
237    }
238
239    public BuildProperties getBuildProperties() {
240        return mBuildProperties;
241    }
242
243    public KeyStore getKeyStore() {
244        return mKeyStore;
245    }
246
247    public WifiBackupRestore getWifiBackupRestore() {
248        return mWifiBackupRestore;
249    }
250
251    public WifiMulticastLockManager getWifiMulticastLockManager() {
252        return mWifiMulticastLockManager;
253    }
254
255    public WifiSupplicantControl getWifiSupplicantControl() {
256        return mWifiSupplicantControl;
257    }
258
259    public WifiConfigManager getWifiConfigManager() {
260        return mWifiConfigManager;
261    }
262
263    public TelephonyManager makeTelephonyManager() {
264        // may not be available when WiFi starts
265        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
266    }
267
268    public IWificond makeWificond() {
269        // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
270        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
271        return IWificond.Stub.asInterface(binder);
272    }
273
274    /**
275     * Create a SoftApManager.
276     * @param wifiNative reference to WifiNative
277     * @param nmService reference to NetworkManagementService
278     * @param cm reference to ConnectivityManager
279     * @param countryCode Country code
280     * @param allowed2GChannels list of allowed 2G channels
281     * @param listener listener for SoftApManager
282     * @param apInterface network interface to start hostapd against
283     * @return an instance of SoftApManager
284     */
285    public SoftApManager makeSoftApManager(
286            WifiNative wifiNative,
287            INetworkManagementService nmService, ConnectivityManager cm,
288            String countryCode, ArrayList<Integer> allowed2GChannels,
289            SoftApManager.Listener listener, IApInterface apInterface) {
290        return new SoftApManager(
291                mWifiServiceHandlerThread.getLooper(),
292                wifiNative, countryCode,
293                allowed2GChannels, listener, apInterface,
294                nmService);
295    }
296
297    /**
298     * Create a WifiLog instance.
299     * @param tag module name to include in all log messages
300     */
301    public WifiLog makeLog(String tag) {
302        return new LogcatLog(tag);
303    }
304
305    public BaseWifiDiagnostics makeWifiDiagnostics(WifiNative wifiNative) {
306        if (mUseRealLogger) {
307            return new WifiDiagnostics(
308                    mContext, this, mWifiStateMachine, wifiNative, mBuildProperties);
309        } else {
310            return new BaseWifiDiagnostics();
311        }
312    }
313
314    /**
315     * Obtain an instance of WifiScanner.
316     * If it was not already created, then obtain an instance.  Note, this must be done lazily since
317     * WifiScannerService is separate and created later.
318     */
319    public synchronized WifiScanner getWifiScanner() {
320        if (mWifiScanner == null) {
321            mWifiScanner = new WifiScanner(mContext,
322                    IWifiScanner.Stub.asInterface(ServiceManager.getService(
323                            Context.WIFI_SCANNING_SERVICE)),
324                    mWifiStateMachineHandlerThread.getLooper());
325        }
326        return mWifiScanner;
327    }
328
329    /**
330     * Obtain an instance of WifiNetworkSelector.
331     */
332    public WifiNetworkSelector getWifiNetworkSelector() {
333        return mWifiNetworkSelector;
334    }
335}
336