diff options
4 files changed, 325 insertions, 180 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index 58f122619cd6..754b88117613 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -622,6 +622,14 @@ public class AccessPoint implements Comparable<AccessPoint> { return mRssi; } + public ConcurrentHashMap<String, ScanResult> getScanResults() { + return mScanResultCache; + } + + public Map<String, TimestampedScoredNetwork> getScoredNetworkCache() { + return mScoredNetworkCache; + } + /** * Updates {@link #mRssi}. * @@ -845,41 +853,8 @@ public class AccessPoint implements Comparable<AccessPoint> { } if (WifiTracker.sVerboseLogging) { - // Add RSSI/band information for this config, what was seen up to 6 seconds ago - // verbose WiFi Logging is only turned on thru developers settings - if (isActive() && mInfo != null) { - summary.append(" f=" + Integer.toString(mInfo.getFrequency())); - } - summary.append(" " + getVisibilityStatus()); - if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) { - summary.append(" (" + config.getNetworkSelectionStatus().getNetworkStatusString()); - if (config.getNetworkSelectionStatus().getDisableTime() > 0) { - long now = System.currentTimeMillis(); - long diff = (now - config.getNetworkSelectionStatus().getDisableTime()) / 1000; - long sec = diff%60; //seconds - long min = (diff/60)%60; //minutes - long hour = (min/60)%60; //hours - summary.append(", "); - if (hour > 0) summary.append(Long.toString(hour) + "h "); - summary.append( Long.toString(min) + "m "); - summary.append( Long.toString(sec) + "s "); - } - summary.append(")"); - } - - if (config != null) { - WifiConfiguration.NetworkSelectionStatus networkStatus = - config.getNetworkSelectionStatus(); - for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE; - index < WifiConfiguration.NetworkSelectionStatus - .NETWORK_SELECTION_DISABLED_MAX; index++) { - if (networkStatus.getDisableReasonCounter(index) != 0) { - summary.append(" " + WifiConfiguration.NetworkSelectionStatus - .getNetworkDisableReasonString(index) + "=" - + networkStatus.getDisableReasonCounter(index)); - } - } - } + evictOldScanResults(); + summary.append(WifiUtils.buildLoggingSummary(this, config)); } // If Speed label and summary are both present, use the preference combination to combine @@ -897,127 +872,6 @@ public class AccessPoint implements Comparable<AccessPoint> { } /** - * Returns the visibility status of the WifiConfiguration. - * - * @return autojoin debugging information - * TODO: use a string formatter - * ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"] - * For instance [-40,5/-30,2] - */ - private String getVisibilityStatus() { - StringBuilder visibility = new StringBuilder(); - StringBuilder scans24GHz = new StringBuilder(); - StringBuilder scans5GHz = new StringBuilder(); - String bssid = null; - - long now = System.currentTimeMillis(); - - if (isActive() && mInfo != null) { - bssid = mInfo.getBSSID(); - if (bssid != null) { - visibility.append(" ").append(bssid); - } - visibility.append(" rssi=").append(mInfo.getRssi()); - visibility.append(" "); - visibility.append(" score=").append(mInfo.score); - if (mSpeed != Speed.NONE) { - visibility.append(" speed=").append(getSpeedLabel()); - } - visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate)); - visibility.append(String.format("%.1f,", mInfo.txRetriesRate)); - visibility.append(String.format("%.1f ", mInfo.txBadRate)); - visibility.append(String.format("rx=%.1f", mInfo.rxSuccessRate)); - } - - int maxRssi5 = WifiConfiguration.INVALID_RSSI; - int maxRssi24 = WifiConfiguration.INVALID_RSSI; - final int maxDisplayedScans = 4; - int num5 = 0; // number of scanned BSSID on 5GHz band - int num24 = 0; // number of scanned BSSID on 2.4Ghz band - int numBlackListed = 0; - evictOldScanResults(); - - // TODO: sort list by RSSI or age - long nowMs = SystemClock.elapsedRealtime(); - for (ScanResult result : mScanResultCache.values()) { - if (result.frequency >= LOWER_FREQ_5GHZ - && result.frequency <= HIGHER_FREQ_5GHZ) { - // Strictly speaking: [4915, 5825] - num5++; - - if (result.level > maxRssi5) { - maxRssi5 = result.level; - } - if (num5 <= maxDisplayedScans) { - scans5GHz.append(verboseScanResultSummary(result, bssid, nowMs)); - } - } else if (result.frequency >= LOWER_FREQ_24GHZ - && result.frequency <= HIGHER_FREQ_24GHZ) { - // Strictly speaking: [2412, 2482] - num24++; - - if (result.level > maxRssi24) { - maxRssi24 = result.level; - } - if (num24 <= maxDisplayedScans) { - scans24GHz.append(verboseScanResultSummary(result, bssid, nowMs)); - } - } - } - visibility.append(" ["); - if (num24 > 0) { - visibility.append("(").append(num24).append(")"); - if (num24 > maxDisplayedScans) { - visibility.append("max=").append(maxRssi24).append(","); - } - visibility.append(scans24GHz.toString()); - } - visibility.append(";"); - if (num5 > 0) { - visibility.append("(").append(num5).append(")"); - if (num5 > maxDisplayedScans) { - visibility.append("max=").append(maxRssi5).append(","); - } - visibility.append(scans5GHz.toString()); - } - if (numBlackListed > 0) - visibility.append("!").append(numBlackListed); - visibility.append("]"); - - return visibility.toString(); - } - - @VisibleForTesting - /* package */ String verboseScanResultSummary(ScanResult result, String bssid, long nowMs) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(" \n{").append(result.BSSID); - if (result.BSSID.equals(bssid)) { - stringBuilder.append("*"); - } - stringBuilder.append("=").append(result.frequency); - stringBuilder.append(",").append(result.level); - int speed = getSpecificApSpeed(result); - if (speed != Speed.NONE) { - stringBuilder.append(",") - .append(getSpeedLabel(speed)); - } - int ageSeconds = (int) (nowMs - result.timestamp / 1000) / 1000; - stringBuilder.append(",").append(ageSeconds).append("s"); - stringBuilder.append("}"); - return stringBuilder.toString(); - } - - @Speed private int getSpecificApSpeed(ScanResult result) { - TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID); - if (timedScore == null) { - return Speed.NONE; - } - // For debugging purposes we may want to use mRssi rather than result.level as the average - // speed wil be determined by mRssi - return timedScore.getScore().calculateBadge(result.level); - } - - /** * Return whether this is the active connection. * For ephemeral connections (networkId is invalid), this returns false if the network is * disconnected. @@ -1275,7 +1129,7 @@ public class AccessPoint implements Comparable<AccessPoint> { } @Nullable - private String getSpeedLabel(@Speed int speed) { + String getSpeedLabel(@Speed int speed) { switch (speed) { case Speed.VERY_FAST: return mContext.getString(R.string.speed_label_very_fast); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java new file mode 100644 index 000000000000..932c6fd82c50 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.wifi; + +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.os.SystemClock; +import android.support.annotation.VisibleForTesting; + +import java.util.Map; + +public class WifiUtils { + + public static String buildLoggingSummary(AccessPoint accessPoint, WifiConfiguration config) { + final StringBuilder summary = new StringBuilder(); + final WifiInfo info = accessPoint.getInfo(); + // Add RSSI/band information for this config, what was seen up to 6 seconds ago + // verbose WiFi Logging is only turned on thru developers settings + if (accessPoint.isActive() && info != null) { + summary.append(" f=" + Integer.toString(info.getFrequency())); + } + summary.append(" " + getVisibilityStatus(accessPoint)); + if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) { + summary.append(" (" + config.getNetworkSelectionStatus().getNetworkStatusString()); + if (config.getNetworkSelectionStatus().getDisableTime() > 0) { + long now = System.currentTimeMillis(); + long diff = (now - config.getNetworkSelectionStatus().getDisableTime()) / 1000; + long sec = diff % 60; //seconds + long min = (diff / 60) % 60; //minutes + long hour = (min / 60) % 60; //hours + summary.append(", "); + if (hour > 0) summary.append(Long.toString(hour) + "h "); + summary.append(Long.toString(min) + "m "); + summary.append(Long.toString(sec) + "s "); + } + summary.append(")"); + } + + if (config != null) { + WifiConfiguration.NetworkSelectionStatus networkStatus = + config.getNetworkSelectionStatus(); + for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE; + index < WifiConfiguration.NetworkSelectionStatus + .NETWORK_SELECTION_DISABLED_MAX; index++) { + if (networkStatus.getDisableReasonCounter(index) != 0) { + summary.append(" " + WifiConfiguration.NetworkSelectionStatus + .getNetworkDisableReasonString(index) + "=" + + networkStatus.getDisableReasonCounter(index)); + } + } + } + + return summary.toString(); + } + + /** + * Returns the visibility status of the WifiConfiguration. + * + * @return autojoin debugging information + * TODO: use a string formatter + * ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"] + * For instance [-40,5/-30,2] + */ + private static String getVisibilityStatus(AccessPoint accessPoint) { + final WifiInfo info = accessPoint.getInfo(); + StringBuilder visibility = new StringBuilder(); + StringBuilder scans24GHz = new StringBuilder(); + StringBuilder scans5GHz = new StringBuilder(); + String bssid = null; + + if (accessPoint.isActive() && info != null) { + bssid = info.getBSSID(); + if (bssid != null) { + visibility.append(" ").append(bssid); + } + visibility.append(" rssi=").append(info.getRssi()); + visibility.append(" "); + visibility.append(" score=").append(info.score); + if (accessPoint.getSpeed() != AccessPoint.Speed.NONE) { + visibility.append(" speed=").append(accessPoint.getSpeedLabel()); + } + visibility.append(String.format(" tx=%.1f,", info.txSuccessRate)); + visibility.append(String.format("%.1f,", info.txRetriesRate)); + visibility.append(String.format("%.1f ", info.txBadRate)); + visibility.append(String.format("rx=%.1f", info.rxSuccessRate)); + } + + int maxRssi5 = WifiConfiguration.INVALID_RSSI; + int maxRssi24 = WifiConfiguration.INVALID_RSSI; + final int maxDisplayedScans = 4; + int num5 = 0; // number of scanned BSSID on 5GHz band + int num24 = 0; // number of scanned BSSID on 2.4Ghz band + int numBlackListed = 0; + + // TODO: sort list by RSSI or age + long nowMs = SystemClock.elapsedRealtime(); + for (ScanResult result : accessPoint.getScanResults().values()) { + if (result.frequency >= AccessPoint.LOWER_FREQ_5GHZ + && result.frequency <= AccessPoint.HIGHER_FREQ_5GHZ) { + // Strictly speaking: [4915, 5825] + num5++; + + if (result.level > maxRssi5) { + maxRssi5 = result.level; + } + if (num5 <= maxDisplayedScans) { + scans5GHz.append( + verboseScanResultSummary(accessPoint, result, bssid, + nowMs)); + } + } else if (result.frequency >= AccessPoint.LOWER_FREQ_24GHZ + && result.frequency <= AccessPoint.HIGHER_FREQ_24GHZ) { + // Strictly speaking: [2412, 2482] + num24++; + + if (result.level > maxRssi24) { + maxRssi24 = result.level; + } + if (num24 <= maxDisplayedScans) { + scans24GHz.append( + verboseScanResultSummary(accessPoint, result, bssid, + nowMs)); + } + } + } + visibility.append(" ["); + if (num24 > 0) { + visibility.append("(").append(num24).append(")"); + if (num24 > maxDisplayedScans) { + visibility.append("max=").append(maxRssi24).append(","); + } + visibility.append(scans24GHz.toString()); + } + visibility.append(";"); + if (num5 > 0) { + visibility.append("(").append(num5).append(")"); + if (num5 > maxDisplayedScans) { + visibility.append("max=").append(maxRssi5).append(","); + } + visibility.append(scans5GHz.toString()); + } + if (numBlackListed > 0) { + visibility.append("!").append(numBlackListed); + } + visibility.append("]"); + + return visibility.toString(); + } + + @VisibleForTesting + /* package */ static String verboseScanResultSummary(AccessPoint accessPoint, ScanResult result, + String bssid, long nowMs) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(" \n{").append(result.BSSID); + if (result.BSSID.equals(bssid)) { + stringBuilder.append("*"); + } + stringBuilder.append("=").append(result.frequency); + stringBuilder.append(",").append(result.level); + int speed = getSpecificApSpeed(result, accessPoint.getScoredNetworkCache()); + if (speed != AccessPoint.Speed.NONE) { + stringBuilder.append(",") + .append(accessPoint.getSpeedLabel(speed)); + } + int ageSeconds = (int) (nowMs - result.timestamp / 1000) / 1000; + stringBuilder.append(",").append(ageSeconds).append("s"); + stringBuilder.append("}"); + return stringBuilder.toString(); + } + + @AccessPoint.Speed + private static int getSpecificApSpeed(ScanResult result, + Map<String, TimestampedScoredNetwork> scoredNetworkCache) { + TimestampedScoredNetwork timedScore = scoredNetworkCache.get(result.BSSID); + if (timedScore == null) { + return AccessPoint.Speed.NONE; + } + // For debugging purposes we may want to use mRssi rather than result.level as the average + // speed wil be determined by mRssi + return timedScore.getScore().calculateBadge(result.level); + } +} diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java index 66f4a0114dc1..ec594a69ef03 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java @@ -66,7 +66,6 @@ import java.util.Collections; public class AccessPointTest { private static final String TEST_SSID = "\"test_ssid\""; - private static final int NUM_SCAN_RESULTS = 5; private static final ArrayList<ScanResult> SCAN_RESULTS = buildScanResultCache(); @@ -439,26 +438,6 @@ public class AccessPointTest { } @Test - public void testVerboseSummaryString_showsScanResultSpeedLabel() { - WifiTracker.sVerboseLogging = true; - - Bundle bundle = new Bundle(); - ArrayList<ScanResult> scanResults = buildScanResultCache(); - bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults); - AccessPoint ap = new AccessPoint(mContext, bundle); - - when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) - .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); - - ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, - MAX_SCORE_CACHE_AGE_MILLIS); - String summary = ap.verboseScanResultSummary(scanResults.get(0), null, 0); - - assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue(); - } - - @Test public void testSummaryString_concatenatesSpeedLabel() { AccessPoint ap = createAccessPointWithScanResultCache(); ap.update(new WifiConfiguration()); @@ -559,7 +538,6 @@ public class AccessPointTest { private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() { return buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve); - } private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) { @@ -570,7 +548,6 @@ public class AccessPointTest { badgeCurve, false /* meteredHint */, attr1); - } private AccessPoint createAccessPointWithScanResultCache() { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java new file mode 100644 index 000000000000..c5795d34eae8 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settingslib.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.NetworkKey; +import android.net.RssiCurve; +import android.net.ScoredNetwork; +import android.net.WifiKey; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiNetworkScoreCache; +import android.os.Bundle; +import android.os.SystemClock; +import android.text.format.DateUtils; + +import com.android.settingslib.R; +import com.android.settingslib.SettingsLibRobolectricTestRunner; +import com.android.settingslib.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; + +@RunWith(SettingsLibRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class WifiUtilsTest { + private static final String TEST_SSID = "\"test_ssid\""; + private static final String TEST_BSSID = "00:00:00:00:00:00"; + private static final long MAX_SCORE_CACHE_AGE_MILLIS = + 20 * DateUtils.MINUTE_IN_MILLIS; + + private Context mContext; + @Mock + private RssiCurve mockBadgeCurve; + @Mock + private WifiNetworkScoreCache mockWifiNetworkScoreCache; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + } + + @Test + public void testVerboseSummaryString_showsScanResultSpeedLabel() { + WifiTracker.sVerboseLogging = true; + + Bundle bundle = new Bundle(); + ArrayList<ScanResult> scanResults = buildScanResultCache(); + bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults); + AccessPoint ap = new AccessPoint(mContext, bundle); + + when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) + .thenReturn(buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve)); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); + + ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, + MAX_SCORE_CACHE_AGE_MILLIS); + String summary = WifiUtils.verboseScanResultSummary(ap, scanResults.get(0), null, 0); + + assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue(); + } + + private static ArrayList<ScanResult> buildScanResultCache() { + ArrayList<ScanResult> scanResults = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + ScanResult scanResult = createScanResult(TEST_SSID, "bssid-" + i, i); + scanResults.add(scanResult); + } + return scanResults; + } + + private static ScanResult createScanResult(String ssid, String bssid, int rssi) { + ScanResult scanResult = new ScanResult(); + scanResult.SSID = ssid; + scanResult.level = rssi; + scanResult.BSSID = bssid; + scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; + scanResult.capabilities = ""; + return scanResult; + } + + private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) { + Bundle attr1 = new Bundle(); + attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve); + return new ScoredNetwork( + new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)), + badgeCurve, + false /* meteredHint */, + attr1); + } +} |