diff options
author | Jong Wook Kim <jongwook@google.com> | 2018-04-23 11:18:41 -0700 |
---|---|---|
committer | Jong Wook Kim <jongwook@google.com> | 2018-06-18 18:20:14 -0700 |
commit | ffb6a68d1271747794cc17c779d7dcc3dc15a1af (patch) | |
tree | 737d1d7ee31101b0427aafc92f1f14c6ab5c6132 | |
parent | 9031858215eb529b175adcb45deee639703f3ada (diff) |
Collect Link Speed Metrics
Add a histogram of link speed values.
Stop logging this metrics when WIFI_LINK_SPEED_METRICS_ENABLED settings
value is set to 0.
Bug: 78354985
Test: Unittest
Test: adb shell dumpsys wifi | grep -10 linkSpeedCounts
Test: adb shell settings put global wifi_link_speed_metrics_enabled 1
Test: adb shell dumpsys wifi wifiMetricsProto
Test: adb shell dumpsys wifi | grep -10 linkSpeedCounts
Test: adb shell dumpsys wifi | grep -10 mExperimentValues
Change-Id: Iad8995d90dc1a29f615a88b92a0f12220e27f546
-rw-r--r-- | service/java/com/android/server/wifi/WifiMetrics.java | 77 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java | 83 |
2 files changed, 158 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index f0d12d955..8a1821655 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -31,6 +31,7 @@ import android.provider.Settings; import android.util.Base64; import android.util.Log; import android.util.Pair; +import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; @@ -44,6 +45,7 @@ import com.android.server.wifi.hotspot2.Utils; import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount; import com.android.server.wifi.nano.WifiMetricsProto.ExperimentValues; +import com.android.server.wifi.nano.WifiMetricsProto.LinkSpeedCount; import com.android.server.wifi.nano.WifiMetricsProto.PnoScanMetrics; import com.android.server.wifi.nano.WifiMetricsProto.SoftApConnectedClientsEvent; import com.android.server.wifi.nano.WifiMetricsProto.StaEvent; @@ -88,6 +90,8 @@ public class WifiMetrics { private static final int MIN_RSSI_POLL = -127; public static final int MAX_RSSI_DELTA = 127; public static final int MIN_RSSI_DELTA = -127; + /** Minimum link speed (Mbps) to count for link_speed_counts */ + public static final int MIN_LINK_SPEED_MBPS = 0; /** Maximum time period between ScanResult and RSSI poll to generate rssi delta datapoint */ public static final long TIMEOUT_RSSI_DELTA_MILLIS = 3000; private static final int MIN_WIFI_SCORE = 0; @@ -114,6 +118,7 @@ public class WifiMetrics { // Minimum time wait before generating next WifiIsUnusableEvent from data stall public static final int MIN_DATA_STALL_WAIT_MS = 120 * 1000; // 2 minutes private static final int WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED_DEFAULT = 0; // 0 = false + private static final int WIFI_LINK_SPEED_METRICS_ENABLED_DEFAULT = 0; // 0 = false private Clock mClock; private boolean mScreenOn; @@ -134,6 +139,8 @@ public class WifiMetrics { /** Tracks if we should be logging WifiIsUnusableEvent */ private boolean mUnusableEventLogging = false; + /** Tracks if we should be logging LinkSpeedCounts */ + private boolean mLinkSpeedCountsLogging = true; /** * Metrics are stored within an instance of the WifiLog proto during runtime, @@ -163,6 +170,8 @@ public class WifiMetrics { private final Map<Integer, SparseIntArray> mRssiPollCountsMap = new HashMap<>(); /** Mapping of RSSI scan-poll delta values to counts. */ private final SparseIntArray mRssiDeltaCounts = new SparseIntArray(); + /** Mapping of link speed values to LinkSpeedCount objects. */ + private final SparseArray<LinkSpeedCount> mLinkSpeedCounts = new SparseArray<>(); /** RSSI of the scan result for the last connection event*/ private int mScanResultRssi = 0; /** Boot-relative timestamp when the last candidate scanresult was received, used to calculate @@ -490,6 +499,11 @@ public class WifiMetrics { WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED_DEFAULT); mUnusableEventLogging = (unusableEventFlag == 1); setWifiIsUnusableLoggingEnabled(mUnusableEventLogging); + int linkSpeedCountsFlag = mFacade.getIntegerSetting( + mContext, Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED, + WIFI_LINK_SPEED_METRICS_ENABLED_DEFAULT); + mLinkSpeedCountsLogging = (linkSpeedCountsFlag == 1); + setLinkSpeedCountsLoggingEnabled(mLinkSpeedCountsLogging); if (mWifiDataStall != null) { mWifiDataStall.loadSettings(); } @@ -1143,6 +1157,7 @@ public class WifiMetrics { mLastPollLinkSpeed = wifiInfo.getLinkSpeed(); mLastPollFreq = wifiInfo.getFrequency(); incrementRssiPollRssiCount(mLastPollFreq, mLastPollRssi); + incrementLinkSpeedCount(mLastPollLinkSpeed, mLastPollRssi); } /** @@ -1186,6 +1201,32 @@ public class WifiMetrics { } /** + * Increment occurrence count of link speed. + * Ignores link speed values that are lower than MIN_LINK_SPEED_MBPS + * and rssi values outside the bounds of [MIN_RSSI_POLL, MAX_RSSI_POLL] + */ + @VisibleForTesting + public void incrementLinkSpeedCount(int linkSpeed, int rssi) { + if (!(mLinkSpeedCountsLogging + && linkSpeed >= MIN_LINK_SPEED_MBPS + && rssi >= MIN_RSSI_POLL + && rssi <= MAX_RSSI_POLL)) { + return; + } + synchronized (mLock) { + LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.get(linkSpeed); + if (linkSpeedCount == null) { + linkSpeedCount = new LinkSpeedCount(); + linkSpeedCount.linkSpeedMbps = linkSpeed; + mLinkSpeedCounts.put(linkSpeed, linkSpeedCount); + } + linkSpeedCount.count++; + linkSpeedCount.rssiSumDbm += Math.abs(rssi); + linkSpeedCount.rssiSumOfSquaresDbmSq += rssi * rssi; + } + } + + /** * Increment count of Watchdog successes. */ public void incrementNumLastResortWatchdogSuccesses() { @@ -1997,6 +2038,18 @@ public class WifiMetrics { sb.append(mRssiDeltaCounts.get(i) + " "); } pw.println(" " + sb.toString()); + pw.println("mWifiLogProto.linkSpeedCounts: "); + sb.setLength(0); + for (int i = 0; i < mLinkSpeedCounts.size(); i++) { + LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.valueAt(i); + sb.append(linkSpeedCount.linkSpeedMbps).append(":{") + .append(linkSpeedCount.count).append(", ") + .append(linkSpeedCount.rssiSumDbm).append(", ") + .append(linkSpeedCount.rssiSumOfSquaresDbmSq).append("} "); + } + if (sb.length() > 0) { + pw.println(sb.toString()); + } pw.print("mWifiLogProto.alertReasonCounts="); sb.setLength(0); for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN; @@ -2206,6 +2259,8 @@ public class WifiMetrics { + mExperimentValues.wifiDataStallMinTxBad); pw.println("mExperimentValues.wifiDataStallMinTxSuccessWithoutRx=" + mExperimentValues.wifiDataStallMinTxSuccessWithoutRx); + pw.println("mExperimentValues.linkSpeedCountsLoggingEnabled=" + + mExperimentValues.linkSpeedCountsLoggingEnabled); pw.println("WifiIsUnusableEventList: "); for (WifiIsUnusableWithTime event : mWifiIsUnusableList) { pw.println(event); @@ -2275,6 +2330,7 @@ public class WifiMetrics { List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>(); List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>(); List<WifiMetricsProto.RssiPollCount> rssiDeltas = new ArrayList<>(); + List<WifiMetricsProto.LinkSpeedCount> linkSpeeds = new ArrayList<>(); List<WifiMetricsProto.AlertReasonCount> alertReasons = new ArrayList<>(); List<WifiMetricsProto.WifiScoreCount> scores = new ArrayList<>(); synchronized (mLock) { @@ -2325,7 +2381,7 @@ public class WifiMetrics { /** * Convert the SparseIntArrays of RSSI poll rssi, counts, and frequency to the - * proto's repeated ntKeyVal array. + * proto's repeated IntKeyVal array. */ for (Map.Entry<Integer, SparseIntArray> entry : mRssiPollCountsMap.entrySet()) { int frequency = entry.getKey(); @@ -2355,6 +2411,14 @@ public class WifiMetrics { /** + * Add LinkSpeedCount objects from mLinkSpeedCounts to proto. + */ + for (int i = 0; i < mLinkSpeedCounts.size(); i++) { + linkSpeeds.add(mLinkSpeedCounts.valueAt(i)); + } + mWifiLogProto.linkSpeedCounts = linkSpeeds.toArray(mWifiLogProto.linkSpeedCounts); + + /** * Convert the SparseIntArray of alert reasons and counts to the proto's repeated * IntKeyVal array. */ @@ -2563,6 +2627,7 @@ public class WifiMetrics { mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000; mRssiPollCountsMap.clear(); mRssiDeltaCounts.clear(); + mLinkSpeedCounts.clear(); mWifiAlertReasonCounts.clear(); mWifiScoreCounts.clear(); mWifiLogProto.clear(); @@ -3216,6 +3281,16 @@ public class WifiMetrics { } /** + * Sets whether or not LinkSpeedCounts is logged in metrics + */ + @VisibleForTesting + public void setLinkSpeedCountsLoggingEnabled(boolean enabled) { + synchronized (mLock) { + mExperimentValues.linkSpeedCountsLoggingEnabled = enabled; + } + } + + /** * Sets the minimum number of txBad to trigger a data stall */ public void setWifiDataStallMinTxBad(int minTxBad) { diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index 27e0935cd..4fbee803d 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -244,7 +244,6 @@ public class WifiMetricsTest { private static final int WATCHDOG_TOTAL_CONNECTION_FAILURE_COUNT_AFTER_TRIGGER = 6; private static final int RSSI_POLL_FREQUENCY = 5150; private static final int NUM_RSSI_LEVELS_TO_INCREMENT = 20; - private static final int FIRST_RSSI_LEVEL = -80; private static final int NUM_OPEN_NETWORK_SCAN_RESULTS = 1; private static final int NUM_PERSONAL_NETWORK_SCAN_RESULTS = 4; private static final int NUM_ENTERPRISE_NETWORK_SCAN_RESULTS = 3; @@ -308,6 +307,7 @@ public class WifiMetricsTest { private static final long WIFI_POWER_METRICS_LOGGING_DURATION = 280; private static final long WIFI_POWER_METRICS_SCAN_TIME = 33; private static final boolean WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING = true; + private static final boolean LINK_SPEED_COUNTS_LOGGING_SETTING = true; private static final int DATA_STALL_MIN_TX_BAD_SETTING = 5; private static final int DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING = 75; @@ -331,6 +331,8 @@ public class WifiMetricsTest { private static final int SOFT_AP_CHANNEL_FREQUENCY = 2437; private static final int SOFT_AP_CHANNEL_BANDWIDTH = SoftApConnectedClientsEvent.BANDWIDTH_20; private static final boolean IS_MAC_RANDOMIZATION_ON = true; + private static final int NUM_LINK_SPEED_LEVELS_TO_INCREMENT = 30; + private static final int TEST_RSSI_LEVEL = -80; private ScanDetail buildMockScanDetail(boolean hidden, NetworkDetail.HSRelease hSRelease, String capabilities) { @@ -707,6 +709,7 @@ public class WifiMetricsTest { addWifiPowerMetrics(); mWifiMetrics.setWifiIsUnusableLoggingEnabled(WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING); + mWifiMetrics.setLinkSpeedCountsLoggingEnabled(LINK_SPEED_COUNTS_LOGGING_SETTING); mWifiMetrics.setWifiDataStallMinTxBad(DATA_STALL_MIN_TX_BAD_SETTING); mWifiMetrics.setWifiDataStallMinRxWithoutTx(DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING); } @@ -999,6 +1002,8 @@ public class WifiMetricsTest { mDecodedProto.wifiRadioUsage.scanTimeMs); assertEquals(WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING, mDecodedProto.experimentValues.wifiIsUnusableLoggingEnabled); + assertEquals(LINK_SPEED_COUNTS_LOGGING_SETTING, + mDecodedProto.experimentValues.linkSpeedCountsLoggingEnabled); assertEquals(DATA_STALL_MIN_TX_BAD_SETTING, mDecodedProto.experimentValues.wifiDataStallMinTxBad); assertEquals(DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING, @@ -2079,4 +2084,80 @@ public class WifiMetricsTest { verifyUnusableEvent(mDecodedProto.wifiIsUnusableEventList[1], 2); verifyUnusableEvent(mDecodedProto.wifiIsUnusableEventList[2], 3); } + + /** + * Verify that LinkSpeedCounts is correctly logged in metrics + */ + @Test + public void testLinkSpeedCounts() throws Exception { + when(mFacade.getIntegerSetting(eq(mContext), + eq(Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED), anyInt())).thenReturn(1); + mWifiMetrics.loadSettings(); + for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) { + for (int j = 0; j <= i; j++) { + mWifiMetrics.incrementLinkSpeedCount( + WifiMetrics.MIN_LINK_SPEED_MBPS + i, TEST_RSSI_LEVEL); + } + } + dumpProtoAndDeserialize(); + assertEquals(NUM_LINK_SPEED_LEVELS_TO_INCREMENT, mDecodedProto.linkSpeedCounts.length); + for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) { + assertEquals("Incorrect link speed", WifiMetrics.MIN_LINK_SPEED_MBPS + i, + mDecodedProto.linkSpeedCounts[i].linkSpeedMbps); + assertEquals("Incorrect count of link speed", + i + 1, mDecodedProto.linkSpeedCounts[i].count); + assertEquals("Incorrect sum of absolute values of rssi values", + Math.abs(TEST_RSSI_LEVEL) * (i + 1), + mDecodedProto.linkSpeedCounts[i].rssiSumDbm); + assertEquals("Incorrect sum of squares of rssi values", + TEST_RSSI_LEVEL * TEST_RSSI_LEVEL * (i + 1), + mDecodedProto.linkSpeedCounts[i].rssiSumOfSquaresDbmSq); + } + } + + /** + * Verify that LinkSpeedCounts is not logged when disabled in settings + */ + @Test + public void testNoLinkSpeedCountsWhenDisabled() throws Exception { + when(mFacade.getIntegerSetting(eq(mContext), + eq(Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED), anyInt())).thenReturn(0); + mWifiMetrics.loadSettings(); + for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) { + for (int j = 0; j <= i; j++) { + mWifiMetrics.incrementLinkSpeedCount( + WifiMetrics.MIN_LINK_SPEED_MBPS + i, TEST_RSSI_LEVEL); + } + } + dumpProtoAndDeserialize(); + assertEquals("LinkSpeedCounts should not be logged when disabled in settings", + 0, mDecodedProto.linkSpeedCounts.length); + } + + /** + * Verify that LinkSpeedCounts is not logged when the link speed value is lower than + * MIN_LINK_SPEED_MBPS or when the rssi value is outside of + * [MIN_RSSI_LEVEL, MAX_RSSI_LEVEL] + */ + @Test + public void testNoLinkSpeedCountsForOutOfBoundValues() throws Exception { + when(mFacade.getIntegerSetting(eq(mContext), + eq(Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED), anyInt())).thenReturn(1); + mWifiMetrics.loadSettings(); + for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) { + mWifiMetrics.incrementLinkSpeedCount( + WifiMetrics.MIN_LINK_SPEED_MBPS - i, MIN_RSSI_LEVEL); + } + for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) { + mWifiMetrics.incrementLinkSpeedCount( + WifiMetrics.MIN_LINK_SPEED_MBPS, MIN_RSSI_LEVEL - i); + } + for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) { + mWifiMetrics.incrementLinkSpeedCount( + WifiMetrics.MIN_LINK_SPEED_MBPS, MAX_RSSI_LEVEL + i); + } + dumpProtoAndDeserialize(); + assertEquals("LinkSpeedCounts should not be logged for out of bound values", + 0, mDecodedProto.linkSpeedCounts.length); + } } |