From 358daf5df00f5563253ba3465fbc7029f7ac1056 Mon Sep 17 00:00:00 2001 From: Michael Plass Date: Wed, 28 Mar 2018 14:36:07 -0700 Subject: [WifiScoreReport] Stay on working wifi If packets are actually moving in both directions at a sufficiently high rate, stay on wifi. Bug: 74613347 Test: Unit tests Change-Id: I49862984c9c3f67d64669102bb929a07110797ba --- .../com/android/server/wifi/ScoringParams.java | 30 ++++++++++++++++++++++ .../com/android/server/wifi/WifiScoreReport.java | 7 +++++ .../android/server/wifi/WifiScoreReportTest.java | 29 +++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/service/java/com/android/server/wifi/ScoringParams.java b/service/java/com/android/server/wifi/ScoringParams.java index 3fabfc4a5..0cad22531 100644 --- a/service/java/com/android/server/wifi/ScoringParams.java +++ b/service/java/com/android/server/wifi/ScoringParams.java @@ -54,6 +54,10 @@ public class ScoringParams { public static final String KEY_RSSI5 = "rssi5"; public final int[] rssi5 = {-80, -77, -70, -57}; + /** Guidelines based on packet rates (packets/sec) */ + public static final String KEY_PPS = "pps"; + public final int[] pps = {0, 1, 100}; + /** Number of seconds for RSSI forecast */ public static final String KEY_HORIZON = "horizon"; public static final int MIN_HORIZON = -9; @@ -70,12 +74,16 @@ public class ScoringParams { for (int i = 0; i < rssi5.length; i++) { rssi5[i] = source.rssi5[i]; } + for (int i = 0; i < pps.length; i++) { + pps[i] = source.pps[i]; + } horizon = source.horizon; } public void validate() throws IllegalArgumentException { validateRssiArray(rssi2); validateRssiArray(rssi5); + validateOrderedNonNegativeArray(pps); validateRange(horizon, MIN_HORIZON, MAX_HORIZON); } @@ -94,6 +102,16 @@ public class ScoringParams { } } + private void validateOrderedNonNegativeArray(int[] a) throws IllegalArgumentException { + int low = 0; + for (int i = 0; i < a.length; i++) { + if (a[i] < low) { + throw new IllegalArgumentException(); + } + low = a[i]; + } + } + public void parseString(String kvList) throws IllegalArgumentException { KeyValueListParser parser = new KeyValueListParser(','); parser.setString(kvList); @@ -102,6 +120,7 @@ public class ScoringParams { } updateIntArray(rssi2, parser, KEY_RSSI2); updateIntArray(rssi5, parser, KEY_RSSI5); + updateIntArray(pps, parser, KEY_PPS); horizon = updateInt(parser, KEY_HORIZON, horizon); } @@ -134,6 +153,9 @@ public class ScoringParams { appendInts(sb, rssi2); appendKey(sb, KEY_RSSI5); appendInts(sb, rssi5); + //TODO(b/74613347) - leave these out, pending unit test updates + // appendKey(sb, KEY_PPS); + // appendInts(sb, pps); appendKey(sb, KEY_HORIZON); sb.append(horizon); return sb.toString(); @@ -297,6 +319,14 @@ public class ScoringParams { return mVal.horizon; } + /** + * Returns a packet rate that should be considered acceptable for staying on wifi, + * no matter how bad the RSSI gets (packets per second). + */ + public int getYippeeSkippyPacketsPerSecond() { + return mVal.pps[2]; + } + private static final int MINIMUM_5GHZ_BAND_FREQUENCY_IN_MEGAHERTZ = 5000; private int[] getRssiArray(int frequency) { diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java index e11b697b6..32529f88d 100644 --- a/service/java/com/android/server/wifi/WifiScoreReport.java +++ b/service/java/com/android/server/wifi/WifiScoreReport.java @@ -128,6 +128,13 @@ public class WifiScoreReport { score = s2; + if (wifiInfo.score > ConnectedScore.WIFI_TRANSITION_SCORE + && score <= ConnectedScore.WIFI_TRANSITION_SCORE + && wifiInfo.txSuccessRate >= mScoringParams.getYippeeSkippyPacketsPerSecond() + && wifiInfo.rxSuccessRate >= mScoringParams.getYippeeSkippyPacketsPerSecond()) { + score = ConnectedScore.WIFI_TRANSITION_SCORE + 1; + } + if (wifiInfo.score > ConnectedScore.WIFI_TRANSITION_SCORE && score <= ConnectedScore.WIFI_TRANSITION_SCORE) { // We don't want to trigger a downward breach unless the rssi is diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java index d60264c61..bf662f01a 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java @@ -259,6 +259,35 @@ public class WifiScoreReportTest { assertTrue(oops, minScore > ConnectedScore.WIFI_TRANSITION_SCORE); } + /** + * Don't breach if the success rates are great + * + * Ramp the RSSI down, but maintain a high packet throughput + * + * Expect score to stay above above threshold. + */ + @Test + public void allowTerribleRssiIfDataIsMovingWell() throws Exception { + mWifiInfo.txSuccessRate = mScoringParams.getYippeeSkippyPacketsPerSecond() + 0.1; + mWifiInfo.rxSuccessRate = mScoringParams.getYippeeSkippyPacketsPerSecond() + 0.1; + assertTrue(mWifiInfo.txSuccessRate > 10); + mWifiInfo.setFrequency(5220); + for (int r = -30; r >= -200; r -= 2) { + mWifiInfo.setRssi(r); + mWifiScoreReport.calculateAndReportScore(mWifiInfo, mNetworkAgent, mWifiMetrics); + assertTrue(mWifiInfo.score > ConnectedScore.WIFI_TRANSITION_SCORE); + } + // If the throughput dips, we should let go + mWifiInfo.rxSuccessRate = mScoringParams.getYippeeSkippyPacketsPerSecond() - 0.1; + mWifiScoreReport.calculateAndReportScore(mWifiInfo, mNetworkAgent, mWifiMetrics); + assertTrue(mWifiInfo.score < ConnectedScore.WIFI_TRANSITION_SCORE); + // And even if throughput improves again, once we have decided to let go, disregard + // the good rates. + mWifiInfo.rxSuccessRate = mScoringParams.getYippeeSkippyPacketsPerSecond() + 0.1; + mWifiScoreReport.calculateAndReportScore(mWifiInfo, mNetworkAgent, mWifiMetrics); + assertTrue(mWifiInfo.score < ConnectedScore.WIFI_TRANSITION_SCORE); + } + /** * This setup causes some reports to be generated when println * methods are called, to check for "concurrent" modification -- cgit v1.2.3