WifiInjector.java revision 63fad8b4722c94ce9107690b647cdbe7e8a1c4f9
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 /** 244 * Create a WifiLog instance. 245 * @param tag module name to include in all log messages 246 */ 247 public WifiLog makeLog(String tag) { 248 return new LogcatLog(tag); 249 } 250 251 public BaseWifiDiagnostics makeWifiDiagnostics(WifiNative wifiNative) { 252 if (mUseRealLogger) { 253 return new WifiDiagnostics( 254 mContext, this, mWifiStateMachine, wifiNative, mBuildProperties); 255 } else { 256 return new BaseWifiDiagnostics(); 257 } 258 } 259} 260