1. WifiConnectivityManager 管理连接过程


在其收到底层传递的扫描结果消息时,在 handleScanResults 中处理,里面调用了如下主要步骤:

  • 用到了 NetworkSelector 类对象进行处理,getCandidatesFromScan,以 ScanDetail 对象列表为输入获取到 WifiCandidates.Candidate 对象列表;
  • 用到了 NetworkSelector 类对象进行处理,SelectNetwork,以前面的 WifiCandidates.Candidate 列表为输入,经过处理获取到 WifiConfiguration 对象用来连接;
  • 继续调用同类方法 connectToNetwork,传入 WifiConfiguration 对象作为参数开启连接过程

1.1 WifiNetworkSelector 获取候选 WifiCandidates


WifiNetworkSelector 主要的两个方法如前面提到,这里分析第一个用于获取候选扫描结果的接口

getCandidatesFromScan


  • 创建新的 WifiCandidates 对象,其内部维护了内部类 Candidates 对应的一个 map
  • 调用 filterScanResults 对结果进行过滤
  • 遍历所有的 NetworkNominator 对象,执行其 nominateNetworks 接口,其参数信息和说明如下:
        /*** Evaluate all the networks from the scan results.** @param scanDetails             a list of scan details constructed from the scan results* @param currentNetwork          configuration of the current connected network*                                or null if disconnected* @param currentBssid            BSSID of the current connected network or null if*                                disconnected* @param connected               a flag to indicate if ClientModeImpl is in connected*                                state* @param untrustedNetworkAllowed a flag to indicate if untrusted networks like*                                ephemeral networks are allowed* @param onConnectableListener   callback to record all of the connectable networks*/void nominateNetworks(List<ScanDetail> scanDetails,WifiConfiguration currentNetwork, String currentBssid,boolean connected, boolean untrustedNetworkAllowed,OnConnectableListener onConnectableListener);

重点是 scanDetails 和 onConnectableListener 两个对象,其中 OnConnectableListener 接口类如下:

        /*** Callback for recording connectable candidates*/public interface OnConnectableListener {/*** Notes that an access point is an eligible connection candidate** @param scanDetail describes the specific access point* @param config     is the WifiConfiguration for the network*/void onConnectable(ScanDetail scanDetail, WifiConfiguration config);}

在此处调用的接口 onConnectable 即为:

                    void onConnectable(ScanDetail scanDetail, WifiConfiguration config){WifiCandidates.Key key = wifiCandidates.keyFromScanDetailAndConfig(scanDetail, config);if (key != null) {boolean metered = isEverMetered(config, wifiInfo, scanDetail);// TODO(b/151981920) Saved passpoint candidates are marked ephemeralboolean added = wifiCandidates.add(key, config,registeredNominator.getId(),scanDetail.getScanResult().level,scanDetail.getScanResult().frequency,calculateLastSelectionWeight(config.networkId),metered,isFromCarrierOrPrivilegedApp(config),predictThroughput(scanDetail));if (added) {mConnectableNetworks.add(Pair.create(scanDetail, config));mWifiConfigManager.updateScanDetailForNetwork(config.networkId, scanDetail);mWifiMetrics.setNominatorForNetwork(config.networkId,toProtoNominatorId(registeredNominator.getId()));}}}

经过 nominateNetworks 处理最终得到了 WifiCandidates 对象 wifiCandidates,最终将其 Candidates 对象列表返回

这里需要分析 NetworkNominator 以及其 nominateNetworks 接口的处理过程才能明白 wifiCandidates 和 mConnectableNetworks 如何生成其列表的

2. NetworkNominator


是 NetworkSelector 的内部类,其内部对象记录在 mNominators 中,通过 WifiNetworkSelector 的 registerNetworkNominator 方法注册

在 WifiInjector 的构造过程中注册了三个 Nominator 对象:

  • SavedNetworkNominator:用于保存的网络
  • NetworkSuggestionNominator:用于提供最高可用性候选建议
  • ScoredNetworkNominator:用于通过评分机制选择网络连接,用到了 NetworkScoreManager 用于管理网络评分

三者均是在 WifiInjector 初始化过程中创建和初始化的并注册到 WifiNetworkSelector 中,此处分别对其 nominateNetworks 进行分析

SavedNetworkNominator::nominateNetworks 采用两个步骤 分别通过 findMatchedSavedNetworks 和 findMatchedPasspointNetworks 对用户配置保存的和 passpoint 网络信息进行查询,提取信息,生成对应的 WifiConfiguration 对象列表

其他两个 NetworkNonimator 类似的处理方式~

3. WifiConfigManager 管理的配置出处


重点处理扫描结果的入口是 handleScanResults,其中调用了 NetworkSelector 的方法进行处理,也会调用 WifiConfigManager 的 addOrUpdateNetwork 更新已有的配置

WifiConnectivityManager 的 connectToNetwork 方法在其 handleScanResults 过程中被调用,进而调用 ClientModeImpl 的 startConnectToNetwork 接口进入实际的连接过程

当 Candidate 为空的时候 handleScanResult 会调用 OpenNetworkNotifier 的 handleScanResults 将对应的扫描结果(可用未保存)进行广播通知,这里面会调用 recommendNetwork 首先进行过滤,查询到对应的 ScanResult 对象 recommendation,调用 postInitialNotification 处理,recommend 的方式就是选择 rssi 最高的对象

处理方法是调用 postNotification,传入通过 NotificationBuilder 的 createConnectToAvailableNetworkNotification 方法创建的 Notification 对象

3.1 创建新的 WifiConfiguration 和 WifiCandidates


  1. ScanResultUtil::createNetworkFromScanResult 接口创建
  2. ScoreTracker::getCandidateConfiguration 接口根据 mBestCandidateType 的判断,是 ScoreTracker.EXTERNAL_SCORED_UNTRUSTED_NETWORK,在其 switch 分支中处理时调用了上述接口创建 WifiConfiguration 对象;
  3. ScoreTracker::getCandidateConfiguration 中调用了 WifiConfigManager::addOrUpdateNetwork 将新创建的配置保存起来;
  4. ScoreTracker::getCandidateConfiguration 会重新在 WifiConfigManager 中通过 getConfiguredNetwork 获取配置并且对其调用 onConnectableListener 的 onConnectable 方法;
  5. 上述过程发生在 ScoredNetworkNominator::nominateNetworks 中,在执行 2,3,4 步骤之前会遍历 ScanDetail 列表,通过 ScoreTracker 分别记录保存的以及不信任的(未保存的)结果,设置如 mBestCandidateType 等信息用于 getCandidateConfiguration 处理;
  6. 再次回溯,对应的 nominateNetworks 方法在 WifiNetworkSelector::getCandidatesFromScan 中,对三种 NetworkNominator 进行遍历,分别调用其 nominateNetworks 方法;
  7. 同样从对应的 onConnectable 方法看到,wifiCandidates 和 mConnectableNetworks 的 add 方法被调用,生成了对应的 WifiCandidates 对象中的 Candidates 列表;
  8. 将上述列表返回到 handleScanResults 继续处理

4. WifiNetworkSelector 选定连接的网络


WifiNetworkSelector 主要的两个方法如前面提到,这里分析第二个用于获取候选扫描结果的接口

SelectNetwork


  • 使用传进来的 Candidate 列表重新创建新的 WifiCandidates 对象
  • 生成根据 configuration id 组织的 groupedCandidates;
  • 对每个 group 成员使用 activeScorer 进行 scoreCandidates 处理,生成对应的 ScoredCandidate 对象 choice;
  • 调用 WifiConfigManager 的 setNetworkCandidateScanResult 进行 NetworkSelectionStatus更新;
  • 接下来遍历所有的 CandidateScorer 采用其 scoreCandidates 方法,对 WifiCandidates 进行计算获得对应的 ScoredCandidate 对象 choice;
choice = wifiCandidates.choose(candidateScorer);
  • 如果 CandidateScorer 是当前的 activeScorer 则说明是当前最佳选择,记录其 networkId 信息到 selectedNetworkId;
  • 根据 selectedNetworkId 记录信息从 WifiConfigManager 通过 getConfiguredNetwork 获取到 WifiConfiguration 信息返回;

到此网络的选择完成,接下来通过 connectToNetwork 进行连接

WifiConfigManager NetworkSelector 和 WifiConnectivityManager相关推荐

  1. Android P WiFi自动连接评分机制

    1.WifiConnectivityManager的初始化 frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiState ...

  2. android系统 wifi,Android系统wifi分析-手动连接过程

    1.已保存显示时间较长 16:59:50~16:59:55 原因是,刚好系统保存热点信息里边没有该热点:没有匹配上: 07-16 16:59:51.017 1318 2154 D WifiServic ...

  3. [android-wifi](7.1)漫游部分逻辑

    android-wifi(7.1)漫游部分逻辑 漫游说明:一个场所有若干台AP,相同的SSID不同的BSSID,STA可以在这个场所的不同地方自动连接信号好的AP. 协议规定: 相关类 WifiQua ...

  4. 【安卓Framework学习】Wifi框架学习之热点评分机制

    系列文章目录 [安卓Framework学习]Wifi框架学习之核心类 [安卓Framework学习]Wifi框架学习之wifi状态机 [安卓Framework学习]Wifi框架学习之连接与断开流程 [ ...

  5. 【安卓Framework学习】Wifi框架学习之核心类

    系列文章目录 [安卓Framework学习]Wifi框架学习之开启与关闭流程 [安卓Framework学习]Wifi框架学习之wifi状态机 [安卓Framework学习]Wifi框架学习之连接与断开 ...

  6. Android7 WIFI系统 PNO机制流程详解和隐藏BUG修改

    WIFI启动过程,WifiStateMachine加载驱动固件,连接上wpa_s的socket并检查好配置文件后,进入到DisconnectedState状态.在DisconnectedState状态 ...

  7. Wi-Fi PNO扫描流程(Android P)

    简介:当手机灭屏情况下,有保存网络时,若已连接,不扫描,否则,PNO扫描,即只扫描已保存的网络.最小间隔min=20s,最大间隔max=20s*3=60s PNO 即Preferred Network ...

  8. Android wifi PNO扫描流程(Andriod O)

    版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/h784707460/article/details/79702275,未经博主允许不得转载. 一. Android ...

  9. Android-O wifi PNO扫描流程

    一. Android O wifi扫描机制 Android O的扫面场景可以归结为以下四种: 1. 亮屏情况下,在Wifi settings界面,固定扫描,时间间隔为10s. 2. 亮屏情况下,非Wi ...

  10. [转载]Android7 WIFI系统 PNO机制流程详解和隐藏BUG修改

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/zhangdaxia2/article/ ...

最新文章

  1. 新能源关键技术预见的研究
  2. 《斗罗大陆》引入阿里云云原生数据库 PolarDB 游戏体验更流畅
  3. 异数OS 2017 DPDK 峰会观后感
  4. 基于互联网大数据的管理创新
  5. Taro+react开发(31)微信小程序都是要通过编译的
  6. 基于MaxCompute+PAI的用户增长方案实践
  7. IT行业趋势前沿:SOA和开源
  8. 积分图像 Integral
  9. 传网易、京东6月相继赴港上市:共计筹资50亿美元
  10. 并发设计模式之Guarded Suspension模式
  11. Eclipse 字体选择
  12. Android查看wakeLock调用情况
  13. [转]上海五年的奋斗历程 从月薪3500到700万(感人!催人振奋!)
  14. Spring.NET学习笔记17——事务传播行为(基础篇) Level 200
  15. linux 调度总结
  16. 微服务网关Gateway在实战中如何结合注册中心,定义过滤器?
  17. 计算机刷bios版本,技嘉bios升级工具(@BIOS)
  18. 华为模拟器linux,华为ENSP模拟器 官方安装版
  19. android studio 单元测试详解
  20. Linux——逻辑分区

热门文章

  1. Python破解协议密码
  2. centos7 vsftpd默认端口修改
  3. SSL之父称SSL不会因被攻击而失去生命力
  4. 在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例
  5. listview 点击条目 自动置顶或者自动置底部
  6. Android - UI
  7. redis通过lua脚本实现分布式锁
  8. 如何去除list中的重复元素
  9. Java通过反射获取类的私有属性和方法
  10. 邬建国教授受聘为浙江大学光彪教授