• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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