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