PS:上一节谈到frameworks层的WifiManager类是WLAN的核心类
所以我们这一节先从WifiManager展开。
一、WLAN开关分析
应用层中WifiSettings中new了WifiEnabler对象,在WifiEnabler中调用了WifiManager的setWifiEnabled()方法。
路径:frameworks/base/wifi/java/android/net/wifi/WfiManager.java
WfiManager->setWifiEnabled()
/** * Enable or disable Wi-Fi. * <p> * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE} * permission to toggle wifi. * * @param enabled {@code true} to enable, {@code false} to disable. * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is * either already in the requested state, or in progress toward the requested state. * @throws {@link java.lang.SecurityException} if the caller is missing required permissions. */ public boolean setWifiEnabled(boolean enabled) { try { return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
这里返回了一个服务调用结果
IWifiManager mService
路径:frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl ps:注意是aidl
IWifiManager->setWifiEnabled()
那么我们需要找到IWifiManager.aidl相对应的Service 找到实现IWifiManager.Stub的类
WifiServiceImpl extends IWifiManager.Stub
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
WifiServiceImpl->setWifiEnabled()
/** * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} * @param enable {@code true} to enable, {@code false} to disable. * @return {@code true} if the enable/disable operation was * started or is already in the queue. */ @Override public synchronized boolean setWifiEnabled(String packageName, boolean enable) throws RemoteException { ... ... //判断是否飞行模式以及各种权限和打印日志,略过 ... mWifiController.sendMessage(CMD_WIFI_TOGGLED); return true; }
这里发送了一条WLAN切换信息
WifiController mWifiController
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
/**状态机 * WifiController is the class used to manage on/off state of WifiStateMachine for various operating * modes (normal, airplane, wifi hotspot, etc.). */ public class WifiController extends StateMachine {
不同于WifiStateMachine ,WifiStateMachine是一个复杂的状态机,它维护了Wifi的启动、扫描、连接、断开等多个状态。WifiController 是高级别的wifi状态机,管理wifi开关,wifi热点开关等状态。
WifiController(Context context, WifiStateMachine wsm, Looper wifiStateMachineLooper, WifiSettingsStore wss, Looper wifiServiceLooper, FrameworkFacade f, WifiStateMachinePrime wsmp) { super(TAG, wifiServiceLooper); mFacade = f; mContext = context; mWifiStateMachine = wsm; mWifiStateMachineLooper = wifiStateMachineLooper; mWifiStateMachinePrime = wsmp; mSettingsStore = wss; // CHECKSTYLE:OFF IndentationCheck
//添加各个状态及父状态
addState(mDefaultState); addState(mStaDisabledState, mDefaultState); addState(mStaEnabledState, mDefaultState); addState(mDeviceActiveState, mStaEnabledState); addState(mStaDisabledWithScanState, mDefaultState); addState(mEcmState, mDefaultState); // CHECKSTYLE:ON IndentationCheck boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn(); boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled(); boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable(); boolean isLocationModeActive = mSettingsStore.getLocationModeSetting(mContext) == Settings.Secure.LOCATION_MODE_OFF; log("isAirplaneModeOn = " + isAirplaneModeOn + ", isWifiEnabled = " + isWifiEnabled + ", isScanningAvailable = " + isScanningAlwaysAvailable + ", isLocationModeActive = " + isLocationModeActive); if (checkScanOnlyModeAvailable()) { setInitialState(mStaDisabledWithScanState); } else { setInitialState(mStaDisabledState); }
路径:frameworks/base/core/java/com/android/internal/util/StateMachine.java
addState()方法是父类StateMachine的方法,第一个参数是新添加的状态,第二个是其父状态。
/** * Add a new state to the state machine. Bottom up addition * of states is allowed but the same state may only exist * in one hierarchy. * * @param state the state to add * @param parent the parent of state * @return stateInfo for this state */ private final StateInfo addState(State state, State parent) { if (mDbg) { mSm.log("addStateInternal: E state=" + state.getName() + ",parent=" + ((parent == null) ? "" : parent.getName())); } StateInfo parentStateInfo = null; if (parent != null) { parentStateInfo = mStateInfo.get(parent); if (parentStateInfo == null) { // Recursively add our parent as it‘s not been added yet. parentStateInfo = addState(parent, null); } } StateInfo stateInfo = mStateInfo.get(state); if (stateInfo == null) { stateInfo = new StateInfo(); mStateInfo.put(state, stateInfo); } // Validate that we aren‘t adding the same state in two different hierarchies. if ((stateInfo.parentStateInfo != null) && (stateInfo.parentStateInfo != parentStateInfo)) { throw new RuntimeException("state already added"); } stateInfo.state = state; stateInfo.parentStateInfo = parentStateInfo; stateInfo.active = false; if (mDbg) mSm.log("addStateInternal: X stateInfo: " + stateInfo); return stateInfo; }
StaDisabledState、StaEnabledState、StaDisabledWithScanState、EcmState的父状态都是DefaultState;而DeviceActiveState的父状态是StaEnabledState。
初始状态为StaDisableState
class StaDisabledState extends State { private int mDeferredEnableSerialNumber = 0; private boolean mHaveDeferredEnable = false; private long mDisabledTimestamp; @Override public void enter() { mWifiStateMachinePrime.disableWifi(); // Supplicant can‘t restart right away, so note the time we switched off mDisabledTimestamp = SystemClock.elapsedRealtime(); mDeferredEnableSerialNumber++; mHaveDeferredEnable = false; mWifiStateMachine.clearANQPCache(); } ... ...
在该状态下对接收到的CMD_WIFI_TOGGLED消息执行相应代码块。
@Override public boolean processMessage(Message msg) { switch (msg.what) { case CMD_WIFI_TOGGLED: if (mSettingsStore.isWifiToggleEnabled()) { if (doDeferEnable(msg)) { if (mHaveDeferredEnable) { // have 2 toggles now, inc serial number and ignore both mDeferredEnableSerialNumber++; } mHaveDeferredEnable = !mHaveDeferredEnable; break; } transitionTo(mDeviceActiveState); } else if (checkScanOnlyModeAvailable()) { // only go to scan mode if we aren‘t in airplane mode
//进入扫描模式
if (mSettingsStore.isAirplaneModeOn()) { transitionTo(mStaDisabledWithScanState); } } break;
该状态下基本上没做处理然后切换到了DeviceActiveState。DeviceActiveState的父状态为StaEnabledState,
状态机的机制是,当转换为目标状态时,会依次调用父状态和本身的enter()方法。
StaEnableState
class StaEnabledState extends State { @Override public void enter() { log("StaEnabledState.enter()"); } ... ...//没做处理
DeviceActiveState
class DeviceActiveState extends State { @Override public void enter() { mWifiStateMachinePrime.enterClientMode(); mWifiStateMachine.setHighPerfModeEnabled(false); } ... ...
WifiStateMachinePrime mWifiStateMachinePrime
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachinePrime.java
/** * Method to switch wifi into client mode where connections to configured networks will be * attempted. */ public void enterClientMode() { changeMode(ModeStateMachine.CMD_START_CLIENT_MODE); }
private void changeMode(int newMode) { mModeStateMachine.sendMessage(newMode); }
ModeStateMachine mModeStateMachine
明显,ModeStateMachine也是状态机,是WifiStateMachinePrime的内部类
private class ModeStateMachine extends StateMachine { // Commands for the state machine - these will be removed, // along with the StateMachine itself public static final int CMD_START_CLIENT_MODE = 0; public static final int CMD_START_SCAN_ONLY_MODE = 1; public static final int CMD_DISABLE_WIFI = 3; private final State mWifiDisabledState = new WifiDisabledState(); private final State mClientModeActiveState = new ClientModeActiveState(); private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState(); ModeStateMachine() { super(TAG, mLooper); addState(mClientModeActiveState); addState(mScanOnlyModeActiveState); addState(mWifiDisabledState);
...
...
ModeStateMachine有四种状态WifiDisabledState、ClientModeActiveState、ScanOnlyModeActiveState及父状态ModeActiveState。
初始也是关闭状态
WiFiDisableState
class WifiDisabledState extends ModeActiveState { @Override public void enter() { Log.d(TAG, "Entering WifiDisabledState"); mDefaultModeManager.sendScanAvailableBroadcast(mContext, false); mScanRequestProxy.enableScanningForHiddenNetworks(false); mScanRequestProxy.clearScanResults(); } @Override public boolean processMessage(Message message) { Log.d(TAG, "received a message in WifiDisabledState: " + message); if (checkForAndHandleModeChange(message)) { return HANDLED; } return NOT_HANDLED; } @Override public void exit() { // do not have an active mode manager... nothing to clean up } }
private boolean checkForAndHandleModeChange(Message message) { switch(message.what) { case ModeStateMachine.CMD_START_CLIENT_MODE: Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode"); mModeStateMachine.transitionTo(mClientModeActiveState); break; case ModeStateMachine.CMD_START_SCAN_ONLY_MODE: Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode"); mModeStateMachine.transitionTo(mScanOnlyModeActiveState); break; case ModeStateMachine.CMD_DISABLE_WIFI: Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled"); mModeStateMachine.transitionTo(mWifiDisabledState); break; default: return NOT_HANDLED; } return HANDLED; }
接着转换为ClientModeActiveState
class ClientModeActiveState extends ModeActiveState { ClientListener mListener; private class ClientListener implements ClientModeManager.Listener { ... @Override public void enter() { Log.d(TAG, "Entering ClientModeActiveState"); mListener = new ClientListener(); mManager = mWifiInjector.makeClientModeManager(mListener); mManager.start(); mActiveModeManagers.add(mManager); updateBatteryStatsWifiState(true); } ...
ActiveModeManager mManager
ClientModeManager是ActiveModeManager的实现类
/** * Start client mode. */ public void start() { mStateMachine.sendMessage(ClientModeStateMachine.CMD_START); }
ClientModeStateMachine mStateMachine
ClientModeStateMachine也是一个状态机,有两种状态IdleState和StartedState
ClientModeStateMachine(Looper looper) { super(TAG, looper); addState(mIdleState); addState(mStartedState); setInitialState(mIdleState); start(); }
初始为IdleState状态
private class IdleState extends State { @Override public void enter() { Log.d(TAG, "entering IdleState"); mClientInterfaceName = null; mIfaceIsUp = false; } @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_START: updateWifiState(WifiManager.WIFI_STATE_ENABLING, WifiManager.WIFI_STATE_DISABLED); mClientInterfaceName = mWifiNative.setupInterfaceForClientMode( false /* not low priority */, mWifiNativeInterfaceCallback); if (TextUtils.isEmpty(mClientInterfaceName)) { Log.e(TAG, "Failed to create ClientInterface. Sit in Idle"); updateWifiState(WifiManager.WIFI_STATE_UNKNOWN, WifiManager.WIFI_STATE_ENABLING); updateWifiState(WifiManager.WIFI_STATE_DISABLED, WifiManager.WIFI_STATE_UNKNOWN); break; } sendScanAvailableBroadcast(false); mScanRequestProxy.enableScanningForHiddenNetworks(false); mScanRequestProxy.clearScanResults(); transitionTo(mStartedState); break; default: Log.d(TAG, "received an invalid message: " + message); return NOT_HANDLED; } return HANDLED; } }
WifiNative mWifiNative
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
/** * Setup an interface for Client mode operations. * * This method configures an interface in STA mode in all the native daemons * (wificond, wpa_supplicant & vendor HAL). * * @param lowPrioritySta The requested STA has a low request priority (lower probability of * getting created, higher probability of getting destroyed). * @param interfaceCallback Associated callback for notifying status changes for the iface. * @return Returns the name of the allocated interface, will be null on failure. */ public String setupInterfaceForClientMode(boolean lowPrioritySta, @NonNull InterfaceCallback interfaceCallback) { synchronized (mLock) { if (!startHal()) { Log.e(TAG, "Failed to start Hal"); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal(); return null; } if (!startSupplicant()) { Log.e(TAG, "Failed to start supplicant"); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant(); return null; } Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA); if (iface == null) { Log.e(TAG, "Failed to allocate new STA iface"); return null; } iface.externalListener = interfaceCallback; iface.name = createStaIface(iface, lowPrioritySta); if (TextUtils.isEmpty(iface.name)) { Log.e(TAG, "Failed to create STA iface in vendor HAL"); mIfaceMgr.removeIface(iface.id); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal(); return null; } if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) { Log.e(TAG, "Failed to setup iface in wificond on " + iface); teardownInterface(iface.name); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond(); return null; } if (!mSupplicantStaIfaceHal.setupIface(iface.name)) { Log.e(TAG, "Failed to setup iface in supplicant on " + iface); teardownInterface(iface.name); mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant(); return null; } iface.networkObserver = new NetworkObserverInternal(iface.id); if (!registerNetworkObserver(iface.networkObserver)) { Log.e(TAG, "Failed to register network observer on " + iface); teardownInterface(iface.name); return null; } mWifiMonitor.startMonitoring(iface.name); // Just to avoid any race conditions with interface state change callbacks, // update the interface state before we exit. onInterfaceStateChanged(iface, isInterfaceUp(iface.name)); initializeNwParamsForClientInterface(iface.name); Log.i(TAG, "Successfully setup " + iface); return iface.name; } }
startHal()
startSupplicant()
加载驱动setupInterfaceForClientMode()
另外启动了Wifi监视器startMonitoring()
startHal()
/** Helper method invoked to start supplicant if there were no ifaces */ private boolean startHal() { synchronized (mLock) { if (!mIfaceMgr.hasAnyIface()) { if (mWifiVendorHal.isVendorHalSupported()) { if (!mWifiVendorHal.startVendorHal()) { Log.e(TAG, "Failed to start vendor HAL"); return false; } } else { Log.i(TAG, "Vendor Hal not supported, ignoring start."); } } return true; } }
isVendorHalSupported()和startVendorHal()分别调用了HalDeviceManager的isSupported()和start()方法。
startSupplicant()实际上调用了WificondControl的enableSupplicant()方法
/** * Enable wpa_supplicant via wificond. * @return Returns true on success. */ public boolean enableSupplicant() { if (!retrieveWificondAndRegisterForDeath()) { return false; } try { return mWificond.enableSupplicant(); } catch (RemoteException e) { Log.e(TAG, "Failed to enable supplicant due to remote exception"); } return false; }
retrieveWificondAndRegisterForDeath()
private boolean retrieveWificondAndRegisterForDeath() { if (mWificond != null) { if (mVerboseLoggingEnabled) { Log.d(TAG, "Wificond handle already retrieved"); } // We already have a wificond handle. return true; } mWificond = mWifiInjector.makeWificond();
IWificond mWificond
路径:system/connectivity/wificond/aidl/android/net/wifi/IWificond.aidl
其实现类为WiFiInjector
在上面的方法中被初始化
public IWificond makeWificond() { // We depend on being able to refresh our binder in WifiStateMachine, so don‘t cache it. IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME); return IWificond.Stub.asInterface(binder); }
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java
WIFICOND_SERVICE_NAME = wificond
ServiceManager.getService("wificond")直接调用了底层cpp
Status Server::enableSupplicant(bool* success) { *success = supplicant_manager_->StartSupplicant(); return Status::ok(); }
路径:system/connectivity/wificond/server.cpp