Fastbootd: Use Fastboot AIDL with the help of fastbootshim for legacy fastboot HAL

Bug: 205760652
Test: build & flash & reboot fastboot
Change-Id: I79617a396f536258655bdc28006ac2d0a7ab1912
Signed-off-by: Sandeep Dhavale <dhavale@google.com>
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index eed49fa..765174b 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -168,6 +168,7 @@
         "android.hardware.boot-V1-ndk",
         "libboot_control_client",
         "android.hardware.fastboot@1.1",
+        "android.hardware.fastboot-V1-ndk",
         "android.hardware.health@2.0",
         "android.hardware.health-V1-ndk",
         "libasyncio",
@@ -192,6 +193,7 @@
         "libc++fs",
         "libhealthhalutils",
         "libhealthshim",
+        "libfastbootshim",
         "libsnapshot_cow",
         "liblz4",
         "libsnapshot_nobinder",
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 3799d1f..f8befd3 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -57,8 +57,6 @@
 using android::fs_mgr::MetadataBuilder;
 using android::hal::CommandResult;
 using ::android::hardware::hidl_string;
-using ::android::hardware::fastboot::V1_0::Result;
-using ::android::hardware::fastboot::V1_0::Status;
 using android::snapshot::SnapshotManager;
 using MergeStatus = android::hal::BootControlClient::MergeStatus;
 
@@ -203,20 +201,21 @@
         return false;
     }
 
-    Result ret;
-    auto ret_val = fastboot_hal->doOemSpecificErase([&](Result result) { ret = result; });
-    if (!ret_val.isOk()) {
-        return false;
-    }
-    if (ret.status == Status::NOT_SUPPORTED) {
-        return false;
-    } else if (ret.status != Status::SUCCESS) {
-        device->WriteStatus(FastbootResult::FAIL, ret.message);
-    } else {
+    auto status = fastboot_hal->doOemSpecificErase();
+    if (status.isOk()) {
         device->WriteStatus(FastbootResult::OKAY, "Erasing succeeded");
+        return true;
     }
-
-    return true;
+    switch (status.getExceptionCode()) {
+        case EX_UNSUPPORTED_OPERATION:
+            return false;
+        case EX_SERVICE_SPECIFIC:
+            device->WriteStatus(FastbootResult::FAIL, status.getDescription());
+            return false;
+        default:
+            LOG(ERROR) << "Erase operation failed" << status.getDescription();
+            return false;
+    }
 }
 
 bool EraseHandler(FastbootDevice* device, const std::vector<std::string>& args) {
@@ -266,18 +265,16 @@
     if (args[0] == "oem postwipedata userdata") {
         return device->WriteStatus(FastbootResult::FAIL, "Unable to do oem postwipedata userdata");
     }
-
-    Result ret;
-    auto ret_val = fastboot_hal->doOemCommand(args[0], [&](Result result) { ret = result; });
-    if (!ret_val.isOk()) {
-        return device->WriteStatus(FastbootResult::FAIL, "Unable to do OEM command");
-    }
-    if (ret.status != Status::SUCCESS) {
-        return device->WriteStatus(FastbootResult::FAIL, ret.message);
+    std::string message;
+    auto status = fastboot_hal->doOemCommand(args[0], &message);
+    if (!status.isOk()) {
+        LOG(ERROR) << "Unable to do OEM command " << args[0].c_str() << status.getDescription();
+        return device->WriteStatus(FastbootResult::FAIL,
+                                   "Unable to do OEM command " + status.getDescription());
     }
 
-    device->WriteInfo(ret.message);
-    return device->WriteStatus(FastbootResult::OKAY, ret.message);
+    device->WriteInfo(message);
+    return device->WriteStatus(FastbootResult::OKAY, message);
 }
 
 bool DownloadHandler(FastbootDevice* device, const std::vector<std::string>& args) {
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 4932e5c..5afeb4f 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -25,6 +25,7 @@
 #include <android/binder_manager.h>
 #include <android/hardware/boot/1.0/IBootControl.h>
 #include <android/hardware/fastboot/1.1/IFastboot.h>
+#include <fastbootshim.h>
 #include <fs_mgr.h>
 #include <fs_mgr/roots.h>
 #include <health-shim/shim.h>
@@ -64,6 +65,27 @@
     return nullptr;
 }
 
+std::shared_ptr<aidl::android::hardware::fastboot::IFastboot> get_fastboot_service() {
+    using aidl::android::hardware::fastboot::IFastboot;
+    using HidlFastboot = android::hardware::fastboot::V1_1::IFastboot;
+    using aidl::android::hardware::fastboot::FastbootShim;
+    auto service_name = IFastboot::descriptor + "/default"s;
+    ndk::SpAIBinder binder(AServiceManager_getService(service_name.c_str()));
+    std::shared_ptr<IFastboot> fastboot = IFastboot::fromBinder(binder);
+    if (fastboot != nullptr) {
+        LOG(INFO) << "Using AIDL fastboot service";
+        return fastboot;
+    }
+    LOG(INFO) << "Unable to get AIDL fastboot service, trying HIDL...";
+    android::sp<HidlFastboot> hidl_fastboot = HidlFastboot::getService();
+    if (hidl_fastboot != nullptr) {
+        LOG(INFO) << "Found and now using fastboot HIDL implementation";
+        return ndk::SharedRefBase::make<FastbootShim>(hidl_fastboot);
+    }
+    LOG(WARNING) << "No fastboot implementation is found.";
+    return nullptr;
+}
+
 FastbootDevice::FastbootDevice()
     : kCommandMap({
               {FB_CMD_SET_ACTIVE, SetActiveHandler},
@@ -87,7 +109,7 @@
       }),
       boot_control_hal_(BootControlClient::WaitForService()),
       health_hal_(get_health_service()),
-      fastboot_hal_(IFastboot::getService()),
+      fastboot_hal_(get_fastboot_service()),
       active_slot_("") {
     if (android::base::GetProperty("fastbootd.protocol", "usb") == "tcp") {
         transport_ = std::make_unique<ClientTcpTransport>();
diff --git a/fastboot/device/fastboot_device.h b/fastboot/device/fastboot_device.h
index 9df8fa5..fcaf249 100644
--- a/fastboot/device/fastboot_device.h
+++ b/fastboot/device/fastboot_device.h
@@ -23,8 +23,8 @@
 #include <vector>
 
 #include <BootControlClient.h>
+#include <aidl/android/hardware/fastboot/IFastboot.h>
 #include <aidl/android/hardware/health/IHealth.h>
-#include <android/hardware/fastboot/1.1/IFastboot.h>
 
 #include "commands.h"
 #include "transport.h"
@@ -52,7 +52,7 @@
     Transport* get_transport() { return transport_.get(); }
     BootControlClient* boot_control_hal() const { return boot_control_hal_.get(); }
     BootControlClient* boot1_1() const;
-    android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal() {
+    std::shared_ptr<aidl::android::hardware::fastboot::IFastboot> fastboot_hal() {
         return fastboot_hal_;
     }
     std::shared_ptr<aidl::android::hardware::health::IHealth> health_hal() { return health_hal_; }
@@ -65,7 +65,7 @@
     std::unique_ptr<Transport> transport_;
     std::unique_ptr<BootControlClient> boot_control_hal_;
     std::shared_ptr<aidl::android::hardware::health::IHealth> health_hal_;
-    android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal_;
+    std::shared_ptr<aidl::android::hardware::fastboot::IFastboot> fastboot_hal_;
     std::vector<char> download_data_;
     std::string active_slot_;
 };
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index b6eb2cd..5f99656 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -41,9 +41,7 @@
 #endif
 
 using MergeStatus = android::hal::BootControlClient::MergeStatus;
-using ::android::hardware::fastboot::V1_0::FileSystemType;
-using ::android::hardware::fastboot::V1_0::Result;
-using ::android::hardware::fastboot::V1_0::Status;
+using aidl::android::hardware::fastboot::FileSystemType;
 using namespace android::fs_mgr;
 using namespace std::string_literals;
 
@@ -104,17 +102,16 @@
         *message = "Fastboot HAL not found";
         return false;
     }
+    std::string device_variant = "";
+    auto status = fastboot_hal->getVariant(&device_variant);
 
-    Result ret;
-    auto ret_val = fastboot_hal->getVariant([&](std::string device_variant, Result result) {
-        *message = device_variant;
-        ret = result;
-    });
-    if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
+    if (!status.isOk()) {
         *message = "Unable to get device variant";
+        LOG(ERROR) << message->c_str() << status.getDescription();
         return false;
     }
 
+    *message = device_variant;
     return true;
 }
 
@@ -147,17 +144,14 @@
         return false;
     }
 
-    Result ret;
-    auto ret_val = fastboot_hal->getBatteryVoltageFlashingThreshold(
-            [&](int32_t voltage_threshold, Result result) {
-                *message = battery_voltage >= voltage_threshold ? "yes" : "no";
-                ret = result;
-            });
-
-    if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
+    auto voltage_threshold = 0;
+    auto status = fastboot_hal->getBatteryVoltageFlashingThreshold(&voltage_threshold);
+    if (!status.isOk()) {
         *message = "Unable to get battery voltage flashing threshold";
+        LOG(ERROR) << message->c_str() << status.getDescription();
         return false;
     }
+    *message = battery_voltage >= voltage_threshold ? "yes" : "no";
 
     return true;
 }
@@ -169,18 +163,14 @@
         *message = "Fastboot HAL not found";
         return false;
     }
-
-    Result ret;
-    auto ret_val =
-            fastboot_hal->getOffModeChargeState([&](bool off_mode_charging_state, Result result) {
-                *message = off_mode_charging_state ? "1" : "0";
-                ret = result;
-            });
-    if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
+    bool off_mode_charging_state = false;
+    auto status = fastboot_hal->getOffModeChargeState(&off_mode_charging_state);
+    if (!status.isOk()) {
         *message = "Unable to get off mode charge state";
+        LOG(ERROR) << message->c_str() << status.getDescription();
         return false;
     }
-
+    *message = off_mode_charging_state ? "1" : "0";
     return true;
 }
 
@@ -337,14 +327,11 @@
     }
 
     FileSystemType type;
-    Result ret;
-    auto ret_val =
-            fastboot_hal->getPartitionType(args[0], [&](FileSystemType fs_type, Result result) {
-                type = fs_type;
-                ret = result;
-            });
-    if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
+    auto status = fastboot_hal->getPartitionType(args[0], &type);
+
+    if (!status.isOk()) {
         *message = "Unable to retrieve partition type";
+        LOG(ERROR) << message->c_str() << status.getDescription();
     } else {
         switch (type) {
             case FileSystemType::RAW: