@L_404_0@
Android N selectQualifiedNetwork分析
今天了解了一下Wifi自动连接时的评分机制,总结如下:
WifiConnectivityManager的初始化:
/frameworks/opt/net/wifi/service/java/com/androID/server/wifi/WifiStateMachine.java
class SupplicantStartedState extends State { if (mWifiScanner == null) { mWifiScanner = mWifiInjector.getWifiScanner(); synchronized (mWifiReqCountLock) { mWifiConnectivityManager = mWifiInjector.makeWifiConnectivityManager(mWifiInfo, hasConnectionRequests()); mWifiConnectivityManager.setUntrustedConnectionAllowed(mUntrustedReqCount > 0); mWifiConnectivityManager.handleScreenStateChanged(mScreenOn); } }
/frameworks/opt/net/wifi/service/java/com/androID/server/wifi/WifiInjector.java
public WifiConnectivityManager makeWifiConnectivityManager(WifiInfo wifiInfo, boolean hasConnectionRequests) { return new WifiConnectivityManager(mContext, mWifiStateMachine, getWifiScanner(), mWifiConfigManager, wifiInfo, mWifiNetworkSelector, mWifiConnectivityHelper, mWifiLastResortWatchdog, mOpenNetworkNotifIEr, mWifiMetrics, mWifiStateMachineHandlerThread.getLooper(), mClock, mConnectivityLocalLog, hasConnectionRequests, mFrameworkFacade, mSavednetworkEvaluator, mscoredNetworkEvaluator, mPasspointNetworkEvaluator); }
WifiConnectivityManager中会注册三个Evaluator。
/frameworks/opt/net/wifi/service/java/com/androID/server/wifi/WifiConnectivityManager.java
mNetworkSelector.registerNetworkEvaluator(savednetworkEvaluator, SAVED_NETWORK_EVALUATOR_PRIORITY); if (hs2Enabled) { mNetworkSelector.registerNetworkEvaluator(passpointNetworkEvaluator, PAsspOINT_NETWORK_EVALUATOR_PRIORITY); } mNetworkSelector.registerNetworkEvaluator(scoredNetworkEvaluator, scoreD_NETWORK_EVALUATOR_PRIORITY);
继续看下注册方法,其实就是初始化一个NetworkEvaluator数组,大小为6,即优先级从高到低0-5。
/frameworks/opt/net/wifi/service/java/com/androID/server/wifi/WifiNetworkSelector.java
public static final int EVALUATOR_MIN_PRIORITY = 6; private final NetworkEvaluator[] mEvaluators = new NetworkEvaluator[MAX_NUM_EVALUATORS]; public boolean registerNetworkEvaluator(NetworkEvaluator evaluator, int priority) { if (priority < 0 || priority >= EVALUATOR_MIN_PRIORITY) { localLog("InvalID network evaluator priority: " + priority); return false; } if (mEvaluators[priority] != null) { localLog("Priority " + priority + " is already registered by " + mEvaluators[priority].getname()); return false; } mEvaluators[priority] = evaluator; return true; }
WifiConnectivityManager的网络评估
private boolean handleScanResults(@R_502_6818@<ScanDetail> scanDetails, String @R_502_6818@enername) { if (mSupportCMCC && mWifiManagerEx.isautoConnect() == false) { Log.i(TAG, "WifiManagerEx isautoConnect false, " + mWifiManagerEx.isautoConnect()); return false; } if (!mP2pWifiCoexistSupported && wifip2pServiceImpl.mP2pConnectingOrConnected) { Log.i(TAG, "Do not auto connect when wifi and p2p should not coexsit"); return false; } refreshBssIDBlack@R_502_6818@(); if (mStateMachine.islinkDebouncing() || mStateMachine.isSupplicantTransIEntState()) { localLog(@R_502_6818@enername + " onResults: No network selection because linkDebouncing is " + mStateMachine.islinkDebouncing() + " and supplicantTransIEnt is " + mStateMachine.isSupplicantTransIEntState()); return false; } localLog(@R_502_6818@enername + " onResults: start network selection"); WifiConfiguration candIDate = mNetworkSelector.selectNetwork(scanDetails, buildBssIDBlack@R_502_6818@(), mWifiInfo, mStateMachine.isConnected(), mStateMachine.isdisconnected(), mUntrustedConnectionAllowed); mWifiLastResortWatchdog.updateAvailableNetworks( mNetworkSelector.getConnectableScanDetails()); mWifiMetrics.countScanResults(scanDetails); if (candIDate != null) { localLog(@R_502_6818@enername + ": WNS candIDate-" + candIDate.SSID); connectToNetwork(candIDate); return true; } else { if (mWifiState == WIFI_STATE_disCONNECTED) { mOpenNetworkNotifIEr.handleScanResults( mNetworkSelector.getFilteredScanDetailsForOpenUnsavednetworks()); } return false; } }
如API注释所述,对周期性、单次和pno扫描的结果进行潜在网络候选者的选择,如果有合适的网络,则进行连接
看下candiate是如何产生的:
public WifiConfiguration selectNetwork(@R_502_6818@<ScanDetail> scanDetails, HashSet<String> bssIDBlack@R_502_6818@, WifiInfo wifiInfo, boolean connected, boolean disconnected, boolean untrustednetworkAllowed) mFilterednetworks.clear(); mConnectableNetworks.clear(); if (scanDetails.size() == 0) { localLog("Empty connectivity scan result"); return null; WifiConfiguration currentNetwork = mWifiConfigManager.getConfigurednetwork(wifiInfo.getNetworkID()); String currentBssID = wifiInfo.getBSSID(); if (!isNetworkSelectionNeeded(scanDetails, wifiInfo, connected, disconnected)) { return null; } for (NetworkEvaluator registeredEvaluator : mEvaluators) { if (registeredEvaluator != null) { registeredEvaluator.update(scanDetails); } } mFilterednetworks = filterScanResults(scanDetails, bssIDBlack@R_502_6818@, connected, currentBssID); if (mFilterednetworks.size() == 0) { return null; } WifiConfiguration selectednetwork = null; for (NetworkEvaluator registeredEvaluator : mEvaluators) { if (registeredEvaluator != null) { localLog("About to run " + registeredEvaluator.getname() + " :"); selectednetwork = registeredEvaluator.evaluateNetworks( new Array@R_502_6818@<>(mFilterednetworks), currentNetwork, currentBssID, connected, untrustednetworkAllowed, mConnectableNetworks); if (selectednetwork != null) { localLog(registeredEvaluator.getname() + " selects " + WifiNetworkSelector.toNetworkString(selectednetwork) + " : " + selectednetwork.getNetworkSelectionStatus().getCandIDate().BSSID); break; } if (selectednetwork != null) { selectednetwork = overrIDeCandIDateWithUserConnectChoice(selectednetwork); mLastNetworkSelectionTimeStamp = mClock.getElapsedSinceBootMillis(); } return selectednetwork; }
看下是否可以进行网络选择:
1、 当前网络无效时
2、 当前没有连接网络时
private boolean isNetworkSelectionNeeded(@R_502_6818@<ScanDetail> scanDetails, WifiInfo wifiInfo, boolean connected, boolean disconnected) { if (scanDetails.size() == 0) { localLog("Empty connectivity scan results. Skip network selection."); return false; } if (connected) { if (isCurrentNetworkSufficIEnt(wifiInfo, scanDetails)) { localLog("Current connected network already sufficIEnt. Skip network selection."); return false; } else { localLog("Current connected network is not sufficIEnt."); return true; } } else if (disconnected) { return true; } else {
判断网络是否有效,主要是看以下几点要素:
RSSi(区分2.4G还是5G)packet rateephemeral(短暂的)open network5G优先级>2.4G private boolean isCurrentNetworkSufficIEnt(WifiInfo wifiInfo, @R_502_6818@<ScanDetail> scanDetails) { WifiConfiguration network = mWifiConfigManager.getConfigurednetwork(wifiInfo.getNetworkID()); int currentRSSi = wifiInfo.getRSSi(); boolean hasQualifIEdRSSi = (wifiInfo.is24GHz() && (currentRSSi > mThresholdQualifIEdRSSi24)) || (wifiInfo.is5GHz() && (currentRSSi > mThresholdQualifIEdRSSi5)); boolean hasActiveStream = (wifiInfo.getTxSuccessRatePps() > mStayOnNetworkMinimumTxRate) || (wifiInfo.getRxSuccessRatePps() > mStayOnNetworkMinimumRxRate); if (hasQualifIEdRSSi && hasActiveStream) { localLog("Stay on current network because of good RSSI and ongoing traffic"); return true; } if (network.ephemeral) { localLog("Current network is an ephemeral one."); return false; } if (WifiConfigurationUtil.isConfigForOpenNetwork(network)) { localLog("Current network is a open one."); return false; } if (wifiInfo.is24GHz()) { if (is5GHzNetworkAvailable(scanDetails)) { localLog("Current network is 2.4GHz. 5GHz networks available."); return false; } } if (!hasQualifIEdRSSi) { localLog("Current network RSSI[" + currentRSSi + "]-acceptable but not qualifIEd."); return false; } return true; }
SavednetworkEvaluator的筛选
首先遍历扫描结果:
for (ScanDetail scanDetail : scanDetails) { ScanResult scanResult = scanDetail.getScanResult(); int highestscoreOfScanResult = Integer.MIN_VALUE; int candIDateIDOfScanResult = WifiConfiguration.INVALID_NETWORK_ID; //过滤passpoint和ephemeral,如API所述这类网络交由PasspointNetworkEvaluator //和scoredNetworkEvaluator进行评估 if (network.isPasspoint() || network.isEphemeral()) { continue; }
接着过滤没有enabled的,scan bssID和config对不上的和eap-sim之类的网络但是没插卡的。
if (!status.isNetworkEnabled()) { continue; } else if (network.BSSID != null && !network.BSSID.equals("any") && !network.BSSID.equals(scanResult.BSSID)) { localLog("Network " + WifiNetworkSelector.toNetworkString(network)+ " has specifIEd BSSID " + network.BSSID + ". Skip " + scanResult.BSSID); continue; } else if (TelephonyUtil.isSimConfig(network) && !mWifiConfigManager.isSimPresent()) { localLog("isSimPresent"); continue; }
网络评分的关键:计算BSSID的分数,评分几大要素如下:
RSSI5GlastUserSelectednetworkIDcurrentNetworkisFirmwareRoamingSupportedisConfigForOpenNetwork private int calculateBssIDscore(ScanResult scanResult, WifiConfiguration network, WifiConfiguration currentNetwork, String currentBssID, StringBuffer sbuf) { int score = 0; boolean is5GHz = scanResult.is5GHz(); sbuf.append("[ ").append(scanResult.SSID).append(" ").append(scanResult.BSSID) .append(" RSSI:").append(scanResult.level).append(" ] "); int RSSiSaturationThreshold = is5GHz ? mThresholdSaturatedRSSi5 : mThresholdSaturatedRSSi24; int RSSi = scanResult.level < RSSiSaturationThreshold ? scanResult.level : RSSiSaturationThreshold; score += (RSSi + mRSSiscoreOffset) * mRSSiscoreSlope; sbuf.append(" RSSI score: ").append(score).append(","); //如果是5G频段,会有奖励。 if (is5GHz) { score += mBand5GHzAward; sbuf.append(" 5GHz bonus: ").append(mBand5GHzAward).append(","); } //之前连接过也有奖励 int lastUserSelectednetworkID = mWifiConfigManager.getLastSelectednetwork(); if (lastUserSelectednetworkID != WifiConfiguration.INVALID_NETWORK_ID && lastUserSelectednetworkID == network.networkID) { long timeDifference = mClock.getElapsedSinceBootMillis() - mWifiConfigManager.getLastSelectedTimeStamp(); if (timeDifference > 0) { int bonus = mLastSelectionAward - (int) (timeDifference / 1000 / 60); score += bonus > 0 ? bonus : 0; sbuf.append(" User selection ").append(timeDifference / 1000 / 60) .append(" minutes ago, bonus: ").append(bonus).append(","); } } //如果是当前正在连接的网络,也会加分 if (currentNetwork != null && (network.networkID == currentNetwork.networkID /* || network.islinked(currentNetwork) */)) { score += mSameNetworkAward; sbuf.append(" Same network bonus: ").append(mSameNetworkAward).append(","); //支持漫游也会有奖励 if (mConnectivityHelper.isFirmwareRoamingSupported() && currentBssID != null && !currentBssID.equals(scanResult.BSSID)) { score += mSameBssIDAward; sbuf.append(" Equivalent BSSID bonus: ").append(mSameBssIDAward).append(","); } } //BSSID相同也会有奖励 if (currentBssID != null && currentBssID.equals(scanResult.BSSID)) { score += mSameBssIDAward; sbuf.append(" Same BSSID bonus: ").append(mSameBssIDAward).append(","); } //不是开放的网络,也会有奖励 if (!WifiConfigurationUtil.isConfigForOpenNetwork(network)) { score += mSecurityAward; sbuf.append(" Secure network bonus: ").append(mSecurityAward).append(","); sbuf.append(" ## Total score: ").append(score).append("\n"); return score; }
总结 以上是内存溢出为你收集整理的Android 8.0/9.0 wifi 自动连接评分机制全部内容,希望文章能够帮你解决Android 8.0/9.0 wifi 自动连接评分机制所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)