Android WiFi 连接

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() 当前连接的WiFi
  • mWifiPickerTracker.getWifiEntries() 搜索的WiFi
  • mAddWifiNetworkPreference 添加WiFi项
  • WifiManager.java#connectStandardWifiEntry.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 changedif (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 changedremovePreference(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 animationgetView().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() {@Overridepublic 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);}}};@Overridepublic 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);}@Overridepublic 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();}@Overridepublic 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 connectionmLastScanRssi = 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 netlinkcase 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:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/233239.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

性能分析与调优: Linux 实现 CPU剖析与火焰图

目录 一、实验 1.环境 2.CPU 剖析 3.CPU火焰图 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系统 prometheus、node_exporter 192.168.204.18grafana监测GUIgrafana192.168.204.19agent 监测 主机 node_exporter192…

【Java】设计模式之两阶段终止

两阶段终止 两阶段终止&#xff0c;即Two Phase Termination。是用来终止线程的套路。 它的思想是&#xff0c;如何在一个线程T1中优雅地终止线程T2&#xff1f;这里的【优雅】指的是给T2一个料理后事的机会。 错误思路&#xff1a; 使用stop方法。stop 方法会真正杀死线程…

使用命令行方式搭建uni-app + Vue3 + Typescript + Pinia + Vite + Tailwind CSS + uv-ui开发脚手架

使用命令行方式搭建uni-app Vue3 Typescript Pinia Vite Tailwind CSS uv-ui开发脚手架 项目代码以上传至码云&#xff0c;项目地址&#xff1a;https://gitee.com/breezefaith/uniapp-vue3-ts-scaffold 文章目录 使用命令行方式搭建uni-app Vue3 Typescript Pinia V…

多线程执行后台任务,提供效率

场景&#xff1a; 大批量复制物料描述到新的物料上&#xff0c;多线程同时执行已提高效率 REPORT zmm316. INCLUDE zmm316_top. INCLUDE zmm316_f01. *----------------------------------------------------------------------- I N I T I A L I Z A T I O N *------------…

向量数据库:usearch的简单使用+实现图片检索应用

usearch的简单使用 usearch是快速开源搜索和聚类引擎&#xff0c;用于C、C、Python、JavaScript、Rust、Java、Objective-C、Swift、C#、GoLang和Wolfram &#x1f50d;中的向量和&#x1f51c;字符串 // https://github.com/unum-cloud/usearch/blob/main/python/README.md …

[C#]使用sdcb.paddleocr部署v4版本ocr识别模型

【官方框架地址】 https://github.com/sdcb/PaddleSharp 【算法介绍】 PaddleOCR&#xff0c;全称为PaddlePaddle OCR&#xff0c;是PaddlePaddle深度学习平台下的一款强大的光学字符识别工具。它利用深度学习技术&#xff0c;实现了高精度的文字识别&#xff0c;可以帮助用户…

生态系统服务构建生态安全格局中的实践技术应用

生态安全是指生态系统的健康和完整情况。生态安全的内涵可以归纳为&#xff1a;一&#xff0c;保持生态系统活力和内外部组分、结构的稳定与持续性&#xff1b;二&#xff0c;维持生态系统生态功能的完整性&#xff1b;三&#xff0c;面临外来不利因素时&#xff0c;生态系统具…

window使用cpolar实现内网穿透

文章目录 cpolar下载和安装启动和配置cpolar卸载 cpolar下载和安装 进入spolar官网&#xff0c;完成注册&#xff0c;下载相应的cploar版本解压和运行安装文件 配置安装路径&#xff0c;然后选择next&#xff0c;完成即可 启动和配置 点击首页的快捷图标打开网页&#xf…

分布式系统架构设计之分布式消息队列基础知识

随着微服务、大数据和云计算的普及&#xff0c;分布式系统已经成为现代软件架构的核心。在分布式系统中&#xff0c;各个组件间的通信和数据交换尤其重要&#xff0c;而消息队列正是实现这一目标的关键技术之一。 在分布式架构设计过程中&#xff0c;架构师们需要对消息队列有…

StarRocks 在小红书自助分析场景的应用与实践

作者&#xff1a;小红书 OLAP 研发负责人 王成 近两年 StarRocks 一直是小红书 OLAP 引擎体系里非常重要的部分&#xff0c;过去一年&#xff0c;小红书的 StarRocks 使用规模呈现出翻倍的增长速度&#xff0c;目前整体规模已经达到 30 个集群&#xff0c;CPU 规模已经达到了 3…

Redis——centos7环境安装Redis6.2.14版本,make命令编译时报错:jemalloc/jemalloc.h:没有那个文件或目录

一、报错原因 在redis-6.2.14文件夹下有一个README.md文件&#xff0c;有如下一段话&#xff1a; 在构建 Redis 时&#xff0c;通过设置 MALLOC 环境变量来选择非默认的内存分配器。Redis 默认编译并链接到 libc malloc&#xff0c;但在 Linux 系统上&#xff0c;jemalloc 是…

图像分割-Grabcut法(C#)

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 本文的VB版本请访问&#xff1a;图像分割-Grabcut法-CSDN博客 GrabCut是一种基于图像分割的技术&#xff0c;它可以用于将图像中的…

Python | 基于Mediapipe框架的手势识别系统

一、项目要求 1、题目 本题着力于解决会商演示系统中的非接触式人机交互问题&#xff0c;具体而言&#xff0c;其核心问题就是通过计算机视觉技术实现对基于视频流的手势动作进行实时检测和识别。通过摄像头采集并识别控制者连续的手势动作&#xff0c;完成包括点击、平移、缩放…

小白入门基础 - Restful

一&#xff1a;REST与RESTful&#xff1a; REST&#xff1a;表现层状态转移&#xff0c;资源在网络中以某种形式进行状态转移。 RESTful是基于REST理念的一套开发风格&#xff0c;是具体的开发规则。 服务器端只返回数据&#xff0c;以json或者xml的格式。 RESTful开发规范&a…

【大数据】Spark学习笔记

初识Spark Spark和Hadoop HadoopSpark起源时间20052009起源地MapReduceUniversity of California Berkeley数据处理引擎BatchBatch编程模型MapReduceResilient distributed Datesets内存管理Disk BasedJVM Managed延迟高中吞吐量中高优化机制手动手动APILow levelhigh level流…

MySQL之视图外连接、内连接和子查询的使用

目录 一、视图 1.1 含义 1.2 操作 1.3 SQL数据 二、连接查询案例 &#xff08;1&#xff09;查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数 &#xff08;2&#xff09;查询同时存在" 01 "课程和" 02 "课程的情况 &a…

docker安裝gocd-server,并配置gitlab授权登录

gocd的地址&#xff1a;Installing GoCD server on Windows | GoCD User Documentation gocd文档&#xff1a;GitHub - gocd/docker-gocd-server: Docker server image for GoCD 一、docker拉取gocd镜像 #拉取server镜像 docker pull gocd/gocd-server:v21.1.0docker pull g…

java SSM水质历史数据可视化设计myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM水质历史数据可视化设计是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主…

QT常用控件使用及布局

QT常用控件使用及布局 文章目录 QT常用控件使用及布局1、创建带Ui的工程2、ui界面介绍1、界面设计区2、对象监视区3、对象监属性编辑区4、信号与槽5、布局器6、控件1、Layouts1、布局管理器2、布局的dome 2、Spacers3、Buttons4、项目视图组(Item Views)5、项目控件组(Item Wid…

“数据要素×”正式来袭|美创“全栈能力、深入场景”保障数据价值安全释放

千呼万唤&#xff0c;1月4日&#xff0c;国家数据局等17部门联合印发的《“数据要素”三年行动计划&#xff08;2024—2026年&#xff09;》&#xff08;下称《三年行动计划》&#xff09;正式发布&#xff01; 作为国家数据局成立以来公开发布的首个重磅文件&#xff0c;《三年…