根据自己的理解整理了Android O的wifi启动流程,为便于理解,绘制了Android O wifi架构图。有理解不到之处和错误之处,请各位指出,一起学习。
一. Android O wifi 架构:

由于Android O的Treble化,Android O上Wifi架构变动也比较大,尤其是JNI层、Hal层、HIDL层。

下图是Android O Treble HIDL大致结构:

Android wifi打开流程(Android O)-LMLPHP

下图是Android O wifi架构:

Android wifi打开流程(Android O)-LMLPHP

下图是Android Wlan架构(from android官网)

Android wifi打开流程(Android O)-LMLPHP

二. 函数调用流程:

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 := ""
 

01-11 13:16