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