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