Android WiFi 连接
- 1、设置中WiFi显示
- 2、WiFi 连接流程
- 2.1 获取PrimaryClientModeManager
- 2.2 ClientModeImpl状态机ConnectableState
- 2.3 ISupplicantStaNetworkCallback 回调监听
- 3、 简要时序图
- 4、原生低层驱动
- 5、关键日志
1、设置中WiFi显示
Android WiFi基础概览
packages/apps/Settings/src/com/android/settings/network/NetworkProviderSettings.java
packages/apps/Settings/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
mWifiPickerTracker.getConnectedWifiEntry()
当前连接的WiFimWifiPickerTracker.getWifiEntries()
搜索的WiFimAddWifiNetworkPreference
添加WiFi项WifiManager.java#connect
和StandardWifiEntry.java#connect->WifiManager.java#connect
连接WiFi
protected void updateWifiEntryPreferences() {
// bypass the update if the activity and the view are not ready, or it's restricted UI.
if (getActivity() == null || getView() == null || mIsRestricted) {
return;
}
// in case state has changed
if (mWifiPickerTracker == null
|| mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
return;
}
boolean hasAvailableWifiEntries = false;
mWifiEntryPreferenceCategory.setVisible(true);
final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry();
PreferenceCategory connectedWifiPreferenceCategory = getConnectedWifiPreferenceCategory();
connectedWifiPreferenceCategory.setVisible(connectedEntry != null);
if (connectedEntry != null) {
final LongPressWifiEntryPreference connectedPref =
connectedWifiPreferenceCategory.findPreference(connectedEntry.getKey());
if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
connectedWifiPreferenceCategory.removeAll();
final ConnectedWifiEntryPreference pref =
createConnectedWifiEntryPreference(connectedEntry);
pref.setKey(connectedEntry.getKey());
pref.refresh();
connectedWifiPreferenceCategory.addPreference(pref);
pref.setOnPreferenceClickListener(preference -> {
if (connectedEntry.canSignIn()) {
connectedEntry.signIn(null /* callback */);
} else {
launchNetworkDetailsFragment(pref);
}
return true;
});
pref.setOnGearClickListener(preference -> {
launchNetworkDetailsFragment(pref);
});
if (mClickedConnect) {
mClickedConnect = false;
scrollToPreference(connectedWifiPreferenceCategory);
}
}
} else {
connectedWifiPreferenceCategory.removeAll();
}
int index = 0;
cacheRemoveAllPrefs(mWifiEntryPreferenceCategory);
List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();
for (WifiEntry wifiEntry : wifiEntries) {
hasAvailableWifiEntries = true;
String key = wifiEntry.getKey();
LongPressWifiEntryPreference pref =
(LongPressWifiEntryPreference) getCachedPreference(key);
if (pref != null) {
if (pref.getWifiEntry() == wifiEntry) {
pref.setOrder(index++);
continue;
} else {
// Create a new preference if the underlying WifiEntry object has changed
removePreference(key);
}
}
pref = createLongPressWifiEntryPreference(wifiEntry);
pref.setKey(wifiEntry.getKey());
pref.setOrder(index++);
pref.refresh();
if (wifiEntry.getHelpUriString() != null) {
pref.setOnButtonClickListener(preference -> {
openSubscriptionHelpPage(wifiEntry);
});
}
mWifiEntryPreferenceCategory.addPreference(pref);
}
removeCachedPrefs(mWifiEntryPreferenceCategory);
if (!hasAvailableWifiEntries) {
setProgressBarVisible(true);
Preference pref = new Preference(getPrefContext());
pref.setSelectable(false);
pref.setSummary(R.string.wifi_empty_list_wifi_on);
pref.setOrder(index++);
pref.setKey(PREF_KEY_EMPTY_WIFI_LIST);
mWifiEntryPreferenceCategory.addPreference(pref);
} else {
// Continuing showing progress bar for an additional delay to overlap with animation
getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */);
}
mAddWifiNetworkPreference.setOrder(index++);
mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference);
setAdditionalSettingsSummaries();
}
2、WiFi 连接流程
2.1 获取PrimaryClientModeManager
packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
WifiManager.java#connect > WifiServiceImpl.java#connect > ConnectHelper.java#connectToNetwork > ActiveModeWarden.java#getPrimaryClientModeManager/getPrimaryClientModeManagerNullable/getClientModeManagerInRole(ROLE_CLIENT_PRIMARY)
2.2 ClientModeImpl状态机ConnectableState
packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
ConnectHelper.java#connectToNetwork > ConcreteClientModeManager.java#connectToNetwork > ClientModeImpl.java#connectNetwork > ConnectableState#CMD_CONNECT_NETWORK > ClientModeImpl.java#connectToUserSelectNetwork > ClientModeImpl.java#connectToUserSelectNetwork > ConnectableState#CMD_START_CONNECT > ClientModeImpl.java#connectToNetwork > WifiNative.java#connectToNetwork > SupplicantStaIfaceHal.java#connectToNetwork > SupplicantStaIfaceHalAidlImpl.java#connectToNetwork
class ConnectableState extends State {
private boolean mIsScreenStateChangeReceiverRegistered = false;
BroadcastReceiver mScreenStateChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
sendMessage(CMD_SCREEN_STATE_CHANGED, 1);
} else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
sendMessage(CMD_SCREEN_STATE_CHANGED, 0);
}
}
};
@Override
public void enter() {
Log.d(getTag(), "entering ConnectableState: ifaceName = " + mInterfaceName);
setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
mWifiStateTracker.updateState(mInterfaceName, WifiStateTracker.INVALID);
mIpClientCallbacks = new IpClientCallbacksImpl();
Log.d(getTag(), "Start makeIpClient ifaceName = " + mInterfaceName);
mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
mIpClientCallbacks.awaitCreation();
}
private void continueEnterSetup(IpClientManager ipClientManager) {
mIpClient = ipClientManager;
setupClientMode();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
if (!mIsScreenStateChangeReceiverRegistered) {
mContext.registerReceiver(mScreenStateChangeReceiver, filter);
mIsScreenStateChangeReceiverRegistered = true;
}
// Learn the initial state of whether the screen is on.
// We update this field when we receive broadcasts from the system.
handleScreenStateChanged(mContext.getSystemService(PowerManager.class).isInteractive());
if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
loge("Failed to remove networks on entering connect mode");
}
mWifiInfo.reset();
mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
sendNetworkChangeBroadcast(DetailedState.DISCONNECTED);
// Inform metrics that Wifi is Enabled (but not yet connected)
mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_ENABLED);
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
}
@Override
public void exit() {
// Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc)
mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISABLED);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_DISABLED);
if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
loge("Failed to remove networks on exiting connect mode");
}
if (mIsScreenStateChangeReceiverRegistered) {
mContext.unregisterReceiver(mScreenStateChangeReceiver);
mIsScreenStateChangeReceiverRegistered = false;
}
stopClientMode();
mWifiScoreCard.doWrites();
}
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_CONNECTABLE_STATE_SETUP:
if (mIpClient != null) {
loge("Setup connectable state again when IpClient is ready?");
} else {
IpClientManager ipClientManager = (IpClientManager) message.obj;
continueEnterSetup(ipClientManager);
}
break;
case CMD_ENABLE_RSSI_POLL: {
mEnableRssiPolling = (message.arg1 == 1);
break;
}
case CMD_SCREEN_STATE_CHANGED: {
handleScreenStateChanged(message.arg1 != 0);
break;
}
case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST: {
if (mIpClient == null) {
logd("IpClient is not ready, "
+ "WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST dropped");
break;
}
if (mWifiP2pConnection.shouldTemporarilyDisconnectWifi()) {
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_FRAMEWORK_DISCONNECT,
StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST);
mWifiNative.disconnect(mInterfaceName);
} else {
mWifiNative.reconnect(mInterfaceName);
}
break;
}
case CMD_RECONNECT: {
WorkSource workSource = (WorkSource) message.obj;
mWifiConnectivityManager.forceConnectivityScan(workSource);
break;
}
case CMD_REASSOCIATE: {
if (mIpClient != null) {
logd("IpClient is not ready, REASSOCIATE dropped");
mWifiNative.reassociate(mInterfaceName);
}
break;
}
case CMD_START_CONNECT: {
if (mIpClient == null) {
logd("IpClient is not ready, START_CONNECT dropped");
break;
}
/* connect command coming from auto-join */
int netId = message.arg1;
int uid = message.arg2;
String bssid = (String) message.obj;
mSentHLPs = false;
// Stop lingering (if it was lingering before) if we start a new connection.
// This means that the ClientModeManager was reused for another purpose, so it
// should no longer be in lingering mode.
mClientModeManager.setShouldReduceNetworkScore(false);
if (!hasConnectionRequests()) {
if (mNetworkAgent == null) {
loge("CMD_START_CONNECT but no requests and not connected,"
+ " bailing");
break;
} else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
loge("CMD_START_CONNECT but no requests and connected, but app "
+ "does not have sufficient permissions, bailing");
break;
}
}
WifiConfiguration config =
mWifiConfigManager.getConfiguredNetworkWithoutMasking(netId);
logd("CMD_START_CONNECT "
+ " my state " + getCurrentState().getName()
+ " nid=" + netId
+ " roam=" + mIsAutoRoaming);
if (config == null) {
loge("CMD_START_CONNECT and no config, bail out...");
break;
}
mCurrentConnectionDetectedCaptivePortal = false;
mTargetNetworkId = netId;
// Update scorecard while there is still state from existing connection
mLastScanRssi = mWifiConfigManager.findScanRssi(netId,
mWifiHealthMonitor.getScanRssiValidTimeMs());
mWifiScoreCard.noteConnectionAttempt(mWifiInfo, mLastScanRssi, config.SSID);
mWifiBlocklistMonitor.setAllowlistSsids(config.SSID, Collections.emptyList());
mWifiBlocklistMonitor.updateFirmwareRoamingConfiguration(Set.of(config.SSID));
updateWifiConfigOnStartConnection(config, bssid);
reportConnectionAttemptStart(config, mTargetBssid,
WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);
String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName);
mWifiInfo.setMacAddress(currentMacAddress);
Log.i(getTag(), "Connecting with " + currentMacAddress + " as the mac address");
mTargetWifiConfiguration = config;
mNetworkNotFoundEventCount = 0;
/* Check for FILS configuration again after updating the config */
if (config.isFilsSha256Enabled() || config.isFilsSha384Enabled()) {
boolean isIpClientStarted = startIpClient(config, true);
if (isIpClientStarted) {
mIpClientWithPreConnection = true;
transitionTo(mL2ConnectingState);
break;
}
}
mInsecureEapNetworkHandler.prepareConnection(mTargetWifiConfiguration);
setSelectedRcoiForPasspoint(config);
connectToNetwork(config);
break;
}
case CMD_START_FILS_CONNECTION: {
if (mIpClient == null) {
logd("IpClient is not ready, START_FILS_CONNECTION dropped");
break;
}
mWifiMetrics.incrementConnectRequestWithFilsAkmCount();
List<Layer2PacketParcelable> packets;
packets = (List<Layer2PacketParcelable>) message.obj;
if (mVerboseLoggingEnabled) {
Log.d(getTag(), "Send HLP IEs to supplicant");
}
addLayer2PacketsToHlpReq(packets);
WifiConfiguration config = mTargetWifiConfiguration;
connectToNetwork(config);
break;
}
case CMD_CONNECT_NETWORK: {
ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
if (mIpClient == null) {
logd("IpClient is not ready, CONNECT_NETWORK dropped");
cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
break;
}
NetworkUpdateResult result = cnm.result;
int netId = result.getNetworkId();
connectToUserSelectNetwork(
netId, message.sendingUid, result.hasCredentialChanged(),
cnm.packageName);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CONNECT_NETWORK,
mWifiConfigManager.getConfiguredNetwork(netId));
cnm.listener.sendSuccess();
break;
}
case CMD_SAVE_NETWORK: {
ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
if (mIpClient == null) {
logd("IpClient is not ready, SAVE_NETWORK dropped");
cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
break;
}
NetworkUpdateResult result = cnm.result;
int netId = result.getNetworkId();
if (mWifiInfo.getNetworkId() == netId) {
if (result.hasCredentialChanged()) {
// The network credentials changed and we're connected to this network,
// start a new connection with the updated credentials.
logi("CMD_SAVE_NETWORK credential changed for nid="
+ netId + ". Reconnecting.");
startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
} else {
if (result.hasProxyChanged()) {
if (mIpClient != null) {
log("Reconfiguring proxy on connection");
WifiConfiguration currentConfig =
getConnectedWifiConfigurationInternal();
if (currentConfig != null) {
mIpClient.setHttpProxy(currentConfig.getHttpProxy());
} else {
Log.w(getTag(),
"CMD_SAVE_NETWORK proxy change - but no current "
+ "Wi-Fi config");
}
}
}
if (result.hasIpChanged()) {
// The current connection configuration was changed
// We switched from DHCP to static or from static to DHCP, or the
// static IP address has changed.
log("Reconfiguring IP on connection");
WifiConfiguration currentConfig =
getConnectedWifiConfigurationInternal();
if (currentConfig != null) {
transitionTo(mL3ProvisioningState);
} else {
Log.w(getTag(), "CMD_SAVE_NETWORK Ip change - but no current "
+ "Wi-Fi config");
}
}
}
} else if (mWifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID
&& result.hasCredentialChanged()) {
logi("CMD_SAVE_NETWORK credential changed for nid="
+ netId + " while disconnected. Connecting.");
WifiConfiguration config =
mWifiConfigManager.getConfiguredNetwork(netId);
if (!mWifiPermissionsUtil.isAdminRestrictedNetwork(config)) {
startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
}
} else if (result.hasCredentialChanged()) {
WifiConfiguration currentConfig =
getConnectedWifiConfigurationInternal();
WifiConfiguration updatedConfig =
mWifiConfigManager.getConfiguredNetwork(netId);
if (currentConfig != null && currentConfig.isLinked(updatedConfig)) {
logi("current network linked config saved, update linked networks");
updateLinkedNetworks(currentConfig);
}
}
cnm.listener.sendSuccess();
break;
}
case CMD_BLUETOOTH_CONNECTION_STATE_CHANGE: {
mWifiNative.setBluetoothCoexistenceScanMode(
mInterfaceName, mWifiGlobals.isBluetoothConnected());
break;
}
case CMD_SET_SUSPEND_OPT_ENABLED: {
if (message.arg1 == 1) {
setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
if (message.arg2 == 1) {
mSuspendWakeLock.release();
}
} else {
setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
}
break;
}
case WifiMonitor.ANQP_DONE_EVENT: {
mPasspointManager.notifyANQPDone((AnqpEvent) message.obj);
break;
}
case CMD_STOP_IP_PACKET_OFFLOAD: {
int slot = message.arg1;
int ret = stopWifiIPPacketOffload(slot);
if (mNetworkAgent != null) {
mNetworkAgent.sendSocketKeepaliveEvent(slot, ret);
}
break;
}
case WifiMonitor.RX_HS20_ANQP_ICON_EVENT: {
mPasspointManager.notifyIconDone((IconEvent) message.obj);
break;
}
case WifiMonitor.HS20_DEAUTH_IMMINENT_EVENT:
mPasspointManager.handleDeauthImminentEvent((WnmData) message.obj,
getConnectedWifiConfigurationInternal());
break;
case WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT:
mWifiMetrics
.incrementTotalNumberOfPasspointConnectionsWithTermsAndConditionsUrl();
mTermsAndConditionsUrl = mPasspointManager
.handleTermsAndConditionsEvent((WnmData) message.obj,
getConnectedWifiConfigurationInternal());
if (mTermsAndConditionsUrl == null) {
loge("Disconnecting from Passpoint network due to an issue with the "
+ "Terms and Conditions URL");
sendMessage(CMD_DISCONNECT, StaEvent.DISCONNECT_PASSPOINT_TAC);
}
break;
case WifiMonitor.HS20_REMEDIATION_EVENT:
mPasspointManager.receivedWnmFrame((WnmData) message.obj);
break;
case WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE: {
handleBssTransitionRequest((BtmFrameData) message.obj);
break;
}
case CMD_CONFIG_ND_OFFLOAD: {
final boolean enabled = (message.arg1 > 0);
mWifiNative.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
break;
}
// Link configuration (IP address, DNS, ...) changes notified via netlink
case CMD_UPDATE_LINKPROPERTIES: {
updateLinkProperties((LinkProperties) message.obj);
break;
}
case CMD_START_IP_PACKET_OFFLOAD:
case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF:
case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
if (mNetworkAgent != null) {
mNetworkAgent.sendSocketKeepaliveEvent(message.arg1,
SocketKeepalive.ERROR_INVALID_NETWORK);
}
break;
}
case CMD_INSTALL_PACKET_FILTER: {
mCachedPacketFilter = (byte[]) message.obj;
if (mContext.getResources().getBoolean(
R.bool.config_wifiEnableApfOnNonPrimarySta)
|| isPrimary()) {
mWifiNative.installPacketFilter(mInterfaceName, mCachedPacketFilter);
} else {
Log.v(TAG, "Not applying packet filter on non primary CMM");
}
break;
}
case CMD_READ_PACKET_FILTER: {
final byte[] packetFilter;
if (mContext.getResources().getBoolean(
R.bool.config_wifiEnableApfOnNonPrimarySta)
|| isPrimary()) {
packetFilter = mWifiNative.readPacketFilter(mInterfaceName);
} else {
Log.v(TAG, "Retrieving cached packet filter on non primary CMM");
packetFilter = mCachedPacketFilter;
}
if (mIpClient != null) {
mIpClient.readPacketFilterComplete(packetFilter);
}
break;
}
case CMD_SET_FALLBACK_PACKET_FILTERING: {
if ((boolean) message.obj) {
mWifiNative.startFilteringMulticastV4Packets(mInterfaceName);
} else {
mWifiNative.stopFilteringMulticastV4Packets(mInterfaceName);
}
break;
}
case CMD_DIAGS_CONNECT_TIMEOUT: {
mWifiDiagnostics.reportConnectionEvent(
WifiDiagnostics.CONNECTION_EVENT_TIMEOUT, mClientModeManager);
break;
}
case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
case CMD_RESET_SIM_NETWORKS:
case WifiMonitor.NETWORK_CONNECTION_EVENT:
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
case CMD_RSSI_POLL:
case CMD_ONESHOT_RSSI_POLL:
case CMD_PRE_DHCP_ACTION:
case CMD_PRE_DHCP_ACTION_COMPLETE:
case CMD_POST_DHCP_ACTION:
case WifiMonitor.SUP_REQUEST_IDENTITY:
case WifiMonitor.SUP_REQUEST_SIM_AUTH:
case WifiMonitor.TARGET_BSSID_EVENT:
case WifiMonitor.ASSOCIATED_BSSID_EVENT:
case WifiMonitor.TRANSITION_DISABLE_INDICATION:
case CMD_UNWANTED_NETWORK:
case CMD_CONNECTING_WATCHDOG_TIMER:
case WifiMonitor.NETWORK_NOT_FOUND_EVENT:
case CMD_ROAM_WATCHDOG_TIMER: {
// no-op: all messages must be handled in the base state in case it was missed
// in one of the child states.
break;
}
case CMD_ACCEPT_EAP_SERVER_CERTIFICATE:
case CMD_REJECT_EAP_SERVER_CERTIFICATE:
case CMD_START_ROAM:
case CMD_START_RSSI_MONITORING_OFFLOAD:
case CMD_STOP_RSSI_MONITORING_OFFLOAD:
case CMD_IP_CONFIGURATION_SUCCESSFUL:
case CMD_IP_CONFIGURATION_LOST:
case CMD_IP_REACHABILITY_LOST:
case CMD_IP_REACHABILITY_FAILURE: {
mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
break;
}
case 0: {
// We want to notice any empty messages (with what == 0) that might crop up.
// For example, we may have recycled a message sent to multiple handlers.
Log.wtf(getTag(), "Error! empty message encountered");
break;
}
default: {
loge("Error! unhandled message" + message);
break;
}
}
logStateAndMessage(message, this);
return HANDLED;
}
}
2.3 ISupplicantStaNetworkCallback 回调监听
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java
SupplicantStaIfaceHalAidlImpl.java#connectToNetwork / addNetworkAndSaveConfig > SupplicantStaNetworkHalAidlImpl.java#saveWifiConfiguration / registerNewCallback / registerCallback > mISupplicantStaNetwork.registerCallback(callback)
3、 简要时序图
4、原生低层驱动
external/wpa_supplicant_8
5、关键日志
WifiService: connect uid=
|WifiConfigManager: Adding/Updating network|WifiConfigManager: Enable disabled network:|WifiConfigManager: Enabling network|WifiConfigManager: Update network last connect|WifiPickerTracker: Received broadcast:|WifiClientModeImpl.*entering.*State
|WifiClientModeImpl.*entering|WifiClientModeImpl.*connectToUserSelectNetwork netId|WifiClientModeImpl.*CMD_START_CONNECT
|WifiClientModeImpl.*Select candidate security params for|WifiClientModeImpl.*Connecting with
|SupplicantStaIfaceHalAidlImpl: connectToNetwork|SupplicantStaNetworkHalAidlImpl: Successfully set SSID|SupplicantStaNetworkHalAidlImpl: The target security params|SupplicantStaIfaceHalAidlImpl: ISupplicantStaIfaceCallback|wpa_supplicant:.* State:
|wpa_supplicant: Notifying state change event|wpa_supplicant: wlan
wpa_supplicant: wlan|wpa_supplicant: