servicemanager: guaranteeClient on wait register
When clients exit quickly, a client callback may not be registered yet.
We should still keep guaranteeClient set, so that they will get the
notification.
Fixes: 285202885
Test: boot
Test: aidl_lazy_test
Test: libbinder_ndk_unit_test
Change-Id: If50112a3b6c191afdadf7441638cc117fa1620ea
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 98a70ed..cae9684 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -404,14 +404,13 @@
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.hasClients = prevClients, // see b/279898063, matters if existing callbacks
- .guaranteeClient = false, // handled below
+ .guaranteeClient = false,
.ctx = ctx,
};
if (auto it = mNameToRegistrationCallback.find(name); it != mNameToRegistrationCallback.end()) {
- // TODO: this is only needed once
- // See also getService - handles case where client never gets the service,
- // we want the service to quit.
+ // If someone is currently waiting on the service, notify the service that
+ // we're waiting and flush it to the service.
mNameToService[name].guaranteeClient = true;
CHECK(handleServiceClientCallback(2 /* sm + transaction */, name, false));
mNameToService[name].guaranteeClient = true;
@@ -714,6 +713,11 @@
mNameToClientCallback[name].push_back(cb);
+ // Flush updated info to client callbacks (especially if guaranteeClient
+ // and !hasClient, see b/285202885). We may or may not have clients at
+ // this point, so ignore the return value.
+ (void)handleServiceClientCallback(2 /* sm + transaction */, name, false);
+
return Status::ok();
}