根据自己的理解整理了Android O的wifi启动流程,为便于理解,绘制了Android O wifi架构图。有理解不到之处和错误之处,请各位指出,一起学习。
一. Android O wifi 架构:
由于Android O的Treble化,Android O上Wifi架构变动也比较大,尤其是JNI层、Hal层、HIDL层。
下图是Android O Treble HIDL大致结构:
下图是Android O wifi架构:
下图是Android Wlan架构(from android官网)
二. 函数调用流程:
1. 在wifisettings activity的onStart函数中,创建一个WifiEnabler对象,用于实现wifi开关功能。
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
onStart()
mWifiEnabler = createWifiEnabler();
2. WifiEnabler开关SwitchToggled中会调用WifiManager.setWifiEnabled方法。
packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
onSwithToggled(boolean isCkecked)
mWifiManager.setWifiEnabled(isChecked)
3. WifiManager调用WifiService的方法。
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
setWifiEnabled(boolean enabled)
mService.setWifiEnabled(mContext.getOpPackageName(), enabled)
4. WiFiManager使用aidl方式和WifiService进行通信。
frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl
boolean setWifiEnabled(String packageName, boolean enable);
5. WifiServiceImpl中实现WifiService的方法,像WifiController发消息:CMD_WIFI_TOGGLED.
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
public synchronized boolean setWifiEnabled(String packageName, boolean enable)
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
6. WifiController状态机处理消息:CMD_WIFI_TOGGLED
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
WifiController状态机的状态变化,这里我们只说softap关闭状态下打开sta的情况;有时间的话,可以跟一下softap打开状态下打开sta的流程。这里只需关注“Turn ON STA” .
* ------------------
* ApStaDisabledState
* ------------------
* / \
* -> Turn ON STA / \ Turn on SAP <-
* / \
* / \
* --------------- --------------
* StaEnabledState ApEnabledState
* --------------- --------------
* \ /
* \ /
* -> Turn ON SAP \ / Turn on STA <-
* \ /
* ---------------
* QcApStaEnablingState
* ---------------
* | |
* | |
* -> CMD_AP_STARTED | | CMD_STA_STARTED <-
*(SAP turn on completed) | | (STA turn on completed)
* | |
* ---------------------
* QcApStaEnabledState
* ----------------------
* / \
/ \
* -> Turn on OFF STA / \ Turn OFF SAP
* / \
* ------------------------
* QcApStaDisablingState
* ------------------------
* /\
* / \
* -> CMD_WIFI_DISABLED / \ CMD_AP_STOPPED <-
*(STA turn OFF completed)/ \ (SAP turn OFF completed)
* / \
* / \
* ------------------- -------------
* ApEnabledState StaEnabledState
* ------------------- ---------------
6.1 ApStaDisabledState 状态下,不对CMD_WIFI_TOGGLED消息处理
6.2 转向StaEnabledState状态,在该状态的enter()函数中启动supplicant, processMessage中会根据扫描、sta/ap共存等条件做相应的状态处理。
class StaEnabledState extends State
enter()
mWifiStateMachine.setSupplicantRunning(true);
public boolean processMessage(Message msg)
case CMD_WIFI_TOGGLED:
7. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
public void setSupplicantRunning(boolean enable)
sendMessage(CMD_START_SUPPLICANT);
8. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
又是状态机,这里简单给出wifi状态机的各状态及结构。感觉有必要专门讲一下状态机。
WifiStateMachine state:
|- DefaultState
|-- InitialState
|-- SupplicantStartingState
|-- SupplicantStartedState
|--- ScanModeState
|--- ConnectModeState
|---- L2ConnectedState
|----- ObtainingIpState
|----- ConnectedState
|----- RoamingState
|---- DisconnectingState
|---- DisconnectedState
|---- WpsRunningState
|---- FilsState
|--- WaitForP2pDisableState
|-- SupplicantStoppingState
|-- SoftApstate
InitialState状态中处理消息:CMD_START_SUPPLICANT, 做加载驱动、启动supplicant操作,然后转向SupplicantStartingState状态。
class InitialState extends State
case CMD_START_SUPPLICANT:
mClientInterface = mWifiNative.setupForClientMode(); // loadDriver
mWifiNative.enableSupplicant() // start supplicant
transitionTo(mSupplicantStartingState);
9. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
public IClientInterface setupForClientMode()
startHalIfNecessary(true)) // start Hal
IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode();
//启动Hal层。如果支持STA/AP共存,startConcurrentVendorHal;如果不支持共存:isStaMode=true启动sta模式,isStaMode=false启动ap模式。
private boolean startHalIfNecessary(boolean isStaMode)
if (mStaAndAPConcurrency)
// start ap & sta Concurrent Hal
return mWifiVendorHal.startConcurrentVendorHal(isStaMode);
return mWifiVendorHal.startVendorHal(isStaMode); // start Hal. Here
10. 不同于android N,wifinative会调用JNI层com_android_server_wifi_WifiNative.cpp. Android O在framework增加了调用Hal层的相关接口及hal设备管理接口。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java
public boolean startVendorHal(boolean isStaMode)
mHalDeviceManager.start() //start wifi vendor hal
mIWifiStaIface = mHalDeviceManager.createStaIface(null, null); //loadDriver
11. 这个代码跟的有些凌乱
frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java
public IWifiStaIface createStaIface(InterfaceDestroyedListener destroyedListener,
Looper looper) {
return (IWifiStaIface) createIface(IfaceType.STA, destroyedListener, looper);
}
private IWifiIface createIface(int ifaceType, InterfaceDestroyedListener destroyedListener, Looper looper)
IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, destroyedListener, looper);
private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType, InterfaceDestroyedListener destroyedListener, Looper looper)
IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);
private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData, int ifaceType)
WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(ifaceCreationData.chipModeId);
12. Android O不在使用之前版本的JNI com_android_server_wifi_WifiNative.cpp。而是用HIDL,其实现在/hardware/interfaces/.
hardware/interfaces/wifi/1.1/default/wifi_chip.cpp
Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb)
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id)
WifiStatus status = handleChipConfiguration(mode_id);
WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id)
if (mode_id == kStaChipModeId) {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
} else {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
}
13. hardware/interfaces/wifi/1.0/default/wifi_mode_controller.cpp
bool WifiModeController::changeFirmwareMode(IfaceType type)
driver_tool_->LoadDriver()
driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))
14. 最后调到hal层,android O的hal层也进行了重写。位置也从之前的版本中的hardware/libhardware_legacy/wifi/移到了frameworks/opt/net/wifi/libwifi_hal/
frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp
bool DriverTool::LoadDriver()
return ::wifi_load_driver() == 0;
15 frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp
int wifi_load_driver()
if (is_wifi_driver_loaded()) return 0;
insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)
除了一些打开wifi时的消息通知、广播、状态变化,这里没有详细描述;至此,wifi打开的相关工作已经完成。
Qcom平台把加载wifi驱动的动作放在了开机时,在init.target.rc文件中:
insmod /vendor/lib/modules/qca_cld3_wlan.ko
根据实际情况,可能需要将开机加载驱动改为原来的动态加载。只需要做两处改动:
A. init脚本中删除加载wlan driver的行
B. 确认如下几个宏是打开和正确定义,在产品平台对应的makefile文件中加入即可:
WIFI_DRIVER_MODULE_PATH := "/vendor/lib/modules/wlan.ko"
WIFI_DRIVER_MODULE_NAME := "wlan"
WIFI_DRIVER_MODULE_ARG := ""