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