1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "LegacySupport"
18 
19 #include <android/hidl/base/1.0/IBase.h>
20 #include <hidl/HidlSupport.h>
21 #include <hidl/LegacySupport.h>
22 #include <hidl/ServiceManagement.h>
23 #include <hidl/Status.h>
24 
25 using android::hidl::base::V1_0::IBase;
26 
27 namespace android::hardware {
28 
29 namespace details {
30 
31 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
32         const std::string& interfaceName, const std::string& expectInterfaceName,
33         RegisterServiceCb registerServiceCb, const std::string& serviceName) {
34     sp<IBase> service =
35             getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);
36 
37     if (service == nullptr) {
38         ALOGE("Could not get passthrough implementation for %s/%s.", interfaceName.c_str(),
39               serviceName.c_str());
40         return EXIT_FAILURE;
41     }
42     if (service->isRemote()) {
43         ALOGE("Implementation of %s/%s is remote!", interfaceName.c_str(), serviceName.c_str());
44         return EXIT_FAILURE;
45     }
46 
47     std::string actualName;
48     Return<void> result = service->interfaceDescriptor(
49             [&actualName](const hidl_string& descriptor) { actualName = descriptor; });
50     if (!result.isOk()) {
51         ALOGE("Error retrieving interface name from %s/%s: %s", interfaceName.c_str(),
52               serviceName.c_str(), result.description().c_str());
53         return EXIT_FAILURE;
54     }
55     if (actualName != expectInterfaceName) {
56         ALOGE("Implementation of %s/%s is actually %s, not a %s!", interfaceName.c_str(),
57               serviceName.c_str(), actualName.c_str(), expectInterfaceName.c_str());
58         return EXIT_FAILURE;
59     }
60 
61     status_t status = registerServiceCb(service, serviceName);
62     if (status == OK) {
63         ALOGI("Registration complete for %s/%s.", interfaceName.c_str(), serviceName.c_str());
64     } else {
65         ALOGE("Could not register service %s/%s (%d).", interfaceName.c_str(), serviceName.c_str(),
66               status);
67     }
68 
69     return status;
70 }
71 
72 }  // namespace details
73 
74 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
75         const std::string& interfaceName, const std::string& expectInterfaceName,
76         const std::string& serviceName) {
77     return details::registerPassthroughServiceImplementation(
78             interfaceName, expectInterfaceName,
79             [](const sp<IBase>& service, const std::string& name) {
80                 return details::registerAsServiceInternal(service, name);
81             },
82             serviceName);
83 }
84 
85 }  // namespace android::hardware
86