/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import android.content.Context;
import android.net.NetworkKey;
import android.net.NetworkScoreManager;
import android.net.WifiKey;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConnectionStatistics;
import android.os.Process;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import com.android.server.wifi.anqp.ANQPElement;
import com.android.server.wifi.anqp.Constants;
import com.android.server.wifi.hotspot2.ANQPData;
import com.android.server.wifi.hotspot2.AnqpCache;
import com.android.server.wifi.hotspot2.Chronograph;
import com.android.server.wifi.hotspot2.NetworkDetail;
import com.android.server.wifi.hotspot2.PasspointMatch;
import com.android.server.wifi.hotspot2.PasspointMatchInfo;
import com.android.server.wifi.hotspot2.SupplicantBridge;
import com.android.server.wifi.hotspot2.pps.HomeSP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * AutoJoin controller is responsible for WiFi Connect decision
 *
 * It runs in the thread context of WifiStateMachine
 *
 */
public class WifiAutoJoinController {

    private Context mContext;
    private WifiStateMachine mWifiStateMachine;
    private WifiConfigStore mWifiConfigStore;
    private WifiNative mWifiNative;

    private NetworkScoreManager scoreManager;
    private WifiNetworkScoreCache mNetworkScoreCache;

    private static final String TAG = "WifiAutoJoinController ";
    private static boolean DBG = false;
    private static boolean VDBG = false;
    private static final boolean mStaStaSupported = false;

    public static int mScanResultMaximumAge = 40000; /* milliseconds unit */
    public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */

    private String mCurrentConfigurationKey = null; //used by autojoin

    private final HashMap<String, ScanDetail> scanResultCache = new HashMap<>();

    private WifiConnectionStatistics mWifiConnectionStatistics;

    /**
     * Whether to allow connections to untrusted networks.
     */
    private boolean mAllowUntrustedConnections = false;

    /* For debug purpose only: if the scored override a score */
    boolean didOverride = false;

    // Lose the non-auth failure blacklisting after 8 hours
    private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8;
    // Lose some temporary blacklisting after 30 minutes
    private final static long loseBlackListSoftMilli = 1000 * 60 * 30;

    /**
     * @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS
     */
    private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute

    public static final int AUTO_JOIN_IDLE = 0;
    public static final int AUTO_JOIN_ROAMING = 1;
    public static final int AUTO_JOIN_EXTENDED_ROAMING = 2;
    public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3;

    public static final int HIGH_THRESHOLD_MODIFIER = 5;

    public static final int MAX_RSSI_DELTA = 50;

    // Below are AutoJoin wide parameters indicating if we should be aggressive before joining
    // weak network. Note that we cannot join weak network that are going to be marked as unanted by
    // ConnectivityService because this will trigger link flapping.
    /**
     * There was a non-blacklisted configuration that we bailed from because of a weak signal
     */
    boolean didBailDueToWeakRssi = false;
    /**
     * number of time we consecutively bailed out of an eligible network because its signal
     * was too weak
     */
    int weakRssiBailCount = 0;

    WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s,
                           WifiConnectionStatistics st, WifiNative n) {
        mContext = c;
        mWifiStateMachine = w;
        mWifiConfigStore = s;
        mWifiNative = n;
        mNetworkScoreCache = null;
        mWifiConnectionStatistics = st;
        scoreManager =
                (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE);
        if (scoreManager == null)
            logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE);

        if (scoreManager != null) {
            mNetworkScoreCache = new WifiNetworkScoreCache(mContext);
            scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
        } else {
            logDbg("No network score service: Couldnt register as a WiFi score Manager, type="
                    + Integer.toString(NetworkKey.TYPE_WIFI)
                    + " service " + Context.NETWORK_SCORE_SERVICE);
            mNetworkScoreCache = null;
        }
    }

    void enableVerboseLogging(int verbose) {
        if (verbose > 0) {
            DBG = true;
            VDBG = true;
        } else {
            DBG = false;
            VDBG = false;
        }
    }

    /**
     * Flush out scan results older than mScanResultMaximumAge
     */
    private void ageScanResultsOut(int delay) {
        if (delay <= 0) {
            delay = mScanResultMaximumAge; // Something sane
        }
        long milli = System.currentTimeMillis();
        if (VDBG) {
            logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size "
                    + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli));
        }

        Iterator<HashMap.Entry<String, ScanDetail>> iter = scanResultCache.entrySet().iterator();
        while (iter.hasNext()) {
            HashMap.Entry<String, ScanDetail> entry = iter.next();
            ScanDetail scanDetail = entry.getValue();
            if ((scanDetail.getSeen() + delay) < milli) {
                iter.remove();
            }
        }
    }


    void averageRssiAndRemoveFromCache(ScanResult result) {
        // Fetch the previous instance for this result
        ScanDetail sd = scanResultCache.get(result.BSSID);
        if (sd != null) {
            ScanResult sr = sd.getScanResult();
            if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0
                    && result.level == 0
                    && sr.level < -20) {
                // A 'zero' RSSI reading is most likely a chip problem which returns
                // an unknown RSSI, hence ignore it
                result.level = sr.level;
            }

            // If there was a previous cache result for this BSSID, average the RSSI values
            result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge);

            // Remove the previous Scan Result - this is not necessary
            scanResultCache.remove(result.BSSID);
        } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) {
            // A 'zero' RSSI reading is most likely a chip problem which returns
            // an unknown RSSI, hence initialize it to a sane value
            result.level = mWifiConfigStore.scanResultRssiLevelPatchUp;
        }
    }

    void addToUnscoredNetworks(ScanResult result, List<NetworkKey> unknownScanResults) {
        WifiKey wkey;
        // Quoted SSIDs are the only one valid at this stage
        try {
            wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID);
        } catch (IllegalArgumentException e) {
            logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID +
                    "] ->skipping this network");
            wkey = null;
        }
        if (wkey != null) {
            NetworkKey nkey = new NetworkKey(wkey);
            //if we don't know this scan result then request a score from the scorer
            unknownScanResults.add(nkey);
        }
        if (VDBG) {
            String cap = "";
            if (result.capabilities != null)
                cap = result.capabilities;
            logDbg(result.SSID + " " + result.BSSID + " rssi="
                    + result.level + " cap " + cap + " is not scored");
        }
    }

    int addToScanCache(List<ScanDetail> scanList) {
        int numScanResultsKnown = 0; // Record number of scan results we knew about
        WifiConfiguration associatedConfig = null;
        boolean didAssociate = false;
        long now = System.currentTimeMillis();

        ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>();

        for (ScanDetail scanDetail : scanList) {
            ScanResult result = scanDetail.getScanResult();
            if (result.SSID == null) continue;

            // Make sure we record the last time we saw this result
            scanDetail.setSeen();

            averageRssiAndRemoveFromCache(result);

            if (!mNetworkScoreCache.isScoredNetwork(result)) {
                addToUnscoredNetworks(result, unknownScanResults);
            } else {
                if (VDBG) {
                    String cap = "";
                    if (result.capabilities != null)
                        cap = result.capabilities;
                    int score = mNetworkScoreCache.getNetworkScore(result);
                    logDbg(result.SSID + " " + result.BSSID + " rssi="
                            + result.level + " cap " + cap + " is scored : " + score);
                }
            }

            // scanResultCache.put(result.BSSID, new ScanResult(result));
            scanResultCache.put(result.BSSID, scanDetail);
            // Add this BSSID to the scanResultCache of a Saved WifiConfiguration
            didAssociate = mWifiConfigStore.updateSavedNetworkHistory(scanDetail);

            // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration
            if (!didAssociate) {
                // We couldn't associate the scan result to a Saved WifiConfiguration
                // Hence it is untrusted
                result.untrusted = true;
            } else {
                // If the scan result has been blacklisted fir 18 hours -> unblacklist
                if ((now - result.blackListTimestamp) > loseBlackListHardMilli) {
                    result.setAutoJoinStatus(ScanResult.ENABLED);
                }
            }
            if (didAssociate) {
                numScanResultsKnown++;
                result.isAutoJoinCandidate++;
            } else {
                result.isAutoJoinCandidate = 0;
            }
        }

        if (unknownScanResults.size() != 0) {
            NetworkKey[] newKeys =
                    unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]);
            // Kick the score manager, we will get updated scores asynchronously
            scoreManager.requestScores(newKeys);
        }
        return numScanResultsKnown;
    }

    void logDbg(String message) {
        logDbg(message, false);
    }

    void logDbg(String message, boolean stackTrace) {
        if (stackTrace) {
            Log.d(TAG, message + " stack:"
                    + Thread.currentThread().getStackTrace()[2].getMethodName() + " - "
                    + Thread.currentThread().getStackTrace()[3].getMethodName() + " - "
                    + Thread.currentThread().getStackTrace()[4].getMethodName() + " - "
                    + Thread.currentThread().getStackTrace()[5].getMethodName());
        } else {
            Log.d(TAG, message);
        }
    }

    // Called directly from WifiStateMachine
    int newSupplicantResults(boolean doAutoJoin) {
        int numScanResultsKnown;
        List<ScanDetail> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync();
        numScanResultsKnown = addToScanCache(scanList);
        ageScanResultsOut(mScanResultMaximumAge);
        if (DBG) {
            logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size())
                    + " known=" + numScanResultsKnown + " "
                    + doAutoJoin);
        }
        if (doAutoJoin) {
            attemptAutoJoin();
        }
        mWifiConfigStore.writeKnownNetworkHistory(false);
        return numScanResultsKnown;
    }


    /**
     * Not used at the moment
     * should be a call back from WifiScanner HAL ??
     * this function is not hooked and working yet, it will receive scan results from WifiScanners
     * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan
     * results as normal.
     */
    void newHalScanResults() {
        List<ScanDetail> scanList = null;//mWifiScanner.syncGetScanResultsList();
        String akm = WifiParser.parse_akm(null, null);
        logDbg(akm);
        addToScanCache(scanList);
        ageScanResultsOut(0);
        attemptAutoJoin();
        mWifiConfigStore.writeKnownNetworkHistory(false);
    }

    /**
     * network link quality changed, called directly from WifiTrafficPoller,
     * or by listening to Link Quality intent
     */
    void linkQualitySignificantChange() {
        attemptAutoJoin();
    }

    /**
     * compare a WifiConfiguration against the current network, return a delta score
     * If not associated, and the candidate will always be better
     * For instance if the candidate is a home network versus an unknown public wifi,
     * the delta will be infinite, else compare Kepler scores etc…
     * Negatve return values from this functions are meaningless per se, just trying to
     * keep them distinct for debug purpose (i.e. -1, -2 etc...)
     */
    private int compareNetwork(WifiConfiguration candidate,
                               String lastSelectedConfiguration) {
        if (candidate == null)
            return -3;

        WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration();
        if (currentNetwork == null) {
            // Return any absurdly high score, if we are not connected there is no current
            // network to...
            return 1000;
        }

        if (candidate.configKey(true).equals(currentNetwork.configKey(true))) {
            return -2;
        }

        if (DBG) {
            logDbg("compareNetwork will compare " + candidate.configKey()
                    + " with current " + currentNetwork.configKey());
        }
        int order = compareWifiConfigurations(currentNetwork, candidate);

        // The lastSelectedConfiguration is the configuration the user has manually selected
        // thru WifiPicker, or that a 3rd party app asked us to connect to via the
        // enableNetwork with disableOthers=true WifiManager API
        // As this is a direct user choice, we strongly prefer this configuration,
        // hence give +/-100
        if ((lastSelectedConfiguration != null)
                && currentNetwork.configKey().equals(lastSelectedConfiguration)) {
            // currentNetwork is the last selected configuration,
            // so keep it above connect choices (+/-60) and
            // above RSSI/scorer based selection of linked configuration (+/- 50)
            // by reducing order by -100
            order = order - 100;
            if (VDBG) {
                logDbg("     ...and prefers -100 " + currentNetwork.configKey()
                        + " over " + candidate.configKey()
                        + " because it is the last selected -> "
                        + Integer.toString(order));
            }
        } else if ((lastSelectedConfiguration != null)
                && candidate.configKey().equals(lastSelectedConfiguration)) {
            // candidate is the last selected configuration,
            // so keep it above connect choices (+/-60) and
            // above RSSI/scorer based selection of linked configuration (+/- 50)
            // by increasing order by +100
            order = order + 100;
            if (VDBG) {
                logDbg("     ...and prefers +100 " + candidate.configKey()
                        + " over " + currentNetwork.configKey()
                        + " because it is the last selected -> "
                        + Integer.toString(order));
            }
        }

        return order;
    }

    /**
     * update the network history fields fo that configuration
     * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it
     * and took over management
     * - if it is a "connect", remember which network were there at the point of the connect, so
     * as those networks get a relative lower score than the selected configuration
     *
     * @param netId
     * @param userTriggered : if the update come from WiFiManager
     * @param connect       : if the update includes a connect
     */
    public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) {
        WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId);
        if (selected == null) {
            logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!");
            return;
        }

        if (selected.SSID == null) {
            logDbg("updateConfigurationHistory nid=" + netId +
                    " no SSID in selected configuration!");
            return;
        }

        if (userTriggered) {
            // Reenable autojoin for this network,
            // since the user want to connect to this configuration
            selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);
            selected.selfAdded = false;
            selected.dirty = true;
        }

        if (DBG && userTriggered) {
            if (selected.connectChoices != null) {
                logDbg("updateConfigurationHistory will update "
                        + Integer.toString(netId) + " now: "
                        + Integer.toString(selected.connectChoices.size())
                        + " uid=" + Integer.toString(selected.creatorUid), true);
            } else {
                logDbg("updateConfigurationHistory will update "
                        + Integer.toString(netId)
                        + " uid=" + Integer.toString(selected.creatorUid), true);
            }
        }

        if (connect && userTriggered) {
            boolean found = false;
            int choice = 0;
            int size = 0;

            // Reset the triggered disabled count, because user wanted to connect to this
            // configuration, and we were not.
            selected.numUserTriggeredWifiDisableLowRSSI = 0;
            selected.numUserTriggeredWifiDisableBadRSSI = 0;
            selected.numUserTriggeredWifiDisableNotHighRSSI = 0;
            selected.numUserTriggeredJoinAttempts++;

            List<WifiConfiguration> networks =
                    mWifiConfigStore.getRecentConfiguredNetworks(12000, false);
            if (networks != null) size = networks.size();
            logDbg("updateConfigurationHistory found " + size + " networks");
            if (networks != null) {
                for (WifiConfiguration config : networks) {
                    if (DBG) {
                        logDbg("updateConfigurationHistory got " + config.SSID + " nid="
                                + Integer.toString(config.networkId));
                    }

                    if (selected.configKey(true).equals(config.configKey(true))) {
                        found = true;
                        continue;
                    }

                    // If the selection was made while config was visible with reasonably good RSSI
                    // then register the user preference, else ignore
                    if (config.visibility == null ||
                            (config.visibility.rssi24 < mWifiConfigStore.thresholdBadRssi24.get()
                            && config.visibility.rssi5 < mWifiConfigStore.thresholdBadRssi5.get())
                    ) {
                        continue;
                    }

                    choice = MAX_RSSI_DELTA + 10; // Make sure the choice overrides the RSSI diff

                    // The selected configuration was preferred over a recently seen config
                    // hence remember the user's choice:
                    // add the recently seen config to the selected's connectChoices array

                    if (selected.connectChoices == null) {
                        selected.connectChoices = new HashMap<String, Integer>();
                    }

                    logDbg("updateConfigurationHistory add a choice " + selected.configKey(true)
                            + " over " + config.configKey(true)
                            + " choice " + Integer.toString(choice));

                    // Add the visible config to the selected's connect choice list
                    selected.connectChoices.put(config.configKey(true), choice);

                    if (config.connectChoices != null) {
                        if (VDBG) {
                            logDbg("updateConfigurationHistory will remove "
                                    + selected.configKey(true) + " from " + config.configKey(true));
                        }
                        // Remove the selected from the recently seen config's connectChoice list
                        config.connectChoices.remove(selected.configKey(true));

                        if (selected.linkedConfigurations != null) {
                            // Remove the selected's linked configuration from the
                            // recently seen config's connectChoice list
                            for (String key : selected.linkedConfigurations.keySet()) {
                                config.connectChoices.remove(key);
                            }
                        }
                    }
                }
                if (found == false) {
                    // We haven't found the configuration that the user just selected in our
                    // scan cache.
                    // In that case we will need a new scan before attempting to connect to this
                    // configuration anyhow and thus we can process the scan results then.
                    logDbg("updateConfigurationHistory try to connect to an old network!! : "
                            + selected.configKey());
                }

                if (selected.connectChoices != null) {
                    if (VDBG)
                        logDbg("updateConfigurationHistory " + Integer.toString(netId)
                                + " now: " + Integer.toString(selected.connectChoices.size()));
                }
            }
        }

        // TODO: write only if something changed
        if (userTriggered || connect) {
            mWifiConfigStore.writeKnownNetworkHistory(false);
        }
    }

    int getConnectChoice(WifiConfiguration source, WifiConfiguration target) {
        Integer choice = null;
        if (source == null || target == null) {
            return 0;
        }

        if (source.connectChoices != null
                && source.connectChoices.containsKey(target.configKey(true))) {
            choice = source.connectChoices.get(target.configKey(true));
        } else if (source.linkedConfigurations != null) {
            for (String key : source.linkedConfigurations.keySet()) {
                WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key);
                if (config != null) {
                    if (config.connectChoices != null) {
                        choice = config.connectChoices.get(target.configKey(true));
                    }
                }
            }
        }

        if (choice == null) {
            // We didn't find the connect choice; fallback to some default choices
            int sourceScore = getSecurityScore(source);
            int targetScore = getSecurityScore(target);
            choice = sourceScore - targetScore;
        }

        if (choice < 0) {
            choice = 20; // Compatibility with older files
        }

        return choice;
    }

    int compareWifiConfigurationsFromVisibility(WifiConfiguration.Visibility a, int aRssiBoost,
                                                String dbgA, WifiConfiguration.Visibility b, int bRssiBoost, String dbgB) {

        int aRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref)
        int bRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref)

        int aScore = 0;
        int bScore = 0;

        boolean aPrefers5GHz = false;
        boolean bPrefers5GHz = false;

        /**
         * Calculate a boost to apply to RSSI value of configuration we want to join on 5GHz:
         * Boost RSSI value of 5GHz bands iff the base value is better than threshold,
         * penalize the RSSI value of 5GHz band iff the base value is lower than threshold
         * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas
         * we prefer 2.4GHz otherwise.
         */
        aRssiBoost5 = rssiBoostFrom5GHzRssi(a.rssi5, dbgA + "->");
        bRssiBoost5 = rssiBoostFrom5GHzRssi(b.rssi5, dbgB + "->");

        // Select which band to use for a
        if (a.rssi5 + aRssiBoost5 > a.rssi24) {
            // Prefer a's 5GHz
            aPrefers5GHz = true;
        }

        // Select which band to use for b
        if (b.rssi5 + bRssiBoost5 > b.rssi24) {
            // Prefer b's 5GHz
            bPrefers5GHz = true;
        }

        if (aPrefers5GHz) {
            if (bPrefers5GHz) {
                // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either
                // one, but directly compare the RSSI values, this improves stability,
                // since the 5GHz RSSI boost can introduce large fluctuations
                aScore = a.rssi5 + aRssiBoost;
            } else {
                // If only a is on 5GHz, then apply the 5GHz preference boost to a
                aScore = a.rssi5 + aRssiBoost + aRssiBoost5;
            }
        } else {
            aScore = a.rssi24 + aRssiBoost;
        }

        if (bPrefers5GHz) {
            if (aPrefers5GHz) {
                // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either
                // one, but directly compare the RSSI values, this improves stability,
                // since the 5GHz RSSI boost can introduce large fluctuations
                bScore = b.rssi5 + bRssiBoost;
            } else {
                // If only b is on 5GHz, then apply the 5GHz preference boost to b
                bScore = b.rssi5 + bRssiBoost + bRssiBoost5;
            }
        } else {
            bScore = b.rssi24 + bRssiBoost;
        }

        if (VDBG) {
            logDbg("        " + dbgA + " is5=" + aPrefers5GHz + " score=" + aScore
                    + " " + dbgB + " is5=" + bPrefers5GHz + " score=" + bScore);
        }

        // Debug only, record RSSI comparison parameters
        if (a != null) {
            a.score = aScore;
            a.currentNetworkBoost = aRssiBoost;
            a.bandPreferenceBoost = aRssiBoost5;
        }
        if (b != null) {
            b.score = bScore;
            b.currentNetworkBoost = bRssiBoost;
            b.bandPreferenceBoost = bRssiBoost5;
        }

        // Compare a and b
        // If a score is higher then a > b and the order is descending (negative)
        // If b score is higher then a < b and the order is ascending (positive)
        return bScore - aScore;
    }

    // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50]
    // The result represents "approximately" an RSSI difference measured in dBM
    // Adjusted with various parameters:
    // +) current network gets a +15 boost
    // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the
    // fact that at short range we prefer 5GHz band as it is cleaner of interference and
    // provides for wider channels
    int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b,
                                      String currentConfiguration) {
        int order = 0;

        // Boost used so as to favor current config
        int aRssiBoost = 0;
        int bRssiBoost = 0;

        // Retrieve the visibility
        WifiConfiguration.Visibility astatus = a.visibility;
        WifiConfiguration.Visibility bstatus = b.visibility;
        if (astatus == null || bstatus == null) {
            // Error visibility wasn't set
            logDbg("    compareWifiConfigurations NULL band status!");
            return 0;
        }

        // Apply Hysteresis, boost RSSI of current configuration
        if (null != currentConfiguration) {
            if (a.configKey().equals(currentConfiguration)) {
                aRssiBoost = mWifiConfigStore.currentNetworkBoost;
            } else if (b.configKey().equals(currentConfiguration)) {
                bRssiBoost = mWifiConfigStore.currentNetworkBoost;
            }
        }

        if (VDBG) {
            logDbg("    compareWifiConfigurationsRSSI: " + a.configKey()
                            + " rssi=" + Integer.toString(astatus.rssi24)
                            + "," + Integer.toString(astatus.rssi5)
                            + " boost=" + Integer.toString(aRssiBoost)
                            + " " + b.configKey() + " rssi="
                            + Integer.toString(bstatus.rssi24) + ","
                            + Integer.toString(bstatus.rssi5)
                            + " boost=" + Integer.toString(bRssiBoost)
            );
        }

        order = compareWifiConfigurationsFromVisibility(
                a.visibility, aRssiBoost, a.configKey(),
                b.visibility, bRssiBoost, b.configKey());

        // Normalize the order to [-50, +50] = [ -MAX_RSSI_DELTA, MAX_RSSI_DELTA]
        if (order > MAX_RSSI_DELTA) order = MAX_RSSI_DELTA;
        else if (order < -MAX_RSSI_DELTA) order = -MAX_RSSI_DELTA;

        if (VDBG) {
            String prefer = " = ";
            if (order > 0) {
                prefer = " < "; // Ascending
            } else if (order < 0) {
                prefer = " > "; // Descending
            }
            logDbg("    compareWifiConfigurationsRSSI " + a.configKey()
                    + " rssi=(" + a.visibility.rssi24
                    + "," + a.visibility.rssi5
                    + ") num=(" + a.visibility.num24
                    + "," + a.visibility.num5 + ")"
                    + prefer + b.configKey()
                    + " rssi=(" + b.visibility.rssi24
                    + "," + b.visibility.rssi5
                    + ") num=(" + b.visibility.num24
                    + "," + b.visibility.num5 + ")"
                    + " -> " + order);
        }

        return order;
    }

    /**
     * b/18490330 only use scorer for untrusted networks
     * <p/>
     * int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) {
     * <p/>
     * boolean aIsActive = false;
     * boolean bIsActive = false;
     * <p/>
     * // Apply Hysteresis : boost RSSI of current configuration before
     * // looking up the score
     * if (null != mCurrentConfigurationKey) {
     * if (a.configKey().equals(mCurrentConfigurationKey)) {
     * aIsActive = true;
     * } else if (b.configKey().equals(mCurrentConfigurationKey)) {
     * bIsActive = true;
     * }
     * }
     * int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive);
     * int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive);
     * <p/>
     * // Both configurations need to have a score for the scorer to be used
     * // ...and the scores need to be different:-)
     * if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE
     * || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) {
     * if (VDBG)  {
     * logDbg("    compareWifiConfigurationsWithScorer no-scores: "
     * + a.configKey()
     * + " "
     * + b.configKey());
     * }
     * return 0;
     * }
     * <p/>
     * if (VDBG) {
     * String prefer = " = ";
     * if (scoreA < scoreB) {
     * prefer = " < ";
     * } if (scoreA > scoreB) {
     * prefer = " > ";
     * }
     * logDbg("    compareWifiConfigurationsWithScorer " + a.configKey()
     * + " rssi=(" + a.visibility.rssi24
     * + "," + a.visibility.rssi5
     * + ") num=(" + a.visibility.num24
     * + "," + a.visibility.num5 + ")"
     * + " sc=" + scoreA
     * + prefer + b.configKey()
     * + " rssi=(" + b.visibility.rssi24
     * + "," + b.visibility.rssi5
     * + ") num=(" + b.visibility.num24
     * + "," + b.visibility.num5 + ")"
     * + " sc=" + scoreB
     * + " -> " + Integer.toString(scoreB - scoreA));
     * }
     * <p/>
     * // If scoreA > scoreB, the comparison is descending hence the return value is negative
     * return scoreB - scoreA;
     * }
     */

    int getSecurityScore(WifiConfiguration config) {

        if (TextUtils.isEmpty(config.SSID) == false) {
            if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
                    || config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)
                    || config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
                /* enterprise or PSK networks get highest score */
                return 100;
            } else if (config.allowedKeyManagement.get(KeyMgmt.NONE)) {
                /* open networks have lowest score */
                return 33;
            }
        } else if (TextUtils.isEmpty(config.FQDN) == false) {
            /* passpoint networks have medium preference */
            return 66;
        }

        /* bad network */
        return 0;
    }

    int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) {
        int order = 0;
        boolean linked = false;

        if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null)
                && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)
                && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) {
            if ((a.linkedConfigurations.get(b.configKey(true)) != null)
                    && (b.linkedConfigurations.get(a.configKey(true)) != null)) {
                linked = true;
            }
        }

        if (a.ephemeral && b.ephemeral == false) {
            if (VDBG) {
                logDbg("    compareWifiConfigurations ephemeral and prefers " + b.configKey()
                        + " over " + a.configKey());
            }
            return 1; // b is of higher priority - ascending
        }
        if (b.ephemeral && a.ephemeral == false) {
            if (VDBG) {
                logDbg("    compareWifiConfigurations ephemeral and prefers " + a.configKey()
                        + " over " + b.configKey());
            }
            return -1; // a is of higher priority - descending
        }

        // Apply RSSI, in the range [-5, +5]
        // after band adjustment, +n difference roughly corresponds to +10xn dBm
        order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey);

        // If the configurations are not linked, compare by user's choice, only a
        // very high RSSI difference can then override the choice
        if (!linked) {
            int choice;

            choice = getConnectChoice(a, b);
            if (choice > 0) {
                // a is of higher priority - descending
                order = order - choice;
                if (VDBG) {
                    logDbg("    compareWifiConfigurations prefers " + a.configKey()
                            + " over " + b.configKey()
                            + " due to user choice of " + choice
                            + " order -> " + Integer.toString(order));
                }
                if (a.visibility != null) {
                    a.visibility.lastChoiceBoost = choice;
                    a.visibility.lastChoiceConfig = b.configKey();
                }
            }

            choice = getConnectChoice(b, a);
            if (choice > 0) {
                // a is of lower priority - ascending
                order = order + choice;
                if (VDBG) {
                    logDbg("    compareWifiConfigurations prefers " + b.configKey() + " over "
                            + a.configKey() + " due to user choice of " + choice
                            + " order ->" + Integer.toString(order));
                }
                if (b.visibility != null) {
                    b.visibility.lastChoiceBoost = choice;
                    b.visibility.lastChoiceConfig = a.configKey();
                }
            }
        }

        if (order == 0) {
            // We don't know anything - pick the last seen i.e. K behavior
            // we should do this only for recently picked configurations
            if (a.priority > b.priority) {
                // a is of higher priority - descending
                if (VDBG) {
                    logDbg("    compareWifiConfigurations prefers -1 " + a.configKey() + " over "
                            + b.configKey() + " due to priority");
                }

                order = -1;
            } else if (a.priority < b.priority) {
                // a is of lower priority - ascending
                if (VDBG) {
                    logDbg("    compareWifiConfigurations prefers +1 " + b.configKey() + " over "
                            + a.configKey() + " due to priority");
                }
                order = 1;
            }
        }

        String sorder = " == ";
        if (order > 0) {
            sorder = " < ";
        } else if (order < 0) {
            sorder = " > ";
        }

        if (VDBG) {
            logDbg("compareWifiConfigurations: " + a.configKey() + sorder
                    + b.configKey() + " order " + Integer.toString(order));
        }

        return order;
    }

    boolean isBadCandidate(int rssi5, int rssi24) {
        return (rssi5 < -80 && rssi24 < -90);
    }

    /*
    int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) {
        int scorerOrder = compareWifiConfigurationsWithScorer(a, b);
        int order = compareWifiConfigurations(a, b);

        if (scorerOrder * order < 0) {
            if (VDBG) {
                logDbg("    -> compareWifiConfigurationsTop: " +
                        "scorer override " + scorerOrder + " " + order);
            }
            // For debugging purpose, remember that an override happened
            // during that autojoin Attempt
            didOverride = true;
            a.numScorerOverride++;
            b.numScorerOverride++;
        }

        if (scorerOrder != 0) {
            // If the scorer came up with a result then use the scorer's result, else use
            // the order provided by the base comparison function
            order = scorerOrder;
        }
        return order;
    }
    */

    public int rssiBoostFrom5GHzRssi(int rssi, String dbg) {
        if (!mWifiConfigStore.enable5GHzPreference) {
            return 0;
        }
        if (rssi
                > mWifiConfigStore.bandPreferenceBoostThreshold5.get()) {
            // Boost by 2 dB for each point
            //    Start boosting at -65
            //    Boost by 20 if above -55
            //    Boost by 40 if abore -45
            int boost = mWifiConfigStore.bandPreferenceBoostFactor5
                    * (rssi - mWifiConfigStore.bandPreferenceBoostThreshold5.get());
            if (boost > 50) {
                // 50 dB boost allows jumping from 2.4 to 5GHz
                // consistently
                boost = 50;
            }
            if (VDBG && dbg != null) {
                logDbg("        " + dbg + ":    rssi5 " + rssi + " 5GHz-boost " + boost);
            }
            return boost;
        }

        if (rssi
                < mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) {
            // penalize if < -75
            int boost = mWifiConfigStore.bandPreferencePenaltyFactor5
                    * (rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5.get());
            return boost;
        }
        return 0;
    }

    /**
     * attemptRoam() function implements the core of the same SSID switching algorithm
     * <p/>
     * Run thru all recent scan result of a WifiConfiguration and select the
     * best one.
     */
    public ScanResult attemptRoam(ScanResult a,
                                  WifiConfiguration current, int age, String currentBSSID) {
        if (current == null) {
            if (VDBG) {
                logDbg("attemptRoam not associated");
            }
            return a;
        }

        ScanDetailCache scanDetailCache =
                mWifiConfigStore.getScanDetailCache(current);

        if (scanDetailCache == null) {
            if (VDBG) {
                logDbg("attemptRoam no scan cache");
            }
            return a;
        }
        if (scanDetailCache.size() > 6) {
            if (VDBG) {
                logDbg("attemptRoam scan cache size "
                        + scanDetailCache.size() + " --> bail");
            }
            // Implement same SSID roaming only for configurations
            // that have less than 4 BSSIDs
            return a;
        }

        if (current.BSSID != null && !current.BSSID.equals("any")) {
            if (DBG) {
                logDbg("attemptRoam() BSSID is set "
                        + current.BSSID + " -> bail");
            }
            return a;
        }

        // Determine which BSSID we want to associate to, taking account
        // relative strength of 5 and 2.4 GHz BSSIDs
        long nowMs = System.currentTimeMillis();

        for (ScanDetail sd : scanDetailCache.values()) {
            ScanResult b = sd.getScanResult();
            int bRssiBoost5 = 0;
            int aRssiBoost5 = 0;
            int bRssiBoost = 0;
            int aRssiBoost = 0;
            if ((sd.getSeen() == 0) || (b.BSSID == null)
                    || ((nowMs - sd.getSeen()) > age)
                    || b.autoJoinStatus != ScanResult.ENABLED
                    || b.numIpConfigFailures > 8) {
                continue;
            }

            // Pick first one
            if (a == null) {
                a = b;
                continue;
            }

            if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) {
                // Prefer a BSSID that doesn't have less number of Ip config failures
                logDbg("attemptRoam: "
                        + b.BSSID + " rssi=" + b.level + " ipfail=" + b.numIpConfigFailures
                        + " freq=" + b.frequency
                        + " > "
                        + a.BSSID + " rssi=" + a.level + " ipfail=" + a.numIpConfigFailures
                        + " freq=" + a.frequency);
                a = b;
                continue;
            }

            // Apply hysteresis: we favor the currentBSSID by giving it a boost
            if (currentBSSID != null && currentBSSID.equals(b.BSSID)) {
                // Reduce the benefit of hysteresis if RSSI <= -75
                if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) {
                    bRssiBoost = mWifiConfigStore.associatedHysteresisLow;
                } else {
                    bRssiBoost = mWifiConfigStore.associatedHysteresisHigh;
                }
            }
            if (currentBSSID != null && currentBSSID.equals(a.BSSID)) {
                if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) {
                    // Reduce the benefit of hysteresis if RSSI <= -75
                    aRssiBoost = mWifiConfigStore.associatedHysteresisLow;
                } else {
                    aRssiBoost = mWifiConfigStore.associatedHysteresisHigh;
                }
            }

            // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve
            //   Boost the BSSID if it is on 5GHz, above a threshold
            //   But penalize it if it is on 5GHz and below threshold
            //
            //   With he current threshold values, 5GHz network with RSSI above -55
            //   Are given a boost of 30DB which is enough to overcome the current BSSID
            //   hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases
            //
            // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\
            // soem amount of hysteresis
            if (b.is5GHz()) {
                bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID);
            }
            if (a.is5GHz()) {
                aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID);
            }

            if (VDBG) {
                String comp = " < ";
                if (b.level + bRssiBoost + bRssiBoost5 > a.level + aRssiBoost + aRssiBoost5) {
                    comp = " > ";
                }
                logDbg("attemptRoam: "
                        + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost)
                        + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency
                        + comp
                        + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost)
                        + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency);
            }

            // Compare the RSSIs after applying the hysteresis boost and the 5GHz
            // boost if applicable
            if (b.level + bRssiBoost + bRssiBoost5 > a.level + aRssiBoost + aRssiBoost5) {
                // b is the better BSSID
                a = b;
            }
        }
        if (a != null) {
            if (VDBG) {
                StringBuilder sb = new StringBuilder();
                sb.append("attemptRoam: " + current.configKey() +
                        " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency);
                if (currentBSSID != null) {
                    sb.append(" Current: " + currentBSSID);
                }
                sb.append("\n");
                logDbg(sb.toString());
            }
        }
        return a;
    }

    /**
     * getNetworkScore()
     * <p/>
     * if scorer is present, get the network score of a WifiConfiguration
     * <p/>
     * Note: this should be merge with setVisibility
     *
     * @param config
     * @return score
     */
    int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) {

        if (mNetworkScoreCache == null) {
            if (VDBG) {
                logDbg("       getConfigNetworkScore for " + config.configKey()
                        + "  -> no scorer, hence no scores");
            }
            return WifiNetworkScoreCache.INVALID_NETWORK_SCORE;
        }

        if (mWifiConfigStore.getScanDetailCache(config) == null) {
            if (VDBG) {
                logDbg("       getConfigNetworkScore for " + config.configKey()
                        + " -> no scan cache");
            }
            return WifiNetworkScoreCache.INVALID_NETWORK_SCORE;
        }

        // Get current date
        long nowMs = System.currentTimeMillis();

        int startScore = -10000;

        // Run thru all cached scan results
        for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) {
            ScanResult result = sd.getScanResult();
            if ((nowMs - sd.getSeen()) < age) {
                int sc = mNetworkScoreCache.getNetworkScore(result, isActive);
                if (sc > startScore) {
                    startScore = sc;
                }
            }
        }
        if (startScore == -10000) {
            startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE;
        }
        if (VDBG) {
            if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) {
                logDbg("    getConfigNetworkScore for " + config.configKey()
                        + " -> no available score");
            } else {
                logDbg("    getConfigNetworkScore for " + config.configKey()
                        + " isActive=" + isActive
                        + " score = " + Integer.toString(startScore));
            }
        }

        return startScore;
    }

    /**
     * Set whether connections to untrusted connections are allowed.
     */
    void setAllowUntrustedConnections(boolean allow) {
        boolean changed = mAllowUntrustedConnections != allow;
        mAllowUntrustedConnections = allow;
        if (changed) {
            // Trigger a scan so as to reattempt autojoin
            mWifiStateMachine.startScanForUntrustedSettingChange();
        }
    }

    private boolean isOpenNetwork(ScanResult result) {
        return !result.capabilities.contains("WEP") &&
                !result.capabilities.contains("PSK") &&
                !result.capabilities.contains("EAP");
    }

    private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) {
        long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong(
                mContext.getContentResolver(),
                Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS,
                DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS);

        // Check whether the currently selected network has a score curve. If
        // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here.
        // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we
        // keep going - it could be that another BSSID is in range (has been seen recently) which
        // has a score, even if the one we're immediately connected to doesn't.
        ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult();
        boolean currentNetworkHasScoreCurve = mNetworkScoreCache.hasScoreCurve(currentScanResult);
        if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) {
            if (DBG) {
                if (currentNetworkHasScoreCurve) {
                    logDbg("Current network has a score curve, keeping network: "
                            + currentScanResult);
                } else {
                    logDbg("Current network has no score curve, giving up: " + config.SSID);
                }
            }
            return currentNetworkHasScoreCurve;
        }

        if (mWifiConfigStore.getScanDetailCache(config) == null
                || mWifiConfigStore.getScanDetailCache(config).isEmpty()) {
            return false;
        }

        long currentTimeMs = System.currentTimeMillis();
        for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) {
            ScanResult result = sd.getScanResult();
            if (currentTimeMs > sd.getSeen()
                    && currentTimeMs - sd.getSeen() < ephemeralOutOfRangeTimeoutMs
                    && mNetworkScoreCache.hasScoreCurve(result)) {
                if (DBG) {
                    logDbg("Found scored BSSID, keeping network: " + result.BSSID);
                }
                return true;
            }
        }

        if (DBG) {
            logDbg("No recently scored BSSID found, giving up connection: " + config.SSID);
        }
        return false;
    }

    // After WifiStateMachine ask the supplicant to associate or reconnect
    // we might still obtain scan results from supplicant
    // however the supplicant state in the mWifiInfo and supplicant state tracker
    // are updated when we get the supplicant state change message which can be
    // processed after the SCAN_RESULT message, so at this point the framework doesn't
    // know that supplicant is ASSOCIATING.
    // A good fix for this race condition would be for the WifiStateMachine to add
    // a new transient state where it expects to get the supplicant message indicating
    // that it started the association process and within which critical operations
    // like autojoin should be deleted.

    // This transient state would remove the need for the roam Wathchdog which
    // basically does that.

    // At the moment, we just query the supplicant state synchronously with the
    // mWifiNative.status() command, which allow us to know that
    // supplicant has started association process, even though we didnt yet get the
    // SUPPLICANT_STATE_CHANGE message.

    private static final List<String> ASSOC_STATES = Arrays.asList(
            "ASSOCIATING",
            "ASSOCIATED",
            "FOUR_WAY_HANDSHAKE",
            "GROUP_KEY_HANDSHAKE");

    private int getNetID(String wpaStatus) {
        if (VDBG) {
            logDbg("attemptAutoJoin() status=" + wpaStatus);
        }

        try {
            int id = WifiConfiguration.INVALID_NETWORK_ID;
            String state = null;
            BufferedReader br = new BufferedReader(new StringReader(wpaStatus));
            String line;
            while ((line = br.readLine()) != null) {
                int split = line.indexOf('=');
                if (split < 0) {
                    continue;
                }

                String name = line.substring(0, split);
                if (name.equals("id")) {
                    try {
                        id = Integer.parseInt(line.substring(split + 1));
                        if (state != null) {
                            break;
                        }
                    } catch (NumberFormatException nfe) {
                        return WifiConfiguration.INVALID_NETWORK_ID;
                    }
                } else if (name.equals("wpa_state")) {
                    state = line.substring(split + 1);
                    if (ASSOC_STATES.contains(state)) {
                        return WifiConfiguration.INVALID_NETWORK_ID;
                    } else if (id >= 0) {
                        break;
                    }
                }
            }
            return id;
        } catch (IOException ioe) {
            return WifiConfiguration.INVALID_NETWORK_ID;    // Won't happen
        }
    }

    private boolean setCurrentConfigurationKey(WifiConfiguration currentConfig,
                                               int supplicantNetId) {
        if (currentConfig != null) {
            if (supplicantNetId != currentConfig.networkId
                    // https://b.corp.google.com/issue?id=16484607
                    // mark this condition as an error only if the mismatched networkId are valid
                    && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID
                    && currentConfig.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
                logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid="
                        + Integer.toString(supplicantNetId) + " WifiStateMachine="
                        + Integer.toString(currentConfig.networkId));
                mWifiStateMachine.disconnectCommand();
                return false;
            } else if (currentConfig.ephemeral && (!mAllowUntrustedConnections ||
                    !haveRecentlySeenScoredBssid(currentConfig))) {
                // The current connection is untrusted (the framework added it), but we're either
                // no longer allowed to connect to such networks, the score has been nullified
                // since we connected, or the scored BSSID has gone out of range.
                // Drop the current connection and perform the rest of autojoin.
                logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network");
                mWifiStateMachine.disconnectCommand(Process.WIFI_UID,
                        mAllowUntrustedConnections ? 1 : 0);
                return false;
            } else {
                mCurrentConfigurationKey = currentConfig.configKey();
                return true;
            }
        } else {
            // If not invalid, then maybe in the process of associating, skip this attempt
            return supplicantNetId == WifiConfiguration.INVALID_NETWORK_ID;
        }
    }

    private void updateBlackListStatus(WifiConfiguration config, long now) {
        // Wait for 5 minutes before reenabling config that have known,
        // repeated connection or DHCP failures
        if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE
                || config.disableReason
                == WifiConfiguration.DISABLED_ASSOCIATION_REJECT
                || config.disableReason
                == WifiConfiguration.DISABLED_AUTH_FAILURE) {
            if (config.blackListTimestamp == 0
                    || (config.blackListTimestamp > now)) {
                // Sanitize the timestamp
                config.blackListTimestamp = now;
            }
            if ((now - config.blackListTimestamp) >
                    mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) {
                // Re-enable the WifiConfiguration
                config.status = WifiConfiguration.Status.ENABLED;

                // Reset the blacklist condition
                config.numConnectionFailures = 0;
                config.numIpConfigFailures = 0;
                config.numAuthFailures = 0;
                config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);

                config.dirty = true;
            } else {
                if (VDBG) {
                    long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli
                            - (now - config.blackListTimestamp);
                    logDbg("attemptautoJoin " + config.configKey()
                            + " dont unblacklist yet, waiting for "
                            + delay + " ms");
                }
            }
        }
        // Avoid networks disabled because of AUTH failure altogether
        if (DBG) {
            logDbg("attemptAutoJoin skip candidate due to auto join status "
                    + Integer.toString(config.autoJoinStatus) + " key "
                    + config.configKey(true)
                    + " reason " + config.disableReason);
        }
    }

    boolean underSoftThreshold(WifiConfiguration config) {
        return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Soft.get()
                && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft.get();
    }

    boolean underHardThreshold(WifiConfiguration config) {
        return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Hard.get()
                && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard.get();
    }

    boolean underThreshold(WifiConfiguration config, int rssi24, int rssi5) {
        return config.visibility.rssi24 < rssi24 && config.visibility.rssi5 < rssi5;
    }

    /**
     * attemptAutoJoin() function implements the core of the a network switching algorithm
     * Return false if no acceptable networks were found.
     */
    boolean attemptAutoJoin() {
        boolean found = false;
        didOverride = false;
        didBailDueToWeakRssi = false;
        int networkSwitchType = AUTO_JOIN_IDLE;

        long now = System.currentTimeMillis();

        String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration();

        // Reset the currentConfiguration Key, and set it only if WifiStateMachine and
        // supplicant agree
        mCurrentConfigurationKey = null;
        WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration();

        WifiConfiguration candidate = null;

        // Obtain the subset of recently seen networks
        List<WifiConfiguration> list =
                mWifiConfigStore.getRecentConfiguredNetworks(mScanResultAutoJoinAge, false);
        if (list == null) {
            if (VDBG) logDbg("attemptAutoJoin nothing known=" +
                    mWifiConfigStore.getConfiguredNetworkSize());
            return false;
        }

        // Find the currently connected network: ask the supplicant directly
        int supplicantNetId = getNetID(mWifiNative.status(true));

        if (DBG) {
            String conf = "";
            String last = "";
            if (currentConfiguration != null) {
                conf = " current=" + currentConfiguration.configKey();
            }
            if (lastSelectedConfiguration != null) {
                last = " last=" + lastSelectedConfiguration;
            }
            logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size())
                    + conf + last
                    + " ---> suppNetId=" + Integer.toString(supplicantNetId));
        }

        if (!setCurrentConfigurationKey(currentConfiguration, supplicantNetId)) {
            return false;
        }

        int currentNetId = -1;
        if (currentConfiguration != null) {
            // If we are associated to a configuration, it will
            // be compared thru the compareNetwork function
            currentNetId = currentConfiguration.networkId;
        }

        /**
         * Run thru all visible configurations without looking at the one we
         * are currently associated to
         * select Best Network candidate from known WifiConfigurations
         */
        for (WifiConfiguration config : list) {
            if (config.SSID == null) {
                continue;
            }

            if (config.autoJoinStatus >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) {
                updateBlackListStatus(config, now);
                continue;
            }

            if (config.userApproved == WifiConfiguration.USER_PENDING ||
                    config.userApproved == WifiConfiguration.USER_BANNED) {
                if (DBG) {
                    logDbg("attemptAutoJoin skip candidate due to user approval status "
                            + WifiConfiguration.userApprovedAsString(config.userApproved) + " key "
                            + config.configKey(true));
                }
                continue;
            }

            // Try to un-blacklist based on elapsed time
            if (config.blackListTimestamp > 0) {
                if (now < config.blackListTimestamp) {
                    /**
                     * looks like there was a change in the system clock since we black listed, and
                     * timestamp is not meaningful anymore, hence lose it.
                     * this event should be rare enough so that we still want to lose the black list
                     */
                    config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);
                } else {
                    if ((now - config.blackListTimestamp) > loseBlackListHardMilli) {
                        // Reenable it after 18 hours, i.e. next day
                        config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);
                    } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) {
                        // Lose blacklisting due to bad link
                        config.setAutoJoinStatus(config.autoJoinStatus - 8);
                    }
                }
            }

            if (config.visibility == null) {
                continue;
            }

            // Try to unblacklist based on good visibility
            if (underSoftThreshold(config)) {
                logDenial("attemptAutoJoin do not unblacklist due to low visibility ", config);
            } else if (underHardThreshold(config)) {
                // If the network is simply temporary disabled, don't allow reconnect until
                // RSSI becomes good enough
                config.setAutoJoinStatus(config.autoJoinStatus - 1);
                logDenial("attemptAutoJoin good candidate seen, bumped soft -> status=", config);
            } else {
                config.setAutoJoinStatus(config.autoJoinStatus - 3);
                logDenial("attemptAutoJoin good candidate seen, bumped hard -> status=", config);
            }

            if (config.autoJoinStatus >=
                    WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) {
                // Network is blacklisted, skip
                logDenial("attemptAutoJoin skip blacklisted -> status=", config);
                continue;
            }
            if (config.networkId == currentNetId) {
                if (DBG) {
                    logDbg("attemptAutoJoin skip current candidate  "
                            + Integer.toString(currentNetId)
                            + " key " + config.configKey(true));
                }
                continue;
            }

            boolean isLastSelected = false;
            if (lastSelectedConfiguration != null &&
                    config.configKey().equals(lastSelectedConfiguration)) {
                isLastSelected = true;
            }

            if (config.lastRoamingFailure != 0
                    && currentConfiguration != null
                    && (lastSelectedConfiguration == null
                    || !config.configKey().equals(lastSelectedConfiguration))) {
                // Apply blacklisting for roaming to this config if:
                //   - the target config had a recent roaming failure
                //   - we are currently associated
                //   - the target config is not the last selected
                if (now > config.lastRoamingFailure
                        && (now - config.lastRoamingFailure)
                        < config.roamingFailureBlackListTimeMilli) {
                    if (DBG) {
                        logDbg("compareNetwork not switching to " + config.configKey()
                                + " from current " + currentConfiguration.configKey()
                                + " because it is blacklisted due to roam failure, "
                                + " blacklist remain time = "
                                + (now - config.lastRoamingFailure) + " ms");
                    }
                    continue;
                }
            }

            int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount;
            if (underThreshold(config,
                    mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI.get() - boost,
                    mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI.get() - boost)) {

                logDenial("attemptAutoJoin skip due to low visibility -> status=", config);

                // Don't try to autojoin a network that is too far but
                // If that configuration is a user's choice however, try anyway
                if (!isLastSelected) {
                    config.autoJoinBailedDueToLowRssi = true;
                    didBailDueToWeakRssi = true;
                    continue;
                } else {
                    // Next time, try to be a bit more aggressive in auto-joining
                    if (config.autoJoinUseAggressiveJoinAttemptThreshold
                            < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST
                            && config.autoJoinBailedDueToLowRssi) {
                        config.autoJoinUseAggressiveJoinAttemptThreshold += 4;
                    }
                }
            }
            if (config.numNoInternetAccessReports > 0
                    && !isLastSelected
                    && !config.validatedInternetAccess) {
                // Avoid autoJoining this network because last time we used it, it didn't
                // have internet access, and we never manage to validate internet access on this
                // network configuration
                if (DBG) {
                    logDbg("attemptAutoJoin skip candidate due to no InternetAccess  "
                            + config.configKey(true)
                            + " num reports " + config.numNoInternetAccessReports);
                }
                continue;
            }

            if (DBG) {
                String cur = "";
                if (candidate != null) {
                    cur = " current candidate " + candidate.configKey();
                }
                logDbg("attemptAutoJoin trying id="
                        + Integer.toString(config.networkId) + " "
                        + config.configKey(true)
                        + " status=" + config.autoJoinStatus
                        + cur);
            }

            if (candidate == null) {
                candidate = config;
            } else {
                if (VDBG) {
                    logDbg("attemptAutoJoin will compare candidate  " + candidate.configKey()
                            + " with " + config.configKey());
                }

                int order = compareWifiConfigurations(candidate, config);
                if (VDBG) {
                    logDbg("attemptAutoJoin compareWifiConfigurations returned " + order);
                }

                // The lastSelectedConfiguration is the configuration the user has manually selected
                // thru WifiPicker, or that a 3rd party app asked us to connect to via the
                // enableNetwork with disableOthers=true WifiManager API
                // As this is a direct user choice, we strongly prefer this configuration,
                // hence give +/-100
                if ((lastSelectedConfiguration != null)
                        && candidate.configKey().equals(lastSelectedConfiguration)) {
                    // candidate is the last selected configuration,
                    // so keep it above connect choices (+/-60) and
                    // above RSSI/scorer based selection of linked configuration (+/- 50)
                    // by reducing order by -100
                    order = order - 100;
                    if (VDBG) {
                        logDbg("     ...and prefers -100 " + candidate.configKey()
                                + " over " + config.configKey()
                                + " because it is the last selected -> "
                                + Integer.toString(order));
                    }
                } else if ((lastSelectedConfiguration != null)
                        && config.configKey().equals(lastSelectedConfiguration)) {
                    // config is the last selected configuration,
                    // so keep it above connect choices (+/-60) and
                    // above RSSI/scorer based selection of linked configuration (+/- 50)
                    // by increasing order by +100
                    order = order + 100;
                    if (VDBG) {
                        logDbg("     ...and prefers +100 " + config.configKey()
                                + " over " + candidate.configKey()
                                + " because it is the last selected -> "
                                + Integer.toString(order));
                    }
                }

                if (order > 0) {
                    // Ascending : candidate < config
                    candidate = config;
                }
            }
        }

        // Now, go thru scan result to try finding a better untrusted network
        if (mNetworkScoreCache != null && mAllowUntrustedConnections) {
            int rssi5 = WifiConfiguration.INVALID_RSSI;
            int rssi24 = WifiConfiguration.INVALID_RSSI;
            if (candidate != null) {
                rssi5 = candidate.visibility.rssi5;
                rssi24 = candidate.visibility.rssi24;
            }

            // Get current date
            long nowMs = System.currentTimeMillis();
            int currentScore = -10000;
            // The untrusted network with highest score
            ScanDetail untrustedCandidate = null;
            // Look for untrusted scored network only if the current candidate is bad
            if (isBadCandidate(rssi24, rssi5)) {
                for (ScanDetail scanDetail : scanResultCache.values()) {
                    ScanResult result = scanDetail.getScanResult();
                    // We look only at untrusted networks with a valid SSID
                    // A trusted result would have been looked at thru it's Wificonfiguration
                    if (TextUtils.isEmpty(result.SSID) || !result.untrusted ||
                            !isOpenNetwork(result)) {
                        continue;
                    }
                    String quotedSSID = "\"" + result.SSID + "\"";
                    if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains(quotedSSID)) {
                        // SSID had been Forgotten by user, then don't score it
                        continue;
                    }
                    if ((nowMs - result.seen) < mScanResultAutoJoinAge) {
                        // Increment usage count for the network
                        mWifiConnectionStatistics.incrementOrAddUntrusted(quotedSSID, 0, 1);

                        boolean isActiveNetwork = currentConfiguration != null
                                && currentConfiguration.SSID.equals(quotedSSID);
                        int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork);
                        if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE
                                && score > currentScore) {
                            // Highest score: Select this candidate
                            currentScore = score;
                            untrustedCandidate = scanDetail;
                            if (VDBG) {
                                logDbg("AutoJoinController: found untrusted candidate "
                                        + result.SSID
                                        + " RSSI=" + result.level
                                        + " freq=" + result.frequency
                                        + " score=" + score);
                            }
                        }
                    }
                }
            }
            if (untrustedCandidate != null) {
                // At this point, we have an untrusted network candidate.
                // Create the new ephemeral configuration and see if we should switch over
                candidate =
                        mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate);
                candidate.allowedKeyManagement.set(KeyMgmt.NONE);
                candidate.ephemeral = true;
            }
        }

        long lastUnwanted =
                System.currentTimeMillis()
                        - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp;
        if (candidate == null
                && lastSelectedConfiguration == null
                && currentConfiguration == null
                && didBailDueToWeakRssi
                && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0
                || lastUnwanted > (1000 * 60 * 60 * 24 * 7))
                ) {
            // We are bailing out of autojoin although we are seeing a weak configuration, and
            // - we didn't find another valid candidate
            // - we are not connected
            // - without a user network selection choice
            // - ConnectivityService has not triggered an unwanted network disconnect
            //       on this device for a week (hence most likely there is no SIM card or cellular)
            // If all those conditions are met, then boost the RSSI of the weak networks
            // that we are seeing so as we will eventually pick one
            if (weakRssiBailCount < 10)
                weakRssiBailCount += 1;
        } else {
            if (weakRssiBailCount > 0)
                weakRssiBailCount -= 1;
        }

        /**
         *  If candidate is found, check the state of the connection so as
         *  to decide if we should be acting on this candidate and switching over
         */
        int networkDelta = compareNetwork(candidate, lastSelectedConfiguration);
        if (DBG && candidate != null) {
            String doSwitch = "";
            String current = "";
            if (networkDelta < 0) {
                doSwitch = " -> not switching";
            }
            if (currentConfiguration != null) {
                current = " with current " + currentConfiguration.configKey();
            }
            logDbg("attemptAutoJoin networkSwitching candidate "
                    + candidate.configKey()
                    + current
                    + " linked=" + (currentConfiguration != null
                    && currentConfiguration.isLinked(candidate))
                    + " : delta="
                    + Integer.toString(networkDelta) + " "
                    + doSwitch);
        }

        /**
         * Ask WifiStateMachine permission to switch :
         * if user is currently streaming voice traffic,
         * then we should not be allowed to switch regardless of the delta
         */
        if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) {      // !!! JNo: Here!
            if (mStaStaSupported) {
                logDbg("mStaStaSupported --> error do nothing now ");
            } else {
                if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) {
                    networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING;
                } else {
                    networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING;
                }
                if (DBG) {
                    logDbg("AutoJoin auto connect with netId "
                            + Integer.toString(candidate.networkId)
                            + " to " + candidate.configKey());
                }
                if (didOverride) {
                    candidate.numScorerOverrideAndSwitchedNetwork++;
                }
                candidate.numAssociation++;
                mWifiConnectionStatistics.numAutoJoinAttempt++;

                if (candidate.ephemeral) {
                    // We found a new candidate that we are going to connect to, then
                    // increase its connection count
                    mWifiConnectionStatistics.
                            incrementOrAddUntrusted(candidate.SSID, 1, 0);
                }

                if (candidate.BSSID == null || candidate.BSSID.equals("any")) {
                    // First step we selected the configuration we want to connect to
                    // Second step: Look for the best Scan result for this configuration
                    // TODO this algorithm should really be done in one step
                    String currentBSSID = mWifiStateMachine.getCurrentBSSID();
                    ScanResult roamCandidate =
                            attemptRoam(null, candidate, mScanResultAutoJoinAge, null);
                    if (roamCandidate != null && currentBSSID != null
                            && currentBSSID.equals(roamCandidate.BSSID)) {
                        // Sanity, we were already asociated to that candidate
                        roamCandidate = null;
                    }
                    if (roamCandidate != null && roamCandidate.is5GHz()) {
                        // If the configuration hasn't a default BSSID selected, and the best
                        // candidate is 5GHZ, then select this candidate so as WifiStateMachine and
                        // supplicant will pick it first
                        candidate.autoJoinBSSID = roamCandidate.BSSID;
                        if (VDBG) {
                            logDbg("AutoJoinController: lock to 5GHz "
                                    + candidate.autoJoinBSSID
                                    + " RSSI=" + roamCandidate.level
                                    + " freq=" + roamCandidate.frequency);
                        }
                    } else {
                        // We couldnt find a roam candidate
                        candidate.autoJoinBSSID = "any";
                    }
                }
                mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT,
                        candidate.networkId, networkSwitchType, candidate);
                found = true;
            }
        }

        if (networkSwitchType == AUTO_JOIN_IDLE && !mWifiConfigStore.enableHalBasedPno.get()) {
            String currentBSSID = mWifiStateMachine.getCurrentBSSID();
            // Attempt same WifiConfiguration roaming
            ScanResult roamCandidate =
                    attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID);
            if (roamCandidate != null && currentBSSID != null
                    && currentBSSID.equals(roamCandidate.BSSID)) {
                roamCandidate = null;
            }
            if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) {
                if (DBG) {
                    logDbg("AutoJoin auto roam with netId "
                            + Integer.toString(currentConfiguration.networkId)
                            + " " + currentConfiguration.configKey() + " to BSSID="
                            + roamCandidate.BSSID + " freq=" + roamCandidate.frequency
                            + " RSSI=" + roamCandidate.level);
                }
                networkSwitchType = AUTO_JOIN_ROAMING;
                mWifiConnectionStatistics.numAutoRoamAttempt++;

                mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM,
                        currentConfiguration.networkId, 1, roamCandidate);
                found = true;
            }
        }
        if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType));
        return found;
    }

    private void logDenial(String reason, WifiConfiguration config) {
        if (!DBG) {
            return;
        }
        logDbg(reason + config.toString());
    }

    WifiConfiguration getWifiConfiguration(WifiNative.WifiPnoNetwork network) {
        if (network.configKey != null) {
            return mWifiConfigStore.getWifiConfiguration(network.configKey);
        }
        return null;
    }

    ArrayList<WifiNative.WifiPnoNetwork> getPnoList(WifiConfiguration current) {
        int size = -1;
        ArrayList<WifiNative.WifiPnoNetwork> list = null;

        if (mWifiConfigStore.mCachedPnoList != null) {
            size = mWifiConfigStore.mCachedPnoList.size();
        }
        Log.d(TAG, " get Pno List total size:" + size);

        if (current != null) {
            String configKey = current.configKey();
            /**
             * If we are currently associated to a WifiConfiguration then include
             * only those networks that have a higher priority
             */
            list = new ArrayList<WifiNative.WifiPnoNetwork>();
            for (WifiNative.WifiPnoNetwork network : mWifiConfigStore.mCachedPnoList) {
                WifiConfiguration config = getWifiConfiguration(network);
                if (config != null && !configKey.equals(network.configKey)) {
                    int choice = getConnectChoice(config, current);
                    if (choice > 0) {
                        // config is of higher priority
                        list.add(network);
                        network.rssi_threshold = mWifiConfigStore.thresholdGoodRssi24.get();
                    }
                }
            }
        } else {
            list = mWifiConfigStore.mCachedPnoList;
        }
        return list;
    }
}

