Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28f58812 authored by Yifan Hong's avatar Yifan Hong Committed by Automerger Merge Worker
Browse files

Merge "GetBatteryInfo() also reads AIDL health HAL." am: d33b067f am: 9113d574 am: 905def0b

Original change: https://android-review.googlesource.com/c/platform/bootable/recovery/+/1906334

Change-Id: Ic4bf79cb42825823f2a63c452d0d6554c218d450
parents 9254de8e 905def0b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ cc_binary {
    ],

    shared_libs: [
        "android.hardware.health-V1-ndk", // from librecovery_utils
        "librecovery_ui",
    ],

+2 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ cc_binary {
    ],

    shared_libs: [
        "android.hardware.health-V1-ndk", // from librecovery_utils
        "libbase",
        "libcrypto",
    ],
@@ -128,6 +129,7 @@ cc_test {
    ],

    static_libs: [
        "android.hardware.health-V1-ndk", // from librecovery_utils
        "libminadbd_services",
        "libfusesideload",
        "librecovery_utils",
+12 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ cc_defaults {
    shared_libs: [
        "android.hardware.health@2.0",
        "libbase",
        "libbinder_ndk",
        "libext4_utils",
        "libfs_mgr",
        "libhidlbase",
@@ -42,8 +43,10 @@ cc_defaults {
        "libotautil",

        // External dependencies.
        "android.hardware.health-translate-ndk",
        "libfstab",
        "libhealthhalutils",
        "libhealthshim",
    ],
}

@@ -70,6 +73,15 @@ cc_library_static {
        "libvold_headers",
    ],

    shared_libs: [
        // The following cannot be placed in librecovery_utils_defaults,
        // because at the time of writing, android.hardware.health-V1-ndk.so
        // is not installed to the system image yet. (It is installed
        // to the recovery ramdisk.) Hence, minadbd_test must link to it
        // statically.
        "android.hardware.health-V1-ndk",
    ],

    export_include_dirs: [
        "include",
    ],
+45 −28
Original line number Diff line number Diff line
@@ -20,59 +20,74 @@
#include <unistd.h>

#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <health-shim/shim.h>
#include <healthhalutils/HealthHalUtils.h>

BatteryInfo GetBatteryInfo() {
  using android::hardware::health::V1_0::BatteryStatus;
  using android::hardware::health::V2_0::get_health_service;
  using android::hardware::health::V2_0::IHealth;
  using android::hardware::health::V2_0::Result;
  using android::hardware::health::V2_0::toString;
  using HidlHealth = android::hardware::health::V2_0::IHealth;
  using aidl::android::hardware::health::BatteryStatus;
  using aidl::android::hardware::health::HealthShim;
  using aidl::android::hardware::health::IHealth;
  using aidl::android::hardware::health::toString;
  using std::string_literals::operator""s;

  android::sp<IHealth> health = get_health_service();
  auto service_name = IHealth::descriptor + "/default"s;
  std::shared_ptr<IHealth> health;
  if (AServiceManager_isDeclared(service_name.c_str())) {
    ndk::SpAIBinder binder(AServiceManager_waitForService(service_name.c_str()));
    health = IHealth::fromBinder(binder);
  }
  if (health == nullptr) {
    LOG(INFO) << "Unable to get AIDL health service, trying HIDL...";
    android::sp<HidlHealth> hidl_health = get_health_service();
    if (hidl_health != nullptr) {
      health = ndk::SharedRefBase::make<HealthShim>(hidl_health);
    }
  }
  if (health == nullptr) {
    LOG(WARNING) << "No health implementation is found; assuming defaults";
  }

  int wait_second = 0;
  while (true) {
    auto charge_status = BatteryStatus::UNKNOWN;

    if (health == nullptr) {
      LOG(WARNING) << "No health implementation is found; assuming defaults";
    } else {
      health
          ->getChargeStatus([&charge_status](auto res, auto out_status) {
            if (res == Result::SUCCESS) {
              charge_status = out_status;
    if (health != nullptr) {
      auto res = health->getChargeStatus(&charge_status);
      if (!res.isOk()) {
        LOG(WARNING) << "Unable to call getChargeStatus: " << res.getDescription();
        charge_status = BatteryStatus::UNKNOWN;
      }
          })
          .isOk();  // should not have transport error
    }

    // Treat unknown status as on charger. See hardware/interfaces/health/1.0/types.hal for the
    // meaning of the return values.
    // Treat unknown status as on charger. See hardware/interfaces/health/aidl/BatteryStatus.aidl
    // for the meaning of the return values.
    bool charging = (charge_status != BatteryStatus::DISCHARGING &&
                     charge_status != BatteryStatus::NOT_CHARGING);

    Result res = Result::UNKNOWN;
    int32_t capacity = INT32_MIN;
    if (health != nullptr) {
      health
          ->getCapacity([&res, &capacity](auto out_res, auto out_capacity) {
            res = out_res;
            capacity = out_capacity;
          })
          .isOk();  // should not have transport error
      auto res = health->getCapacity(&capacity);
      if (!res.isOk()) {
        LOG(WARNING) << "Unable to call getCapacity: " << res.getDescription();
        capacity = INT32_MIN;
      }
    }

    LOG(INFO) << "charge_status " << toString(charge_status) << ", charging " << charging
              << ", status " << toString(res) << ", capacity " << capacity;
              << ", capacity " << capacity;

    constexpr int BATTERY_READ_TIMEOUT_IN_SEC = 10;
    // At startup, the battery drivers in devices like N5X/N6P take some time to load
    // the battery profile. Before the load finishes, it reports value 50 as a fake
    // capacity. BATTERY_READ_TIMEOUT_IN_SEC is set that the battery drivers are expected
    // to finish loading the battery profile earlier than 10 seconds after kernel startup.
    if (res == Result::SUCCESS && capacity == 50) {
    if (capacity == 50) {
      if (wait_second < BATTERY_READ_TIMEOUT_IN_SEC) {
        LOG(INFO) << "Battery capacity == 50, waiting "
                  << (BATTERY_READ_TIMEOUT_IN_SEC - wait_second)
                  << " seconds to ensure this is not a fake value...";
        sleep(1);
        wait_second++;
        continue;
@@ -80,10 +95,12 @@ BatteryInfo GetBatteryInfo() {
    }
    // If we can't read battery percentage, it may be a device without battery. In this
    // situation, use 100 as a fake battery percentage.
    if (res != Result::SUCCESS) {
    if (capacity == INT32_MIN) {
      LOG(WARNING) << "Using fake battery capacity 100.";
      capacity = 100;
    }

    LOG(INFO) << "GetBatteryInfo() reporting charging " << charging << ", capacity " << capacity;
    return BatteryInfo{ charging, capacity };
  }
}
+7 −0
Original line number Diff line number Diff line
@@ -138,7 +138,14 @@ cc_test {
        "unit/*.cpp",
    ],

    shared_libs: [
        "libbinder_ndk",
    ],

    static_libs: libapplypatch_static_libs + librecovery_static_libs + [
        "android.hardware.health-translate-ndk",
        "android.hardware.health-V1-ndk",
        "libhealthshim",
        "librecovery_ui",
        "libfusesideload",
        "libminui",