Correct instantiation of internal attribute
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusProxy.cpp
index 1a21ec4..1701fe1 100644 (file)
@@ -4,16 +4,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// Workaround for libstdc++ bug
+#ifndef _GLIBCXX_USE_NANOSLEEP
+#define _GLIBCXX_USE_NANOSLEEP
+#endif
+
 #include "DBusProxy.h"
-#include "DBusServiceRegistry.h"
 #include "DBusUtils.h"
 
-#include <algorithm>
 #include <cassert>
-#include <iostream>
-#include <dbus/dbus.h>
-#include <functional>
-#include <CommonAPI/Event.h>
+
 
 namespace CommonAPI {
 namespace DBus {
@@ -22,114 +22,98 @@ DBusProxyStatusEvent::DBusProxyStatusEvent(DBusProxy* dbusProxy) :
                 dbusProxy_(dbusProxy) {
 }
 
-void DBusProxyStatusEvent::onFirstListenerAdded(const Listener& listener) {
-    auto serviceStatusListener = std::bind(
-                    &DBusProxyStatusEvent::onServiceAvailableSignalHandler,
-                    this,
-                    std::placeholders::_1,
-                    std::placeholders::_2);
-
-    subscription_ = dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().subscribe(
-                    dbusProxy_->dbusBusName_ + ":" + dbusProxy_->dbusObjectPath_ + ":" + dbusProxy_->interfaceName_,
-                    serviceStatusListener);
+void DBusProxyStatusEvent::onListenerAdded(const CancellableListener& listener) {
+    if (dbusProxy_->isAvailable())
+        listener(AvailabilityStatus::AVAILABLE);
 }
 
-void DBusProxyStatusEvent::onLastListenerRemoved(const Listener& listener) {
-    dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().unsubscribe(subscription_);
+
+DBusProxy::DBusProxy(const std::string& commonApiAddress,
+                     const std::string& dbusInterfaceName,
+                     const std::string& dbusBusName,
+                     const std::string& dbusObjectPath,
+                     const std::shared_ptr<DBusProxyConnection>& dbusConnection):
+                DBusProxyBase(dbusConnection),
+                commonApiServiceId_(split(commonApiAddress, ':')[1]),
+                commonApiParticipantId_(split(commonApiAddress, ':')[2]),
+                dbusBusName_(dbusBusName),
+                dbusObjectPath_(dbusObjectPath),
+                dbusInterfaceName_(dbusInterfaceName),
+                dbusProxyStatusEvent_(this),
+                availabilityStatus_(AvailabilityStatus::UNKNOWN),
+                interfaceVersionAttribute_(*this, "getInterfaceVersion", "uu"),
+                dbusServiceRegistry_(dbusConnection->getDBusServiceRegistry()) {
+
+    const std::string commonApiDomain = split(commonApiAddress, ':')[0];
+    assert(commonApiDomain == "local");
+
+    dbusServiceRegistrySubscription_ = dbusServiceRegistry_->subscribeAvailabilityListener(
+                    commonApiAddress,
+                    std::bind(&DBusProxy::onDBusServiceInstanceStatus, this, std::placeholders::_1));
 }
 
-SubscriptionStatus DBusProxyStatusEvent::onServiceAvailableSignalHandler(const std::string& name,
-                                                                         const AvailabilityStatus& availabilityStatus) {
-    AvailabilityStatus availability = availabilityStatus;
+DBusProxy::~DBusProxy() {
+    dbusServiceRegistry_->unsubscribeAvailabilityListener(
+                    getAddress(),
+                    dbusServiceRegistrySubscription_);
+}
 
-    return notifyListeners(availability);
+bool DBusProxy::isAvailable() const {
+    return (availabilityStatus_ == AvailabilityStatus::AVAILABLE);
 }
 
-const std::string DBusProxy::domain_ = "local";
+bool DBusProxy::isAvailableBlocking() const {
+    if (availabilityStatus_ == AvailabilityStatus::UNKNOWN) {
+        std::chrono::milliseconds singleWaitDuration(2);
 
-DBusProxy::DBusProxy(const std::string& dbusBusName,
-                     const std::string& dbusObjectPath,
-                     const std::string& interfaceName,
-                     const std::shared_ptr<DBusProxyConnection>& dbusProxyConnection) :
-                                                dbusBusName_(dbusBusName),
-                                dbusObjectPath_(dbusObjectPath),
-                                interfaceName_(interfaceName),
-                                statusEvent_(this),
-                                interfaceVersionAttribute_(*this, "getInterfaceVersion"),
-                                available_(false),
-                                availableSet_(false),
-                                connection_(dbusProxyConnection) {
-}
-
-DBusProxy::DBusProxy(const std::string& dbusBusName,
-                     const std::string& dbusObjectPath,
-                     const std::string& interfaceName,
-                     const std::shared_ptr<DBusProxyConnection>& connection,
-                     const bool isAlwaysAvailable) :
-                 dbusBusName_(dbusBusName),
-                 dbusObjectPath_(dbusObjectPath),
-                 interfaceName_(interfaceName),
-                 statusEvent_(this),
-                 interfaceVersionAttribute_(*this, "getInterfaceVersion"),
-                 available_(isAlwaysAvailable),
-                 availableSet_(isAlwaysAvailable),
-                 connection_(connection) {
+        // Wait for the service registry
+        while (availabilityStatus_ == AvailabilityStatus::UNKNOWN) {
+            std::this_thread::sleep_for(singleWaitDuration);
+        }
+    }
+
+    return isAvailable();
 }
 
-std::string DBusProxy::getAddress() const {
-    return domain_ + ":" + interfaceName_ + ":" + dbusBusName_;
+ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
+    return dbusProxyStatusEvent_;
 }
 
-const std::string& DBusProxy::getDomain() const {
-    return domain_;
+InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
+    return interfaceVersionAttribute_;
 }
 
-const std::string& DBusProxy::getServiceId() const {
-    return getInterfaceName();
+void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus) {
+    availabilityStatus_ = availabilityStatus;
+    dbusProxyStatusEvent_.notifyListeners(availabilityStatus);
 }
 
-const std::string& DBusProxy::getInstanceId() const {
+const std::string& DBusProxy::getDBusBusName() const {
     return dbusBusName_;
 }
 
-
-bool DBusProxy::isAvailable() const {
-    if (!availableSet_) {
-        auto status = getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait_for(std::chrono::milliseconds(1));
-        if (checkReady(status)) {
-            available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
-            availableSet_ = true;
-        }
-    }
-    return available_;
+const std::string& DBusProxy::getDBusObjectPath() const {
+    return dbusObjectPath_;
 }
 
-bool DBusProxy::isAvailableBlocking() const {
+const std::string& DBusProxy::getInterfaceName() const {
+    return dbusInterfaceName_;
+}
 
-    if (!availableSet_) {
-        getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait();
-        available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
-        availableSet_ = true;
-    }
-    return available_;
+const std::string& DBusProxy::getDomain() const {
+    return commonApiDomain_;
 }
 
-ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
-    return statusEvent_;
+const std::string& DBusProxy::getServiceId() const {
+    return commonApiServiceId_;
 }
 
-InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
-    return interfaceVersionAttribute_;
+const std::string& DBusProxy::getInstanceId() const {
+    return commonApiParticipantId_;
 }
 
-DBusMessage DBusProxy::createMethodCall(const char* methodName,
-                                        const char* methodSignature) const {
-    return DBusMessage::createMethodCall(
-                    dbusBusName_.c_str(),
-                    dbusObjectPath_.c_str(),
-                    getInterfaceName().c_str(),
-                    methodName,
-                    methodSignature);
+std::string DBusProxy::getAddress() const {
+    return commonApiDomain_ + ":" + commonApiServiceId_ + ":" + commonApiParticipantId_;
 }
 
 } // namespace DBus