GetBatteryInfo() also reads AIDL health HAL.
Test: call GetBatteryInfo manually with and without AIDL health HAL Bug: 170338625 Bug: 177269435 Change-Id: I123739e5bc372d5198fd711f592ceac04d46ab28
This commit is contained in:
parent
436a520a57
commit
67a8fd2175
5 changed files with 67 additions and 28 deletions
|
@ -157,6 +157,7 @@ cc_binary {
|
||||||
],
|
],
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
"android.hardware.health-V1-ndk", // from librecovery_utils
|
||||||
"librecovery_ui",
|
"librecovery_ui",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ cc_binary {
|
||||||
],
|
],
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
"android.hardware.health-V1-ndk", // from librecovery_utils
|
||||||
"libbase",
|
"libbase",
|
||||||
"libcrypto",
|
"libcrypto",
|
||||||
],
|
],
|
||||||
|
@ -128,6 +129,7 @@ cc_test {
|
||||||
],
|
],
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
|
"android.hardware.health-V1-ndk", // from librecovery_utils
|
||||||
"libminadbd_services",
|
"libminadbd_services",
|
||||||
"libfusesideload",
|
"libfusesideload",
|
||||||
"librecovery_utils",
|
"librecovery_utils",
|
||||||
|
|
|
@ -31,6 +31,7 @@ cc_defaults {
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"android.hardware.health@2.0",
|
"android.hardware.health@2.0",
|
||||||
"libbase",
|
"libbase",
|
||||||
|
"libbinder_ndk",
|
||||||
"libext4_utils",
|
"libext4_utils",
|
||||||
"libfs_mgr",
|
"libfs_mgr",
|
||||||
"libhidlbase",
|
"libhidlbase",
|
||||||
|
@ -42,8 +43,10 @@ cc_defaults {
|
||||||
"libotautil",
|
"libotautil",
|
||||||
|
|
||||||
// External dependencies.
|
// External dependencies.
|
||||||
|
"android.hardware.health-translate-ndk",
|
||||||
"libfstab",
|
"libfstab",
|
||||||
"libhealthhalutils",
|
"libhealthhalutils",
|
||||||
|
"libhealthshim",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +73,15 @@ cc_library_static {
|
||||||
"libvold_headers",
|
"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: [
|
export_include_dirs: [
|
||||||
"include",
|
"include",
|
||||||
],
|
],
|
||||||
|
|
|
@ -20,59 +20,74 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
#include <android/binder_manager.h>
|
||||||
|
#include <health-shim/shim.h>
|
||||||
#include <healthhalutils/HealthHalUtils.h>
|
#include <healthhalutils/HealthHalUtils.h>
|
||||||
|
|
||||||
BatteryInfo GetBatteryInfo() {
|
BatteryInfo GetBatteryInfo() {
|
||||||
using android::hardware::health::V1_0::BatteryStatus;
|
|
||||||
using android::hardware::health::V2_0::get_health_service;
|
using android::hardware::health::V2_0::get_health_service;
|
||||||
using android::hardware::health::V2_0::IHealth;
|
using HidlHealth = android::hardware::health::V2_0::IHealth;
|
||||||
using android::hardware::health::V2_0::Result;
|
using aidl::android::hardware::health::BatteryStatus;
|
||||||
using android::hardware::health::V2_0::toString;
|
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;
|
int wait_second = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
auto charge_status = BatteryStatus::UNKNOWN;
|
auto charge_status = BatteryStatus::UNKNOWN;
|
||||||
|
if (health != nullptr) {
|
||||||
if (health == nullptr) {
|
auto res = health->getChargeStatus(&charge_status);
|
||||||
LOG(WARNING) << "No health implementation is found; assuming defaults";
|
if (!res.isOk()) {
|
||||||
} else {
|
LOG(WARNING) << "Unable to call getChargeStatus: " << res.getDescription();
|
||||||
health
|
charge_status = BatteryStatus::UNKNOWN;
|
||||||
->getChargeStatus([&charge_status](auto res, auto out_status) {
|
|
||||||
if (res == Result::SUCCESS) {
|
|
||||||
charge_status = out_status;
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.isOk(); // should not have transport error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat unknown status as on charger. See hardware/interfaces/health/1.0/types.hal for the
|
// Treat unknown status as on charger. See hardware/interfaces/health/aidl/BatteryStatus.aidl
|
||||||
// meaning of the return values.
|
// for the meaning of the return values.
|
||||||
bool charging = (charge_status != BatteryStatus::DISCHARGING &&
|
bool charging = (charge_status != BatteryStatus::DISCHARGING &&
|
||||||
charge_status != BatteryStatus::NOT_CHARGING);
|
charge_status != BatteryStatus::NOT_CHARGING);
|
||||||
|
|
||||||
Result res = Result::UNKNOWN;
|
|
||||||
int32_t capacity = INT32_MIN;
|
int32_t capacity = INT32_MIN;
|
||||||
if (health != nullptr) {
|
if (health != nullptr) {
|
||||||
health
|
auto res = health->getCapacity(&capacity);
|
||||||
->getCapacity([&res, &capacity](auto out_res, auto out_capacity) {
|
if (!res.isOk()) {
|
||||||
res = out_res;
|
LOG(WARNING) << "Unable to call getCapacity: " << res.getDescription();
|
||||||
capacity = out_capacity;
|
capacity = INT32_MIN;
|
||||||
})
|
}
|
||||||
.isOk(); // should not have transport error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "charge_status " << toString(charge_status) << ", charging " << charging
|
LOG(INFO) << "charge_status " << toString(charge_status) << ", charging " << charging
|
||||||
<< ", status " << toString(res) << ", capacity " << capacity;
|
<< ", capacity " << capacity;
|
||||||
|
|
||||||
constexpr int BATTERY_READ_TIMEOUT_IN_SEC = 10;
|
constexpr int BATTERY_READ_TIMEOUT_IN_SEC = 10;
|
||||||
// At startup, the battery drivers in devices like N5X/N6P take some time to load
|
// 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
|
// 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
|
// 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.
|
// 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) {
|
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);
|
sleep(1);
|
||||||
wait_second++;
|
wait_second++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -80,10 +95,12 @@ BatteryInfo GetBatteryInfo() {
|
||||||
}
|
}
|
||||||
// If we can't read battery percentage, it may be a device without battery. In this
|
// If we can't read battery percentage, it may be a device without battery. In this
|
||||||
// situation, use 100 as a fake battery percentage.
|
// 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;
|
capacity = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "GetBatteryInfo() reporting charging " << charging << ", capacity " << capacity;
|
||||||
return BatteryInfo{ charging, capacity };
|
return BatteryInfo{ charging, capacity };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,14 @@ cc_test {
|
||||||
"unit/*.cpp",
|
"unit/*.cpp",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
shared_libs: [
|
||||||
|
"libbinder_ndk",
|
||||||
|
],
|
||||||
|
|
||||||
static_libs: libapplypatch_static_libs + librecovery_static_libs + [
|
static_libs: libapplypatch_static_libs + librecovery_static_libs + [
|
||||||
|
"android.hardware.health-translate-ndk",
|
||||||
|
"android.hardware.health-V1-ndk",
|
||||||
|
"libhealthshim",
|
||||||
"librecovery_ui",
|
"librecovery_ui",
|
||||||
"libfusesideload",
|
"libfusesideload",
|
||||||
"libminui",
|
"libminui",
|
||||||
|
|
Loading…
Reference in a new issue