Align with the subdivided IService interfaces 00/136400/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 29 Jun 2017 09:20:35 +0000 (18:20 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 29 Jun 2017 09:52:15 +0000 (18:52 +0900)
Change-Id: I64b3b0857433e53fd6f8dc89ef16a38b197449c6
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
src/server/ActiveUserMonitor.cpp
src/server/ActiveUserMonitor.h
src/server/Credential.cpp
src/server/ServerMain.cpp
src/server/ServiceLoader.cpp
src/server/ServiceLoader.h
src/server/ServiceRunner.cpp
src/server/ServiceRunner.h

index 999fd1b..4110d68 100644 (file)
 
 #include <systemd/sd-login.h>
 #include <ServerUtil.h>
+#include "ServiceLoader.h"
 #include "ActiveUserMonitor.h"
 
 #define ROOT_UID 0
 
 using namespace ctx;
 
-ActiveUserMonitor::ActiveUserMonitor() :
+ActiveUserMonitor::ActiveUserMonitor(ServiceLoader* svcLoader) :
+       __serviceLoader(svcLoader),
        __connection(NULL),
-       __activateUser(NULL),
-       __deactivateUser(NULL),
-       __activeUid(ROOT_UID),
        __userNewSignalId(0),
        __userRemovedSignalId(0),
        __newClientSignalId(0)
@@ -37,11 +36,9 @@ ActiveUserMonitor::~ActiveUserMonitor()
 {
 }
 
-void ActiveUserMonitor::start(GDBusConnection* conn, uid_cb_t activateUser, uid_cb_t deactivateUser)
+void ActiveUserMonitor::start(GDBusConnection* conn)
 {
        __connection = conn;
-       __activateUser = activateUser;
-       __deactivateUser = deactivateUser;
 
        __userNewSignalId = g_dbus_connection_signal_subscribe(__connection,
                        NULL, "org.freedesktop.systemd1.Manager", "UserSessionStartupFinished", NULL,
@@ -67,28 +64,13 @@ void ActiveUserMonitor::__onUserSessionStarted(GDBusConnection* conn, const gcha
                const gchar* path, const gchar* iface, const gchar* name,
                GVariant* param, gpointer userData)
 {
-       uint32_t uid = 0;
-       guint64 uid64 = 0;
-
-       g_variant_get_child(param, 0, "t", &uid64);
-       uid = static_cast<uint32_t>(uid64);
+       guint64 uid = 0;
+       g_variant_get_child(param, 0, "t", &uid);
+       IF_FAIL_VOID_TAG(uid != 0, _W, "UID == 0");
 
-       IF_FAIL_VOID_TAG(uid > 0, _W, "UID == 0");
-
-       _D("UID: %u", uid);
+       _D("UID: %llu", uid);
 
-       ActiveUserMonitor* monitor = static_cast<ActiveUserMonitor*>(userData);
-
-       if (monitor->__activeUid == uid)
-               return;
-
-       if (monitor->__activeUid > ROOT_UID) {
-               _W("Over-activation of the user %u", uid);
-               monitor->__deactivateUser(monitor->__activeUid);
-       }
-
-       monitor->__activateUser(uid);
-       monitor->__activeUid = uid;
+       static_cast<ActiveUserMonitor*>(userData)->__add(static_cast<uid_t>(uid));
 }
 
 void ActiveUserMonitor::__onUserRemoved(GDBusConnection* conn, const gchar* sender,
@@ -97,45 +79,48 @@ void ActiveUserMonitor::__onUserRemoved(GDBusConnection* conn, const gchar* send
 {
        uint32_t uid = 0;
        g_variant_get_child(param, 0, "u", &uid);
-       IF_FAIL_VOID_TAG(uid > 0, _W, "UID == 0");
+       IF_FAIL_VOID_TAG(uid != 0, _W, "UID == 0");
 
        _D("UID: %u", uid);
 
-       ActiveUserMonitor* monitor = static_cast<ActiveUserMonitor*>(userData);
-
-       if (monitor->__activeUid == ROOT_UID) {
-               _W("No active user");
-               return;
-       }
-
-       if (monitor->__activeUid != uid) {
-               _W("Mismatched uid");
-       }
-
-       monitor->__deactivateUser(uid);
-       monitor->__activeUid = ROOT_UID;
+       static_cast<ActiveUserMonitor*>(userData)->__remove(static_cast<uid_t>(uid));
 }
 
 void ActiveUserMonitor::__onNewClient(GDBusConnection* conn, const gchar* sender,
                const gchar* path, const gchar* iface, const gchar* name,
                GVariant* param, gpointer userData)
 {
-       _D(GREEN("A new ServiceProxy signaled"));
+       _D(GREEN("A new ServiceProxy(%s) has been created."), sender);
 
        ActiveUserMonitor* monitor = static_cast<ActiveUserMonitor*>(userData);
-       IF_FAIL_VOID(monitor->__activeUid == ROOT_UID);
+       IF_FAIL_VOID(monitor->__uids.empty());
 
        uid_t* users = NULL;
-       int numUsers = sd_get_active_uids(&users);
-       IF_FAIL_VOID(numUsers > 0);
+       int numUsers = sd_get_uids(&users);
+
+       for (int i = 0; i < numUsers; ++i) {
+               monitor->__add(users[i]);
+       }
 
-       uid_t activeUid = users[0];
        g_free(users);
+}
 
-       IF_FAIL_VOID(activeUid != ROOT_UID);
+void ActiveUserMonitor::__add(uid_t uid)
+{
+       if (__uids.find(uid) != __uids.end())
+               return;
+
+       __serviceLoader->startUser(uid);
+       __serviceLoader->notifyUserNew(uid);
+       __uids.insert(uid);
+}
 
-       _D("UID: %u", monitor->__activeUid);
+void ActiveUserMonitor::__remove(uid_t uid)
+{
+       if (__uids.find(uid) == __uids.end())
+               return;
 
-       monitor->__activeUid = activeUid;
-       monitor->__activateUser(activeUid);
+       __serviceLoader->stopUser(uid);
+       __serviceLoader->notifyUserRemoved(uid);
+       __uids.erase(uid);
 }
index d84fc9c..a4ea2c2 100644 (file)
 #ifndef __CONTEXT_ACTIVE_USER_MONITOR_H__
 #define __CONTEXT_ACTIVE_USER_MONITOR_H__
 
+#include <set>
 #include <ContextTypes.h>
 
 namespace ctx {
 
-       class ActiveUserMonitor {
-
-               typedef void (*uid_cb_t)(uid_t);
+       class ServiceLoader;
 
+       class ActiveUserMonitor {
        public:
-               ActiveUserMonitor();
+               ActiveUserMonitor(ServiceLoader* svcLoader);
                ~ActiveUserMonitor();
 
-               void start(GDBusConnection* conn, uid_cb_t activateUser, uid_cb_t deactivateUser);
+               void start(GDBusConnection* conn);
                void stop();
 
        private:
@@ -45,13 +45,17 @@ namespace ctx {
                                const gchar* path, const gchar* iface, const gchar* name,
                                GVariant* param, gpointer userData);
 
+               void __add(uid_t uid);
+               void __remove(uid_t uid);
+
+               ServiceLoader* __serviceLoader;
                GDBusConnection* __connection;
-               uid_cb_t __activateUser;
-               uid_cb_t __deactivateUser;
-               uid_t __activeUid;
+
                guint __userNewSignalId;
                guint __userRemovedSignalId;
                guint __newClientSignalId;
+
+               std::set<uid_t> __uids;
        };
 
 }
index 5bf2e14..445e569 100644 (file)
@@ -154,5 +154,5 @@ const std::string& Credential::getClientId() const
 
 bool Credential::isSystem() const
 {
-       return util::isSystemUid(__uid);
+       return util::isSystem(__uid);
 }
index a1d002e..3738a00 100644 (file)
@@ -64,22 +64,12 @@ void MainLoop::stop()
 }
 
 static ServiceLoader __serviceLoader;
-static ActiveUserMonitor __activeUserMonitor;
+static ActiveUserMonitor __activeUserMonitor(&__serviceLoader);
 static AlarmInitializer __alarmInit;
 
-static void __activateUser(uid_t uid)
-{
-       __serviceLoader.startUser(uid);
-}
-
-static void __deactivateUser(uid_t uid)
-{
-       __serviceLoader.stopUser();
-}
-
 static void __startService(GDBusConnection* conn)
 {
-       __activeUserMonitor.start(conn, __activateUser, __deactivateUser);
+       __activeUserMonitor.start(conn);
 
        _I("Loading services");
        if (!__serviceLoader.load(conn)) {
@@ -96,8 +86,7 @@ static gboolean __stopService(gpointer data)
        __activeUserMonitor.stop();
 
        _I("Unloading services");
-       __serviceLoader.stopUser();
-       __serviceLoader.stopSystem();
+       __serviceLoader.stopAll();
 
        MainLoop::stop();
        return G_SOURCE_REMOVE;
index 90f8ef1..70b2a6e 100644 (file)
 
 #include "ServiceLoader.h"
 
-#define ROOT_UID 0
-
 using namespace ctx;
 
-ServiceLoader::ServiceLoader() :
-       __activeUser(ROOT_UID)
+ServiceLoader::ServiceLoader()
 {
 }
 
@@ -41,6 +38,31 @@ ServiceLoader::~ServiceLoader()
        }
 }
 
+template<typename ServiceType>
+void ServiceLoader::__create(GDBusConnection* conn)
+{
+       IService* svc = NULL;
+
+       try {
+               svc = new ServiceType();
+       } catch (const std::runtime_error& e) {
+               _I(YELLOW("%s"), e.what());
+               return;
+       }
+
+       ServiceRunner* runner = NULL;
+
+       if (dynamic_cast<IUserService*>(svc)) {
+               runner = new UserServiceRunner(conn, svc);
+               __userServices.push_back(runner);
+       } else {
+               runner = new SystemServiceRunner(conn, svc);
+               __systemServices.push_back(runner);
+       }
+
+       svc->setServiceRunner(runner);
+}
+
 bool ServiceLoader::load(GDBusConnection* conn)
 {
        __create<ContextStoreService>(conn);
@@ -67,36 +89,45 @@ void ServiceLoader::stopSystem()
 
 void ServiceLoader::startUser(uid_t uid)
 {
-       IF_FAIL_VOID(__activeUser != uid);
-       _I("Starting services for %u", static_cast<unsigned int>(uid));
-
-       util::setActiveUid(uid);
-
-       for (auto& runner : __userServices) {
-               runner->start();
+       if (util::isNormalUser(uid)) {
+               for (auto& runner : __userServices) {
+                       runner->stop();
+                       runner->start(uid);
+               }
        }
+}
 
-       for (auto& runner : __systemServices) {
-               runner->notifyUserNew();
+void ServiceLoader::stopUser(uid_t uid)
+{
+       if (util::isNormalUser(uid)) {
+               for (auto& runner : __userServices) {
+                       runner->stop();
+               }
        }
 
-       __activeUser = uid;
 }
 
-void ServiceLoader::stopUser()
+void ServiceLoader::stopAll()
 {
-       IF_FAIL_VOID(__activeUser != ROOT_UID);
-       _I("Stopping services for %u", static_cast<unsigned int>(__activeUser));
-
        for (auto& runner : __userServices) {
                runner->stop();
        }
 
-       util::setActiveUid(ROOT_UID);
+       for (auto& runner : __systemServices) {
+               runner->stop();
+       }
+}
 
+void ServiceLoader::notifyUserNew(uid_t uid)
+{
        for (auto& runner : __systemServices) {
-               runner->notifyUserRemoved();
+               runner->notifyUserNew(uid);
        }
+}
 
-       __activeUser = ROOT_UID;
+void ServiceLoader::notifyUserRemoved(uid_t uid)
+{
+       for (auto& runner : __systemServices) {
+               runner->notifyUserRemoved(uid);
+       }
 }
index ef85039..cdf426d 100644 (file)
@@ -20,6 +20,7 @@
 #include <vector>
 #include <ContextTypes.h>
 #include <IService.h>
+#include <IUserService.h>
 #include "ServiceRunner.h"
 #include "ServiceClient.h"
 
@@ -32,36 +33,22 @@ namespace ctx {
 
                bool load(GDBusConnection* conn);
 
-               void startUser(uid_t uid);
-               void stopUser();
                void startSystem();
                void stopSystem();
 
-       private:
-               uid_t __activeUser;
-               std::vector<ServiceRunner*> __userServices;
-               std::vector<ServiceRunner*> __systemServices;
+               void startUser(uid_t uid);
+               void stopUser(uid_t uid);
 
-               template<typename ServiceType> void __create(GDBusConnection* conn)
-               {
-                       IService* svc = NULL;
+               void stopAll();
 
-                       try {
-                               svc = new ServiceType();
-                       } catch (const std::runtime_error& e) {
-                               _I(YELLOW("%s"), e.what());
-                               return;
-                       }
+               void notifyUserNew(uid_t uid);
+               void notifyUserRemoved(uid_t uid);
 
-                       ServiceRunner* runner = new ServiceRunner(conn, svc);
-                       svc->setServiceRunner(runner);
+       private:
+               std::vector<ServiceRunner*> __userServices;
+               std::vector<ServiceRunner*> __systemServices;
 
-                       if (svc->isUserService()) {
-                               __userServices.push_back(runner);
-                       } else {
-                               __systemServices.push_back(runner);
-                       }
-               }
+               template<typename ServiceType> void __create(GDBusConnection* conn);
        };
 
 }
index b35859d..f29edbc 100644 (file)
  * limitations under the License.
  */
 
-#include <ScopeMutex.h>
+#include <ServerUtil.h>
+#include <SharedUtil.h>
+#include <ISystemService.h>
+#include <IUserService.h>
 #include "MethodCall.h"
 #include "ServiceClient.h"
 #include "ServiceRunner.h"
 using namespace ctx;
 
 ServiceRunner::ServiceRunner(GDBusConnection* conn, IService* service) :
-       __service(service),
-       __started(false),
+       serviceInstance(service),
+       started(false),
+       __uid(0),
        __connection(conn),
        __objPath(CTX_DBUS_PATH "/"),
        __interface(CTX_DBUS_IFACE "."),
        __nodeInfo(NULL),
        __registrationId(0)
 {
-       __objPath += __service->getServiceName();
-       __interface += __service->getServiceName();
+       __objPath += serviceInstance->getServiceName();
+       __interface += serviceInstance->getServiceName();
 }
 
 ServiceRunner::~ServiceRunner()
@@ -50,33 +54,34 @@ GDBusConnection* ServiceRunner::getConnection()
 
 IService* ServiceRunner::getService()
 {
-       return __service;
+       return serviceInstance;
 }
 
-bool ServiceRunner::start()
+bool ServiceRunner::start(uid_t uid)
 {
-       IF_FAIL_RETURN(!__started, true);
+       IF_FAIL_RETURN(!started, true);
 
-       _I(CYAN("Starting '%s'"), __service->getServiceName());
+       _I(CYAN("Starting '%s'"), serviceInstance->getServiceName());
 
-       if (!__init()) {
+       if (!__init(uid)) {
                _E("Starting failed");
-               __release();
+               __release(uid);
                return false;
        }
 
-       __started = true;
+       started = true;
+       __uid = uid;
        return true;
 }
 
 void ServiceRunner::stop()
 {
-       IF_FAIL_VOID(__started);
-       __started = false;
+       IF_FAIL_VOID(started);
+       started = false;
 
-       _I(PURPLE("Stopping '%s'"), __service->getServiceName());
+       _I(PURPLE("Stopping '%s'"), serviceInstance->getServiceName());
 
-       __release();
+       __release(__uid);
 }
 
 void ServiceRunner::publish(const std::string& busName, const std::string& signalName, GVariant* param)
@@ -88,19 +93,7 @@ void ServiceRunner::publish(const std::string& busName, const std::string& signa
        HANDLE_GERROR(gerr);
 }
 
-void ServiceRunner::notifyUserNew()
-{
-       if (__started)
-               __service->onUserActivated();
-}
-
-void ServiceRunner::notifyUserRemoved()
-{
-       if (__started)
-               __service->onUserDeactivated();
-}
-
-bool ServiceRunner::__init()
+bool ServiceRunner::__init(uid_t uid)
 {
        GError* gerr = NULL;
        GDBusInterfaceVTable vtable;
@@ -110,7 +103,7 @@ bool ServiceRunner::__init()
        vtable.set_property = NULL;
 
        std::string introspection("<node><interface name='");
-       introspection += __interface + "'>" + __service->getMethodSpecs() + "</interface></node>";
+       introspection += __interface + "'>" + serviceInstance->getMethodSpecs() + "</interface></node>";
 
        __nodeInfo = g_dbus_node_info_new_for_xml(introspection.c_str(), NULL);
        IF_FAIL_RETURN_TAG(__nodeInfo, false, _E, "NodeInfo creation failed");
@@ -120,10 +113,10 @@ bool ServiceRunner::__init()
        HANDLE_GERROR(gerr);
        IF_FAIL_RETURN_TAG(__registrationId > 0, false, _E, "Object registration failed");
 
-       return __service->prepare();
+       return __prepare(uid);
 }
 
-void ServiceRunner::__release()
+void ServiceRunner::__release(uid_t uid)
 {
        for (auto iter = __clients.begin(); iter != __clients.end(); ++iter) {
                iter->second.client->onDisconnected();
@@ -132,7 +125,7 @@ void ServiceRunner::__release()
 
        __clients.clear();
 
-       __service->cleanup();
+       __cleanup(uid);
 
        if (__registrationId > 0)
                g_dbus_connection_unregister_object(__connection, __registrationId);
@@ -146,16 +139,14 @@ void ServiceRunner::__onMethodCalled(GDBusConnection* conn, const gchar* sender,
                GVariant* param, GDBusMethodInvocation* invocation, gpointer userData)
 {
        ServiceRunner* runner = static_cast<ServiceRunner*>(userData);
-       runner->__onMethodCalled(sender, name, param, invocation);
-}
 
-void ServiceRunner::__onMethodCalled(const std::string& sender,
-               const std::string& name, GVariant* param, GDBusMethodInvocation* invocation)
-{
-       _I("'%s' called '%s.%s'", sender.c_str(), __service->getServiceName(), name.c_str());
+       _I("'%s' called '%s.%s'", sender, iface, name);
 
-       ServiceClient* client = __getClient(sender);
-       IF_FAIL_VOID(client);
+       ServiceClient* client = runner->__getClient(sender);
+       if (!client) {
+               g_dbus_method_invocation_return_error_literal(invocation, CTX_ERROR_DOMAIN, E_SUPPORT, "");
+               return;
+       }
 
        client->onMethodCalled(new MethodCall(client, name, param, invocation));
 }
@@ -167,15 +158,12 @@ ServiceClient* ServiceRunner::__getClient(const std::string& busName)
        if (iter != __clients.end())
                return iter->second.client;
 
-       ServiceClient* client = new ServiceClient(this, busName);
-       if (!client->isVerified()) {
-               delete client;
-               return NULL;
-       }
+       ServiceClient* client = __createClient(busName);
+       IF_FAIL_RETURN(client, NULL);
 
-       IMethodCallHandler* callHandler = __service->createMethodCallHandler(client);
+       IMethodCallHandler* callHandler = serviceInstance->createMethodCallHandler(client);
        if (!callHandler) {
-               _E("This cannot be NULL.");
+               _E("%s's method call handler cannot be NULL.", serviceInstance->getServiceName());
                delete client;
                return NULL;
        }
@@ -198,7 +186,7 @@ void ServiceRunner::__onNameOwnerChanged(GDBusConnection* conn, const gchar* sen
 
 void ServiceRunner::__removeClient(const std::string& busName)
 {
-       _I("'%s' lost '%s'", __service->getServiceName(), busName.c_str());
+       _I("'%s' lost '%s'", serviceInstance->getServiceName(), busName.c_str());
 
        auto iter = __clients.find(busName);
        IF_FAIL_VOID(iter != __clients.end());
@@ -222,3 +210,84 @@ void ServiceRunner::__unwatch(unsigned int watchId)
 {
        g_dbus_connection_signal_unsubscribe(__connection, watchId);
 }
+
+
+SystemServiceRunner::SystemServiceRunner(GDBusConnection* conn, IService* service) :
+       ServiceRunner(conn, service)
+{
+}
+
+void SystemServiceRunner::notifyUserNew(uid_t uid)
+{
+       if (started)
+               static_cast<ISystemService*>(serviceInstance)->onUserActivated(uid);
+}
+
+void SystemServiceRunner::notifyUserRemoved(uid_t uid)
+{
+       if (started)
+               static_cast<ISystemService*>(serviceInstance)->onUserDeactivated(uid);
+}
+
+bool SystemServiceRunner::__prepare(uid_t uid)
+{
+       return static_cast<ISystemService*>(serviceInstance)->prepare();
+}
+
+void SystemServiceRunner::__cleanup(uid_t uid)
+{
+       static_cast<ISystemService*>(serviceInstance)->cleanup();
+}
+
+ServiceClient* SystemServiceRunner::__createClient(const std::string& busName)
+{
+       ServiceClient* client = new ServiceClient(this, busName);
+
+       if (!client->isVerified()) {
+               delete client;
+               return NULL;
+       }
+
+       return client;
+}
+
+UserServiceRunner::UserServiceRunner(GDBusConnection* conn, IService* service) :
+       ServiceRunner(conn, service)
+{
+}
+
+void UserServiceRunner::notifyUserNew(uid_t uid)
+{
+}
+
+void UserServiceRunner::notifyUserRemoved(uid_t uid)
+{
+}
+
+bool UserServiceRunner::__prepare(uid_t uid)
+{
+       return static_cast<IUserService*>(serviceInstance)->prepare(uid);
+}
+
+void UserServiceRunner::__cleanup(uid_t uid)
+{
+       static_cast<IUserService*>(serviceInstance)->cleanup(uid);
+}
+
+ServiceClient* UserServiceRunner::__createClient(const std::string& busName)
+{
+       ServiceClient* client = new ServiceClient(this, busName);
+
+       if (!client->isVerified()) {
+               delete client;
+               return NULL;
+       }
+
+       if (!util::isNormalUser(client->getUid())) {
+               _W("%s does not support container users.", serviceInstance->getServiceName());
+               delete client;
+               return NULL;
+       }
+
+       return client;
+}
index b51fcd9..0e7cf3d 100644 (file)
@@ -29,14 +29,13 @@ namespace ctx {
 
        class ServiceRunner : public IServiceRunner {
        public:
-               ServiceRunner(GDBusConnection* conn, IService* service);
-               ~ServiceRunner();
+               virtual ~ServiceRunner();
 
-               bool start();
-               void stop();
+               virtual void notifyUserNew(uid_t uid) = 0;
+               virtual void notifyUserRemoved(uid_t uid) = 0;
 
-               void notifyUserNew();
-               void notifyUserRemoved();
+               bool start(uid_t uid = 0);
+               void stop();
 
                void publish(const std::string& busName, const std::string& signalName, GVariant* param);
 
@@ -44,6 +43,12 @@ namespace ctx {
                GDBusConnection* getConnection();
                IService* getService();
 
+       protected:
+               ServiceRunner(GDBusConnection* conn, IService* service);
+
+               IService* serviceInstance;
+               bool started;
+
        private:
                static void __onMethodCalled(GDBusConnection* conn, const gchar* sender,
                                const gchar* path, const gchar* iface, const gchar* name,
@@ -53,19 +58,20 @@ namespace ctx {
                                const gchar* path, const gchar* iface, const gchar* name,
                                GVariant* param, gpointer userData);
 
-               void __onMethodCalled(const std::string& sender,
-                               const std::string& name, GVariant* param, GDBusMethodInvocation* invocation);
+               virtual bool __prepare(uid_t uid) = 0;
+               virtual void __cleanup(uid_t uid) = 0;
 
-               bool __init();
-               void __release();
+               virtual ServiceClient* __createClient(const std::string& busName) = 0;
+
+               bool __init(uid_t uid);
+               void __release(uid_t uid);
 
                ServiceClient* __getClient(const std::string& busName);
                void __removeClient(const std::string& busName);
                unsigned int __watch(const std::string& busName, ServiceClient* client);
                void __unwatch(unsigned int watchId);
 
-               IService* __service;
-               bool __started;
+               uid_t __uid;
 
                GDBusConnection* __connection;
                std::string __objPath;
@@ -82,6 +88,36 @@ namespace ctx {
                std::map<std::string, __ClientInfo> __clients;
        };
 
+
+       class SystemServiceRunner : public ServiceRunner {
+       public:
+               SystemServiceRunner(GDBusConnection* conn, IService* service);
+
+               void notifyUserNew(uid_t uid);
+               void notifyUserRemoved(uid_t uid);
+
+       private:
+               bool __prepare(uid_t uid);
+               void __cleanup(uid_t uid);
+
+               ServiceClient* __createClient(const std::string& busName);
+       };
+
+
+       class UserServiceRunner : public ServiceRunner {
+       public:
+               UserServiceRunner(GDBusConnection* conn, IService* service);
+
+               void notifyUserNew(uid_t uid);
+               void notifyUserRemoved(uid_t uid);
+
+       private:
+               bool __prepare(uid_t uid);
+               void __cleanup(uid_t uid);
+
+               ServiceClient* __createClient(const std::string& busName);
+       };
+
 }
 
 #endif /* __CONTEXT_SERVICE_RUNNER_H__ */