根據本身的理解整理了Android O的wifi啓動流程,爲便於理解,繪製了Android O wifi架構圖。有理解不到之處和錯誤之處,請各位指出,一塊兒學習。
一. Android O wifi 架構:java
因爲Android O的Treble化,Android O上Wifi架構變更也比較大,尤爲是JNI層、Hal層、HIDL層。android
下圖是Android O Treble HIDL大體結構:架構
下圖是Android O wifi架構:app
下圖是Android Wlan架構(from android官網)函數
二. 函數調用流程:oop
1. 在wifisettings activity的onStart函數中,建立一個WifiEnabler對象,用於實現wifi開關功能。學習
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.javathis
onStart()server
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 := ""