1 #define LOG_TAG "hwservicemanager"
2 #include "HidlService.h"
3
4 #include <android-base/logging.h>
5 #include <hidl/HidlTransportSupport.h>
6 #include <sstream>
7
8 namespace android {
9 namespace hidl {
10 namespace manager {
11 namespace implementation {
12
HidlService(const std::string & interfaceName,const std::string & instanceName,const sp<IBase> & service,pid_t pid)13 HidlService::HidlService(
14 const std::string &interfaceName,
15 const std::string &instanceName,
16 const sp<IBase> &service,
17 pid_t pid)
18 : mInterfaceName(interfaceName),
19 mInstanceName(instanceName),
20 mService(service),
21 mPid(pid)
22 {}
23
getService() const24 sp<IBase> HidlService::getService() const {
25 return mService;
26 }
setService(sp<IBase> service,pid_t pid)27 void HidlService::setService(sp<IBase> service, pid_t pid) {
28 mService = service;
29 mPid = pid;
30
31 sendRegistrationNotifications();
32 }
33
getDebugPid() const34 pid_t HidlService::getDebugPid() const {
35 return mPid;
36 }
getInterfaceName() const37 const std::string &HidlService::getInterfaceName() const {
38 return mInterfaceName;
39 }
getInstanceName() const40 const std::string &HidlService::getInstanceName() const {
41 return mInstanceName;
42 }
43
addListener(const sp<IServiceNotification> & listener)44 void HidlService::addListener(const sp<IServiceNotification> &listener) {
45 if (mService != nullptr) {
46 auto ret = listener->onRegistration(
47 mInterfaceName, mInstanceName, true /* preexisting */);
48 if (!ret.isOk()) {
49 LOG(ERROR) << "Not adding listener for " << mInterfaceName << "/"
50 << mInstanceName << ": transport error when sending "
51 << "notification for already registered instance.";
52 return;
53 }
54 }
55 mListeners.push_back(listener);
56 }
57
removeListener(const wp<IBase> & listener)58 bool HidlService::removeListener(const wp<IBase>& listener) {
59 using ::android::hardware::interfacesEqual;
60
61 bool found = false;
62
63 for (auto it = mListeners.begin(); it != mListeners.end();) {
64 if (interfacesEqual(*it, listener.promote())) {
65 it = mListeners.erase(it);
66 found = true;
67 } else {
68 ++it;
69 }
70 }
71
72 return found;
73 }
74
registerPassthroughClient(pid_t pid)75 void HidlService::registerPassthroughClient(pid_t pid) {
76 mPassthroughClients.insert(pid);
77 }
78
getPassthroughClients() const79 const std::set<pid_t> &HidlService::getPassthroughClients() const {
80 return mPassthroughClients;
81 }
82
string() const83 std::string HidlService::string() const {
84 std::stringstream ss;
85 ss << mInterfaceName << "/" << mInstanceName;
86 return ss.str();
87 }
88
sendRegistrationNotifications()89 void HidlService::sendRegistrationNotifications() {
90 if (mListeners.size() == 0 || mService == nullptr) {
91 return;
92 }
93
94 hidl_string iface = mInterfaceName;
95 hidl_string name = mInstanceName;
96
97 for (auto it = mListeners.begin(); it != mListeners.end();) {
98 auto ret = (*it)->onRegistration(iface, name, false /* preexisting */);
99 if (ret.isOk()) {
100 ++it;
101 } else {
102 LOG(ERROR) << "Dropping registration callback for " << iface << "/" << name
103 << ": transport error.";
104 it = mListeners.erase(it);
105 }
106 }
107 }
108
109 } // namespace implementation
110 } // namespace manager
111 } // namespace hidl
112 } // namespace android
113