transport: Add non-template functions for service registration
Add an implementation of registerPassthroughServiceImplementation
which takes interface name as string instead of using a template.
This allows services to avoid dependency on interface libraries.
Bug: 148115870
Test: verify that updated audio HAL service works
Change-Id: I1ef9d9f830e4ff217c5b24bb5b4919af05d7cfa6
diff --git a/transport/LegacySupport.cpp b/transport/LegacySupport.cpp
new file mode 100644
index 0000000..866de5f
--- /dev/null
+++ b/transport/LegacySupport.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LegacySupport"
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+
+using android::hidl::base::V1_0::IBase;
+
+namespace android::hardware {
+
+namespace details {
+
+__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
+ const std::string& interfaceName, RegisterServiceBaseCb registerServiceCb,
+ const std::string& serviceName) {
+ sp<IBase> service =
+ getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);
+
+ if (service == nullptr) {
+ ALOGE("Could not get passthrough implementation for %s/%s.", interfaceName.c_str(),
+ serviceName.c_str());
+ return EXIT_FAILURE;
+ }
+
+ LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!", interfaceName.c_str(),
+ serviceName.c_str());
+
+ std::string actualName;
+ Return<void> result = service->interfaceDescriptor(
+ [&actualName](const hidl_string& descriptor) { actualName = descriptor; });
+ LOG_FATAL_IF(!result.isOk(), "Error retrieving interface name from %s/%s: %s",
+ interfaceName.c_str(), serviceName.c_str(), result.description());
+ LOG_FATAL_IF(actualName != interfaceName, "Implementation of %s/%s is actually %s!",
+ interfaceName.c_str(), serviceName.c_str(), actualName.c_str());
+
+ status_t status = registerServiceCb(service, serviceName);
+
+ if (status == OK) {
+ ALOGI("Registration complete for %s/%s.", interfaceName.c_str(), serviceName.c_str());
+ } else {
+ ALOGE("Could not register service %s/%s (%d).", interfaceName.c_str(), serviceName.c_str(),
+ status);
+ }
+
+ return status;
+}
+
+} // namespace details
+
+__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
+ const std::string& interfaceName, const std::string& serviceName) {
+ return details::registerPassthroughServiceImplementation(
+ interfaceName,
+ [](const sp<IBase>& service, const std::string& name) {
+ return details::registerAsServiceInternal(service, name);
+ },
+ serviceName);
+}
+
+} // namespace android::hardware