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
8namespace android {
9namespace hidl {
10namespace manager {
11namespace implementation {
12
13HidlService::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
24sp<IBase> HidlService::getService() const {
25    return mService;
26}
27void HidlService::setService(sp<IBase> service, pid_t pid) {
28    mService = service;
29    mPid = pid;
30
31    sendRegistrationNotifications();
32}
33
34pid_t HidlService::getPid() const {
35    return mPid;
36}
37const std::string &HidlService::getInterfaceName() const {
38    return mInterfaceName;
39}
40const std::string &HidlService::getInstanceName() const {
41    return mInstanceName;
42}
43
44void 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
58bool 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
75void HidlService::registerPassthroughClient(pid_t pid) {
76    mPassthroughClients.insert(pid);
77}
78
79const std::set<pid_t> &HidlService::getPassthroughClients() const {
80    return mPassthroughClients;
81}
82
83std::string HidlService::string() const {
84    std::stringstream ss;
85    ss << mInterfaceName << "/" << mInstanceName;
86    return ss.str();
87}
88
89void 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