health: registerCallback() and getHealthInfo() does not notify all callbacks
registerCallback() and getHealthInfo() unintentionally broadcast
health info to all callbacks, which has a performance impact.
* registerCallback() still invokes the new callback immediately
* getHealthInfo() does not call any callbacks at all.
Test: VTS test call getHealthInfo does not invoke update()
Bug: 117167903
Change-Id: Ida99fdd73831e747fbf2d65089c7c0e7661fe7c4
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index 4a4bee0..a2b81d1 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -58,7 +58,7 @@
// ignore the error
}
- return update();
+ return updateAndNotify(callback);
}
bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
@@ -156,6 +156,18 @@
return Result::SUCCESS;
}
+Return<Result> Health::updateAndNotify(const sp<IHealthInfoCallback>& callback) {
+ std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
+ std::vector<sp<IHealthInfoCallback>> storedCallbacks{std::move(callbacks_)};
+ callbacks_.clear();
+ if (callback != nullptr) {
+ callbacks_.push_back(callback);
+ }
+ Return<Result> result = update();
+ callbacks_ = std::move(storedCallbacks);
+ return result;
+}
+
void Health::notifyListeners(HealthInfo* healthInfo) {
std::vector<StorageInfo> info;
get_storage_info(info);
@@ -233,7 +245,7 @@
Return<void> Health::getHealthInfo(getHealthInfo_cb _hidl_cb) {
using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
- update();
+ updateAndNotify(nullptr);
struct android::BatteryProperties p = getBatteryProperties(battery_monitor_.get());
V1_0::HealthInfo batteryInfo;
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index b960358..6410474 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -64,6 +64,10 @@
std::unique_ptr<BatteryMonitor> battery_monitor_;
bool unregisterCallbackInternal(const sp<IBase>& cb);
+
+ // update() and only notify the given callback, but none of the other callbacks.
+ // If cb is null, do not notify any callback at all.
+ Return<Result> updateAndNotify(const sp<IHealthInfoCallback>& cb);
};
} // namespace implementation