diff options
author | Kai Shi <kaishi@google.com> | 2020-03-23 11:26:51 -0700 |
---|---|---|
committer | Kai Shi <kaishi@google.com> | 2020-03-28 21:23:13 -0700 |
commit | 5bfeb1ada4d6a12be7df6b72a6ad3fa002a799e3 (patch) | |
tree | ac2b41a4235ebf2d90fd71816a44726789ebd024 | |
parent | 776f77aa028f52fc08c51da38b502014938850ce (diff) |
Add channelUtilization and throughput in metrics
Add channel utilization and Tx and Rx throughput in WifiMetrics.
Also change default Tx PER to 5%.
Test: atest com.android.server.wifi
Test: run adb command "adb shell dumpsys wifi" and check the printed messages of wifiMetrics.
Bug: 152226996
Change-Id: I4b4a1d92aed9b9d9cc652d47ce60abc597583c81
5 files changed, 218 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java index fd29934cf..ba1de327c 100644 --- a/service/java/com/android/server/wifi/WifiDataStall.java +++ b/service/java/com/android/server/wifi/WifiDataStall.java @@ -48,7 +48,7 @@ public class WifiDataStall { // Maximum time that a data stall start time stays valid. public static final long VALIDITY_PERIOD_OF_DATA_STALL_START_MS = 30 * 1000; // 0.5 minutes // Default Tx packet error rate when there is no Tx attempt - public static final int DEFAULT_TX_PACKET_ERROR_RATE = 20; + public static final int DEFAULT_TX_PACKET_ERROR_RATE = 5; // Default CCA level when CCA stats are not available public static final int DEFAULT_CCA_LEVEL_2G = CHANNEL_UTILIZATION_SCALE * 16 / 100; public static final int DEFAULT_CCA_LEVEL_ABOVE_2G = CHANNEL_UTILIZATION_SCALE * 6 / 100; @@ -230,6 +230,7 @@ public class WifiDataStall { int currFrequency = wifiInfo.getFrequency(); mWifiChannelUtilization.refreshChannelStatsAndChannelUtilization(newStats, currFrequency); int ccaLevel = mWifiChannelUtilization.getUtilizationRatio(currFrequency); + mWifiMetrics.incrementChannelUtilizationCount(ccaLevel, currFrequency); if (oldStats == null || newStats == null) { // First poll after new association @@ -242,6 +243,7 @@ public class WifiDataStall { } mIsThroughputSufficient = true; mWifiMetrics.resetWifiIsUnusableLinkLayerStats(); + mWifiMetrics.incrementThroughputKbpsCount(mTxTputKbps, mRxTputKbps, currFrequency); return WifiIsUnusableEvent.TYPE_UNKNOWN; } @@ -322,6 +324,7 @@ public class WifiDataStall { } else { mRxTputKbps = INVALID_THROUGHPUT; } + mWifiMetrics.incrementThroughputKbpsCount(mTxTputKbps, mRxTputKbps, currFrequency); mIsThroughputSufficient = isThroughputSufficientInternal(mTxTputKbps, mRxTputKbps, isTxTrafficHigh, isRxTrafficHigh, timeDeltaLastTwoPollsMs); diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index fb6173732..c563a4bfb 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -442,6 +442,26 @@ public class WifiMetrics { // Connection duration stats collected while link layer stats reports are on private final ConnectionDurationStats mConnectionDurationStats = new ConnectionDurationStats(); + private static final int[] CHANNEL_UTILIZATION_BUCKETS = + {25, 50, 75, 100, 125, 150, 175, 200, 225}; + + private final IntHistogram mChannelUtilizationHistogram2G = + new IntHistogram(CHANNEL_UTILIZATION_BUCKETS); + + private final IntHistogram mChannelUtilizationHistogramAbove2G = + new IntHistogram(CHANNEL_UTILIZATION_BUCKETS); + + private static final int[] THROUGHPUT_MBPS_BUCKETS = + {1, 5, 10, 15, 25, 50, 100, 150, 200, 300, 450, 600, 800, 1200, 1600}; + private final IntHistogram mTxThroughputMbpsHistogram2G = + new IntHistogram(THROUGHPUT_MBPS_BUCKETS); + private final IntHistogram mRxThroughputMbpsHistogram2G = + new IntHistogram(THROUGHPUT_MBPS_BUCKETS); + private final IntHistogram mTxThroughputMbpsHistogramAbove2G = + new IntHistogram(THROUGHPUT_MBPS_BUCKETS); + private final IntHistogram mRxThroughputMbpsHistogramAbove2G = + new IntHistogram(THROUGHPUT_MBPS_BUCKETS); + // Wi-Fi off metrics private final WifiOffMetrics mWifiOffMetrics = new WifiOffMetrics(); @@ -2039,6 +2059,54 @@ public class WifiMetrics { } /** + * Increment occurrence count of channel utilization + * @param channelUtilization Channel utilization of current network + * @param frequency Channel frequency of current network + */ + @VisibleForTesting + public void incrementChannelUtilizationCount(int channelUtilization, int frequency) { + if (channelUtilization < InformationElementUtil.BssLoad.MIN_CHANNEL_UTILIZATION + || channelUtilization > InformationElementUtil.BssLoad.MAX_CHANNEL_UTILIZATION) { + return; + } + synchronized (mLock) { + if (frequency <= KnownBandsChannelHelper.BAND_24_GHZ_END_FREQ) { + mChannelUtilizationHistogram2G.increment(channelUtilization); + } else { + mChannelUtilizationHistogramAbove2G.increment(channelUtilization); + } + } + } + + /** + * Increment occurrence count of Tx and Rx throughput + * @param txThroughputKbps Tx throughput of current network in Kbps + * @param rxThroughputKbps Rx throughput of current network in Kbps + * @param frequency Channel frequency of current network in MHz + */ + @VisibleForTesting + public void incrementThroughputKbpsCount(int txThroughputKbps, int rxThroughputKbps, + int frequency) { + synchronized (mLock) { + if (frequency <= KnownBandsChannelHelper.BAND_24_GHZ_END_FREQ) { + if (txThroughputKbps >= 0) { + mTxThroughputMbpsHistogram2G.increment(txThroughputKbps / 1000); + } + if (rxThroughputKbps >= 0) { + mRxThroughputMbpsHistogram2G.increment(rxThroughputKbps / 1000); + } + } else { + if (txThroughputKbps >= 0) { + mTxThroughputMbpsHistogramAbove2G.increment(txThroughputKbps / 1000); + } + if (rxThroughputKbps >= 0) { + mRxThroughputMbpsHistogramAbove2G.increment(rxThroughputKbps / 1000); + } + } + } + } + + /** * Increment count of Watchdog successes. */ public void incrementNumLastResortWatchdogSuccesses() { @@ -3403,6 +3471,18 @@ public class WifiMetrics { + mWifiOffMetrics.toString()); pw.println("mWifiLogProto.softApConfigLimitationMetrics=" + mSoftApConfigLimitationMetrics.toString()); + pw.println("mChannelUtilizationHistogram2G:\n" + + mChannelUtilizationHistogram2G); + pw.println("mChannelUtilizationHistogramAbove2G:\n" + + mChannelUtilizationHistogramAbove2G); + pw.println("mTxThroughputMbpsHistogram2G:\n" + + mTxThroughputMbpsHistogram2G); + pw.println("mRxThroughputMbpsHistogram2G:\n" + + mRxThroughputMbpsHistogram2G); + pw.println("mTxThroughputMbpsHistogramAbove2G:\n" + + mTxThroughputMbpsHistogramAbove2G); + pw.println("mRxThroughputMbpsHistogramAbove2G:\n" + + mRxThroughputMbpsHistogramAbove2G); } } } @@ -3974,6 +4054,22 @@ public class WifiMetrics { mWifiLogProto.connectionDurationStats = mConnectionDurationStats.toProto(); mWifiLogProto.wifiOffMetrics = mWifiOffMetrics.toProto(); mWifiLogProto.softApConfigLimitationMetrics = mSoftApConfigLimitationMetrics.toProto(); + mWifiLogProto.channelUtilizationHistogram = + new WifiMetricsProto.ChannelUtilizationHistogram(); + mWifiLogProto.channelUtilizationHistogram.utilization2G = + mChannelUtilizationHistogram2G.toProto(); + mWifiLogProto.channelUtilizationHistogram.utilizationAbove2G = + mChannelUtilizationHistogramAbove2G.toProto(); + mWifiLogProto.throughputMbpsHistogram = + new WifiMetricsProto.ThroughputMbpsHistogram(); + mWifiLogProto.throughputMbpsHistogram.tx2G = + mTxThroughputMbpsHistogram2G.toProto(); + mWifiLogProto.throughputMbpsHistogram.txAbove2G = + mTxThroughputMbpsHistogramAbove2G.toProto(); + mWifiLogProto.throughputMbpsHistogram.rx2G = + mRxThroughputMbpsHistogram2G.toProto(); + mWifiLogProto.throughputMbpsHistogram.rxAbove2G = + mRxThroughputMbpsHistogramAbove2G.toProto(); } } @@ -4166,6 +4262,12 @@ public class WifiMetrics { mWifiLockLowLatencyActiveSessionDurationSecHistogram.clear(); mWifiLockStats.clear(); mWifiToggleStats.clear(); + mChannelUtilizationHistogram2G.clear(); + mChannelUtilizationHistogramAbove2G.clear(); + mTxThroughputMbpsHistogram2G.clear(); + mRxThroughputMbpsHistogram2G.clear(); + mTxThroughputMbpsHistogramAbove2G.clear(); + mRxThroughputMbpsHistogramAbove2G.clear(); mPasspointProvisionFailureCounts.clear(); mNumProvisionSuccess = 0; mBssidBlocklistStats = new BssidBlocklistStats(); diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto index f2ed398ec..1cd0b91ed 100644 --- a/service/proto/src/metrics.proto +++ b/service/proto/src/metrics.proto @@ -640,6 +640,12 @@ message WifiLog { // Metrics related to limitation in soft ap config optional SoftApConfigLimitationMetrics soft_ap_config_limitation_metrics = 178; + + // WiFi channel utilization histogram of various RF bands + optional ChannelUtilizationHistogram channel_utilization_histogram = 179; + + // WiFi Tx and Rx throughput histogram at various RF bands + optional ThroughputMbpsHistogram throughput_mbps_histogram = 180; } // Information that gets logged for every WiFi connection. @@ -3055,3 +3061,25 @@ message SoftApConfigLimitationMetrics { // setting limitation repeated Int32Count max_client_setting_when_reach_histogram = 4; } + +// Channel utilization histogram +// The valid utilization range is between 0 and 255 corresponding to +// utilization ratio between 0 and 1 +message ChannelUtilizationHistogram { + // Histogram at 2G + repeated HistogramBucketInt32 utilization_2g = 1; + // Histogram above 2G + repeated HistogramBucketInt32 utilization_above_2g = 2; +} + +// Throughput histogram +message ThroughputMbpsHistogram { + // Tx histogram at 2G + repeated HistogramBucketInt32 tx_2g = 1; + // Tx histogram above 2G + repeated HistogramBucketInt32 tx_above_2g = 2; + // Rx histogram at 2G + repeated HistogramBucketInt32 rx_2g = 3; + // Rx histogram above 2G + repeated HistogramBucketInt32 rx_above_2g = 4; +} diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java index bb8c74d60..cfe1ee8af 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java @@ -204,17 +204,21 @@ public class WifiDataStallTest extends WifiBaseTest { } /** - * Verify throughtput when Rx link speed is unavailable + * Verify throughtput when Rx link speed is unavailable. + * Also verify the logging of channel utilization and throughput. */ @Test public void verifyThroughputNoRxLinkSpeed() throws Exception { mWifiDataStall.checkDataStallAndThroughputSufficiency(null, mNewLlStats, mWifiInfo); + verify(mWifiMetrics).incrementChannelUtilizationCount(10, 5850); + verify(mWifiMetrics).incrementThroughputKbpsCount(50_000, 150_000, 5850); assertEquals(50_000, mWifiDataStall.getTxThroughputKbps()); assertEquals(150_000, mWifiDataStall.getRxThroughputKbps()); when(mWifiInfo.getRxLinkSpeedMbps()).thenReturn(-1); mWifiDataStall.checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo); assertEquals(960, mWifiDataStall.getTxThroughputKbps()); assertEquals(-1, mWifiDataStall.getRxThroughputKbps()); + verify(mWifiMetrics).incrementThroughputKbpsCount(960, -1, 5850); } /** @@ -226,6 +230,7 @@ public class WifiDataStallTest extends WifiBaseTest { assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiDataStall .checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo)); + verify(mWifiMetrics).incrementThroughputKbpsCount(960, 9609, 5850); verifyUpdateWifiIsUnusableLinkLayerStats(); when(mClock.getElapsedSinceBootMillis()).thenReturn( 10L + DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index 315a17bc1..841a1326e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -4564,4 +4564,82 @@ public class WifiMetricsTest extends WifiBaseTest { mDecodedProto.softApConfigLimitationMetrics.maxClientSettingWhenReachHistogram); } + /** + * Test the logging of channel utilization + */ + @Test + public void testChannelUtilization() throws Exception { + mWifiMetrics.incrementChannelUtilizationCount(180, 2412); + mWifiMetrics.incrementChannelUtilizationCount(150, 2412); + mWifiMetrics.incrementChannelUtilizationCount(230, 2412); + mWifiMetrics.incrementChannelUtilizationCount(20, 5510); + mWifiMetrics.incrementChannelUtilizationCount(50, 5510); + + dumpProtoAndDeserialize(); + + HistogramBucketInt32[] expected2GHistogram = { + buildHistogramBucketInt32(150, 175, 1), + buildHistogramBucketInt32(175, 200, 1), + buildHistogramBucketInt32(225, Integer.MAX_VALUE, 1), + }; + + HistogramBucketInt32[] expectedAbove2GHistogram = { + buildHistogramBucketInt32(Integer.MIN_VALUE, 25, 1), + buildHistogramBucketInt32(50, 75, 1), + }; + + assertHistogramBucketsEqual(expected2GHistogram, + mDecodedProto.channelUtilizationHistogram.utilization2G); + assertHistogramBucketsEqual(expectedAbove2GHistogram, + mDecodedProto.channelUtilizationHistogram.utilizationAbove2G); + } + + /** + * Test the logging of Tx and Rx throughput + */ + @Test + public void testThroughput() throws Exception { + mWifiMetrics.incrementThroughputKbpsCount(500, 800, 2412); + mWifiMetrics.incrementThroughputKbpsCount(5_000, 4_000, 2412); + mWifiMetrics.incrementThroughputKbpsCount(54_000, 48_000, 2412); + mWifiMetrics.incrementThroughputKbpsCount(50_000, 49_000, 5510); + mWifiMetrics.incrementThroughputKbpsCount(801_000, 790_000, 5510); + mWifiMetrics.incrementThroughputKbpsCount(1100_000, 1200_000, 5510); + mWifiMetrics.incrementThroughputKbpsCount(1599_000, 1800_000, 6120); + dumpProtoAndDeserialize(); + + HistogramBucketInt32[] expectedTx2GHistogramMbps = { + buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1), + buildHistogramBucketInt32(5, 10, 1), + buildHistogramBucketInt32(50, 100, 1), + }; + + HistogramBucketInt32[] expectedRx2GHistogramMbps = { + buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1), + buildHistogramBucketInt32(1, 5, 1), + buildHistogramBucketInt32(25, 50, 1), + }; + + HistogramBucketInt32[] expectedTxAbove2GHistogramMbps = { + buildHistogramBucketInt32(50, 100, 1), + buildHistogramBucketInt32(800, 1200, 2), + buildHistogramBucketInt32(1200, 1600, 1), + }; + + HistogramBucketInt32[] expectedRxAbove2GHistogramMbps = { + buildHistogramBucketInt32(25, 50, 1), + buildHistogramBucketInt32(600, 800, 1), + buildHistogramBucketInt32(1200, 1600, 1), + buildHistogramBucketInt32(1600, Integer.MAX_VALUE, 1), + }; + + assertHistogramBucketsEqual(expectedTx2GHistogramMbps, + mDecodedProto.throughputMbpsHistogram.tx2G); + assertHistogramBucketsEqual(expectedTxAbove2GHistogramMbps, + mDecodedProto.throughputMbpsHistogram.txAbove2G); + assertHistogramBucketsEqual(expectedRx2GHistogramMbps, + mDecodedProto.throughputMbpsHistogram.rx2G); + assertHistogramBucketsEqual(expectedRxAbove2GHistogramMbps, + mDecodedProto.throughputMbpsHistogram.rxAbove2G); + } } |