Multiple connection names from one factory
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusFactory.cpp
index fbdf2b2..39bfb7a 100644 (file)
-/* Copyright (C) 2013 BMW Group\r
- * Author: Manfred Bathelt (manfred.bathelt@bmw.de)\r
- * Author: Juergen Gehring (juergen.gehring@bmw.de)\r
- * This Source Code Form is subject to the terms of the Mozilla Public\r
- * License, v. 2.0. If a copy of the MPL was not distributed with this\r
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
-#include "DBusProxy.h"\r
-#include "DBusConnection.h"\r
-#include "DBusFactory.h"\r
-#include "DBusAddressTranslator.h"\r
-#include "DBusServiceRegistry.h"\r
-#include "DBusUtils.h"\r
-\r
-#include <algorithm>\r
-#include <cassert>\r
-#include <sstream>\r
-#include <unordered_map>\r
-#include <vector>\r
-\r
-namespace CommonAPI {\r
-namespace DBus {\r
-\r
-std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;\r
-std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;\r
-\r
-\r
-void DBusFactory::registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryMethod) {\r
-    if(!registeredProxyFactoryFunctions_) {\r
-        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction>();\r
-    }\r
-    registeredProxyFactoryFunctions_->insert({interfaceName, proxyFactoryMethod});\r
-}\r
-\r
-void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod) {\r
-    if(!registeredAdapterFactoryFunctions_) {\r
-        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction>();\r
-    }\r
-    registeredAdapterFactoryFunctions_->insert({interfaceName, adapterFactoryMethod});\r
-}\r
-\r
-\r
-\r
-DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo) :\r
-                CommonAPI::Factory(runtime, middlewareInfo),\r
-                dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),\r
-                acquiredConnectionName_("") {\r
-    dbusConnection_->connect();\r
-}\r
-\r
-DBusFactory::~DBusFactory() {\r
-}\r
-\r
-\r
-std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::string& serviceName,\r
-                                                                   const std::string& domainName) {\r
-    return dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances(serviceName, domainName);\r
-}\r
-\r
-\r
-bool DBusFactory::isServiceInstanceAlive(const std::string& participantId,\r
-                                         const std::string& serviceName,\r
-                                         const std::string& domainName) {\r
-\r
-    return dbusConnection_->getDBusServiceRegistry()->isServiceInstanceAlive(participantId, serviceName, domainName);\r
-}\r
-\r
-std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceIdentifier,\r
-                                                const std::string& participantId,\r
-                                                const std::string& serviceName,\r
-                                                const std::string& domain) {\r
-    std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;\r
-\r
-    std::string interfaceName;\r
-    std::string connectionName;\r
-    std::string objectPath;\r
-\r
-    DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);\r
-\r
-    if(!registeredProxyFactoryFunctions_) {\r
-        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction> {};\r
-    }\r
-\r
-    for (auto it = registeredProxyFactoryFunctions_->begin(); it != registeredProxyFactoryFunctions_->end(); ++it) {\r
-        if(it->first == interfaceIdentifier) {\r
-            return (it->second)(connectionName.c_str(), objectPath.c_str(), dbusConnection_);\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-std::shared_ptr<StubAdapter> DBusFactory::createAdapter(std::shared_ptr<StubBase> stubBase,\r
-                                                        const char* interfaceIdentifier,\r
-                                                        const std::string& participantId,\r
-                                                        const std::string& serviceName,\r
-                                                        const std::string& domain) {\r
-    assert(dbusConnection_->isConnected());\r
-\r
-    std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;\r
-\r
-    std::string interfaceName;\r
-    std::string connectionName;\r
-    std::string objectPath;\r
-\r
-    DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);\r
-\r
-    if(acquiredConnectionName_ == "") {\r
-        dbusConnection_->requestServiceNameAndBlock(connectionName);\r
-        acquiredConnectionName_ = connectionName;\r
-    } else if (acquiredConnectionName_ != connectionName) {\r
-        return NULL;\r
-    }\r
-\r
-    if(!registeredAdapterFactoryFunctions_) {\r
-        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};\r
-    }\r
-\r
-    for (auto it = registeredAdapterFactoryFunctions_->begin(); it != registeredAdapterFactoryFunctions_->end(); ++it) {\r
-        if(it->first == interfaceIdentifier) {\r
-            std::shared_ptr<DBusStubAdapter> dbusStubAdapter =  (it->second)(connectionName.c_str(), objectPath.c_str(), dbusConnection_, stubBase);\r
-            dbusStubAdapter->init();\r
-            return dbusStubAdapter;\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-\r
-} // namespace DBus\r
-} // namespace CommonAPI\r
+/* Copyright (C) 2013 BMW Group
+ * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
+ * Author: Juergen Gehring (juergen.gehring@bmw.de)
+ * 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>
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+
+namespace CommonAPI {
+namespace DBus {
+
+
+std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;
+std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;
+
+
+void DBusFactory::registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryMethod) {
+    if(!registeredProxyFactoryFunctions_) {
+        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction>();
+    }
+    registeredProxyFactoryFunctions_->insert({interfaceName, proxyFactoryMethod});
+}
+
+void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod) {
+    if(!registeredAdapterFactoryFunctions_) {
+        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction>();
+    }
+    registeredAdapterFactoryFunctions_->insert({interfaceName, adapterFactoryMethod});
+}
+
+
+DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr<MainLoopContext> mainLoopContext) :
+                CommonAPI::Factory(runtime, middlewareInfo),
+                dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),
+                mainLoopContext_(mainLoopContext) {
+    bool startDispatchThread = !mainLoopContext_;
+    dbusConnection_->connect(startDispatchThread);
+    if(mainLoopContext_) {
+        dbusConnection_->attachMainLoopContext(mainLoopContext);
+    }
+}
+
+
+DBusFactory::~DBusFactory() {
+}
+
+
+std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::string& serviceName,
+                                                                   const std::string& domainName) {
+    return dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances(serviceName, domainName);
+}
+
+
+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");
+
+    std::string interfaceName;
+    std::string connectionName;
+    std::string objectPath;
+    DBusAddressTranslator::getInstance().searchForDBusAddress(serviceAddress, interfaceName, connectionName, objectPath);
+
+    return dbusConnection_->getDBusServiceRegistry()->isServiceInstanceAlive(interfaceName, connectionName, objectPath);
+}
+
+
+bool DBusFactory::isServiceInstanceAlive(const std::string& participantId,
+                                         const std::string& serviceName,
+                                         const std::string& domainName) {
+    std::string serviceAddress = domainName + ":" + serviceName + ":" + 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,
+                                                const std::string& domain) {
+    std::string commonApiAddress = domain + ":" + serviceName + ":" + participantId;
+
+    std::string interfaceName;
+    std::string connectionName;
+    std::string objectPath;
+
+    DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
+
+    if(!registeredProxyFactoryFunctions_) {
+        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction> {};
+    }
+
+    for (auto it = registeredProxyFactoryFunctions_->begin(); it != registeredProxyFactoryFunctions_->end(); ++it) {
+        if(it->first == interfaceId) {
+            return (it->second)(commonApiAddress, interfaceName, connectionName, objectPath, dbusConnection_);
+        }
+    }
+
+    return NULL;
+}
+
+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;
+
+    std::string interfaceName;
+    std::string connectionName;
+    std::string objectPath;
+
+    DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
+
+    bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName);
+    if (!isServiceNameAcquired) {
+        return false;
+    }
+
+    if(!registeredAdapterFactoryFunctions_) {
+        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};
+    }
+
+    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 true;
+        }
+    }
+
+       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);
+}
+
+
+} // namespace DBus
+} // namespace CommonAPI