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

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.javapublic 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.javaclass 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 WifiStateMachinePrimemWifiStateMachine.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  BroadcastmScanRequestProxy.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.javapublic IClientInterface setupInterfaceForClientMode(@NonNull String ifaceName){... clientInterface = mWificond.createClientInterface(ifaceName); //创建ClientInterface..mClientInterfaces.put(ifaceName, clientInterface); IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); // 获取WifiScannerImplPnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(ifaceName);mPnoScanEventHandlers.put(ifaceName,  pnoScanEventHandler);wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
}
http://www.lryc.cn/news/257677.html

相关文章:

  • 十五、机器学习进阶知识:K-Means聚类算法
  • 软件崩溃时Visual Studio中看不到有效的调用堆栈,使用Windbg动态调试去分析定位
  • 搭乘“低代码”快车,引领食品行业数字化转型全新升级
  • Axure->Axure安装,Axure菜单栏和工具栏功能介绍,页面及概要区
  • 【BUG】微信小程序image不会随着url动态变化
  • 供应链管理痛点大解析!内附解决方案
  • 【Python深度学习第二版】学习笔记之——神经网络
  • 计算机视觉之手势、面部、姿势捕捉以Python Mediapipe为工具
  • 基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(一)——创建Glue
  • Vue学习计划-Vue2--VueCLi(二)vuecli脚手架创建的项目内部主要文件分析
  • spring boot项目如何自定义参数校验规则
  • springboot整合xxl-job,通过代码进行调度中心注册开启任务等
  • k8s集群部分使用gpu资源的pod出现UnexpectedAdmissionError问题
  • 自定义 el-select 和 el-input 样式
  • 解决本地centos虚拟机重启,自动变换 ip 地址的问题
  • pt36项目短信OAth2.0
  • 教师们如何一对一私发成绩?
  • 12.11
  • Spring JdbcTemplate
  • 力扣编程题算法初阶之双指针算法+代码分析
  • 实现安装“自由化”!在Windows 11中如何绕过“您尝试安装的应用程序未通过微软验证”
  • 【mysql】下一行减去上一行数据、自增序列场景应用
  • CLIP在Github上的使用教程
  • 入职字节外包一个月,我离职了。。。
  • SpringBoot的web开发
  • 传染病传播速度
  • 前端打包环境配置步骤
  • css的4种引入方式--内联样式(标签内style)、内部样式表(<style>)、外部样式表(<link>、@import)
  • GPT-4 变懒了?官方回复
  • 编译器和 IR:LLVM IR、SPIR-V 和 MLIR