该评分器与BubbleFunScorer
和CompatibilityScorer
最大的不同是它会综合考虑最近30次rssi的统计信息,而不是仅仅最近一次。
逻辑较少,整体代码如下
private ScoredCandidate scoreCandidate(Candidate candidate) {
int rssiSaturationThreshold = mScoringParams.getGoodRssi(candidate.getFrequency());
int rssi = Math.min(candidate.getScanRssi(), rssiSaturationThreshold);
int cutoff = estimatedCutoff(candidate);
int score = (rssi - cutoff) * RSSI_SCORE_SLOPE_IS_4;
if (ScanResult.is6GHz(candidate.getFrequency())) {
score += BAND_6GHZ_AWARD_IS_40;
} else if (ScanResult.is5GHz(candidate.getFrequency())) {
score += BAND_5GHZ_AWARD_IS_40;
}
score += (int) (candidate.getLastSelectionWeight() * LAST_SELECTION_AWARD_IS_480);
if (candidate.isCurrentNetwork()) {
score += CURRENT_NETWORK_BOOST_IS_16 + SAME_BSSID_AWARD_IS_24;
}
if (!candidate.isOpenNetwork()) {
score += SECURITY_AWARD_IS_80;
}
// To simulate the old strict priority rule, subtract a penalty based on
// which nominator added the candidate.
score -= 1000 * candidate.getNominatorId();
return new ScoredCandidate(score, 10,
USE_USER_CONNECT_CHOICE, candidate);
}
- **信号强度RSSI处理: **先处理RSSI的值,最高不超过GoodRSSI
int rssiSaturationThreshold = mScoringParams.getGoodRssi(candidate.getFrequency());
int rssi = Math.min(candidate.getScanRssi(), rssiSaturationThreshold);
estimatedCutoff()
方法根据最近30次的rssi信息计算出一个cutoff值,这里的cutoff实际上是作为计算rssi评分的基准。
int cutoff = estimatedCutoff(candidate);
int score = (rssi - cutoff) * RSSI_SCORE_SLOPE_IS_4; // int RSSI_SCORE_SLOPE_IS_4 = 4
estimatedCutoff()
的计算其实很简单:
初始值: cutoff = -RSSI_SCORE_OFFSET = -85; lowest = -90; highest = -80
然后计算出最近30次rssi统计的标准差sigma
,并将cutoff暂定为 mean - 2*sigma
,最后将cutoff限定在 lowest
和 highest
之间
理论上,如果两组rssi的均值一样,对于rssi离散的热点,cutoff会更低一些
private int estimatedCutoff(Candidate candidate) {
int cutoff = -RSSI_SCORE_OFFSET;
int lowest = cutoff - RSSI_RAIL;
int highest = cutoff + RSSI_RAIL;
WifiScoreCardProto.Signal signal = candidate.getEventStatistics(Event.SIGNAL_POLL);
if (signal == null) return cutoff;
if (!signal.hasRssi()) return cutoff;
if (signal.getRssi().getCount() > MIN_POLLS_FOR_SIGNIFICANCE) {
double mean = signal.getRssi().getSum() / signal.getRssi().getCount();
double mean_square = signal.getRssi().getSumOfSquares() / signal.getRssi().getCount();
double variance = mean_square - mean * mean;
double sigma = Math.sqrt(variance);
double value = mean - 2.0 * sigma;
cutoff = (int) Math.min(Math.max(value, lowest), highest);
}
return cutoff;
}
-
**频段奖励:**根据候选网络的频段(6GHz、5GHz等),分别添加了 BAND_6GHZ_AWARD_IS_40 和 BAND_5GHZ_AWARD_IS_40 奖励
-
**最近连接奖励:**具体方法参考BubbleFunScorer。
-
**当前已连接网络奖励:**加40分
-
**安全性奖励:**对于非开放网络,加80分
-
Nominator惩罚: 跟提名器相关,暂时没有深究其原因。
ScoreCardBasedScorer
也不是很复杂,主要区别就是根据rssi的离散状态计算出不同的分数。