add subscribe/unsubscribe methods for DBusServiceRegistry
[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 // Workaround for libstdc++ bug
8 #ifndef _GLIBCXX_USE_NANOSLEEP
9 #define _GLIBCXX_USE_NANOSLEEP
10 #endif
11
12 #include "DBusProxy.h"
13 #include "DBusUtils.h"
14
15 #include <cassert>
16
17
18 namespace CommonAPI {
19 namespace DBus {
20
21 DBusProxyStatusEvent::DBusProxyStatusEvent(DBusProxy* dbusProxy) :
22                 dbusProxy_(dbusProxy) {
23 }
24
25 void DBusProxyStatusEvent::onListenerAdded(const CancellableListener& listener) {
26     if (dbusProxy_->isAvailable())
27         listener(AvailabilityStatus::AVAILABLE);
28 }
29
30
31 DBusProxy::DBusProxy(const std::string& commonApiAddress,
32                      const std::string& dbusInterfaceName,
33                      const std::string& dbusBusName,
34                      const std::string& dbusObjectPath,
35                      const std::shared_ptr<DBusProxyConnection>& dbusConnection):
36                 DBusProxyBase(split(commonApiAddress, ':')[1],
37                               split(commonApiAddress, ':')[2],
38                               dbusInterfaceName,
39                               dbusBusName,
40                               dbusObjectPath,
41                               dbusConnection),
42                 dbusProxyStatusEvent_(this),
43                 availabilityStatus_(AvailabilityStatus::UNKNOWN),
44                 interfaceVersionAttribute_(*this, "getInterfaceVersion") {
45     const std::string commonApiDomain = split(commonApiAddress, ':')[0];
46     assert(commonApiDomain == "local");
47
48     dbusServiceRegistrySubscription_ = dbusConnection->getDBusServiceRegistry()->subscribeAvailabilityListener(
49                     commonApiAddress,
50                     std::bind(&DBusProxy::onDBusServiceInstanceStatus, this, std::placeholders::_1));
51 }
52
53 DBusProxy::~DBusProxy() {
54     getDBusConnection()->getDBusServiceRegistry()->unsubscribeAvailabilityListener(
55                     getAddress(),
56                     dbusServiceRegistrySubscription_);
57 }
58
59 bool DBusProxy::isAvailable() const {
60     return (availabilityStatus_ == AvailabilityStatus::AVAILABLE);
61 }
62
63 bool DBusProxy::isAvailableBlocking() const {
64     if (availabilityStatus_ == AvailabilityStatus::UNKNOWN) {
65         std::chrono::milliseconds singleWaitDuration(100);
66
67         // Wait for the service registry
68         while (availabilityStatus_ == AvailabilityStatus::UNKNOWN) {
69             std::this_thread::sleep_for(singleWaitDuration);
70         }
71     }
72
73     return isAvailable();
74 }
75
76 ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
77     return dbusProxyStatusEvent_;
78 }
79
80 InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
81     return interfaceVersionAttribute_;
82 }
83
84 void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus) {
85     availabilityStatus_ = availabilityStatus;
86
87     dbusProxyStatusEvent_.notifyListeners(availabilityStatus);
88 }
89
90 } // namespace DBus
91 } // namespace CommonAPI