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);
}相关文章:
Android wifi 框架以及Enable流程
Android P相比于Android O的变化 多了WifiStateMachinePrime(状态机的前处理机制),wifiService的相关cmd 不再是直接send 给WifiStateMachine,而是被送到WifiStateMachinePrime先进行处理后,再送往WifiStateMachine也…...
十五、机器学习进阶知识:K-Means聚类算法
文章目录 1、聚类概述2、K-Means聚类算法原理3、K-Means聚类实现3.1 基于SKlearn实现K-Means聚类3.2 自编写方式实现K-Means聚类 4、算法不足与解决思路4.1 存在的问题4.2 常见K值确定方法4.3 算法评估优化思路 1、聚类概述 聚类(Clustering)是指将不同…...
软件崩溃时Visual Studio中看不到有效的调用堆栈,使用Windbg动态调试去分析定位
目录 1、问题说明 2、使用Windbg查看崩溃时详细的函数调用堆栈...
搭乘“低代码”快车,引领食品行业数字化转型全新升级
数字化技术作为重塑传统行业重要的力量,正以不可逆转的趋势改变着企业经营与客户消费的方式。 在近些年的企业数字化服务与交流过程中,织信团队切实感受到大多数企业经营者们从怀疑到犹豫再到焦虑最终转为坚定的态度转变。 在这场数字化转型的竞赛中&a…...
Axure->Axure安装,Axure菜单栏和工具栏功能介绍,页面及概要区
Axure安装Axure菜单栏和工具栏功能介绍,页面及概要区 1.Axure安装 即时设计 - 可实时协作的专业 UI 设计工具 (js.design) 点击上方下载安装⬆ 打开软件点击帮助->管理授权-> 被授权人 Axure 授权密钥:gjqpIxSSUUqFwPoZPi8XwBBhRE2VNmOQsrord0JqShk4QCXxrw6…...
【BUG】微信小程序image不会随着url动态变化
问题描述: 第一次打开界面,显示的是默认头像而不是用户头像,似乎image里面的src只要第一次有值就不会再更新了 解决 不要给src里面的变量设置初始值,而是直接赋空值...
供应链管理痛点大解析!内附解决方案
供应链是指涉及产品或服务生产、运输、分销和最终交付给客户的过程。 用一个汽车制造的例子来帮助大家理解: 原材料采购: 汽车制造商需要从供应商处采购制造汽车所需的原材料,例如金属、橡胶、塑料和玻璃。生产制造:获得原材料&…...
【Python深度学习第二版】学习笔记之——神经网络
首先来说对于神经网络这几章看的很懵,虽然作者已经去掉了数学公式相关内容,讲得已经很想让读者容易理解了,奈何读完还是一知半解,下面就以我目前的理解简单记录一下吧,往后了解的多了再回头看一看。 一、张量运算 作…...
计算机视觉之手势、面部、姿势捕捉以Python Mediapipe为工具
计算机视觉之手势、面部、姿势捕捉以 Python Mediapipe为工具 文章目录 1.Mediapipe库概述2.手势捕捉(hands)3.面部捕捉(face)4.姿势捕捉(pose) 1.Mediapipe库概述 Mediapipe是一个开源且强大的Python库,由Google开发和维护。它提供了丰富的工具和功能,…...
基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(一)——创建Glue
1 通过Athena查询s3中的数据 此实验使用s3作为数据源 ETL: E extract 输入 T transform 转换 L load 输出 大纲 1 通过Athena查询s3中的数据1.1 架构图1.2 创建Glue数据库1.3 创建爬网程序1.4 创建表1.4.1 爬网程序创建表1.4.2 手动创建表 1…...
Vue学习计划-Vue2--VueCLi(二)vuecli脚手架创建的项目内部主要文件分析
1. 文件分析 1. 补充: 什么叫单文件组件? 一个文件中只有一个组件 vue-cli创建的项目中,.vue的文件都是单文件组件,例如App.vue 2. 进入分析 1. package.json: 项目依赖配置文件: 如图,我们说主要的属性…...
spring boot项目如何自定义参数校验规则
spring boot项目对参数进行校验时,比如非空校验,可以直接用validation包里面自带的注解。但是对于一些复杂的参数校验,自带的校验规则无法满足要求,此时需要我们自定义参数校验规则。自定义校验规则和自带的规则实现方式一样&…...
springboot整合xxl-job,通过代码进行调度中心注册开启任务等
背景:由于工作需要,当用户在登录时自动触发定时任务。而不需要我们手动到调度中心管理页面去创建任务。 工程介绍:分为两个项目,第一个是调度中心的项目(xxl-job-admin)。第二个是我们自己的项目࿰…...
k8s集群部分使用gpu资源的pod出现UnexpectedAdmissionError问题
记录一次排查UnexpectedAdmissionError问题的过程 1. 问题 环境 3master节点N个GPU节点 kubelet版本:v1.19.4 kubernetes版本:v1.19.4 生产环境K8S集群,莫名其妙的出现大量UnexpectedAdmissionError状态的Pod,导致部分任务执…...
自定义 el-select 和 el-input 样式
文章目录 需求分析el-select 样式el-input 样式el-table 样式 需求 自定义 选择框的下拉框的样式和输入框 分析 el-select 样式 .select_box{// 默认placeholder:deep .el-input__inner::placeholder {font-size: 14px;font-weight: 500;color: #3E534F;}// 默认框状态样式更…...
解决本地centos虚拟机重启,自动变换 ip 地址的问题
修改网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33 原配置: TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"dhcp" DEFROUTE"yes" IPV4_FAILURE_FATAL"no" IPV6INI…...
pt36项目短信OAth2.0
5、短信验证码 1、注册容联云账号,登录并查看开发文档(以下分析来自接口文档) 2、开发文档【准备1】:请求URL地址1.示例:https://app.cloopen.com:8883/2013-12-26/Accounts/{}/SMS/TemplateSMS?sig{}ACCOUNT SID# s…...
教师们如何一对一私发成绩?
在传统的教育中,老师通常会通过班级群或家长会等方式发布学生的成绩信息。然而,这种公开的方式可能会让一些学生感到尴尬和不安,因为他们可能不愿意让其他人知道他们的成绩情况。为了解决这个问题,今天我就给老师们推荐一款免费的…...
12.11
1.q,w,e亮led1,2,3; a,s,d灭led1,2,3; main.c #include "uar1.h"#include "led.h"void delay(int ms){int i,j;for(i0;i<ms;i){for…...
Spring JdbcTemplate
一、简介 Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多的操作模板类。 针对操作关系型数据: jdbcTemplateHibe…...
惯性导航解算及误差分析
目录 1.连续时间下三维运动的微分性质 1.1 旋转矩阵的微分方程 1.2 四元数的微分方程 1.3 旋转向量的微分方程 2.惯性导航解算 2.1 姿态更新 2.2 速度更新 2.3 位置更新 3.惯性导航误差分析 3.1 姿态误差微分方程 3.2 速度误差微分方程 3.3 位置误差方程 3.4 bias…...
c++如何通过文件映射mmap在多进程间实现高性能数据共享【进阶】
mmap 多进程共享必须用 MAP_SHARED,因其确保所有进程映射同一物理页并同步回文件;MAP_PRIVATE 为写时复制,修改不共享。需 O_RDWR 打开、ftruncate 预设大小,并配合适当同步机制。为什么 mmap 在多进程共享中必须用 MAP_SHARED 而…...
环境配置实战:从CUDA与PyTorch版本不匹配报错到多版本灵活管理
1. 当PyTorch遇上CUDA:版本冲突的幕后真相 刚跑起来的深度学习代码突然报错"RuntimeError: The detected CUDA version mismatches...",这种场景就像你拿着iPhone充电器想给安卓手机充电——插口根本不匹配。我去年在部署一个图像识别项目时就…...
VR摩托车|沉浸式交通安全教育的新方向
在交通安全教育不断创新的今天,如何让参与者真正理解风险、形成安全意识,成为教育场景中的关键问题。传统的宣讲与视频观看虽然信息完整,却常因缺乏代入感而难以真正触动体验者。而“VR摩托车”作为一款结合虚拟现实技术、实景交互系统和交通…...
储能变流器双向软开关设计:从拓扑选型到控制策略的工程实现
一、储能PCS的技术挑战与设计目标1.1 储能系统的核心需求储能变流器(PCS)是实现电池与电网之间能量双向流动的关键设备,在充电模式下将电网交流电转换为直流电为电池充电,在放电模式下将电池直流电转换为交流电馈入电网或供给负载…...
构建高效Cursor Pro功能解锁的模块化架构实现指南
构建高效Cursor Pro功能解锁的模块化架构实现指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial request limi…...
Zotero PDF Preview:在文献库中无缝预览PDF的终极指南
Zotero PDF Preview:在文献库中无缝预览PDF的终极指南 【免费下载链接】zotero-pdf-preview Preview Zotero attachments in the library view. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-pdf-preview 在学术研究和文献管理工作中,频繁…...
3大核心能力+2套配置方案:obsidian-i18n终极汉化指南
3大核心能力2套配置方案:obsidian-i18n终极汉化指南 【免费下载链接】obsidian-i18n 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-i18n 面对全英文的应用界面,你是否曾因语言障碍而错失高效工具?当专业术语晦涩难懂&#…...
实战演练:基于快马AI快速构建竞品价格监控爬虫系统
今天想和大家分享一个非常实用的爬虫实战项目——竞品价格监控系统。这个系统可以帮助我们实时跟踪不同电商平台上同类产品的价格变化,对于市场调研、价格策略制定都很有帮助。下面我会详细介绍整个实现过程,以及我在使用InsCode(快马)平台时的一些体验。…...
百度网盘秒传链接网页工具终极指南:全平台免费极速转存方案
百度网盘秒传链接网页工具终极指南:全平台免费极速转存方案 【免费下载链接】baidupan-rapidupload 百度网盘秒传链接转存/生成/转换 网页工具 (全平台可用) 项目地址: https://gitcode.com/gh_mirrors/bai/baidupan-rapidupload 还在为百度网盘资源分享的繁…...
