当前位置: 首页 > 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);
}

相关文章:

  • 第八节HarmonyOS @Component自定义组件的生命周期
  • ubuntu虚拟机设置跳不出来
  • 【Rust】所有权的认识
  • 华为 ArkTS 边框怎么设置,当边边框怎么设置(鸿蒙开发)
  • 模拟电路学习笔记(一)之芯片篇(持续更新)
  • postgreSQL 查询所有模式的语句
  • 2023年JetBrains开发调查:Java 8仍广泛使用
  • MyBatis查询优化:枚举在条件构建中的妙用
  • OA系统是什么,能用低代码开发吗?
  • 外包干了2个月,技术明显退步了...
  • Sequential Modeling Enables Scalable Learning for Large Vision Models
  • Spring Security 6.x 系列(7)—— 源码分析之Builder设计模式
  • RK3568平台开发系列讲解(Linux系统篇)device_node 转换成 platform_device
  • CCF CSP认证 历年题目自练Day51
  • uniapp搭建内网映射测试https域名
  • ES6指北【2】—— 箭头函数
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • ES6之路之模块详解
  • Tornado学习笔记(1)
  • 闭包--闭包之tab栏切换(四)
  • 创建一个Struts2项目maven 方式
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 容器服务kubernetes弹性伸缩高级用法
  • 使用SAX解析XML
  • 微服务入门【系列视频课程】
  • 优秀架构师必须掌握的架构思维
  • 原生JS动态加载JS、CSS文件及代码脚本
  • #数学建模# 线性规划问题的Matlab求解
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (2)Java 简介
  • (52)只出现一次的数字III
  • (floyd+补集) poj 3275
  • (第二周)效能测试
  • (二)JAVA使用POI操作excel
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)Google的Objective-C编码规范
  • (转)创业家杂志:UCWEB天使第一步
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • .NET 8.0 中有哪些新的变化?
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 服务 ServiceController
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • @KafkaListener注解详解(一)| 常用参数详解
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @SuppressWarnings注解
  • [@Controller]4 详解@ModelAttribute
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • []error LNK2001: unresolved external symbol _m
  • [20181219]script使用小技巧.txt
  • [docker] Docker的私有仓库部署——Harbor
  • [ESP32] 编码旋钮驱动
  • [Flutter] extends、implements、mixin和 abstract、extension的使用介绍说明
  • [hdu 3746] Cyclic Nacklace [kmp]
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • [MySQL数据库部署及初始化相关]