Setting the active container through D-Bus 32/25032/9
authorJan Olszak <j.olszak@samsung.com>
Fri, 25 Jul 2014 08:42:26 +0000 (10:42 +0200)
committerJan Olszak <j.olszak@samsung.com>
Mon, 28 Jul 2014 14:40:27 +0000 (16:40 +0200)
[Bug/Feature]   D-Bus API for setting the active container
[Cause]         N/A
[Solution]      Added the new API
                Added a common part of dbus definitions
[Verification]  Build, install, run tests

Change-Id: I4be877c17751b6334e8d424ff64de8d884699ede

server/common-dbus-definitions.hpp [new file with mode: 0644]
server/container-connection.cpp
server/container-dbus-definitions.hpp
server/containers-manager.cpp
server/containers-manager.hpp
server/host-connection.cpp
server/host-connection.hpp
server/host-dbus-definitions.hpp
tests/unit_tests/server/ut-container-connection.cpp
tests/unit_tests/server/ut-containers-manager.cpp

diff --git a/server/common-dbus-definitions.hpp b/server/common-dbus-definitions.hpp
new file mode 100644 (file)
index 0000000..8821b34
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jan Olszak <j.olszak@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file
+ * @author  Jan Olszak (j.olszak@samsung.com)
+ * @brief   Common dbus api definitions
+ */
+
+#ifndef SERVER_COMMON_DBUS_DEFINITIONS_HPP
+#define SERVER_COMMON_DBUS_DEFINITIONS_HPP
+
+#include <string>
+
+
+namespace security_containers {
+namespace api {
+const std::string ERROR_FORBIDDEN  = "org.tizen.containers.Error.Forbidden";
+const std::string ERROR_FORWARDED  = "org.tizen.containers.Error.Forwarded";
+const std::string ERROR_UNKNOWN_ID = "org.tizen.containers.Error.UnknownId";
+
+const std::string METHOD_PROXY_CALL    = "ProxyCall";
+
+} // namespace api
+} // namespace security_containers
+
+
+#endif // SERVER_COMMON_DBUS_DEFINITIONS_HPP
index f71a5a6..0e96bb2 100644 (file)
@@ -59,19 +59,19 @@ ContainerConnection::ContainerConnection(const std::string& address, const OnNam
     mDbusConnection = dbus::DbusConnection::create(address);
 
     LOGT("Setting DBUS name");
-    mDbusConnection->setName(api::BUS_NAME,
+    mDbusConnection->setName(api::container::BUS_NAME,
                              std::bind(&ContainerConnection::onNameAcquired, this),
                              std::bind(&ContainerConnection::onNameLost, this));
 
     if (!waitForNameAndSetCallback(NAME_ACQUIRED_TIMEOUT, callback)) {
-        LOGE("Could not acquire dbus name: " << api::BUS_NAME);
-        throw ContainerConnectionException("Could not acquire dbus name: " + api::BUS_NAME);
+        LOGE("Could not acquire dbus name: " << api::container::BUS_NAME);
+        throw ContainerConnectionException("Could not acquire dbus name: " + api::container::BUS_NAME);
     }
 
     LOGT("Registering DBUS interface");
     using namespace std::placeholders;
-    mDbusConnection->registerObject(api::OBJECT_PATH,
-                                    api::DEFINITION,
+    mDbusConnection->registerObject(api::container::OBJECT_PATH,
+                                    api::container::DEFINITION,
                                     std::bind(&ContainerConnection::onMessageCall,
                                               this,
                                               _1,
@@ -157,11 +157,11 @@ void ContainerConnection::onMessageCall(const std::string& objectPath,
                                         GVariant* parameters,
                                         dbus::MethodResultBuilder::Pointer result)
 {
-    if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) {
+    if (objectPath != api::container::OBJECT_PATH || interface != api::container::INTERFACE) {
         return;
     }
 
-    if (methodName == api::METHOD_NOTIFY_ACTIVE_CONTAINER) {
+    if (methodName == api::container::METHOD_NOTIFY_ACTIVE_CONTAINER) {
         const gchar* application = NULL;
         const gchar* message = NULL;
         g_variant_get(parameters, "(&s&s)", &application, &message);
@@ -171,7 +171,7 @@ void ContainerConnection::onMessageCall(const std::string& objectPath,
         }
     }
 
-    if (methodName == api::METHOD_FILE_MOVE_REQUEST) {
+    if (methodName == api::container::METHOD_FILE_MOVE_REQUEST) {
         const gchar* destination = NULL;
         const gchar* path = NULL;
         g_variant_get(parameters, "(&s&s)", &destination, &path);
@@ -234,9 +234,9 @@ void ContainerConnection::sendNotification(const std::string& container,
                                          container.c_str(),
                                          application.c_str(),
                                          message.c_str());
-    mDbusConnection->emitSignal(api::OBJECT_PATH,
-                                api::INTERFACE,
-                                api::SIGNAL_NOTIFICATION,
+    mDbusConnection->emitSignal(api::container::OBJECT_PATH,
+                                api::container::INTERFACE,
+                                api::container::SIGNAL_NOTIFICATION,
                                 parameters);
 }
 
index fe72e4d..0e280d4 100644 (file)
 #ifndef SERVER_CONTAINER_DBUS_DEFINITIONS_HPP
 #define SERVER_CONTAINER_DBUS_DEFINITIONS_HPP
 
-#include <string>
+#include "common-dbus-definitions.hpp"
 
 
 namespace security_containers {
 namespace api {
-
+namespace container {
 
 const std::string BUS_NAME                          = "org.tizen.containers.domain";
 const std::string OBJECT_PATH                       = "/org/tizen/containers/domain";
@@ -38,7 +38,6 @@ const std::string INTERFACE                         = "org.tizen.containers.doma
 
 const std::string METHOD_NOTIFY_ACTIVE_CONTAINER    = "NotifyActiveContainer";
 const std::string METHOD_FILE_MOVE_REQUEST          = "FileMoveRequest";
-const std::string METHOD_PROXY_CALL                 = "ProxyCall";
 const std::string SIGNAL_NOTIFICATION               = "Notification";
 
 const std::string FILE_MOVE_DESTINATION_NOT_FOUND   = "FILE_MOVE_DESTINATION_NOT_FOUND";
@@ -78,7 +77,7 @@ const std::string DEFINITION =
     "  </interface>"
     "</node>";
 
-
+} // namespace container
 } // namespace api
 } // namespace security_containers
 
index b2c4222..012a8f7 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "config.hpp"
 
+#include "host-dbus-definitions.hpp"
+#include "common-dbus-definitions.hpp"
 #include "container-dbus-definitions.hpp"
 #include "containers-manager.hpp"
 #include "container-admin.hpp"
@@ -58,9 +60,6 @@ bool regexMatchVector(const std::string& str, const std::vector<boost::regex>& v
 }
 
 const std::string HOST_ID = "host";
-const std::string DBUS_ERROR_NAME_FORBIDDEN = "org.tizen.containers.Error.Forbidden";
-const std::string DBUS_ERROR_NAME_FORWARDED = "org.tizen.containers.Error.Forwarded";
-const std::string DBUS_ERROR_NAME_UNKNOWN_TARGET = "org.tizen.containers.Error.UnknownTarget";
 
 } // namespace
 
@@ -84,6 +83,9 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet
     mHostConnection.setGetActiveContainerIdCallback(bind(&ContainersManager::handleGetActiveContainerIdCall,
                                                          this, _1));
 
+    mHostConnection.setSetActiveContainerCallback(bind(&ContainersManager::handleSetActiveContainerCall,
+                                                       this, _1, _2));
+
     for (auto& containerConfig : mConfig.containerConfigs) {
         std::string containerConfigPath;
 
@@ -138,7 +140,6 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet
     }
 }
 
-
 ContainersManager::~ContainersManager()
 {
     LOGD("Destroying ContainersManager object...");
@@ -154,7 +155,6 @@ ContainersManager::~ContainersManager()
     LOGD("ContainersManager object destroyed");
 }
 
-
 void ContainersManager::focus(const std::string& containerId)
 {
     /* try to access the object first to throw immediately if it doesn't exist */
@@ -169,7 +169,6 @@ void ContainersManager::focus(const std::string& containerId)
     foregroundContainer->goForeground();
 }
 
-
 void ContainersManager::startAll()
 {
     LOGI("Starting all containers");
@@ -198,7 +197,6 @@ void ContainersManager::startAll()
     }
 }
 
-
 void ContainersManager::stopAll()
 {
     LOGI("Stopping all containers");
@@ -208,7 +206,6 @@ void ContainersManager::stopAll()
     }
 }
 
-
 std::string ContainersManager::getRunningForegroundContainerId()
 {
     for (auto& container : mContainers) {
@@ -304,26 +301,26 @@ void ContainersManager::handleContainerMoveFileRequest(const std::string& srcCon
     ContainerMap::const_iterator dstIter = mContainers.find(dstContainerId);
     if (dstIter == mContainers.end()) {
         LOGE("Destination container '" << dstContainerId << "' not found");
-        result->set(g_variant_new("(s)", api::FILE_MOVE_DESTINATION_NOT_FOUND.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_DESTINATION_NOT_FOUND.c_str()));
         return;
     }
     Container& dstContanier = *dstIter->second;
 
     if (srcContainerId == dstContainerId) {
         LOGE("Cannot send a file to yourself");
-        result->set(g_variant_new("(s)", api::FILE_MOVE_WRONG_DESTINATION.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_WRONG_DESTINATION.c_str()));
         return;
     }
 
     if (!regexMatchVector(path, srcContainer.getPermittedToSend())) {
         LOGE("Source container has no permissions to send the file: " << path);
-        result->set(g_variant_new("(s)", api::FILE_MOVE_NO_PERMISSIONS_SEND.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_NO_PERMISSIONS_SEND.c_str()));
         return;
     }
 
     if (!regexMatchVector(path, dstContanier.getPermittedToRecv())) {
         LOGE("Destination container has no permissions to receive the file: " << path);
-        result->set(g_variant_new("(s)", api::FILE_MOVE_NO_PERMISSIONS_RECEIVE.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_NO_PERMISSIONS_RECEIVE.c_str()));
         return;
     }
 
@@ -333,11 +330,11 @@ void ContainersManager::handleContainerMoveFileRequest(const std::string& srcCon
 
     if (!utils::moveFile(srcPath, dstPath)) {
         LOGE("Failed to move the file: " << path);
-        result->set(g_variant_new("(s)", api::FILE_MOVE_FAILED.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_FAILED.c_str()));
     } else {
-        result->set(g_variant_new("(s)", api::FILE_MOVE_SUCCEEDED.c_str()));
+        result->set(g_variant_new("(s)", api::container::FILE_MOVE_SUCCEEDED.c_str()));
         try {
-            dstContanier.sendNotification(srcContainerId, path, api::FILE_MOVE_SUCCEEDED);
+            dstContanier.sendNotification(srcContainerId, path, api::container::FILE_MOVE_SUCCEEDED);
         } catch (ServerException&) {
             LOGE("Notification to '" << dstContainerId << "' has not been sent");
         }
@@ -361,7 +358,7 @@ void ContainersManager::handleProxyCall(const std::string& caller,
                                               targetMethod)) {
         LOGW("Forbidden proxy call; " << caller << " -> " << target << "; " << targetBusName
                 << "; " << targetObjectPath << "; " << targetInterface << "; " << targetMethod);
-        result->setError(DBUS_ERROR_NAME_FORBIDDEN, "Proxy call forbidden");
+        result->setError(api::ERROR_FORBIDDEN, "Proxy call forbidden");
         return;
     }
 
@@ -373,7 +370,7 @@ void ContainersManager::handleProxyCall(const std::string& caller,
             GVariant* targetResult = asyncMethodCallResult.get();
             result->set(g_variant_new("(v)", targetResult));
         } catch (dbus::DbusException& e) {
-            result->setError(DBUS_ERROR_NAME_FORWARDED, e.what());
+            result->setError(api::ERROR_FORWARDED, e.what());
         }
     };
 
@@ -390,7 +387,7 @@ void ContainersManager::handleProxyCall(const std::string& caller,
     ContainerMap::const_iterator targetIter = mContainers.find(target);
     if (targetIter == mContainers.end()) {
         LOGE("Target container '" << target << "' not found");
-        result->setError(DBUS_ERROR_NAME_UNKNOWN_TARGET, "Unknown proxy call target");
+        result->setError(api::ERROR_UNKNOWN_ID, "Unknown proxy call target");
         return;
     }
 
@@ -445,4 +442,26 @@ void ContainersManager::handleGetActiveContainerIdCall(dbus::MethodResultBuilder
     }
 }
 
+void ContainersManager::handleSetActiveContainerCall(const std::string& id,
+                                                     dbus::MethodResultBuilder::Pointer result)
+{
+    LOGI("SetActiveContainer call; Id=" << id );
+    auto container = mContainers.find(id);
+    if (container == mContainers.end()){
+        LOGE("No container with id=" << id );
+        result->setError(api::ERROR_UNKNOWN_ID, "No such container id");
+        return;
+    }
+
+    if (container->second->isStopped()){
+        LOGE("Could not activate a stopped container");
+        result->setError(api::host::ERROR_CONTAINER_STOPPED,
+                         "Could not activate a stopped container");
+        return;
+    }
+
+    focus(id);
+    result->setVoid();
+}
+
 } // namespace security_containers
index b685028..33767a9 100644 (file)
@@ -102,11 +102,12 @@ private:
                          const std::string& targetMethod,
                          GVariant* parameters,
                          dbus::MethodResultBuilder::Pointer result);
-
     void handleGetContainerDbuses(dbus::MethodResultBuilder::Pointer result);
     void handleDbusStateChanged(const std::string& containerId, const std::string& dbusAddress);
     void handleGetContainerIdsCall(dbus::MethodResultBuilder::Pointer result);
     void handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result);
+    void handleSetActiveContainerCall(const std::string& id,
+                                      dbus::MethodResultBuilder::Pointer result);
 
 };
 
index 0d96039..83ba8f8 100644 (file)
@@ -51,19 +51,19 @@ HostConnection::HostConnection()
     mDbusConnection = dbus::DbusConnection::createSystem();
 
     LOGT("Setting DBUS name");
-    mDbusConnection->setName(hostapi::BUS_NAME,
+    mDbusConnection->setName(api::host::BUS_NAME,
                              std::bind(&HostConnection::onNameAcquired, this),
                              std::bind(&HostConnection::onNameLost, this));
 
     if (!waitForName(NAME_ACQUIRED_TIMEOUT)) {
-        LOGE("Could not acquire dbus name: " << hostapi::BUS_NAME);
-        throw HostConnectionException("Could not acquire dbus name: " + hostapi::BUS_NAME);
+        LOGE("Could not acquire dbus name: " << api::host::BUS_NAME);
+        throw HostConnectionException("Could not acquire dbus name: " + api::host::BUS_NAME);
     }
 
     LOGT("Registering DBUS interface");
     using namespace std::placeholders;
-    mDbusConnection->registerObject(hostapi::OBJECT_PATH,
-                                    hostapi::DEFINITION,
+    mDbusConnection->registerObject(api::host::OBJECT_PATH,
+                                    api::host::DEFINITION,
                                     std::bind(&HostConnection::onMessageCall,
                                               this, _1, _2, _3, _4, _5));
 
@@ -125,24 +125,39 @@ void HostConnection::setGetActiveContainerIdCallback(const GetActiveContainerIdC
     mGetActiveContainerIdCallback = callback;
 }
 
+void HostConnection::setSetActiveContainerCallback(const SetActiveContainerCallback& callback)
+{
+    mSetActiveContainerCallback = callback;
+}
+
 void HostConnection::onMessageCall(const std::string& objectPath,
                                         const std::string& interface,
                                         const std::string& methodName,
                                         GVariant* parameters,
                                         dbus::MethodResultBuilder::Pointer result)
 {
-    if (objectPath != hostapi::OBJECT_PATH || interface != hostapi::INTERFACE) {
+    if (objectPath != api::host::OBJECT_PATH || interface != api::host::INTERFACE) {
+        return;
+    }
+
+    if (methodName == api::host::METHOD_SET_ACTIVE_CONTAINER) {
+        const gchar* id = NULL;
+        g_variant_get(parameters, "(&s)", &id);
+
+        if (mSetActiveContainerCallback) {
+            mSetActiveContainerCallback(id, result);
+        }
         return;
     }
 
-    if (methodName == hostapi::METHOD_GET_CONTAINER_DBUSES) {
+    if (methodName == api::host::METHOD_GET_CONTAINER_DBUSES) {
         if (mGetContainerDbusesCallback) {
             mGetContainerDbusesCallback(result);
         }
         return;
     }
 
-    if (methodName == hostapi::METHOD_PROXY_CALL) {
+    if (methodName == api::METHOD_PROXY_CALL) {
         const gchar* target = NULL;
         const gchar* targetBusName = NULL;
         const gchar* targetObjectPath = NULL;
@@ -171,14 +186,14 @@ void HostConnection::onMessageCall(const std::string& objectPath,
         return;
     }
 
-    if (methodName == hostapi::METHOD_GET_CONTAINER_ID_LIST){
+    if (methodName == api::host::METHOD_GET_CONTAINER_ID_LIST){
         if (mGetContainerIdsCallback){
             mGetContainerIdsCallback(result);
         }
         return;
     }
 
-    if (methodName == hostapi::METHOD_GET_ACTIVE_CONTAINER_ID){
+    if (methodName == api::host::METHOD_GET_ACTIVE_CONTAINER_ID){
         if (mGetActiveContainerIdCallback){
             mGetActiveContainerIdCallback(result);
         }
@@ -206,9 +221,9 @@ void HostConnection::signalContainerDbusState(const std::string& containerId,
                                               const std::string& dbusAddress)
 {
     GVariant* parameters = g_variant_new("(ss)", containerId.c_str(), dbusAddress.c_str());
-    mDbusConnection->emitSignal(hostapi::OBJECT_PATH,
-                                hostapi::INTERFACE,
-                                hostapi::SIGNAL_CONTAINER_DBUS_STATE,
+    mDbusConnection->emitSignal(api::host::OBJECT_PATH,
+                                api::host::INTERFACE,
+                                api::host::SIGNAL_CONTAINER_DBUS_STATE,
                                 parameters);
 }
 
index 962fbb9..bc9015d 100644 (file)
@@ -51,13 +51,15 @@ public:
                                GVariant* parameters,
                                dbus::MethodResultBuilder::Pointer result
                               )> ProxyCallCallback;
-
     typedef std::function<void(dbus::MethodResultBuilder::Pointer result
                               )> GetContainerDbusesCallback;
-    typedef std::function<void(dbus::MethodResultBuilder::Pointer result)> GetContainerIdsCallback;
+    typedef std::function<void(dbus::MethodResultBuilder::Pointer result
+                              )> GetContainerIdsCallback;
     typedef std::function<void(dbus::MethodResultBuilder::Pointer result
                               )> GetActiveContainerIdCallback;
-
+    typedef std::function<void(const std::string& id,
+                               dbus::MethodResultBuilder::Pointer result
+                              )> SetActiveContainerCallback;
 
     /**
      * Register proxy call callback
@@ -85,6 +87,11 @@ public:
     void setGetActiveContainerIdCallback(const GetContainerIdsCallback& callback);
 
     /**
+     * Register a callback called to set the active container
+     */
+    void setSetActiveContainerCallback(const SetActiveContainerCallback& callback);
+
+    /**
      * Make a proxy call
      */
     void proxyCallAsync(const std::string& busName,
@@ -104,6 +111,7 @@ private:
     GetContainerDbusesCallback mGetContainerDbusesCallback;
     GetContainerIdsCallback mGetContainerIdsCallback;
     GetActiveContainerIdCallback mGetActiveContainerIdCallback;
+    SetActiveContainerCallback mSetActiveContainerCallback;
 
     void onNameAcquired();
     void onNameLost();
index ef30e1a..12e8d4a 100644 (file)
 #ifndef SERVER_HOST_DBUS_DEFINITIONS_HPP
 #define SERVER_HOST_DBUS_DEFINITIONS_HPP
 
-#include <string>
+#include "common-dbus-definitions.hpp"
 
 
 namespace security_containers {
-namespace hostapi {
+namespace api {
+namespace host {
 
+const std::string BUS_NAME                       = "org.tizen.containers.host";
+const std::string OBJECT_PATH                    = "/org/tizen/containers/host";
+const std::string INTERFACE                      = "org.tizen.containers.host.manager";
 
-const std::string BUS_NAME                          = "org.tizen.containers.host";
-const std::string OBJECT_PATH                       = "/org/tizen/containers/host";
-const std::string INTERFACE                         = "org.tizen.containers.host.manager";
+const std::string ERROR_CONTAINER_STOPPED        = "org.tizen.containers.host.Error.ContainersStopped";
 
-const std::string METHOD_PROXY_CALL                 = "ProxyCall";
-const std::string METHOD_GET_CONTAINER_DBUSES       = "GetContainerDbuses";
-const std::string METHOD_GET_CONTAINER_ID_LIST      = "GetContainerIds";
-const std::string METHOD_GET_ACTIVE_CONTAINER_ID    = "GetActiveContainerId";
+const std::string METHOD_GET_CONTAINER_DBUSES    = "GetContainerDbuses";
+const std::string METHOD_GET_CONTAINER_ID_LIST   = "GetContainerIds";
+const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId";
+const std::string METHOD_SET_ACTIVE_CONTAINER    = "SetActiveContainer";
+
+const std::string SIGNAL_CONTAINER_DBUS_STATE    = "ContainerDbusState";
 
-const std::string SIGNAL_CONTAINER_DBUS_STATE       = "ContainerDbusState";
 
 const std::string DEFINITION =
     "<node>"
@@ -64,6 +67,9 @@ const std::string DEFINITION =
     "    <method name='" + METHOD_GET_ACTIVE_CONTAINER_ID + "'>"
     "      <arg type='s' name='result' direction='out'/>"
     "    </method>"
+    "    <method name='" + METHOD_SET_ACTIVE_CONTAINER + "'>"
+    "      <arg type='s' name='id' direction='in'/>"
+    "    </method>"
     "    <signal name='" + SIGNAL_CONTAINER_DBUS_STATE + "'>"
     "      <arg type='s' name='container'/>"
     "      <arg type='s' name='dbusAddress'/>"
@@ -71,8 +77,8 @@ const std::string DEFINITION =
     "  </interface>"
     "</node>";
 
-
-} // namespace hostapi
+} // namespace host
+} // namespace api
 } // namespace security_containers
 
 
index 9f7b680..29dd310 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "container-connection.hpp"
 #include "container-connection-transport.hpp"
+#include "host-dbus-definitions.hpp"
 #include "container-dbus-definitions.hpp"
 // TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager
 #include "fake-power-manager-dbus-definitions.hpp"
@@ -152,10 +153,10 @@ BOOST_AUTO_TEST_CASE(NotifyActiveContainerApiTest)
     connection->setNotifyActiveContainerCallback(callback);
 
     DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress());
-    client->callMethod(api::BUS_NAME,
-                       api::OBJECT_PATH,
-                       api::INTERFACE,
-                       api::METHOD_NOTIFY_ACTIVE_CONTAINER,
+    client->callMethod(api::container::BUS_NAME,
+                       api::container::OBJECT_PATH,
+                       api::container::INTERFACE,
+                       api::container::METHOD_NOTIFY_ACTIVE_CONTAINER,
                        g_variant_new("(ss)", "testapp", "testmessage"),
                        "()");
     BOOST_CHECK(notifyCalled.wait(EVENT_TIMEOUT));
@@ -178,9 +179,9 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApiTest)
                        const std::string& interface,
                        const std::string& signalName,
                        GVariant* parameters) {
-        if (objectPath == api::OBJECT_PATH &&
-            interface == api::INTERFACE &&
-            signalName == api::SIGNAL_NOTIFICATION &&
+        if (objectPath == api::container::OBJECT_PATH &&
+            interface == api::container::INTERFACE &&
+            signalName == api::container::SIGNAL_NOTIFICATION &&
             g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) {
 
             const gchar* container = NULL;
@@ -194,7 +195,7 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApiTest)
             }
         }
     };
-    client->signalSubscribe(handler, api::BUS_NAME);
+    client->signalSubscribe(handler, api::container::BUS_NAME);
 
     connection->sendNotification("testcontainer", "testapp", "testmessage");
 
index d4708e3..b3ce809 100644 (file)
@@ -72,6 +72,7 @@ const std::string TEST_MESSAGE = "testmessage";
 const std::string FILE_CONTENT = "File content\n"
                                  "Line 1\n"
                                  "Line 2\n";
+const std::string NON_EXISTANT_CONTAINER_ID = "NON_EXISTANT_CONTAINER_ID";
 
 class DbusAccessory {
 public:
@@ -126,7 +127,7 @@ public:
 
     void signalSubscribe(const DbusConnection::SignalCallback& callback)
     {
-        mClient->signalSubscribe(callback, isHost() ? hostapi::BUS_NAME : api::BUS_NAME);
+        mClient->signalSubscribe(callback, isHost() ? api::host::BUS_NAME : api::container::BUS_NAME);
     }
 
     void emitSignal(const std::string& objectPath,
@@ -140,10 +141,10 @@ public:
     void callMethodNotify()
     {
         GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str());
-        mClient->callMethod(api::BUS_NAME,
-                            api::OBJECT_PATH,
-                            api::INTERFACE,
-                            api::METHOD_NOTIFY_ACTIVE_CONTAINER,
+        mClient->callMethod(api::container::BUS_NAME,
+                            api::container::OBJECT_PATH,
+                            api::container::INTERFACE,
+                            api::container::METHOD_NOTIFY_ACTIVE_CONTAINER,
                             parameters,
                             "()");
     }
@@ -151,10 +152,10 @@ public:
     std::string callMethodMove(const std::string& dest, const std::string& path)
     {
         GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str());
-        GVariantPtr result = mClient->callMethod(api::BUS_NAME,
-                                                 api::OBJECT_PATH,
-                                                 api::INTERFACE,
-                                                 api::METHOD_FILE_MOVE_REQUEST,
+        GVariantPtr result = mClient->callMethod(api::container::BUS_NAME,
+                                                 api::container::OBJECT_PATH,
+                                                 api::container::INTERFACE,
+                                                 api::container::METHOD_FILE_MOVE_REQUEST,
                                                  parameters,
                                                  "(s)");
 
@@ -212,10 +213,13 @@ public:
                                                    interface.c_str(),
                                                    method.c_str(),
                                                    parameters);
-        GVariantPtr result = mClient->callMethod(isHost() ? hostapi::BUS_NAME : api::BUS_NAME,
-                                                 isHost() ? hostapi::OBJECT_PATH : api::OBJECT_PATH,
-                                                 isHost() ? hostapi::INTERFACE : api::INTERFACE,
-                                                 isHost() ? hostapi::METHOD_PROXY_CALL : api::METHOD_PROXY_CALL,
+        GVariantPtr result = mClient->callMethod(isHost() ? api::host::BUS_NAME :
+                                                            api::container::BUS_NAME,
+                                                 isHost() ? api::host::OBJECT_PATH :
+                                                            api::container::OBJECT_PATH,
+                                                 isHost() ? api::host::INTERFACE :
+                                                            api::container::INTERFACE,
+                                                 api::METHOD_PROXY_CALL,
                                                  packedParameters,
                                                  "(v)");
         GVariant* unpackedResult = NULL;
@@ -227,10 +231,10 @@ public:
     {
         assert(isHost());
         Dbuses dbuses;
-        GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME,
-                                                 hostapi::OBJECT_PATH,
-                                                 hostapi::INTERFACE,
-                                                 hostapi::METHOD_GET_CONTAINER_DBUSES,
+        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
+                                                 api::host::OBJECT_PATH,
+                                                 api::host::INTERFACE,
+                                                 api::host::METHOD_GET_CONTAINER_DBUSES,
                                                  NULL,
                                                  "(a{ss})");
         GVariant* array = NULL;
@@ -249,10 +253,10 @@ public:
     std::vector<std::string> callMethodGetContainerIds()
     {
         assert(isHost());
-        GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME,
-                                                 hostapi::OBJECT_PATH,
-                                                 hostapi::INTERFACE,
-                                                 hostapi::METHOD_GET_CONTAINER_ID_LIST,
+        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
+                                                 api::host::OBJECT_PATH,
+                                                 api::host::INTERFACE,
+                                                 api::host::METHOD_GET_CONTAINER_ID_LIST,
                                                  NULL,
                                                  "(as)");
 
@@ -274,10 +278,10 @@ public:
     std::string callMethodGetActiveContainerId()
     {
         assert(isHost());
-        GVariantPtr result = mClient->callMethod(hostapi::BUS_NAME,
-                                                 hostapi::OBJECT_PATH,
-                                                 hostapi::INTERFACE,
-                                                 hostapi::METHOD_GET_ACTIVE_CONTAINER_ID,
+        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
+                                                 api::host::OBJECT_PATH,
+                                                 api::host::INTERFACE,
+                                                 api::host::METHOD_GET_ACTIVE_CONTAINER_ID,
                                                  NULL,
                                                  "(s)");
 
@@ -286,6 +290,19 @@ public:
         return containerId;
     }
 
+    void callMethodSetActiveContainer(const std::string& id)
+    {
+        assert(isHost());
+        GVariant* parameters = g_variant_new("(s)", id.c_str());
+        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
+                                                 api::host::OBJECT_PATH,
+                                                 api::host::INTERFACE,
+                                                 api::host::METHOD_SET_ACTIVE_CONTAINER,
+                                                 parameters,
+                                                 "()");
+
+    }
+
 private:
     const int mId;
     DbusConnection::Pointer mClient;
@@ -413,9 +430,9 @@ BOOST_AUTO_TEST_CASE(NotifyActiveContainerTest)
                       const std::string& signalName,
                       GVariant* parameters)
         {
-            if (objectPath == api::OBJECT_PATH &&
-                interface == api::INTERFACE &&
-                signalName == api::SIGNAL_NOTIFICATION &&
+            if (objectPath == api::container::OBJECT_PATH &&
+                interface == api::container::INTERFACE &&
+                signalName == api::container::SIGNAL_NOTIFICATION &&
                 g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) {
 
                 const gchar* container = NULL;
@@ -516,9 +533,9 @@ BOOST_AUTO_TEST_CASE(MoveFileTest)
                        const std::string& signalName,
                        GVariant* parameters)
         {
-            if (objectPath == api::OBJECT_PATH &&
-                interface == api::INTERFACE &&
-                signalName == api::SIGNAL_NOTIFICATION &&
+            if (objectPath == api::container::OBJECT_PATH &&
+                interface == api::container::INTERFACE &&
+                signalName == api::container::SIGNAL_NOTIFICATION &&
                 g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) {
 
                 const gchar* source = NULL;
@@ -547,27 +564,27 @@ BOOST_AUTO_TEST_CASE(MoveFileTest)
 
     // sending to a non existing container
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(BUGGY_CONTAINER, NO_PATH),
-                      api::FILE_MOVE_DESTINATION_NOT_FOUND);
+                      api::container::FILE_MOVE_DESTINATION_NOT_FOUND);
     BOOST_CHECK(notificationLatch.empty());
 
     // sending to self
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER1, NO_PATH),
-                      api::FILE_MOVE_WRONG_DESTINATION);
+                      api::container::FILE_MOVE_WRONG_DESTINATION);
     BOOST_CHECK(notificationLatch.empty());
 
     // no permission to send
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, "/etc/secret1"),
-                      api::FILE_MOVE_NO_PERMISSIONS_SEND);
+                      api::container::FILE_MOVE_NO_PERMISSIONS_SEND);
     BOOST_CHECK(notificationLatch.empty());
 
     // no permission to receive
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, "/etc/secret2"),
-                      api::FILE_MOVE_NO_PERMISSIONS_RECEIVE);
+                      api::container::FILE_MOVE_NO_PERMISSIONS_RECEIVE);
     BOOST_CHECK(notificationLatch.empty());
 
     // non existing file
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, BUGGY_PATH),
-                      api::FILE_MOVE_FAILED);
+                      api::container::FILE_MOVE_FAILED);
     BOOST_CHECK(notificationLatch.empty());
 
     // a working scenario
@@ -580,12 +597,12 @@ BOOST_AUTO_TEST_CASE(MoveFileTest)
     BOOST_REQUIRE(utils::saveFileContent(CONTAINER1PATH + "/file", FILE_CONTENT));
 
     BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(CONTAINER2, TMP + "/file"),
-                      api::FILE_MOVE_SUCCEEDED);
+                      api::container::FILE_MOVE_SUCCEEDED);
     BOOST_CHECK(notificationLatch.wait(EVENT_TIMEOUT));
     BOOST_CHECK(notificationLatch.empty());
     BOOST_CHECK_EQUAL(notificationSource, CONTAINER1);
     BOOST_CHECK_EQUAL(notificationPath, TMP + "/file");
-    BOOST_CHECK_EQUAL(notificationRetcode, api::FILE_MOVE_SUCCEEDED);
+    BOOST_CHECK_EQUAL(notificationRetcode, api::container::FILE_MOVE_SUCCEEDED);
     BOOST_CHECK(!fs::exists(CONTAINER1PATH + "/file"));
     BOOST_CHECK_EQUAL(utils::readFileContent(CONTAINER2PATH + "/file"), FILE_CONTENT);
 
@@ -756,9 +773,9 @@ BOOST_AUTO_TEST_CASE(ContainerDbusesSignalsTest)
                          const std::string& interface,
                          const std::string& signalName,
                          GVariant* parameters) {
-        if (objectPath == hostapi::OBJECT_PATH &&
-            interface == hostapi::INTERFACE &&
-            signalName == hostapi::SIGNAL_CONTAINER_DBUS_STATE) {
+        if (objectPath == api::host::OBJECT_PATH &&
+            interface == api::host::INTERFACE &&
+            signalName == api::host::SIGNAL_CONTAINER_DBUS_STATE) {
 
             const gchar* containerId = NULL;
             const gchar* dbusAddress = NULL;
@@ -827,4 +844,28 @@ BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest)
     BOOST_CHECK(dbus.callMethodGetActiveContainerId() == "");
 }
 
+BOOST_AUTO_TEST_CASE(SetActiveContainerTest)
+{
+    ContainersManager cm(TEST_DBUS_CONFIG_PATH);
+    cm.startAll();
+
+    DbusAccessory dbus(DbusAccessory::HOST_ID);
+
+    std::vector<std::string> containerIds = {"ut-containers-manager-console1-dbus",
+                                             "ut-containers-manager-console2-dbus",
+                                             "ut-containers-manager-console3-dbus"};
+
+    for (std::string& containerId: containerIds){
+        BOOST_REQUIRE_NO_THROW(dbus.callMethodSetActiveContainer(containerId));
+        BOOST_CHECK(dbus.callMethodGetActiveContainerId() == containerId);
+    }
+
+    BOOST_REQUIRE_THROW(dbus.callMethodSetActiveContainer(NON_EXISTANT_CONTAINER_ID),
+                        DbusException);
+
+    cm.stopAll();
+    BOOST_REQUIRE_THROW(dbus.callMethodSetActiveContainer("ut-containers-manager-console1-dbus"),
+                        DbusException);
+}
+
 BOOST_AUTO_TEST_SUITE_END()