Add IServiceManager addWithChain.
This prevents hwservicemanager from having to make oneway calls.
The method onRegistration will be deprecated after this as well.
Bug: 36424585
Test: hidl_test, boot
Change-Id: I05c8f86962da5f778dcf660d0adf598522ead282
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 66fa7cb..9b4338b 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -57,10 +57,11 @@
using android::base::WaitForProperty;
+using ::android::hidl::base::V1_0::IBase;
using IServiceManager1_0 = android::hidl::manager::V1_0::IServiceManager;
using IServiceManager1_1 = android::hidl::manager::V1_1::IServiceManager;
using IServiceManager1_2 = android::hidl::manager::V1_2::IServiceManager;
-using android::hidl::manager::V1_0::IServiceNotification;
+using ::android::hidl::manager::V1_0::IServiceNotification;
namespace android {
namespace hardware {
@@ -73,7 +74,7 @@
static constexpr bool kIsRecovery = false;
#endif
-void waitForHwServiceManager() {
+static void waitForHwServiceManager() {
using std::literals::chrono_literals::operator""s;
while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) {
@@ -91,7 +92,7 @@
in.substr(0, prefix.size()) == prefix;
}
-std::string binaryName() {
+static std::string binaryName() {
std::ifstream ifs("/proc/self/cmdline");
std::string cmdline;
if (!ifs.is_open()) {
@@ -107,27 +108,27 @@
return cmdline;
}
-std::string packageWithoutVersion(const std::string& packageAndVersion) {
+static std::string packageWithoutVersion(const std::string& packageAndVersion) {
size_t at = packageAndVersion.find('@');
if (at == std::string::npos) return packageAndVersion;
return packageAndVersion.substr(0, at);
}
-void tryShortenProcessName(const std::string& packageAndVersion) {
+static void tryShortenProcessName(const std::string& descriptor) {
const static std::string kTasks = "/proc/self/task/";
// make sure that this binary name is in the same package
std::string processName = binaryName();
// e.x. android.hardware.foo is this package
- if (!startsWith(packageWithoutVersion(processName), packageWithoutVersion(packageAndVersion))) {
+ if (!startsWith(packageWithoutVersion(processName), packageWithoutVersion(descriptor))) {
return;
}
- // e.x. android.hardware.module.foo@1.2 -> foo@1.2
- size_t lastDot = packageAndVersion.rfind('.');
+ // e.x. android.hardware.module.foo@1.2::IFoo -> foo@1.2
+ size_t lastDot = descriptor.rfind('.');
if (lastDot == std::string::npos) return;
- size_t secondDot = packageAndVersion.rfind('.', lastDot - 1);
+ size_t secondDot = descriptor.rfind('.', lastDot - 1);
if (secondDot == std::string::npos) return;
std::string newName = processName.substr(secondDot + 1, std::string::npos);
@@ -151,7 +152,7 @@
fs >> oldComm;
// don't rename if it already has an explicit name
- if (startsWith(packageAndVersion, oldComm)) {
+ if (startsWith(descriptor, oldComm)) {
fs.seekg(0, fs.beg);
fs << newName;
}
@@ -164,7 +165,7 @@
* Returns the age of the current process by reading /proc/self/stat and comparing starttime to the
* current time. This is useful for measuring how long it took a HAL to register itself.
*/
-long getProcessAgeMs() {
+static long getProcessAgeMs() {
constexpr const int PROCFS_STAT_STARTTIME_INDEX = 21;
std::string content;
android::base::ReadFileToString("/proc/self/stat", &content, false);
@@ -185,18 +186,23 @@
return -1;
}
-void onRegistration(const std::string& packageName, const std::string& interfaceName,
- const std::string& instanceName) {
+static void onRegistrationImpl(const std::string& descriptor, const std::string& instanceName) {
long halStartDelay = getProcessAgeMs();
if (halStartDelay >= 0) {
// The "start delay" printed here is an estimate of how long it took the HAL to go from
// process creation to registering itself as a HAL. Actual start time could be longer
// because the process might not have joined the threadpool yet, so it might not be ready to
// process transactions.
- LOG(INFO) << "Registered " << interfaceName << "/" << instanceName << " (start delay of "
+ LOG(INFO) << "Registered " << descriptor << "/" << instanceName << " (start delay of "
<< halStartDelay << "ms)";
}
- tryShortenProcessName(packageName);
+
+ tryShortenProcessName(descriptor);
+}
+
+void onRegistration(const std::string& packageName, const std::string& interfaceName,
+ const std::string& instanceName) {
+ return onRegistrationImpl(packageName + "::" + interfaceName, instanceName);
}
} // details
@@ -719,7 +725,6 @@
const std::string& instance,
bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
- using ::android::hidl::base::V1_0::IBase;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;
@@ -819,6 +824,32 @@
return nullptr;
}
+status_t registerAsServiceInternal(const sp<IBase>& service, const std::string& name) {
+ if (service == nullptr) {
+ return UNEXPECTED_NULL;
+ }
+
+ sp<IServiceManager1_2> sm = defaultServiceManager1_2();
+ if (sm == nullptr) {
+ return INVALID_OPERATION;
+ }
+
+ bool registered = false;
+ Return<void> ret = service->interfaceChain([&](const auto& chain) {
+ registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false);
+ });
+
+ if (!ret.isOk()) {
+ LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();
+ }
+
+ if (registered) {
+ onRegistrationImpl(getDescriptor(service.get()), name);
+ }
+
+ return registered ? OK : UNKNOWN_ERROR;
+}
+
} // namespace details
} // namespace hardware