AccessPoint.java revision 98773d4837922715c740d06bfd02666dceaf350b
1773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi/*
2773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project
3773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
4773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * you may not use this file except in compliance with the License.
6773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * You may obtain a copy of the License at
7773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
8773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
10773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * See the License for the specific language governing permissions and
14773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * limitations under the License.
15773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi */
16773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
17daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kastenpackage com.android.settingslib.wifi;
18f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Triviimport android.app.AppGlobals;
20773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Triviimport android.content.Context;
21a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenimport android.content.pm.ApplicationInfo;
22a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenimport android.content.pm.IPackageManager;
2375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Triviimport android.content.pm.PackageManager;
241ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Triviimport android.net.ConnectivityManager;
2505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Triviimport android.net.Network;
2613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.NetworkCapabilities;
2713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.NetworkInfo;
2813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.NetworkInfo.DetailedState;
2913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.NetworkInfo.State;
3013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.NetworkKey;
3113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.ScoredNetwork;
3213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.IWifiManager;
3313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.ScanResult;
3413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.WifiConfiguration;
3513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.WifiConfiguration.KeyMgmt;
3613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.WifiInfo;
3713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.WifiManager;
3813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.net.wifi.WifiNetworkScoreCache;
3913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.os.Bundle;
4013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.os.RemoteException;
4113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.os.ServiceManager;
4213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.os.SystemClock;
4313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.os.UserHandle;
4413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.support.annotation.NonNull;
4513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.text.Spannable;
4613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.text.SpannableString;
4713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.text.TextUtils;
4813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.text.style.TtsSpan;
4913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport android.util.Log;
5013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
5113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport com.android.settingslib.R;
5213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
5313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport java.util.ArrayList;
5413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport java.util.Collection;
5513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport java.util.Iterator;
5613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport java.util.concurrent.ConcurrentHashMap;
5713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Triviimport java.util.concurrent.atomic.AtomicInteger;
5813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
5913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
6013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivipublic class AccessPoint implements Comparable<AccessPoint> {
6113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    static final String TAG = "SettingsLib.AccessPoint";
6213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
6313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
6413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Lower bound on the 2.4 GHz (802.11b/g/n) WLAN channels
6513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
6613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int LOWER_FREQ_24GHZ = 2400;
6713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
6813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
6913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Upper bound on the 2.4 GHz (802.11b/g/n) WLAN channels
7013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
7113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int HIGHER_FREQ_24GHZ = 2500;
7213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
7313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
7413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Lower bound on the 5.0 GHz (802.11a/h/j/n/ac) WLAN channels
7513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
7613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int LOWER_FREQ_5GHZ = 4900;
7713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
7813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
7913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Upper bound on the 5.0 GHz (802.11a/h/j/n/ac) WLAN channels
8013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
8113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int HIGHER_FREQ_5GHZ = 5900;
8213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
8313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
8413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
8513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Experimental: we should be able to show the user the list of BSSIDs and bands
8613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     *  for that SSID.
8713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     *  For now this data is used only with Verbose Logging so as to show the band and number
8813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     *  of BSSIDs on which that network is seen.
8913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
9013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private final ConcurrentHashMap<String, ScanResult> mScanResultCache =
9113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            new ConcurrentHashMap<String, ScanResult>(32);
9213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final long MAX_SCAN_RESULT_AGE_MS = 15000;
9313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
94e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    private static final String KEY_NETWORKINFO = "key_networkinfo";
9513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_WIFIINFO = "key_wifiinfo";
9613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_SCANRESULT = "key_scanresult";
9713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_SSID = "key_ssid";
9813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_SECURITY = "key_security";
9913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_PSKTYPE = "key_psktype";
10013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_SCANRESULTCACHE = "key_scanresultcache";
10113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final String KEY_CONFIG = "key_config";
10213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final AtomicInteger sLastId = new AtomicInteger(0);
10313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
10413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
10513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * These values are matched in string arrays -- changes must be kept in sync
10613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
10713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int SECURITY_NONE = 0;
10813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int SECURITY_WEP = 1;
10913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int SECURITY_PSK = 2;
11013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int SECURITY_EAP = 3;
11113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
11213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final int PSK_UNKNOWN = 0;
11313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final int PSK_WPA = 1;
11413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final int PSK_WPA2 = 2;
11513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static final int PSK_WPA_WPA2 = 3;
11613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
11713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public static final int SIGNAL_LEVELS = 4;
11813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
11913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private final Context mContext;
12013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
12113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private String ssid;
12213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private String bssid;
12313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int security;
12413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int networkId = WifiConfiguration.INVALID_NETWORK_ID;
12513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
12613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int pskType = PSK_UNKNOWN;
12713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
12813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private WifiConfiguration mConfig;
12913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
13013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int mRssi = Integer.MAX_VALUE;
13113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private long mSeen = 0;
13213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
13313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private WifiInfo mInfo;
13413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private NetworkInfo mNetworkInfo;
13513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    AccessPointListener mAccessPointListener;
13613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
13713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private Object mTag;
13813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
13913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int mRankingScore = Integer.MIN_VALUE;
14013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private int mBadge = ScoredNetwork.BADGING_NONE;
14113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // used to co-relate internal vs returned accesspoint.
14313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    int mId;
14413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public AccessPoint(Context context, Bundle savedState) {
14613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        mContext = context;
14713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        mConfig = savedState.getParcelable(KEY_CONFIG);
14813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (mConfig != null) {
14913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            loadConfig(mConfig);
15013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
15113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (savedState.containsKey(KEY_SSID)) {
152a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ssid = savedState.getString(KEY_SSID);
153a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
154a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        if (savedState.containsKey(KEY_SECURITY)) {
155a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            security = savedState.getInt(KEY_SECURITY);
156a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
157a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        if (savedState.containsKey(KEY_PSKTYPE)) {
158a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            pskType = savedState.getInt(KEY_PSKTYPE);
159a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
160a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        mInfo = (WifiInfo) savedState.getParcelable(KEY_WIFIINFO);
161a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        if (savedState.containsKey(KEY_NETWORKINFO)) {
162a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            mNetworkInfo = savedState.getParcelable(KEY_NETWORKINFO);
163a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
164a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        if (savedState.containsKey(KEY_SCANRESULTCACHE)) {
165a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            ArrayList<ScanResult> scanResultArrayList =
166a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                    savedState.getParcelableArrayList(KEY_SCANRESULTCACHE);
167a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            mScanResultCache.clear();
168a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            for (ScanResult result : scanResultArrayList) {
169a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                mScanResultCache.put(result.BSSID, result);
170a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            }
171a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
172a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        update(mConfig, mInfo, mNetworkInfo);
1736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        mRssi = getRssi();
1746a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        mSeen = getSeen();
175712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi        mId = sLastId.incrementAndGet();
176712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi    }
1771fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1781fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    AccessPoint(Context context, ScanResult result) {
1796a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        mContext = context;
180d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi        initWithScanResult(result);
1816a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        mId = sLastId.incrementAndGet();
1826a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
1844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    AccessPoint(Context context, WifiConfiguration config) {
18545d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi        mContext = context;
1861fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        loadConfig(config);
1871fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        mId = sLastId.incrementAndGet();
1881fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
1891fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    AccessPoint(Context context, AccessPoint other) {
1911fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        mContext = context;
1921fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        copyFrom(other);
1931fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
1941fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1951fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    /**
196e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten     * Copy accesspoint information. NOTE: We do not copy tag information because that is never
197b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten     * set on the internal copy.
1981fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi     * @param that
1991fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi     */
2001fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    void copyFrom(AccessPoint that) {
2011fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        that.evictOldScanResults();
202b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        this.ssid = that.ssid;
2031fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.bssid = that.bssid;
2041fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.security = that.security;
2051fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.networkId = that.networkId;
2061fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.pskType = that.pskType;
207b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        this.mConfig = that.mConfig; //TODO: Watch out, this object is mutated.
2081fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mRssi = that.mRssi;
2091fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mSeen = that.mSeen;
2101fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mInfo = that.mInfo;
2111fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mNetworkInfo = that.mNetworkInfo;
2121fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mScanResultCache.clear();
2131fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mScanResultCache.putAll(that.mScanResultCache);
2141fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mId = that.mId;
2151fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mBadge = that.mBadge;
2161fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        this.mRankingScore = that.mRankingScore;
217b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten    }
2181fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
2191fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    @Override
2201fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    public int compareTo(@NonNull AccessPoint other) {
2211fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // Active one goes first.
222b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (isActive() && !other.isActive()) return -1;
2231fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        if (!isActive() && other.isActive()) return 1;
2241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
2251fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // Reachable one goes before unreachable one.
2261fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        if (mRssi != Integer.MAX_VALUE && other.mRssi == Integer.MAX_VALUE) return -1;
227b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (mRssi == Integer.MAX_VALUE && other.mRssi != Integer.MAX_VALUE) return 1;
2281fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
2291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // Configured (saved) one goes before unconfigured one.
2301fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        if (networkId != WifiConfiguration.INVALID_NETWORK_ID
2311fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                && other.networkId == WifiConfiguration.INVALID_NETWORK_ID) return -1;
2321fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        if (networkId == WifiConfiguration.INVALID_NETWORK_ID
2331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                && other.networkId != WifiConfiguration.INVALID_NETWORK_ID) return 1;
2341fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
2351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // Higher scores go before lower scores
2361fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        if (mRankingScore != other.mRankingScore) {
2376a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            return (mRankingScore > other.mRankingScore) ? -1 : 1;
2386a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
239172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi
240172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi        // Sort by signal strength, bucketed by level
241ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        int difference = WifiManager.calculateSignalLevel(other.mRssi, SIGNAL_LEVELS)
242172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi                - WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS);
243172e4da556ad3cb1d2a06cfa019903310aa291d5Jean-Michel Trivi        if (difference != 0) {
244a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            return difference;
245f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        }
2461fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // Sort by ssid.
247f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        return ssid.compareToIgnoreCase(other.ssid);
24845d40b8ac4cd8f3f73813a26334c7e5ecc3cb73cJean-Michel Trivi    }
249f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
2501fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    @Override
251e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    public boolean equals(Object other) {
252e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        if (!(other instanceof AccessPoint)) return false;
253f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        return (this.compareTo((AccessPoint) other) == 0);
254f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
2551fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
256e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    @Override
257e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    public int hashCode() {
2586a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        int result = 0;
259e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        if (mInfo != null) result += 13 * mInfo.hashCode();
260e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        result += 19 * mRssi;
2616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result += 23 * networkId;
2626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result += 29 * ssid.hashCode();
263e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return result;
264e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    }
265f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
266f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    @Override
2671fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    public String toString() {
268ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        StringBuilder builder = new StringBuilder().append("AccessPoint(")
269ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi                .append(ssid);
270ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        if (isSaved()) {
271ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi            builder.append(',').append("saved");
272ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        }
273ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        if (isActive()) {
274ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi            builder.append(',').append("active");
275ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        }
276ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        if (isEphemeral()) {
277ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi            builder.append(',').append("ephemeral");
278ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        }
279ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        if (isConnectable()) {
280ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi            builder.append(',').append("connectable");
281ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        }
282ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        if (security != SECURITY_NONE) {
283ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi            builder.append(',').append(securityToString(security, pskType));
284ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi        }
2854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        builder.append(",rankingScore=").append(mRankingScore);
2864614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        builder.append(",badge=").append(mBadge);
2874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
288e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        return builder.append(')').toString();
28949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    }
2904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
2914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    /**
2924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi     * Updates the AccessPoint rankingScore and badge, returning true if the data has changed.
2934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi     *
2944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi     * @param scoreCache The score cache to use to retrieve scores.
2954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi     */
2964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    boolean updateScores(WifiNetworkScoreCache scoreCache) {
2974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        int oldBadge = mBadge;
2984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        int oldRankingScore = mRankingScore;
2994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        mBadge = ScoredNetwork.BADGING_NONE;
3004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        mRankingScore = Integer.MIN_VALUE;
3014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        for (ScanResult result : mScanResultCache.values()) {
3034614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ScoredNetwork score = scoreCache.getScoredNetwork(result);
3044614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (score == null) {
305e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                continue;
30649e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            }
3074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (score.hasRankingScore()) {
3094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi                mRankingScore = Math.max(mRankingScore, score.calculateRankingScore(result.level));
3104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            }
3114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            mBadge = Math.max(mBadge, score.calculateBadge(result.level));
3124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        }
3134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        return (oldBadge != mBadge || oldRankingScore != mRankingScore);
3154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
3164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    private void evictOldScanResults() {
3184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        long nowMs = SystemClock.elapsedRealtime();
3194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) {
3204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ScanResult result = iter.next();
3214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            // result timestamp is in microseconds
3224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MS) {
323e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                iter.remove();
3244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            }
3254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        }
3264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
3274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    public boolean matches(ScanResult result) {
3294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        return ssid.equals(result.SSID) && security == getSecurity(result);
3304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
3314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    public boolean matches(WifiConfiguration config) {
3334614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (config.isPasspoint() && mConfig != null && mConfig.isPasspoint()) {
3344614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            return ssid.equals(removeDoubleQuotes(config.SSID)) && config.FQDN.equals(mConfig.FQDN);
335f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
336f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            return ssid.equals(removeDoubleQuotes(config.SSID))
337f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                    && security == getSecurity(config)
33824430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi                    && (mConfig == null || mConfig.shared == config.shared);
339e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        }
340e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
341e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
342e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    public WifiConfiguration getConfig() {
343e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        return mConfig;
344e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
345e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
346e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    public void clearConfig() {
347e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        mConfig = null;
348e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        networkId = WifiConfiguration.INVALID_NETWORK_ID;
349e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
350e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
351e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    public WifiInfo getInfo() {
352e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        return mInfo;
353fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
354fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten
35525d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    public int getLevel() {
35625d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi        if (mRssi == Integer.MAX_VALUE) {
357e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            return -1;
358e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        }
359e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        return WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS);
360fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
361ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi
362fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    public int getRssi() {
363e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        evictOldScanResults();
364e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        int rssi = Integer.MIN_VALUE;
365e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        for (ScanResult result : mScanResultCache.values()) {
366e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            if (result.level > rssi) {
36725d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi                rssi = result.level;
368ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi            }
369ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        }
370ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi
371ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        return rssi;
372fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
373e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
374e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    public long getSeen() {
375e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        evictOldScanResults();
376e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        long seen = 0;
37725d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi        for (ScanResult result : mScanResultCache.values()) {
378e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            if (result.timestamp > seen) {
379e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                seen = result.timestamp;
380a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            }
381a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
382a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
383a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        return seen;
384a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
385a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
386a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    public NetworkInfo getNetworkInfo() {
387a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        return mNetworkInfo;
388a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
389fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten
390fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    public int getSecurity() {
391a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        return security;
392a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
393a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
394fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    public String getSecurityString(boolean concise) {
395fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        Context context = mContext;
396fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        if (mConfig != null && mConfig.isPasspoint()) {
397a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            return concise ? context.getString(R.string.wifi_security_short_eap) :
398a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                context.getString(R.string.wifi_security_eap);
399a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
400a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        switch(security) {
401a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            case SECURITY_EAP:
402a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                return concise ? context.getString(R.string.wifi_security_short_eap) :
403a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                    context.getString(R.string.wifi_security_eap);
404a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            case SECURITY_PSK:
405a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                switch (pskType) {
406fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten                    case PSK_WPA:
407fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten                        return concise ? context.getString(R.string.wifi_security_short_wpa) :
408fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten                            context.getString(R.string.wifi_security_wpa);
409a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                    case PSK_WPA2:
410a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                        return concise ? context.getString(R.string.wifi_security_short_wpa2) :
411a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                            context.getString(R.string.wifi_security_wpa2);
412a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                    case PSK_WPA_WPA2:
413a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                        return concise ? context.getString(R.string.wifi_security_short_wpa_wpa2) :
414a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                            context.getString(R.string.wifi_security_wpa_wpa2);
415a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                    case PSK_UNKNOWN:
416a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                    default:
417f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                        return concise ? context.getString(R.string.wifi_security_short_psk_generic)
41875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                                : context.getString(R.string.wifi_security_psk_generic);
41975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                }
42075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            case SECURITY_WEP:
42175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                return concise ? context.getString(R.string.wifi_security_short_wep) :
42275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    context.getString(R.string.wifi_security_wep);
42375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            case SECURITY_NONE:
42475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            default:
42575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                return concise ? "" : context.getString(R.string.wifi_security_none);
42675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
42775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
42875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
42975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getSsidStr() {
43075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return ssid;
43175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
43275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
43375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getBssid() {
43475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return bssid;
43575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
43675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
43775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public CharSequence getSsid() {
43875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        final SpannableString str = new SpannableString(ssid);
43975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        str.setSpan(new TtsSpan.TelephoneBuilder(ssid).build(), 0, ssid.length(),
44075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
44175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return str;
44275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
44375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
44475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getConfigName() {
44575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        if (mConfig != null && mConfig.isPasspoint()) {
44675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            return mConfig.providerFriendlyName;
44775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        } else {
44875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            return ssid;
44975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
4505f71e35da153d194d805e030ab38935599e065d2Jean-Michel Trivi    }
45175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
45275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public DetailedState getDetailedState() {
45375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        if (mNetworkInfo != null) {
45475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            return mNetworkInfo.getDetailedState();
45575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
45675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        Log.w(TAG, "NetworkInfo is null, cannot return detailed state");
45775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return null;
45875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
45975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
46075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getSavedNetworkSummary() {
46175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        WifiConfiguration config = mConfig;
46275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        if (config != null) {
46375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            PackageManager pm = mContext.getPackageManager();
46475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            String systemName = pm.getNameForUid(android.os.Process.SYSTEM_UID);
46575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            int userId = UserHandle.getUserId(config.creatorUid);
46675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            ApplicationInfo appInfo = null;
46775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            if (config.creatorName != null && config.creatorName.equals(systemName)) {
46875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                appInfo = mContext.getApplicationInfo();
46975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            } else {
47075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                try {
47175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    IPackageManager ipm = AppGlobals.getPackageManager();
47275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    appInfo = ipm.getApplicationInfo(config.creatorName, 0 /* flags */, userId);
47375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                } catch (RemoteException rex) {
47475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                }
47575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            }
47675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            if (appInfo != null &&
47775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    !appInfo.packageName.equals(mContext.getString(R.string.settings_package)) &&
47875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    !appInfo.packageName.equals(
47975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                    mContext.getString(R.string.certinstaller_package))) {
48075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                return mContext.getString(R.string.saved_network, appInfo.loadLabel(pm));
48175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            }
48275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
48375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return "";
48475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
48575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
48675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getSummary() {
48775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return getSettingsSummary(mConfig);
48875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
48975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
49075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    public String getSettingsSummary() {
49175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        return getSettingsSummary(mConfig);
49275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
49375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
49475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    private String getSettingsSummary(WifiConfiguration config) {
49575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        // Update to new summary
496f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi        StringBuilder summary = new StringBuilder();
497f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi
498f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi        if (isActive() && config != null && config.isPasspoint()) {
499f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi            // This is the active connection on passpoint
500f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi            summary.append(getSummary(mContext, getDetailedState(),
501f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi                    false, config.providerFriendlyName));
502f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi        } else if (isActive()) {
503f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi            // This is the active connection on non-passpoint network
50413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(getSummary(mContext, getDetailedState(),
50513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    mInfo != null && mInfo.isEphemeral()));
50613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (config != null && config.isPasspoint()) {
50713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            String format = mContext.getString(R.string.available_via_passpoint);
50813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(String.format(format, config.providerFriendlyName));
50913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (config != null && config.hasNoInternetAccess()) {
51013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            int messageID = config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled()
51113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    ? R.string.wifi_no_internet_no_reconnect
51213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    : R.string.wifi_no_internet;
51313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(mContext.getString(messageID));
51413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) {
51513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            WifiConfiguration.NetworkSelectionStatus networkStatus =
51613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    config.getNetworkSelectionStatus();
51713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            switch (networkStatus.getNetworkSelectionDisableReason()) {
51813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
51913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
52013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    break;
52113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
52213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
52313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
52413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    break;
52513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                case WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION:
52613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append(mContext.getString(R.string.wifi_disabled_generic));
52713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    break;
52813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
52913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) {
53013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider));
53113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range
53213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(mContext.getString(R.string.wifi_not_in_range));
53313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else { // In range, not disabled.
53413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (config != null) { // Is saved network
53513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                summary.append(mContext.getString(R.string.wifi_remembered));
53613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
53713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
53813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
53913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (WifiTracker.sVerboseLogging > 0) {
54013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // Add RSSI/band information for this config, what was seen up to 6 seconds ago
54113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // verbose WiFi Logging is only turned on thru developers settings
54213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (mInfo != null && mNetworkInfo != null) { // This is the active connection
54313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                summary.append(" f=" + Integer.toString(mInfo.getFrequency()));
54413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
54513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            summary.append(" " + getVisibilityStatus());
54613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) {
54713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                summary.append(" (" + config.getNetworkSelectionStatus().getNetworkStatusString());
54813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                if (config.getNetworkSelectionStatus().getDisableTime() > 0) {
54913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    long now = System.currentTimeMillis();
55013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    long diff = (now - config.getNetworkSelectionStatus().getDisableTime()) / 1000;
55113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    long sec = diff%60; //seconds
55213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    long min = (diff/60)%60; //minutes
55313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    long hour = (min/60)%60; //hours
55413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append(", ");
55513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    if (hour > 0) summary.append(Long.toString(hour) + "h ");
55613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append( Long.toString(min) + "m ");
55713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    summary.append( Long.toString(sec) + "s ");
55813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                }
55913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                summary.append(")");
56013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
56113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
56213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (config != null) {
56313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                WifiConfiguration.NetworkSelectionStatus networkStatus =
56413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                        config.getNetworkSelectionStatus();
56513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
56613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                        index < WifiConfiguration.NetworkSelectionStatus
56713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                        .NETWORK_SELECTION_DISABLED_MAX; index++) {
56813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    if (networkStatus.getDisableReasonCounter(index) != 0) {
56913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                        summary.append(" " + WifiConfiguration.NetworkSelectionStatus
57013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                                .getNetworkDisableReasonString(index) + "="
57113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                                + networkStatus.getDisableReasonCounter(index));
57213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    }
57313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                }
57413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
57513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
57613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        return summary.toString();
57713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
57813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
57913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    /**
58013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * Returns the visibility status of the WifiConfiguration.
58113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     *
58213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * @return autojoin debugging information
58313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * TODO: use a string formatter
58413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"]
58513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     * For instance [-40,5/-30,2]
58613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     */
58713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private String getVisibilityStatus() {
58813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        StringBuilder visibility = new StringBuilder();
58913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        StringBuilder scans24GHz = null;
59013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        StringBuilder scans5GHz = null;
59113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        String bssid = null;
59213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
59313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        long now = System.currentTimeMillis();
59413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
59513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (mInfo != null) {
59613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            bssid = mInfo.getBSSID();
59713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (bssid != null) {
59813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                visibility.append(" ").append(bssid);
59913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
60013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(" rssi=").append(mInfo.getRssi());
60113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(" ");
60213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(" score=").append(mInfo.score);
60313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(" rankingScore=").append(getRankingScore());
60413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(" badge=").append(getBadge());
60513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate));
60613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(String.format("%.1f,", mInfo.txRetriesRate));
60713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(String.format("%.1f ", mInfo.txBadRate));
60813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            visibility.append(String.format("rx=%.1f", mInfo.rxSuccessRate));
60913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
61013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
61113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int rssi5 = WifiConfiguration.INVALID_RSSI;
61213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int rssi24 = WifiConfiguration.INVALID_RSSI;
61313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int num5 = 0;
61413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int num24 = 0;
61513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int numBlackListed = 0;
61613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int n24 = 0; // Number scan results we included in the string
61713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        int n5 = 0; // Number scan results we included in the string
61813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        evictOldScanResults();
61913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // TODO: sort list by RSSI or age
62013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        for (ScanResult result : mScanResultCache.values()) {
62113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
62213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (result.frequency >= LOWER_FREQ_5GHZ
62313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    && result.frequency <= HIGHER_FREQ_5GHZ) {
62413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                // Strictly speaking: [4915, 5825]
62513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                // number of known BSSID on 5GHz band
62613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                num5 = num5 + 1;
62713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            } else if (result.frequency >= LOWER_FREQ_24GHZ
6288a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi                    && result.frequency <= HIGHER_FREQ_24GHZ) {
6298a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi                // Strictly speaking: [2412, 2482]
6308a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi                // number of known BSSID on 2.4Ghz band
6318a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi                num24 = num24 + 1;
6328a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi            }
6338a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
6343ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
6353ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            if (result.frequency >= LOWER_FREQ_5GHZ
6363ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    && result.frequency <= HIGHER_FREQ_5GHZ) {
6373ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                if (result.level > rssi5) {
6383ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    rssi5 = result.level;
6393ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                }
640de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                if (n5 < 4) {
6413ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    if (scans5GHz == null) scans5GHz = new StringBuilder();
64237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi                    scans5GHz.append(" \n{").append(result.BSSID);
643de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    if (bssid != null && result.BSSID.equals(bssid)) scans5GHz.append("*");
644de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    scans5GHz.append("=").append(result.frequency);
645de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    scans5GHz.append(",").append(result.level);
646f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                    scans5GHz.append("}");
647de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                    n5++;
64824430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi                }
649de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            } else if (result.frequency >= LOWER_FREQ_24GHZ
650f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi                    && result.frequency <= HIGHER_FREQ_24GHZ) {
65168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi                if (result.level > rssi24) {
6523ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    rssi24 = result.level;
653581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi                }
654f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                if (n24 < 4) {
655f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    if (scans24GHz == null) scans24GHz = new StringBuilder();
6563ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    scans24GHz.append(" \n{").append(result.BSSID);
6573ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    if (bssid != null && result.BSSID.equals(bssid)) scans24GHz.append("*");
6583ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    scans24GHz.append("=").append(result.frequency);
6593ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    scans24GHz.append(",").append(result.level);
6603ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                    scans24GHz.append("}");
661f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    n24++;
662f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                }
663f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            }
664f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        }
665f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        visibility.append(" [");
666f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        if (num24 > 0) {
667f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            visibility.append("(").append(num24).append(")");
668f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            if (n24 <= 4) {
669f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                if (scans24GHz != null) {
670f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    visibility.append(scans24GHz.toString());
671f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                }
672f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            } else {
673f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                visibility.append("max=").append(rssi24);
674f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                if (scans24GHz != null) {
675f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    visibility.append(",").append(scans24GHz.toString());
676f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                }
677f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            }
678f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        }
679f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        visibility.append(";");
680f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        if (num5 > 0) {
681f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            visibility.append("(").append(num5).append(")");
682f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            if (n5 <= 4) {
683f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                if (scans5GHz != null) {
684f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    visibility.append(scans5GHz.toString());
685f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                }
686f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            } else {
687f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                visibility.append("max=").append(rssi5);
688f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                if (scans5GHz != null) {
689f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                    visibility.append(",").append(scans5GHz.toString());
690f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi                }
691f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            }
6923ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        }
693f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi        if (numBlackListed > 0)
694f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            visibility.append("!").append(numBlackListed);
695b2aeb0f1009555181dabb944fe05901cb6e6f632Jean-Michel Trivi        visibility.append("]");
696581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi
697581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi        return visibility.toString();
698581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi    }
699581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi
700581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi    /**
701581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi     * Return whether this is the active connection.
702581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi     * For ephemeral connections (networkId is invalid), this returns false if the network is
703581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi     * disconnected.
704581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi     */
705581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi    public boolean isActive() {
70613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        return mNetworkInfo != null &&
70713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                (networkId != WifiConfiguration.INVALID_NETWORK_ID ||
70813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                 mNetworkInfo.getState() != State.DISCONNECTED);
709e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    }
710581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi
71124430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi    public boolean isConnectable() {
7123ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        return getLevel() != -1 && getDetailedState() == null;
713f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi    }
714f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
7153ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi    public boolean isEphemeral() {
7163ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        return mInfo != null && mInfo.isEphemeral() &&
71713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
71813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
7193ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
72013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    public boolean isPasspoint() {
7215d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        return mConfig != null && mConfig.isPasspoint();
72296ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten    }
72396ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten
72496ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten    /**
72596ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten     * Return whether the given {@link WifiInfo} is for this access point.
7265d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi     * If the current AP does not have a network Id then the config is used to
7275d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi     * match based on SSID and security.
7285d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi     */
7295d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi    private boolean isInfoForThisAccessPoint(WifiConfiguration config, WifiInfo info) {
7305d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        if (isPasspoint() == false && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
7315d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi            return networkId == info.getNetworkId();
7325d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        } else if (config != null) {
73396ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten            return matches(config);
7345d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        }
7355d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        else {
7365d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi            // Might be an ephemeral connection with no WifiConfiguration. Try matching on SSID.
7375d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi            // (Note that we only do this if the WifiConfiguration explicitly equals INVALID).
7385d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi            // TODO: Handle hex string SSIDs.
7395d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi            return ssid.equals(removeDoubleQuotes(info.getSSID()));
7405d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        }
7415d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi    }
7425d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi
7435d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi    public boolean isSaved() {
7445d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi        return networkId != WifiConfiguration.INVALID_NETWORK_ID;
74513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
74613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
7475d9a1aa19d218c9e4ed22d4d773471c01362442eJean-Michel Trivi    public Object getTag() {
74813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        return mTag;
749a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
750a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
751a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    public void setTag(Object tag) {
752ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        mTag = tag;
753ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi    }
7548a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
755ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi    /**
756ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi     * Generate and save a default wifiConfiguration with common values.
757ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi     * Can only be called for unsecured networks.
758ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi     */
759ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi    public void generateOpenNetworkConfig() {
760ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (security != SECURITY_NONE)
761ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            throw new IllegalStateException();
762ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (mConfig != null)
7638a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi            return;
764ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        mConfig = new WifiConfiguration();
765ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        mConfig.SSID = AccessPoint.convertToQuotedString(ssid);
766ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        mConfig.allowedKeyManagement.set(KeyMgmt.NONE);
767ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi    }
768ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi
76913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    void loadConfig(WifiConfiguration config) {
77013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (config.isPasspoint())
771de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ssid = config.providerFriendlyName;
77213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        else
773a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
774a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
775a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        bssid = config.BSSID;
77606a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        security = getSecurity(config);
777de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        networkId = config.networkId;
7788a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        mConfig = config;
779de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
7808a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
781de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    private void initWithScanResult(ScanResult result) {
782de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        ssid = result.SSID;
783de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        bssid = result.BSSID;
784de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        security = getSecurity(result);
7854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (security == SECURITY_PSK)
786de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            pskType = getPskType(result);
7874614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        mRssi = result.level;
7884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        mSeen = result.timestamp;
7894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
7904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
791de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    public void saveWifiState(Bundle savedState) {
7924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        if (ssid != null) savedState.putString(KEY_SSID, getSsidStr());
7934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        savedState.putInt(KEY_SECURITY, security);
794de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        savedState.putInt(KEY_PSKTYPE, pskType);
7958a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        if (mConfig != null) savedState.putParcelable(KEY_CONFIG, mConfig);
7968a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        savedState.putParcelable(KEY_WIFIINFO, mInfo);
797de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        evictOldScanResults();
79806a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        savedState.putParcelableArrayList(KEY_SCANRESULTCACHE,
799de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi                new ArrayList<ScanResult>(mScanResultCache.values()));
80006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (mNetworkInfo != null) {
80113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            savedState.putParcelable(KEY_NETWORKINFO, mNetworkInfo);
80213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
803de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
80413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
805fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    public void setListener(AccessPointListener listener) {
80624430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi        mAccessPointListener = listener;
8073ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi    }
8083ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
80913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    boolean update(ScanResult result) {
81013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (matches(result)) {
811de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            /* Add or update the scan result for the BSSID */
8126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            mScanResultCache.put(result.BSSID, result);
8136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
8146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            int oldLevel = getLevel();
815a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            int oldRssi = getRssi();
816a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            mSeen = getSeen();
81775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            mRssi = (getRssi() + oldRssi)/2;
818a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            int newLevel = getLevel();
819d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi
820c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            if (newLevel > 0 && newLevel != oldLevel && mAccessPointListener != null) {
82113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                mAccessPointListener.onLevelChanged(this);
82213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
82313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // This flag only comes from scans, is not easily saved in config
824c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            if (security == SECURITY_PSK) {
825c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                pskType = getPskType(result);
826c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
82713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
82813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (mAccessPointListener != null) {
8294b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                mAccessPointListener.onAccessPointChanged(this);
83013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
83113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
83213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return true;
83313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
83413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        return false;
83513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
83613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
837c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
838c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        boolean reorder = false;
83901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        if (info != null && isInfoForThisAccessPoint(config, info)) {
84001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten            reorder = (mInfo == null);
84101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten            mRssi = info.getRssi();
842c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            mInfo = info;
8434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            mNetworkInfo = networkInfo;
844c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            if (mAccessPointListener != null) {
84513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                mAccessPointListener.onAccessPointChanged(this);
846a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi            }
847c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        } else if (mInfo != null) {
848c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            reorder = true;
849c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            mInfo = null;
850c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            mNetworkInfo = null;
851c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            if (mAccessPointListener != null) {
852c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                mAccessPointListener.onAccessPointChanged(this);
853c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
8544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        }
8554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        return reorder;
8564b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
857c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
858c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    void update(WifiConfiguration config) {
859c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        mConfig = config;
860c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        networkId = config.networkId;
861c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (mAccessPointListener != null) {
862c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            mAccessPointListener.onAccessPointChanged(this);
863c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
864c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
865c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
866c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    void setRssi(int rssi) {
867c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        mRssi = rssi;
8680d26ec3e2bb632d611ec3c752266aeb90f31bcf9Glenn Kasten    }
869c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
8704b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    int getRankingScore() {
8714b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        return mRankingScore;
8724b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
8734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
874c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    int getBadge() {
87549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        return mBadge;
87649e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    }
877c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
878c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    public static String getSummary(Context context, String ssid, DetailedState state,
879c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            boolean isEphemeral, String passpointProvider) {
880c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (state == DetailedState.CONNECTED && ssid == null) {
881337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            if (TextUtils.isEmpty(passpointProvider) == false) {
8820d26ec3e2bb632d611ec3c752266aeb90f31bcf9Glenn Kasten                // Special case for connected + passpoint networks.
8830d26ec3e2bb632d611ec3c752266aeb90f31bcf9Glenn Kasten                String format = context.getString(R.string.connected_via_passpoint);
884c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return String.format(format, passpointProvider);
885c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } else if (isEphemeral) {
886c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                // Special case for connected + ephemeral networks.
887c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return context.getString(R.string.connected_via_wfa);
8884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            }
8894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        }
890c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
891c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Case when there is wifi connected without internet connectivity.
892c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        final ConnectivityManager cm = (ConnectivityManager)
893c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                context.getSystemService(Context.CONNECTIVITY_SERVICE);
8940d26ec3e2bb632d611ec3c752266aeb90f31bcf9Glenn Kasten        if (state == DetailedState.CONNECTED) {
895c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            IWifiManager wifiManager = IWifiManager.Stub.asInterface(
896c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                    ServiceManager.getService(Context.WIFI_SERVICE));
897c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            NetworkCapabilities nc = null;
898c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
899337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            try {
900337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten                nc = cm.getNetworkCapabilities(wifiManager.getCurrentNetwork());
901c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } catch (RemoteException e) {}
902c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
903c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            if (nc != null) {
904c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                if (nc.hasCapability(nc.NET_CAPABILITY_CAPTIVE_PORTAL)) {
905c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                    return context.getString(
906c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                        com.android.internal.R.string.network_available_sign_in);
907c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                } else if (!nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
908c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                    return context.getString(R.string.wifi_connected_no_internet);
909c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                }
910c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
9114b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        }
912337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        if (state == null) {
9134b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            Log.w(TAG, "state is null, returning empty summary");
9144b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            return "";
915c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
916337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        String[] formats = context.getResources().getStringArray((ssid == null)
917337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten                ? R.array.wifi_status : R.array.wifi_status_with_ssid);
918c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        int index = state.ordinal();
919c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
920c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        if (index >= formats.length || formats[index].length() == 0) {
921c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return "";
922c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        }
9238b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten        return String.format(formats[index], ssid);
92401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    }
92549e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten
926c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    public static String getSummary(Context context, DetailedState state, boolean isEphemeral) {
927c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return getSummary(context, null, state, isEphemeral, null);
9288b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten    }
9298b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten
9308b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten    public static String getSummary(Context context, DetailedState state, boolean isEphemeral,
93113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            String passpointProvider) {
93201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        return getSummary(context, null, state, isEphemeral, passpointProvider);
933c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
934c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
9356fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    public static String convertToQuotedString(String string) {
9366fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        return "\"" + string + "\"";
9376fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    }
938989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi
939989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    private static int getPskType(ScanResult result) {
940989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        boolean wpa = result.capabilities.contains("WPA-PSK");
941989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        boolean wpa2 = result.capabilities.contains("WPA2-PSK");
942989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        if (wpa2 && wpa) {
94313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return PSK_WPA_WPA2;
944989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } else if (wpa2) {
945989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return PSK_WPA2;
946989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } else if (wpa) {
9478b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            return PSK_WPA;
948337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        } else {
94949e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            Log.w(TAG, "Received abnormal flag string: " + result.capabilities);
950989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return PSK_UNKNOWN;
95113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
95213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
95313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
95413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    private static int getSecurity(ScanResult result) {
95513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (result.capabilities.contains("WEP")) {
95613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return SECURITY_WEP;
9576fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } else if (result.capabilities.contains("PSK")) {
9586fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi            return SECURITY_PSK;
9596fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } else if (result.capabilities.contains("EAP")) {
960989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SECURITY_EAP;
961989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
962989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        return SECURITY_NONE;
963989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    }
96413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
965989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    static int getSecurity(WifiConfiguration config) {
966989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
967989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SECURITY_PSK;
968989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
969a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten        if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
970989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
9718b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            return SECURITY_EAP;
972337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        }
97349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten        return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
974989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    }
9758b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten
9768b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten    public static String securityToString(int security, int pskType) {
9778b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten        if (security == SECURITY_WEP) {
9788b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            return "WEP";
97913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else if (security == SECURITY_PSK) {
98013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            if (pskType == PSK_WPA) {
98113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                return "WPA";
98213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            } else if (pskType == PSK_WPA2) {
98313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                return "WPA2";
984989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            } else if (pskType == PSK_WPA_WPA2) {
985989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                return "WPA_WPA2";
986989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            }
987fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            return "PSK";
988fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi        } else if (security == SECURITY_EAP) {
989d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            return "EAP";
990d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
991d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        return "NONE";
992fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
993d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
994d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    static String removeDoubleQuotes(String string) {
995d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if (TextUtils.isEmpty(string)) {
996d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            return "";
997d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
998d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        int length = string.length();
999d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if ((length > 1) && (string.charAt(0) == '"')
1000fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi                && (string.charAt(length - 1) == '"')) {
1001d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            return string.substring(1, length - 1);
1002d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
1003d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        return string;
1004d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
1005d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
1006d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    public interface AccessPointListener {
1007d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        void onAccessPointChanged(AccessPoint accessPoint);
1008fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        void onLevelChanged(AccessPoint accessPoint);
1009c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
1010c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
1011c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi