healthd: move global gHealth service pointer
... to class implementation::Health. Expose APIs
InitInstance(), GetImplmentation()
for its setter and getter.
Clients that statically links to android.hardware
.health@2.0-impl (e.g. charger, recovery)
should use InitInstance().
Test: health VTS tests
Bug: 63702641
Change-Id: I51b9b976d0b723dac1a03e5113d5d9e84300c0e9
diff --git a/healthd/Health.cpp b/healthd/Health.cpp
index 74f3eec..d271811 100644
--- a/healthd/Health.cpp
+++ b/healthd/Health.cpp
@@ -13,6 +13,8 @@
namespace V2_0 {
namespace implementation {
+sp<Health> Health::instance_;
+
Health::Health(struct healthd_config* c) {
battery_monitor_ = std::make_unique<BatteryMonitor>();
battery_monitor_->init(c);
@@ -154,7 +156,17 @@
(void)unregisterCallbackInternal(who.promote());
}
-// Methods from ::android::hidl::base::V1_0::IBase follow.
+sp<IHealth> Health::initInstance(struct healthd_config* c) {
+ if (instance_ == nullptr) {
+ instance_ = new Health(c);
+ }
+ return instance_;
+}
+
+sp<Health> Health::getImplementation() {
+ CHECK(instance_ != nullptr);
+ return instance_;
+}
} // namespace implementation
} // namespace V2_0
diff --git a/healthd/HealthServiceCommon.cpp b/healthd/HealthServiceCommon.cpp
index 260ca78..68ff526 100644
--- a/healthd/HealthServiceCommon.cpp
+++ b/healthd/HealthServiceCommon.cpp
@@ -33,9 +33,6 @@
using android::hardware::health::V2_0::IHealth;
using android::hardware::health::V2_0::implementation::Health;
-// see healthd_common.cpp
-android::sp<IHealth> gHealth;
-
extern int healthd_main(void);
static void binder_event(uint32_t /*epevents*/) {
@@ -63,8 +60,8 @@
// TODO(b/68724651): healthd_board_* functions should be removed in health@2.0
healthd_board_init(config);
- gHealth = new ::android::hardware::health::V2_0::implementation::Health(config);
- CHECK_EQ(gHealth->registerAsService(HEALTH_INSTANCE_NAME), android::OK)
+ android::sp<IHealth> service = Health::initInstance(config);
+ CHECK_EQ(service->registerAsService(HEALTH_INSTANCE_NAME), android::OK)
<< LOG_TAG << ": Failed to register HAL";
LOG(INFO) << LOG_TAG << ": Hal init done";
@@ -85,7 +82,7 @@
HealthInfo info;
convertToHealthInfo(prop, info);
- static_cast<Health*>(gHealth.get())->notifyListeners(info);
+ Health::getImplementation()->notifyListeners(info);
}
static struct healthd_mode_ops healthd_mode_service_2_0_ops = {
diff --git a/healthd/healthd_common.cpp b/healthd/healthd_common.cpp
index 19e600f..140c49d 100644
--- a/healthd/healthd_common.cpp
+++ b/healthd/healthd_common.cpp
@@ -91,7 +91,7 @@
#ifndef HEALTHD_USE_HEALTH_2_0
static BatteryMonitor* gBatteryMonitor = nullptr;
#else
-extern sp<::android::hardware::health::V2_0::IHealth> gHealth;
+using ::android::hardware::health::V2_0::implementation::Health;
#endif
struct healthd_mode_ops *healthd_mode_ops = nullptr;
@@ -160,42 +160,42 @@
status_t err = UNKNOWN_ERROR;
switch (id) {
case BATTERY_PROP_CHARGE_COUNTER: {
- gHealth->getChargeCounter([&](Result r, int32_t v) {
+ Health::getImplementation()->getChargeCounter([&](Result r, int32_t v) {
err = convertStatus(r);
val->valueInt64 = v;
});
break;
}
case BATTERY_PROP_CURRENT_NOW: {
- gHealth->getCurrentNow([&](Result r, int32_t v) {
+ Health::getImplementation()->getCurrentNow([&](Result r, int32_t v) {
err = convertStatus(r);
val->valueInt64 = v;
});
break;
}
case BATTERY_PROP_CURRENT_AVG: {
- gHealth->getCurrentAverage([&](Result r, int32_t v) {
+ Health::getImplementation()->getCurrentAverage([&](Result r, int32_t v) {
err = convertStatus(r);
val->valueInt64 = v;
});
break;
}
case BATTERY_PROP_CAPACITY: {
- gHealth->getCapacity([&](Result r, int32_t v) {
+ Health::getImplementation()->getCapacity([&](Result r, int32_t v) {
err = convertStatus(r);
val->valueInt64 = v;
});
break;
}
case BATTERY_PROP_ENERGY_COUNTER: {
- gHealth->getEnergyCounter([&](Result r, int64_t v) {
+ Health::getImplementation()->getEnergyCounter([&](Result r, int64_t v) {
err = convertStatus(r);
val->valueInt64 = v;
});
break;
}
case BATTERY_PROP_BATTERY_STATUS: {
- gHealth->getChargeStatus([&](Result r, BatteryStatus v) {
+ Health::getImplementation()->getChargeStatus([&](Result r, BatteryStatus v) {
err = convertStatus(r);
val->valueInt64 = static_cast<int64_t>(v);
});
@@ -237,7 +237,7 @@
#ifndef HEALTHD_USE_HEALTH_2_0
healthd_battery_update_internal(gBatteryMonitor->update());
#else
- gHealth->update();
+ Health::getImplementation()->update();
#endif
}
@@ -249,7 +249,7 @@
nativeHandle->data[0] = fd;
::android::hardware::hidl_handle handle;
handle.setTo(nativeHandle, true /* shouldOwn */);
- gHealth->debug(handle, {} /* options */);
+ Health::getImplementation()->debug(handle, {} /* options */);
#endif
fsync(fd);
diff --git a/healthd/include/health2/Health.h b/healthd/include/health2/Health.h
index 4e78380..012b95b 100644
--- a/healthd/include/health2/Health.h
+++ b/healthd/include/health2/Health.h
@@ -22,9 +22,16 @@
struct Health : public IHealth, hidl_death_recipient {
public:
+ static sp<IHealth> initInstance(struct healthd_config* c);
+ // Should only be called by implementation itself (-impl, -service).
+ // Clients should not call this function. Instead, initInstance() initializes and returns the
+ // global instance that has fewer functions.
+ // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
+ static sp<Health> getImplementation();
+
Health(struct healthd_config* c);
- // TODO(b/62229583): clean up and hide these functions.
+ // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
void notifyListeners(const HealthInfo& info);
// Methods from IHealth follow.
@@ -44,6 +51,8 @@
void serviceDied(uint64_t cookie, const wp<IBase>& /* who */) override;
private:
+ static sp<Health> instance_;
+
std::mutex callbacks_lock_;
std::vector<sp<IHealthInfoCallback>> callbacks_;
std::unique_ptr<BatteryMonitor> battery_monitor_;