Variants fully integrated with InputStream, bugfixing Variants and
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusProxy.cpp
1 /* Copyright (C) 2013 BMW Group
2  * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3  * Author: Juergen Gehring (juergen.gehring@bmw.de)
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DBusProxy.h"
8 #include "DBusServiceRegistry.h"
9 #include "DBusUtils.h"
10
11 #include <algorithm>
12 #include <cassert>
13 #include <dbus/dbus.h>
14 #include <functional>
15 #include <CommonAPI/Event.h>
16
17 namespace CommonAPI {
18 namespace DBus {
19
20 DBusProxyStatusEvent::DBusProxyStatusEvent(DBusProxy* dbusProxy) :
21                 dbusProxy_(dbusProxy) {
22 }
23
24 void DBusProxyStatusEvent::onFirstListenerAdded(const Listener& listener) {
25     auto serviceStatusListener = std::bind(
26                     &DBusProxyStatusEvent::onServiceAvailableSignalHandler,
27                     this,
28                     std::placeholders::_1,
29                     std::placeholders::_2);
30
31     subscription_ = dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().subscribe(
32                     dbusProxy_->dbusBusName_ + ":" + dbusProxy_->dbusObjectPath_ + ":" + dbusProxy_->interfaceName_,
33                     serviceStatusListener);
34 }
35
36 void DBusProxyStatusEvent::onLastListenerRemoved(const Listener& listener) {
37     dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().unsubscribe(subscription_);
38 }
39
40 SubscriptionStatus DBusProxyStatusEvent::onServiceAvailableSignalHandler(const std::string& name,
41                                                                          const AvailabilityStatus& availabilityStatus) {
42     AvailabilityStatus availability = availabilityStatus;
43
44     return notifyListeners(availability);
45 }
46
47 const std::string DBusProxy::domain_ = "local";
48
49 DBusProxy::DBusProxy(const std::string& dbusBusName,
50                      const std::string& dbusObjectPath,
51                      const std::string& interfaceName,
52                      const std::shared_ptr<DBusProxyConnection>& dbusProxyConnection) :
53                                                  dbusBusName_(dbusBusName),
54                                  dbusObjectPath_(dbusObjectPath),
55                                  interfaceName_(interfaceName),
56                                  statusEvent_(this),
57                                  interfaceVersionAttribute_(*this, "getInterfaceVersion"),
58                                  available_(false),
59                                  availableSet_(false),
60                                  connection_(dbusProxyConnection) {
61 }
62
63 DBusProxy::DBusProxy(const std::string& dbusBusName,
64                      const std::string& dbusObjectPath,
65                      const std::string& interfaceName,
66                      const std::shared_ptr<DBusProxyConnection>& connection,
67                      const bool isAlwaysAvailable) :
68                  dbusBusName_(dbusBusName),
69                  dbusObjectPath_(dbusObjectPath),
70                  interfaceName_(interfaceName),
71                  statusEvent_(this),
72                  interfaceVersionAttribute_(*this, "getInterfaceVersion"),
73                  available_(isAlwaysAvailable),
74                  availableSet_(isAlwaysAvailable),
75                  connection_(connection) {
76 }
77
78 std::string DBusProxy::getAddress() const {
79     return domain_ + ":" + interfaceName_ + ":" + dbusBusName_;
80 }
81
82 const std::string& DBusProxy::getDomain() const {
83     return domain_;
84 }
85
86 const std::string& DBusProxy::getServiceId() const {
87     return getInterfaceName();
88 }
89
90 const std::string& DBusProxy::getInstanceId() const {
91     return dbusBusName_;
92 }
93
94
95 bool DBusProxy::isAvailable() const {
96     if (!availableSet_) {
97         auto status = getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait_for(std::chrono::milliseconds(1));
98         if (checkReady(status)) {
99             available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
100             availableSet_ = true;
101         }
102     }
103     return available_;
104 }
105
106 bool DBusProxy::isAvailableBlocking() const {
107
108     if (!availableSet_) {
109         getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait();
110         available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
111         availableSet_ = true;
112     }
113     return available_;
114 }
115
116 ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
117     return statusEvent_;
118 }
119
120 InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
121     return interfaceVersionAttribute_;
122 }
123
124 DBusMessage DBusProxy::createMethodCall(const char* methodName,
125                                         const char* methodSignature) const {
126     return DBusMessage::createMethodCall(
127                     dbusBusName_.c_str(),
128                     dbusObjectPath_.c_str(),
129                     getInterfaceName().c_str(),
130                     methodName,
131                     methodSignature);
132 }
133
134 } // namespace DBus
135 } // namespace CommonAPI