Merge "Interface with health HAL to read battery voltage"
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 6b175af..38cf1bb 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -122,6 +122,7 @@
     shared_libs: [
         "android.hardware.boot@1.0",
         "android.hardware.fastboot@1.0",
+        "android.hardware.health@2.0",
         "libadbd",
         "libasyncio",
         "libbase",
@@ -139,6 +140,10 @@
         "libutils",
     ],
 
+    static_libs: [
+        "libhealthhalutils",
+    ],
+
     cpp_std: "c++17",
 }
 
diff --git a/fastboot/constants.h b/fastboot/constants.h
index c11d9de..2eaf006 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -62,3 +62,4 @@
 #define FB_VAR_HW_REVISION "hw-revision"
 #define FB_VAR_VARIANT "variant"
 #define FB_VAR_OFF_MODE_CHARGE_STATE "off-mode-charge"
+#define FB_VAR_BATTERY_VOLTAGE "battery-voltage"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 4fa1148..b02d968 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -96,6 +96,7 @@
             {FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}},
             {FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}},
             {FB_VAR_OFF_MODE_CHARGE_STATE, {GetOffModeChargeState, nullptr}},
+            {FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
             {FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}}};
 
     if (args.size() < 2) {
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 6862741..b843c05 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -20,6 +20,8 @@
 #include <android-base/strings.h>
 #include <android/hardware/boot/1.0/IBootControl.h>
 #include <android/hardware/fastboot/1.0/IFastboot.h>
+#include <healthhalutils/HealthHalUtils.h>
+
 #include <algorithm>
 
 #include "constants.h"
@@ -30,6 +32,8 @@
 using ::android::hardware::boot::V1_0::IBootControl;
 using ::android::hardware::boot::V1_0::Slot;
 using ::android::hardware::fastboot::V1_0::IFastboot;
+using ::android::hardware::health::V2_0::get_health_service;
+
 namespace sph = std::placeholders;
 
 FastbootDevice::FastbootDevice()
@@ -52,6 +56,7 @@
       }),
       transport_(std::make_unique<ClientUsbTransport>()),
       boot_control_hal_(IBootControl::getService()),
+      health_hal_(get_health_service()),
       fastboot_hal_(IFastboot::getService()) {}
 
 FastbootDevice::~FastbootDevice() {
diff --git a/fastboot/device/fastboot_device.h b/fastboot/device/fastboot_device.h
index 189cf80..2eb7177 100644
--- a/fastboot/device/fastboot_device.h
+++ b/fastboot/device/fastboot_device.h
@@ -24,6 +24,7 @@
 
 #include <android/hardware/boot/1.0/IBootControl.h>
 #include <android/hardware/fastboot/1.0/IFastboot.h>
+#include <android/hardware/health/2.0/IHealth.h>
 
 #include "commands.h"
 #include "transport.h"
@@ -53,12 +54,14 @@
     android::sp<android::hardware::fastboot::V1_0::IFastboot> fastboot_hal() {
         return fastboot_hal_;
     }
+    android::sp<android::hardware::health::V2_0::IHealth> health_hal() { return health_hal_; }
 
   private:
     const std::unordered_map<std::string, CommandHandler> kCommandMap;
 
     std::unique_ptr<Transport> transport_;
     android::sp<android::hardware::boot::V1_0::IBootControl> boot_control_hal_;
+    android::sp<android::hardware::health::V2_0::IHealth> health_hal_;
     android::sp<android::hardware::fastboot::V1_0::IFastboot> fastboot_hal_;
     std::vector<char> download_data_;
 };
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index bcf13a5..01415d7 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -24,6 +24,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <ext4_utils/ext4_utils.h>
+#include <healthhalutils/HealthHalUtils.h>
 
 #include "fastboot_device.h"
 #include "flashing.h"
@@ -117,6 +118,30 @@
     return true;
 }
 
+bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
+                       std::string* message) {
+    using android::hardware::health::V2_0::HealthInfo;
+    using android::hardware::health::V2_0::Result;
+
+    auto health_hal = device->health_hal();
+    if (!health_hal) {
+        *message = "Health HAL not found";
+        return false;
+    }
+
+    Result ret;
+    auto ret_val = health_hal->getHealthInfo([&](Result result, HealthInfo info) {
+        *message = std::to_string(info.legacy.batteryVoltage);
+        ret = result;
+    });
+    if (!ret_val.isOk() || (ret != Result::SUCCESS)) {
+        *message = "Unable to get battery voltage";
+        return false;
+    }
+
+    return true;
+}
+
 bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
                     std::string* message) {
     std::string suffix = device->GetCurrentSlot();
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
index b06881e..e7c3c7c 100644
--- a/fastboot/device/variables.h
+++ b/fastboot/device/variables.h
@@ -55,7 +55,8 @@
 bool GetVariant(FastbootDevice* device, const std::vector<std::string>& args, std::string* message);
 bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& args,
                            std::string* message);
-
+bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& args,
+                       std::string* message);
 // Helpers for getvar all.
 std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
 std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device);