1c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein/*
2c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Copyright (C) 2015 The Android Open Source Project
3c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein *
4c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Licensed under the Apache License, Version 2.0 (the "License");
5c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * you may not use this file except in compliance with the License.
6c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * You may obtain a copy of the License at
7c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein *
8c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein *      http://www.apache.org/licenses/LICENSE-2.0
9c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein *
10c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Unless required by applicable law or agreed to in writing, software
11c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * distributed under the License is distributed on an "AS IS" BASIS,
12c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * See the License for the specific language governing permissions and
14c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * limitations under the License.
15c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */
164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandepackage com.android.server.wifi;
184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.ScanResult;
204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport android.net.wifi.WifiConfiguration;
21e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalleimport android.os.SystemClock;
22c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silbersteinimport android.util.Log;
234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.ArrayList;
254d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collection;
264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Collections;
274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpandeimport java.util.Comparator;
2822b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Piusimport java.util.HashMap;
294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
30c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein/**
31c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein * Maps BSSIDs to their individual ScanDetails for a given WifiConfiguration.
32c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein */
33c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silbersteinpublic class ScanDetailCache {
348eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande
358eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande    private static final String TAG = "ScanDetailCache";
36c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein    private static final boolean DBG = false;
378eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande
3822b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    private final WifiConfiguration mConfig;
3922b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    private final int mMaxSize;
4022b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    private final int mTrimSize;
4122b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    private final HashMap<String, ScanDetail> mMap;
42c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein
4322b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    /**
4422b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * Scan Detail cache associated with each configured network.
4522b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     *
4622b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * The cache size is trimmed down to |trimSize| once it crosses the provided |maxSize|.
4722b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * Since this operation is relatively expensive, ensure that |maxSize| and |trimSize| are not
4822b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * too close to each other. |trimSize| should always be <= |maxSize|.
4922b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     *
5022b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * @param config   WifiConfiguration object corresponding to the network.
5122b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * @param maxSize  Max size desired for the cache.
5222b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * @param trimSize Size to trim the cache down to once it reaches |maxSize|.
5322b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     */
5422b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    ScanDetailCache(WifiConfiguration config, int maxSize, int trimSize) {
554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mConfig = config;
5622b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        mMaxSize = maxSize;
5722b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        mTrimSize = trimSize;
5822b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        mMap = new HashMap(16, 0.75f);
594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    void put(ScanDetail scanDetail) {
6222b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        // First check if we have reached |maxSize|. if yes, trim it down to |trimSize|.
6322b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        if (mMap.size() >= mMaxSize) {
6422b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius            trim();
6522b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        }
66a547460e835d6dfde84eda72df470846d11ba807Vinit Deshpande
674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mMap.put(scanDetail.getBSSIDString(), scanDetail);
684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanResult get(String bssid) {
714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ScanDetail scanDetail = getScanDetail(bssid);
724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return scanDetail == null ? null : scanDetail.getScanResult();
734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    ScanDetail getScanDetail(String bssid) {
764d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.get(bssid);
774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
784d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    void remove(String bssid) {
804d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        mMap.remove(bssid);
814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
824d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    int size() {
844d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.size();
854d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
864d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    boolean isEmpty() {
884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return size() == 0;
894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    Collection<String> keySet() {
924d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.keySet();
934d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
944d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
954d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    Collection<ScanDetail> values() {
964d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return mMap.values();
974d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
984d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
99c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein    /**
10022b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * Method to reduce the cache to |mTrimSize| size by removing the oldest entries.
10122b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius     * TODO: Investigate if this method can be further optimized.
102c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     */
10322b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius    private void trim() {
1044d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        int currentSize = mMap.size();
10522b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        if (currentSize < mTrimSize) {
1064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            return; // Nothing to trim
1074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values());
1094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() != 0) {
1104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            // Sort by descending timestamp
1114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            Collections.sort(list, new Comparator() {
1124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                public int compare(Object o1, Object o2) {
1134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanDetail a = (ScanDetail) o1;
1144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ScanDetail b = (ScanDetail) o2;
1154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.getSeen() > b.getSeen()) {
1164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.getSeen() < b.getSeen()) {
1194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    return a.getBSSIDString().compareTo(b.getBSSIDString());
1224d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
1234d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            });
1244d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
12522b5eca14a99c2bbeeae8361c665923ce71e1603Roshan Pius        for (int i = 0; i < currentSize - mTrimSize; i++) {
1264d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            // Remove oldest results from scan cache
1274d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            ScanDetail result = list.get(i);
1284d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            mMap.remove(result.getBSSIDString());
1294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1304d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
1314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    /* @hide */
1334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    private ArrayList<ScanDetail> sort() {
1344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values());
1354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() != 0) {
1364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            Collections.sort(list, new Comparator() {
1374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                public int compare(Object o1, Object o2) {
138c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                    ScanResult a = ((ScanDetail) o1).getScanResult();
139c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                    ScanResult b = ((ScanDetail) o2).getScanResult();
1404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.numIpConfigFailures > b.numIpConfigFailures) {
1414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1424d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.numIpConfigFailures < b.numIpConfigFailures) {
1444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.seen > b.seen) {
1474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.seen < b.seen) {
1504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.level > b.level) {
1534d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return -1;
1544d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1554d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    if (a.level < b.level) {
1564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                        return 1;
1574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    }
1584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    return a.BSSID.compareTo(b.BSSID);
1594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
1604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            });
1614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
1624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return list;
1634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
1644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
165c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein    /**
166c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * Method to get cached scan results that are less than 'age' old.
167c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     *
168c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * @param age long Time window of desired results.
169c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * @return WifiConfiguration.Visibility matches in the given visibility
170c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     */
1714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public WifiConfiguration.Visibility getVisibilityByRssi(long age) {
1724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        WifiConfiguration.Visibility status = new WifiConfiguration.Visibility();
1734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        long now_ms = System.currentTimeMillis();
175cb59612d2af82044ee74e8f595c9a40498db14b4Pierre Vandwalle        long now_elapsed_ms = SystemClock.elapsedRealtime();
176c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein        for (ScanDetail scanDetail : values()) {
1774d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            ScanResult result = scanDetail.getScanResult();
178c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein            if (scanDetail.getSeen() == 0) {
1794d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                continue;
180c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein            }
1814d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
1824d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (result.is5GHz()) {
1834d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //strictly speaking: [4915, 5825]
1844d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //number of known BSSID on 5GHz band
1854d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                status.num5 = status.num5 + 1;
1864d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            } else if (result.is24GHz()) {
1874d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //strictly speaking: [2412, 2482]
1884d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                //number of known BSSID on 2.4Ghz band
1894d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                status.num24 = status.num24 + 1;
1904d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
1914d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
192e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle            if (result.timestamp != 0) {
193e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle                if (DBG) {
194e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle                    Log.e("getVisibilityByRssi", " considering " + result.SSID + " " + result.BSSID
195c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                            + " elapsed=" + now_elapsed_ms + " timestamp=" + result.timestamp
196c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                            + " age = " + age);
197e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle                }
198c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                if ((now_elapsed_ms - (result.timestamp / 1000)) > age) continue;
199e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle            } else {
200c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                // This checks the time at which we have received the scan result from supplicant
201e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle                if ((now_ms - result.seen) > age) continue;
202e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle            }
2034d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2044d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            if (result.is5GHz()) {
2054d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi5) {
2064d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi5 = result.level;
2074d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age5 = result.seen;
2084d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID5 = result.BSSID;
2094d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2104d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            } else if (result.is24GHz()) {
2114d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.level > status.rssi24) {
2124d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.rssi24 = result.level;
2134d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.age24 = result.seen;
2144d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    status.BSSID24 = result.BSSID;
2154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2164d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
2174d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
2184d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2194d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return status;
2204d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2214d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
222c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein    /**
223c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * Method to get scan matches for the desired time window.  Returns matches by passpoint time if
224c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * the WifiConfiguration is passpoint.
225c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     *
226c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * @param age long desired time for matches.
227c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     * @return WifiConfiguration.Visibility matches in the given visibility
228c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein     */
2294d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public WifiConfiguration.Visibility getVisibility(long age) {
23001282351e9b99a4929a6f30ac9813c2567c7f829Peter Qiu        return getVisibilityByRssi(age);
2314d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2324d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2334d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2344d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    @Override
2354d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    public String toString() {
2364d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        StringBuilder sbuf = new StringBuilder();
2374d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        sbuf.append("Scan Cache:  ").append('\n');
2384d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2394d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        ArrayList<ScanDetail> list = sort();
2404d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        long now_ms = System.currentTimeMillis();
2414d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        if (list.size() > 0) {
2424d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            for (ScanDetail scanDetail : list) {
2434d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                ScanResult result = scanDetail.getScanResult();
2444d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long milli = now_ms - scanDetail.getSeen();
2454d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageSec = 0;
2464d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageMin = 0;
2474d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageHour = 0;
2484d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageMilli = 0;
2494d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                long ageDay = 0;
2504d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (now_ms > scanDetail.getSeen() && scanDetail.getSeen() > 0) {
2514d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageMilli = milli % 1000;
2524d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    ageSec   = (milli / 1000) % 60;
253c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                    ageMin   = (milli / (60 * 1000)) % 60;
254c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                    ageHour  = (milli / (60 * 60 * 1000)) % 24;
255c14fe5d3f6a84d8a0788956e15f9102a3aa354a6Rebecca Silberstein                    ageDay   = (milli / (24 * 60 * 60 * 1000));
2564d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2574d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append("{").append(result.BSSID).append(",").append(result.frequency);
2584d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append(",").append(String.format("%3d", result.level));
2594d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (ageSec > 0 || ageMilli > 0) {
2604d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(String.format(",%4d.%02d.%02d.%02d.%03dms", ageDay,
2614d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                            ageHour, ageMin, ageSec, ageMilli));
2624d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2634d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                if (result.numIpConfigFailures > 0) {
2644d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(",ipfail=");
2654d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                    sbuf.append(result.numIpConfigFailures);
2664d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                }
2674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande                sbuf.append("} ");
2684d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            }
2694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande            sbuf.append('\n');
2704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        }
2714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2724d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande        return sbuf.toString();
2734d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande    }
2744d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande
2754d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande}
276