Android R WiFi 选网机制解读

我们从 WifiNetworkSelector 入手研究 Android R WiFi 选网机制

在 WifiInjector 的构造过程中, 会初始化 WifiNetworkSelector 对象,并进行 registerCandidateScorer 动作, 之后注册了三个 NetworkNominator 对象

mWifiNetworkSelector.registerCandidateScorer(compatibilityScorer);
mWifiNetworkSelector.registerCandidateScorer(scoreCardBasedScorer);
mWifiNetworkSelector.registerCandidateScorer(bubbleFunScorer);
mWifiNetworkSelector.registerCandidateScorer(throughputScorer);

mWifiMetrics.setWifiNetworkSelector(mWifiNetworkSelector);

// Register the various network Nominators with the network selector.
mWifiNetworkSelector.registerNetworkNominator(mSavedNetworkNominator);
mWifiNetworkSelector.registerNetworkNominator(mNetworkSuggestionNominator);
mWifiNetworkSelector.registerNetworkNominator(mScoredNetworkNominator);
  • CompatibilityScorer: 不知道干啥的,从名字看 兼容性评分器
  • ScoreCardBasedScorer: 基于 ScoreCard 的评分器
  • BubbleFunScorer: 不知道啥意思
  • ThroughputScorer: 综合考虑 rssi 和 吞吐 的评分器
    这些评分器被添加进 WifiNetworkSelector 的 mCandidateScorers 变量
private final Map<String, WifiCandidates.CandidateScorer> mCandidateScorers = new ArrayMap<>();

至于这些评分器会怎么被应用到,我们后面再看

  • SavedNetworkNominator:用于保存的网络
  • NetworkSuggestionNominator:用于提供最高可用性候选建议
  • ScoredNetworkNominator:用于通过评分机制选择网络连接,用到了 NetworkScoreManager 用于管理网络评分
    这三个 NetworkNominator 被添加进 WifiNetworkSelector 的 mNominators 变量
private final List<NetworkNominator> mNominators = new ArrayList<>(3);

至于这三个 NetworkNominator 会被怎么应用到,我们后面再看

WifiConnectivityManager 内部类 AllSingleScanListener 的 onResults 方法会在接收到扫描结果后被调用
onResults 的其中这一行调用 handleScanResults 方法连接选出的网络

boolean wasConnectAttempted = handleScanResults(mScanDetails, ALL_SINGLE_SCAN_LISTENER, isFullBandScanResults);

我们来看 handleScanResults 方法原型及实现

private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName, boolean isFullScan)

handleScanResults 做了以下事情

  1. 更新和释放 Block 的 ssid 列表信息;涉及黑名单机制,日后可以再研究研究
// Check if any blocklisted BSSIDs can be freed.
Set<String> bssidBlocklist = mBssidBlocklistMonitor.updateAndGetBssidBlocklist();
  1. 判断当前是否处于 transient state,如果是的话则不再进一步处理;

  2. 开始进行 WiFi网络选择

    • 通过 WifiNetworkSelector 类的 getCandidatesFromScan 方法对扫描结果进行处理,获取 List<WifiCandidates.Candidate> candidates

    • 更新 mLatestCandidates 为最新,并且记录其 timestamp 信息(mLatestCandidatesTimestampMs);

    • 如果设备处于高速移动(WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT)且可以进行高速移动下的优化选择,则调用 filterCandidatesHighMovement 对获取到的 candidates 进行过滤;

    • 继续调用 WifiNetworkSelector 的 selectNetwork 方法选择网络,结果为 WifiConfiguration 类型,同时更新选择时间戳;

    • 如果存在被选中的 candidates,则进行连接过程 connectToNetwork;

    • 否则如果当前处于 WIFI_STATE_DISCONNECTED 状态,则调用 OpenNetworkNotifier 的 handleScanResults 接口进行处理,主要是在扫描结果中选择网络推荐给应用进行连接

下面主要讲讲 getCandidatesFromScan 和 selectNetwork 两个方法

public List<WifiCandidates.Candidate> getCandidatesFromScan(
        List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
        boolean connected, boolean disconnected, boolean untrustedNetworkAllowed)
getCandidatesFromScan 做的事情有
  1. 通过 isNetworkSelectionNeeded 判断是否需要进行网络选择,这个没什么好说的,主要是两个判断条件

    • 当前选网需与上次间隔10s,否则不会进行
    • 对当前网络进行 sufficiency check
  2. 遍历 mNominators ,调用其 update 方法

  3. 通过 filterScanResults 获取 mFilteredNetworks

  4. new 一个 WifiCandidates 对象, add 当前网络(我们总是希望当前连接网络也参与选网)

  5. 遍历所有已注册的 NetworkNominator 对象,执行其 nominateNetworks 接口

需要注重的点是 每个NetworkNominator 的 nominateNetworks 方法

nominateNetworks 方法原型

void nominateNetworks(List<ScanDetail> scanDetails,
        WifiConfiguration currentNetwork, String currentBssid,
        boolean connected, boolean untrustedNetworkAllowed,
        OnConnectableListener onConnectableListener)

OnConnectableListener 定义

public interface OnConnectableListener {
    void onConnectable(ScanDetail scanDetail, WifiConfiguration config);
}

在实际的 getCandidatesFromScan 对 nominateNetworks 的调用中,使用了匿名写法

registeredNominator.nominateNetworks(
    new ArrayList<>(mFilteredNetworks), currentNetwork, currentBssid, connected,
    untrustedNetworkAllowed,
    (scanDetail, 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 ephemeral
            boolean 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()));
            }
        }
    });

所以疑点是 WifiCandidates 的一些操作和各个 NetworkNominator 的 nominateNetworks 具体做了些什么
WifiCandidates 见我的这篇解读 WifiCandidates

看完之后就知道是,每个 NetworkNominator nominateNetwork 完之后,onConnectable 会被调用,这里是匿名写法
做的事情就是 把这个参选网络加入到 WifiCandidates 的 mCandidates 中

最后 getCandidatesFromScan 返回 WifiCandidates 的 mCandidates

这样,所有扫描到的网络都经过了 NetworkNominator 的 nominateNetwork, 至于这三个 NetworkNominator 的 nominateNetwork 具体做了什么,后面我们再看

selectNetwork 做的事情有
  1. 使用传进来的 Candidate 列表重新创建新的 WifiCandidates 对象, 依赖的是 WifiCandidates 重载的构造方法

  2. 通过 getActiveCandidateScorer 获取 activeScorer

  3. 生成根据 configuration id 组织的 groupedCandidates ;

  4. 对每个 group 成员使用 activeScorer 进行 scoreCandidates 处理,生成对应的 ScoredCandidate 对象 choice;

  5. 调用 WifiConfigManager 的 setNetworkCandidateScanResult 进行 NetworkSelectionStatus更新;

  6. 接下来遍历所有的 CandidateScorer 采用其 scoreCandidates 方法,对 WifiCandidates 进行计算获得对应的 ScoredCandidate 对象 choice;

  7. 如果 CandidateScorer 是当前的 activeScorer 则说明是当前最佳选择,记录其 networkId 信息到 selectedNetworkId;

  8. 根据 selectedNetworkId 记录信息从 WifiConfigManager 通过 getConfiguredNetwork 获取到 WifiConfiguration 信息返回

这里对上述步骤做一些解释:

  • 关于 activeScorer : 默认的参选网络评分器是 ThroughputScorer

至于这三个 CandidateScorer 怎么评分的,我们后面再看

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值