WifiInjector.java revision 974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0
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
73    public WifiInjector(Context context) {
74        if (context == null) {
75            throw new IllegalStateException(
76                    "WifiInjector should not be initialized with a null Context.");
77        }
78
79        if (sWifiInjector != null) {
80            throw new IllegalStateException(
81                    "WifiInjector was already created, use getInstance instead.");
82        }
83
84        sWifiInjector = this;
85
86        mContext = context;
87        // Now create and start handler threads
88        mWifiServiceHandlerThread = new HandlerThread("WifiService");
89        mWifiServiceHandlerThread.start();
90        mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
91        mWifiStateMachineHandlerThread.start();
92
93        // Now get instances of all the objects that depend on the HandlerThreads
94        mTrafficPoller =  new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
95                WifiNative.getWlanNativeInterface().getInterfaceName());
96        mCountryCode = new WifiCountryCode(WifiNative.getWlanNativeInterface(),
97                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
98                mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
99                mContext.getResources()
100                        .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
101        mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade,
102                mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext),
103                this, mBackupManagerProxy, mCountryCode);
104        mSettingsStore = new WifiSettingsStore(mContext);
105        mCertManager = new WifiCertManager(mContext);
106        mNotificationController = new WifiNotificationController(mContext,
107                mWifiServiceHandlerThread.getLooper(), mWifiStateMachine,
108                mFrameworkFacade, null);
109        mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
110        mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
111                mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
112        mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
113        mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine,
114                BatteryStatsService.getService());
115    }
116
117    /**
118     *  Obtain an instance of the WifiInjector class.
119     *
120     *  This is the generic method to get an instance of the class. The first instance should be
121     *  retrieved using the getInstanceWithContext method.
122     */
123    public static WifiInjector getInstance() {
124        if (sWifiInjector == null) {
125            throw new IllegalStateException(
126                    "Attempted to retrieve a WifiInjector instance before constructor was called.");
127        }
128        return sWifiInjector;
129    }
130
131    public WifiMetrics getWifiMetrics() {
132        return mWifiMetrics;
133    }
134
135    public BackupManagerProxy getBackupManagerProxy() {
136        return mBackupManagerProxy;
137    }
138
139    public FrameworkFacade getFrameworkFacade() {
140        return mFrameworkFacade;
141    }
142
143    public HandlerThread getWifiServiceHandlerThread() {
144        return mWifiServiceHandlerThread;
145    }
146
147    public HandlerThread getWifiStateMachineHandlerThread() {
148        return mWifiStateMachineHandlerThread;
149    }
150
151    public WifiTrafficPoller getWifiTrafficPoller() {
152        return mTrafficPoller;
153    }
154
155    public WifiCountryCode getWifiCountryCode() {
156        return mCountryCode;
157    }
158
159    public WifiStateMachine getWifiStateMachine() {
160        return mWifiStateMachine;
161    }
162
163    public WifiSettingsStore getWifiSettingsStore() {
164        return mSettingsStore;
165    }
166
167    public WifiCertManager getWifiCertManager() {
168        return mCertManager;
169    }
170
171    public WifiNotificationController getWifiNotificationController() {
172        return mNotificationController;
173    }
174
175    public WifiLockManager getWifiLockManager() {
176        return mLockManager;
177    }
178
179    public WifiController getWifiController() {
180        return mWifiController;
181    }
182
183    public WifiLastResortWatchdog getWifiLastResortWatchdog() {
184        return mWifiLastResortWatchdog;
185    }
186
187    public Clock getClock() {
188        return mClock;
189    }
190
191    public PropertyService getPropertyService() {
192        return mPropertyService;
193    }
194
195    public BuildProperties getBuildProperties() {
196        return mBuildProperties;
197    }
198
199    public KeyStore getKeyStore() {
200        return mKeyStore;
201    }
202
203    public WifiBackupRestore getWifiBackupRestore() {
204        return mWifiBackupRestore;
205    }
206
207    public WifiMulticastLockManager getWifiMulticastLockManager() {
208        return mWifiMulticastLockManager;
209    }
210
211    public IWificond makeWificond() {
212        // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
213        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
214        return IWificond.Stub.asInterface(binder);
215    }
216
217    /**
218     * Create a SoftApManager.
219     * @param wifiNative reference to WifiNative
220     * @param nmService reference to NetworkManagementService
221     * @param cm reference to ConnectivityManager
222     * @param countryCode Country code
223     * @param allowed2GChannels list of allowed 2G channels
224     * @param listener listener for SoftApManager
225     * @param apInterface network interface to start hostapd against
226     * @return an instance of SoftApManager
227     */
228    public SoftApManager makeSoftApManager(
229            WifiNative wifiNative,
230            INetworkManagementService nmService, ConnectivityManager cm,
231            String countryCode, ArrayList<Integer> allowed2GChannels,
232            SoftApManager.Listener listener, IApInterface apInterface) {
233        return new SoftApManager(
234                mWifiServiceHandlerThread.getLooper(),
235                wifiNative, countryCode,
236                allowed2GChannels, listener, apInterface);
237    }
238}
239