版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/huangweiqing80/article/details/82384518
一. Android O wifi 架构:

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

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

下图是Android O wifi架构:


二.WiFi启动流程梳理
2.1 设置启动WiFi

设置这边说到底其实就是监控WiFi开关的变化,然后根据开关走对应的逻辑处理。

两个比较重要的类:

1)WifiSettings:设置中wifi主界面所对应的代码

2)WifiEnabler:设置中负责wifi开关打开和关闭事件处理的类

在wifisettings activity的onStart函数中,创建一个WifiEnabler对象,用于实现wifi开关功能。
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java

    public void onStart() {        super.onStart();        // On/off switch is hidden for Setup Wizard (returns null)        mWifiEnabler = createWifiEnabler();        mWifiTracker.startTracking();        if (mIsRestricted) {            restrictUi();            return;        }        onWifiStateChanged(mWifiManager.getWifiState());    }

onStart函数调用createWifiEnabler:

    /**     * @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)     */    private WifiEnabler createWifiEnabler() {        final SettingsActivity activity = (SettingsActivity) getActivity();        return new WifiEnabler(activity, new SwitchBarController(activity.getSwitchBar()),            mMetricsFeatureProvider);    }

下面进入
/aosp/packages/apps/Settings/src/com/android/settings/widget/SwitchBarController.java
看看SwitchBarController这个类

public class SwitchBarController extends SwitchWidgetController implements    SwitchBar.OnSwitchChangeListener {    private final SwitchBar mSwitchBar;    public SwitchBarController(SwitchBar switchBar) {        mSwitchBar = switchBar;    }     .     .     .    @Override    public void startListening() {        mSwitchBar.addOnSwitchChangeListener(this);    }     .     .     .     @Override    public void onSwitchChanged(Switch switchView, boolean isChecked) {        if (mListener != null) {            mListener.onSwitchToggled(isChecked);        }    }    .    .    .}

上面的两个函数startListening和onSwitchChanged是重点,一个是启动SwitchBar的监听,一个监听到有变化之后的调用

然后我们再回到刚才的createWifiEnabler函数调用的WifiEnabler类
/aosp/packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java

@VisibleForTesting    WifiEnabler(Context context, SwitchWidgetController switchWidget,            MetricsFeatureProvider metricsFeatureProvider,            ConnectivityManagerWrapper connectivityManagerWrapper) {        mContext = context;        mSwitchWidget = switchWidget;        mSwitchWidget.setListener(this);        mMetricsFeatureProvider = metricsFeatureProvider;        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);        mConnectivityManager = connectivityManagerWrapper;        mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);        // The order matters! We really should not depend on this. :(        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);        setupSwitchController();    }

WifiEnabler类我们重点看setupSwitchController这个函数

    public void setupSwitchController() {        final int state = mWifiManager.getWifiState();        handleWifiStateChanged(state);        if (!mListeningToOnSwitchChange) {            mSwitchWidget.startListening();            mListeningToOnSwitchChange = true;        }        mSwitchWidget.setupView();    }

在setupSwitchController函数中,我们看到有
if (!mListeningToOnSwitchChange) {
mSwitchWidget.startListening();
mListeningToOnSwitchChange = true;
}
这里是调用前面的启动监听将mListeningToOnSwitchChange设为true,这样当我们点击wifi开关按钮的时候就会调用前面的onSwitchChanged随即调用mListener.onSwitchToggled(isChecked);
下面再来看看onSwitchToggled这个函数

public boolean onSwitchToggled(boolean isChecked) {        //Do nothing if called as a result of a state machine event        if (mStateMachineEvent) {            return true;        }        // Show toast message if Wi-Fi is not allowed in airplane mode        if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();            // Reset switch to off. No infinite check/listenenr loop.            mSwitchWidget.setChecked(false);            return false;        }        // Disable tethering if enabling Wifi        if (mayDisableTethering(isChecked)) {            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);        }        if (isChecked) {            mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_WIFI_ON);        } else {            // Log if user was connected at the time of switching off.            mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_WIFI_OFF,                    mConnected.get());        }        if (!mWifiManager.setWifiEnabled(isChecked)) {            // Error            mSwitchWidget.setEnabled(true);            Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();        }        return true;    }

我们可以看到WifiEnabler开关SwitchToggled中会调用WifiManager.setWifiEnabled方法。
看到这里其实发现应用层打开和关闭WiFi就是调用了WifiManager的setWifiEabled(boolean)接口。

2.2 WiFi framework

看下WifiManager的setWifiEabled(boolean)接口

framework/base/wifi/java/android/net/wifi/WifiManager.javapublic boolean setWifiEnabled(boolean enabled) {        try {            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }

应用层的WifiManager都是怎么来的呢

mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

2.2.1 mService是什么

而WifiManager.setWifiEnabled函数中的mService是啥呢

IWifiManager mService;
 public WifiManager(Context context, IWifiManager service, Looper looper) {        mContext = context;        mService = service;        mLooper = looper;        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;    }

其实WiFiManager使用aidl方式和WifiService进行通信。

frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl

     boolean setWifiEnabled(String packageName, boolean enable);

2.3.最终调用的的是WifiServiceImpl中的setWifiEnabled方法:
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);

2.4. WifiController状态机处理消息:CMD_WIFI_TOGGLED

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java

WifiController状态机的状态变化,这里我们只说softap关闭状态下打开sta的情况;有时间的话,可以跟一下softap打开状态下打开sta的流程。这里只需关注“Turn ON STA” .

2.4.1 ApStaDisabledState 状态下,不对CMD_WIFI_TOGGLED消息处理

2.4.2 转向StaEnabledState状态,在该状态的enter()函数中启动supplicant, processMessage中会根据扫描、sta/ap共存等条件做相应的状态处理。

class StaEnabledState extends State {        @Override        public void enter() {            mWifiStateMachine.setSupplicantRunning(true);        }        @Override        public boolean processMessage(Message msg) {            switch (msg.what) {                case CMD_WIFI_TOGGLED:                    if (! mSettingsStore.isWifiToggleEnabled()) {                        if (mSettingsStore.isScanAlwaysAvailable()) {                            transitionTo(mStaDisabledWithScanState);                        } else {                            transitionTo(mApStaDisabledState);                        }                    }                    break;

可以看到WifiController再让mWifiStateMachine状态机去启动Supplicant
下面看看mWifiStateMachine.setSupplicantRunning(true);

2.5. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java

  public void setSupplicantRunning(boolean enable) {        if (enable) {            sendMessage(CMD_START_SUPPLICANT);        } else {            sendMessage(CMD_STOP_SUPPLICANT);        }    }

从上面可以看到setSupplicantRunning发送了一个消息CMD_START_SUPPLICANT,那么我们就到WifiStateMachine的InitialState状态里面去看看processMessage函数
2.6. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java

这里先简单给出wifi状态机WifiStateMachine的各状态及结构。

WifiStateMachine state:    |- DefaultState        |-- InitialState        |-- SupplicantStartingState        |-- SupplicantStartedState            |--- ScanModeState            |--- ConnectModeState                |---- L2ConnectedState                    |----- ObtainingIpState                    |----- ConnectedState                    |----- RoamingState                |---- DisconnectingState                |---- DisconnectedState                |---- WpsRunningState                |---- FilsState            |--- WaitForP2pDisableState        |-- SupplicantStoppingState        |-- SoftApstate

InitialState状态中处理消息:CMD_START_SUPPLICANT, 做加载驱动、启动supplicant操作,mWifiMonitor.startMonitoring然后转向SupplicantStartingState状态。

    class InitialState extends State {        @Override        public boolean processMessage(Message message) {            logStateAndMessage(message, this);        switch (message.what) {        case CMD_START_SUPPLICANT:           ...            mClientInterface = mWifiNative.setupForClientMode();                              // loadDriver           ...                               if (!mWifiNative.enableSupplicant()) {                         // start supplicant                        loge("Failed to start supplicant!");                        setWifiState(WifiManager.WIFI_STATE_UNKNOWN);                        cleanup();                        break;                    }                    if (mVerboseLoggingEnabled) log("Supplicant start successful");                    mWifiMonitor.startMonitoring(mInterfaceName, true);                      //startMonitoring                    mWifiInjector.getWifiLastResortWatchdog().clearAllFailureCounts();                    setSupplicantLogLevel();                    transitionTo(mSupplicantStartingState);                    break;

2.7. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

    public Pair<Integer, IClientInterface> setupForClientMode() {        if (!startHalIfNecessary(true)) {                                                              // start Hal            Log.e(mTAG, "Failed to start HAL for client mode");            return Pair.create(SETUP_FAILURE_HAL, null);        }        IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode();        if (iClientInterface == null) {            return Pair.create(SETUP_FAILURE_WIFICOND, null);        }        return Pair.create(SETUP_SUCCESS, iClientInterface);    }

//启动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

2.8. 不同于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

2.9. 继续跟mIWifiStaIface = mHalDeviceManager.createStaIface(null, null);

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);

2.10. 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);        }

2.11. hardware/interfaces/wifi/1.0/default/wifi_mode_controller.cpp

 bool WifiModeController::changeFirmwareMode(IfaceType type)         driver_tool_->LoadDriver()        driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))

2.12. 最后调到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;

2.13 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打开的相关工作已经完成。

有些平台把加载wifi驱动的动作放在了开机时,在init.$(target).rc文件中:

insmod /vendor/lib/modules/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 := ""

参考https://blog.csdn.net/h784707460/article/details/79572861

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. 浅析android通过jni控制service服务程序的简易流程
  4. Android(安卓)Wifi模块分析(三)
  5. Android中dispatchDraw分析
  6. Android四大基本组件介绍与生命周期
  7. Android(安卓)Service AIDL
  8. Android(安卓)bluetooth介绍(四): a2dp connect流程分析
  9. Android调用天气预报的WebService简单例子

随机推荐

  1. Android下BroadcastReceiver应用详解
  2. Android(安卓)音频的播放之一
  3. Android评论留言页面
  4. Android 6.0 源代码编译实践
  5. Android中下拉列表框操作
  6. Android让一个apk作为Launcher启动
  7. Android 网络操作(上传下载等)
  8. android程序安全注意点
  9. Android 探究 LayoutInflater setFactory
  10. Android 线程池管理工具类