12173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland#define LOG_TAG "hwservicemanager"
22173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland#include "HidlService.h"
32173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
42173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland#include <android-base/logging.h>
5ad645828c0b1e4d0c84d96f9a1e574916c259be1Steven Moreland#include <hidl/HidlTransportSupport.h>
62173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland#include <sstream>
72173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
82173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandnamespace android {
92173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandnamespace hidl {
102173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandnamespace manager {
112173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandnamespace implementation {
122173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
132173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven MorelandHidlService::HidlService(
14d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland    const std::string &interfaceName,
15d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland    const std::string &instanceName,
16cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland    const sp<IBase> &service,
17cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland    pid_t pid)
18d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland: mInterfaceName(interfaceName),
19d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland  mInstanceName(instanceName),
20cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland  mService(service),
21cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland  mPid(pid)
222173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland{}
232173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
24b3a90f0de29292ec4288484c3e66b225d86bdc15Yifan Hongsp<IBase> HidlService::getService() const {
252173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    return mService;
262173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
27cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Morelandvoid HidlService::setService(sp<IBase> service, pid_t pid) {
282173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    mService = service;
29cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland    mPid = pid;
302173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
312173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    sendRegistrationNotifications();
322173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
33cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland
34cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Morelandpid_t HidlService::getPid() const {
35cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland    return mPid;
36cdf9472ffbd015938a99e3658b21bfb9758dca97Steven Moreland}
37d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Morelandconst std::string &HidlService::getInterfaceName() const {
38d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland    return mInterfaceName;
392173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
40d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Morelandconst std::string &HidlService::getInstanceName() const {
412173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    return mInstanceName;
422173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
432173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
442173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandvoid HidlService::addListener(const sp<IServiceNotification> &listener) {
452173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    if (mService != nullptr) {
4630acc22dac05ec3cd872a27fd60827296ebd41acSteven Moreland        auto ret = listener->onRegistration(
4730acc22dac05ec3cd872a27fd60827296ebd41acSteven Moreland            mInterfaceName, mInstanceName, true /* preexisting */);
487fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen        if (!ret.isOk()) {
497fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            LOG(ERROR) << "Not adding listener for " << mInterfaceName << "/"
507fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen                       << mInstanceName << ": transport error when sending "
517fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen                       << "notification for already registered instance.";
527fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            return;
537fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen        }
547fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen    }
557fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen    mListeners.push_back(listener);
567fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen}
577fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen
587fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenenbool HidlService::removeListener(const wp<IBase>& listener) {
59ad645828c0b1e4d0c84d96f9a1e574916c259be1Steven Moreland    using ::android::hardware::interfacesEqual;
60ad645828c0b1e4d0c84d96f9a1e574916c259be1Steven Moreland
617fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen    bool found = false;
627fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen
637fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen    for (auto it = mListeners.begin(); it != mListeners.end();) {
64ad645828c0b1e4d0c84d96f9a1e574916c259be1Steven Moreland        if (interfacesEqual(*it, listener.promote())) {
657fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            it = mListeners.erase(it);
667fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            found = true;
677fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen        } else {
687fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            ++it;
697fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen        }
702173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    }
717fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen
727fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen    return found;
732173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
742173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
75ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hongvoid HidlService::registerPassthroughClient(pid_t pid) {
76ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong    mPassthroughClients.insert(pid);
77ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong}
78ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong
79ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hongconst std::set<pid_t> &HidlService::getPassthroughClients() const {
80ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong    return mPassthroughClients;
81ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong}
82ee531a829e99f427dac47383f70d6a1c0fd1ca84Yifan Hong
832173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Morelandstd::string HidlService::string() const {
842173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    std::stringstream ss;
85d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland    ss << mInterfaceName << "/" << mInstanceName;
862173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    return ss.str();
872173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
882173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
8972103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenenvoid HidlService::sendRegistrationNotifications() {
902173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    if (mListeners.size() == 0 || mService == nullptr) {
912173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland        return;
922173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    }
932173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
94d544cf6502ff3a9958887b683f0500edcebd8cb8Steven Moreland    hidl_string iface = mInterfaceName;
952173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    hidl_string name = mInstanceName;
962173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
9772103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen    for (auto it = mListeners.begin(); it != mListeners.end();) {
9872103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen        auto ret = (*it)->onRegistration(iface, name, false /* preexisting */);
9972103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen        if (ret.isOk()) {
10072103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen            ++it;
10172103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen        } else {
1027fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen            LOG(ERROR) << "Dropping registration callback for " << iface << "/" << name
1037fafc144d14c9acfd9152a51dfb5ca3d87b995d4Martijn Coenen                       << ": transport error.";
10472103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen            it = mListeners.erase(it);
10572103a0ad5abf7ec79f0ca7558330b131810e6d3Martijn Coenen        }
1062173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland    }
1072173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}
1082173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland
1092173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}  // namespace implementation
1102173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}  // namespace manager
1112173d3c8d6f5a5a78bd145063ac177d7f0657d33Steven Moreland}  // namespace hidl
112b3a90f0de29292ec4288484c3e66b225d86bdc15Yifan Hong}  // namespace android
113