WifiInjector.java revision d68fa5a0cb9715a20cc06010b40ccbe6ba8cb64c
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.IWificond;
23import android.os.HandlerThread;
24import android.os.IBinder;
25import android.os.INetworkManagementService;
26import android.os.ServiceManager;
27import android.os.SystemProperties;
28import android.os.UserManager;
29import android.provider.Settings;
30import android.security.KeyStore;
31
32import com.android.internal.R;
33import com.android.server.am.BatteryStatsService;
34
35import java.util.ArrayList;
36
37/**
38 *  WiFi dependency injector. To be used for accessing various WiFi class instances and as a
39 *  handle for mock injection.
40 *
41 *  Some WiFi class instances currently depend on having a Looper from a HandlerThread that has
42 *  been started. To accommodate this, we have a two-phased approach to initialize and retrieve
43 *  an instance of the WifiInjector.
44 */
45public class WifiInjector {
46    private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
47    private static final String WIFICOND_SERVICE_NAME = "wificond";
48
49    static WifiInjector sWifiInjector = null;
50
51    private final Context mContext;
52    private final FrameworkFacade mFrameworkFacade = new FrameworkFacade();
53    private final HandlerThread mWifiServiceHandlerThread;
54    private final HandlerThread mWifiStateMachineHandlerThread;
55    private final WifiTrafficPoller mTrafficPoller;
56    private final WifiCountryCode mCountryCode;
57    private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy();
58    private final WifiStateMachine mWifiStateMachine;
59    private final WifiSettingsStore mSettingsStore;
60    private final WifiCertManager mCertManager;
61    private final WifiNotificationController mNotificationController;
62    private final WifiLockManager mLockManager;
63    private final WifiController mWifiController;
64    private final Clock mClock = new Clock();
65    private final WifiMetrics mWifiMetrics = new WifiMetrics(mClock);
66    private final WifiLastResortWatchdog mWifiLastResortWatchdog;
67    private final PropertyService mPropertyService = new SystemPropertyService();
68    private final BuildProperties mBuildProperties = new SystemBuildProperties();
69    private final KeyStore mKeyStore = KeyStore.getInstance();
70    private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
71    private final WifiMulticastLockManager mWifiMulticastLockManager;
72    private final boolean mUseRealLogger;
73
74    public WifiInjector(Context context) {
75        if (context == null) {
76            throw new IllegalStateException(
77                    "WifiInjector should not be initialized with a null Context.");
78        }
79
80        if (sWifiInjector != null) {
81            throw new IllegalStateException(
82                    "WifiInjector was already created, use getInstance instead.");
83        }
84
85        sWifiInjector = this;
86
87        mContext = context;
88        mUseRealLogger = mContext.getResources().getBoolean(
89                R.bool.config_wifi_enable_wifi_firmware_debugging);
90
91        // Now create and start handler threads
92        mWifiServiceHandlerThread = new HandlerThread("WifiService");
93        mWifiServiceHandlerThread.start();
94        mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
95        mWifiStateMachineHandlerThread.start();
96
97        // Now get instances of all the objects that depend on the HandlerThreads
98        mTrafficPoller =  new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
99                WifiNative.getWlanNativeInterface().getInterfaceName());
100        mCountryCode = new WifiCountryCode(WifiNative.getWlanNativeInterface(),
101                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
102                mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
103                mContext.getResources()
104                        .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
105        mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade,
106                mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext),
107                this, mBackupManagerProxy, mCountryCode);
108        mSettingsStore = new WifiSettingsStore(mContext);
109        mCertManager = new WifiCertManager(mContext);
110        mNotificationController = new WifiNotificationController(mContext,
111                mWifiServiceHandlerThread.getLooper(), mWifiStateMachine,
112                mFrameworkFacade, null);
113        mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
114        mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
115                mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
116        mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
117        mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine,
118                BatteryStatsService.getService());
119    }
120
121    /**
122     *  Obtain an instance of the WifiInjector class.
123     *
124     *  This is the generic method to get an instance of the class. The first instance should be
125     *  retrieved using the getInstanceWithContext method.
126     */
127    public static WifiInjector getInstance() {
128        if (sWifiInjector == null) {
129            throw new IllegalStateException(
130                    "Attempted to retrieve a WifiInjector instance before constructor was called.");
131        }
132        return sWifiInjector;
133    }
134
135    public WifiMetrics getWifiMetrics() {
136        return mWifiMetrics;
137    }
138
139    public BackupManagerProxy getBackupManagerProxy() {
140        return mBackupManagerProxy;
141    }
142
143    public FrameworkFacade getFrameworkFacade() {
144        return mFrameworkFacade;
145    }
146
147    public HandlerThread getWifiServiceHandlerThread() {
148        return mWifiServiceHandlerThread;
149    }
150
151    public HandlerThread getWifiStateMachineHandlerThread() {
152        return mWifiStateMachineHandlerThread;
153    }
154
155    public WifiTrafficPoller getWifiTrafficPoller() {
156        return mTrafficPoller;
157    }
158
159    public WifiCountryCode getWifiCountryCode() {
160        return mCountryCode;
161    }
162
163    public WifiStateMachine getWifiStateMachine() {
164        return mWifiStateMachine;
165    }
166
167    public WifiSettingsStore getWifiSettingsStore() {
168        return mSettingsStore;
169    }
170
171    public WifiCertManager getWifiCertManager() {
172        return mCertManager;
173    }
174
175    public WifiNotificationController getWifiNotificationController() {
176        return mNotificationController;
177    }
178
179    public WifiLockManager getWifiLockManager() {
180        return mLockManager;
181    }
182
183    public WifiController getWifiController() {
184        return mWifiController;
185    }
186
187    public WifiLastResortWatchdog getWifiLastResortWatchdog() {
188        return mWifiLastResortWatchdog;
189    }
190
191    public Clock getClock() {
192        return mClock;
193    }
194
195    public PropertyService getPropertyService() {
196        return mPropertyService;
197    }
198
199    public BuildProperties getBuildProperties() {
200        return mBuildProperties;
201    }
202
203    public KeyStore getKeyStore() {
204        return mKeyStore;
205    }
206
207    public WifiBackupRestore getWifiBackupRestore() {
208        return mWifiBackupRestore;
209    }
210
211    public WifiMulticastLockManager getWifiMulticastLockManager() {
212        return mWifiMulticastLockManager;
213    }
214
215    public IWificond makeWificond() {
216        // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
217        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
218        return IWificond.Stub.asInterface(binder);
219    }
220
221    /**
222     * Create a SoftApManager.
223     * @param wifiNative reference to WifiNative
224     * @param nmService reference to NetworkManagementService
225     * @param cm reference to ConnectivityManager
226     * @param countryCode Country code
227     * @param allowed2GChannels list of allowed 2G channels
228     * @param listener listener for SoftApManager
229     * @param apInterface network interface to start hostapd against
230     * @return an instance of SoftApManager
231     */
232    public SoftApManager makeSoftApManager(
233            WifiNative wifiNative,
234            INetworkManagementService nmService, ConnectivityManager cm,
235            String countryCode, ArrayList<Integer> allowed2GChannels,
236            SoftApManager.Listener listener, IApInterface apInterface) {
237        return new SoftApManager(
238                mWifiServiceHandlerThread.getLooper(),
239                wifiNative, nmService, countryCode,
240                allowed2GChannels, listener, apInterface);
241    }
242
243    public BaseWifiDiagnostics makeWifiDiagnostics(WifiNative wifiNative) {
244        if (mUseRealLogger) {
245            return new WifiDiagnostics(mContext, mWifiStateMachine, wifiNative, mBuildProperties);
246        } else {
247            return new BaseWifiDiagnostics();
248        }
249    }
250}
251