当前位置: 首页 > article >正文

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)
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 直接会进入)
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 实例
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
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等等),就像是东厂的小兵,监视着下面的一举一动,一有变化马上上报头头
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 关联
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);
}

http://www.kler.cn/news/157212.html

相关文章:

  • 质量小议35 -- SQL注入
  • 【NI-RIO入门】Real Time(实时系统解释)
  • 开发工具idea中推荐插件
  • Flink入门之部署(二)
  • 工业机器视觉megauging(向光有光)使用说明书(十五,轻量级的visionpro)
  • 基于python和django旅游管理系统
  • Android11编译第八弹:root用户密码设置
  • Leetcode 2953. Count Complete Substrings
  • 电梯安全远程监控系统的主要作用和意义
  • 华清远见嵌入式学习——C++——作业3
  • PTA 7-223 sdut-C语言实验-求阶乘(循环结构)
  • 基于Java SSM教学管理系统
  • C语言 操作符详解
  • vue项目配置多个代理
  • SpringBoot集成Mybatis使用切面对所有Service的事务统一管理
  • xattr -r -d com.apple.quarantine是用于删除文件的扩展属性的命令
  • 五、分支和循环
  • JNPF低代码平台高效赋能开发者
  • Glide系列-活动缓存和内存缓存
  • 人工智能_机器学习060_核函数对应数学公式_数据空间错位分割_简单介绍_以及核函数总结---人工智能工作笔记0100
  • 兔子的后院奇遇:深入了解RabbitMQ中的死信队列【RabbitMQ 四】
  • 基于python电商销售数据可视化大屏全屏系统设计与实现+开题报告
  • pytorch bert实现文本分类
  • 前端开发_CSS
  • 大数据之HBase(二)
  • 《开箱元宇宙》:Madballs 解锁炫酷新境界,人物化身系列大卖
  • Linux基础操作一:连接Linux
  • 从顺序表中删除具有最小值的元素(假设唯一) 并由函数返回被删元素的值。空出的位 置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
  • 【shell】
  • 华为云购买参考:到底选购ECS还是CCE?