Android wifi Enable之后扫描流程

流程框架图

通常我们在设备开启wifi之后,等会会自动扫描出周围的热点。

下面看下自动扫描周围热点的流程

代码流程

1. ClientModeManager.ClientModeStateMachine

  • ClientModeStateMachine 由CMD_START 转换到StartedState
  • StartedState 状态机,在更新wifiState时,发送广播 WifiManager.WIFI_STATE_CHANGED_ACTION , 通知WifiTracker 开始进行Scan
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java
public boolean processMessage(Message message) {.... mClientInterfaceName = mWifiNative.setupInterfaceForClientMode....transitionTo(mStartedState); //跳转到 StartedState
}private class StartedState extends State {...private void onUpChanged(boolean isUp) {.... sendScanAvailableBroadcast(true);mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,// 发 WifiManager.WIFI_STATE_CHANGED_ACTION 广播通知 wifiTracker 启动startScanupdateWifiState(WifiManager.WIFI_STATE_ENABLED,WifiManager.WIFI_STATE_ENABLING); }
}

2. WifiTracker.BroadcastReceiver --> wifiManager.StartScan

  • WifiTracker 广播监听到WifiManager.WIFI_STATE_CHANGED_ACTION ,开启wifiManager.StartScan
frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
public void onReceive(Context context, Intent intent) {if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,WifiManager.WIFI_STATE_UNKNOWN));
}
}
private void updateWifiState(int state) {1. WifiManager.WIFI_STATE_ENABLEDmScanner.resume();2.wifi 非enabled 则 mScanner.pause();
}
public void handleMessage(Message message) {.. mWifiManager.startScan(); // 开启Wifi Scan 
}

3. wifiManager.StartScan --> WifiServiceImpl --> ScanRequestProxy.StartScan

  • 获取mWifiScanner 实例
  • 检查 调用者UID , apk package 是否有权限进行Scan,如无则直接放回
  • Create a worksource using the caller’s UID.
  • Create the scan settings.
  • 初始化Scan 的band 为DFS,是否Scan 隐藏的AP
  • mWifiScanner 发起StartScan
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ScanRequestProxy.java
public boolean startScan(int callingUid, String packageName){retrieveWifiScannerIfNecessary();...// Create a worksource using the caller's UID.WorkSource workSource = new WorkSource(callingUid);// Create the scan settings.WifiScanner.ScanSettings settings = new WifiScanner.ScanSettings();// always do full scanssettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN| WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;mWifiScanner.startScan(settings, new ScanRequestProxyScanListener(), workSource);
}

4. WifiScanner.startScan --> WifiScaningServiceImpl.ClientHandler.handleMessage

  • 发送scan 请求[CMD_START_SINGLE_SCAN ] to WifiScaningServiceImpl 处理
frameworks/base/wifi/java/android/net/wifi/WifiScanner.java
public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) {scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);
}

5. WifiScanner.startScan --> WifiScaningServiceImpl.ClientHandler.handleMessage

  • 先进行有效Scan检查
  • 当前正在Scanning,如为有效的(活)scaning,标志为ActiveScans,否则标志为PendingScans
  • 当前非Scanning,标志为PendingScans,开启一次新的Scan – tryToStartNewScan()
  • 非有效Scan,上报错误Failed
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.javaclass DriverStartedState extends State {case WifiScanner.CMD_START_SINGLE_SCAN:.... 一大堆code (其实就干了几件事情,见上面描述)....tryToStartNewScan();}

6. WifiScaningServiceImpl.tryToStartNewScan – WifiNative.scan

  • WifiScaningServiceImpl 到WifiScannerImpl
  • WifiScannerImpl 再到WificondScannerImpl
  • WificondScannerImpl最终到WifiNative , 可见与Android N 相比,O、P 的Scan变化太大,但是其套路还是不变,就是上面的环节无论是如何地进行封装,最后还是给到WifiNative 来处理
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
void tryToStartNewScan() {....mScannerImpl.startSingleScan(settings, this);
}frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java
public abstract boolean startSingleScan(WifiNative.ScanSettings settings,WifiNative.ScanEventHandler eventHandler);frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WificondScannerImpl.javapublic boolean startSingleScan(WifiNative.ScanSettings settings,    WifiNative.ScanEventHandler eventHandler) {....freqs = allFreqs.getScanFreqs();success = mWifiNative.scan(mIfaceName, settings.scanType, freqs, hiddenNetworkSSIDSet);}

7. WifiNative.scan --> WificondControl

  • WifiNative 转到 WificondControl
  • WificondControl 通过binder 到wificond
  • wificond 开始初步的scan 任务 (scannerImpl.scan)
  • scannerImpl 传到scan_utils
  • scan_utils 通过netlink 将 NL80211_CMD_TRIGGER_SCAN传递wpa_supplicant(driver_nl80211_event.c)
  • driver_nl80211_event 将cmd下到wlan drv 里,开始了真正的干活 – scanning
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
public boolean scan( @NonNull String ifaceName, int scanType, Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
}frameworks/opt/net/wifi/service/java/com/android/server/wifi/WificondControl.javapublic boolean scan(@NonNull String ifaceName, int scanType, Set<Integer> freqs,Set<String> hiddenNetworkSSIDs)
{..  scannerImpl.scan(settings); 
}system/connectivity/wificond/scanning/scanner_impl.cpp
Status ScannerImpl::scan(const SingleScanSettings& scan_settings, bool* out_success) {scan_utils_->Scan(interface_index_, request_random_mac, scan_type,ssids, freqs, &error_code); // 
}
system/connectivity/wificond/scanning/scan_utils.cpp
bool ScanUtils::Scan(uint32_t interface_index,bool request_random_mac,int scan_type,const vector<vector<uint8_t>>& ssids,const vector<uint32_t>& freqs,int* error_code) {NL80211Packet trigger_scan(netlink_manager_->GetFamilyId(),NL80211_CMD_TRIGGER_SCAN,netlink_manager_->GetSequenceNumber(),getpid());if (scan_flags) {trigger_scan.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_SCAN_FLAGS,scan_flags));}// We are receiving an ERROR/ACK message instead of the actual// scan results here, so it is OK to expect a timely response because// kernel is supposed to send the ERROR/ACK back before the scan starts.vector<unique_ptr<const NL80211Packet>> response;if (!netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,error_code)) {// Logging is done inside |SendMessageAndGetAckOrError|.return false;}
}

8. 扫描结果回传

  • 具体与scan 执行流恰为逆向,可参见上面的整体框架图
  • 这里简单说明下,当wlan drv 完成scan 之后
  • 由 wificond 直接给到WificondControl,
  • WificondControl.OnScanResultReady 上报 WifiMonitor
  • WifiMonitor -> WificondScannerImpl -> WifiScaningServiceImpl->
  • WifiScaningServiceImpl ->WifiService --> WifiTraker --> WifiSettings 刷新扫描结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/197984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

让代码变得优雅简洁的神器:Java8 Stream流式编程

原创/朱季谦 本文主要基于实际项目常用的Stream Api流式处理总结。 因笔者主要从事风控反欺诈相关工作&#xff0c;故而此文使用比较熟悉的三要素之一的【手机号】黑名单作代码案例说明。 我在项目当中&#xff0c;很早就开始使用Java 8的流特性进行开发了&#xff0c;但是一直…

流媒体方案之FFmpeg——实现物联网视频监控项目

目录 前言 一、FFmpeg介绍 二、FFmpeg简易理解 三、FFmpeg的重要概念 四、软硬件准备 五、移植、运行FFmpeg 六、运行FFmpeg 前言 最近想做一个安防相关的项目&#xff0c;所以跟着韦东山老师的视频来学习视频监控方案的相关知识&#xff0c;韦东山老师讲的课非常好&…

LaTex入门简明教程

文章目录 写在前面安装Texlive的安装TeXstudio 的安装 LaTex 的使用节指令图指令表指令公式指令参考文献指令引用指令TeXstudio 编译 LaTex 的 \label{} 写法建议最后 写在前面 这篇文章面向没有任何 LaTex 基础的小白&#xff0c;主要讲解了 LaTex 的安装和使用。读完文章之后…

android https 证书过期

有的时候 我们android https 证书过期 &#xff0c;或者使用明文等方式去访问服务器 可能会碰到类似的 问题 &#xff1a; javax.net.ssl.SSLHandshakeException: Chain validation failed java.security.cert.CertPathValidatorException: Response is unreliable: its validi…

通讯录管理系统(基于C语言)

模块设计 本通讯录管理系统功能模块共包括9个部分&#xff1a;1.输入数据、2.显示数据、 3.插入数据、4.删除数据、5.查看数据、6.修改数据、7.保存数据、 8.返回主菜单、9.退出系统. 一&#xff0e;总体设计 通讯录的每一条信息包括&#xff1a;姓名、性别、住址、联系电话…

西南科技大学模拟电子技术实验七(集成运算放大器的非线性应用)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) 预习计算内容根据运放的非线…

【Linux下如何生成coredump文件】

一&#xff0c;什么是coredump 我们经常听到大家说到程序core掉了&#xff0c;需要定位解决&#xff0c;这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;并且在满足一定条件下&#xff08;这里为什么说需要满足一定的条件呢&#…

QT使用SQLite(打开db数据库以及对数据库进行增删改查)

QTSQLite 在QT中使用sqlite数据库&#xff0c;有多种使用方法&#xff0c;在这里我只提供几种简单&#xff0c;代码简短的方法&#xff0c;包括一些特殊字符处理。 用SQlite建立一个简单学生管理数据库 数据库中有两个表一个是class和student。 class表结构 student表结果…

非标设计之气缸类型

空压机&#xff1a; 空压机又称空气压缩机&#xff0c;简单来说就是将机械能转化为压力能来进行工作的&#xff0c;空压机在电力行业应用比较多&#xff0c;除了在电力行业应用较多外&#xff0c;其实空压机还有一个比较常见的用途就是用来制冷和分离气体&#xff0c;输送气体…

【web安全】RCE漏洞原理

前言 菜某的笔记总结&#xff0c;如有错误请指正。 RCE漏洞介绍 简而言之&#xff0c;就是代码中使用了可以把字符串当做代码执行的函数&#xff0c;但是又没有对用户的输入内容做到充分的过滤&#xff0c;导致可以被远程执行一些命令。 RCE漏洞的分类 RCE漏洞分为代码执行…

RT-Thread 三步实现利用DMA进行串口发送

应某些网友需求&#xff0c;说网上根本找不到基于Rt-Thread DMA串口发送代码&#xff0c;只有官方开源的串口DMA接收。 其实这些东西并不难&#xff0c;只要你细心去看哪些闲置的驱动文件且都是包装好的&#xff0c;通过关键字去查询或点开源文件查看&#xff0c;花不了几分钟…

【C/PTA —— 14.结构体1(课内实践)】

C/PTA —— 14.结构体1&#xff08;课内实践&#xff09; 6-1 计算两个复数之积6-2 结构体数组中查找指定编号人员6-3 综合成绩6-4 结构体数组按总分排序 6-1 计算两个复数之积 struct complex multiply(struct complex x, struct complex y) {struct complex product;product.…

Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

解决 Selenium 自动化中的常见疑难杂症 这里记录一些关于 Selenium的常用操作和疑难杂症。 有一些细节的知识点就不重复介绍了&#xff0c;因为之前的文章中都有&#xff01; 如果对本文中的知识点有疑问的&#xff0c;可以先阅读我以前分享的文章&#xff01; 知识点&…

PyQt实战 创建一个PyQt5项目

前后端分离 参考链接 PyQt5实战&#xff08;二&#xff09;&#xff1a;创建一个PyQt5项目_pyqt5实战项目_笨鸟未必先飞的博客-CSDN博客 项目目录 创建一个QT项目 调用pyuic工具将dialog.ui文件编译为Python程序文件ui_dialog.py。 # -*- coding: utf-8 -*-# Form implemen…

【离散差分】LeetCode2953:统计完全子字符串

作者推荐 [二分查找]LeetCode2040:两个有序数组的第 K 小乘积 本题其它解法 【滑动窗口】LeetCode2953:统计完全子字符串 涉及知识点 分块循环 离散差分 题目 给你一个字符串 word 和一个整数 k 。 如果 word 的一个子字符串 s 满足以下条件&#xff0c;我们称它是 完全…

云原生之深入解析如何限制Kubernetes集群中文件描述符与线程数量

一、背景 linux 中为了防止进程恶意使用资源&#xff0c;系统使用 ulimit 来限制进程的资源使用情况&#xff08;包括文件描述符&#xff0c;线程数&#xff0c;内存大小等&#xff09;。同样地在容器化场景中&#xff0c;需要限制其系统资源的使用量。ulimit: docker 默认支持…

08、分析测试执行时间及获取pytest帮助

官方用例 # content of test_slow_func.py import pytest from time import sleeppytest.mark.parametrize(delay,(1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.0,0.1,0.2,0,3)) def test_slow_func(delay):print("test_slow_func {}".format(delay))sleep(delay)assert…

同旺科技 USB TO SPI / I2C --- 调试W5500_TCP Client测试

所需设备&#xff1a; 内附链接 1、USB转SPI_I2C适配器(专业版); 首先&#xff0c;连接W5500模块与同旺科技USB TO SPI / I2C适配器&#xff0c;如下图&#xff1a; 网关IP地址寄存器(192.168.1.1)子网掩码寄存器(255.255.255.0)源MAC地址寄存器源IP地址寄存器(192.168.1.8)…

QT4和 QT5 槽函数连接的区别

正常连接方式 //QT4官方用列QLabel *label new QLabel;QScrollBar *scrollBar new QScrollBar;QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));//QT5官方用列QLabel *label new QLabel;QLineEdit *lineEdit new QLineEdit;QObject::c…

STK Components 二次开发-飞行器

1.创建飞机 参数帮助文档 var poitList GetTracksData(); var waypointPropagator new WaypointPropagator(m_earth, poitList); var locationPoint waypointPropagator.CreatePoint();m_aircraft new Platform {Name "MH730",LocationPoint locationPoint,Or…