return vsm_get_status();
}
-VsmStatus Client::vsm_lock_domain(const char*) noexcept
+VsmStatus Client::vsm_lock_domain(const char* id) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ assert(id);
+
+ GVariant* args_in = g_variant_new("(s)", id);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_LOCK_CONTAINER, args_in);
}
-VsmStatus Client::vsm_unlock_domain(const char*) noexcept
+VsmStatus Client::vsm_unlock_domain(const char* id) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ assert(id);
+
+ GVariant* args_in = g_variant_new("(s)", id);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_UNLOCK_CONTAINER, args_in);
}
VsmStatus Client::vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback,
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_INVALID_ID = "org.tizen.containers.Error.InvalidId";
-const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal";
+const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden";
+const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded";
+const std::string ERROR_INVALID_ID = "org.tizen.containers.Error.InvalidId";
+const std::string ERROR_INVALID_STATE = "org.tizen.containers.Error.InvalidState";
+const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal";
const std::string METHOD_PROXY_CALL = "ProxyCall";
return mAdmin->isStopped();
}
+void Container::suspend()
+{
+ Lock lock(mReconnectMutex);
+ mAdmin->suspend();
+}
+
+void Container::resume()
+{
+ Lock lock(mReconnectMutex);
+ mAdmin->resume();
+}
+
bool Container::isPaused()
{
Lock lock(mReconnectMutex);
bool isStopped();
/**
+ * Suspend container.
+ */
+ void suspend();
+
+ /**
+ * Resume container.
+ */
+ void resume();
+
+ /**
* @return Is the container in a paused state?
*/
bool isPaused();
mHostConnection.setDestroyContainerCallback(bind(&ContainersManager::handleDestroyContainerCall,
this, _1, _2));
+ mHostConnection.setLockContainerCallback(bind(&ContainersManager::handleLockContainerCall,
+ this, _1, _2));
+
+ mHostConnection.setUnlockContainerCallback(bind(&ContainersManager::handleUnlockContainerCall,
+ this, _1, _2));
+
for (auto& containerConfig : mConfig.containerConfigs) {
createContainer(containerConfig);
}
}
}
+bool ContainersManager::isPaused(const std::string& containerId)
+{
+ auto iter = mContainers.find(containerId);
+ if (iter == mContainers.end()) {
+ LOGE("No such container id: " << containerId);
+ throw ContainerOperationException("No such container");
+ }
+
+ return iter->second->isPaused();
+}
+
+bool ContainersManager::isRunning(const std::string& containerId)
+{
+ auto iter = mContainers.find(containerId);
+ if (iter == mContainers.end()) {
+ LOGE("No such container id: " << containerId);
+ throw ContainerOperationException("No such container");
+ }
+ return iter->second->isRunning();
+}
+
std::string ContainersManager::getRunningForegroundContainerId()
{
for (auto& container : mContainers) {
thread.detach(); //TODO fix it
}
+void ContainersManager::handleLockContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ LOGI("LockContainer call; Id=" << id );
+ auto iter = mContainers.find(id);
+ if (iter == mContainers.end()) {
+ LOGE("Failed to lock container - no such container id: " << id);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ return;
+ }
+
+ auto& container = *iter->second;
+ if (!container.isRunning()) {
+ LOGE("Container id=" << id << " is not running.");
+ result->setError(api::ERROR_INVALID_STATE, "Container is not running");
+ return;
+ }
+
+ LOGT("Lock container");
+ try {
+ container.suspend();
+ } catch (ContainerOperationException& e) {
+ LOGE(e.what());
+ result->setError(api::ERROR_INTERNAL, e.what());
+ return;
+ }
+
+ result->setVoid();
+}
+
+void ContainersManager::handleUnlockContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ LOGI("UnlockContainer call; Id=" << id );
+ auto iter = mContainers.find(id);
+ if (iter == mContainers.end()) {
+ LOGE("Failed to unlock container - no such container id: " << id);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ return;
+ }
+
+ auto& container = *iter->second;
+ if (!container.isPaused()) {
+ LOGE("Container id=" << id << " is not paused.");
+ result->setError(api::ERROR_INVALID_STATE, "Container is not paused");
+ return;
+ }
+
+ LOGT("Unlock container");
+ try {
+ container.resume();
+ } catch (ContainerOperationException& e) {
+ LOGE(e.what());
+ result->setError(api::ERROR_INTERNAL, e.what());
+ return;
+ }
+
+ result->setVoid();
+}
+
} // namespace security_containers
void stopAll();
/**
+ * @return Is the container in a paused state?
+ */
+ bool isPaused(const std::string& containerId);
+
+ /**
+ * @return Is the container running?
+ */
+ bool isRunning(const std::string& containerId);
+
+ /**
* @return id of the currently focused/foreground container
*/
std::string getRunningForegroundContainerId();
dbus::MethodResultBuilder::Pointer result);
void handleDestroyContainerCall(const std::string& id,
dbus::MethodResultBuilder::Pointer result);
+ void handleLockContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result);
+ void handleUnlockContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result);
};
mDestroyContainerCallback = callback;
}
+void HostConnection::setLockContainerCallback(const LockContainerCallback& callback)
+{
+ mLockContainerCallback = callback;
+}
+
+void HostConnection::setUnlockContainerCallback(const UnlockContainerCallback& callback)
+{
+ mUnlockContainerCallback = callback;
+}
+
+
void HostConnection::onMessageCall(const std::string& objectPath,
const std::string& interface,
const std::string& methodName,
mDestroyContainerCallback(id, result);
}
}
+
+ if (methodName == api::host::METHOD_LOCK_CONTAINER) {
+ const gchar* id = NULL;
+ g_variant_get(parameters, "(&s)", &id);
+
+ if (mLockContainerCallback){
+ mLockContainerCallback(id, result);
+ }
+ }
+
+ if (methodName == api::host::METHOD_UNLOCK_CONTAINER) {
+ const gchar* id = NULL;
+ g_variant_get(parameters, "(&s)", &id);
+
+ if (mUnlockContainerCallback){
+ mUnlockContainerCallback(id, result);
+ }
+ }
}
void HostConnection::proxyCallAsync(const std::string& busName,
typedef std::function<void(const std::string& id,
dbus::MethodResultBuilder::Pointer result
)> DestroyContainerCallback;
+ typedef std::function<void(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result
+ )> LockContainerCallback;
+ typedef std::function<void(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result
+ )> UnlockContainerCallback;
/**
* Register proxy call callback
void setDestroyContainerCallback(const DestroyContainerCallback& callback);
/**
+ * Register a callback called to lock container
+ */
+ void setLockContainerCallback(const LockContainerCallback& callback);
+
+ /**
+ * Register a callback called to unlock container
+ */
+ void setUnlockContainerCallback(const UnlockContainerCallback& callback);
+
+ /**
* Make a proxy call
*/
void proxyCallAsync(const std::string& busName,
SetActiveContainerCallback mSetActiveContainerCallback;
CreateContainerCallback mCreateContainerCallback;
DestroyContainerCallback mDestroyContainerCallback;
+ LockContainerCallback mLockContainerCallback;
+ UnlockContainerCallback mUnlockContainerCallback;
void onNameAcquired();
void onNameLost();
const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer";
const std::string METHOD_CREATE_CONTAINER = "CreateContainer";
const std::string METHOD_DESTROY_CONTAINER = "DestroyContainer";
+const std::string METHOD_LOCK_CONTAINER = "LockContainer";
+const std::string METHOD_UNLOCK_CONTAINER = "UnlockContainer";
const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState";
" <method name='" + METHOD_DESTROY_CONTAINER + "'>"
" <arg type='s' name='id' direction='in'/>"
" </method>"
+ " <method name='" + METHOD_LOCK_CONTAINER + "'>"
+ " <arg type='s' name='id' direction='in'/>"
+ " </method>"
+ " <method name='" + METHOD_UNLOCK_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'/>"
vsm_client_free(client);
}
+BOOST_AUTO_TEST_CASE(LockUnlockContainerTest)
+{
+ const std::string newActiveContainerId = "ut-containers-manager-console2-dbus";
+
+ VsmClient client = vsm_client_create();
+ VsmStatus status = vsm_connect(client);
+ BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+ status = vsm_lock_domain(client, newActiveContainerId.c_str());
+ BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+ status = vsm_unlock_domain(client, newActiveContainerId.c_str());
+ BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+ vsm_client_free(client);
+}
+
BOOST_AUTO_TEST_CASE(FileMoveRequestTest)
{
const std::string path = "/tmp/fake_path";
asyncResult);
}
+ void callMethodLockContainer(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_LOCK_CONTAINER,
+ parameters,
+ "()");
+ }
+
+ void callMethodUnlockContainer(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_UNLOCK_CONTAINER,
+ parameters,
+ "()");
+ }
+
private:
const int mId;
DbusConnection::Pointer mClient;
expectedMessage("Not implemented"));
}
+BOOST_AUTO_TEST_CASE(LockUnlockContainerTest)
+{
+ 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){
+ dbus.callMethodLockContainer(containerId);
+ BOOST_CHECK(cm.isPaused(containerId));
+ dbus.callMethodUnlockContainer(containerId);
+ BOOST_CHECK(cm.isRunning(containerId));
+ }
+
+ BOOST_REQUIRE_THROW(dbus.callMethodLockContainer(NON_EXISTANT_CONTAINER_ID),
+ DbusException);
+ BOOST_REQUIRE_THROW(dbus.callMethodUnlockContainer(NON_EXISTANT_CONTAINER_ID),
+ DbusException);
+
+ cm.stopAll();
+ BOOST_REQUIRE_THROW(dbus.callMethodLockContainer("ut-containers-manager-console1-dbus"),
+ DbusException);
+ BOOST_REQUIRE_THROW(dbus.callMethodUnlockContainer("ut-containers-manager-console1-dbus"),
+ DbusException);
+}
+
BOOST_AUTO_TEST_SUITE_END()