当前位置:

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

访客 2024-04-24 599 0

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

当wifi打印到wpa_supplicant:wlan0:State:GROUP_HANDSHAKE->COMPLETED时系统会打印:Line3378:02-2501:29:28.09511461661DConnectivityService:registerNetworkAgentNetworkAgentInfo{ni{[type:WIFI[],state:CONNECTING/CONNECTING,reason:(unspecified),extra:"XXXX",......Line3379:02-2501:29:28.09611461667DConnectivityService:GotNetworkAgentMessengerLine3380:02-2501:29:28.09611461667DConnectivityService:NetworkAgentInfo[WIFI()-100]EVENT_NETWORK_INFO_CHANGED,goingfromnulltoCONNECTINGLine3382:02-2501:29:28.09611461667DConnectivityService:NetworkAgentconnectedLine3401:02-2501:29:28.20611461667DConnectivityService:ignoringduplicatenetworkstatenon-changeLine3402:02-2501:29:28.20611461667DConnectivityService:notifyTypeCALLBACK_CAP_CHANGEDforNetworkAgentInfo[WIFI()-100]Line3403:02-2501:29:28.20611461667DConnectivityService:updateNetworkScoreforNetworkAgentInfo[WIFI()-100]to56Line3413:02-2501:29:28.22911461667DConnectivityService:UpdateofLinkPropertiesforNetworkAgentInfo[WIFI()-100];created=false;everConnected=false跟踪分析可知:在WIFI连接过程中,到链路层L2ConnectedState状态时L2ConnectedStatemNetworkAgent=newWifiNetworkAgent(getHandler().getLooper(),mContext,"WifiNetworkAgent",mNetworkInfo,mNetworkCapabilitiesFilter,mLinkProperties,60,mNetworkMisc);到ConnectivityService.javaregisterNetworkAgentif(DBG)log("registerNetworkAgent"nai);mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,nai));EVENT_REGISTER_NETWORK_AGENThandleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);na.asyncChannel.connect(mContext,mTrackerHandler,na.messenger);replyHalfConnected(STATUS_SUCCESSFUL);发送"CMD_CHANNEL_HALF_CONNECTED"告知source端半连接已建立AsyncChannel.CMD_CHANNEL_HALF_CONNECTEDhandleAsyncChannelHalfConnect(msg);if(msg.arg1==AsyncChannel.STATUS_SUCCESSFUL)if(VDBG)log("NetworkAgentconnected");sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);//NetworkAgent在收到“CMD_CHANNEL_FULL_CONNECTION”请求后,便开始创建自己的AsyncChannel,并完成其初始化,连接的对端是ConnectivityServicecaseAsyncChannel.CMD_CHANNEL_FULL_CONNECTION-->NetworkAgent#handleMessagereplyToMessage(msg,AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,AsyncChannel.STATUS_SUCCESSFUL);updateNetworkInfo(na,networkInfo);WifiStateMachine.setNetworkDetailedState————ObtainingIpStatesendNetworkInfoEVENT_NETWORK_INFO_CHANGEDupdateNetworkInfo(na,networkInfo);打印:"ConnectivityService:NetworkAgentInfo[WIFI()-102]EVENT_NETWORK_INFO_CHANGED,goingfromnulltoCONNECTING",注意,这里才是CONNECTING而已,CONNECTED在后面WifiStateMachine#L2ConnectedState//Sendtheupdatescoretonetworkagent.mWifiScoreReport.calculateAndReportScore(mWifiInfo,mNetworkAgent,mAggressiveHandover,mWifiMetrics);NetworkAgent.sendNetworkScorequeueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED,score,0);updateNetworkScore(nai,msg.arg1);if(VDBG)log("updateNetworkScorefor"nai.name()"to"score);rematchAllNetworksAndRequests//这里也会进入一次rematchAllNetworksAndRequests,但是实际不发挥切换网络的作用当IpManager获得到IP地址,WifiStateMachine通过设置的回调,发出CMD_IP_CONFIGURATION_SUCCESSFUL消息,会向NetworkAgent发送CONNECTED的状态caseCMD_IP_CONFIGURATION_SUCCESSFUL:sendConnectedState();setNetworkDetailedState(DetailedState.CONNECTED);//设置网络状态为CONNECTEDmNetworkAgent.sendNetworkInfo(mNetworkInfo);//这里发送EVENT_NETWORK_INFO_CHANGED到ConnectivityService处理updateNetworkInfo//由updateNetworkInfo处理打印:"ConnectivityService:NetworkAgentInfo[WIFI()-100]EVENT_NETWORK_INFO_CHANGED,goingfromCONNECTINGtoCONNECTED"和上面的对比,这里已经是CONNECTED了if(!networkAgent.everConnected&&state==NetworkInfo.State.CONNECTED)updateLinkProperties(networkAgent,null);updateInterfaces打印:"ConnectivityService:Addingifacewlan0tonetwork100s"updateRoutes(newLp,oldLp,netId);打印:"AddingRoute[fe80::/64->::wlan0]tonetwork100"updateDnses(newLp,oldLp,netId);打印:"SettingDNSserversfornetwork100to[/172.28.1.xx,/172.28.1.xx]"notifyNetworkCallbacks(networkAgent,ConnectivityManager.CALLBACK_IP_CHANGED);打印:"ConnectivityService:notifyTypeCALLBACK_IP_CHANGEDforNetworkAgentInfo[WIFI()-100]"networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);//向NetworkMonitor发送CMD_NETWORK_CONNECTED信号updateSignalStrengthThresholds(networkAgent,"CONNECT",null);//根据字面意思是更新信号强度阈值,没细究rematchNetworkAndRequests(networkAgent,ReapUnvalidatedNetworks.REAP,now);//rematchNetworkAndRequests用于比较网络分值和进行网络切换打印:"rematchingNetworkAgentInfo[WIFI()-100]"//FindandmigratetothisNetworkanyNetworkRequestsforwhichthisnetworkisnowthebest.查找此网络现在最适合的任何网络请求并将其迁移到此网络。for(NetworkRequestInfonri: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,那时候才成立}//通知相应的网络变化到NetworkFactorysendUpdatedScoreToFactories(nri.request,score);}}回到前面updateNetworkInfo中,NetworkMonitor收到CMD_NETWORK_CONNECTEDCMD_NETWORK_CONNECTED——NetworkMonitor.javalogNetworkEvent(NetworkEvent.NETWORK_CONNECTED);transitionTo(mEvaluatingState);caseCMD_REEVALUATEisCaptivePortal(mAttempts);URLhttpsUrl=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_DNSxxxxx"打印:"NetworkMonitor/NetworkAgentInfo[WIFI()-103]:PROBE_HTTPhttps://xxxxx"if(probeResult.isSuccessful()){transitionTo(mValidatedState);}elseif(probeResult.isPortal()){transitionTo(mValidatedState);}else{//这里会重新ping3次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]validationpassed"caseNetworkMonitor.EVENT_NETWORK_TESTEDupdateCapabilities(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:rematchforNetworkAgentInfo[WIFI()-104]"因为当前的网络是MOBILE,所以currentNetwork!=nullif(currentNetwork!=null){打印:"ConnectivityService:acceptingnetworkinplaceofNetworkAgentInfo[MOBILE(LTE)-102]"currentNetwork.removeRequest(nri.request.requestId);currentNetwork.lingerRequest(nri.request,now,mLingerDelayMs);//lingerRequest是延迟禁用的流程,默认延迟是30s,即数据连接打开的情况下再连接WiFi,数据连接并不会马上断开,而是会先进入一个Lingering状态,然后过一段时间后(默认30s),才会断开连接。affectedNetworks.add(currentNetwork);}通知相应的网络分值变化到NetworkFactorysendUpdatedScoreToFactories(nri.request,score);打印:"ConnectivityService:sendingnewMinNetworkScore(20):NetworkRequest[TRACK_DEFAULTid=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.javaEVENT_NETWORK_LINGER_COMPLETEhandleLingerComplete(nai);if(unneeded(oldNetwork,UnneededFor.TEARDOWN)){//Tearthenetworkdown.//安卓7及之前版本执行这个,所以LTE和wifi无法共存,查看到unneeded里的numRequests始终为0,所以后面会返回trueteardownUnneededNetwork(oldNetwork);//卸载旧网络,执行到这里的时候会发现ifconfig的rmnet_data0接口消失了}else{//安卓8.0执行这个,LTE和wifi是共存的,通过添加日志打印,查看到unneeded里的numRequests始终为1,所以会直接返回falseupdateCapabilities(oldNetwork.getCurrentScore(),oldNetwork,oldNetwork.networkCapabilities);//不卸载,放在后台Putthenetworkinthebackground.}

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

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~