diff options
author | Mingguang Xu <mingguangxu@google.com> | 2019-03-28 11:26:30 -0700 |
---|---|---|
committer | Mingguang Xu <mingguangxu@google.com> | 2019-04-03 00:48:34 -0700 |
commit | 4e4fdb68c27fed31010ea1a791cc717d28e0b2bb (patch) | |
tree | 43f1019adc20e5efef100f78d47f26d6f7c9ab85 | |
parent | 7da1c005ae579ae742b333b7da30c457a1aba9ea (diff) |
Wifi usability: Collect good usability stats when score breaches low
Besides randomly collecting Wifi usability stats with good labels, need
to explicitly collect stats with good labels when Wifi score or Wifi
usability score breaches low. In this way we can get more diversified
types of stats with good labels.
Bug: 129514031
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: Ic264865ad5721aab6497d0cea7d0cf35a86c8f03
Signed-off-by: Mingguang Xu <mingguangxu@google.com>
-rw-r--r-- | service/java/com/android/server/wifi/WifiMetrics.java | 28 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java | 188 |
2 files changed, 216 insertions, 0 deletions
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index dca05e6ef..e8da69c12 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -168,6 +168,10 @@ public class WifiMetrics { // >= 300 private static final int[] WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS = {50, 100, 150, 200, 300}; + // Minimum time wait before generating a LABEL_GOOD stats after score breaching low. + public static final int MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS = 60 * 1000; // 1 minute + // Maximum time that a score breaching low event stays valid. + public static final int VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS = 90 * 1000; // 1.5 minutes private Clock mClock; private boolean mScreenOn; @@ -199,6 +203,7 @@ public class WifiMetrics { android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; private int mProbeElapsedTimeSinceLastUpdateMs = -1; private int mProbeMcsRateSinceLastUpdate = -1; + private long mScoreBreachLowTimeMillis = -1; /** Tracks if we should be logging WifiIsUnusableEvent */ private boolean mUnusableEventLogging = false; @@ -1701,6 +1706,11 @@ public class WifiMetrics { StaEvent event = new StaEvent(); event.type = StaEvent.TYPE_SCORE_BREACH; addStaEvent(event); + // Only record the first score breach by checking whether mScoreBreachLowTimeMillis + // has been set to -1 + if (!wifiWins && mScoreBreachLowTimeMillis == -1) { + mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); + } } } } @@ -3429,6 +3439,7 @@ public class WifiMetrics { android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; mProbeElapsedTimeSinceLastUpdateMs = -1; mProbeMcsRateSinceLastUpdate = -1; + mScoreBreachLowTimeMillis = -1; mWifiConfigStoreReadDurationHistogram.clear(); mWifiConfigStoreWriteDurationHistogram.clear(); mLinkProbeSuccessRssiCounts.clear(); @@ -4037,6 +4048,7 @@ public class WifiMetrics { * @param firmwareAlertCode WifiIsUnusableEvent.firmwareAlertCode for firmware alert code */ public void logWifiIsUnusableEvent(int triggerType, int firmwareAlertCode) { + mScoreBreachLowTimeMillis = -1; if (!mUnusableEventLogging) { return; } @@ -4215,6 +4227,16 @@ public class WifiMetrics { addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, WifiUsabilityStats.TYPE_UNKNOWN, -1); } + if (mScoreBreachLowTimeMillis != -1) { + long elapsedTime = mClock.getElapsedSinceBootMillis() - mScoreBreachLowTimeMillis; + if (elapsedTime >= MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS) { + mScoreBreachLowTimeMillis = -1; + if (elapsedTime <= VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS) { + addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, + WifiUsabilityStats.TYPE_UNKNOWN, -1); + } + } + } // Invoke Wifi usability stats listener. sendWifiUsabilityStats(mSeqNumInsideFramework, isSameBssidAndFreq, @@ -4411,6 +4433,7 @@ public class WifiMetrics { } else { // Only add a bad event if at least |MIN_DATA_STALL_WAIT_MS| // has passed. + mScoreBreachLowTimeMillis = -1; if (mWifiUsabilityStatsListBad.isEmpty() || (mWifiUsabilityStatsListBad.getLast().stats[mWifiUsabilityStatsListBad .getLast().stats.length - 1].timeStampMs @@ -4569,6 +4592,11 @@ public class WifiMetrics { StaEvent event = new StaEvent(); event.type = StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH; addStaEvent(event); + // Only record the first score breach by checking whether mScoreBreachLowTimeMillis + // has been set to -1 + if (!wifiWins && mScoreBreachLowTimeMillis == -1) { + mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); + } } } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index 6c19bbb05..8270887d5 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -3656,4 +3656,192 @@ public class WifiMetricsTest { assertHistogramBucketsEqual(expectedLowLatencyHistogram, mDecodedProto.wifiLockStats.lowLatencyLockAcqDurationSecHistogram); } + + /** + * Verify that LABEL_GOOD stats are generated if Wifi score breaches low and there + * is no WifiIsUnusableEvent in MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreGeneratedByWifiScoreBreachLow() throws Exception { + // The elapsed time falls into the interval for adding good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1, + false, true); + dumpProtoAndDeserialize(); + assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and the checking + * time is less than MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedByWifiScoreBreachLow() throws Exception { + // The elapsed time is shorter than necessary to add good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS - 1, + false, true); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and the checking + * time is greater than VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedIfWifiScoreBreachExpires() throws Exception { + // The Wifi score breaching expires for adding good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + 1, + false, true); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and there is + * WifiIsUnusableEvent occured within MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedIfBadEventOccured() throws Exception { + // The elapsed time falls into the interval for adding good stats and bad event occurs + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1, + true, true); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are generated if Wifi usability score breaches low and there + * is no WifiIsUnusableEvent in MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreGeneratedByWifiUsabilityScoreBreachLow() throws Exception { + // The elapsed time falls into the interval for adding good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1, + false, false); + dumpProtoAndDeserialize(); + assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and + * the checking time is less than MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedByWifiUsabilityScoreBreachLow() throws Exception { + // The elapsed time is shorter than necessary to add good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS - 1, + false, false); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and + * the checking time is greater than VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedIfWifiUsabilityScoreBreachExpires() throws Exception { + // The Wifi usability score breaching expires for adding good stats + createTestForDataCollectionByScoreBreach( + WifiMetrics.VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + 1, + false, false); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and there + * is WifiIsUnusableEvent occured within MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis + * @throws Exception + */ + @Test + public void testGoodStatsAreNotGeneratedIfBadEventOccuredForUsabilityScore() throws Exception { + // The elapsed time falls into the interval for adding good stats and bad event occurs + createTestForDataCollectionByScoreBreach( + WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1, + true, false); + dumpProtoAndDeserialize(); + assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length); + } + + /** + * Create a test to verify data collection logic triggered by score breaching low + * @param elapsedTimeAfterBreach The elapsed time after score breaches low + * @param isThereBadEvent Whether there is a bad event happened after score breaches low + * @param isWifiScore Whether it is Wifi score or not that breaches the threshold + */ + private void createTestForDataCollectionByScoreBreach( + long elapsedTimeAfterBreach, boolean isThereBadEvent, boolean isWifiScore) { + WifiInfo info = mock(WifiInfo.class); + when(info.getRssi()).thenReturn(nextRandInt()); + when(info.getLinkSpeed()).thenReturn(nextRandInt()); + WifiLinkLayerStats stats2 = new WifiLinkLayerStats(); + mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); + + addOneBadWifiUsabilityStats(info); + if (isWifiScore) { + stats2 = wifiScoreBreachesLow(info, stats2); + } else { + stats2 = wifiUsabilityScoreBreachesLow(info, stats2); + } + if (isThereBadEvent) { + mWifiMetrics.logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1); + } + when(mClock.getElapsedSinceBootMillis()).thenReturn(elapsedTimeAfterBreach); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats2); + } + + // Simulate adding one LABEL_BAD WifiUsabilityStats + private void addOneBadWifiUsabilityStats(WifiInfo info) { + WifiLinkLayerStats stats1 = new WifiLinkLayerStats(); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats1); + mWifiMetrics.addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, + WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1); + } + + // Simulate that Wifi score breaches low + private WifiLinkLayerStats wifiScoreBreachesLow(WifiInfo info, WifiLinkLayerStats stats2) { + int upper = WifiMetrics.LOW_WIFI_SCORE + 7; + int lower = WifiMetrics.LOW_WIFI_SCORE - 8; + mWifiMetrics.incrementWifiScoreCount(upper); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats2); + stats2 = nextRandomStats(stats2); + long timeMs = 0; + when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs); + // Wifi score breaches low + mWifiMetrics.incrementWifiScoreCount(lower); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats2); + stats2 = nextRandomStats(stats2); + return stats2; + } + + // Simulate that Wifi usability score breaches low + private WifiLinkLayerStats wifiUsabilityScoreBreachesLow(WifiInfo info, + WifiLinkLayerStats stats2) { + int upper = WifiMetrics.LOW_WIFI_USABILITY_SCORE + 7; + int lower = WifiMetrics.LOW_WIFI_USABILITY_SCORE - 8; + mWifiMetrics.incrementWifiUsabilityScoreCount(1, upper, 30); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats2); + stats2 = nextRandomStats(stats2); + long timeMs = 0; + when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs); + // Wifi usability score breaches low + mWifiMetrics.incrementWifiUsabilityScoreCount(2, lower, 30); + mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats2); + stats2 = nextRandomStats(stats2); + return stats2; + } } |