Multiple connection names from one factory
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusFactory.cpp
index 52a8737..39bfb7a 100644 (file)
@@ -4,12 +4,14 @@
  * 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/. */
+
 #include "DBusProxy.h"
 #include "DBusConnection.h"
 #include "DBusFactory.h"
 #include "DBusAddressTranslator.h"
 #include "DBusServiceRegistry.h"
 #include "DBusUtils.h"
+#include "DBusServicePublisher.h"
 
 #include <algorithm>
 #include <cassert>
@@ -20,6 +22,7 @@
 namespace CommonAPI {
 namespace DBus {
 
+
 std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;
 std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;
 
@@ -39,14 +42,18 @@ void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAd
 }
 
 
-
-DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo) :
+DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr<MainLoopContext> mainLoopContext) :
                 CommonAPI::Factory(runtime, middlewareInfo),
                 dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),
-                acquiredConnectionName_("") {
-    dbusConnection_->connect();
+                mainLoopContext_(mainLoopContext) {
+    bool startDispatchThread = !mainLoopContext_;
+    dbusConnection_->connect(startDispatchThread);
+    if(mainLoopContext_) {
+        dbusConnection_->attachMainLoopContext(mainLoopContext);
+    }
 }
 
+
 DBusFactory::~DBusFactory() {
 }
 
@@ -57,6 +64,11 @@ std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::st
 }
 
 
+void DBusFactory::getAvailableServiceInstancesAsync(Factory::GetAvailableServiceInstancesCallback callback, const std::string& serviceName, const std::string& serviceDomainName) {
+    dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstancesAsync(callback, serviceName, serviceDomainName);
+}
+
+
 bool DBusFactory::isServiceInstanceAlive(const std::string& serviceAddress) {
     std::vector<std::string> parts = split(serviceAddress, ':');
     assert(parts[0] == "local");
@@ -77,6 +89,34 @@ bool DBusFactory::isServiceInstanceAlive(const std::string& participantId,
     return isServiceInstanceAlive(serviceAddress);
 }
 
+
+SubscriptionStatus DBusFactory::isServiceInstanceAliveCallbackThunk(Factory::IsServiceInstanceAliveCallback callback, const AvailabilityStatus& status) {
+    callback(status == AvailabilityStatus::AVAILABLE);
+    return SubscriptionStatus::CANCEL;
+}
+
+void DBusFactory::isServiceInstanceAliveAsync(Factory::IsServiceInstanceAliveCallback callback, const std::string& serviceAddress) {
+    std::string interfaceName;
+    std::string connectionName;
+    std::string objectPath;
+
+    DBusAddressTranslator::getInstance().searchForDBusAddress(serviceAddress, interfaceName, connectionName, objectPath);
+
+    dbusConnection_->getDBusServiceRegistry()->subscribeAvailabilityListener(
+                    serviceAddress,
+                    std::bind(&DBusFactory::isServiceInstanceAliveCallbackThunk,
+                              this,
+                              callback,
+                              std::placeholders::_1)
+    );
+}
+
+void DBusFactory::isServiceInstanceAliveAsync(Factory::IsServiceInstanceAliveCallback callback, const std::string& serviceInstanceID, const std::string& serviceName, const std::string& serviceDomainName) {
+    std::string commonApiAddress = serviceDomainName + ":" + serviceName + ":" + serviceInstanceID;
+    isServiceInstanceAliveAsync(callback, commonApiAddress);
+}
+
+
 std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceId,
                                                 const std::string& participantId,
                                                 const std::string& serviceName,
@@ -102,11 +142,11 @@ std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceId,
     return NULL;
 }
 
-std::shared_ptr<StubAdapter> DBusFactory::createAdapter(std::shared_ptr<StubBase> stubBase,
-                                                        const char* interfaceId,
-                                                        const std::string& participantId,
-                                                        const std::string& serviceName,
-                                                        const std::string& domain) {
+bool DBusFactory::registerAdapter(std::shared_ptr<StubBase> stubBase,
+                                                                 const char* interfaceId,
+                                                                 const std::string& participantId,
+                                                                 const std::string& serviceName,
+                                                                 const std::string& domain) {
     assert(dbusConnection_->isConnected());
 
     std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
@@ -117,26 +157,33 @@ std::shared_ptr<StubAdapter> DBusFactory::createAdapter(std::shared_ptr<StubBase
 
     DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
 
-    if(acquiredConnectionName_ == "") {
-        dbusConnection_->requestServiceNameAndBlock(connectionName);
-        acquiredConnectionName_ = connectionName;
-    } else if (acquiredConnectionName_ != connectionName) {
-        return NULL;
+    bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName);
+    if (!isServiceNameAcquired) {
+        return false;
     }
 
     if(!registeredAdapterFactoryFunctions_) {
         registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};
     }
 
-    for (auto it = registeredAdapterFactoryFunctions_->begin(); it != registeredAdapterFactoryFunctions_->end(); ++it) {
-        if(it->first == interfaceId) {
-            std::shared_ptr<DBusStubAdapter> dbusStubAdapter =  (it->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_, stubBase);
+    auto foundFunction = registeredAdapterFactoryFunctions_->find(interfaceId);
+    if(foundFunction != registeredAdapterFactoryFunctions_->end()) {
+        std::shared_ptr<DBusStubAdapter> dbusStubAdapter = (foundFunction->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_, stubBase);
+        if(!dbusStubAdapter) {
+            return false;
+        }
+        if(DBusServicePublisher::getInstance()->registerService(commonApiAddress, dbusStubAdapter)) {
             dbusStubAdapter->init();
-            return dbusStubAdapter;
+            return true;
         }
     }
 
-    return NULL;
+       return false;
+}
+
+bool DBusFactory::unregisterService(const std::string& participantId, const std::string& serviceName, const std::string& domain) {
+    std::string serviceAddress(domain + ":" + serviceName + ":" + participantId);
+    return DBusServicePublisher::getInstance()->unregisterService(serviceAddress);
 }