summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormukesh agrawal <quiche@google.com>2016-08-11 17:22:12 -0700
committerGlen Kuhne <kuh@google.com>2016-08-29 15:52:15 -0700
commita284841edf33e4070748816a034c47f996bfeb81 (patch)
treeca46597c92844f9af5d9f359c95b441cb4475d4f
parent924ef8d3df3bb7b36750b26f1cb9542d01aaabb3 (diff)
downloadwifi-a284841edf33e4070748816a034c47f996bfeb81.tar.gz
WifiMetrics: add metric for alert reasons
Add metric to track the number of alerts triggered by Wifi driver/firmware. This will give us a concrete measurement of stability in the field. BUG=29158746 TEST=tests/wifitests/runtests.sh Change-Id: I435e5d792a97c197fe685e5b2c05d7b8efda62f0
-rw-r--r--service/java/com/android/server/wifi/WifiLoggerHal.java5
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java50
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java4
-rw-r--r--service/proto/wifi.proto12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java64
5 files changed, 125 insertions, 10 deletions
diff --git a/service/java/com/android/server/wifi/WifiLoggerHal.java b/service/java/com/android/server/wifi/WifiLoggerHal.java
index 8a0276480..0294e9bf7 100644
--- a/service/java/com/android/server/wifi/WifiLoggerHal.java
+++ b/service/java/com/android/server/wifi/WifiLoggerHal.java
@@ -46,4 +46,9 @@ public class WifiLoggerHal {
public static final byte RX_PKT_FATE_DRV_DROP_INVALID = 8;
public static final byte RX_PKT_FATE_DRV_DROP_NOBUFS = 9;
public static final byte RX_PKT_FATE_DRV_DROP_OTHER = 10;
+
+ /** These aren't formally part of the HAL. But they probably should be, eventually. */
+ public static final byte WIFI_ALERT_REASON_RESERVED = 0;
+ public static final byte WIFI_ALERT_REASON_MIN = 0;
+ public static final byte WIFI_ALERT_REASON_MAX = 64;
}
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 0dc5ccf2e..4547466c3 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -76,11 +76,14 @@ public class WifiMetrics {
* combination. Indexed by WifiLog.WifiState * (1 + screenOn)
*/
private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray();
+ /** Mapping of RSSI values to counts. */
+ private final SparseIntArray mRssiPollCounts = new SparseIntArray();
+ /** Mapping of alert reason to the respective alert count. */
+ private final SparseIntArray mWifiAlertReasonCounts = new SparseIntArray();
/**
* Records the elapsedRealtime (in seconds) that represents the beginning of data
* capture for for this WifiMetricsProto
*/
- private final SparseIntArray mRssiPollCounts = new SparseIntArray();
private long mRecordStartTimeSec;
class RouterFingerPrint {
@@ -806,6 +809,22 @@ public class WifiMetrics {
}
}
+ /**
+ * Increments the count of alerts by alert reason.
+ *
+ * @param reason The cause of the alert. The reason values are driver-specific.
+ */
+ public void incrementAlertReasonCount(int reason) {
+ if (reason > WifiLoggerHal.WIFI_ALERT_REASON_MAX
+ || reason < WifiLoggerHal.WIFI_ALERT_REASON_MIN) {
+ reason = WifiLoggerHal.WIFI_ALERT_REASON_RESERVED;
+ }
+ synchronized (mLock) {
+ int alertCount = mWifiAlertReasonCounts.get(reason);
+ mWifiAlertReasonCounts.put(reason, alertCount + 1);
+ }
+ }
+
public static final String PROTO_DUMP_ARG = "wifiMetricsProto";
/**
* Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager
@@ -930,6 +949,21 @@ public class WifiMetrics {
sb.append(mRssiPollCounts.get(i) + " ");
}
pw.println(" " + sb.toString());
+ pw.print("mWifiLogProto.alertReasonCounts=");
+ sb.setLength(0);
+ for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN;
+ i <= WifiLoggerHal.WIFI_ALERT_REASON_MAX; i++) {
+ int count = mWifiAlertReasonCounts.get(i);
+ if (count > 0) {
+ sb.append("(" + i + "," + count + "),");
+ }
+ }
+ if (sb.length() > 1) {
+ sb.setLength(sb.length() - 1); // strip trailing comma
+ pw.println(sb.toString());
+ } else {
+ pw.println("()");
+ }
}
}
}
@@ -943,6 +977,7 @@ public class WifiMetrics {
private void consolidateProto(boolean incremental) {
List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>();
List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>();
+ List<WifiMetricsProto.AlertReasonCount> alertReasons = new ArrayList<>();
synchronized (mLock) {
for (ConnectionEvent event : mConnectionEventList) {
// If this is not incremental, dump full ConnectionEvent list
@@ -1000,6 +1035,18 @@ public class WifiMetrics {
rssis.add(keyVal);
}
mWifiLogProto.rssiPollRssiCount = rssis.toArray(mWifiLogProto.rssiPollRssiCount);
+
+ /**
+ * Convert the SparseIntArray of alert reasons and counts to the proto's repeated
+ * IntKeyVal array.
+ */
+ for (int i = 0; i < mWifiAlertReasonCounts.size(); i++) {
+ WifiMetricsProto.AlertReasonCount keyVal = new WifiMetricsProto.AlertReasonCount();
+ keyVal.reason = mWifiAlertReasonCounts.keyAt(i);
+ keyVal.count = mWifiAlertReasonCounts.valueAt(i);
+ alertReasons.add(keyVal);
+ }
+ mWifiLogProto.alertReasonCount = alertReasons.toArray(mWifiLogProto.alertReasonCount);
}
}
@@ -1016,6 +1063,7 @@ public class WifiMetrics {
mWifiSystemStateEntries.clear();
mRecordStartTimeSec = mClock.elapsedRealtime() / 1000;
mRssiPollCounts.clear();
+ mWifiAlertReasonCounts.clear();
mWifiLogProto.clear();
}
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 603c4757c..541d72755 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -4189,7 +4189,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
case CMD_FIRMWARE_ALERT:
if (mWifiLogger != null) {
byte[] buffer = (byte[])message.obj;
- mWifiLogger.captureAlertData(message.arg1, buffer);
+ int alertReason = message.arg1;
+ mWifiLogger.captureAlertData(alertReason, buffer);
+ mWifiMetrics.incrementAlertReasonCount(alertReason);
}
break;
case CMD_GET_LINK_LAYER_STATS:
diff --git a/service/proto/wifi.proto b/service/proto/wifi.proto
index 3b0e8544b..05ca06de8 100644
--- a/service/proto/wifi.proto
+++ b/service/proto/wifi.proto
@@ -189,6 +189,9 @@ message WifiLog {
// Counts the occurrences of each individual RSSI poll level
repeated RssiPollCount rssi_poll_rssi_count = 35;
+
+ // Counts the occurrences of each alert reason.
+ repeated AlertReasonCount alert_reason_count = 47;
}
// Information that gets logged for every WiFi connection.
@@ -349,3 +352,12 @@ message RssiPollCount {
// Number of RSSI polls with 'rssi'
optional int32 count = 2;
}
+
+// Number of occurrences of a specific alert reason value
+message AlertReasonCount {
+ // Alert reason
+ optional int32 reason = 1;
+
+ // Number of alerts with |reason|.
+ optional int32 count = 2;
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 011682b81..b10f5734a 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -104,15 +104,32 @@ public class WifiMetricsTest {
mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
}
+ /** Verifies that dump() includes the expected header */
@Test
- public void dumpHumanReadable() throws Exception {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- PrintWriter writer = new PrintWriter(stream);
- String[] args = new String[0];
- mWifiMetrics.dump(null, writer, args);
- writer.flush();
- assertTrue("stream.toString().contains(\"WifiMetrics\")",
- stream.toString().contains("WifiMetrics"));
+ public void stateDumpIncludesHeader() throws Exception {
+ assertStringContains(getStateDump(), "WifiMetrics");
+ }
+
+ /** Verifies that dump() includes correct alert count when there are no alerts. */
+ @Test
+ public void stateDumpAlertCountIsCorrectWithNoAlerts() throws Exception {
+ assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=()");
+ }
+
+ /** Verifies that dump() includes correct alert count when there is one alert. */
+ @Test
+ public void stateDumpAlertCountIsCorrectWithOneAlert() throws Exception {
+ mWifiMetrics.incrementAlertReasonCount(1);
+ assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,1)");
+ }
+
+ /** Verifies that dump() includes correct alert count when there are multiple alerts. */
+ @Test
+ public void stateDumpAlertCountIsCorrectWithMultipleAlerts() throws Exception {
+ mWifiMetrics.incrementAlertReasonCount(1);
+ mWifiMetrics.incrementAlertReasonCount(1);
+ mWifiMetrics.incrementAlertReasonCount(16);
+ assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,2),(16,1)");
}
@Test
@@ -243,6 +260,14 @@ public class WifiMetricsTest {
mWifiMetrics.incrementRssiPollRssiCount(FIRST_RSSI_LEVEL + i);
}
}
+ // Test alert-reason clamping.
+ mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MIN - 1);
+ mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MAX + 1);
+ // Simple cases for alert reason.
+ mWifiMetrics.incrementAlertReasonCount(1);
+ mWifiMetrics.incrementAlertReasonCount(1);
+ mWifiMetrics.incrementAlertReasonCount(1);
+ mWifiMetrics.incrementAlertReasonCount(2);
}
/**
@@ -324,6 +349,10 @@ public class WifiMetricsTest {
assertEquals(FIRST_RSSI_LEVEL + i, mDeserializedWifiMetrics.rssiPollRssiCount[i].rssi);
assertEquals(i + 1, mDeserializedWifiMetrics.rssiPollRssiCount[i].count);
}
+ assertEquals(2, mDeserializedWifiMetrics.alertReasonCount[0].count); // Clamped reasons.
+ assertEquals(3, mDeserializedWifiMetrics.alertReasonCount[1].count);
+ assertEquals(1, mDeserializedWifiMetrics.alertReasonCount[2].count);
+ assertEquals(3, mDeserializedWifiMetrics.alertReasonCount.length);
}
/**
@@ -461,6 +490,8 @@ public class WifiMetricsTest {
dumpProtoAndDeserialize();
//Check there are only 3 connection events
assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 4);
+ assertEquals(mDeserializedWifiMetrics.rssiPollRssiCount.length, 0);
+ assertEquals(mDeserializedWifiMetrics.alertReasonCount.length, 0);
// Create 2 ConnectionEvents
mWifiMetrics.startConnectionEvent(null, "BLUE",
@@ -479,4 +510,21 @@ public class WifiMetricsTest {
//Check there are only 2 connection events
assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
}
+
+ private void assertStringContains(
+ String actualString, String expectedSubstring) {
+ assertTrue("Expected text not found in: " + actualString,
+ actualString.contains(expectedSubstring));
+ }
+
+ private String getStateDump() {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(stream);
+ String[] args = new String[0];
+ mWifiMetrics.dump(null, writer, args);
+ writer.flush();
+ return stream.toString();
+ }
}
+
+