HidlService.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. #define LOG_TAG "hwservicemanager"
  17. #include "HidlService.h"
  18. #include <android-base/logging.h>
  19. #include <hidl/HidlTransportSupport.h>
  20. #include <hwbinder/BpHwBinder.h>
  21. #include <sstream>
  22. using ::android::hardware::interfacesEqual;
  23. namespace android {
  24. namespace hidl {
  25. namespace manager {
  26. namespace implementation {
  27. static constexpr int kNoClientRepeatLimit = 2;
  28. HidlService::HidlService(
  29. const std::string &interfaceName,
  30. const std::string &instanceName,
  31. const sp<IBase> &service,
  32. pid_t pid)
  33. : mInterfaceName(interfaceName),
  34. mInstanceName(instanceName),
  35. mService(service),
  36. mPid(pid)
  37. {}
  38. sp<IBase> HidlService::getService() const {
  39. return mService;
  40. }
  41. void HidlService::setService(sp<IBase> service, pid_t pid) {
  42. mService = service;
  43. mPid = pid;
  44. mClientCallbacks.clear();
  45. mHasClients = false;
  46. mGuaranteeClient = false;
  47. mNoClientsCounter = 0;
  48. sendRegistrationNotifications();
  49. }
  50. pid_t HidlService::getDebugPid() const {
  51. return mPid;
  52. }
  53. const std::string &HidlService::getInterfaceName() const {
  54. return mInterfaceName;
  55. }
  56. const std::string &HidlService::getInstanceName() const {
  57. return mInstanceName;
  58. }
  59. void HidlService::addListener(const sp<IServiceNotification> &listener) {
  60. if (mService != nullptr) {
  61. auto ret = listener->onRegistration(
  62. mInterfaceName, mInstanceName, true /* preexisting */);
  63. if (!ret.isOk()) {
  64. LOG(ERROR) << "Not adding listener for " << mInterfaceName << "/"
  65. << mInstanceName << ": transport error when sending "
  66. << "notification for already registered instance.";
  67. return;
  68. }
  69. }
  70. mListeners.push_back(listener);
  71. }
  72. bool HidlService::removeListener(const wp<IBase>& listener) {
  73. bool found = false;
  74. for (auto it = mListeners.begin(); it != mListeners.end();) {
  75. if (interfacesEqual(*it, listener.promote())) {
  76. it = mListeners.erase(it);
  77. found = true;
  78. } else {
  79. ++it;
  80. }
  81. }
  82. return found;
  83. }
  84. void HidlService::registerPassthroughClient(pid_t pid) {
  85. mPassthroughClients.insert(pid);
  86. }
  87. const std::set<pid_t> &HidlService::getPassthroughClients() const {
  88. return mPassthroughClients;
  89. }
  90. void HidlService::addClientCallback(const sp<IClientCallback>& callback) {
  91. if (mHasClients) {
  92. // we have this kernel feature, so make sure we're in an updated state
  93. forceHandleClientCallbacks(false /*onInterval*/);
  94. }
  95. if (mHasClients) {
  96. // make sure this callback is in the same state as all of the rest
  97. sendClientCallbackNotification(callback, true /*hasClients*/);
  98. }
  99. mClientCallbacks.push_back(callback);
  100. }
  101. bool HidlService::removeClientCallback(const sp<IClientCallback>& callback) {
  102. bool found = false;
  103. for (auto it = mClientCallbacks.begin(); it != mClientCallbacks.end();) {
  104. if (interfacesEqual(*it, callback)) {
  105. it = mClientCallbacks.erase(it);
  106. found = true;
  107. } else {
  108. ++it;
  109. }
  110. }
  111. return found;
  112. }
  113. ssize_t HidlService::handleClientCallbacks(bool isCalledOnInterval) {
  114. if (!mClientCallbacks.empty()) {
  115. return forceHandleClientCallbacks(isCalledOnInterval);
  116. }
  117. return -1;
  118. }
  119. ssize_t HidlService::forceHandleClientCallbacks(bool isCalledOnInterval) {
  120. ssize_t count = getNodeStrongRefCount();
  121. // binder driver doesn't support this feature
  122. if (count == -1) return count;
  123. bool hasClients = count > 1; // this process holds a strong count
  124. if (mGuaranteeClient) {
  125. // we have no record of this client
  126. if (!mHasClients && !hasClients) {
  127. sendClientCallbackNotifications(true);
  128. }
  129. // guarantee is temporary
  130. mGuaranteeClient = false;
  131. }
  132. if (hasClients && !mHasClients) {
  133. // client was retrieved in some other way
  134. sendClientCallbackNotifications(true);
  135. }
  136. // there are no more clients, but the callback has not been called yet
  137. if (!hasClients && mHasClients && isCalledOnInterval) {
  138. mNoClientsCounter++;
  139. if (mNoClientsCounter >= kNoClientRepeatLimit) {
  140. sendClientCallbackNotifications(false);
  141. }
  142. }
  143. return count;
  144. }
  145. void HidlService::guaranteeClient() {
  146. mGuaranteeClient = true;
  147. }
  148. std::string HidlService::string() const {
  149. std::stringstream ss;
  150. ss << mInterfaceName << "/" << mInstanceName;
  151. return ss.str();
  152. }
  153. ssize_t HidlService::getNodeStrongRefCount() {
  154. using ::android::hardware::toBinder;
  155. using ::android::hardware::BpHwBinder;
  156. using ::android::hardware::IBinder;
  157. if (mService == nullptr) return -1;
  158. // this justifies the bp cast below, no in-process HALs need this
  159. if (!mService->isRemote()) return -1;
  160. sp<IBinder> binder = toBinder(mService);
  161. if (binder == nullptr) return -1;
  162. sp<BpHwBinder> bpBinder = static_cast<BpHwBinder*>(binder.get());
  163. return bpBinder->getNodeStrongRefCount();
  164. }
  165. void HidlService::sendRegistrationNotifications() {
  166. if (mListeners.size() == 0 || mService == nullptr) {
  167. return;
  168. }
  169. hidl_string iface = mInterfaceName;
  170. hidl_string name = mInstanceName;
  171. for (auto it = mListeners.begin(); it != mListeners.end();) {
  172. auto ret = (*it)->onRegistration(iface, name, false /* preexisting */);
  173. if (ret.isOk()) {
  174. ++it;
  175. } else {
  176. LOG(ERROR) << "Dropping registration callback for " << iface << "/" << name
  177. << ": transport error.";
  178. it = mListeners.erase(it);
  179. }
  180. }
  181. }
  182. void HidlService::sendClientCallbackNotifications(bool hasClients) {
  183. CHECK(hasClients != mHasClients) << "Record shows: " << mHasClients
  184. << " so we can't tell clients again that we have client: " << hasClients;
  185. LOG(INFO) << "Notifying " << string() << " they have clients: " << hasClients;
  186. for (const auto& cb : mClientCallbacks) {
  187. sendClientCallbackNotification(cb, hasClients);
  188. }
  189. mNoClientsCounter = 0;
  190. mHasClients = hasClients;
  191. }
  192. void HidlService::sendClientCallbackNotification(const sp<IClientCallback>& callback, bool hasClients) {
  193. Return<void> ret = callback->onClients(getService(), hasClients);
  194. if (!ret.isOk()) {
  195. LOG(WARNING) << "onClients callback failed for " << string() << ": " << ret.description();
  196. }
  197. }
  198. } // namespace implementation
  199. } // namespace manager
  200. } // namespace hidl
  201. } // namespace android