• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #include <hidl/HidlLazyUtils.h>
18 #include <hidl/HidlTransportSupport.h>
19 #include <sys/wait.h>
20 #include <utils/Errors.h>
21 #include <utils/Log.h>
22 #include <utils/StrongPointer.h>
23 
24 #pragma once
25 
26 namespace android {
27 namespace hardware {
28 namespace details {
29 template <class Interface, typename Func>
30 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
31     Func registerServiceCb, const std::string& name = "default") {
32     sp<Interface> service = Interface::getService(name, true /* getStub */);
33 
34     if (service == nullptr) {
35         ALOGE("Could not get passthrough implementation for %s/%s.",
36             Interface::descriptor, name.c_str());
37         return EXIT_FAILURE;
38     }
39 
40     LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
41             Interface::descriptor, name.c_str());
42 
43     status_t status = registerServiceCb(service, name);
44 
45     if (status == OK) {
46         ALOGI("Registration complete for %s/%s.",
47             Interface::descriptor, name.c_str());
48     } else {
49         ALOGE("Could not register service %s/%s (%d).",
50             Interface::descriptor, name.c_str(), status);
51     }
52 
53     return status;
54 }
55 }  // namespace details
56 
57 /**
58  * Registers passthrough service implementation.
59  */
60 template <class Interface>
61 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
62     const std::string& name = "default") {
63     return details::registerPassthroughServiceImplementation<Interface>(
64         [](const sp<Interface>& service, const std::string& name) {
65             return service->registerAsService(name);
66         },
67         name);
68 }
69 
70 /**
71  * Creates default passthrough service implementation. This method never returns.
72  *
73  * Return value is exit status.
74  */
75 template <class Interface>
76 __attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
77     const std::string& name, size_t maxThreads = 1) {
78     configureRpcThreadpool(maxThreads, true);
79     status_t result = registerPassthroughServiceImplementation<Interface>(name);
80 
81     if (result != OK) {
82         return result;
83     }
84 
85     joinRpcThreadpool();
86     return UNKNOWN_ERROR;
87 }
88 template<class Interface>
89 __attribute__((warn_unused_result))
90 status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) {
91     return defaultPassthroughServiceImplementation<Interface>("default", maxThreads);
92 }
93 
94 /**
95  * Registers a passthrough service implementation that exits when there are 0 clients.
96  *
97  * If this function is called multiple times to register different services, then this process will
98  * only exit once all services have 0 clients. This function does not know about clients registered
99  * through registerPassthroughServiceImplementation, so if that function is used in conjunction with
100  * this one, the process may exit while a client is still using the HAL.
101  */
102 template <class Interface>
103 __attribute__((warn_unused_result)) status_t registerLazyPassthroughServiceImplementation(
104     const std::string& name = "default") {
105     // Make LazyServiceRegistrar static so that multiple calls to
106     // registerLazyPassthroughServiceImplementation work as expected: each HAL is registered and the
107     // process only exits once all HALs have 0 clients.
108     using android::hardware::LazyServiceRegistrar;
109     static auto serviceCounter(std::make_shared<LazyServiceRegistrar>());
110 
111     return details::registerPassthroughServiceImplementation<Interface>(
112         [](const sp<Interface>& service, const std::string& name) {
113             return serviceCounter->registerService(service, name);
114         },
115         name);
116 }
117 
118 /**
119  * Creates default passthrough service implementation that exits when there are 0 clients. This
120  * method never returns.
121  *
122  * Return value is exit status.
123  */
124 template <class Interface>
125 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
126     const std::string& name, size_t maxThreads = 1) {
127     configureRpcThreadpool(maxThreads, true);
128     status_t result = registerLazyPassthroughServiceImplementation<Interface>(name);
129 
130     if (result != OK) {
131         return result;
132     }
133 
134     joinRpcThreadpool();
135     return UNKNOWN_ERROR;
136 }
137 template <class Interface>
138 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
139     size_t maxThreads = 1) {
140     return defaultLazyPassthroughServiceImplementation<Interface>("default", maxThreads);
141 }
142 
143 }  // namespace hardware
144 }  // namespace android
145