上面是直接绘制的图片,根据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的评分机制(三)