Merge "Bluetooth hal metrics: Add LogBluetoothHalCrashReason"
diff --git a/common/metrics.cc b/common/metrics.cc
index 5d2365f..10eedc8 100644
--- a/common/metrics.cc
+++ b/common/metrics.cc
@@ -878,6 +878,28 @@
   }
 }
 
+void LogBluetoothHalCrashReason(const RawAddress& address, uint32_t error_code,
+                                uint32_t vendor_error_code) {
+  std::string obfuscated_id;
+  int metric_id = 0;
+  if (!address.IsEmpty()) {
+    obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
+    metric_id = MetricIdAllocator::GetInstance().AllocateId(address);
+  }
+  // nullptr and size 0 represent missing value for obfuscated_id
+  android::util::BytesField obfuscated_id_field(
+      address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
+      address.IsEmpty() ? 0 : obfuscated_id.size());
+  int ret = android::util::stats_write(
+      android::util::BLUETOOTH_HAL_CRASH_REASON_REPORTED, metric_id,
+      obfuscated_id_field, error_code, vendor_error_code);
+  if (ret < 0) {
+    LOG(WARNING) << __func__ << ": failed for " << address << ", error_code "
+                 << loghex(error_code) << ", vendor_error_code "
+                 << loghex(vendor_error_code) << ", error " << ret;
+  }
+}
+
 }  // namespace common
 
 }  // namespace bluetooth
diff --git a/common/metrics.h b/common/metrics.h
index c4fd14f..a36a64c 100644
--- a/common/metrics.h
+++ b/common/metrics.h
@@ -479,6 +479,16 @@
                          const std::string& model,
                          const std::string& hardware_version,
                          const std::string& software_version);
+
+/**
+ * Logs when received Bluetooth HAL crash reason report.
+ *
+ * @param address current connected address.
+ * @param error_code the crash reason from bluetooth hal
+ * @param vendor_error_code the vendor crash reason from bluetooth Firmware
+ */
+void LogBluetoothHalCrashReason(const RawAddress& address, uint32_t error_code,
+                                uint32_t vendor_error_code);
 }  // namespace common
 
 }  // namespace bluetooth
diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc
index 3c60aa9..7de2e0e 100644
--- a/hci/src/hci_layer.cc
+++ b/hci/src/hci_layer.cc
@@ -187,6 +187,10 @@
     }
     return;
   }
+  // The Bluetooth hal suddenly died and no root inflammation packet received.
+  // Record it with "Default" code.
+  bluetooth::common::LogBluetoothHalCrashReason(
+      RawAddress::kEmpty, 0x00 /*Default*/, 0x00 /*Default*/);
   abort();
 }
 
@@ -591,9 +595,14 @@
 }
 
 void handle_root_inflammation_event() {
-  LOG(ERROR) << __func__
-             << ": Root inflammation event! setting timer to restart.";
-  // TODO(ugoyu) Report to bluetooth metrics here
+  LOG(ERROR)
+      << __func__
+      << ": Root inflammation event! setting timer to restart. error_code: "
+      << loghex(root_inflamed_error_code)
+      << " vendor _error_code: " << loghex(root_inflamed_vendor_error_code);
+  bluetooth::common::LogBluetoothHalCrashReason(
+      RawAddress::kEmpty, root_inflamed_error_code,
+      root_inflamed_vendor_error_code);
   {
     // Try to stop hci command and startup timers
     std::unique_lock<std::recursive_timed_mutex> lock(