WifiInjector.java revision 99d4b81a25df948c46cac9027eb111ee7a786742
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.NetworkScoreManager;
21import android.net.wifi.IApInterface;
22import android.net.wifi.IWifiScanner;
23import android.net.wifi.IWificond;
24import android.net.wifi.WifiConfiguration;
25import android.net.wifi.WifiInfo;
26import android.net.wifi.WifiNetworkScoreCache;
27import android.net.wifi.WifiScanner;
28import android.os.HandlerThread;
29import android.os.IBinder;
30import android.os.INetworkManagementService;
31import android.os.Looper;
32import android.os.ServiceManager;
33import android.os.SystemProperties;
34import android.os.UserManager;
35import android.provider.Settings;
36import android.security.KeyStore;
37import android.telephony.TelephonyManager;
38import android.util.LocalLog;
39
40import com.android.internal.R;
41import com.android.server.am.BatteryStatsService;
42import com.android.server.net.DelayedDiskWrite;
43import com.android.server.net.IpConfigStore;
44import com.android.server.wifi.hotspot2.PasspointManager;
45import com.android.server.wifi.hotspot2.PasspointNetworkEvaluator;
46import com.android.server.wifi.hotspot2.PasspointObjectFactory;
47import com.android.server.wifi.util.WifiPermissionsUtil;
48import com.android.server.wifi.util.WifiPermissionsWrapper;
49
50/**
51 *  WiFi dependency injector. To be used for accessing various WiFi class instances and as a
52 *  handle for mock injection.
53 *
54 *  Some WiFi class instances currently depend on having a Looper from a HandlerThread that has
55 *  been started. To accommodate this, we have a two-phased approach to initialize and retrieve
56 *  an instance of the WifiInjector.
57 */
58public class WifiInjector {
59    private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
60    private static final String WIFICOND_SERVICE_NAME = "wificond";
61
62    static WifiInjector sWifiInjector = null;
63
64    private final Context mContext;
65    private final FrameworkFacade mFrameworkFacade = new FrameworkFacade();
66    private final HandlerThread mWifiServiceHandlerThread;
67    private final HandlerThread mWifiStateMachineHandlerThread;
68    private final WifiTrafficPoller mTrafficPoller;
69    private final WifiCountryCode mCountryCode;
70    private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy();
71    private final WifiApConfigStore mWifiApConfigStore;
72    private final WifiNative mWifiNative;
73    private final WifiNative mWifiP2pNative;
74    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
75    private final SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
76    private final WifiVendorHal mWifiVendorHal;
77    private final WifiStateMachine mWifiStateMachine;
78    private final WifiSettingsStore mSettingsStore;
79    private final WifiCertManager mCertManager;
80    private final WifiLockManager mLockManager;
81    private final WifiController mWifiController;
82    private final WificondControl mWificondControl;
83    private final Clock mClock = new Clock();
84    private final WifiMetrics mWifiMetrics = new WifiMetrics(mClock);
85    private final WifiLastResortWatchdog mWifiLastResortWatchdog;
86    private final PropertyService mPropertyService = new SystemPropertyService();
87    private final BuildProperties mBuildProperties = new SystemBuildProperties();
88    private final KeyStore mKeyStore = KeyStore.getInstance();
89    private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
90    private final WifiMulticastLockManager mWifiMulticastLockManager;
91    private final WifiConfigStore mWifiConfigStore;
92    private final WifiKeyStore mWifiKeyStore;
93    private final WifiNetworkHistory mWifiNetworkHistory;
94    private final WifiSupplicantControl mWifiSupplicantControl;
95    private final IpConfigStore mIpConfigStore;
96    private final WifiConfigStoreLegacy mWifiConfigStoreLegacy;
97    private final WifiConfigManager mWifiConfigManager;
98    private final WifiNetworkSelector mWifiNetworkSelector;
99    private final SavedNetworkEvaluator mSavedNetworkEvaluator;
100    private final PasspointNetworkEvaluator mPasspointNetworkEvaluator;
101    private final RecommendedNetworkEvaluator mRecommendedNetworkEvaluator;
102    private final WifiNetworkScoreCache mWifiNetworkScoreCache;
103    private final NetworkScoreManager mNetworkScoreManager;
104    private WifiScanner mWifiScanner;
105    private final WifiPermissionsWrapper mWifiPermissionsWrapper;
106    private final WifiPermissionsUtil mWifiPermissionsUtil;
107    private final PasspointManager mPasspointManager;
108    private final SIMAccessor mSimAccessor;
109    private HandlerThread mWifiAwareHandlerThread;
110    private HalDeviceManager mHalDeviceManager;
111
112    private final boolean mUseRealLogger;
113
114    public WifiInjector(Context context) {
115        if (context == null) {
116            throw new IllegalStateException(
117                    "WifiInjector should not be initialized with a null Context.");
118        }
119
120        if (sWifiInjector != null) {
121            throw new IllegalStateException(
122                    "WifiInjector was already created, use getInstance instead.");
123        }
124
125        sWifiInjector = this;
126
127        mContext = context;
128        mUseRealLogger = mContext.getResources().getBoolean(
129                R.bool.config_wifi_enable_wifi_firmware_debugging);
130        mSettingsStore = new WifiSettingsStore(mContext);
131        mWifiPermissionsWrapper = new WifiPermissionsWrapper(mContext);
132        mNetworkScoreManager = mContext.getSystemService(NetworkScoreManager.class);
133        mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
134                mSettingsStore, UserManager.get(mContext), mNetworkScoreManager, this);
135
136        // Now create and start handler threads
137        mWifiServiceHandlerThread = new HandlerThread("WifiService");
138        mWifiServiceHandlerThread.start();
139        mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
140        mWifiStateMachineHandlerThread.start();
141        Looper wifiStateMachineLooper = mWifiStateMachineHandlerThread.getLooper();
142
143        // Now get instances of all the objects that depend on the HandlerThreads
144        mTrafficPoller =  new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
145                WifiNative.getWlanNativeInterface().getInterfaceName());
146        mCountryCode = new WifiCountryCode(WifiNative.getWlanNativeInterface(),
147                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
148                mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
149                mContext.getResources()
150                        .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
151        mWifiApConfigStore = new WifiApConfigStore(mContext, mBackupManagerProxy);
152
153        // Modules interacting with Native.
154        mHalDeviceManager = new HalDeviceManager();
155        mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread);
156        mSupplicantStaIfaceHal = new SupplicantStaIfaceHal(mContext, WifiMonitor.getInstance());
157        mWificondControl = new WificondControl(this);
158        mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal();
159        mWifiNative = WifiNative.getWlanNativeInterface();
160        mWifiNative.setSupplicantStaIfaceHal(mSupplicantStaIfaceHal);
161        mWifiNative.setSupplicantP2pIfaceHal(mSupplicantP2pIfaceHal);
162        mWifiNative.setWifiVendorHal(mWifiVendorHal);
163        mWifiNative.setWificondControl(mWificondControl);
164        mWifiP2pNative = WifiNative.getP2pNativeInterface();
165        mWifiP2pNative.setSupplicantStaIfaceHal(mSupplicantStaIfaceHal);
166        mWifiP2pNative.setSupplicantP2pIfaceHal(mSupplicantP2pIfaceHal);
167        mWifiP2pNative.setWifiVendorHal(mWifiVendorHal);
168        mWifiP2pNative.setWificondControl(mWificondControl);
169
170        // WifiConfigManager/Store objects and their dependencies.
171        // New config store
172        mWifiKeyStore = new WifiKeyStore(mKeyStore);
173        mWifiConfigStore = new WifiConfigStore(
174                mContext, wifiStateMachineLooper, mClock,
175                WifiConfigStore.createSharedFile());
176        // Legacy config store
177        DelayedDiskWrite writer = new DelayedDiskWrite();
178        mWifiNetworkHistory = new WifiNetworkHistory(mContext, mWifiNative.getLocalLog(), writer);
179        mWifiSupplicantControl = new WifiSupplicantControl(
180                TelephonyManager.from(mContext), mWifiNative, mWifiNative.getLocalLog());
181        mIpConfigStore = new IpConfigStore(writer);
182        mWifiConfigStoreLegacy = new WifiConfigStoreLegacy(
183                mWifiNetworkHistory, mWifiSupplicantControl, mIpConfigStore);
184        // Config Manager
185        mWifiConfigManager = new WifiConfigManager(mContext, mFrameworkFacade, mClock,
186                UserManager.get(mContext), TelephonyManager.from(mContext),
187                mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy, mWifiPermissionsWrapper,
188                new NetworkListStoreData(), new DeletedEphemeralSsidsStoreData());
189        mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext);
190        mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiConfigManager, mClock);
191        LocalLog localLog = mWifiNetworkSelector.getLocalLog();
192        mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext,
193                mWifiConfigManager, mClock, localLog, wifiStateMachineLooper, mFrameworkFacade);
194        ExternalScoreEvaluator externalScoreEvaluator = new ExternalScoreEvaluator(
195                mContext, mWifiConfigManager, mWifiNetworkScoreCache, mClock, localLog);
196        mRecommendedNetworkEvaluator = new RecommendedNetworkEvaluator(context,
197                context.getContentResolver(), wifiStateMachineLooper,
198                mFrameworkFacade, mWifiNetworkScoreCache, mNetworkScoreManager, mWifiConfigManager,
199                localLog, externalScoreEvaluator);
200        mSimAccessor = new SIMAccessor(mContext);
201        mPasspointManager = new PasspointManager(mContext, mWifiNative, mWifiKeyStore, mClock,
202                mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore);
203        mPasspointNetworkEvaluator = new PasspointNetworkEvaluator(
204                mPasspointManager, mWifiConfigManager, localLog);
205        mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade,
206                wifiStateMachineLooper, UserManager.get(mContext),
207                this, mBackupManagerProxy, mCountryCode, mWifiNative);
208        mCertManager = new WifiCertManager(mContext);
209        mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
210        mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
211                mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
212        mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
213        mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine,
214                BatteryStatsService.getService());
215    }
216
217    /**
218     *  Obtain an instance of the WifiInjector class.
219     *
220     *  This is the generic method to get an instance of the class. The first instance should be
221     *  retrieved using the getInstanceWithContext method.
222     */
223    public static WifiInjector getInstance() {
224        if (sWifiInjector == null) {
225            throw new IllegalStateException(
226                    "Attempted to retrieve a WifiInjector instance before constructor was called.");
227        }
228        return sWifiInjector;
229    }
230
231    public WifiMetrics getWifiMetrics() {
232        return mWifiMetrics;
233    }
234
235    public SupplicantStaIfaceHal getSupplicantStaIfaceHal() {
236        return mSupplicantStaIfaceHal;
237    }
238
239    public BackupManagerProxy getBackupManagerProxy() {
240        return mBackupManagerProxy;
241    }
242
243    public FrameworkFacade getFrameworkFacade() {
244        return mFrameworkFacade;
245    }
246
247    public HandlerThread getWifiServiceHandlerThread() {
248        return mWifiServiceHandlerThread;
249    }
250
251    public HandlerThread getWifiStateMachineHandlerThread() {
252        return mWifiStateMachineHandlerThread;
253    }
254
255    public WifiTrafficPoller getWifiTrafficPoller() {
256        return mTrafficPoller;
257    }
258
259    public WifiCountryCode getWifiCountryCode() {
260        return mCountryCode;
261    }
262
263    public WifiApConfigStore getWifiApConfigStore() {
264        return mWifiApConfigStore;
265    }
266
267    public WifiStateMachine getWifiStateMachine() {
268        return mWifiStateMachine;
269    }
270
271    public WifiSettingsStore getWifiSettingsStore() {
272        return mSettingsStore;
273    }
274
275    public WifiCertManager getWifiCertManager() {
276        return mCertManager;
277    }
278
279    public WifiLockManager getWifiLockManager() {
280        return mLockManager;
281    }
282
283    public WifiController getWifiController() {
284        return mWifiController;
285    }
286
287    public WifiLastResortWatchdog getWifiLastResortWatchdog() {
288        return mWifiLastResortWatchdog;
289    }
290
291    public Clock getClock() {
292        return mClock;
293    }
294
295    public PropertyService getPropertyService() {
296        return mPropertyService;
297    }
298
299    public BuildProperties getBuildProperties() {
300        return mBuildProperties;
301    }
302
303    public KeyStore getKeyStore() {
304        return mKeyStore;
305    }
306
307    public WifiBackupRestore getWifiBackupRestore() {
308        return mWifiBackupRestore;
309    }
310
311    public WifiMulticastLockManager getWifiMulticastLockManager() {
312        return mWifiMulticastLockManager;
313    }
314
315    public WifiSupplicantControl getWifiSupplicantControl() {
316        return mWifiSupplicantControl;
317    }
318
319    public WifiConfigManager getWifiConfigManager() {
320        return mWifiConfigManager;
321    }
322
323    public PasspointManager getPasspointManager() {
324        return mPasspointManager;
325    }
326
327    public TelephonyManager makeTelephonyManager() {
328        // may not be available when WiFi starts
329        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
330    }
331
332    public IWificond makeWificond() {
333        // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
334        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
335        return IWificond.Stub.asInterface(binder);
336    }
337
338    /**
339     * Create a SoftApManager.
340     * @param nmService NetworkManagementService allowing SoftApManager to listen for interface
341     * changes
342     * @param listener listener for SoftApManager
343     * @param apInterface network interface to start hostapd against
344     * @param config softAp WifiConfiguration
345     * @return an instance of SoftApManager
346     */
347    public SoftApManager makeSoftApManager(INetworkManagementService nmService,
348                                           SoftApManager.Listener listener,
349                                           IApInterface apInterface,
350                                           WifiConfiguration config) {
351        return new SoftApManager(mWifiServiceHandlerThread.getLooper(),
352                                 mWifiNative, mCountryCode.getCountryCode(),
353                                 listener, apInterface, nmService,
354                                 mWifiApConfigStore, config);
355    }
356
357    /**
358     * Create a WifiLog instance.
359     * @param tag module name to include in all log messages
360     */
361    public WifiLog makeLog(String tag) {
362        return new LogcatLog(tag);
363    }
364
365    public BaseWifiDiagnostics makeWifiDiagnostics(WifiNative wifiNative) {
366        if (mUseRealLogger) {
367            return new WifiDiagnostics(
368                    mContext, this, mWifiStateMachine, wifiNative, mBuildProperties,
369                    new LastMileLogger(this));
370        } else {
371            return new BaseWifiDiagnostics();
372        }
373    }
374
375    /**
376     * Obtain an instance of WifiScanner.
377     * If it was not already created, then obtain an instance.  Note, this must be done lazily since
378     * WifiScannerService is separate and created later.
379     */
380    public synchronized WifiScanner getWifiScanner() {
381        if (mWifiScanner == null) {
382            mWifiScanner = new WifiScanner(mContext,
383                    IWifiScanner.Stub.asInterface(ServiceManager.getService(
384                            Context.WIFI_SCANNING_SERVICE)),
385                    mWifiStateMachineHandlerThread.getLooper());
386        }
387        return mWifiScanner;
388    }
389
390    /**
391     * Obtain an instance of WifiNetworkSelector.
392     */
393    public WifiNetworkSelector getWifiNetworkSelector() {
394        return mWifiNetworkSelector;
395    }
396
397    /**
398     * Obtain a new instance of WifiConnectivityManager.
399     *
400     * Create and return a new WifiConnectivityManager.
401     * @param wifiInfo WifiInfo object for updating wifi state.
402     * @param hasConnectionRequests boolean indicating if WifiConnectivityManager to start
403     * immediately based on connection requests.
404     */
405    public WifiConnectivityManager makeWifiConnectivityManager(WifiInfo wifiInfo,
406                                                               boolean hasConnectionRequests) {
407        return new WifiConnectivityManager(mContext, mWifiStateMachine, getWifiScanner(),
408                mWifiConfigManager, wifiInfo, mWifiNetworkSelector, mWifiLastResortWatchdog,
409                mWifiMetrics, mWifiStateMachineHandlerThread.getLooper(), mClock,
410                hasConnectionRequests, mFrameworkFacade, mSavedNetworkEvaluator,
411                mRecommendedNetworkEvaluator, mPasspointNetworkEvaluator);
412    }
413
414    public WifiPermissionsUtil getWifiPermissionsUtil() {
415        return mWifiPermissionsUtil;
416    }
417
418    public WifiPermissionsWrapper getWifiPermissionsWrapper() {
419        return mWifiPermissionsWrapper;
420    }
421
422    /**
423     * Returns a singleton instance of a HandlerThread for injection. Uses lazy initialization.
424     *
425     * TODO: share worker thread with other Wi-Fi handlers (b/27924886)
426     */
427    public HandlerThread getWifiAwareHandlerThread() {
428        if (mWifiAwareHandlerThread == null) { // lazy initialization
429            mWifiAwareHandlerThread = new HandlerThread("wifiAwareService");
430            mWifiAwareHandlerThread.start();
431        }
432        return mWifiAwareHandlerThread;
433    }
434
435    /**
436     * Returns a single instance of HalDeviceManager for injection.
437     */
438    public HalDeviceManager getHalDeviceManager() {
439        return mHalDeviceManager;
440    }
441}
442