Target platform: android Q10 platform

android 会将已连接的wifi AP保存到这个文件: data/misc/wifi/WifiConfigStore.xml

然后当wifi 再次打开的时候 scan results后 会将scan results和保存的已连接的wifi AP 中对比, 如果有已保存的wifi网络,则自动重连。

以下是一个已保存的网络节点

ID: 0 SSID: "Pixel_8287" PROVIDER-NAME: null BSSID: null FQDN: null PRIO: 0 HIDDEN: false PMF: false
 NetworkSelectionStatus NETWORK_SELECTION_ENABLED
 hasEverConnected: true
 numAssociation 3
 update time=04-13 15:58:20.958
 creation time=04-13 15:56:48.640
 validatedInternetAccess trusted
 macRandomizationSetting: 0
 mRandomizedMacAddress: 4e:c2:34:a4:04:79
 KeyMgmt: WPA_PSK Protocols: WPA RSN
 AuthAlgorithms: OPEN
 PairwiseCiphers: TKIP CCMP
 GroupCiphers: WEP40 WEP104 TKIP CCMP
 GroupMgmtCiphers:
 SuiteBCiphers:
 PSK/SAE: *
Enterprise config:
IP config:
IP assignment: DHCP
Proxy settings: NONE
 cuid=1000 cname=android.uid.system:1000 luid=1000 lname=android.uid.system:1000 lcuid=1000 userApproved=USER_UNSPECIFIED noInternetAccessExpected=true
lastConnected: 04-13 18:04:49.865
recentFailure: Association Rejection code: 0

 

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java

handleScanResults

    WifiConfiguration candidate = mNetworkSelector.selectNetwork(scanDetails, buildBssidBlacklist(), mWifiInfo, mStateMachine.isConnected(), mStateMachine.isDisconnected(), mUntrustedConnectionAllowed);

 

685    /**686     * Select the best network from the ones in range.687     *688     * @param scanDetails    List of ScanDetail for all the APs in range689     * @param bssidBlacklist Blacklisted BSSIDs690     * @param wifiInfo       Currently connected network691     * @param connected      True if the device is connected692     * @param disconnected   True if the device is disconnected693     * @param untrustedNetworkAllowed True if untrusted networks are allowed for connection694     * @return Configuration of the selected network, or Null if nothing695     */696    @Nullable697    public WifiConfiguration selectNetwork(List scanDetails,698            HashSet bssidBlacklist, WifiInfo wifiInfo,699            boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) {700        mFilteredNetworks.clear();701        mConnectableNetworks.clear();702        if (scanDetails.size() == 0) {703            localLog("Empty connectivity scan result");704            return null;705        }706707        WifiConfiguration currentNetwork =708                mWifiConfigManager.getConfiguredNetwork(wifiInfo.getNetworkId());709710        // Always get the current BSSID from WifiInfo in case that firmware initiated711        // roaming happened.712        String currentBssid = wifiInfo.getBSSID();713714        // Shall we start network selection at all?715        if (!isNetworkSelectionNeeded(scanDetails, wifiInfo, connected, disconnected)) {716            return null;717        }718719        // Update all configured networks before initiating network selection.720        updateConfiguredNetworks();721722        // Update the registered network evaluators.723        for (NetworkEvaluator registeredEvaluator : mEvaluators) {724            registeredEvaluator.update(scanDetails);725        }726727        // Filter out unwanted networks.728        mFilteredNetworks = filterScanResults(scanDetails, bssidBlacklist,729                connected && wifiInfo.score >= WIFI_POOR_SCORE, currentBssid);730        if (mFilteredNetworks.size() == 0) {731            return null;732        }733734        // Determine the weight for the last user selection735        final int lastUserSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork();736        final double lastSelectionWeight = calculateLastSelectionWeight();737        final ArraySet mNetworkIds = new ArraySet<>();738739        // Go through the registered network evaluators in order740        WifiConfiguration selectedNetwork = null;741        WifiCandidates wifiCandidates = new WifiCandidates(mWifiScoreCard);742        if (currentNetwork != null) {743            wifiCandidates.setCurrent(currentNetwork.networkId, currentBssid);744        }745        for (NetworkEvaluator registeredEvaluator : mEvaluators) {746            localLog("About to run " + registeredEvaluator.getName() + " :");747            WifiConfiguration choice = registeredEvaluator.evaluateNetworks(748                    new ArrayList<>(mFilteredNetworks), currentNetwork, currentBssid, connected,749                    untrustedNetworkAllowed,750                    (scanDetail, config, score) -> {751                        if (config != null) {752                            mConnectableNetworks.add(Pair.create(scanDetail, config));753                            mNetworkIds.add(config.networkId);754                            if (config.networkId == lastUserSelectedNetworkId) {755                                wifiCandidates.add(scanDetail, config,756                                        registeredEvaluator.getId(), score, lastSelectionWeight);757                            } else {758                                wifiCandidates.add(scanDetail, config,759                                        registeredEvaluator.getId(), score);760                            }761                            mWifiMetrics.setNominatorForNetwork(config.networkId,762                                    evaluatorIdToNominatorId(registeredEvaluator.getId()));763                        }764                    });765            if (choice != null && !mNetworkIds.contains(choice.networkId)) {766                Log.wtf(TAG, registeredEvaluator.getName()767                        + " failed to report choice with noConnectibleListener");768            }769            if (selectedNetwork == null && choice != null) {770                selectedNetwork = choice; // First one wins771                localLog(registeredEvaluator.getName() + " selects "772                        + WifiNetworkSelector.toNetworkString(selectedNetwork));773            }774        }775776        if (mConnectableNetworks.size() != wifiCandidates.size()) {777            localLog("Connectable: " + mConnectableNetworks.size()778                    + " Candidates: " + wifiCandidates.size());779        }780781        // Update the NetworkSelectionStatus in the configs for the current candidates782        // This is needed for the legacy user connect choice, at least783        Collection> groupedCandidates =784                wifiCandidates.getGroupedCandidates();785        for (Collection group: groupedCandidates) {786            WifiCandidates.Candidate best = null;787            for (WifiCandidates.Candidate candidate: group) {788                // Of all the candidates with the same networkId, choose the789                // one with the smallest evaluatorId, and break ties by790                // picking the one with the highest score.791                if (best == null792                        || candidate.getEvaluatorId() < best.getEvaluatorId()793                        || (candidate.getEvaluatorId() == best.getEvaluatorId()794                            && candidate.getEvaluatorScore() > best.getEvaluatorScore())) {795                    best = candidate;796                }797            }798            if (best != null) {799                ScanDetail scanDetail = best.getScanDetail();800                if (scanDetail != null) {801                    mWifiConfigManager.setNetworkCandidateScanResult(best.getNetworkConfigId(),802                            scanDetail.getScanResult(), best.getEvaluatorScore());803                }804            }805        }806807        ArrayMap experimentNetworkSelections = new ArrayMap<>(); // for metrics808809        final int legacySelectedNetworkId = selectedNetwork == null810                ? WifiConfiguration.INVALID_NETWORK_ID811                : selectedNetwork.networkId;812813        int selectedNetworkId = legacySelectedNetworkId;814815        // Run all the CandidateScorers816        boolean legacyOverrideWanted = true;817        final WifiCandidates.CandidateScorer activeScorer = getActiveCandidateScorer();818        for (WifiCandidates.CandidateScorer candidateScorer : mCandidateScorers.values()) {819            WifiCandidates.ScoredCandidate choice;820            try {821                choice = wifiCandidates.choose(candidateScorer);822            } catch (RuntimeException e) {823                Log.wtf(TAG, "Exception running a CandidateScorer", e);824                continue;825            }826            int networkId = choice.candidateKey == null827                    ? WifiConfiguration.INVALID_NETWORK_ID828                    : choice.candidateKey.networkId;829            String chooses = " would choose ";830            if (candidateScorer == activeScorer) {831                chooses = " chooses ";832                legacyOverrideWanted = candidateScorer.userConnectChoiceOverrideWanted();833                selectedNetworkId = networkId;834            }835            String id = candidateScorer.getIdentifier();836            int expid = experimentIdFromIdentifier(id);837            localLog(id + chooses + networkId838                    + " score " + choice.value + "+/-" + choice.err839                    + " expid " + expid);840            experimentNetworkSelections.put(expid, networkId);841        }842843        // Update metrics about differences in the selections made by various methods844        final int activeExperimentId = activeScorer == null ? LEGACY_CANDIDATE_SCORER_EXP_ID845                : experimentIdFromIdentifier(activeScorer.getIdentifier());846        experimentNetworkSelections.put(LEGACY_CANDIDATE_SCORER_EXP_ID, legacySelectedNetworkId);847        for (Map.Entry entry :848                experimentNetworkSelections.entrySet()) {849            int experimentId = entry.getKey();850            if (experimentId == activeExperimentId) continue;851            int thisSelectedNetworkId = entry.getValue();852            mWifiMetrics.logNetworkSelectionDecision(experimentId, activeExperimentId,853                    selectedNetworkId == thisSelectedNetworkId,854                    groupedCandidates.size());855        }856857        // Get a fresh copy of WifiConfiguration reflecting any scan result updates858        selectedNetwork = mWifiConfigManager.getConfiguredNetwork(selectedNetworkId);859        if (selectedNetwork != null && legacyOverrideWanted) {860            selectedNetwork = overrideCandidateWithUserConnectChoice(selectedNetwork);861            mLastNetworkSelectionTimeStamp = mClock.getElapsedSinceBootMillis();862        }863        return selectedNetwork;864    }

 

303    private boolean isNetworkSelectionNeeded(List scanDetails, WifiInfo wifiInfo,304                        boolean connected, boolean disconnected) {305        if (scanDetails.size() == 0) {306            localLog("Empty connectivity scan results. Skip network selection.");307            return false;308        }309310        if (connected) {311            // Is roaming allowed?312            if (!mEnableAutoJoinWhenAssociated) {313                localLog("Switching networks in connected state is not allowed."314                        + " Skip network selection.");315                return false;316            }317318            // Has it been at least the minimum interval since last network selection?319            if (mLastNetworkSelectionTimeStamp != INVALID_TIME_STAMP) {320                long gap = mClock.getElapsedSinceBootMillis()321                            - mLastNetworkSelectionTimeStamp;322                if (gap < MINIMUM_NETWORK_SELECTION_INTERVAL_MS) {323                    localLog("Too short since last network selection: " + gap + " ms."324                            + " Skip network selection.");325                    return false;326                }327            }328329            if (isCurrentNetworkSufficient(wifiInfo, scanDetails)) {330                localLog("Current connected network already sufficient. Skip network selection.");331                return false;332            } else {333                localLog("Current connected network is not sufficient.");334                return true;335            }336        } else if (disconnected) {337            return true;338        } else {339            // No network selection if ClientModeImpl is in a state other than340            // CONNECTED or DISCONNECTED.341            localLog("ClientModeImpl is in neither CONNECTED nor DISCONNECTED state."342                    + " Skip network selection.");343            return false;344        }345    }

 

221    private boolean isCurrentNetworkSufficient(WifiInfo wifiInfo, List scanDetails) {222        // Currently connected?223        if (wifiInfo.getSupplicantState() != SupplicantState.COMPLETED) {224            localLog("No current connected network.");225            return false;226        } else {227            localLog("Current connected network: " + wifiInfo.getSSID()228                    + " , ID: " + wifiInfo.getNetworkId());229        }230231        int currentRssi = wifiInfo.getRssi();232        boolean hasQualifiedRssi = currentRssi233                > mScoringParams.getSufficientRssi(wifiInfo.getFrequency());234        boolean hasActiveStream = (wifiInfo.txSuccessRate > mStayOnNetworkMinimumTxRate)235                || (wifiInfo.rxSuccessRate > mStayOnNetworkMinimumRxRate);236        if (hasQualifiedRssi && hasActiveStream) {237            localLog("Stay on current network because of good RSSI and ongoing traffic");238            return true;239        }240        WifiConfiguration network =241                mWifiConfigManager.getConfiguredNetwork(wifiInfo.getNetworkId());242243        if (network == null) {244            localLog("Current network was removed.");245            return false;246        }247248        if (mWifiConfigManager.getLastSelectedNetwork() == network.networkId249                && (mClock.getElapsedSinceBootMillis()250                    - mWifiConfigManager.getLastSelectedTimeStamp())251                <= LAST_USER_SELECTION_SUFFICIENT_MS) {252            localLog("Current network is recently user-selected.");253            return true;254        }255256        // OSU (Online Sign Up) network for Passpoint Release 2 is sufficient network.257        if (network.osu) {258            return true;259        }260261        // Ephemeral network is not qualified.262        if (wifiInfo.isEphemeral()) {263            localLog("Current network is an ephemeral one.");264            return false;265        }266267        if (wifiInfo.is24GHz()) {268            // 2.4GHz networks is not qualified whenever 5GHz is available269            if (is5GHzNetworkAvailable(scanDetails)) {270                localLog("Current network is 2.4GHz. 5GHz networks available.");271                return false;272            }273        }274        if (!hasQualifiedRssi) {275            localLog("Current network RSSI[" + currentRssi + "]-acceptable but not qualified.");276            return false;277        }278279        // Open network is not qualified.280        if (WifiConfigurationUtil.isConfigForOpenNetwork(network)) {281            localLog("Current network is a open one.");282            return false;283        }284285        // Network with no internet access reports is not qualified.286        if (network.numNoInternetAccessReports > 0 && !network.noInternetAccessExpected) {287            localLog("Current network has [" + network.numNoInternetAccessReports288                    + "] no-internet access reports.");289            return false;290        }291        return true;292    }

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Android(安卓)- 判断当前网络环境、隐藏软键盘、动态监测及获取
  3. android文件存储的五种方式简介
  4. 请求网络数据后更新视图
  5. Android(安卓)Studio Build Output 汉字乱码
  6. Android开发之MAC下无法连接Android设备
  7. jni中使用libcurl做网络开发
  8. android httpclient https 单向连接tomcat
  9. Android学习笔记之文件的保存与读取

随机推荐

  1. Android Service AIDL
  2. Android软键盘适配问题
  3. Android异步消息机制之Handler
  4. Android开发:Activity初始化时屏蔽EditTex
  5. TabHost与RadioGroup结合完成的菜单【带
  6. Android中的FILL_PARENT与WRAP_CONTENT的
  7. Android bluetooth介绍(四): a2dp connect流
  8. Android之应用程序基础
  9. android 设置中划线 下划线等
  10. android 零星调试笔记