[RK3288][Android6.0] WiFi之NetworkMonitor对评分机制的影响

来源:互联网 发布:淘宝二级页面有什么用 编辑:程序博客网 时间:2024/05/18 13:04

Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

由来:
在上一篇文章有提到getCurrentScore()会对NetworkAgent传过来的值根据当前的networkCapabilities决定是否扣分,而NetworkMonitor正是基于管理网络连接状态而诞生的,它用来检测的网络有效性,当有效是,会将networkCapabilities的状态从无效更新到NET_CAPABILITY_VALIDATED状态
创建:
NetworkMonitor的创建在NetworkAgentInfo()的时候创建

public NetworkAgentInfo(...){    //NetworkAgent共生死    networkMonitor = connService.createNetworkMonitor(context, handler, this, defaultRequest);}
public NetworkMonitor createNetworkMonitor(Context context, Handler handler,        NetworkAgentInfo nai, NetworkRequest defaultRequest) {    return new NetworkMonitor(context, handler, nai, defaultRequest);}

调用:
NetworkAgent注册时调用updateNetworkInfo():
ConnectivityService.java

private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {    //这是网络已经连接上,但是能否连通有待验证    networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);}

这是NetworkMonitor是处于默认状态的
NetworkMonitor.java
processMessage -> //DefaultState状态
 transitionTo(mEvaluatingState) -> //切换到EvaluatingState
 enter ->
  sendMessage -> //CMD_REEVALUATE,发给自己处理
 processMessage

public boolean processMessage(Message message) {    case CMD_REEVALUATE:        // Note: This call to isCaptivePortal() could take up to a minute. Resolving the        // server's IP addresses could hit the DNS timeout, and attempting connections        // to each of the server's several IP addresses (currently one IPv4 and one        // IPv6) could each take SOCKET_TIMEOUT_MS.  During this time this StateMachine        // will be unresponsive. isCaptivePortal() could be executed on another Thread        // if this is found to cause problems.        //isCaptivePortal()字面意思大概就是是否能够访问入口,那么猜测应该是否能够访问服务器吧        int httpResponseCode = isCaptivePortal();        if (httpResponseCode == 204) {            //如果访问正常,那么就切换到mValidatedState状态            transitionTo(mValidatedState);    }        return HANDLED;}

isCaptivePortal()的过程其实就是从某个服务器上去拿数据,看是否成功,成功说明网络通信正常

protected int isCaptivePortal(){    if (!mIsCaptivePortalCheckEnabled) return 204;    HttpURLConnection urlConnection = null;    int httpResponseCode = 599;    try {        //mServer即DEFAULT_SERVER        //private static final String DEFAULT_SERVER = "connectivitycheck.gstatic.com"        //所以url的值是“http://connectivitycheck.gstatic.com/generate_204”        URL url = new URL("http", mServer, "/generate_204");        //这里获取内容的代码省略了    return httpResponseCode;}

enter //ValidatedState  -> mConnectivityServiceHandler.sendMessage //EVENT_NETWORK_TESTED

ConnectivityService中的NetworkStateTrackerHandler处理此条消息:

public void handleMessage(Message msg) {  case NetworkMonitor.EVENT_NETWORK_TESTED: {        NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;        if (isLiveNetworkAgent(nai, "EVENT_NETWORK_TESTED")) {            final boolean valid =                    (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);            if (DBG) log(nai.name() + " validation " + (valid ? " passed" : "failed"));            if (valid != nai.lastValidated) {                final int oldScore = nai.getCurrentScore();                //更新此值                nai.lastValidated = valid;                nai.everValidated |= valid;                //更新Capabilities                updateCapabilities(nai, nai.networkCapabilities);                // If score has changed, rebroadcast to NetworkFactories. b/17726566                //通知所有注册的NetworkFactory去根据最新score去更新各自连接状态                if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);            }    }}
private void updateCapabilities(NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) {    // Don't modify caller's NetworkCapabilities.    networkCapabilities = new NetworkCapabilities(networkCapabilities);    //lastValidated的值变化,添加NET_CAPABILITY_VALIDATED,绕了一大圈就是为了更新此值    if (nai.lastValidated) {        networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);    } else {        networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);    }}

更新完networkCapabilities之后,再调用sendUpdatedScoreToFactories(),也是通过发送CMD_REQUEST_NETWORK请求
这部分内容在分析NetworkFactory调用流程有分析过了,这里不再给出。

private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {    for (int i = 0; i < nai.networkRequests.size(); i++) {        NetworkRequest nr = nai.networkRequests.valueAt(i);        // Don't send listening requests to factories. b/17393458        if (!isRequest(nr)) continue;        sendUpdatedScoreToFactories(nr, nai.getCurrentScore());    }}

nai.getCurrentScore()

private int getCurrentScore(boolean pretendValidated) {    int score = currentScore;    //这时候的条件hasCapability(NET_CAPABILITY_VALIDATED)就成立了,所以不会再减分    if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED) && !pretendValidated) {        score -= UNVALIDATED_SCORE_PENALTY;    }    if (score < 0) score = 0;    return score;}

正是因为NetworkMonitor对连接的管理机制对score的影响,所以在WiFi评分的过程中,可以看到一开始的score是20(Agent送过来的是60),等连接并且网络通信正常之后才设置成60并再触发一次。
也即是说只是连接但是不能通信的网络对应的score是较低的,思维逻辑也很合理。

参考:
网络连接评分机制之NetworkMonitor(原)

阅读全文
1 0
原创粉丝点击