一 前言
上一篇分析了连接AP的过程,当底层完成wifi连接,便会事件通知WifiMonitor,WifiMonitor监听到该事件后发送消息NETWORK_CONNECTION_EVENT。
二 代码具体流程
1 frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMonitor.java
底层完成wifi连接,便会事件通知WifiMonitor,WifiMonitor监听到该事件后发送消息NETWORK_CONNECTION_EVENT。
/**
* Broadcast the network connection event to all the handlers registered for this event.
*
* @param iface Name of iface on which this occurred.
* @param networkId ID of the network in wpa_supplicant.
* @param bssid BSSID of the access point.
*/
public void broadcastNetworkConnectionEvent(String iface, int networkId, String bssid) {
sendMessage(iface, NETWORK_CONNECTION_EVENT, networkId, 0, bssid);
}
2 frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
WifiStateMachine此时处于DisconnectedState,该状态未能处理该消息,抛给它的父状态ConnectModeState处理。
case WifiMonitor.NETWORK_CONNECTION_EVENT:
if (mVerboseLoggingEnabled) log("Network connection established");
mLastNetworkId = message.arg1;
mWifiConfigManager.clearRecentFailureReason(mLastNetworkId);
mLastBssid = (String) message.obj;
reasonCode = message.arg2;
// TODO: This check should not be needed after WifiStateMachinePrime refactor.
// Currently, the last connected network configuration is left in
// wpa_supplicant, this may result in wpa_supplicant initiating connection
// to it after a config store reload. Hence the old network Id lookups may not
// work, so disconnect the network and let network selector reselect a new
// network.
config = getCurrentWifiConfiguration();
if (config != null) {
mWifiInfo.setBSSID(mLastBssid);
mWifiInfo.setNetworkId(mLastNetworkId);
mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
ScanDetailCache scanDetailCache =
mWifiConfigManager.getScanDetailCacheForNetwork(config.networkId);
if (scanDetailCache != null && mLastBssid != null) {
ScanResult scanResult = scanDetailCache.getScanResult(mLastBssid);
if (scanResult != null) {
mWifiInfo.setFrequency(scanResult.frequency);
}
}
mWifiConnectivityManager.trackBssid(mLastBssid, true, reasonCode);
// We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA'
if (config.enterpriseConfig != null
&& TelephonyUtil.isSimEapMethod(
config.enterpriseConfig.getEapMethod())) {
String anonymousIdentity =
mWifiNative.getEapAnonymousIdentity(mInterfaceName);
if (anonymousIdentity != null) {
config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
} else {
Log.d(TAG, "Failed to get updated anonymous identity"
+ " from supplicant, reset it in WifiConfiguration.");
config.enterpriseConfig.setAnonymousIdentity(null);
}
mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
}
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
} else {
logw("Connected to unknown networkId " + mLastNetworkId
+ ", disconnecting...");
sendMessage(CMD_DISCONNECT);
}
break;
可以看到一些操作,将ap的相关属性值赋给mWifiInfo。
mWifiInfo.setBSSID(mLastBssid)
mWifiInfo.setNetworkId(mLastNetworkId)
mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName))
更新Wifi的状态信息NetworkInfo,mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID)
并调用sendNetworkStateChangeBroadcast(mLastBssid)。