[Bug/Feature] ContainerConnection lifecycle is tied with a connection's lifecycle,
OnNameLost callback added.
[Cause] Be consistent, OnNameLost callback will be required to handle disconnections
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: Ie43eda2a4774ef003bee9ed877b6caab041035ba
Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@partner.samsung.com>
} // namespace
-ContainerConnection::ContainerConnection()
+ContainerConnection::ContainerConnection(const std::string& address, const OnNameLostCallback& callback)
: mNameAcquired(false)
, mNameLost(false)
{
-}
-
-
-ContainerConnection::~ContainerConnection()
-{
-}
-
-
-void ContainerConnection::connect(const std::string& address)
-{
if (address.empty()) {
LOGW("The connection to the container is disabled");
return;
LOGT("Connecting to DBUS on " << address);
mDbusConnection = dbus::DbusConnection::create(address);
- LOGT("Setting DBUS name");
+ LOGT("Setting DBUS name");
mDbusConnection->setName(api::BUS_NAME,
std::bind(&ContainerConnection::onNameAcquired, this),
std::bind(&ContainerConnection::onNameLost, this));
- if (!waitForName(NAME_ACQUIRED_TIMEOUT)) {
+ if (!waitForNameAndSetCallback(NAME_ACQUIRED_TIMEOUT, callback)) {
LOGE("Could not acquire dbus name: " << api::BUS_NAME);
- disconnect();
throw ContainerConnectionException("Could not acquire dbus name: " + api::BUS_NAME);
}
LOGD("Connected");
}
-
-void ContainerConnection::disconnect()
+ContainerConnection::~ContainerConnection()
{
- LOGD("Disconnecting");
- mDbusConnection.reset();
-
- std::unique_lock<std::mutex> lock(mNameMutex);
- mNameAcquired = false;
- mNameLost = false;
}
-bool ContainerConnection::waitForName(const unsigned int timeoutMs)
+bool ContainerConnection::waitForNameAndSetCallback(const unsigned int timeoutMs, const OnNameLostCallback& callback)
{
std::unique_lock<std::mutex> lock(mNameMutex);
mNameCondition.wait_for(lock,
[this] {
return mNameAcquired || mNameLost;
});
+ if(mNameAcquired) {
+ mOnNameLostCallback = callback;
+ }
+
return mNameAcquired;
}
std::unique_lock<std::mutex> lock(mNameMutex);
mNameLost = true;
mNameCondition.notify_one();
- //TODO some callback?
+
+ if(mOnNameLostCallback) {
+ mOnNameLostCallback();
+ }
}
void ContainerConnection::setNotifyActiveContainerCallback(
class ContainerConnection {
public:
- ContainerConnection();
- ~ContainerConnection();
-
- /**
- * Connect to container.
- */
- void connect(const std::string& address);
+ typedef std::function<void()> OnNameLostCallback;
- /**
- * Disconnect from container.
- */
- void disconnect();
+ ContainerConnection(const std::string& address, const OnNameLostCallback& callback);
+ ~ContainerConnection();
// ------------- API --------------
std::condition_variable mNameCondition;
bool mNameAcquired;
bool mNameLost;
+ OnNameLostCallback mOnNameLostCallback;
NotifyActiveContainerCallback mNotifyActiveContainerCallback;
void onNameAcquired();
void onNameLost();
- bool waitForName(const unsigned int timeoutMs);
+ bool waitForNameAndSetCallback(const unsigned int timeoutMs, const OnNameLostCallback& callback);
void onMessageCall(const std::string& objectPath,
const std::string& interface,
{
mConnectionTransport.reset(new ContainerConnectionTransport(mConfig.runMountPoint));
mAdmin->start();
- mConnection.connect(mConnectionTransport->acquireAddress());
+ mConnection.reset(new ContainerConnection(mConnectionTransport->acquireAddress(),
+ std::bind(&Container::onNameLostCallback, this)));
// Send to the background only after we're connected,
// otherwise it'd take ages.
void Container::stop()
{
- mConnection.disconnect();
+ mConnection.reset();
mAdmin->stop();
mConnectionTransport.reset();
}
return mAdmin->isPaused();
}
+void Container::onNameLostCallback()
+{
+ // TODO: try to reconnect
+}
+
} // namespace security_containers
ContainerConfig mConfig;
std::unique_ptr<ContainerAdmin> mAdmin;
std::unique_ptr<ContainerConnectionTransport> mConnectionTransport;
- ContainerConnection mConnection;
+ std::unique_ptr<ContainerConnection> mConnection;
+
+ void onNameLostCallback();
};
} // namespace
-BOOST_AUTO_TEST_CASE(ConstructorDestructorTest)
-{
- BOOST_REQUIRE_NO_THROW(ContainerConnection());
-}
-
-BOOST_AUTO_TEST_CASE(ConnectTest)
+BOOST_AUTO_TEST_CASE(ConstructorDestructorConnectTest)
{
ScopedGlibLoop loop;
ScopedDbusDaemon dbus;
- ContainerConnection connection;
-
- BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
- BOOST_REQUIRE_NO_THROW(connection.disconnect());
+ BOOST_REQUIRE_NO_THROW(ContainerConnection(dbus.acquireAddress(), nullptr));
}
BOOST_AUTO_TEST_CASE(NotifyActiveContainerApiTest)
ScopedDbusDaemon dbus;
Latch notifyCalled;
- ContainerConnection connection;
+ std::unique_ptr<ContainerConnection> connection;
- BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
+ BOOST_REQUIRE_NO_THROW(connection.reset(new ContainerConnection(dbus.acquireAddress(), nullptr)));
auto callback = [&](const std::string& application, const std::string& message) {
if (application == "testapp" && message == "testmessage") {
notifyCalled.set();
}
};
- connection.setNotifyActiveContainerCallback(callback);
+ connection->setNotifyActiveContainerCallback(callback);
DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress());
client->callMethod(api::BUS_NAME,
ScopedDbusDaemon dbus;
Latch signalEmitted;
- ContainerConnection connection;
+ std::unique_ptr<ContainerConnection> connection;
- BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
+ BOOST_REQUIRE_NO_THROW(connection.reset(new ContainerConnection(dbus.acquireAddress(), nullptr)));
DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress());
};
client->signalSubscribe(handler, api::BUS_NAME);
- connection.sendNotification("testcontainer", "testapp", "testmessage");
+ connection->sendNotification("testcontainer", "testapp", "testmessage");
BOOST_CHECK(signalEmitted.wait(EVENT_TIMEOUT));
}