(一百七十八)WiFi扫描结果framework和app共享么?

2023-12-19 07:32

本文主要是介绍(一百七十八)WiFi扫描结果framework和app共享么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.流程回顾

WifiScanningServiceImpl

                    case WifiScanner.CMD_START_SINGLE_SCAN:mWifiMetrics.incrementOneshotScanCount();int handler = msg.arg2;Bundle scanParams = (Bundle) msg.obj;if (scanParams == null) {logCallback("singleScanInvalidRequest",  ci, handler, "null params");replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null");return HANDLED;}scanParams.setDefusable(true);ScanSettings scanSettings =scanParams.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY);WorkSource workSource =scanParams.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY);if (validateScanRequest(ci, handler, scanSettings)) {logScanRequest("addSingleScanRequest", ci, handler, workSource,scanSettings, null);replySucceeded(msg);// If there is an active scan that will fulfill the scan request then// mark this request as an active scan, otherwise mark it pending.// If were not currently scanning then try to start a scan. Otherwise// this scan will be scheduled when transitioning back to IdleState// after finishing the current scan.if (getCurrentState() == mScanningState) {if (activeScanSatisfies(scanSettings)) {mActiveScans.addRequest(ci, handler, workSource, scanSettings);} else {mPendingScans.addRequest(ci, handler, workSource, scanSettings);}} else {mPendingScans.addRequest(ci, handler, workSource, scanSettings);tryToStartNewScan();}} else {logCallback("singleScanInvalidRequest",  ci, handler, "bad request");replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request");mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION, 1);}return HANDLED;

1.1 扫描命令下发

首先scan有个scanSettings的设定,即扫描不是都是一样的,有细致差别,具体是在scanSettings里携带的

如果scan设定当前的囊括新来的,那么就认为是一个类别的扫描,可以一起等刚刚下发的扫描命令返回上来的扫描结果,否则进入等待队列等下一次扫描

        boolean activeScanSatisfies(ScanSettings settings) {if (mActiveScanSettings == null) {return false;}if (!activeScanTypeSatisfies(getNativeScanType(settings.type))) {return false;}// there is always one bucket for a single scanWifiNative.BucketSettings activeBucket = mActiveScanSettings.buckets[0];// validate that all requested channels are being scannedChannelCollection activeChannels = mChannelHelper.createChannelCollection();activeChannels.addChannels(activeBucket);if (!activeChannels.containsSettings(settings)) {return false;}// if the request is for a full scan, but there is no ongoing full scanif ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0&& (activeBucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)== 0) {return false;}if (!ArrayUtils.isEmpty(settings.hiddenNetworks)) {if (ArrayUtils.isEmpty(mActiveScanSettings.hiddenNetworks)) {return false;}List<WifiNative.HiddenNetwork> activeHiddenNetworks = new ArrayList<>();for (WifiNative.HiddenNetwork hiddenNetwork : mActiveScanSettings.hiddenNetworks) {activeHiddenNetworks.add(hiddenNetwork);}for (ScanSettings.HiddenNetwork hiddenNetwork : settings.hiddenNetworks) {WifiNative.HiddenNetwork nativeHiddenNetwork = new WifiNative.HiddenNetwork();nativeHiddenNetwork.ssid = hiddenNetwork.ssid;if (!activeHiddenNetworks.contains(nativeHiddenNetwork)) {return false;}}}return true;}

会判断扫描的

  • type(WifiNative.SCAN_TYPE_LOW_LATENCY WifiNative.SCAN_TYPE_LOW_POWER WifiNative.SCAN_TYPE_HIGH_ACCURACY)
  • channel(settings用的是WIFI_BAND_BOTH_WITH_DFS即2.4+5+dfs)
  • full scan
  • hiddenNetworks

是否包含这次请求的扫描,这样不是返回上来的扫描结果会比要求的多么?没必要担心,后续有过滤

1.2 扫描结果过滤

                    case CMD_SCAN_RESULTS_AVAILABLE:mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS,mActiveScans.size());reportScanResults(mScannerImpl.getLatestSingleScanResults());mActiveScans.clear();transitionTo(mIdleState);return HANDLED;void reportScanResults(ScanData results) {if (results != null && results.getResults() != null) {if (results.getResults().length > 0) {mWifiMetrics.incrementNonEmptyScanResultCount();} else {mWifiMetrics.incrementEmptyScanResultCount();}}ScanData[] allResults = new ScanData[] {results};for (RequestInfo<ScanSettings> entry : mActiveScans) {ScanData[] resultsToDeliver = ScanScheduleUtil.filterResultsForSettings(mChannelHelper, allResults, entry.settings, -1);WifiScanner.ParcelableScanData parcelableResultsToDeliver =new WifiScanner.ParcelableScanData(resultsToDeliver);logCallback("singleScanResults",  entry.clientInfo, entry.handlerId,describeForLog(resultsToDeliver));entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableResultsToDeliver);// make sure the handler is removedentry.reportEvent(WifiScanner.CMD_SINGLE_SCAN_COMPLETED, 0, null);}WifiScanner.ParcelableScanData parcelableAllResults =new WifiScanner.ParcelableScanData(allResults);for (RequestInfo<Void> entry : mSingleScanListeners) {logCallback("singleScanResults",  entry.clientInfo, entry.handlerId,describeForLog(allResults));entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults);}if (results.isAllChannelsScanned()) {mCachedScanResults.clear();mCachedScanResults.addAll(Arrays.asList(results.getResults()));}}List<ScanResult> getCachedScanResultsAsList() {return mCachedScanResults;}}

这边的filterResultsForSettings会将扫描结果按扫描settings过滤一遍再返回回来,这样既考虑了扫描效率,又考虑了扫描Setting。

    /*** Returns a filtered version of the scan results from the chip that represents only the data* requested in the settings. Will return null if the result should not be reported.** If a ScanData indicates that the bucket the settings were placed in was scanned then it* will always be included (filtered to only include requested channels). If it indicates that* the bucket was definitely not scanned then the scan data will not be reported.* If it is not possible to determine if the settings bucket was scanned or not then a* ScanData will be included if the scan was empty or there was at least one scan result that* matches a requested channel (again the results will be filtered to only include requested* channels.*/public static ScanData[] filterResultsForSettings(ChannelHelper channelHelper,ScanData[] scanDatas, ScanSettings settings, int scheduledBucket) {List<ScanData> filteredScanDatas = new ArrayList<>(scanDatas.length);List<ScanResult> filteredResults = new ArrayList<>();for (ScanData scanData : scanDatas) {// only report ScanData if the settings bucket could have been scannedif (isBucketMaybeScanned(scheduledBucket, scanData.getBucketsScanned())) {filteredResults.clear();for (ScanResult scanResult : scanData.getResults()) {if (channelHelper.settingsContainChannel(settings, scanResult.frequency)) {filteredResults.add(scanResult);}if (settings.numBssidsPerScan > 0&& filteredResults.size() >= settings.numBssidsPerScan) {break;}}// will include scan results if the scan was empty, there was at least one// one result that matched the scan request or we are sure that all the requested// channels were scanned.if (filteredResults.size() == scanData.getResults().length) {filteredScanDatas.add(scanData);} else if (filteredResults.size() > 0 || isBucketDefinitlyScanned(scheduledBucket,scanData.getBucketsScanned())) {filteredScanDatas.add(new ScanData(scanData.getId(),scanData.getFlags(),filteredResults.toArray(new ScanResult[filteredResults.size()])));}}}if (filteredScanDatas.size() == 0) {return null;} else {return filteredScanDatas.toArray(new ScanData[filteredScanDatas.size()]);}}

 

2.总结

WiFi扫描结果framework和app共享这个要看是否这两者的扫描settings处于包含关系,比如framework的扫描settings包含app的,那么它们可以共一次扫描的扫描结果,但是app拿到的扫描结果后续会按照scansettings过滤一下。

这样既考虑效率又考虑特殊需求的处理很符合逻辑了。

举例Settings的扫描是TYPE_HIGH_ACCURACY + WIFI_BAND_BOTH_WITH_DFS,而framework比如WifiConnectivityManager的扫描TYPE_HIGH_ACCURACY,但WIFI_BAND_BOTH_WITH_DFS不能保证。

另外扫描结果依赖注册的listener回调,即即使scan Settings一样,settings还没下发扫描,framework的扫描结果settings也是拿不到的,上层应用是从ScanRequestProxy下发扫描命令和获取扫描结果的,而WifiConnectivityManager是自己下发到WiFiscanner并且自己注册监听器的。

这篇关于(一百七十八)WiFi扫描结果framework和app共享么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/511371

相关文章

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如