赞
踩
Wi-Fi STA/STA 并发:Android 12 引入了 Wi-Fi STA/STA 并发功能,使设备可同时连接到两个 Wi-Fi 网络
packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml
<!-- Enable Make-Before-Break Wifi network switching.
Note: this is conditional on the device supporting dual concurrent STAs. -->
<bool translatable="false" name="config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled">false</bool>
<!-- Enable concurrent peer to peer + internet connectivity
Note: this is conditional on the device supporting dual concurrent STAs. -->
<bool translatable="false" name="config_wifiMultiStaLocalOnlyConcurrencyEnabled">false</bool>
<!-- Enable concurrent restricted connectivity + internet connectivity
Note: this is conditional on the device supporting dual concurrent STAs. -->
<bool translatable="false" name="config_wifiMultiStaRestrictedConcurrencyEnabled">false</bool>
<!-- Enable concurrent internet connectivity + internet connectivity
Note: this is conditional on the device supporting dual concurrent STAs. -->
<bool translatable="false" name="config_wifiMultiStaMultiInternetConcurrencyEnabled">false</bool>
mWifiManager.isWifiEnabled()
WIFI开关是否打开mWifiManager.isStaConcurrencyForMultiInternetSupported()
属性config_wifiMultiStaMultiInternetConcurrencyEnabled
配置mWifiManager.getStaConcurrencyForMultiInternetMode() == WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP
模式双WIFI STA/STA开关是否打开(模式设置setStaConcurrencyForMultiInternetMode
)
WifiManager#WIFI_MULTI_INTERNET_MODE_DBS_AP
:限制与 DBS AP 的双频的并发连接。WifiManager#WIFI_MULTI_INTERNET_MODE_MULTI_AP
:连接到任意 AP,其中的各个连接使用不同的频段。WifiManager#WIFI_MULTI_INTERNET_MODE_DISABLED
:停用功能。
adb shell cmd wifi
(Android framework服务命令行工具框架 - Android13)
packages/modules/Wifi/service/java/com/android/server/wifi/WifiShellCommand.java
- 启用详细日志记录:
adb shell cmd wifi set-verbose-logging enabled
- 清理旧的wifi建议(如果有的话):
adb shell cmd wifi remove-all-suggestions
adb shell cmd wifi list-all-suggestions
- WiFi连接状态查询:
adb shell cmd wifi status | grep -E "==|connected to"
==== ClientModeManager instance: ConcreteClientModeManager{id=33409 iface=wlan0 role=ROLE_CLIENT_PRIMARY} ==== Wifi is connected to "guest_5G" ==== ClientModeManager instance: ConcreteClientModeManager{id=82271673 iface=wlan1 role=ROLE_CLIENT_SECONDARY_LONG_LIVED} ==== Wifi is connected to "guest"
- 1
- 2
- 3
- 4
- 添加WifiNetworkSuggestion网络连接:
adb shell cmd wifi add-suggestion guest_5G wpa3 12345678 -p
- 执行网络扫描:
adb shell cmd wifi start-scan
- 断开移除WifiNetworkSuggestion网络:
adb shell cmd wifi remove-suggestion guest_5G
添加WifiNetworkSuggestion网络连接:
- 参数
guest_5G wpa3 12345678
网络名称、类型、密码- 参数
-p
(或-o
)设置setOemPaid(true)
、setOemPrivate(true)
(设备能够连接到副Wi-Fi网络:添加 Wi-Fi 网络建议,方法是将 setOemPaid 或 setOemPrivate 设置为 true。)mConnectivityManager.requestNetwork(networkRequest, networkCallback)
:TRANSPORT_WIFI
网络请求
(在 ConnectivityManager 中,提交具有相应功能的 NetworkRequest:为 setOemPaid 提交 NET_CAPABILITY_OEM_PAID 功能(为 setOemPrivate 提交 NET_CAPABILITY_OEM_PRIVATE 功能))
case "add-suggestion": { WifiNetworkSuggestion suggestion = buildSuggestion(pw); if (suggestion == null) { pw.println("Invalid network suggestion parameter"); return -1; } int errorCode = mWifiService.addNetworkSuggestions( Arrays.asList(suggestion), SHELL_PACKAGE_NAME, null); if (errorCode != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { pw.println("Add network suggestion failed with error code: " + errorCode); return -1; } // untrusted/oem-paid networks need a corresponding NetworkRequest. if (suggestion.isUntrusted() || (SdkLevel.isAtLeastS() && (suggestion.isOemPaid() || suggestion.isOemPrivate()))) { NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder() .addTransportType(TRANSPORT_WIFI); if (suggestion.isUntrusted()) { networkRequestBuilder.removeCapability(NET_CAPABILITY_TRUSTED); } if (SdkLevel.isAtLeastS()) { if (suggestion.isOemPaid()) { networkRequestBuilder.addCapability(NET_CAPABILITY_OEM_PAID); } if (suggestion.isOemPrivate()) { networkRequestBuilder.addCapability(NET_CAPABILITY_OEM_PRIVATE); } } NetworkRequest networkRequest = networkRequestBuilder.build(); ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(); pw.println("Adding request: " + networkRequest); mConnectivityManager.requestNetwork(networkRequest, networkCallback); sActiveRequests.put( suggestion.getSsid(), Pair.create(networkRequest, networkCallback)); } return 0; } //解析网络参数 private WifiNetworkSuggestion buildSuggestion(PrintWriter pw) { String ssid = getNextArgRequired(); String type = getNextArgRequired(); WifiNetworkSuggestion.Builder suggestionBuilder = new WifiNetworkSuggestion.Builder(); suggestionBuilder.setSsid(ssid); if (TextUtils.equals(type, "wpa3")) { suggestionBuilder.setWpa3Passphrase(getNextArgRequired()); } else if (TextUtils.equals(type, "wpa2")) { suggestionBuilder.setWpa2Passphrase(getNextArgRequired()); } else if (TextUtils.equals(type, "owe")) { suggestionBuilder.setIsEnhancedOpen(true); } else if (TextUtils.equals(type, "open")) { // nothing to do. } else { throw new IllegalArgumentException("Unknown network type " + type); } boolean isCarrierMerged = false; String option = getNextOption(); while (option != null) { if (option.equals("-u")) { suggestionBuilder.setUntrusted(true); } else if (option.equals("-o")) { if (SdkLevel.isAtLeastS()) { suggestionBuilder.setOemPaid(true); } else { throw new IllegalArgumentException( "-o OEM paid suggestions not supported before S"); } } else if (option.equals("-p")) { if (SdkLevel.isAtLeastS()) { suggestionBuilder.setOemPrivate(true); } else { throw new IllegalArgumentException( "-p OEM private suggestions not supported before S"); } } else if (option.equals("-m")) { suggestionBuilder.setIsMetered(true); } else if (option.equals("-s")) { suggestionBuilder.setCredentialSharedWithUser(true); } else if (option.equals("-d")) { suggestionBuilder.setIsInitialAutojoinEnabled(false); } else if (option.equals("-b")) { suggestionBuilder.setBssid(MacAddress.fromString(getNextArgRequired())); } else if (option.equals("-r")) { if (SdkLevel.isAtLeastS()) { suggestionBuilder.setMacRandomizationSetting( WifiNetworkSuggestion.RANDOMIZATION_NON_PERSISTENT); } else { throw new IllegalArgumentException( "-r non_persistent MAC randomization not supported before S"); } } else if (option.equals("-a")) { if (SdkLevel.isAtLeastS()) { isCarrierMerged = true; } else { throw new IllegalArgumentException("-a option is not supported before S"); } } else if (option.equals("-i")) { if (SdkLevel.isAtLeastS()) { int subId = Integer.parseInt(getNextArgRequired()); suggestionBuilder.setSubscriptionId(subId); } else { throw new IllegalArgumentException( "-i subscription ID option is not supported before S"); } } else if (option.equals("-c")) { int carrierId = Integer.parseInt(getNextArgRequired()); suggestionBuilder.setCarrierId(carrierId); } else if (option.equals("-h")) { suggestionBuilder.setIsHiddenSsid(true); } else { pw.println("Ignoring unknown option " + option); } option = getNextOption(); } WifiNetworkSuggestion suggestion = suggestionBuilder.build(); if (isCarrierMerged) { if (suggestion.wifiConfiguration.subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { pw.println("Carrier merged network must have valid subscription Id"); return null; } suggestion.wifiConfiguration.carrierMerged = true; } return suggestion; }
断开移除WifiNetworkSuggestion网络:
mConnectivityManager.unregisterNetworkCallback(nrAndNc.second)
:移除请求时的NetworkCallback就可以断开WiFi网络mWifiService.removeNetworkSuggestions()
:移除WifiNetworkSuggestion网路信息,这里就会移除WifiConfigStoreNetworkSuggestions.xml
保存信息
case "remove-suggestion": { String ssid = getNextArgRequired(); String action = getNextArg(); int actionCode = ACTION_REMOVE_SUGGESTION_DISCONNECT; if (action != null && action.equals("lingering")) { actionCode = ACTION_REMOVE_SUGGESTION_LINGER; } List<WifiNetworkSuggestion> suggestions = mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME); WifiNetworkSuggestion suggestion = suggestions.stream() .filter(s -> s.getSsid().equals(ssid)) .findAny() .orElse(null); if (suggestion == null) { pw.println("No matching suggestion to remove"); return -1; } mWifiService.removeNetworkSuggestions( Arrays.asList(suggestion), SHELL_PACKAGE_NAME, actionCode); // untrusted/oem-paid networks need a corresponding NetworkRequest. if (suggestion.isUntrusted() || (SdkLevel.isAtLeastS() && (suggestion.isOemPaid() || suggestion.isOemPrivate()))) { Pair<NetworkRequest, ConnectivityManager.NetworkCallback> nrAndNc = sActiveRequests.remove(suggestion.getSsid()); if (nrAndNc == null) { pw.println("No matching request to remove"); return -1; } pw.println("Removing request: " + nrAndNc.first); mConnectivityManager.unregisterNetworkCallback(nrAndNc.second); } return 0; }
packages/modules/Wifi/service/java/com/android/server/wifi/WifiConfigStore.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiConfigManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
Dump of WifiConfigStore
WifiConfigStore - Store File Begin ----
Name: /data/misc/apexdata/com.android.wifi/WifiConfigStore.xml, File Id: 0, Credentials encrypted: false
Name: /data/misc/apexdata/com.android.wifi/WifiConfigStoreSoftAp.xml, File Id: 1, Credentials encrypted: false
Name: /data/misc_ce/0/apexdata/com.android.wifi/WifiConfigStore.xml, File Id: 2, Credentials encrypted: false
Name: /data/misc_ce/0/apexdata/com.android.wifi/WifiConfigStoreNetworkSuggestions.xml, File Id: 3, Credentials encrypted: false
WifiConfigStore - Store Data Begin ----
- 设置
setOemPaid
或setOemPrivate
,并mWifiService.addNetworkSuggestions
添加WifiNetworkSuggestion
信息NetworkRequest
请求信息添加TRANSPORT_WIFI
、NET_CAPABILITY_OEM_PRIVATE
(或NET_CAPABILITY_OEM_PAID
)mConnectivityManager.requestNetwork(networkRequest, networkCallback)
请网络,networkCallback
监听连接状态(断开是注销networkCallback
)- 请求执行到
OemWifiNetworkFactory.java#needNetworkFor
,OemPaidWifiNetworkFactory
有挂起的网络请求触发,设置mOemPaidConnectionAllowed、mOemPaidConnectionRequestorWs
,并开启自动联接setAutoJoinEnabled
和启动连接性扫描startConnectivityScan
packages/modules/Wifi/service/java/com/android/server/wifi/OemWifiNetworkFactory.java
protected void needNetworkFor(NetworkRequest networkRequest) { if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) { mOemPaidConnectionReqCount++; if (mOemPaidConnectionReqCount == 1) { mWifiConnectivityManager.setOemPaidConnectionAllowed( true, new WorkSource(networkRequest.getRequestorUid(), networkRequest.getRequestorPackageName())); } } if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) { mOemPrivateConnectionReqCount++; if (mOemPrivateConnectionReqCount == 1) { mWifiConnectivityManager.setOemPrivateConnectionAllowed( true, new WorkSource(networkRequest.getRequestorUid(), networkRequest.getRequestorPackageName())); } } }
packages/modules/Wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java
public void setOemPaidConnectionAllowed(boolean allowed, WorkSource requestorWs) { localLog("setOemPaidConnectionAllowed: allowed=" + allowed + ", requestorWs=" + requestorWs); if (mOemPaidConnectionAllowed != allowed) { mOemPaidConnectionAllowed = allowed; mOemPaidConnectionRequestorWs = requestorWs; checkAllStatesAndEnableAutoJoin(); } } private void checkAllStatesAndEnableAutoJoin() { // if auto-join was disabled externally, don't re-enable for any triggers. // External triggers to disable always trumps any internal state. setAutoJoinEnabled(mAutoJoinEnabledExternal && (mUntrustedConnectionAllowed || mOemPaidConnectionAllowed || mOemPrivateConnectionAllowed || mTrustedConnectionAllowed || mRestrictedConnectionAllowedUids.size() != 0 || hasMultiInternetConnection()) && !mSpecificNetworkRequestInProgress); startConnectivityScan(SCAN_IMMEDIATELY); }
接收到WifiScanner扫描结果
AllSingleScanListener#onResults
:
- 获取Wifi候选者
mNetworkSelector.getCandidatesFromScan()
- 当支持STA双WIFI连接且
secondaryCmmCandidates
不为空,执行handleCandidatesFromScanResultsUsingSecondaryCmmIfAvailable
去mActiveModeWarden.requestSecondaryLongLivedClientModeManager
请求创建副WiFi类型ROLE_CLIENT_SECONDARY_LONG_LIVED
的ConcreteClientModeManager
- 最后执行
connectToNetworkUsingCmmWithoutMbb > triggerConnectToNetworkUsingCmm > clientModeManager.startConnectToNetwork()
连接网络,只有就可主Wifi连接一样,只是不同的wlan0
或wlan1
。(Android WiFi 连接)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。