Android WIFi 8.0——数据流量切换到wifi

在这里插入图片描述

上面是直接绘制的图片,根据log走的真实流程,下面附上自己跟踪log的记录:

当wifi打印到wpa_supplicant: wlan0: State: GROUP_HANDSHAKE -> COMPLETED时
系统会打印:
Line 3378: 02-25 01:29:28.095  1146  1661 D ConnectivityService: registerNetworkAgent NetworkAgentInfo{
    
     ni{
    
    [type: WIFI[], state: CONNECTING/CONNECTING, reason: (unspecified), extra: "XXXX", ......
Line 3379: 02-25 01:29:28.096  1146  1667 D ConnectivityService: Got NetworkAgent Messenger
Line 3380: 02-25 01:29:28.096  1146  1667 D ConnectivityService: NetworkAgentInfo [WIFI () - 100] EVENT_NETWORK_INFO_CHANGED, going from null to CONNECTING
Line 3382: 02-25 01:29:28.096  1146  1667 D ConnectivityService: NetworkAgent connected
Line 3401: 02-25 01:29:28.206  1146  1667 D ConnectivityService: ignoring duplicate network state non-change
Line 3402: 02-25 01:29:28.206  1146  1667 D ConnectivityService: notifyType CALLBACK_CAP_CHANGED for NetworkAgentInfo [WIFI () - 100]
Line 3403: 02-25 01:29:28.206  1146  1667 D ConnectivityService: updateNetworkScore for NetworkAgentInfo [WIFI () - 100] to 56
Line 3413: 02-25 01:29:28.229  1146  1667 D ConnectivityService: Update of LinkProperties for NetworkAgentInfo [WIFI () - 100]; created=false; everConnected=false
跟踪分析可知:
在WIFI连接过程中,到链路层L2ConnectedState状态时
L2ConnectedState 
    mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,
        "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,
        mLinkProperties, 60, mNetworkMisc);
到ConnectivityService.java
registerNetworkAgent
    if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
    EVENT_REGISTER_NETWORK_AGENT
        handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
            na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);  
                replyHalfConnected(STATUS_SUCCESSFUL);   发送"CMD_CHANNEL_HALF_CONNECTED"告知source端半连接已建立
                    AsyncChannel.CMD_CHANNEL_HALF_CONNECTED
                        handleAsyncChannelHalfConnect(msg);
                            if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL)
                                if (VDBG) log("NetworkAgent connected");
                                sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
                                //NetworkAgent在收到 “CMD_CHANNEL_FULL_CONNECTION” 请求后,便开始创建自己的AsyncChannel,并完成其初始化,连接的对端是ConnectivityService
                                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION  -->NetworkAgent#handleMessage
                                    replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,AsyncChannel.STATUS_SUCCESSFUL);                                           
            updateNetworkInfo(na, networkInfo);
WifiStateMachine.setNetworkDetailedState    ————ObtainingIpState        
    sendNetworkInfo
        EVENT_NETWORK_INFO_CHANGED
            updateNetworkInfo(na, networkInfo);
            打印:"ConnectivityService: NetworkAgentInfo [WIFI () - 102] EVENT_NETWORK_INFO_CHANGED, going from null to CONNECTING  "  ,注意,这里才是CONNECTING而已,CONNECTED在后面

    WifiStateMachine# L2ConnectedState                  
        // Send the update score to network agent.
        mWifiScoreReport.calculateAndReportScore(
                mWifiInfo, mNetworkAgent, mAggressiveHandover,
                mWifiMetrics);
            NetworkAgent.sendNetworkScore
                queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
                    updateNetworkScore(nai, msg.arg1);
                        if (VDBG) log("updateNetworkScore for " + nai.name() + " to " + score);
                        rematchAllNetworksAndRequests //这里也会进入一次rematchAllNetworksAndRequests,但是实际不发挥切换网络的作用
当IpManager获得到IP地址,WifiStateMachine通过设置的回调,发出CMD_IP_CONFIGURATION_SUCCESSFUL消息,会向NetworkAgent发送CONNECTED的状态
case CMD_IP_CONFIGURATION_SUCCESSFUL:
    sendConnectedState();
        setNetworkDetailedState(DetailedState.CONNECTED); // 设置网络状态为CONNECTED
            mNetworkAgent.sendNetworkInfo(mNetworkInfo); //这里发送EVENT_NETWORK_INFO_CHANGED到ConnectivityService处理
                updateNetworkInfo //由updateNetworkInfo处理
                    打印:"ConnectivityService: NetworkAgentInfo [WIFI () - 100] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTED" 和上面的对比,这里已经是CONNECTED了
                    if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED)
                        updateLinkProperties(networkAgent, null);
                            updateInterfaces
                                打印:"ConnectivityService: Adding iface wlan0 to network 100s"
                            updateRoutes(newLp, oldLp, netId);
                                打印:"Adding Route [fe80::/64 -> :: wlan0] to network 100"
                            updateDnses(newLp, oldLp, netId);
                                打印:"Setting DNS servers for network 100 to [/172.28.1.xx, /172.28.1.xx]"
                            notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
                                打印:"ConnectivityService: notifyType CALLBACK_IP_CHANGED for NetworkAgentInfo [WIFI () - 100]"
                    networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);  //向NetworkMonitor发送CMD_NETWORK_CONNECTED信号
                    updateSignalStrengthThresholds(networkAgent, "CONNECT", null);//根据字面意思是更新信号强度阈值,没细究
                    rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now);  //rematchNetworkAndRequests用于比较网络分值和进行网络切换
                        打印:"rematching NetworkAgentInfo [WIFI () - 100]"
                        //Find and migrate to this Network any NetworkRequests for which this network is now the best.查找此网络现在最适合的任何网络请求并将其迁移到此网络。 
                        for (NetworkRequestInfo nri : mNetworkRequests.values()){
    
    
                            //检查它是否满足网络功能
                            if (satisfiesMobileMultiNetworkCheck){
    
    
                                打印:"ConnectivityService: currentScore = 0, newScore = 16"
                                //新网络更好的话
                                if (currentNetwork == null ||isBestMobileMultiNetwork(currentNetwork,currentNetwork.networkCapabilities,newNetwork,newNetwork.networkCapabilities,nri.request.networkCapabilities) ||currentNetwork.getCurrentScore() < score){
    
    
                                    //此时判断还不成立,后面还会调用一次rematchNetworkAndRequests,那时候才成立             
                                }
                                //通知相应的网络变化到NetworkFactory
                                sendUpdatedScoreToFactories(nri.request, score); 
                            }
                        }                 

回到前面updateNetworkInfo中,NetworkMonitor收到CMD_NETWORK_CONNECTED
CMD_NETWORK_CONNECTED——NetworkMonitor.java
    logNetworkEvent(NetworkEvent.NETWORK_CONNECTED);
    transitionTo(mEvaluatingState);
        case CMD_REEVALUATE
            isCaptivePortal(mAttempts);
                URL httpsUrl = mCaptivePortalHttpsUrl; 
                    mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl(context));
                        getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);  //CAPTIVE_PORTAL_HTTPS_URL是在应用桌面设置的
                sendDnsAndHttpProbes //去ping网络
                    打印:"NetworkMonitor/NetworkAgentInfo [WIFI () - 103]: PROBE_DNS xxxxx"
                    打印:"NetworkMonitor/NetworkAgentInfo [WIFI () - 103]: PROBE_HTTP https://xxxxx"
            if (probeResult.isSuccessful()){
    
    
                transitionTo(mValidatedState);
            }
            else if (probeResult.isPortal()){
    
    
                transitionTo(mValidatedState);
            }
            else{
    
    
                //这里会重新ping 3次
                if (mAttempts > CAPTIVE_INTERNET_REEVALUATE_TIMES){
    
    
                    transitionTo(mValidatedState);
                }
            }
这里连接wifi是有网络的
然后进入ValidatedState状态
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,NETWORK_TEST_RESULT_VALID, mNetId, null));    
    打印:"ConnectivityService: NetworkAgentInfo [WIFI () - 103] validation passed"
    case NetworkMonitor.EVENT_NETWORK_TESTED
        updateCapabilities(oldScore, nai, nai.networkCapabilities);
            rematchAllNetworksAndRequests(nai, oldScore); 
                rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now); 
再一次分析rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);  
rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);
    这一次if成立,即新网络更好
    if (currentNetwork == null ||isBestMobileMultiNetwork(currentNetwork,currentNetwork.networkCapabilities,newNetwork,newNetwork.networkCapabilities,nri.request.networkCapabilities) ||currentNetwork.getCurrentScore() < score){
    
    
        打印:"ConnectivityService: rematch for NetworkAgentInfo [WIFI () - 104]"
        因为当前的网络是MOBILE,所以currentNetwork != null
        if (currentNetwork != null){
    
    
            打印:"ConnectivityService:    accepting network in place of NetworkAgentInfo [MOBILE (LTE) - 102]"
            currentNetwork.removeRequest(nri.request.requestId);
            currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);   //lingerRequest是延迟禁用的流程,默认延迟是30s,即数据连接打开的情况下再连接WiFi,数据连接并不会马上断开,而是会先进入一个Lingering状态,然后过一段时间后(默认30s),才会断开连接。
            affectedNetworks.add(currentNetwork);                
        }
        通知相应的网络分值变化到NetworkFactory
        sendUpdatedScoreToFactories(nri.request, score);
            打印:"ConnectivityService: sending new Min Network Score(20): NetworkRequest [ TRACK_DEFAULT id=8, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN] ]"
            nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0, networkRequest);
        isNewDefault = true;
    } 
    if (isNewDefault)  
        makeDefault(newNetwork);   //通知系统服务此网络已启动。
    updateLingerState(newNetwork, now);
        nai.updateLingerTimer(); // 根据前面的30s延时定时——NetworkAgentInfo.java
            EVENT_NETWORK_LINGER_COMPLETE
                handleLingerComplete(nai); 
                    if (unneeded(oldNetwork, UnneededFor.TEARDOWN)){
    
    
                        // Tear the network down.
                        //安卓7及之前版本执行这个,所以LTE和wifi无法共存,查看到unneeded里的numRequests始终为0,所以后面会返回true
                        teardownUnneededNetwork(oldNetwork); //卸载旧网络,执行到这里的时候会发现ifconfig的rmnet_data0接口消失了
                    }
                    else{
    
    
                        //安卓8.0执行这个,LTE和wifi是共存的,通过添加日志打印,查看到unneeded里的numRequests始终为1,所以会直接返回false
                        updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork,oldNetwork.networkCapabilities);      //不卸载,放在后台Put the network in the background.                  
                    }

参考:
ANDROID Q 学习WIFI的评分机制(二)
ANDROID Q 学习WIFI的评分机制(三)

猜你喜欢

转载自blog.csdn.net/weixin_40535588/article/details/121808181