Android wifi 框架以及Enable流程

Android P相比于Android O的变化

  • 多了WifiStateMachinePrime(状态机的前处理机制),wifiService的相关cmd 不再是直接send 给WifiStateMachine,而是被送到WifiStateMachinePrime先进行处理后,再送往WifiStateMachine
  • 也多了一层ClientModeManager处理(将之前初始化wpa_supplicant专门抽出一层类在这里面来做),详细看后面的代码

Wifi 整体流程框架图

  • 基本与Android O Wifi 主体框架一致
  • 三板斧的套路还是被传承下来(1. Application <--> 2. WiFiService(WifiStateMachine) <--> 3. WifiNative(wpa_supplicant -- wlan drv))

代码流程

1. WifiSettings --> WifiManager

点击 wifi button 开启wifi 触发的代码流程如下,

  • wifiSettings 响应onPreferenceTreeClick 送往WifiEnable
  • WifiEnabler 根据传入的状态,call WifiManager 设置wifi状态 (开启跳转到WifiServiceImpl)
java 复制代码
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
 public boolean onPreferenceTreeClick(Preference preference){
  ..... 
  return super.onPreferenceTreeClick(preference);
 }

packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
public boolean onSwitchToggled(boolean isChecked){
.... 
mWifiManager.setWifiEnabled(isChecked); // wifiManager 设置wifi 状态
}

2. WifiManager --> WifiService --> WifiServiceImpl -->WifiController

  • 还是老套路,逐级进入WifiService,WifiServiceImpl ,WifiController,WifiStateMachinePrime,WifiNative 等完成CMD_WIFI_TOGGLED的火炬传递
  • 注意随着Android 版本升级后,接递火炬CMD_WIFI_TOGGLED的顺序也发生了变化
  • Android P 版本WifiServiceImpl 将CMD_WIFI_TOGGLED 先送到了WifiController处理,这里稍微有点儿复杂的状态机(都会涉及到处理此cmd),具体根据设备所处状态来跟就可以。(这里以设备从开机状态第一次打开wifi为场景进行说明,此case 直接会进入)
java 复制代码
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
public boolean setWifiEnabled(boolean enabled){
 return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); // jump to WifiServiceImpl
}

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

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
 class StaDisabledState extends State {
....
   public boolean processMessage(Message msg) {
		switch (msg.what) {
		 case CMD_WIFI_TOGGLED:
		 .....
		 transitionTo(mDeviceActiveState); // jump to DeviceActiveState 
}
}
  class DeviceActiveState extends State {
       public void enter() {
          mWifiStateMachinePrime.enterClientMode(); // jump to WifiStateMachinePrime
           mWifiStateMachine.setHighPerfModeEnabled(false);
       }
  }

3. WifiController --> WifiStateMachinePrime

  • WifiStateMachinePrime 传递CMD_START_CLIENT_MODE,先在内部状态机完成一轮转动
  • ModeStateMachine --> ClientModeActiveState
  • 送往ClientModeManager 创建WifiClientModeManager 实例
java 复制代码
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachinePrime.java
public void enterClientMode() {
changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
}

private class ModeStateMachine extends StateMachine {
...
 private boolean checkForAndHandleModeChange(Message message) {
	 case ModeStateMachine.CMD_START_CLIENT_MODE:
	 mModeStateMachine.transitionTo(mClientModeActiveState); //跳转到ClientModeActiveState
 }
 }

class ClientModeActiveState extends ModeActiveState {
	public void enter() {
	mManager = mWifiInjector.makeClientModeManager(mListener); //创建ClientModeManager实例
	mManager.start(); //
	mActiveModeManagers.add(mManager);
	updateBatteryStatsWifiState(true);
	}
}

4. WifiStateMachinePrime --> ClientModeManager

  • ClientModeManager 传递ClientModeStateMachine.CMD_START 开始wpa_supplicant初始化信号
  • 更新 wifiState updateWifiState
  • 通过WifiNative初始化Client Mode
java 复制代码
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java
public void start() {
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
}

private class IdleState extends State {
public boolean processMessage(Message message) {
	 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); //send wifi  Scan Available  Broadcast
	mScanRequestProxy.enableScanningForHiddenNetworks(false);
	mScanRequestProxy.clearScanResults();
	transitionTo(mStartedState);
 }
}

5. ClientModeManager --> WifiNative

  • ClientModeManager 通过CMD_START 将启动传递给WifiNative
  • WifiNative 启动wpa_supplicant service
  • wifiNative 通过SupplicantStaHal 建立与 wpa_supplicant/hidl/1.1 的sta_iface.cpp 关联(ifaceName)
  • wifiNative 向NetworkManagementService 注册NetworkObserverInternal 实例,用于监视 设备iface一举一动
  • wifiNative 开启wifiMonitor , 其开始接手所有的事项(消息以及事件),一有变化就上报framework(wifiStateMachine、wifiServiceImpl、SupplicantStaIfaceHal等等),就像是东厂的小兵,监视着下面的一举一动,一有变化马上上报头头
java 复制代码
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
public String setupInterfaceForClientMode(boolean lowPrioritySta, @NonNull InterfaceCallback interfaceCallback) {
	... 
    	startSupplicant(); // 启动 wpa_supplicant 
    	.. 
    	mWificondControl.setupInterfaceForClientMode(iface.name); // 初始化与wificondcontrol 关联(用于后续wificond 作为framework与 wpa_supplicant 之间的通信信使
    	..
    	mSupplicantStaIfaceHal.setupIface(iface.name); // 
    	mWifiMonitor.startMonitoring(iface.name); // 启动WifiMonitor 上报所有的wpa_supplicant msg&event 
    	initializeNwParamsForClientInterface(iface.name);
}

6. WifiNative--> WificondControl

  • WificondControl 通过 binder 连接到wificond (server.cpp),创建ClientInterface
  • WificondControl 通过binder 连接到 client_interface_binder.cpp 获取 wificondScaner ,用于wifi scan(上报scan results)
  • WificondControl 创建 pnoScan + Scan Event Handler , 且将之与设备 ifaceName 关联
java 复制代码
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WificondControl.java
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WificondControl.java
 public IClientInterface setupInterfaceForClientMode(@NonNull String ifaceName){
   ... 
    clientInterface = mWificond.createClientInterface(ifaceName); //创建ClientInterface
    ..
    mClientInterfaces.put(ifaceName, clientInterface); 
     IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); // 获取WifiScannerImpl
     PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(ifaceName);
     mPnoScanEventHandlers.put(ifaceName,  pnoScanEventHandler);
     wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
}
相关推荐
baidu_247438612 小时前
Android ViewModel定时任务
android·开发语言·javascript
有位神秘人3 小时前
Android中Notification的使用详解
android·java·javascript
·云扬·3 小时前
MySQL Binlog落盘机制深度解析:性能与安全性的平衡艺术
android·mysql·adb
独自破碎E4 小时前
【BISHI9】田忌赛马
android·java·开发语言
代码s贝多芬的音符5 小时前
android 两个人脸对比 mlkit
android
darkb1rd7 小时前
五、PHP类型转换与类型安全
android·安全·php
gjxDaniel7 小时前
Kotlin编程语言入门与常见问题
android·开发语言·kotlin
csj507 小时前
安卓基础之《(22)—高级控件(4)碎片Fragment》
android
峥嵘life8 小时前
Android16 【CTS】CtsMediaCodecTestCases等一些列Media测试存在Failed项
android·linux·学习
stevenzqzq9 小时前
Compose 中的状态可变性体系
android·compose