summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin Moore <devinmoore@google.com>2023-11-28 22:11:19 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-28 22:11:19 +0000
commit280fa3768675ce943f9c1f1a5eab0b592f24de9f (patch)
tree10ffac29a99a769f8da441f28d1a812e9151c9e6
parentb1b7219eb691629ecb65df68eac7fccc8d348d62 (diff)
parent2d2e4c0596980499478db1b5881e19e960422c10 (diff)
downloadlibhidl-280fa3768675ce943f9c1f1a5eab0b592f24de9f.tar.gz
NoHwServiceManager return true in registerForNotifications am: 2d2e4c0596
Original change: https://android-review.googlesource.com/c/platform/system/libhidl/+/2847957 Change-Id: I4e9cbc7921cd9d6115cd297a866482196b331c74 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--transport/ServiceManagement.cpp69
1 files changed, 58 insertions, 11 deletions
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index a759c50..c3d3fa4 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -236,7 +236,7 @@ bool isHidlSupported() {
* to be able service the requests and tell clients there are no services
* registered.
*/
-struct NoHwServiceManager : public IServiceManager1_2 {
+struct NoHwServiceManager : public IServiceManager1_2, hidl_death_recipient {
Return<sp<IBase>> get(const hidl_string& fqName, const hidl_string&) override {
sp<IBase> ret = nullptr;
@@ -274,11 +274,49 @@ struct NoHwServiceManager : public IServiceManager1_2 {
return Void();
}
+ void serviceDied(uint64_t /* cookie */, const wp<IBase>& who) override {
+ sp<IBase> promoted = who.promote();
+ if (promoted) {
+ bool removed = false;
+ for (auto [name, callbacks] : mServiceNotifications) {
+ for (auto it = callbacks.begin(); it != callbacks.end();) {
+ if (interfacesEqual(*it, promoted)) {
+ callbacks.erase(it);
+ removed = true;
+ }
+ it++;
+ }
+ if (removed) return;
+ }
+ }
+ LOG(ERROR) << "Could not find a registered callback for a service who died. "
+ << "Service pointer: " << who.promote().get();
+ }
+
Return<bool> registerForNotifications(const hidl_string& fqName, const hidl_string& name,
- const sp<IServiceNotification>& /* callback */) override {
- LOG(INFO) << "Cannot register for notifications for " << fqName << "/" << name
- << " without hwservicemanager";
- return false;
+ const sp<IServiceNotification>& callback) override {
+ LOG(INFO) << "Will not get any notifications for " << fqName << "/" << name
+ << " without hwservicemanager but keeping the callback.";
+ if (callback == nullptr) {
+ LOG(ERROR) << "Cannot register a null callback for " << fqName << "/" << name;
+ return false;
+ }
+ bool ret = callback->linkToDeath(this, 0);
+ if (!ret) {
+ LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
+ return false;
+ }
+
+ auto [it, inserted] = mServiceNotifications[static_cast<std::string>(fqName) + "/" +
+ static_cast<std::string>(name)]
+ .insert(callback);
+ if (!inserted) {
+ LOG(WARNING) << "This callback for " << fqName << "/" << name
+ << " was already registered so "
+ << "we are not keeping a reference to this one.";
+ return false;
+ }
+ return true;
}
Return<void> debugDump(debugDump_cb _hidl_cb) override {
@@ -294,13 +332,19 @@ struct NoHwServiceManager : public IServiceManager1_2 {
return Void();
}
- Return<bool> unregisterForNotifications(
- const hidl_string& fqName, const hidl_string& name,
- const sp<IServiceNotification>& /* callback */) override {
- LOG(INFO) << "Cannot unregister for notifications for " << fqName << "/" << name
- << " without hwservicemanager";
- return false;
+ Return<bool> unregisterForNotifications(const hidl_string& fqName, const hidl_string& name,
+ const sp<IServiceNotification>& callback) override {
+ auto ret = mServiceNotifications[static_cast<std::string>(fqName) + "/" +
+ static_cast<std::string>(name)]
+ .erase(callback);
+ if (!ret) {
+ LOG(WARNING) << "This callback for " << fqName << "/" << name << " was not previously "
+ << "registered so there is nothing to do.";
+ return false;
+ }
+ return true;
}
+
Return<bool> registerClientCallback(const hidl_string& fqName, const hidl_string& name,
const sp<IBase>&, const sp<IClientCallback>&) {
LOG(INFO) << "Cannot add client callback for " << fqName << "/" << name
@@ -326,6 +370,9 @@ struct NoHwServiceManager : public IServiceManager1_2 {
<< " without hwservicemanager";
return false;
}
+
+ private:
+ std::map<std::string, std::set<sp<IServiceNotification>>> mServiceNotifications;
};
sp<IServiceManager1_2> defaultServiceManager1_2() {