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