author | Yifan Hong <elsk@google.com> | |
Tue, 2 Oct 2018 23:37:43 +0000 (23:37 +0000) | ||
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | |
Tue, 2 Oct 2018 23:37:43 +0000 (23:37 +0000) |
health/2.0/default/Health.cpp | patch | blob | history | |
health/2.0/default/include/health2/Health.h | patch | blob | history |
index e02bfa98df0f0e0e39cd19fb2d83fd6475466642..a2b81d1ba17320458e8f2bfeea575e703cd08f9a 100644 (file)
}
{
- std::lock_guard<std::mutex> _lock(callbacks_lock_);
+ std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
callbacks_.push_back(callback);
// unlock
}
@@ -58,14 +58,14 @@ Return<Result> Health::registerCallback(const sp<IHealthInfoCallback>& callback)
// ignore the error
}
- return update();
+ return updateAndNotify(callback);
}
bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
if (callback == nullptr) return false;
bool removed = false;
- std::lock_guard<std::mutex> _lock(callbacks_lock_);
+ std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
for (auto it = callbacks_.begin(); it != callbacks_.end();) {
if (interfacesEqual(*it, callback)) {
it = callbacks_.erase(it);
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);
healthInfo->diskStats = stats;
healthInfo->storageInfos = info;
- std::lock_guard<std::mutex> _lock(callbacks_lock_);
+ std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
for (auto it = callbacks_.begin(); it != callbacks_.end();) {
auto ret = (*it)->healthInfoChanged(*healthInfo);
if (!ret.isOk() && ret.isDeadObject()) {
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 134cdc6e696b71d3244c2ee46002c6750992c9c2..6410474511fbfbf41264daf4b61696c35f032a53 100644 (file)
// 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 after update() logic is simplified.
void notifyListeners(HealthInfo* info);
// Methods from IHealth follow.
private:
static sp<Health> instance_;
- std::mutex callbacks_lock_;
+ std::recursive_mutex callbacks_lock_;
std::vector<sp<IHealthInfoCallback>> callbacks_;
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