从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. 用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法

    本篇文章小编为大家介绍,用NPOI创建Excel.合并单元格.设置单元格样式.边框的方法.需要的朋友参考下 今天在做项目中,遇到使用代码生成具有一定样式的Excel,找了很多资料,最后终于解决了,Ex ...

  2. 找个些有用的网站(CSS生成)

    http://www.shejidaren.com/css-button-generator-and-beautifucl-style-sheet.html

  3. 【嵌入式】bootloader,linux,filesystem的烧写

    平台: 深圳市优龙科技有限公司的FS2410(基于ARM9) 准备: 1.用串口(UART1,J8)线与PC机相连,这个是用来传输数据和显示信息的 2.连接USB数据下载线(usb device),注 ...

  4. mysql load数据第一列丢失

    mysql load数据第一列丢失 问题描述 MySQL表的结构如下: mysql> desc cms_msg_test_3; +----------------+--------------- ...

  5. java多线程16:join()的使用

    讲解join()方法之前请确保对于即wait()/notify()/notifyAll()机制已熟练掌握.可以参考前面的笔记 join()方法的作用是等待线程销毁.join()方法反应的是一个很现实的 ...

  6. hdu1217(spfa,存在环,但需要将环的元素历遍一次.....求乘积的最大)

    题意:有n个国家货币,给出m种两个国家之间的货币兑换率,求是否可以盈利....... 思路:其实就是看国家货币兑换间是否存在一个环,使得从v点出发时,dis[v]=1,经过环回到v点时,dis[v]& ...

  7. 【转】如何使用visual studio将你的程序打包成安装包

    原文地址:https://www.cnblogs.com/SolarWings/p/6132310.html 很久很久以前,我一直有一个梦想,那就是做出一个自己的游戏,这个游戏很像模像样,除了拥有一个 ...

  8. Ehcache 缓存监控配置

    监控 ehcache缓存: 1,下载: http://terracotta.org/downloads/open-source/destination?name=ehcache-monitor-kit ...

  9. CAS (11) —— CAS TicketRegistry使用Ehcache的集群方案

    CAS (11) -- CAS TicketRegistry使用Ehcache的集群方案 摘要 CAS TicketRegistry使用Ehcache的集群方案 版本 tomcat版本: tomcat ...

  10. Volatile和Transient

    Volatile: Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看 ...