aboutsummaryrefslogtreecommitdiff
path: root/src/android_internal/health_hal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/android_internal/health_hal.cc')
-rw-r--r--src/android_internal/health_hal.cc127
1 files changed, 95 insertions, 32 deletions
diff --git a/src/android_internal/health_hal.cc b/src/android_internal/health_hal.cc
index 0d8ad05fb..f21af800e 100644
--- a/src/android_internal/health_hal.cc
+++ b/src/android_internal/health_hal.cc
@@ -16,67 +16,78 @@
#include "src/android_internal/health_hal.h"
+#include <aidl/android/hardware/health/IHealth.h>
+#include <android/binder_manager.h>
#include <android/hardware/health/2.0/IHealth.h>
#include <healthhalutils/HealthHalUtils.h>
namespace perfetto {
namespace android_internal {
-using ::android::hardware::health::V2_0::IHealth;
+using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+using ::aidl::android::hardware::health::IHealth;
+using ::android::hardware::Return;
using ::android::hardware::health::V2_0::Result;
namespace {
-android::sp<IHealth> g_svc;
+struct HealthService {
+ android::sp<HidlHealth> hidl;
+ std::shared_ptr<IHealth> aidl;
+};
+
+HealthService g_svc;
void ResetService() {
- g_svc = ::android::hardware::health::V2_0::get_health_service();
+ auto aidl_name = std::string(IHealth::descriptor) + "/default";
+ if (AServiceManager_isDeclared(aidl_name.c_str())) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(aidl_name.c_str()));
+ g_svc.aidl = IHealth::fromBinder(binder);
+ if (g_svc.aidl != nullptr) {
+ return;
+ }
+ }
+ g_svc.hidl = ::android::hardware::health::V2_0::get_health_service();
}
-} // namespace
-
-bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
- *value = 0;
- if (!g_svc)
- ResetService();
-
- if (!g_svc)
- return false;
-
- // The Android VNDK documentation states that for blocking services, the
+bool GetBatteryCounterHidl(BatteryCounter counter, int64_t* value) {
+ // The Android HIDL documentation states that for blocking services, the
// caller blocks until the reply is received and the callback is called inline
// in the same thread.
// See https://source.android.com/devices/architecture/hidl/threading .
- Result res;
+ Return<void> ret;
+ Result res = Result::UNKNOWN;
switch (counter) {
case BatteryCounter::kUnspecified:
- res = Result::NOT_FOUND;
break;
case BatteryCounter::kCharge:
- g_svc->getChargeCounter([&res, value](Result hal_res, int32_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getChargeCounter(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCapacityPercent:
- g_svc->getCapacity([&res, value](Result hal_res, int64_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getCapacity(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCurrent:
- g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getCurrentNow(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCurrentAvg:
- g_svc->getCurrentAverage(
+ ret = g_svc.hidl->getCurrentAverage(
[&res, value](Result hal_res, int32_t hal_value) {
res = hal_res;
*value = hal_value;
@@ -84,10 +95,62 @@ bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
break;
} // switch(counter)
- if (res == Result::CALLBACK_DIED)
- g_svc.clear();
+ if (ret.isDeadObject())
+ g_svc.hidl.clear();
+
+ return ret.isOk() && res == Result::SUCCESS;
+}
+
+bool GetBatteryCounterAidl(BatteryCounter counter, int64_t* value) {
+ ndk::ScopedAStatus status;
+ int32_t value32;
+
+ switch (counter) {
+ case BatteryCounter::kUnspecified:
+ return false;
+
+ case BatteryCounter::kCharge:
+ status = g_svc.aidl->getChargeCounterUah(&value32);
+ break;
+
+ case BatteryCounter::kCapacityPercent:
+ status = g_svc.aidl->getCapacity(&value32);
+ break;
+
+ case BatteryCounter::kCurrent:
+ status = g_svc.aidl->getCurrentNowMicroamps(&value32);
+ break;
+
+ case BatteryCounter::kCurrentAvg:
+ status = g_svc.aidl->getCurrentAverageMicroamps(&value32);
+ break;
+ } // switch(counter)
+
+ if (status.isOk()) {
+ *value = value32;
+ return true;
+ }
+
+ if (status.getStatus() == STATUS_DEAD_OBJECT)
+ g_svc.aidl.reset();
+
+ return false;
+}
+
+} // namespace
+
+bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
+ *value = 0;
+ if (!g_svc.aidl && !g_svc.hidl)
+ ResetService();
+
+ if (!g_svc.aidl && !g_svc.hidl)
+ return false;
+
+ if (g_svc.aidl)
+ return GetBatteryCounterAidl(counter, value);
- return res == Result::SUCCESS;
+ return GetBatteryCounterHidl(counter, value);
}
} // namespace android_internal