从android N开始,引入了wifi评分机制,选择wifi的时候会通过评分来选择。

android O源码

frameworks\opt\net\wifi\service\java\com\android\server\wifi\SavedNetworkEvaluator.java

   private int calculateBssidScore(ScanResult scanResult, WifiConfiguration network,
WifiConfiguration currentNetwork, String currentBssid,
StringBuffer sbuf) {
int score = 0;
// 判断信号是否为5GHz
boolean is5GHz = scanResult.is5GHz(); sbuf.append("[ ").append(scanResult.SSID).append(" ").append(scanResult.BSSID)
.append(" RSSI:").append(scanResult.level).append(" ] ");
// Calculate the RSSI score.
int rssiSaturationThreshold = is5GHz ? mThresholdSaturatedRssi5 : mThresholdSaturatedRssi24;
// 根据wifi的信号等级来获取rssi
int rssi = scanResult.level < rssiSaturationThreshold ? scanResult.level
: rssiSaturationThreshold;
score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;
sbuf.append(" RSSI score: ").append(score).append(","); // 5GHz band bonus.
if (is5GHz) {
score += mBand5GHzAward; // score += 40
sbuf.append(" 5GHz bonus: ").append(mBand5GHzAward).append(",");
}
// 之前连接过会有奖励
// Last user selection award.
int lastUserSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork();
if (lastUserSelectedNetworkId != WifiConfiguration.INVALID_NETWORK_ID
&& lastUserSelectedNetworkId == network.networkId) {
// 开机时间减去连接的时间戳,得到的时间就是连接的时间到现在总共多久
long timeDifference = mClock.getElapsedSinceBootMillis()
- mWifiConfigManager.getLastSelectedTimeStamp();
if (timeDifference > 0) {
int bonus = mLastSelectionAward - (int) (timeDifference / 1000 / 60);
score += bonus > 0 ? bonus : 0;
sbuf.append(" User selection ").append(timeDifference / 1000 / 60)
.append(" minutes ago, bonus: ").append(bonus).append(",");
}
} // Same network award.
// 当前正在连接的SSID也会有奖励
if (currentNetwork != null
&& (network.networkId == currentNetwork.networkId
//TODO(b/36788683): re-enable linked configuration check
/* || network.isLinked(currentNetwork) */)) {
score += mSameNetworkAward;
sbuf.append(" Same network bonus: ").append(mSameNetworkAward).append(","); // 如果支持漫游,也会有漫游奖励
// When firmware roaming is supported, equivalent BSSIDs (the ones under the
// same network as the currently connected one) get the same BSSID award.
// 漫游奖励,SSID相同,BSSID不同。
if (mConnectivityHelper.isFirmwareRoamingSupported()
&& currentBssid != null && !currentBssid.equals(scanResult.BSSID)) {
score += mSameBssidAward;
sbuf.append(" Equivalent BSSID bonus: ").append(mSameBssidAward).append(",");
}
} // Same BSSID award.
if (currentBssid != null && currentBssid.equals(scanResult.BSSID)) {
score += mSameBssidAward;
sbuf.append(" Same BSSID bonus: ").append(mSameBssidAward).append(",");
} // Security award.
// 不是开放的网络,也会有奖励
if (!WifiConfigurationUtil.isConfigForOpenNetwork(network)) {
score += mSecurityAward;
sbuf.append(" Secure network bonus: ").append(mSecurityAward).append(",");
} sbuf.append(" ## Total score: ").append(score).append("\n"); return score;
} /**
* Evaluate all the networks from the scan results and return
* the WifiConfiguration of the network chosen for connection.
*
* @return configuration of the chosen network;
* null if no network in this category is available.
*/
public WifiConfiguration evaluateNetworks(List<ScanDetail> scanDetails,
WifiConfiguration currentNetwork, String currentBssid, boolean connected,
boolean untrustedNetworkAllowed,
List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) {
int highestScore = Integer.MIN_VALUE;
ScanResult scanResultCandidate = null;
WifiConfiguration candidate = null;
StringBuffer scoreHistory = new StringBuffer(); for (ScanDetail scanDetail : scanDetails) {
ScanResult scanResult = scanDetail.getScanResult();
int highestScoreOfScanResult = Integer.MIN_VALUE; // 0x80000000
int candidateIdOfScanResult = WifiConfiguration.INVALID_NETWORK_ID; // -1 // One ScanResult can be associated with more than one networks, hence we calculate all
// the scores and use the highest one as the ScanResult's score.
List<WifiConfiguration> associatedConfigurations = null;
WifiConfiguration associatedConfiguration =
mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail); if (associatedConfiguration == null) {
continue;
} else {
associatedConfigurations =
new ArrayList<>(Arrays.asList(associatedConfiguration));
} for (WifiConfiguration network : associatedConfigurations) {
/**
* Ignore Passpoint and Ephemeral networks. They are configured networks,
* but without being persisted to the storage. They are evaluated by
* {@link PasspointNetworkEvaluator} and {@link ScoredNetworkEvaluator}
* respectively.
*/
if (network.isPasspoint() || network.isEphemeral()) {
continue;
} WifiConfiguration.NetworkSelectionStatus status =
network.getNetworkSelectionStatus();
status.setSeenInLastQualifiedNetworkSelection(true); if (!status.isNetworkEnabled()) {
continue;
} else if (network.BSSID != null && !network.BSSID.equals("any")
&& !network.BSSID.equals(scanResult.BSSID)) {
// App has specified the only BSSID to connect for this
// configuration. So only the matching ScanResult can be a candidate.
localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+ " has specified BSSID " + network.BSSID + ". Skip "
+ scanResult.BSSID);
continue;
} else if (TelephonyUtil.isSimConfig(network)
&& !mWifiConfigManager.isSimPresent()) {
// Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
continue;
}
// 计算分数
int score = calculateBssidScore(scanResult, network, currentNetwork, currentBssid,
scoreHistory); // Set candidate ScanResult for all saved networks to ensure that users can
// override network selection. See WifiNetworkSelector#setUserConnectChoice.
// TODO(b/36067705): consider alternative designs to push filtering/selecting of
// user connect choice networks to RecommendedNetworkEvaluator.
if (score > status.getCandidateScore() || (score == status.getCandidateScore()
&& status.getCandidate() != null
&& scanResult.level > status.getCandidate().level)) {
// 重新设置candidate
mWifiConfigManager.setNetworkCandidateScanResult(
network.networkId, scanResult, score);
} // If the network is marked to use external scores, or is an open network with
// curate saved open networks enabled, do not consider it for network selection.
if (network.useExternalScores) {
localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+ " has external score.");
continue;
}
// 判断是否在扫描的列表中评分最高
if (score > highestScoreOfScanResult) {
highestScoreOfScanResult = score;
// 保存networkId
candidateIdOfScanResult = network.networkId;
}
} if (connectableNetworks != null) {
connectableNetworks.add(Pair.create(scanDetail,
mWifiConfigManager.getConfiguredNetwork(candidateIdOfScanResult)));
}
// 根据评分以及level来判断选择最合适的candidate
if (highestScoreOfScanResult > highestScore
|| (highestScoreOfScanResult == highestScore
&& scanResultCandidate != null
&& scanResult.level > scanResultCandidate.level)) {
highestScore = highestScoreOfScanResult;
scanResultCandidate = scanResult;
mWifiConfigManager.setNetworkCandidateScanResult(
candidateIdOfScanResult, scanResultCandidate, highestScore);
// Reload the network config with the updated info.
candidate = mWifiConfigManager.getConfiguredNetwork(candidateIdOfScanResult);
}
} if (scoreHistory.length() > 0) {
localLog("\n" + scoreHistory.toString());
} if (scanResultCandidate == null) {
localLog("did not see any good candidates.");
}
return candidate;
}
}

2018-7-12, Shenzhen

Wifi 评分机制分析的更多相关文章

  1. Android 8.0/9.0 wifi 自动连接评分机制

    前言 Android N wifi auto connect流程分析 Android N selectQualifiedNetwork分析 Wifi自动连接时的评分机制 今天了解了一下Wifi自动连接 ...

  2. lucene 的评分机制

    lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...

  3. Elasticseach的评分机制

    lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...

  4. Linux mips64r2 PCI中断路由机制分析

    Linux mips64r2 PCI中断路由机制分析 本文主要分析mips64r2 PCI设备中断路由原理和irq号分配实现方法,并尝试回答如下问题: PCI设备驱动中断注册(request_irq) ...

  5. IOS Table中Cell的重用reuse机制分析

    IOS Table中Cell的重用reuse机制分析 技术交流新QQ群:414971585 创建UITableViewController子类的实例后,IDE生成的代码中有如下段落: - (UITab ...

  6. 您还有心跳吗?超时机制分析(java)

    注:本人是原作者,首发于并发编程网(您还有心跳吗?超时机制分析),此文结合那里的留言作了一些修改. 问题描述 在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超 ...

  7. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  8. android wifi ANR问题分析总结

    android wifi ANR问题分析总结 1 看看main进程阻塞在那里? 2 调用关系的函数阻塞在那里? 3 最终阻塞函数的阻塞前的log以及状态

  9. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

随机推荐

  1. HTML杂记

    1.URL  uniform resource locator 遵循格式: scheme://host.domain:port/path/filename scheme - 定义因特网服务的类型.最常 ...

  2. 菜鸟学Java(四)——JSP内置对象

    学习JavaWeb就离不开JSP,而学习JSP又不得不了解它常用的九个内置对象.今天来做一个简单介绍. request Request封装了用户提交的信息,通过调用Request相应的方法可以获取封装 ...

  3. 每日英语:A Chinese Father’s Most Important Job

    When it comes to parenting, Chinese fathers say the most important role they play is that of the fam ...

  4. 搜索页面scroll下拉时候进行刷新,显示更多搜索值

    1.封装扩展scroll.vue功能: //props传值 pullup:{ type:Boolean, default:false } _initScroll(){ if(!this.$refs.w ...

  5. Mysql异常问题排查与处理——mysql的DNS反向解析和客户端网卡重启

    中午刚想趴一会,不料锅从天降!!!Mysql连不上了....... 现象如下: 现象1:登录mysql所在服务器,连接MySQL 成功: 现象2:通过客户端远程连接MySQL,返回失败,如下: Ent ...

  6. C# 去除json字符串key引号

    采用正则表达式去除: 方法 /// <summary> /// 去除json key双引号 /// </summary> /// <param name="js ...

  7. Excel工作记录表制作

    前言:我们一天中的工作可能特别忙.事情特别多,这时候你就要像CPU一样去调度.去执行任务,但总要有个地方记录你的执行情况,这就需要我们自己去记录和管理了,下面是使用excel的简单管理记录方式,下图是 ...

  8. SQL 分页 SQL SERVER 2008

    public IList<UserInfo> GetPageList(int pageSize, int pageIndex, out int totalItemCount) { var ...

  9. IIS7 MVC 403 禁止访问:访问被拒绝

  10. 遍历目录下的所有文件-os.walk

    #coding:utf-8 import os for root,dirs,files in os.walk("D:"): for fileItem in files: print ...