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.mzph.cn/news/604451.shtml

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

相关文章

关于对象存储的若干事

引言 最近在阅读鸣嵩的一篇文章&#xff0c;数据库的下一场革命&#xff1a;S3 延迟已降至原先的 10%&#xff0c;云数据库架构该进化了 收获很多&#xff0c;过去时间也基于对象存储做过一些功能实现&#xff0c;特记录下。关于鸣嵩&#xff1a; 曹伟&#xff0c;花名鸣嵩&am…

用友NC word.docx 任意文件读取漏洞复现

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友NC 系统word.docx等接口存在任意文件…

JavaScript 基础二part1.运算符:赋值、一元、比较、逻辑运算符

JavaScript 基础二 1.1 赋值运算符1.2 一元运算符自增运算符的用法&#xff1a;例题 1.3 比较运算符不同类型间的比较严格相等对 null 和 undefined 进行比较 1.4 逻辑运算符例题 1.5 运算符优先级 1.1 赋值运算符 赋值运算符&#xff1a;对变量进行赋值的运算符 已经学过的赋…

光速爱购--靠谱的SpringBoot项目

简介 这是一个靠谱的SpringBoot项目实战&#xff0c;名字叫光速爱购。从零开发项目&#xff0c;视频加文档&#xff0c;十天就能学会开发JavaWeb项目。 教程路线是&#xff1a;搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Java代码&g…

HarmonOS 通用组件(Checkbox)

本文中 我们来说 通用组件中的 Checkbox 我们先搭起一个基本的架子组件 Entry Component struct Index {build() {Row() {Column() {Row() {}}.width(100%)}.height(100%)} }我们可以在Row 行组件中加入代码 Checkbox({name: "age"}) Text("年龄")这样 就…

专为Mac用户设计的思维导图软件MindNode 2023 for Mac助您激发创意!

在现代快节奏的生活中&#xff0c;我们经常需要整理思绪、规划项目、记录灵感。而思维导图作为一种高效的思维工具&#xff0c;能够帮助我们更好地整理和展现思维。现在&#xff0c;我们介绍一款强大而直观的思维导图软件——MindNode 2023 for Mac&#xff0c;助您拓展思维边界…

计算机毕业设计 基于Javaweb的城乡居民基本医疗信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

log4cpp日志库使用

Log4cpp是一个开源的C类库&#xff0c;它提供了C程序中使用日志和跟踪调试的功能&#xff0c;它提供了应用程序运行上下文&#xff0c;方便跟踪调试&#xff1b;可扩展的、多种方式记录日志&#xff0c;包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等&#xf…

【EAI 004】LLM+P:借助LLM和PDDL赋予机器人最优规划能力

论文标题&#xff1a;LLMP: Empowering Large Language Models with Optimal Planning Proficiency 论文作者&#xff1a;Bo Liu, Yuqian Jiang, Xiaohan Zhang, Qiang Liu, Shiqi Zhang, Joydeep Biswas, Peter Stone 作者单位&#xff1a;Department of Computer Science, Th…

安科瑞电力物联网系统在电力设备在线监测中的应用——安科瑞 顾烊宇

摘要&#xff1a;近年来&#xff0c;社会经济发展速度不断提升&#xff0c;对电力能源的需求大幅增加&#xff0c;为保障变电站等电力设备合理发挥功能&#xff0c;保障供电安全性和稳定性&#xff0c;应当加强对电力设备的监测和管理。而电力物联网技术是现代一种安全工器具的…

记一个React组件入参不当导致页面卡死的问题

一、问题描述 1.1 触发现象 点击按钮后页面卡死 1.2 最小 Demo CodeSandBox&#xff1a;https://codesandbox.io/p/sandbox/react-hook-component-stuck-755wcyinscode&#xff1a;https://inscode.csdn.net/ import ./App.css; import React, { useState, useEffect } f…

JVM中对象的创建

一.JVM运行流程 JVM向操作系统申请内存&#xff0c;初始化运行时数据区&#xff0c;接下来装载使用的类&#xff0c;执行类里面相应方法的时候为当前虚拟机栈压入一个栈帧&#xff0c;方法执行完成后栈帧出栈&#xff0c;进行垃圾回收。 二.JVM中对象的创建过程 符号引用&…

第03章_运算符与流程控制

第03章_运算符与流程控制 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题脉络 1. 运算符&#xff08;Operator&#xff09; 运算符是一种特殊的符号&#xff0c;用以表示数据的运算、赋…

CSS基础笔记-04cascade-specificity-inheritance

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》CSS基础笔记-03选择器 前言 Cascading Style Sheets&#xff0c;关键就在于这个cascading&#xff0c;对于这个术语理解&#xff0c;感觉对于我这种CSS新手有点儿不太friendly。本文记录下我对这个术语的理…

互联网分布式应用之SpringCloud

SpringCloud Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. 微服务项目介绍 2. Eure…

kafka-zookeeper集群架构可视化监控,Kafka-Eagle安装部署

1、简介 在 kafka-zookeeper 集群架构下&#xff0c;zookeeper 管理 kafka 的元数据信息&#xff0c;如何监控这些信息&#xff0c;并且能够直观查看和管理 kafka 一些具体 主题、分区等参数信息&#xff0c;是非常便于开发的&#xff0c;因此 Kafka-Eagle 是一个为监控 kafka …

基于机器视觉的车牌检测-边缘检测因子的选择

车牌检测概述 车牌识别在检测报警、汽车出入登记、交通违法违章以及移动电子警察方面应用广泛。车牌识别过程为&#xff1a;首先通过摄像头获取包含车牌的彩色图像&#xff1b;然后进行车牌边缘检测&#xff0c;先粗略定位到车牌位置&#xff0c;再精细定位&#xff1b;最后根…

[AutoSar]基础部分 RTE 05 Port的实例化和初始化

目录 关键词平台说明一、端口类型二、端口的实例化2.1 创建application port2.2 实例化 三、初始化 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、端口类型 如下图所示&am…

MvvmToolkit的使用

背景&#xff1a;MvvmLight不更新了&#xff0c;用Toolkit代替 1、首先下载好社区版本的NuGet包 2、ViewModel中需要继承ObservableObject&#xff0c;查看ObservableObject可以看到里面有实现好InotifyPropertyChanged。 3、对于属性的set&#xff0c;可以简写成一行&#xff…

鸿蒙应用开发 闹钟实现

后台代理提醒简介 随着生活节奏的加快&#xff0c;我们有时会忘记一些重要的事情或日子&#xff0c;所以提醒功能必不可少。应用可能需要在指定的时刻&#xff0c;向用户发送一些业务提醒通知。例如购物类应用&#xff0c;希望在指定时间点提醒用户有优惠活动。为满足此类业务…