Wifi Usability Metrics Proto Update

Generate WifiIsUnusableEvent when there is a data stall or a firmware
alert. In WifiIsUnusableEvent, store metrics related to time, packet
counts, trigger reason, and score.

Also, log ExperimentValues that we plan to change through global
settings varaible.

This logging is enabled by setting WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED
to 1. By default, this metric is not collected.

Manual Check Process:
- Connect to a network
- adb shell settings put global wifi_is_unusable_event_metrics_enabled 1
- adb shell dumpsys wifi wifiMetricsProto
- Move away from the ap to trigger data stall
- adb shell dumpsys wifi | grep -10 WifiIsUnusableEventList
- Verify that there is a WifiIsUnusableEvent

Bug: 77603216
Test: Unittest (settings core/tests/coretests).
Test: Manual Check.
Change-Id: I2d8425a420f5ba18e3eee0e11b6f35f6239a97b2
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4534f48..3839938 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9910,6 +9910,31 @@
         public static final String WIFI_SCORE_PARAMS =
                 "wifi_score_params";
 
+        /**
+         * Setting to enable logging WifiIsUnusableEvent in metrics
+         * which gets triggered when wifi becomes unusable.
+         * Disabled by default, and setting it to 1 will enable it.
+         * @hide
+         */
+        public static final String WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED =
+                "wifi_is_unusable_event_metrics_enabled";
+
+        /**
+         * The minimum number of txBad the framework has to observe
+         * to trigger a wifi data stall.
+         * @hide
+         */
+        public static final String WIFI_DATA_STALL_MIN_TX_BAD =
+                "wifi_data_stall_min_tx_bad";
+
+        /**
+         * The minimum number of txSuccess the framework has to observe
+         * to trigger a wifi data stall when rxSuccess is 0.
+         * @hide
+         */
+        public static final String WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX =
+                "wifi_data_stall_min_tx_success_without_rx";
+
        /**
         * The maximum number of times we will retry a connection to an access
         * point for which we have failed in acquiring an IP address from DHCP.
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 14c641a..676d8d9 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -459,6 +459,8 @@
                     Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
                     Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
                     Settings.Global.WIFI_COUNTRY_CODE,
+                    Settings.Global.WIFI_DATA_STALL_MIN_TX_BAD,
+                    Settings.Global.WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX,
                     Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN,
                     Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
                     Settings.Global.WIFI_DISPLAY_ON,
@@ -468,6 +470,7 @@
                     Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
                     Settings.Global.WIFI_FREQUENCY_BAND,
                     Settings.Global.WIFI_IDLE_MS,
+                    Settings.Global.WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED,
                     Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
                     Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
                     Settings.Global.WIFI_NETWORK_SHOW_RSSI,
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index a23c6d3..4117148 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -459,6 +459,13 @@
 
   // Data on wifi radio usage
   optional WifiRadioUsage wifi_radio_usage = 118;
+
+  // Stores settings values used for metrics testing.
+  optional ExperimentValues experiment_values = 119;
+
+  // List of WifiIsUnusableEvents which get logged when we notice that WiFi is unusable.
+  // Collected only when WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED Settings is enabled.
+  repeated WifiIsUnusableEvent wifi_is_unusable_event_list = 120;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -876,7 +883,7 @@
     STATE_INVALID = 12;
   }
 
-  // Bit mask of all supplicant state changes that occured since the last event
+  // Bit mask of all supplicant state changes that occurred since the last event
   optional uint32 supplicant_state_changes_bitmask = 9 [default = 0];
 
   // The number of milliseconds that have elapsed since the device booted
@@ -884,7 +891,7 @@
 
   optional FrameworkDisconnectReason framework_disconnect_reason = 11 [default = DISCONNECT_UNKNOWN];
 
-  // Flag which indicates if an association rejection event occured due to a timeout
+  // Flag which indicates if an association rejection event occurred due to a timeout
   optional bool association_timed_out = 12 [default = false];
 
   // Authentication failure reason, as reported by WifiManager (calculated from state & deauth code)
@@ -1513,4 +1520,72 @@
 
   // Total time for which the radio is awake due to scan.
   optional int64 scan_time_ms = 2;
+}
+
+message ExperimentValues {
+  // Indicates if we are logging WifiIsUnusableEvent in metrics
+  optional bool wifi_is_unusable_logging_enabled = 1;
+
+  // Minimum number of txBad to trigger a data stall
+  optional int32 wifi_data_stall_min_tx_bad = 2;
+
+  // Minimum number of txSuccess to trigger a data stall
+  // when rxSuccess is 0
+  optional int32 wifi_data_stall_min_tx_success_without_rx = 3;
+}
+
+message WifiIsUnusableEvent {
+  enum TriggerType {
+    // Default/Invalid event
+    TYPE_UNKNOWN = 0;
+
+    // There is a data stall from tx failures
+    TYPE_DATA_STALL_BAD_TX = 1;
+
+    // There is a data stall from rx failures
+    TYPE_DATA_STALL_TX_WITHOUT_RX = 2;
+
+    // There is a data stall from both tx and rx failures
+    TYPE_DATA_STALL_BOTH = 3;
+
+    // Firmware generated an alert
+    TYPE_FIRMWARE_ALERT = 4;
+  }
+
+  // What event triggered WifiIsUnusableEvent.
+  optional TriggerType type = 1;
+
+  // The timestamp at which this event occurred.
+  // Measured in milliseconds that have elapsed since the device booted.
+  optional int64 start_time_millis = 2;
+
+  // NetworkAgent score of connected wifi.
+  // Defaults to -1 if the score was never set.
+  optional int32 last_score = 3 [default = -1];
+
+  // Delta of successfully transmitted (ACKed) unicast data packets
+  // between the last two WifiLinkLayerStats.
+  optional int64 tx_success_delta = 4;
+
+  // Delta of transmitted unicast data retry packets
+  // between the last two WifiLinkLayerStats.
+  optional int64 tx_retries_delta = 5;
+
+  // Delta of lost (not ACKed) transmitted unicast data packets
+  // between the last two WifiLinkLayerStats.
+  optional int64 tx_bad_delta = 6;
+
+  // Delta of received unicast data packets
+  // between the last two WifiLinkLayerStats.
+  optional int64 rx_success_delta = 7;
+
+  // Time in millisecond between the last two WifiLinkLayerStats.
+  optional int64 packet_update_time_delta = 8;
+
+  // The timestamp at which the last WifiLinkLayerStats was updated.
+  // Measured in milliseconds that have elapsed since the device booted.
+  optional int64 last_link_layer_stats_update_time = 9;
+
+  // Firmware alert code. Only valid when the event was triggered by a firmware alert, otherwise -1.
+  optional int32 firmware_alert_code = 10 [default = -1];
 }
\ No newline at end of file