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