From a3d11712f7e8967f588bf1b59ffe7bd56ca713b5 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 29 Jun 2017 11:01:09 +0900 Subject: [PATCH 01/16] ServiceRunner creates ServiceClient before IMethodCallHandler to pass the ServiceClient pointer to IMethodCallHandler Change-Id: Id209c3e9d260964b44125b4508acb6c59a004fd1 Signed-off-by: Mu-Woong Lee --- src/server/ServiceClient.cpp | 9 +++++++-- src/server/ServiceClient.h | 4 +++- src/server/ServiceRunner.cpp | 14 +++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/server/ServiceClient.cpp b/src/server/ServiceClient.cpp index 28ebcf9..757b787 100644 --- a/src/server/ServiceClient.cpp +++ b/src/server/ServiceClient.cpp @@ -20,9 +20,9 @@ using namespace ctx; -ServiceClient::ServiceClient(ServiceRunner* runner, IMethodCallHandler* handler, const std::string& busName) : +ServiceClient::ServiceClient(ServiceRunner* runner, const std::string& busName) : __serviceRunner(runner), - __methodCallHandler(handler), + __methodCallHandler(NULL), __busName(busName), __credential(NULL) { @@ -34,6 +34,11 @@ ServiceClient::~ServiceClient() delete __methodCallHandler; } +void ServiceClient::setHandler(IMethodCallHandler* handler) +{ + __methodCallHandler = handler; +} + const std::string& ServiceClient::getBusName() { return __busName; diff --git a/src/server/ServiceClient.h b/src/server/ServiceClient.h index 820cfcb..f401539 100644 --- a/src/server/ServiceClient.h +++ b/src/server/ServiceClient.h @@ -31,9 +31,11 @@ namespace ctx { class ServiceClient : public IClient { public: - ServiceClient(ServiceRunner* runner, IMethodCallHandler* callHandler, const std::string& busName); + ServiceClient(ServiceRunner* runner, const std::string& busName); ~ServiceClient(); + void setHandler(IMethodCallHandler* handler); + const std::string& getBusName(); const std::string& getId(); diff --git a/src/server/ServiceRunner.cpp b/src/server/ServiceRunner.cpp index 6ded5a3..b35859d 100644 --- a/src/server/ServiceRunner.cpp +++ b/src/server/ServiceRunner.cpp @@ -167,16 +167,20 @@ ServiceClient* ServiceRunner::__getClient(const std::string& busName) if (iter != __clients.end()) return iter->second.client; - IMethodCallHandler* callHandler = __service->createMethodCallHandler(); - IF_FAIL_RETURN(callHandler, NULL); - - ServiceClient* client = new ServiceClient(this, callHandler, busName); + ServiceClient* client = new ServiceClient(this, busName); if (!client->isVerified()) { delete client; return NULL; } - callHandler->setCaller(client); + IMethodCallHandler* callHandler = __service->createMethodCallHandler(client); + if (!callHandler) { + _E("This cannot be NULL."); + delete client; + return NULL; + } + + client->setHandler(callHandler); __ClientInfo info = {client, __watch(busName, client)}; __clients[busName] = info; -- 2.7.4 From cb7d424de32b25e6109d209ead255d73ea6cddae Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 29 Jun 2017 18:20:35 +0900 Subject: [PATCH 02/16] Align with the subdivided IService interfaces Change-Id: I64b3b0857433e53fd6f8dc89ef16a38b197449c6 Signed-off-by: Mu-Woong Lee --- src/server/ActiveUserMonitor.cpp | 85 ++++++++------------ src/server/ActiveUserMonitor.h | 20 +++-- src/server/Credential.cpp | 2 +- src/server/ServerMain.cpp | 17 +--- src/server/ServiceLoader.cpp | 73 ++++++++++++----- src/server/ServiceLoader.h | 33 +++----- src/server/ServiceRunner.cpp | 167 +++++++++++++++++++++++++++------------ src/server/ServiceRunner.h | 60 +++++++++++--- 8 files changed, 279 insertions(+), 178 deletions(-) diff --git a/src/server/ActiveUserMonitor.cpp b/src/server/ActiveUserMonitor.cpp index 999fd1b..4110d68 100644 --- a/src/server/ActiveUserMonitor.cpp +++ b/src/server/ActiveUserMonitor.cpp @@ -16,17 +16,16 @@ #include #include +#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(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(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(userData)->__add(static_cast(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(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(userData)->__remove(static_cast(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(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); } diff --git a/src/server/ActiveUserMonitor.h b/src/server/ActiveUserMonitor.h index d84fc9c..a4ea2c2 100644 --- a/src/server/ActiveUserMonitor.h +++ b/src/server/ActiveUserMonitor.h @@ -17,19 +17,19 @@ #ifndef __CONTEXT_ACTIVE_USER_MONITOR_H__ #define __CONTEXT_ACTIVE_USER_MONITOR_H__ +#include #include 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 __uids; }; } diff --git a/src/server/Credential.cpp b/src/server/Credential.cpp index 5bf2e14..445e569 100644 --- a/src/server/Credential.cpp +++ b/src/server/Credential.cpp @@ -154,5 +154,5 @@ const std::string& Credential::getClientId() const bool Credential::isSystem() const { - return util::isSystemUid(__uid); + return util::isSystem(__uid); } diff --git a/src/server/ServerMain.cpp b/src/server/ServerMain.cpp index a1d002e..3738a00 100644 --- a/src/server/ServerMain.cpp +++ b/src/server/ServerMain.cpp @@ -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; diff --git a/src/server/ServiceLoader.cpp b/src/server/ServiceLoader.cpp index 90f8ef1..70b2a6e 100644 --- a/src/server/ServiceLoader.cpp +++ b/src/server/ServiceLoader.cpp @@ -22,12 +22,9 @@ #include "ServiceLoader.h" -#define ROOT_UID 0 - using namespace ctx; -ServiceLoader::ServiceLoader() : - __activeUser(ROOT_UID) +ServiceLoader::ServiceLoader() { } @@ -41,6 +38,31 @@ ServiceLoader::~ServiceLoader() } } +template +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(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(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(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(__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); + } } diff --git a/src/server/ServiceLoader.h b/src/server/ServiceLoader.h index ef85039..cdf426d 100644 --- a/src/server/ServiceLoader.h +++ b/src/server/ServiceLoader.h @@ -20,6 +20,7 @@ #include #include #include +#include #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 __userServices; - std::vector __systemServices; + void startUser(uid_t uid); + void stopUser(uid_t uid); - template 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 __userServices; + std::vector __systemServices; - if (svc->isUserService()) { - __userServices.push_back(runner); - } else { - __systemServices.push_back(runner); - } - } + template void __create(GDBusConnection* conn); }; } diff --git a/src/server/ServiceRunner.cpp b/src/server/ServiceRunner.cpp index b35859d..f29edbc 100644 --- a/src/server/ServiceRunner.cpp +++ b/src/server/ServiceRunner.cpp @@ -14,7 +14,10 @@ * limitations under the License. */ -#include +#include +#include +#include +#include #include "MethodCall.h" #include "ServiceClient.h" #include "ServiceRunner.h" @@ -22,16 +25,17 @@ 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("" + __service->getMethodSpecs() + ""; + introspection += __interface + "'>" + serviceInstance->getMethodSpecs() + ""; __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(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(serviceInstance)->onUserActivated(uid); +} + +void SystemServiceRunner::notifyUserRemoved(uid_t uid) +{ + if (started) + static_cast(serviceInstance)->onUserDeactivated(uid); +} + +bool SystemServiceRunner::__prepare(uid_t uid) +{ + return static_cast(serviceInstance)->prepare(); +} + +void SystemServiceRunner::__cleanup(uid_t uid) +{ + static_cast(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(serviceInstance)->prepare(uid); +} + +void UserServiceRunner::__cleanup(uid_t uid) +{ + static_cast(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; +} diff --git a/src/server/ServiceRunner.h b/src/server/ServiceRunner.h index b51fcd9..0e7cf3d 100644 --- a/src/server/ServiceRunner.h +++ b/src/server/ServiceRunner.h @@ -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 __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__ */ -- 2.7.4 From 190d55d9f606c178ecc8e84761f6bbd866dd3157 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Fri, 30 Jun 2017 12:02:47 +0900 Subject: [PATCH 03/16] Version 4.0.0 release 1 Change-Id: I2001844afb17d08c19939984b613de9c250b7e77 Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index b124152..f0ab6e3 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -1,6 +1,6 @@ Name: context-service Summary: Tizen Contextual Service Framework -Version: 1.0.2 +Version: 4.0.0 Release: 1 Group: Service/Context License: Apache-2.0 -- 2.7.4 From 3545891bf59e3f6b0fb97f281008662952bd7f14 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 5 Jul 2017 16:43:07 +0900 Subject: [PATCH 04/16] Add IClient::getName() for getting the package id (or the executable path) of a client Change-Id: I2c8143e8c69767123efc08c8d4e1cdcb278227c4 Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 1 + src/server/CMakeLists.txt | 1 + src/server/Credential.cpp | 5 +++++ src/server/Credential.h | 1 + src/server/MethodCall.cpp | 2 +- src/server/ServiceClient.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- src/server/ServiceClient.h | 4 +++- 7 files changed, 51 insertions(+), 5 deletions(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index f0ab6e3..aa23c13 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(alarm-service) BuildRequires: pkgconfig(cynara-creds-gdbus) BuildRequires: pkgconfig(cynara-client) diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 4b474cc..b0c8ba2 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -8,6 +8,7 @@ SET(DEPS gio-2.0 dlog capi-base-common + aul alarm-service cynara-creds-gdbus cynara-client diff --git a/src/server/Credential.cpp b/src/server/Credential.cpp index 445e569..6a29163 100644 --- a/src/server/Credential.cpp +++ b/src/server/Credential.cpp @@ -147,6 +147,11 @@ uid_t Credential::getUid() const return __uid; } +pid_t Credential::getPid() const +{ + return __pid; +} + const std::string& Credential::getClientId() const { return __clientId; diff --git a/src/server/Credential.h b/src/server/Credential.h index 2c00f27..f5f01ad 100644 --- a/src/server/Credential.h +++ b/src/server/Credential.h @@ -33,6 +33,7 @@ namespace ctx { bool hasPrivilege(const char* privil) const; uid_t getUid() const; + pid_t getPid() const; const std::string& getClientId() const; bool isSystem() const; diff --git a/src/server/MethodCall.cpp b/src/server/MethodCall.cpp index 6d50861..81f75df 100644 --- a/src/server/MethodCall.cpp +++ b/src/server/MethodCall.cpp @@ -90,7 +90,7 @@ uid_t MethodCall::getUid() const std::string& MethodCall::getCallerId() { - return getCaller().getId(); + return getCaller().getName(); } bool MethodCall::isSystem() diff --git a/src/server/ServiceClient.cpp b/src/server/ServiceClient.cpp index 757b787..fe8ced2 100644 --- a/src/server/ServiceClient.cpp +++ b/src/server/ServiceClient.cpp @@ -14,10 +14,14 @@ * limitations under the License. */ +#include +#include #include "Credential.h" #include "ServiceRunner.h" #include "ServiceClient.h" +#define BUFFER_SIZE 256 + using namespace ctx; ServiceClient::ServiceClient(ServiceRunner* runner, const std::string& busName) : @@ -39,16 +43,48 @@ void ServiceClient::setHandler(IMethodCallHandler* handler) __methodCallHandler = handler; } -const std::string& ServiceClient::getBusName() +const std::string& ServiceClient::getName() { - return __busName; + if (!__name.empty()) + return __name; + + char buffer[BUFFER_SIZE]; + + // Package ID + int err = aul_app_get_pkgid_bypid_for_uid(__credential->getPid(), buffer, BUFFER_SIZE, __credential->getUid()); + if (IS_SUCCESS(err)) { + __name = buffer; + _I("PkgId: %s", __name.c_str()); + return __name; + } + + // Executable Path + char path[32]; + g_snprintf(path, 32, "/proc/%d/cmdline", __credential->getPid()); + + std::ifstream cmdfile(path); + std::string cmdline; + + if (std::getline(cmdfile, cmdline)) { + __name = cmdline; + _I("cmd: %s", __name.c_str()); + return __name; + } + + _E("Failed to get the client's name"); + return __name; } -const std::string& ServiceClient::getId() +const std::string& ServiceClient::getSecurityLabel() { return __credential->getClientId(); } +const std::string& ServiceClient::getBusName() +{ + return __busName; +} + uid_t ServiceClient::getUid() { return __credential->getUid(); diff --git a/src/server/ServiceClient.h b/src/server/ServiceClient.h index f401539..3de5c58 100644 --- a/src/server/ServiceClient.h +++ b/src/server/ServiceClient.h @@ -36,8 +36,9 @@ namespace ctx { void setHandler(IMethodCallHandler* handler); + const std::string& getName(); + const std::string& getSecurityLabel(); const std::string& getBusName(); - const std::string& getId(); uid_t getUid(); bool isSystem(); @@ -60,6 +61,7 @@ namespace ctx { ServiceRunner* __serviceRunner; IMethodCallHandler* __methodCallHandler; + std::string __name; std::string __busName; Credential* __credential; }; -- 2.7.4 From d0fa3a30443bb0fd6ec595836c67a1e8b149ad47 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 10 Jul 2017 20:12:42 +0900 Subject: [PATCH 05/16] Remove trailing bytes from the cmd string read from /proc/PID/cmdline Change-Id: Ic9ddbec882746395311309c5574104bb2b51d8a6 Signed-off-by: Mu-Woong Lee --- src/server/ServiceClient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/ServiceClient.cpp b/src/server/ServiceClient.cpp index fe8ced2..3cc8e8a 100644 --- a/src/server/ServiceClient.cpp +++ b/src/server/ServiceClient.cpp @@ -66,7 +66,8 @@ const std::string& ServiceClient::getName() std::string cmdline; if (std::getline(cmdfile, cmdline)) { - __name = cmdline; + g_snprintf(buffer, BUFFER_SIZE, "%s", cmdline.c_str()); + __name = buffer; _I("cmd: %s", __name.c_str()); return __name; } -- 2.7.4 From 720fd0e4c0c7a819a856c0adea3b8de4dc4d1d6f Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 10 Jul 2017 21:05:57 +0900 Subject: [PATCH 06/16] Version 4.0.0r2 Change-Id: Ibb4483d620149121a5c67f31932a1fac193dd63c Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index aa23c13..ddf4cef 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -1,7 +1,7 @@ Name: context-service Summary: Tizen Contextual Service Framework Version: 4.0.0 -Release: 1 +Release: 2 Group: Service/Context License: Apache-2.0 Source0: %{name}-%{version}.tar.gz -- 2.7.4 From f8caac8154f01ff1093c139d4063fec6bb9163f4 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 12 Jul 2017 19:21:47 +0900 Subject: [PATCH 07/16] Cleanup non-class function names Change-Id: Iadfd05a82e1e90a986d082672c42ab540f99a233 Signed-off-by: Mu-Woong Lee --- src/server/Credential.cpp | 2 +- src/server/ServerMain.cpp | 36 ++++++++++++++++++------------------ src/server/ServiceLoader.cpp | 4 ++-- src/server/ServiceRunner.cpp | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/server/Credential.cpp b/src/server/Credential.cpp index 6a29163..7ace5c3 100644 --- a/src/server/Credential.cpp +++ b/src/server/Credential.cpp @@ -159,5 +159,5 @@ const std::string& Credential::getClientId() const bool Credential::isSystem() const { - return util::isSystem(__uid); + return util::is_system(__uid); } diff --git a/src/server/ServerMain.cpp b/src/server/ServerMain.cpp index 3738a00..8bee8e4 100644 --- a/src/server/ServerMain.cpp +++ b/src/server/ServerMain.cpp @@ -67,7 +67,7 @@ static ServiceLoader __serviceLoader; static ActiveUserMonitor __activeUserMonitor(&__serviceLoader); static AlarmInitializer __alarmInit; -static void __startService(GDBusConnection* conn) +static void __start_service(GDBusConnection* conn) { __activeUserMonitor.start(conn); @@ -81,7 +81,7 @@ static void __startService(GDBusConnection* conn) __serviceLoader.startSystem(); } -static gboolean __stopService(gpointer data) +static gboolean __stop_service(gpointer data) { __activeUserMonitor.stop(); @@ -92,27 +92,27 @@ static gboolean __stopService(gpointer data) return G_SOURCE_REMOVE; } -static void __busAcquired(GDBusConnection* conn) +static void __bus_acquired(GDBusConnection* conn) { - __startService(conn); + __start_service(conn); } -static void __busLost(GDBusConnection* conn) +static void __bus_lost(GDBusConnection* conn) { - __stopService(NULL); + __stop_service(NULL); } -static void __onSignal(int signum) +static void __on_signal(int signum) { _I(YELLOW("SIGNAL-%d: '%s'"), signum, strsignal(signum)); static bool terminated = false; if (!terminated) { - g_idle_add(__stopService, NULL); + g_idle_add(__stop_service, NULL); terminated = true; } } -static void __onTerminate() +static void __on_terminate() { try { auto unknown = std::current_exception(); @@ -126,7 +126,7 @@ static void __onTerminate() } } -static void __onNewFailed() +static void __on_new_failed() { static unsigned failCount = 0; _E_ALLOC; @@ -137,16 +137,16 @@ static void __onNewFailed() int main(int argc, char* argv[]) { - std::signal(SIGINT, __onSignal); - std::signal(SIGHUP, __onSignal); - std::signal(SIGTERM, __onSignal); - std::signal(SIGQUIT, __onSignal); - std::signal(SIGABRT, __onSignal); + std::signal(SIGINT, __on_signal); + std::signal(SIGHUP, __on_signal); + std::signal(SIGTERM, __on_signal); + std::signal(SIGQUIT, __on_signal); + std::signal(SIGABRT, __on_signal); - std::set_terminate(__onTerminate); - std::set_new_handler(__onNewFailed); + std::set_terminate(__on_terminate); + std::set_new_handler(__on_new_failed); - DBusConnector dbusConnector(__busAcquired, __busLost); + DBusConnector dbusConnector(__bus_acquired, __bus_lost); MainLoop::start(); diff --git a/src/server/ServiceLoader.cpp b/src/server/ServiceLoader.cpp index 70b2a6e..e20fdcf 100644 --- a/src/server/ServiceLoader.cpp +++ b/src/server/ServiceLoader.cpp @@ -89,7 +89,7 @@ void ServiceLoader::stopSystem() void ServiceLoader::startUser(uid_t uid) { - if (util::isNormalUser(uid)) { + if (util::is_normal_user(uid)) { for (auto& runner : __userServices) { runner->stop(); runner->start(uid); @@ -99,7 +99,7 @@ void ServiceLoader::startUser(uid_t uid) void ServiceLoader::stopUser(uid_t uid) { - if (util::isNormalUser(uid)) { + if (util::is_normal_user(uid)) { for (auto& runner : __userServices) { runner->stop(); } diff --git a/src/server/ServiceRunner.cpp b/src/server/ServiceRunner.cpp index f29edbc..eb0b058 100644 --- a/src/server/ServiceRunner.cpp +++ b/src/server/ServiceRunner.cpp @@ -283,7 +283,7 @@ ServiceClient* UserServiceRunner::__createClient(const std::string& busName) return NULL; } - if (!util::isNormalUser(client->getUid())) { + if (!util::is_normal_user(client->getUid())) { _W("%s does not support container users.", serviceInstance->getServiceName()); delete client; return NULL; -- 2.7.4 From 6a6ce75e6ec0a5ece3fa5fcdf5d5195064405925 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 12 Jul 2017 21:18:52 +0900 Subject: [PATCH 08/16] Version 4.0.1 Change-Id: I49ec59cc8cdcedd196a9c90ebccb0cbf2059413d Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index ddf4cef..ff1c58f 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -1,7 +1,7 @@ Name: context-service Summary: Tizen Contextual Service Framework -Version: 4.0.0 -Release: 2 +Version: 4.0.1 +Release: 1 Group: Service/Context License: Apache-2.0 Source0: %{name}-%{version}.tar.gz -- 2.7.4 From 8651f15591a87f0fd1113cf893b98ac2e9dbde87 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Sun, 30 Jul 2017 17:08:46 +0900 Subject: [PATCH 09/16] Store the dbus connection while launching the service Change-Id: I64dd3781ddf584f441c08bb4406c9eeaf3ac377e Signed-off-by: Mu-Woong Lee --- src/server/ServerMain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/ServerMain.cpp b/src/server/ServerMain.cpp index 8bee8e4..312574d 100644 --- a/src/server/ServerMain.cpp +++ b/src/server/ServerMain.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "DBusConnector.h" #include "ServiceLoader.h" #include "ActiveUserMonitor.h" @@ -94,6 +95,7 @@ static gboolean __stop_service(gpointer data) static void __bus_acquired(GDBusConnection* conn) { + util::set_dbus_connection(conn); __start_service(conn); } -- 2.7.4 From c4c94228572e73d0b85625980db68f8b1103b6e8 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Sat, 29 Jul 2017 15:33:08 +0900 Subject: [PATCH 10/16] Remove the legacy agent service implementation Change-Id: I130ace0752ee8b275a40812e13be70cc075ee645 Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 20 +- packaging/contextd-agent.service | 5 +- packaging/org.tizen.contextagent.conf | 23 - packaging/org.tizen.contextagent.service | 7 - src/agent/AgentMain.cpp | 3 +- src/agent/CMakeLists.txt | 17 +- src/agent/legacy/ClientRequest.cpp | 116 ----- src/agent/legacy/ClientRequest.h | 47 -- src/agent/legacy/ContextManager.cpp | 237 --------- src/agent/legacy/ContextManager.h | 63 --- src/agent/legacy/DBusServer.cpp | 228 --------- src/agent/legacy/DBusServer.h | 64 --- src/agent/legacy/ProviderHandler.cpp | 311 ------------ src/agent/legacy/ProviderHandler.h | 78 --- src/agent/legacy/ProviderLoader.cpp | 120 ----- src/agent/legacy/ProviderLoader.h | 63 --- src/agent/legacy/Request.cpp | 66 --- src/agent/legacy/Request.h | 56 --- src/agent/legacy/Server.cpp | 170 ------- src/agent/legacy/Server.h | 37 -- src/agent/legacy/access_control/PeerCreds.cpp | 77 --- src/agent/legacy/access_control/PeerCreds.h | 43 -- src/agent/legacy/access_control/Privilege.cpp | 87 ---- src/agent/legacy/access_control/Privilege.h | 32 -- src/agent/legacy/policy/PolicyManager.cpp | 69 --- src/agent/legacy/policy/PolicyManager.h | 43 -- src/agent/legacy/policy/PolicyRequest.cpp | 53 -- src/agent/legacy/policy/PolicyRequest.h | 39 -- src/agent/legacy/trigger/ActionManager.cpp | 210 -------- src/agent/legacy/trigger/ActionManager.h | 35 -- src/agent/legacy/trigger/ContextMonitor.cpp | 318 ------------ src/agent/legacy/trigger/ContextMonitor.h | 92 ---- src/agent/legacy/trigger/FactRequest.cpp | 68 --- src/agent/legacy/trigger/FactRequest.h | 46 -- src/agent/legacy/trigger/FactTypes.h | 26 - src/agent/legacy/trigger/IContextListener.h | 38 -- src/agent/legacy/trigger/Rule.cpp | 209 -------- src/agent/legacy/trigger/Rule.h | 80 --- src/agent/legacy/trigger/RuleEvaluator.cpp | 385 -------------- src/agent/legacy/trigger/RuleEvaluator.h | 53 -- src/agent/legacy/trigger/RuleManager.cpp | 697 -------------------------- src/agent/legacy/trigger/RuleManager.h | 71 --- src/agent/legacy/trigger/TemplateManager.cpp | 196 -------- src/agent/legacy/trigger/TemplateManager.h | 62 --- src/agent/legacy/trigger/Trigger.cpp | 279 ----------- src/agent/legacy/trigger/Trigger.h | 59 --- 46 files changed, 4 insertions(+), 5094 deletions(-) delete mode 100644 packaging/org.tizen.contextagent.conf delete mode 100644 packaging/org.tizen.contextagent.service delete mode 100644 src/agent/legacy/ClientRequest.cpp delete mode 100644 src/agent/legacy/ClientRequest.h delete mode 100644 src/agent/legacy/ContextManager.cpp delete mode 100644 src/agent/legacy/ContextManager.h delete mode 100644 src/agent/legacy/DBusServer.cpp delete mode 100644 src/agent/legacy/DBusServer.h delete mode 100644 src/agent/legacy/ProviderHandler.cpp delete mode 100644 src/agent/legacy/ProviderHandler.h delete mode 100644 src/agent/legacy/ProviderLoader.cpp delete mode 100644 src/agent/legacy/ProviderLoader.h delete mode 100644 src/agent/legacy/Request.cpp delete mode 100644 src/agent/legacy/Request.h delete mode 100644 src/agent/legacy/Server.cpp delete mode 100644 src/agent/legacy/Server.h delete mode 100644 src/agent/legacy/access_control/PeerCreds.cpp delete mode 100644 src/agent/legacy/access_control/PeerCreds.h delete mode 100644 src/agent/legacy/access_control/Privilege.cpp delete mode 100644 src/agent/legacy/access_control/Privilege.h delete mode 100644 src/agent/legacy/policy/PolicyManager.cpp delete mode 100644 src/agent/legacy/policy/PolicyManager.h delete mode 100644 src/agent/legacy/policy/PolicyRequest.cpp delete mode 100644 src/agent/legacy/policy/PolicyRequest.h delete mode 100644 src/agent/legacy/trigger/ActionManager.cpp delete mode 100644 src/agent/legacy/trigger/ActionManager.h delete mode 100644 src/agent/legacy/trigger/ContextMonitor.cpp delete mode 100644 src/agent/legacy/trigger/ContextMonitor.h delete mode 100644 src/agent/legacy/trigger/FactRequest.cpp delete mode 100644 src/agent/legacy/trigger/FactRequest.h delete mode 100644 src/agent/legacy/trigger/FactTypes.h delete mode 100644 src/agent/legacy/trigger/IContextListener.h delete mode 100644 src/agent/legacy/trigger/Rule.cpp delete mode 100644 src/agent/legacy/trigger/Rule.h delete mode 100644 src/agent/legacy/trigger/RuleEvaluator.cpp delete mode 100644 src/agent/legacy/trigger/RuleEvaluator.h delete mode 100644 src/agent/legacy/trigger/RuleManager.cpp delete mode 100644 src/agent/legacy/trigger/RuleManager.h delete mode 100644 src/agent/legacy/trigger/TemplateManager.cpp delete mode 100644 src/agent/legacy/trigger/TemplateManager.h delete mode 100644 src/agent/legacy/trigger/Trigger.cpp delete mode 100644 src/agent/legacy/trigger/Trigger.h diff --git a/packaging/context-service.spec b/packaging/context-service.spec index ff1c58f..130e273 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -8,13 +8,12 @@ Source0: %{name}-%{version}.tar.gz Source1: contextd.service Source2: org.tizen.context.conf Source3: contextd-agent.service -Source4: org.tizen.contextagent.conf -Source5: org.tizen.contextagent.service BuildRequires: cmake BuildRequires: pkgconfig(libsystemd-login) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(gmodule-2.0) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(aul) @@ -29,15 +28,6 @@ BuildRequires: pkgconfig(context-sensor-recorder-server) BuildRequires: pkgconfig(context-store-server) BuildRequires: pkgconfig(context-job-scheduler-server) -# Legacy support. These dependencies will be removed. -BuildRequires: pkgconfig(gmodule-2.0) -BuildRequires: pkgconfig(vconf) -BuildRequires: pkgconfig(capi-system-device) -BuildRequires: pkgconfig(capi-appfw-app-manager) -BuildRequires: pkgconfig(capi-appfw-package-manager) -BuildRequires: pkgconfig(notification) -BuildRequires: pkgconfig(context-common-legacy) -# --- %description This is a systemd service that contains all features provided by the Tizen Contextual Service Framework. @@ -75,12 +65,6 @@ install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/dbus-1/system.d/ mkdir -p %{buildroot}%{_unitdir_user} install -m 0644 %{SOURCE3} %{buildroot}%{_unitdir_user} -mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/session.d -install -m 0644 %{SOURCE4} %{buildroot}%{_sysconfdir}/dbus-1/session.d/ - -mkdir -p %{buildroot}/usr/share/dbus-1/services -install -m 0644 %{SOURCE5} %{buildroot}/usr/share/dbus-1/services/ - %files %manifest packaging/%{name}.manifest %config %{_sysconfdir}/dbus-1/system.d/* @@ -91,8 +75,6 @@ install -m 0644 %{SOURCE5} %{buildroot}/usr/share/dbus-1/services/ %files -n context-agent %manifest packaging/%{name}.manifest -%config %{_sysconfdir}/dbus-1/session.d/* %{_bindir}/contextd-agent %{_unitdir_user}/contextd-agent.service -/usr/share/dbus-1/services/* %license LICENSE diff --git a/packaging/contextd-agent.service b/packaging/contextd-agent.service index e6e36b3..8eb83c4 100644 --- a/packaging/contextd-agent.service +++ b/packaging/contextd-agent.service @@ -2,8 +2,5 @@ Description=Contextual Service Framework User-Level Agent Daemon [Service] -Type=dbus -BusName=org.tizen.contextagent +Type=simple ExecStart=/usr/bin/contextd-agent -Restart=on-failure -RestartSec=1 diff --git a/packaging/org.tizen.contextagent.conf b/packaging/org.tizen.contextagent.conf deleted file mode 100644 index dfb4f9f..0000000 --- a/packaging/org.tizen.contextagent.conf +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - diff --git a/packaging/org.tizen.contextagent.service b/packaging/org.tizen.contextagent.service deleted file mode 100644 index 198b7d1..0000000 --- a/packaging/org.tizen.contextagent.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Contextual Service Framework User-Level Agent D-Bus - -[D-BUS Service] -Name=org.tizen.contextagent -Exec=/bin/false -SystemdService=contextd-agent.service diff --git a/src/agent/AgentMain.cpp b/src/agent/AgentMain.cpp index b1bfe89..fc1dc8d 100644 --- a/src/agent/AgentMain.cpp +++ b/src/agent/AgentMain.cpp @@ -15,9 +15,8 @@ */ #include -#include "legacy/Server.h" int main(int argc, char* argv[]) { - return mainLegacy(); + return EXIT_SUCCESS; } diff --git a/src/agent/CMakeLists.txt b/src/agent/CMakeLists.txt index c476073..69d426e 100644 --- a/src/agent/CMakeLists.txt +++ b/src/agent/CMakeLists.txt @@ -2,22 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET(target "contextd-agent") -SET(DEPS glib-2.0 gio-2.0 dlog capi-base-common) - -# Legacy support -SET(DEPS ${DEPS} - gmodule-2.0 - vconf - cynara-creds-gdbus - cynara-client - cynara-session - capi-system-device - capi-appfw-app-manager - capi-appfw-package-manager - notification - context-common-legacy -) -# --- +SET(DEPS glib-2.0 gio-2.0 gmodule-2.0 dlog capi-base-common) FILE(GLOB_RECURSE SRCS *.cpp) MESSAGE("Sources: ${SRCS}") diff --git a/src/agent/legacy/ClientRequest.cpp b/src/agent/legacy/ClientRequest.cpp deleted file mode 100644 index 0ae8573..0000000 --- a/src/agent/legacy/ClientRequest.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include "DBusServer.h" -#include "access_control/PeerCreds.h" -#include "ClientRequest.h" - -ctx::ClientRequest::ClientRequest(int type, int reqId, const char *subj, const char *desc, - ctx::Credentials *creds, const char *sender, GDBusMethodInvocation *inv) : - RequestInfo(type, reqId, subj, desc), - __credentials(creds), - __dbusSender(sender), - __invocation(inv) -{ -} - -ctx::ClientRequest::~ClientRequest() -{ - if (__invocation) - g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); - - delete __credentials; -} - -const ctx::Credentials* ctx::ClientRequest::getCredentials() -{ - return __credentials; -} - -const char* ctx::ClientRequest::getPackageId() -{ - if (__credentials) - return __credentials->packageId; - - return NULL; -} - -const char* ctx::ClientRequest::getClient() -{ - if (__credentials) - return __credentials->client; - - return NULL; -} - -bool ctx::ClientRequest::reply(int error) -{ - IF_FAIL_RETURN(__invocation, true); - - _I("Reply %#x", error); - - g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); - __invocation = NULL; - return true; -} - -bool ctx::ClientRequest::reply(int error, ctx::CtxJson1& requestResult) -{ - IF_FAIL_RETURN(__invocation, true); - IF_FAIL_RETURN(error != ERR_NONE || __type != REQ_READ_SYNC, true); - - std::string result = requestResult.str(); - IF_FAIL_RETURN(!result.empty(), false); - - _I("Reply %#x", error); - _SD("Result: %s", result.c_str()); - - g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), EMPTY_JSON_OBJECT)); - __invocation = NULL; - - return true; -} - -bool ctx::ClientRequest::reply(int error, ctx::CtxJson1& requestResult, ctx::CtxJson1& dataRead) -{ - if (__invocation == NULL) { - return publish(error, dataRead); - } - - std::string result = requestResult.str(); - std::string data = dataRead.str(); - IF_FAIL_RETURN(!result.empty() && !data.empty(), false); - - _I("Reply %#x", error); - _SD("Result: %s", result.c_str()); - _SD("Data: %s", data.c_str()); - - g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), data.c_str())); - __invocation = NULL; - - return true; -} - -bool ctx::ClientRequest::publish(int error, ctx::CtxJson1& data) -{ - DBusServer::publish(__dbusSender, __reqId, __subject, error, data.str()); - return true; -} diff --git a/src/agent/legacy/ClientRequest.h b/src/agent/legacy/ClientRequest.h deleted file mode 100644 index e6e653b..0000000 --- a/src/agent/legacy/ClientRequest.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_CLIENT_REQUEST_H_ -#define _CONTEXT_CLIENT_REQUEST_H_ - -#include -#include "Request.h" - -namespace ctx { - - class ClientRequest : public RequestInfo { - public: - ClientRequest(int type, int reqId, const char *subj, const char *desc, - Credentials *creds, const char *sender, GDBusMethodInvocation *inv); - ~ClientRequest(); - - const Credentials* getCredentials(); - const char* getPackageId(); - const char* getClient(); - bool reply(int error); - bool reply(int error, ctx::CtxJson1 &requestResult); - bool reply(int error, ctx::CtxJson1 &requestResult, ctx::CtxJson1 &dataRead); - bool publish(int error, ctx::CtxJson1 &data); - - private: - Credentials *__credentials; - std::string __dbusSender; - GDBusMethodInvocation *__invocation; - }; - -} /* namespace ctx */ - -#endif /* End of _CONTEXT_CLIENT_REQUEST_H_ */ diff --git a/src/agent/legacy/ContextManager.cpp b/src/agent/legacy/ContextManager.cpp deleted file mode 100644 index 9f52415..0000000 --- a/src/agent/legacy/ContextManager.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "access_control/Privilege.h" -#include "trigger/TemplateManager.h" -#include "Server.h" -#include "Request.h" -#include "ProviderHandler.h" -#include "ProviderLoader.h" -#include "ContextManager.h" - -using namespace ctx::trigger; -using namespace ctx; - -ContextManager::ContextManager() -{ - ContextProvider::__setContextManager(this); - CustomRegister::__setCustomRegister(this); - ProviderLoader::init(); -} - -ContextManager::~ContextManager() -{ - release(); -} - -bool ContextManager::init() -{ - return true; -} - -void ContextManager::release() -{ - ProviderHandler::purge(); -} - -void ContextManager::assignRequest(RequestInfo* request) -{ - std::string subject = request->getSubject(); - if (subject.empty()) { - _W("Empty subject name"); - request->reply(ERR_NOT_SUPPORTED); - delete request; - return; - } - - ProviderHandler *handle = ProviderHandler::getInstance(subject, true); - if (!handle || !handle->isSupported()) { - request->reply(ERR_NOT_SUPPORTED); - delete request; - return; - } - - if (request->getType() != REQ_SUPPORT && !handle->isAllowed(request->getCredentials())) { - _W("Permission denied"); - request->reply(ERR_PERMISSION_DENIED); - delete request; - return; - } - - switch (request->getType()) { - case REQ_SUBSCRIBE: - handle->subscribe(request); - break; - case REQ_UNSUBSCRIBE: - handle->unsubscribe(request); - break; - case REQ_READ: - case REQ_READ_SYNC: - handle->read(request); - break; - case REQ_WRITE: - handle->write(request); - break; - case REQ_SUPPORT: - request->reply(ERR_NONE); - delete request; - break; - default: - _E("Invalid type of request"); - delete request; - } -} - -bool ContextManager::isSupported(const char *subject) -{ - ProviderHandler *handle = ProviderHandler::getInstance(subject, true); - - if (!handle) - return false; - - return handle->isSupported(); -} - -bool ContextManager::isAllowed(const Credentials *creds, const char *subject) -{ - IF_FAIL_RETURN(creds, true); /* In case internal requests */ - - ProviderHandler *handle = ProviderHandler::getInstance(subject, true); - - if (!handle) - return false; - - return handle->isAllowed(creds); -} - -void ContextManager::__publish(const char* subject, CtxJson1 &option, int error, CtxJson1 &dataUpdated) -{ - _I("Publishing '%s'", subject); - _J("Option", option); - - ProviderHandler *handle = ProviderHandler::getInstance(subject, false); - IF_FAIL_VOID_TAG(handle, _W, "No corresponding provider"); - - handle->publish(option, error, dataUpdated); -} - -void ContextManager::__replyToRead(const char* subject, CtxJson1 &option, int error, CtxJson1 &dataRead) -{ - _I("Sending data of '%s'", subject); - _J("Option", option); - _J("Data", dataRead); - - ProviderHandler *handle = ProviderHandler::getInstance(subject, false); - IF_FAIL_VOID_TAG(handle, _W, "No corresponding provider"); - - handle->replyToRead(option, error, dataRead); -} - -struct PublishedData { - int type; - ContextManager *mgr; - std::string subject; - int error; - CtxJson1 option; - CtxJson1 data; - PublishedData(int t, ContextManager *m, const char* s, CtxJson1& o, int e, CtxJson1& d) - : type(t), mgr(m), subject(s), error(e) - { - option = o.str(); - data = d.str(); - } -}; - -gboolean ContextManager::__threadSwitcher(gpointer data) -{ - PublishedData *tuple = static_cast(data); - - switch (tuple->type) { - case REQ_SUBSCRIBE: - tuple->mgr->__publish(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data); - break; - case REQ_READ: - tuple->mgr->__replyToRead(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data); - break; - default: - _W("Invalid type"); - } - - delete tuple; - return FALSE; -} - -bool ContextManager::publish(const char* subject, CtxJson1& option, int error, CtxJson1& dataUpdated) -{ - IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter"); - - PublishedData *tuple = new(std::nothrow) PublishedData(REQ_SUBSCRIBE, this, subject, option, error, dataUpdated); - IF_FAIL_RETURN_TAG(tuple, false, _E, "Memory allocation failed"); - - g_idle_add(__threadSwitcher, tuple); - - return true; -} - -bool ContextManager::replyToRead(const char* subject, CtxJson1& option, int error, CtxJson1& dataRead) -{ - IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter"); - - PublishedData *tuple = new(std::nothrow) PublishedData(REQ_READ, this, subject, option, error, dataRead); - IF_FAIL_RETURN_TAG(tuple, false, _E, "Memory allocation failed"); - - g_idle_add(__threadSwitcher, tuple); - - return true; -} - -bool ContextManager::popTriggerTemplate(std::string &subject, int &operation, CtxJson1 &attribute, CtxJson1 &option) -{ - return ProviderLoader::popTriggerTemplate(subject, operation, attribute, option); -} - -/* Only for explicit request of custom provider */ -bool ContextManager::registerCustomProvider(const char* subject, int operation, ctx::CtxJson1 &attribute, ctx::CtxJson1 &option, const char* owner) -{ - IF_FAIL_RETURN_TAG(ProviderHandler::getInstance(subject, true), false, _E, "Register provider failed"); - - TemplateManager* tmplMgr = TemplateManager::getInstance(); - IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed"); - tmplMgr->registerTemplate(subject, operation, attribute, option, owner); - - return true; -} - -bool ContextManager::unregisterCustomProvider(const char* subject) -{ - TemplateManager* tmplMgr = TemplateManager::getInstance(); - IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed"); - tmplMgr->unregisterTemplate(subject); - - int error = ProviderHandler::unregisterCustomProvider(subject); - IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Unregister provider failed"); - - return true; -} diff --git a/src/agent/legacy/ContextManager.h b/src/agent/legacy/ContextManager.h deleted file mode 100644 index ab98910..0000000 --- a/src/agent/legacy/ContextManager.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_CONTEXT_MANAGER_H_ -#define _CONTEXT_CONTEXT_MANAGER_H_ - -#include -#include -#include - -namespace ctx { - - /* Forward declaration */ - class Credentials; - class RequestInfo; - - class ContextManager : public IContextManager, ICustomRegister { - public: - ~ContextManager(); - - bool init(); - void release(); - - void assignRequest(ctx::RequestInfo *request); - bool isSupported(const char *subject); - bool isAllowed(const Credentials *creds, const char *subject); - - /* From the interface class */ - bool publish(const char *subject, ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataUpdated); - bool replyToRead(const char *subject, ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataRead); - bool registerCustomProvider(const char* subject, int operation, ctx::CtxJson1 &attribute, ctx::CtxJson1 &option, const char* owner); - bool unregisterCustomProvider(const char* subject); - - bool popTriggerTemplate(std::string &subject, int &operation, CtxJson1 &attribute, CtxJson1 &option); - - private: - ContextManager(); - - static gboolean __threadSwitcher(gpointer data); - - void __publish(const char *subject, ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataUpdated); - void __replyToRead(const char *subject, ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataRead); - - friend class Server; - - }; /* class ContextManager */ - -} /* namespace ctx */ - -#endif /* _CONTEXT_CONTEXT_MANAGER_H_ */ diff --git a/src/agent/legacy/DBusServer.cpp b/src/agent/legacy/DBusServer.cpp deleted file mode 100644 index ff43612..0000000 --- a/src/agent/legacy/DBusServer.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include - -#include -#include -#include "Server.h" -#include "ClientRequest.h" -#include "access_control/PeerCreds.h" -#include "DBusServer.h" - -using namespace ctx; - -static const gchar __introspection_xml[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - -DBusServer *DBusServer::__theInstance = NULL; - -DBusServer::DBusServer() : - __owner(-1), - __connection(NULL), - __nodeInfo(NULL) -{ -} - -DBusServer::~DBusServer() -{ - __release(); -} - -void DBusServer::__processRequest(const char *sender, GVariant *param, GDBusMethodInvocation *invocation) -{ - gint reqType = 0; - const gchar *cookie = NULL; - gint reqId = 0; - const gchar *subject = NULL; - const gchar *input = NULL; - - g_variant_get(param, "(i&si&s&s)", &reqType, &cookie, &reqId, &subject, &input); - IF_FAIL_VOID_TAG(reqType > 0 && reqId > 0 && cookie && subject && input, _E, "Invalid request"); - - _I("[%d] ReqId: %d, Subject: %s", reqType, reqId, subject); - _SI("Input: %s", input); - - Credentials *creds = NULL; - - if (!peer_creds::get(__connection, sender, cookie, &creds)) { - _E("Peer credentialing failed"); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); - return; - } - - ClientRequest *request = new(std::nothrow) ClientRequest(reqType, reqId, subject, input, creds, sender, invocation); - if (!request) { - _E("Memory allocation failed"); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); - delete creds; - return; - } - - Server::sendRequest(request); -} - -void DBusServer::__reply(GDBusMethodInvocation *invocation, int error) -{ - g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", error)); -} - -void DBusServer::__onMethodCalled(GDBusConnection *conn, const gchar *sender, - const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer userData) -{ - IF_FAIL_VOID_TAG(STR_EQ(path, DBUS_PATH), _W, "Invalid path: %s", path); - IF_FAIL_VOID_TAG(STR_EQ(iface, DBUS_IFACE), _W, "Invalid interface: %s", path); - - if (STR_EQ(name, METHOD_REQUEST)) { - __theInstance->__processRequest(sender, param, invocation); - } else { - __theInstance->__reply(invocation, ERR_NONE); - } -} - -void DBusServer::__onBusAcquired(GDBusConnection *conn, const gchar *name, gpointer userData) -{ - GDBusInterfaceVTable vtable; - vtable.method_call = __onMethodCalled; - vtable.get_property = NULL; - vtable.set_property = NULL; - - guint regId = g_dbus_connection_register_object(conn, DBUS_PATH, - __theInstance->__nodeInfo->interfaces[0], &vtable, NULL, NULL, NULL); - - if (regId <= 0) { - _E("Failed to acquire dbus"); - raise(SIGTERM); - } - - __theInstance->__connection = conn; - _I("Dbus connection acquired"); -} - -void DBusServer::__onNameAcquired(GDBusConnection *conn, const gchar *name, gpointer userData) -{ - _SI("Dbus name acquired: %s", name); - Server::activate(); -} - -void DBusServer::__onNameLost(GDBusConnection *conn, const gchar *name, gpointer userData) -{ - _E("Dbus name lost"); - raise(SIGTERM); -} - -void DBusServer::__onCallDone(GObject *source, GAsyncResult *res, gpointer userData) -{ - _I("Call %u done", *static_cast(userData)); - - GDBusConnection *conn = G_DBUS_CONNECTION(source); - GError *error = NULL; - g_dbus_connection_call_finish(conn, res, &error); - HANDLE_GERROR(error); -} - -bool DBusServer::__init() -{ - __nodeInfo = g_dbus_node_info_new_for_xml(__introspection_xml, NULL); - IF_FAIL_RETURN_TAG(__nodeInfo != NULL, false, _E, "Initialization failed"); - - __owner = g_bus_own_name(G_BUS_TYPE_SESSION, DBUS_DEST, G_BUS_NAME_OWNER_FLAGS_NONE, - __onBusAcquired, __onNameAcquired, __onNameLost, NULL, NULL); - - __theInstance = this; - return true; -} - -void DBusServer::__release() -{ - if (__connection) { - g_dbus_connection_flush_sync(__connection, NULL, NULL); - } - - if (__owner > 0) { - g_bus_unown_name(__owner); - __owner = 0; - } - - if (__connection) { - g_dbus_connection_close_sync(__connection, NULL, NULL); - g_object_unref(__connection); - __connection = NULL; - } - - if (__nodeInfo) { - g_dbus_node_info_unref(__nodeInfo); - __nodeInfo = NULL; - } -} - -void DBusServer::__publish(const char *dest, int reqId, const char *subject, int error, const char *data) -{ - _SI("Publish: %s, %d, %s, %#x, %s", dest, reqId, subject, error, data); - - GVariant *param = g_variant_new("(isis)", reqId, subject, error, data); - IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed"); - - g_dbus_connection_call(__connection, dest, DBUS_PATH, DBUS_IFACE, - METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, NULL); -} - -void DBusServer::__call(const char *dest, const char *obj, const char *iface, const char *method, GVariant *param) -{ - static unsigned int callCount = 0; - ++callCount; - - _SI("Call %u: %s, %s, %s.%s", callCount, dest, obj, iface, method); - - g_dbus_connection_call(__connection, dest, obj, iface, method, param, NULL, - G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, __onCallDone, &callCount); -} - -void DBusServer::publish(std::string dest, int reqId, std::string subject, int error, std::string data) -{ - IF_FAIL_VOID_TAG(__theInstance, _E, "Not initialized"); - __theInstance->__publish(dest.c_str(), reqId, subject.c_str(), error, data.c_str()); -} - -void DBusServer::call(std::string dest, std::string obj, std::string iface, std::string method, GVariant *param) -{ - IF_FAIL_VOID_TAG(__theInstance, _E, "Not initialized"); - __theInstance->__call(dest.c_str(), obj.c_str(), iface.c_str(), method.c_str(), param); -} diff --git a/src/agent/legacy/DBusServer.h b/src/agent/legacy/DBusServer.h deleted file mode 100644 index c4b1c32..0000000 --- a/src/agent/legacy/DBusServer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_DBUS_SERVER_H_ -#define _CONTEXT_DBUS_SERVER_H_ - -#include -#include -#include - -namespace ctx { - - class DBusServer { - public: - ~DBusServer(); - - static void publish(std::string dest, int reqId, std::string subject, int error, std::string data); - static void call(std::string dest, std::string obj, std::string iface, std::string method, GVariant *param); - - private: - DBusServer(); - - static void __onMethodCalled(GDBusConnection *conn, const gchar *sender, - const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data); - static void __onBusAcquired(GDBusConnection *conn, const gchar *name, gpointer userData); - static void __onNameAcquired(GDBusConnection *conn, const gchar *name, gpointer userData); - static void __onNameLost(GDBusConnection *conn, const gchar *name, gpointer userData); - static void __onCallDone(GObject *source, GAsyncResult *res, gpointer userData); - - bool __init(); - void __release(); - void __publish(const char *dest, int reqId, const char *subject, int error, const char *data); - void __call(const char *dest, const char *obj, const char *iface, const char *method, GVariant *param); - - void __processRequest(const char *sender, GVariant *param, GDBusMethodInvocation *invocation); - void __reply(GDBusMethodInvocation *invocation, int error); - - static DBusServer *__theInstance; - - guint __owner; - GDBusConnection *__connection; - GDBusNodeInfo *__nodeInfo; - - friend class Server; - - }; /* class ctx::DBusServer */ - -} /* namespace ctx */ - -#endif /* End of _CONTEXT_DBUS_SERVER_H_ */ diff --git a/src/agent/legacy/ProviderHandler.cpp b/src/agent/legacy/ProviderHandler.cpp deleted file mode 100644 index d4bbc4f..0000000 --- a/src/agent/legacy/ProviderHandler.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include "access_control/Privilege.h" -#include "Request.h" -#include "ProviderHandler.h" - -#define DELETE_DELAY 20 - -using namespace ctx; - -std::map ProviderHandler::__instanceMap; - -ProviderHandler::ProviderHandler(const std::string &subject) : - __subject(subject), - __provider(NULL), - __deleteScheduled(false) -{ - _D("Subject: %s", __subject.c_str()); -} - -ProviderHandler::~ProviderHandler() -{ - _D("Subject: %s", __subject.c_str()); - - for (RequestInfo*& info : __subscribeRequests) { - delete info; - } - __subscribeRequests.clear(); - - for (RequestInfo*& info : __readRequests) { - delete info; - } - __readRequests.clear(); - - delete __provider; -} - -/* TODO: Return proper error code */ -ProviderHandler* ProviderHandler::getInstance(std::string subject, bool force) -{ - InstanceMap::iterator it = __instanceMap.find(subject); - - if (it != __instanceMap.end()) - return it->second; - - if (!force) - return NULL; - - ProviderHandler *handle = new(std::nothrow) ProviderHandler(subject); - IF_FAIL_RETURN_TAG(handle, NULL, _E, "Memory allocation failed"); - - if (!handle->__loadProvider()) { - delete handle; - return NULL; - } - - __instanceMap[subject] = handle; - - return handle; -} - -void ProviderHandler::purge() -{ - for (InstanceMap::iterator it = __instanceMap.begin(); it != __instanceMap.end(); ++it) { - delete it->second; - } - - __instanceMap.clear(); -} - -int ProviderHandler::unregisterCustomProvider(std::string subject) -{ - InstanceMap::iterator it = __instanceMap.find(subject); - IF_FAIL_RETURN_TAG(it != __instanceMap.end(), ERR_NOT_SUPPORTED, _E, "'%s' not found", subject.c_str()); - - __instanceMap.erase(subject); - delete it->second; - - _D("'%s' unregistered", subject.c_str()); - return ERR_NONE; -} - -bool ProviderHandler::isSupported() -{ - /* If idle, self destruct */ - __scheduleToDelete(); - - return __provider->isSupported(); -} - -bool ProviderHandler::isAllowed(const Credentials *creds) -{ - /* If idle, self destruct */ - __scheduleToDelete(); - - IF_FAIL_RETURN(creds, true); /* In case of internal requests */ - - std::vector priv; - __provider->getPrivilege(priv); - - for (unsigned int i = 0; i < priv.size(); ++i) { - if (!privilege_manager::isAllowed(creds, priv[i])) - return false; - } - - return true; -} - -void ProviderHandler::subscribe(RequestInfo *request) -{ - _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); - - CtxJson1 requestResult; - int error = __provider->subscribe(request->getDescription().str(), &requestResult); - - if (!request->reply(error, requestResult) || error != ERR_NONE) { - delete request; - /* If idle, self destruct */ - __scheduleToDelete(); - return; - } - - __subscribeRequests.push_back(request); -} - -void ProviderHandler::unsubscribe(RequestInfo *request) -{ - _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); - - /* Search the subscribe request to be removed */ - auto target = __findRequest(__subscribeRequests, request->getClient(), request->getId()); - if (target == __subscribeRequests.end()) { - _W("Unknown request"); - delete request; - return; - } - - /* Keep the pointer to the request found */ - RequestInfo *reqFound = *target; - - /* Remove the request from the list */ - __subscribeRequests.erase(target); - - /* Check if there exist the same requests */ - if (__findRequest(__subscribeRequests, reqFound->getDescription()) != __subscribeRequests.end()) { - /* Do not stop detecting the subject */ - _D("A same request from '%s' exists", reqFound->getClient()); - request->reply(ERR_NONE); - delete request; - delete reqFound; - return; - } - - /* Stop detecting the subject */ - int error = __provider->unsubscribe(reqFound->getDescription()); - request->reply(error); - delete request; - delete reqFound; - - /* If idle, self destruct */ - __scheduleToDelete(); -} - -void ProviderHandler::read(RequestInfo *request) -{ - _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); - - CtxJson1 requestResult; - int error = __provider->read(request->getDescription().str(), &requestResult); - - if (!request->reply(error, requestResult) || error != ERR_NONE) { - delete request; - /* If idle, self destruct */ - __scheduleToDelete(); - return; - } - - __readRequests.push_back(request); -} - -void ProviderHandler::write(RequestInfo *request) -{ - _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); - - CtxJson1 requestResult; - request->getDescription().set(NULL, KEY_CLIENT_PKG_ID, request->getPackageId()? request->getPackageId() : "SYSTEM"); - int error = __provider->write(request->getDescription(), &requestResult); - - request->reply(error, requestResult); - delete request; - - /* If idle, self destruct */ - __scheduleToDelete(); -} - -bool ProviderHandler::publish(CtxJson1 &option, int error, CtxJson1 &dataUpdated) -{ - auto end = __subscribeRequests.end(); - auto target = __findRequest(__subscribeRequests.begin(), end, option); - - while (target != end) { - if (!(*target)->publish(error, dataUpdated)) { - return false; - } - target = __findRequest(++target, end, option); - } - - return true; -} - -bool ProviderHandler::replyToRead(CtxJson1 &option, int error, CtxJson1 &dataRead) -{ - auto end = __readRequests.end(); - auto target = __findRequest(__readRequests.begin(), end, option); - auto prev = target; - - CtxJson1 dummy; - - while (target != end) { - (*target)->reply(error, dummy, dataRead); - prev = target; - target = __findRequest(++target, end, option); - - delete *prev; - __readRequests.erase(prev); - } - - /* If idle, self destruct */ - __scheduleToDelete(); - - return true; -} - -bool ProviderHandler::__loadProvider() -{ - __provider = __loader.load(__subject.c_str()); - return (__provider != NULL); -} - -bool ProviderHandler::__idle() -{ - return __subscribeRequests.empty() && __readRequests.empty(); -} - -void ProviderHandler::__scheduleToDelete() -{ - if (__provider->unloadable() && !__deleteScheduled && __idle()) { - __deleteScheduled = true; - g_timeout_add_seconds(DELETE_DELAY, __deletor, this); - _D("Delete scheduled for '%s' (%#x)", __subject.c_str(), this); - } -} - -gboolean ProviderHandler::__deletor(gpointer data) -{ - ProviderHandler *handle = static_cast(data); - - if (handle->__idle()) { - __instanceMap.erase(handle->__subject); - delete handle; - return FALSE; - } - - handle->__deleteScheduled = false; - return FALSE; -} - -ProviderHandler::RequestList::iterator -ProviderHandler::__findRequest(RequestList &reqList, CtxJson1 &option) -{ - return __findRequest(reqList.begin(), reqList.end(), option); -} - -ProviderHandler::RequestList::iterator -ProviderHandler::__findRequest(RequestList &reqList, std::string client, int reqId) -{ - for (auto it = reqList.begin(); it != reqList.end(); ++it) { - if (client == (*it)->getClient() && reqId == (*it)->getId()) { - return it; - } - } - return reqList.end(); -} - -ProviderHandler::RequestList::iterator -ProviderHandler::__findRequest(RequestList::iterator begin, RequestList::iterator end, CtxJson1 &option) -{ - for (auto it = begin; it != end; ++it) { - if (option == (*it)->getDescription()) { - return it; - } - } - return end; -} diff --git a/src/agent/legacy/ProviderHandler.h b/src/agent/legacy/ProviderHandler.h deleted file mode 100644 index ae2228e..0000000 --- a/src/agent/legacy/ProviderHandler.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_PROVIDER_HANDLER_H_ -#define _CONTEXT_PROVIDER_HANDLER_H_ - -#include -#include -#include -#include -#include "ProviderLoader.h" - -namespace ctx { - - class Credentials; - class RequestInfo; - - class ProviderHandler { - typedef std::list RequestList; - typedef std::map InstanceMap; - - public: - bool isSupported(); - bool isAllowed(const Credentials *creds); - - void subscribe(RequestInfo *request); - void unsubscribe(RequestInfo *request); - void read(RequestInfo *request); - void write(RequestInfo *request); - - bool publish(ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataUpdated); - bool replyToRead(ctx::CtxJson1 &option, int error, ctx::CtxJson1 &dataRead); - - static ProviderHandler* getInstance(std::string subject, bool force); - static void purge(); - static int unregisterCustomProvider(std::string subject); - - private: - std::string __subject; - ContextProvider *__provider; - RequestList __subscribeRequests; - RequestList __readRequests; - ProviderLoader __loader; - bool __deleteScheduled; - - static InstanceMap __instanceMap; - - ProviderHandler(const std::string &subject); - ~ProviderHandler(); - - bool __loadProvider(); - bool __idle(); - void __scheduleToDelete(); - - RequestList::iterator __findRequest(RequestList &reqList, CtxJson1 &option); - RequestList::iterator __findRequest(RequestList &reqList, std::string client, int reqId); - RequestList::iterator __findRequest(RequestList::iterator begin, RequestList::iterator end, CtxJson1 &option); - - static gboolean __deletor(gpointer data); - - }; /* class ProviderHandler */ - -} /* namespace ctx */ - -#endif /* _CONTEXT_PROVIDER_HANDLER_H_ */ diff --git a/src/agent/legacy/ProviderLoader.cpp b/src/agent/legacy/ProviderLoader.cpp deleted file mode 100644 index 7ef4627..0000000 --- a/src/agent/legacy/ProviderLoader.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include "ProviderLoader.h" - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) - -using namespace ctx; - -typedef ContextProvider* (*create_t)(const char *subject); - -std::map ProviderLoader::__providerLibMap; - -ProviderLoader::ProviderLoader() : - __soHandle(NULL) -{ -} - -ProviderLoader::~ProviderLoader() -{ - __unload(); -} - -ContextProvider* ProviderLoader::load(const char *subject) -{ - ProviderLibMap::iterator it = __providerLibMap.find(subject); - if (it == __providerLibMap.end()) { - _W("No provider for '%s'", subject); - return NULL; - } - - std::string path(_LIBDIR_ LIB_PREFIX); - path = path + it->second + LIB_EXTENSION; - - return __load(path.c_str(), subject); -} - -ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) -{ - _SI("Load '%s' from '%s'", subject, soPath); - - __soHandle = g_module_open(soPath, G_MODULE_BIND_LAZY); - IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", g_module_error()); - - gpointer symbol; - - if (!g_module_symbol(__soHandle, "CreateProvider", &symbol) || symbol == NULL) { - _W("%s", g_module_error()); - g_module_close(__soHandle); - __soHandle = NULL; - return NULL; - } - - create_t create = reinterpret_cast(symbol); - - ContextProvider *prvd = create(subject); - if (!prvd) { - _W("No provider for '%s'", subject); - g_module_close(__soHandle); - __soHandle = NULL; - return NULL; - } - - return prvd; -} - -void ProviderLoader::__unload() -{ - if (!__soHandle) - return; - - g_module_close(__soHandle); - __soHandle = NULL; -} - -bool ProviderLoader::init() -{ - int size = ARRAY_SIZE(subjectLibraryList); - - for (int i = 0; i < size; ++i) { - __providerLibMap[subjectLibraryList[i].subject] = subjectLibraryList[i].library; - _SD("'%s' -> '%s'", subjectLibraryList[i].subject, subjectLibraryList[i].library); - } - - return true; -} - -bool ProviderLoader::popTriggerTemplate(std::string &subject, int &operation, CtxJson1 &attribute, CtxJson1 &option) -{ - static int i = 0; - static int size = ARRAY_SIZE(triggerTemplateList); - - if (i == size) - return false; - - subject = triggerTemplateList[i].subject; - operation = triggerTemplateList[i].operation; - attribute = triggerTemplateList[i].attribute; - option = triggerTemplateList[i].option; - - ++i; - return true; -} diff --git a/src/agent/legacy/ProviderLoader.h b/src/agent/legacy/ProviderLoader.h deleted file mode 100644 index aae6c5d..0000000 --- a/src/agent/legacy/ProviderLoader.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_PROVIDER_LOADER_H_ -#define _CONTEXT_PROVIDER_LOADER_H_ - -#include -#include - -namespace ctx { - - class ContextProvider; - - struct CompareSubjectName { - bool operator()(const char *left, const char *right) const { - while (*left != '\0' && *right != '\0') { - if (*left < *right) - return true; - if (*left > *right) - return false; - ++left; - ++right; - } - return false; - } - }; - - class ProviderLoader { - typedef std::map ProviderLibMap; - - public: - ProviderLoader(); - ~ProviderLoader(); - - ContextProvider* load(const char *subject); - - static bool init(); - static bool popTriggerTemplate(std::string &subject, int &operation, CtxJson1 &attribute, CtxJson1 &option); - - private: - ContextProvider* __load(const char *soPath, const char *subject); - void __unload(); - - GModule *__soHandle; - static ProviderLibMap __providerLibMap; - }; - -} - -#endif /* _CONTEXT_PROVIDER_LOADER_H_ */ diff --git a/src/agent/legacy/Request.cpp b/src/agent/legacy/Request.cpp deleted file mode 100644 index efaa13f..0000000 --- a/src/agent/legacy/Request.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include "Request.h" - -ctx::RequestInfo::RequestInfo(int type, int reqId, const char* subj, const char* desc) : - __type(type), - __reqId(reqId), - __subject(subj), - __description(desc) -{ -} - -ctx::RequestInfo::~RequestInfo() -{ -} - -int ctx::RequestInfo::getType() -{ - return __type; -} - -int ctx::RequestInfo::getId() -{ - return __reqId; -} - -const ctx::Credentials* ctx::RequestInfo::getCredentials() -{ - return NULL; -} - -const char* ctx::RequestInfo::getPackageId() -{ - return NULL; -} - -const char* ctx::RequestInfo::getClient() -{ - return NULL; -} - -const char* ctx::RequestInfo::getSubject() -{ - return __subject.c_str(); -} - -ctx::CtxJson1& ctx::RequestInfo::getDescription() -{ - return __description; -} diff --git a/src/agent/legacy/Request.h b/src/agent/legacy/Request.h deleted file mode 100644 index b3425a1..0000000 --- a/src/agent/legacy/Request.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_REQUEST_INFO_H_ -#define _CONTEXT_REQUEST_INFO_H_ - -#include -#include - -namespace ctx { - - /* Forward declaration */ - class Credentials; - - class RequestInfo { - public: - RequestInfo(int type, int reqId, const char *subj, const char *desc); - virtual ~RequestInfo(); - - int getType(); - int getId(); - const char* getSubject(); - ctx::CtxJson1& getDescription(); - - virtual const Credentials* getCredentials(); - virtual const char* getPackageId(); - /* TODO: remove this getClient() */ - virtual const char* getClient(); - virtual bool reply(int error) = 0; - virtual bool reply(int error, ctx::CtxJson1 &requestResult) = 0; - virtual bool reply(int error, ctx::CtxJson1 &requestResult, ctx::CtxJson1 &dataRead) = 0; - virtual bool publish(int error, ctx::CtxJson1 &data) = 0; - - protected: - int __type; - int __reqId; - std::string __subject; - ctx::CtxJson1 __description; - }; - -} /* namespace ctx */ - -#endif /* End of _CONTEXT_REQUEST_INFO_H_ */ diff --git a/src/agent/legacy/Server.cpp b/src/agent/legacy/Server.cpp deleted file mode 100644 index b6e1c50..0000000 --- a/src/agent/legacy/Server.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include "DBusServer.h" -#include "ContextManager.h" -#include "policy/PolicyManager.h" -#include "trigger/Trigger.h" -#include "Server.h" - -#define RUN(L) g_main_loop_run((L)) -#define QUIT(L) if (g_main_loop_is_running((L)) == TRUE) g_main_loop_quit((L)) - - -static GMainLoop *mainloop = NULL; -static bool started = false; - -static ctx::ContextManager *__contextMgr = NULL; -static ctx::DBusServer *__dbusHandle = NULL; -static ctx::PolicyManager *__policyMgr = NULL; -static ctx::trigger::Trigger *__contextTrigger = NULL; -static ctx::TimerManager __timerManager; - -/* TODO: re-organize activation & deactivation processes */ -void ctx::Server::initialize() -{ - _I("Init Dbus Connection"); - __dbusHandle = new(std::nothrow) ctx::DBusServer(); - IF_FAIL_VOID_TAG(__dbusHandle, _E, "Memory allocation failed"); - IF_FAIL_VOID_TAG(__dbusHandle->__init(), _E, "Initialization Failed"); - - // Start the main loop - _I(CYAN("Launching Context-Service")); - RUN(mainloop); -} - -void ctx::Server::activate() -{ - IF_FAIL_VOID(!started); - - bool result = false; - - _I("Init Database Manager"); - IF_FAIL_CATCH(DatabaseManager::__init()); - - _I("Init Context Manager"); - __contextMgr = new(std::nothrow) ctx::ContextManager(); - IF_FAIL_CATCH_TAG(__contextMgr, _E, "Memory allocation failed"); - result = __contextMgr->init(); - IF_FAIL_CATCH_TAG(result, _E, "Initialization Failed"); - - _I("Init Context Trigger"); - __contextTrigger = new(std::nothrow) ctx::trigger::Trigger(); - IF_FAIL_CATCH_TAG(__contextTrigger, _E, "Memory allocation failed"); - result = __contextTrigger->init(__contextMgr); - IF_FAIL_CATCH_TAG(result, _E, "Initialization Failed"); - - _I("Init Policy Manager"); - __policyMgr = new(std::nothrow) ctx::PolicyManager(__contextMgr); - IF_FAIL_CATCH_TAG(__policyMgr, _E, "Memory allocation failed"); - - started = true; - _I(CYAN("Context-Service Launched")); - return; - -CATCH: - _E(RED("Launching Failed")); - - // Stop the main loop - QUIT(mainloop); -} - -void ctx::Server::release() -{ - _I(CYAN("Terminating Context-Service")); - started = false; - - _I("Release Policy Manager"); - delete __policyMgr; - - _I("Release Context Trigger"); - if (__contextTrigger) - __contextTrigger->release(); - - _I("Release Context Manager"); - if (__contextMgr) - __contextMgr->release(); - - _I("Release Database Manager"); - DatabaseManager::__release(); - - delete __contextTrigger; - delete __contextMgr; - delete __dbusHandle; -} - -static gboolean __postponeRequestAssignment(gpointer data) -{ - ctx::Server::sendRequest(static_cast(data)); - return FALSE; -} - -void ctx::Server::sendRequest(ctx::RequestInfo* request) -{ - if (!started) { - _W("Service not ready..."); - g_idle_add(__postponeRequestAssignment, request); - return; - } - - if (__contextTrigger->assignRequest(request)) - return; - - __contextMgr->assignRequest(request); -} - -static void __signalHandler(int signo) -{ - _I("SIGNAL %d received", signo); - - // Stop the main loop - QUIT(mainloop); -} - -int mainLegacy() -{ - static struct sigaction signalAction; - signalAction.sa_handler = __signalHandler; - sigemptyset(&signalAction.sa_mask); - - sigaction(SIGINT, &signalAction, NULL); - sigaction(SIGHUP, &signalAction, NULL); - sigaction(SIGTERM, &signalAction, NULL); - sigaction(SIGQUIT, &signalAction, NULL); - sigaction(SIGABRT, &signalAction, NULL); - -#if !defined(GLIB_VERSION_2_36) - g_type_init(); -#endif - - _I("Init MainLoop"); - mainloop = g_main_loop_new(NULL, FALSE); - - ctx::Server::initialize(); - ctx::Server::release(); - - g_main_loop_unref(mainloop); - - return EXIT_SUCCESS; -} diff --git a/src/agent/legacy/Server.h b/src/agent/legacy/Server.h deleted file mode 100644 index 621a6ea..0000000 --- a/src/agent/legacy/Server.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_SERVER_H_ -#define _CONTEXT_SERVER_H_ - -int mainLegacy(); - -namespace ctx { - - class RequestInfo; - - class Server { - public: - static void initialize(); - static void activate(); - static void release(); - static void sendRequest(RequestInfo* request); - - }; - -} /* namespace ctx */ - -#endif /* End of _CONTEXT_SERVER_H_ */ diff --git a/src/agent/legacy/access_control/PeerCreds.cpp b/src/agent/legacy/access_control/PeerCreds.cpp deleted file mode 100644 index 336da5a..0000000 --- a/src/agent/legacy/access_control/PeerCreds.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include "PeerCreds.h" - -ctx::Credentials::Credentials(char *pkgId, char *cli, char *sess, char *usr) : - packageId(pkgId), - client(cli), - session(sess), - user(usr) -{ -} - -ctx::Credentials::~Credentials() -{ - g_free(packageId); - g_free(client); - g_free(session); - g_free(user); -} - -bool ctx::peer_creds::get(GDBusConnection *connection, const char *uniqueName, const char *cookie, ctx::Credentials **creds) -{ - pid_t pid = 0; - char *app_id = NULL; - char *packageId = NULL; - gchar *client = NULL; - char *session = NULL; - gchar *user = NULL; - - int err = cynara_creds_gdbus_get_pid(connection, uniqueName, &pid); - IF_FAIL_RETURN_TAG(err == CYNARA_API_SUCCESS, false, _E, "Peer credentialing failed"); - - session = cynara_session_from_pid(pid); - IF_FAIL_CATCH_TAG(session, _E, "Peer credentialing failed"); - - err = cynara_creds_gdbus_get_client(connection, uniqueName, CLIENT_METHOD_DEFAULT, &client); - IF_FAIL_CATCH_TAG(err == CYNARA_API_SUCCESS, _E, "Peer credentialing failed"); - - err = cynara_creds_gdbus_get_user(connection, uniqueName, USER_METHOD_DEFAULT, &user); - IF_FAIL_CATCH_TAG(err == CYNARA_API_SUCCESS, _E, "Peer credentialing failed"); - - app_manager_get_app_id(pid, &app_id); - package_manager_get_package_id_by_app_id(app_id, &packageId); - _D("AppId: %s, PackageId: %s", app_id, packageId); - g_free(app_id); - - *creds = new(std::nothrow) Credentials(packageId, client, session, user); - IF_FAIL_CATCH_TAG(*creds, _E, "Memory allocation failed"); - - return true; - -CATCH: - g_free(packageId); - g_free(client); - g_free(session); - g_free(user); - return false; -} diff --git a/src/agent/legacy/access_control/PeerCreds.h b/src/agent/legacy/access_control/PeerCreds.h deleted file mode 100644 index 255244e..0000000 --- a/src/agent/legacy/access_control/PeerCreds.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_PEER_CREDENTIALS_H_ -#define _CONTEXT_PEER_CREDENTIALS_H_ - -#include -#include -#include - -namespace ctx { - - class Credentials { - public: - char *packageId; - char *client; /* default: smack label */ - char *session; - char *user; /* default: UID */ - Credentials(char *pkgId, char *cli, char *sess, char *usr); - ~Credentials(); - }; - - namespace peer_creds { - - bool get(GDBusConnection *connection, const char *uniqueName, const char *cookie, Credentials **creds); - - } /* namespace peer_creds */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_PEER_CREDENTIALS_H_ */ diff --git a/src/agent/legacy/access_control/Privilege.cpp b/src/agent/legacy/access_control/Privilege.cpp deleted file mode 100644 index b9b6c37..0000000 --- a/src/agent/legacy/access_control/Privilege.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include "PeerCreds.h" -#include "Privilege.h" - -#define PRIV_PREFIX "http://tizen.org/privilege/" -#define CACHE_SIZE 100 - -class PermissionChecker { -private: - cynara *__cynara; - - PermissionChecker() : - __cynara(NULL) - { - cynara_configuration *conf = NULL; - - int err = cynara_configuration_create(&conf); - IF_FAIL_VOID_TAG(err == CYNARA_API_SUCCESS, _E, "Cynara configuration creation failed"); - - err = cynara_configuration_set_cache_size(conf, CACHE_SIZE); - if (err != CYNARA_API_SUCCESS) { - _E("Cynara cache size set failed"); - cynara_configuration_destroy(conf); - return; - } - - err = cynara_initialize(&__cynara, conf); - cynara_configuration_destroy(conf); - if (err != CYNARA_API_SUCCESS) { - _E("Cynara initialization failed"); - __cynara = NULL; - return; - } - - _I("Cynara initialized"); - } - - ~PermissionChecker() - { - if (__cynara) - cynara_finish(__cynara); - - _I("Cynara deinitialized"); - } - -public: - static PermissionChecker& getInstance() - { - static PermissionChecker instance; - return instance; - } - - bool hasPermission(const ctx::Credentials *creds, const char *privilege) - { - IF_FAIL_RETURN_TAG(__cynara, false, _E, "Cynara not initialized"); - int ret = cynara_check(__cynara, creds->client, creds->session, creds->user, privilege); - return (ret == CYNARA_API_ACCESS_ALLOWED); - } -}; - -bool ctx::privilege_manager::isAllowed(const ctx::Credentials *creds, const char *privilege) -{ - IF_FAIL_RETURN(creds && privilege, true); - - std::string priv = PRIV_PREFIX; - priv += privilege; - - return PermissionChecker::getInstance().hasPermission(creds, priv.c_str()); -} diff --git a/src/agent/legacy/access_control/Privilege.h b/src/agent/legacy/access_control/Privilege.h deleted file mode 100644 index 6eb1198..0000000 --- a/src/agent/legacy/access_control/Privilege.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_PRIVILEGE_MANAGER_H_ -#define _CONTEXT_PRIVILEGE_MANAGER_H_ - -namespace ctx { - - /* Forward declaration */ - class Credentials; - - namespace privilege_manager { - - bool isAllowed(const Credentials *creds, const char *privilege); - - } /* namespace privilege_manager */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_PRIVILEGE_MANAGER_H_ */ diff --git a/src/agent/legacy/policy/PolicyManager.cpp b/src/agent/legacy/policy/PolicyManager.cpp deleted file mode 100644 index 782c81c..0000000 --- a/src/agent/legacy/policy/PolicyManager.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include "../ContextManager.h" -#include "PolicyRequest.h" -#include "PolicyManager.h" - -using namespace ctx; - -PolicyManager::PolicyManager(ContextManager *contextMgr) : - __contextMgr(contextMgr) -{ - __subscribe(SUBJ_CUSTOM); - -// __subscribe(SUBJ_APP_LOGGER); -// __subscribe(SUBJ_BATTERY_LOGGER); -// __subscribe(SUBJ_MEDIA_LOGGER); -// __subscribe(SUBJ_PLACE_DETECTION); -// __subscribe(SUBJ_STATE_WIFI); - -// __subscribe(SUBJ_SENSOR_PEDOMETER); -// __subscribe(SUBJ_SENSOR_PRESSURE); -// __subscribe(SUBJ_SENSOR_SLEEP_MONITOR); -// __subscribe(SUBJ_SENSOR_HEART_RATE); -} - -PolicyManager::~PolicyManager() -{ - for (auto &it : __subscriptionMap) { - PolicyRequest *req = new(std::nothrow) PolicyRequest(REQ_UNSUBSCRIBE, it.first, it.second, NULL); - if (!req) { - _E("Memory allocation failed"); - continue; - } - __contextMgr->assignRequest(req); - } - - __subscriptionMap.clear(); -} - -void PolicyManager::__subscribe(const char *subject) -{ - static int rid = 0; - ++rid; - - PolicyRequest *req = new(std::nothrow) PolicyRequest(REQ_SUBSCRIBE, rid, subject, NULL); - IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed"); - - __contextMgr->assignRequest(req); - - __subscriptionMap[rid] = subject; -} diff --git a/src/agent/legacy/policy/PolicyManager.h b/src/agent/legacy/policy/PolicyManager.h deleted file mode 100644 index ce9b315..0000000 --- a/src/agent/legacy/policy/PolicyManager.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_POLICY_MANAGER_H_ -#define _CONTEXT_POLICY_MANAGER_H_ - -#include - -namespace ctx { - - class ContextManger; - - class PolicyManager { - public: - ~PolicyManager(); - - private: - PolicyManager(ContextManager *contextMgr); - - void __subscribe(const char *subject); - - ContextManager *__contextMgr; - std::map __subscriptionMap; - - friend class Server; - }; - -} /* namespace ctx */ - -#endif /* _CONTEXT_POLICY_MANAGER_H_ */ diff --git a/src/agent/legacy/policy/PolicyRequest.cpp b/src/agent/legacy/policy/PolicyRequest.cpp deleted file mode 100644 index cd69534..0000000 --- a/src/agent/legacy/policy/PolicyRequest.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include "PolicyRequest.h" - -using namespace ctx; - -PolicyRequest::PolicyRequest(int type, int reqId, const char *subj, const char *desc) : - RequestInfo(type, reqId, subj, desc) -{ -} - -PolicyRequest::~PolicyRequest() -{ -} - -const char* PolicyRequest::getClient() -{ - return "POLICY"; -} - -bool PolicyRequest::reply(int error) -{ - return true; -} - -bool PolicyRequest::reply(int error, ctx::CtxJson1 &requestResult) -{ - return true; -} - -bool PolicyRequest::reply(int error, ctx::CtxJson1 &requestResult, ctx::CtxJson1 &dataRead) -{ - return true; -} - -bool PolicyRequest::publish(int error, ctx::CtxJson1 &data) -{ - return true; -} diff --git a/src/agent/legacy/policy/PolicyRequest.h b/src/agent/legacy/policy/PolicyRequest.h deleted file mode 100644 index ce68fb8..0000000 --- a/src/agent/legacy/policy/PolicyRequest.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_POLICY_REQUEST_H_ -#define _CONTEXT_POLICY_REQUEST_H_ - -#include "../Request.h" - -namespace ctx { - - class PolicyRequest : public RequestInfo { - public: - PolicyRequest(int type, int reqId, const char *subj, const char *desc); - ~PolicyRequest(); - - const char* getClient(); - - bool reply(int error); - bool reply(int error, ctx::CtxJson1 &requestResult); - bool reply(int error, ctx::CtxJson1 &requestResult, ctx::CtxJson1 &dataRead); - bool publish(int error, ctx::CtxJson1 &data); - }; - -} /* namespace ctx */ - -#endif /* End of _CONTEXT_POLICY_REQUEST_H_ */ diff --git a/src/agent/legacy/trigger/ActionManager.cpp b/src/agent/legacy/trigger/ActionManager.cpp deleted file mode 100644 index 332c87e..0000000 --- a/src/agent/legacy/trigger/ActionManager.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../DBusServer.h" -#include "ActionManager.h" - -using namespace ctx; - -static void __triggerActionAppControl(CtxJson1& action); -static void __triggerActionNotification(CtxJson1& action, std::string pkgId); -static void __triggerActionDbusCall(CtxJson1& action); - -void trigger::action_manager::triggerAction(CtxJson1& action, std::string pkgId) -{ - std::list types; - action.getKeys(&types); - IF_FAIL_VOID_TAG(types.size() == 1, _E, "Invalid action"); - - std::string& type = *(types.begin()); - - if (type.compare(TRIG_RULE_KEY_APP_LAUNCH) == 0) { - __triggerActionAppControl(action); - } else if (type.compare(TRIG_RULE_KEY_NOTIFICATION) == 0) { - __triggerActionNotification(action, pkgId); - } else if (type.compare(TRIG_RULE_KEY_DBUS_CALL) == 0) { - __triggerActionDbusCall(action); - } -} - -void __triggerActionAppControl(CtxJson1& action) -{ - int error; - std::string appctlStr; - action.get(TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, &appctlStr); - - char* str = static_cast(malloc(appctlStr.length())); - if (str == NULL) { - _E("Memory allocation failed"); - return; - } - appctlStr.copy(str, appctlStr.length(), 0); - bundle_raw* encoded = reinterpret_cast(str); - bundle* appctlBundle = bundle_decode(encoded, appctlStr.length()); - - app_control_h app = NULL; - app_control_create(&app); - app_control_import_from_bundle(app, appctlBundle); - - error = app_control_send_launch_request(app, NULL, NULL); - if (error != APP_CONTROL_ERROR_NONE) { - _E("Launch request failed(%d)", error); - } else { - _D("Launch request succeeded"); - } - bundle_free(appctlBundle); - free(str); - app_control_destroy(app); - - error = device_display_change_state(DISPLAY_STATE_NORMAL); - if (error != DEVICE_ERROR_NONE) { - _E("Change display state failed(%d)", error); - } -} - -void __triggerActionNotification(CtxJson1& action, std::string pkgId) -{ - int error; - notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI); - std::string title; - if (action.get(TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, &title)) { - error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification title failed(%d)", error); - } - } - - std::string content; - if (action.get(TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, &content)) { - error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification contents failed(%d)", error); - } - } - - std::string imagePath; - if (action.get(TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, &imagePath)) { - error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, imagePath.c_str()); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification icon image failed(%d)", error); - } - } - - std::string appctlStr; - char* str = NULL; - bundle_raw* encoded = NULL; - bundle* appctlBundle = NULL; - app_control_h app = NULL; - if (action.get(TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, &appctlStr)) { - str = static_cast(malloc(appctlStr.length())); - if (str == NULL) { - _E("Memory allocation failed"); - notification_free(notification); - return; - } - appctlStr.copy(str, appctlStr.length(), 0); - encoded = reinterpret_cast(str); - appctlBundle = bundle_decode(encoded, appctlStr.length()); - - app_control_create(&app); - app_control_import_from_bundle(app, appctlBundle); - - error = notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, app); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set launch option failed(%d)", error); - } - } - - if (!pkgId.empty()) { - error = notification_set_pkgname(notification, pkgId.c_str()); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set package id(%s) failed(%#x)", pkgId.c_str(), error); - } - } - - int soundOn = 0; - error = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &soundOn); - if (error < 0) { - _E("vconf error (%d)", error); - } else if (soundOn) { - error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification sound failed(%d)", error); - } - } - - int vibrationOn = 0; - error = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibrationOn); - if (error < 0) { - _E("vconf error (%d)", error); - } else if (vibrationOn) { - error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification vibration failed(%d)", error); - } - } - - error = notification_post(notification); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Post notification failed(%d)", error); - } else { - _D("Post notification succeeded"); - } - - bundle_free(appctlBundle); - free(str); - notification_free(notification); - if (app) { - app_control_destroy(app); - } - - error = device_display_change_state(DISPLAY_STATE_NORMAL); - if (error != DEVICE_ERROR_NONE) { - _E("Change display state failed(%d)", error); - } -} - -void __triggerActionDbusCall(CtxJson1& action) -{ - std::string busName, object, iface, method; - GVariant *param = NULL; - - action.get(TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, &busName); - IF_FAIL_VOID_TAG(!busName.empty(), _E, "No target bus name"); - - action.get(TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, &object); - IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path"); - - action.get(TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, &iface); - IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name"); - - action.get(TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, &method); - IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name"); - - action.get(TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, ¶m); - - DBusServer::call(busName, object, iface, method, param); -} diff --git a/src/agent/legacy/trigger/ActionManager.h b/src/agent/legacy/trigger/ActionManager.h deleted file mode 100644 index 5d8c026..0000000 --- a/src/agent/legacy/trigger/ActionManager.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_ACTION_MANAGER_H_ -#define _CONTEXT_TRIGGER_ACTION_MANAGER_H_ - -namespace ctx { - /* Forward Declaration */ - class CtxJson1; - -namespace trigger { - - namespace action_manager { - - void triggerAction(CtxJson1& action, std::string pkgId); - - } /* namespace action_manager */ - -} /* namespace trigger*/ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_ACTION_MANAGER_H_ */ diff --git a/src/agent/legacy/trigger/ContextMonitor.cpp b/src/agent/legacy/trigger/ContextMonitor.cpp deleted file mode 100644 index 86d8c99..0000000 --- a/src/agent/legacy/trigger/ContextMonitor.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include "../access_control/Privilege.h" -#include "../ContextManager.h" -#include "ContextMonitor.h" -#include "IContextListener.h" -#include "FactRequest.h" - -using namespace ctx; -using namespace trigger; - -static int __lastRid; -static int __lastErr; - -ContextMonitor *ContextMonitor::__instance = NULL; -ContextManager *ContextMonitor::__contextMgr = NULL; - -static int __generateReqId() -{ - static int reqId = 0; - - if (++reqId < 0) { - // Overflow handling - reqId = 1; - } - - return reqId; -} - -ContextMonitor::ContextMonitor() -{ -} - -ContextMonitor::~ContextMonitor() -{ -} - -void ContextMonitor::setContextManager(ContextManager* ctxMgr) -{ - __contextMgr = ctxMgr; -} - -ContextMonitor* ContextMonitor::getInstance() -{ - IF_FAIL_RETURN_TAG(__contextMgr, NULL, _E, "Context manager is needed"); - - IF_FAIL_RETURN(!__instance, __instance); - - __instance = new(std::nothrow) ContextMonitor(); - IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory alllocation failed"); - - return __instance; -} - -void ContextMonitor::destroy() -{ - if (__instance) { - delete __instance; - __instance = NULL; - } -} - -int ContextMonitor::subscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener) -{ - int reqId = __subscribe(subject.c_str(), &option, listener); - IF_FAIL_RETURN_TAG(reqId > 0, reqId, _E, "Subscribe event failed"); - _D(YELLOW("Subscribe event(rule%d). req%d"), ruleId, reqId); - - return ERR_NONE; -} - -int ContextMonitor::__subscribe(const char* subject, CtxJson1* option, IContextListener* listener) -{ - IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER); - - int rid = __findSub(REQ_SUBSCRIBE, subject, option); - if (rid > 0) { - __addListener(REQ_SUBSCRIBE, rid, listener); - _D("Duplicated request for %s", subject); - return rid; - } - - rid = __generateReqId(); - - FactRequest *req = new(std::nothrow) FactRequest(REQ_SUBSCRIBE, - rid, subject, option ? option->str().c_str() : NULL, this); - IF_FAIL_RETURN_TAG(req, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed"); - - __contextMgr->assignRequest(req); - __addSub(REQ_SUBSCRIBE, rid, subject, option, listener); - - if (__lastErr != ERR_NONE) { - __removeSub(REQ_SUBSCRIBE, rid); - _E("Subscription request failed: %#x", __lastErr); - return __lastErr; - } - - return rid; -} - -int ContextMonitor::unsubscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener) -{ - int rid = __findSub(REQ_SUBSCRIBE, subject.c_str(), &option); - if (rid < 0) { - _D("Invalid unsubscribe request"); - return ERR_INVALID_PARAMETER; - } - - if (__removeListener(REQ_SUBSCRIBE, rid, listener) <= 0) { - __unsubscribe(subject.c_str(), rid); - } - _D(YELLOW("Unsubscribe event(rule%d). req%d"), ruleId, rid); - - return ERR_NONE; -} - -void ContextMonitor::__unsubscribe(const char *subject, int subscriptionId) -{ - FactRequest *req = new(std::nothrow) FactRequest(REQ_UNSUBSCRIBE, subscriptionId, subject, NULL, NULL); - IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed"); - - __contextMgr->assignRequest(req); - __removeSub(REQ_SUBSCRIBE, subscriptionId); -} - -int ContextMonitor::read(std::string subject, CtxJson1 option, IContextListener* listener) -{ - int reqId = __read(subject.c_str(), &option, listener); - IF_FAIL_RETURN_TAG(reqId > 0, ERR_OPERATION_FAILED, _E, "Read condition failed"); - _D(YELLOW("Read condition(%s). req%d"), subject.c_str(), reqId); - - return ERR_NONE; -} - -int ContextMonitor::__read(const char* subject, CtxJson1* option, IContextListener* listener) -{ - IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER); - - int rid = __findSub(REQ_READ, subject, option); - if (rid > 0) { - __addListener(REQ_READ, rid, listener); - _D("Duplicated request for %s", subject); - return rid; - } - - rid = __generateReqId(); - - FactRequest *req = new(std::nothrow) FactRequest(REQ_READ, - rid, subject, option ? option->str().c_str() : NULL, this); - IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed"); - - __contextMgr->assignRequest(req); - __addSub(REQ_READ, rid, subject, option, listener); - - if (__lastErr != ERR_NONE) { - _E("Read request failed: %#x", __lastErr); - return -1; - } - - return rid; -} - -bool ContextMonitor::isSupported(std::string subject) -{ - return __contextMgr->isSupported(subject.c_str()); -} - -bool ContextMonitor::isAllowed(const char *client, const char *subject) -{ - //TODO: re-implement this in the proper 3.0 style - //return __contextMgr->isAllowed(client, subject); - return true; -} - -int ContextMonitor::__findSub(RequestType type, const char* subject, CtxJson1* option) -{ - // @return request id - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - CtxJson1 jOpt; - if (option) { - jOpt = *option; - } - - for (auto it = map->begin(); it != map->end(); ++it) { - if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) { - return it->first; - } - } - - return -1; -} - -bool ContextMonitor::__addSub(RequestType type, int sid, const char* subject, CtxJson1* option, IContextListener* listener) -{ - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - SubscrInfo *info = new(std::nothrow) SubscrInfo(sid, subject, option); - IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed"); - info->listenerList.push_back(listener); - - map->insert(std::pair(sid, info)); - return true; -} - -void ContextMonitor::__removeSub(RequestType type, const char* subject, CtxJson1* option) -{ - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - CtxJson1 jOpt; - if (option) { - jOpt = *option; - } - - for (auto it = map->begin(); it != map->end(); ++it) { - if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) { - delete it->second; - map->erase(it); - return; - } - } -} - -void ContextMonitor::__removeSub(RequestType type, int sid) -{ - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - SubscrInfo* info = map->at(sid); - info->listenerList.clear(); - - delete info; - map->erase(sid); - - return; -} - -int ContextMonitor::__addListener(RequestType type, int sid, IContextListener* listener) -{ - // @return number of listeners for the corresponding sid - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - auto it = map->find(sid); - - SubscrInfo* info = it->second; - info->listenerList.push_back(listener); - - return info->listenerList.size(); -} - -int ContextMonitor::__removeListener(RequestType type, int sid, IContextListener* listener) -{ - // @return number of listeners for the corresponding sid - std::map* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap; - - auto it = map->find(sid); - - SubscrInfo* info = it->second; - - for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) { - if (*it2 == listener) { - info->listenerList.erase(it2); - break; - } - } - - return info->listenerList.size(); -} - -void ContextMonitor::replyResult(int reqId, int error, CtxJson1* requestResult) -{ - _D("Request result received: %d", reqId); - - __lastRid = reqId; - __lastErr = error; -} - -void ContextMonitor::replyResult(int reqId, int error, const char* subject, CtxJson1* option, CtxJson1* fact) -{ - _D(YELLOW("Condition received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str()); - - auto it = __readMap.find(reqId); - IF_FAIL_VOID_TAG(it != __readMap.end(), _E, "Request id not found"); - - SubscrInfo* info = it->second; - for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) { - (*it2)->onConditionReceived(subject, *option, *fact); - } - - __removeSub(REQ_READ, reqId); -} - -void ContextMonitor::publishFact(int reqId, int error, const char* subject, CtxJson1* option, CtxJson1* fact) -{ - _D(YELLOW("Event received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str()); - - auto it = __subscrMap.find(reqId); - IF_FAIL_VOID_TAG(it != __subscrMap.end(), _E, "Request id not found"); - - SubscrInfo* info = it->second; - for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) { - (*it2)->onEventReceived(subject, *option, *fact); - } -} diff --git a/src/agent/legacy/trigger/ContextMonitor.h b/src/agent/legacy/trigger/ContextMonitor.h deleted file mode 100644 index 6f65cdf..0000000 --- a/src/agent/legacy/trigger/ContextMonitor.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_ -#define _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_ - -#include -#include -#include -#include - -namespace ctx { - - class ContextManager; - -namespace trigger { - - class IContextListener; - class FactRequest; - - class ContextMonitor { - public: - static ContextMonitor* getInstance(); - static void setContextManager(ContextManager* ctxMgr); - static void destroy(); - - int subscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener); - int unsubscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener); - int read(std::string subject, CtxJson1 option, IContextListener* listener); - bool isSupported(std::string subject); - bool isAllowed(const char *client, const char *subject); - - void replyResult(int reqId, int error, CtxJson1 *requestResult = NULL); - void replyResult(int reqId, int error, const char *subject, CtxJson1 *option, CtxJson1 *fact); - void publishFact(int reqId, int error, const char *subject, CtxJson1 *option, CtxJson1 *fact); - - private: - ContextMonitor(); - ContextMonitor(const ContextMonitor& other); - ~ContextMonitor(); - - static ContextMonitor *__instance; - static ContextManager *__contextMgr; - - int __subscribe(const char* subject, CtxJson1* option, IContextListener* listener); - void __unsubscribe(const char *subject, int subscriptionId); - int __read(const char *subject, CtxJson1 *option, IContextListener* listener); - - struct SubscrInfo { - int sid; - std::string subject; - CtxJson1 option; - std::list listenerList; - - SubscrInfo(int id, const char *subj, CtxJson1 *opt) : - sid(id), - subject(subj) - { - if (opt) - option = *opt; - } - }; - - std::map __subscrMap; - std::map __readMap; - - int __findSub(RequestType type, const char *subject, CtxJson1 *option); - bool __addSub(RequestType type, int sid, const char *subject, CtxJson1 *option, IContextListener* listener); - void __removeSub(RequestType type, const char *subject, CtxJson1 *option); - void __removeSub(RequestType type, int sid); - int __addListener(RequestType type, int sid, IContextListener* listener); - int __removeListener(RequestType type, int sid, IContextListener* listener); - - }; /* class ContextMonitor */ - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_ */ diff --git a/src/agent/legacy/trigger/FactRequest.cpp b/src/agent/legacy/trigger/FactRequest.cpp deleted file mode 100644 index da9212c..0000000 --- a/src/agent/legacy/trigger/FactRequest.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include "FactRequest.h" - -using namespace ctx; -using namespace ctx::trigger; - -FactRequest::FactRequest(int type, int reqId, const char* subj, const char* desc, ContextMonitor* ctxMonitor) : - RequestInfo(type, reqId, subj, desc), - __ctxMonitor(ctxMonitor), - __replied(false) -{ -} - -FactRequest::~FactRequest() -{ - reply(ERR_OPERATION_FAILED); -} - -const char* FactRequest::getClient() -{ - return "TRIGGER"; -} - -bool FactRequest::reply(int error) -{ - IF_FAIL_RETURN(!__replied && __ctxMonitor, true); - __ctxMonitor->replyResult(__reqId, error); - __replied = (error != ERR_NONE); - return true; -} - -bool FactRequest::reply(int error, CtxJson1& requestResult) -{ - IF_FAIL_RETURN(!__replied && __ctxMonitor, true); - __ctxMonitor->replyResult(__reqId, error, &requestResult); - __replied = (error != ERR_NONE); - return true; -} - -bool FactRequest::reply(int error, CtxJson1& requestResult, CtxJson1& dataRead) -{ - IF_FAIL_RETURN(!__replied && __ctxMonitor, true); - __ctxMonitor->replyResult(__reqId, error, __subject.c_str(), &getDescription(), &dataRead); - return (__replied = true); -} - -bool FactRequest::publish(int error, CtxJson1& data) -{ - IF_FAIL_RETURN(__ctxMonitor, true); - __ctxMonitor->publishFact(__reqId, error, __subject.c_str(), &getDescription(), &data); - return true; -} diff --git a/src/agent/legacy/trigger/FactRequest.h b/src/agent/legacy/trigger/FactRequest.h deleted file mode 100644 index 2c18b4a..0000000 --- a/src/agent/legacy/trigger/FactRequest.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_FACT_REQUEST_H_ -#define _CONTEXT_TRIGGER_FACT_REQUEST_H_ - -#include "ContextMonitor.h" -#include "../Request.h" - -namespace ctx { - -namespace trigger { - - class FactRequest : public RequestInfo { - public: - FactRequest(int type, int reqId, const char* subj, const char* desc, ContextMonitor* ctxMonitor); - ~FactRequest(); - - const char* getClient(); - bool reply(int error); - bool reply(int error, ctx::CtxJson1& requestResult); - bool reply(int error, ctx::CtxJson1& requestResult, ctx::CtxJson1& dataRead); - bool publish(int error, ctx::CtxJson1& data); - - private: - ContextMonitor *__ctxMonitor; - bool __replied; - }; - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_FACT_REQUEST_H_ */ diff --git a/src/agent/legacy/trigger/FactTypes.h b/src/agent/legacy/trigger/FactTypes.h deleted file mode 100644 index fe50f11..0000000 --- a/src/agent/legacy/trigger/FactTypes.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_FACT_TYPES_H_ -#define _CONTEXT_TRIGGER_FACT_TYPES_H_ - -#define FACT_KEY_EVENT "event" -#define FACT_KEY_CONDITION "condition" -#define FACT_KEY_NAME "name" -#define FACT_KEY_OPTION "option" -#define FACT_KEY_DATA "data" - -#endif /* End of _CONTEXT_TRIGGER_FACT_TYPES_H_ */ diff --git a/src/agent/legacy/trigger/IContextListener.h b/src/agent/legacy/trigger/IContextListener.h deleted file mode 100644 index 1311254..0000000 --- a/src/agent/legacy/trigger/IContextListener.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_ -#define _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_ - -namespace ctx { - /* Forward Declaration */ - class CtxJson1; - -namespace trigger { - - class IContextListener { - public: - virtual ~IContextListener() {} - - virtual void onEventReceived(std::string name, CtxJson1 option, CtxJson1 data) = 0; - - virtual void onConditionReceived(std::string name, CtxJson1 option, CtxJson1 data) = 0; - }; - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_ */ diff --git a/src/agent/legacy/trigger/Rule.cpp b/src/agent/legacy/trigger/Rule.cpp deleted file mode 100644 index d6bff32..0000000 --- a/src/agent/legacy/trigger/Rule.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include "Rule.h" -#include "ActionManager.h" -#include "RuleEvaluator.h" -#include "ContextMonitor.h" -#include "FactTypes.h" -#include "RuleManager.h" - -using namespace ctx; -using namespace ctx::trigger; - -RuleManager *Rule::__ruleMgr = NULL; - -Rule::Rule(int i, CtxJson1& d, const char* p, RuleManager* rm) : - __result(EMPTY_JSON_OBJECT), - id(i), - pkgId(p) -{ - // Rule manager - if (!__ruleMgr) { - __ruleMgr = rm; - } - - // Statement - __statement = d.str(); - - // Event - CtxJson1 e; - d.get(NULL, TRIG_RULE_KEY_EVENT, &e); - __event = new(std::nothrow) ContextItem(e); - - // Condition - int condNum = d.getSize(NULL, TRIG_RULE_KEY_CONDITION); - for (int j = 0; j < condNum; j++) { - CtxJson1 c; - d.getAt(NULL, TRIG_RULE_KEY_CONDITION, j, &c); - __condition.push_back(new(std::nothrow) ContextItem(c)); - } - - // Extra - CtxJson1 extra; - d.get(NULL, _TRIG_RULE_KEY_EXTRA, &extra); - __extra = extra.str(); - - // Action - CtxJson1 a; - d.get(NULL, TRIG_RULE_KEY_ACTION, &a); - __action = a.str(); -} - -Rule::~Rule() -{ - // Release resources - delete __event; - for (auto it = __condition.begin(); it != __condition.end(); ++it) { - delete *it; - } -} - -int Rule::start(void) -{ - // Subscribe event - int error = ContextMonitor::getInstance()->subscribe(id, __event->name, __event->option, this); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id); - - return error; -} - -int Rule::stop(void) -{ - // Unsubscribe event - int error = ContextMonitor::getInstance()->unsubscribe(id, __event->name, __event->option, this); - if (error == ERR_NOT_SUPPORTED) { - _E("Stop rule%d (event not supported)"); - return ERR_NONE; - } - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id); - - return error; -} - -bool Rule::__setConditionOptionBasedOnEvent(CtxJson1& option) -{ - // Set condition option if it references event data - std::list optionKeys; - option.getKeys(&optionKeys); - - for (auto it = optionKeys.begin(); it != optionKeys.end(); ++it) { - std::string optKey = (*it); - - std::string optVal; - if (option.get(NULL, optKey.c_str(), &optVal)) { - if (optVal.find("?") != 0) { - continue; - } - - std::string eventKey = optVal.substr(1, optVal.length() - 1); - - std::string newStr; - int new_val; - if (__result.get(FACT_KEY_EVENT "." FACT_KEY_DATA, eventKey.c_str(), &newStr)) { - option.set(NULL, optKey.c_str(), newStr); - } else if (__result.get(FACT_KEY_EVENT "." FACT_KEY_DATA, eventKey.c_str(), &new_val)) { - option.set(NULL, optKey.c_str(), new_val); - } else { - _W("Failed to find '%s' in event data", eventKey.c_str()); - return false; - } - } - } - - return true; -} - -void Rule::onEventReceived(std::string name, CtxJson1 option, CtxJson1 data) -{ - if (__result != EMPTY_JSON_OBJECT) { - __clearResult(); - } - - // Check if creator package is uninstalled - if (RuleManager::isUninstalledPackage(pkgId)) { - _D("Creator(%s) of rule%d is uninstalled.", pkgId.c_str(), id); - g_idle_add(__handleUninstalledRule, &pkgId); - return; - } - - _D("Rule%d received event data", id); - - // Set event data - __result.set(FACT_KEY_EVENT, FACT_KEY_NAME, name); - __result.set(FACT_KEY_EVENT, FACT_KEY_OPTION, option); - __result.set(FACT_KEY_EVENT, FACT_KEY_DATA, data); - - if (__condition.size() == 0) { - __onContextDataPrepared(); - return; - } - - IF_FAIL_VOID_TAG(RuleEvaluator::evaluateRule(__statement, __result), _E, "Event not matched"); - - // Request read conditions - for (auto it = __condition.begin(); it != __condition.end(); ++it) { - CtxJson1 condOption = (*it)->option.str(); - if (!__setConditionOptionBasedOnEvent(condOption)) { // condOption should be copy of original option. - __clearResult(); - return; - } - - int error = ContextMonitor::getInstance()->read((*it)->name.c_str(), condOption, this); - IF_FAIL_VOID_TAG(error == ERR_NONE, _E, "Failed to read condition"); - } - - // TODO timer set -} - -void Rule::onConditionReceived(std::string name, CtxJson1 option, CtxJson1 data) -{ - _D("Rule%d received condition data", id); - - // Set condition data - CtxJson1 item; - item.set(NULL, FACT_KEY_NAME, name); - item.set(NULL, FACT_KEY_OPTION, option); - item.set(NULL, FACT_KEY_DATA, data); - __result.append(NULL, FACT_KEY_CONDITION, item); - - if (__result.getSize(NULL, FACT_KEY_CONDITION) == (int) __condition.size()) { - __onContextDataPrepared(); - } -} - -void Rule::__clearResult() -{ - __result = EMPTY_JSON_OBJECT; - // TODO timer cancel -} - -void Rule::__onContextDataPrepared(void) -{ - if (RuleEvaluator::evaluateRule(__statement, __result)) { - action_manager::triggerAction(__action, pkgId); - } - __clearResult(); -} - -gboolean Rule::__handleUninstalledRule(gpointer data) -{ - std::string* pkgId = static_cast(data); - __ruleMgr->handleRuleOfUninstalledPackage(*pkgId); - - return FALSE; -} diff --git a/src/agent/legacy/trigger/Rule.h b/src/agent/legacy/trigger/Rule.h deleted file mode 100644 index cce117a..0000000 --- a/src/agent/legacy/trigger/Rule.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_RULE_H_ -#define _CONTEXT_TRIGGER_RULE_H_ - -#include -#include -#include -#include "IContextListener.h" - -namespace ctx { - -namespace trigger { - - class RuleManager; - - class Rule : public IContextListener { - private: - struct ContextItem { - std::string name; - ctx::CtxJson1 option; - ContextItem(ctx::CtxJson1 item) { - std::list keyList; - item.getKeys(&keyList); - name = *keyList.begin(); - - ctx::CtxJson1 o; - if (item.get(name.c_str(), TRIG_RULE_KEY_OPTION, &o)) - option = o.str(); - } - }; - - ctx::CtxJson1 __statement; - ContextItem* __event; - std::list __condition; - ctx::CtxJson1 __extra; - ctx::CtxJson1 __action; - ctx::CtxJson1 __result; - - static RuleManager* __ruleMgr; - - void __clearResult(void); - bool __setConditionOptionBasedOnEvent(ctx::CtxJson1& option); - void __onContextDataPrepared(void); - - static gboolean __handleUninstalledRule(gpointer data); - - public: - int id; - std::string pkgId; - - Rule(int i, ctx::CtxJson1& d, const char* p, RuleManager* rm); - ~Rule(); - - int start(void); - int stop(void); - - void onEventReceived(std::string name, ctx::CtxJson1 option, ctx::CtxJson1 data); - void onConditionReceived(std::string name, ctx::CtxJson1 option, ctx::CtxJson1 data); - - }; - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_RULE_H_ */ diff --git a/src/agent/legacy/trigger/RuleEvaluator.cpp b/src/agent/legacy/trigger/RuleEvaluator.cpp deleted file mode 100644 index 6dc66b4..0000000 --- a/src/agent/legacy/trigger/RuleEvaluator.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include "RuleEvaluator.h" -#include "FactTypes.h" - -#define OPERATOR_EQ "==" -#define OPERATOR_NEQ "!=" -#define OPERATOR_LEQ "<=" -#define OPERATOR_GEQ ">=" -#define OPERATOR_LT "<" -#define OPERATOR_GT ">" - -using namespace ctx; -using namespace ctx::trigger; - -RuleEvaluator::RuleEvaluator() -{ -} - -template -bool RuleEvaluator::__evaluateSingleData(T factVal, CtxJson1& comparison, std::string op) -{ - T ruleVal; - comparison.get(NULL, TRIG_RULE_KEY_VALUE, &ruleVal); - - if (op == TRIG_RULE_OP_EQUAL_TO) { - return (ruleVal == factVal); - } else if (op == TRIG_RULE_OP_NOT_EQUAL_TO) { - return (ruleVal != factVal); - } else if (op == TRIG_RULE_OP_GREATER_THAN) { - return (ruleVal > factVal); - } else if (op == TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) { - return (ruleVal >= factVal); - } else if (op == TRIG_RULE_OP_LESS_THAN) { - return (ruleVal < factVal); - } else if (op == TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) { - return (ruleVal <= factVal); - } - - return false; -} - -template -bool RuleEvaluator::__evaluateDualData(T factVal, CtxJson1& comparison, std::string op) -{ - T ruleVal1, ruleVal2; - comparison.getAt(NULL, TRIG_RULE_KEY_VALUE, 0, &ruleVal1); - comparison.getAt(NULL, TRIG_RULE_KEY_VALUE, 1, &ruleVal2); - - if (op == TRIG_RULE_OP_IN) { - return (ruleVal1 <= factVal && factVal <= ruleVal2); - } else if (op == TRIG_RULE_OP_NOT_IN) { - return (factVal < ruleVal1 || ruleVal2 < factVal); - } - - return false; -} - -template -bool RuleEvaluator::__evaluateMultipleData(T factVal, CtxJson1& comparison, std::string op) -{ - T ruleVal; - for (int i = 0; comparison.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &ruleVal); i++) { - if (ruleVal == factVal) { - if (op == TRIG_RULE_OP_ONE_OF) { - return true; - } else if (op == TRIG_RULE_OP_NONE_OF) { - return false; - } - } - } - - if (op == TRIG_RULE_OP_NONE_OF) { - return true; - } - - return false; -} - -template -bool RuleEvaluator::__evaluateData(T factVal, CtxJson1& comparison) -{ - std::string op; - comparison.get(NULL, TRIG_RULE_KEY_OPERATOR, &op); - - if (op == TRIG_RULE_OP_EQUAL_TO || op == TRIG_RULE_OP_NOT_EQUAL_TO || - op == TRIG_RULE_OP_GREATER_THAN || op == TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO || - op == TRIG_RULE_OP_LESS_THAN || op == TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) { - return __evaluateSingleData(factVal, comparison, op); - } else if (op == TRIG_RULE_OP_IN || op == TRIG_RULE_OP_NOT_IN) { - return __evaluateDualData(factVal, comparison, op); - } else if (op == TRIG_RULE_OP_ONE_OF || op == TRIG_RULE_OP_NONE_OF) { - return __evaluateMultipleData(factVal, comparison, op); - } - - return false; -} - -void RuleEvaluator::__replaceSingleDataReferences(CtxJson1& eventFactData, CtxJson1& ruleComp, std::string& dataKey) -{ - std::string refVal; - std::string eventRefStr; - int eventRefInt; - - if (!ruleComp.get(dataKey.c_str(), TRIG_RULE_KEY_VALUE, &refVal)) { - return; - } - - if (refVal.substr(0, 1) != TRIG_RULE_REF_KEY_PREFIX) { - return; - } - - std::string eventKey = refVal.substr(1, refVal.length() - 1); - if (eventFactData.get(NULL, eventKey.c_str(), &eventRefStr)) { - ruleComp.set(dataKey.c_str(), TRIG_RULE_KEY_VALUE, eventRefStr); - } else if (eventFactData.get(NULL, eventKey.c_str(), &eventRefInt)) { - ruleComp.set(dataKey.c_str(), TRIG_RULE_KEY_VALUE, eventRefInt); - } else { - _W("Attribute %s not found in event_data", eventKey.c_str()); - } -} - -void RuleEvaluator::__replaceMultipleDataReferences(CtxJson1& eventFactData, CtxJson1& ruleComp, std::string& dataKey) -{ - std::string refVal; - std::string eventRefStr; - int eventRefInt; - - for (int i = 0; ruleComp.getAt(dataKey.c_str(), TRIG_RULE_KEY_VALUE, i, &refVal); i++) { - if (refVal.substr(0, 1) != TRIG_RULE_REF_KEY_PREFIX) { - continue; - } - - std::string eventKey = refVal.substr(1, refVal.length() - 1); - if (eventFactData.get(NULL, eventKey.c_str(), &eventRefStr)) { - ruleComp.setAt(dataKey.c_str(), TRIG_RULE_KEY_VALUE, i, eventRefStr); - } else if (eventFactData.get(NULL, eventKey.c_str(), &eventRefInt)) { - ruleComp.setAt(dataKey.c_str(), TRIG_RULE_KEY_VALUE, i, eventRefInt); - } else { - _W("Attribute %s not found in event_data", eventKey.c_str()); - } - } -} - -void RuleEvaluator::__replaceDataReferences(CtxJson1 eventFactData, CtxJson1& ruleComp) -{ - // Replace referencing data to actual value - std::list compKeys; - ruleComp.getKeys(&compKeys); - - for (auto it = compKeys.begin(); it != compKeys.end(); ++it) { - std::string dataKey = *it; - - std::string op; - ruleComp.get(dataKey.c_str(), TRIG_RULE_KEY_OPERATOR, &op); - - std::string val; - if (op == TRIG_RULE_OP_EQUAL_TO || op == TRIG_RULE_OP_NOT_EQUAL_TO || - op == TRIG_RULE_OP_GREATER_THAN || op == TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO || - op == TRIG_RULE_OP_LESS_THAN || op == TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) { - - __replaceSingleDataReferences(eventFactData, ruleComp, dataKey); - } else { - __replaceMultipleDataReferences(eventFactData, ruleComp, dataKey); - } - } -} - -bool RuleEvaluator::__evaluateItem(CtxJson1& factItem, CtxJson1& ruleItem, std::string logicalOp) -{ - std::string name; - factItem.get(NULL, FACT_KEY_NAME, &name); - - CtxJson1 comparison; - ruleItem.get(name.c_str(), TRIG_RULE_KEY_COMPARISON, &comparison); - - std::list compKeys; - comparison.getKeys(&compKeys); - if (compKeys.size() == 0) { - return true; - } - - bool isConjunction = (TRIG_RULE_LOGICAL_CONJUNCTION == logicalOp); - - for (auto it = compKeys.begin(); it != compKeys.end(); ++it) { - std::string dataKey = *it; - - CtxJson1 comp; - comparison.get(NULL, dataKey.c_str(), &comp); - - std::string factValStr; - int factValInt; - - bool result; - if (factItem.get(FACT_KEY_DATA, dataKey.c_str(), &factValStr)) { - result = __evaluateData(factValStr, comp); - } else if (factItem.get(FACT_KEY_DATA, dataKey.c_str(), &factValInt)) { - result = __evaluateData(factValInt, comp); - } else { - _W("Could not get value corresponding to data key %s", dataKey.c_str()); - result = false; - } - - if (isConjunction && !result) { - return false; - } else if (!isConjunction && result) { - return true; - } - } - return isConjunction; -} - -bool RuleEvaluator::__evaluateRuleEvent(CtxJson1& fact, CtxJson1& rule) -{ - CtxJson1 factItem; - CtxJson1 ruleItem; - fact.get(NULL, FACT_KEY_EVENT, &factItem); - rule.get(NULL, TRIG_RULE_KEY_EVENT, &ruleItem); - - std::string eventOp; - rule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, &eventOp); - - return __evaluateItem(factItem, ruleItem, eventOp); -} - -CtxJson1 RuleEvaluator::__getConditionFact(CtxJson1& fact, CtxJson1& ruleCond) -{ - std::list condKey; - ruleCond.getKeys(&condKey); - std::string ruleCondName = *(condKey.begin()); - - CtxJson1 factCond; - for (int i = 0; fact.getAt(NULL, FACT_KEY_CONDITION, i, &factCond); i++) { - // Check if fact item name is matched with condition - std::string factCondName; - factCond.get(NULL, FACT_KEY_NAME, &factCondName); - if (factCondName != ruleCondName) { - continue; - } - - // Check if fact item option is mathced with condition - CtxJson1 ruleCondOption; - CtxJson1 factCondOption; - ruleCond.get(ruleCondName.c_str(), TRIG_RULE_KEY_OPTION, &ruleCondOption); - factCond.get(NULL, FACT_KEY_OPTION, &factCondOption); - if (factCondOption == ruleCondOption) { - return factCond; - } - } - - _W(YELLOW("find condition failed for condition")); - return EMPTY_JSON_OBJECT; -} - -bool RuleEvaluator::__evaluateRuleCondition(CtxJson1& fact, CtxJson1& rule) -{ - std::string ruleOp; - rule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, &ruleOp); - bool isConjunction = (TRIG_RULE_LOGICAL_CONJUNCTION == ruleOp); - - CtxJson1 ruleCond; - for (int i = 0; rule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &ruleCond); i++) { - CtxJson1 factCond = __getConditionFact(fact, ruleCond); - - bool result; - if (factCond == EMPTY_JSON_OBJECT) { - result = false; - } else { - std::string condOp; - rule.getAt(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, i, &condOp); - result = __evaluateItem(factCond, ruleCond, condOp); - } - - if (isConjunction && !result) { - return false; - } else if (!isConjunction && result) { - return true; - } - } - - return isConjunction; -} - -bool RuleEvaluator::__replaceOptionReferences(CtxJson1 eventFactData, CtxJson1& ruleOption) -{ - // Replace referencing option to actual value - std::string refVal; - std::string eventRefStr; - int eventRefInt; - - std::list keyList; - ruleOption.getKeys(&keyList); - - for (std::list::iterator it = keyList.begin(); it != keyList.end(); ++it) { - std::string optionKey = *it; - - if (!ruleOption.get(NULL, optionKey.c_str(), &refVal)) { - continue; - } - if (!(refVal.substr(0, 1) == TRIG_RULE_REF_KEY_PREFIX)) { - continue; - } - - std::string eventKey = refVal.substr(1, refVal.length() - 1); - if (eventFactData.get(NULL, eventKey.c_str(), &eventRefStr)) { - ruleOption.set(NULL, optionKey.c_str(), eventRefStr); - } else if (eventFactData.get(NULL, eventKey.c_str(), &eventRefInt)) { - ruleOption.set(NULL, optionKey.c_str(), eventRefInt); - } else { - _W("Option %s not found in event_data", eventKey.c_str()); - return false; - } - } - - return true; -} - -bool RuleEvaluator::__replaceEventReferences(CtxJson1& fact, CtxJson1& rule) -{ - // Replace referencing data/option to actual value - CtxJson1 eventFactData; - if (!fact.get(FACT_KEY_EVENT, FACT_KEY_DATA, &eventFactData)) { - _E("No event data found, error"); - return false; - } - - CtxJson1 ruleCond; - for (int i = 0; rule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &ruleCond); i++) { - std::list condKey; - ruleCond.getKeys(&condKey); - std::string ruleCondName = *(condKey.begin()); - - CtxJson1 ruleComp; - for (int j = 0; ruleCond.getAt(ruleCondName.c_str(), TRIG_RULE_KEY_COMPARISON, j, &ruleComp); j++) { - __replaceDataReferences(eventFactData, ruleComp); - } - - CtxJson1 ruleOption; - if (ruleCond.get(ruleCondName.c_str(), TRIG_RULE_KEY_OPTION, &ruleOption)) { - __replaceOptionReferences(eventFactData, ruleOption); - } - } - - return true; -} - -bool RuleEvaluator::evaluateRule(CtxJson1 rule, CtxJson1 fact) -{ - _D("Rule is %s ", rule.str().c_str()); - _D("fact is %s ", fact.str().c_str()); - - RuleEvaluator eval; - bool ret; - CtxJson1 tempJson; - if (fact.get(NULL, FACT_KEY_CONDITION, &tempJson)) { - CtxJson1 ruleCopy(rule.str()); - if (!eval.__replaceEventReferences(fact, ruleCopy)) { - _W("Replace failed"); - } - ret = eval.__evaluateRuleCondition(fact, ruleCopy); - _D("Checking condition %s", ret ? "true" : "false"); - } else { - ret = eval.__evaluateRuleEvent(fact, rule); - _D("Checking event %s", ret ? "true" : "false"); - } - - return ret; -} diff --git a/src/agent/legacy/trigger/RuleEvaluator.h b/src/agent/legacy/trigger/RuleEvaluator.h deleted file mode 100644 index e9c0370..0000000 --- a/src/agent/legacy/trigger/RuleEvaluator.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_RULE_EVALUATOR_H_ -#define _CONTEXT_TRIGGER_RULE_EVALUATOR_H_ - -namespace ctx { - - class CtxJson1; - -namespace trigger { - - class RuleEvaluator { - private: - RuleEvaluator(); - - bool __evaluateRuleEvent(ctx::CtxJson1& fact, ctx::CtxJson1& rule); - bool __evaluateRuleCondition(ctx::CtxJson1& fact, ctx::CtxJson1& rule); - bool __evaluateItem(ctx::CtxJson1& factItem, ctx::CtxJson1& ruleItem, std::string logicalOp); - template bool __evaluateData(T factVal, CtxJson1& comparison); - template bool __evaluateSingleData(T factVal, CtxJson1& comparison, std::string op); - template bool __evaluateDualData(T factVal, CtxJson1& comparison, std::string op); - template bool __evaluateMultipleData(T factVal, CtxJson1& comparison, std::string op); - - ctx::CtxJson1 __getConditionFact(ctx::CtxJson1& fact, ctx::CtxJson1& ruleCond); - - bool __replaceEventReferences(ctx::CtxJson1& fact, ctx::CtxJson1& rule); - void __replaceDataReferences(ctx::CtxJson1 eventFactData, ctx::CtxJson1& ruleComp); - void __replaceSingleDataReferences(ctx::CtxJson1& eventFactData, ctx::CtxJson1& ruleComp, std::string& dataKey); - void __replaceMultipleDataReferences(ctx::CtxJson1& eventFactData, ctx::CtxJson1& ruleComp, std::string& dataKey); - bool __replaceOptionReferences(ctx::CtxJson1 eventFactData, ctx::CtxJson1& ruleOption); - - public: - static bool evaluateRule(ctx::CtxJson1 rule, ctx::CtxJson1 data); - }; - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_RULE_EVALUATOR_H_ */ diff --git a/src/agent/legacy/trigger/RuleManager.cpp b/src/agent/legacy/trigger/RuleManager.cpp deleted file mode 100644 index 5386cef..0000000 --- a/src/agent/legacy/trigger/RuleManager.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include "RuleManager.h" -#include "ContextMonitor.h" -#include "Rule.h" - -#define RULE_TABLE "ContextTriggerRule" -#define RULE_IDS_JSON "{ \"" TRIG_KEY_ENABLED_IDS "\" : [ ] , \"" TRIG_KEY_DISABLED_IDS "\" : [ ] }"; - -using namespace ctx; -using namespace ctx::trigger; - -static int __stringToInt(std::string str) -{ - int i; - std::istringstream convert(str); - - if (!(convert >> i)) - i = 0; - - return i; -} - -static std::string __intToString(int i) -{ - std::ostringstream convert; - convert << i; - std::string str = convert.str(); - return str; -} - -RuleManager::RuleManager() -{ -} - -RuleManager::~RuleManager() -{ - // Release rule instances - _D("Release rule instances"); - for (auto it = __ruleMap.begin(); it != __ruleMap.end(); ++it) { - Rule* rule = static_cast(it->second); - - int error = rule->stop(); - if (error != ERR_NONE) { - _E("Failed to stop rule%d", it->first); - } - - delete rule; - } - __ruleMap.clear(); -} - -bool RuleManager::init() -{ - bool ret; - int error; - - // Create tables into db (rule, template) - std::string q1 = std::string("status INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL,") - + "packageId TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT ''," - + "details TEXT DEFAULT '' NOT NULL"; - ret = __dbManager.createTableSync(RULE_TABLE, q1.c_str(), NULL); - IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed"); - - // Before re-enable rules, handle uninstalled app's rules - if (__getUninstalledApp() > 0) { - error = __clearRuleOfUninstalledPackage(true); - IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization"); - } - ret = __reenableRule(); - - return ret; -} - -void RuleManager::handleRuleOfUninstalledPackage(std::string pkgId) -{ - __uninstalledPackages.insert(pkgId); - __clearRuleOfUninstalledPackage(); -} - -int RuleManager::__getUninstalledApp(void) -{ - // Return number of uninstalled apps - std::string q1 = "SELECT DISTINCT packageId FROM ContextTriggerRule"; - - std::vector record; - bool ret = __dbManager.executeSync(q1.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, -1, _E, "Query package ids of registered rules failed"); - - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - std::string pkgId; - elem.get(NULL, "packageId", &pkgId); - - if (isUninstalledPackage(pkgId)) { - __uninstalledPackages.insert(pkgId); - } - } - - return __uninstalledPackages.size(); -} - -bool RuleManager::isUninstalledPackage(std::string pkgId) -{ - IF_FAIL_RETURN_TAG(!pkgId.empty(), false, _D, "Empty package id"); - - package_info_h pkgInfo; - int error = package_manager_get_package_info(pkgId.c_str(), &pkgInfo); - - if (error == PACKAGE_MANAGER_ERROR_NONE) { - package_info_destroy(pkgInfo); - } else if (error == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) { - // Uninstalled package found - _D("Uninstalled package found: %s", pkgId.c_str()); - return true; - } else { - _E("Failed to get package info(%s): %d", pkgId.c_str(), error); - } - - return false; -} - -int RuleManager::__clearRuleOfUninstalledPackage(bool isInit) -{ - if (__uninstalledPackages.size() <= 0) { - return ERR_NONE; - } - - int error; - bool ret; - - _D("Clear uninstalled packages' rule started"); - // Package list - std::string pkgList = "("; - std::set::iterator it = __uninstalledPackages.begin(); - pkgList += "packageId = '" + *it + "'"; - it++; - for (; it != __uninstalledPackages.end(); ++it) { - pkgList += " OR packageId = '" + *it + "'"; - } - pkgList += ")"; - - // After event received, disable all the enabled rules of uninstalled apps - if (!isInit) { - std::string q1 = "SELECT rowId FROM ContextTriggerRule WHERE status = 2 and ("; - q1 += pkgList; - q1 += ")"; - - std::vector record; - ret = __dbManager.executeSync(q1.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query enabled rules of uninstalled packages"); - - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - int ruleId; - elem.get(NULL, "rowId", &ruleId); - error = disableRule(ruleId); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule"); - } - _D("Uninstalled packages' rules are disabled"); - } - - // Delete rules of uninstalled packages from DB - std::string q2 = "DELETE FROM ContextTriggerRule WHERE " + pkgList; - std::vector dummy; - ret = __dbManager.executeSync(q2.c_str(), &dummy); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to remove rules from db"); - _D("Uninstalled packages' rules are deleted from db"); - - __uninstalledPackages.clear(); - - return ERR_NONE; -} - -int RuleManager::pauseRuleWithItem(std::string& subject) -{ - std::string q = "SELECT rowId FROM ContextTriggerRule WHERE (status=2) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');"; - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query rowIds to be paused"); - IF_FAIL_RETURN(record.size() > 0, ERR_NONE); - - _D("Pause rules related to %s", subject.c_str()); - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - int rowId; - elem.get(NULL, "rowId", &rowId); - - int error = pauseRule(rowId); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules using custom item"); - } - - return ERR_NONE; -} - -int RuleManager::resumeRuleWithItem(std::string& subject) -{ - std::string q = "SELECT rowId FROM ContextTriggerRule WHERE (status=1) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');"; - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query paused rule ids failed"); - IF_FAIL_RETURN(record.size() > 0, ERR_NONE); - - _D("Resume rules related to %s", subject.c_str()); - std::string qRowId; - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - int rowId; - elem.get(NULL, "rowId", &rowId); - - int error = enableRule(rowId); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to resume rule"); - } - - return ERR_NONE; -} - -bool RuleManager::__reenableRule(void) -{ - int error; - std::string q = "SELECT rowId FROM ContextTriggerRule WHERE status = 2"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query rowIds of enabled rules failed"); - IF_FAIL_RETURN_TAG(record.size() > 0, true, _D, "No rule to re-enable"); - - _D(YELLOW("Re-enable rule started")); - - std::string qRowId; - qRowId.clear(); - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - int rowId; - elem.get(NULL, "rowId", &rowId); - - error = enableRule(rowId); - if (error == ERR_NOT_SUPPORTED) { - qRowId += "(rowId = " + __intToString(rowId) + ") OR "; - } else if (error != ERR_NONE) { - _E("Re-enable rule%d failed(%d)", rowId, error); - } - } - IF_FAIL_RETURN(!qRowId.empty(), true); - qRowId = qRowId.substr(0, qRowId.length() - 4); - - // For rules which is failed to re-enable - std::string qUpdate = "UPDATE ContextTriggerRule SET status = 1 WHERE " + qRowId; - std::vector record2; - ret = __dbManager.executeSync(qUpdate.c_str(), &record2); - IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update rules as paused"); - - return true; -} - -bool RuleManager::__ruleEquals(CtxJson1& lRule, CtxJson1& rRule) -{ - // Compare event - CtxJson1 lEvent, rEvent; - lRule.get(NULL, TRIG_RULE_KEY_EVENT, &lEvent); - rRule.get(NULL, TRIG_RULE_KEY_EVENT, &rEvent); - - std::string lEOp, rEOp; - lRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, &lEOp); - rRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, &rEOp); - - if (lEOp != rEOp || lEvent != rEvent) - return false; - - // Compare conditions - int lCondCnt, rCondCnt; - lCondCnt = lRule.getSize(NULL, TRIG_RULE_KEY_CONDITION); - rCondCnt = rRule.getSize(NULL, TRIG_RULE_KEY_CONDITION); - if (lCondCnt != rCondCnt) - return false; - - std::string lOp, rOp; - lRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, &lOp); - rRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, &rOp); - if (lOp != rOp) - return false; - - for (int i = 0; i < lCondCnt; i++) { - bool found = false; - CtxJson1 lCond; - lRule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &lCond); - - std::string lCOp; - lRule.getAt(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, i, &lCOp); - - for (int j = 0; j < lCondCnt; j++) { - CtxJson1 rCond; - rRule.getAt(NULL, TRIG_RULE_KEY_CONDITION, j, &rCond); - - std::string rCOp; - rRule.getAt(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, j, &rCOp); - - if (lCOp == rCOp && lCond == rCond) { - found = true; - break; - } - } - if (!found) - return false; - } - - // Compare action - CtxJson1 lAction, rAction; - lRule.get(NULL, TRIG_RULE_KEY_ACTION, &lAction); - rRule.get(NULL, TRIG_RULE_KEY_ACTION, &rAction); - if (lAction != rAction) - return false; - - return true; -} - -int64_t RuleManager::__getDuplicatedRuleId(std::string pkgId, CtxJson1& rule) -{ - std::string q = "SELECT rowId, description, details FROM ContextTriggerRule WHERE packageId = '"; - q += pkgId; - q += "'"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query rowId, details by package id failed"); - - std::string rDesc; - rule.get(NULL, TRIG_RULE_KEY_DESCRIPTION, &rDesc); - CtxJson1 rDetails = rule.str(); - rDetails.remove(NULL, TRIG_RULE_KEY_DESCRIPTION); - - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - std::string dStr; - CtxJson1 details; - - elem.get(NULL, "details", &dStr); - details = dStr; - - if (__ruleEquals(rDetails, details)) { - int64_t rowId; - elem.get(NULL, "rowId", &rowId); - - // Description comparison - std::string desc; - elem.get(NULL, "description", &desc); - if (rDesc.compare(desc)) { - // Only description is changed - std::string qUpdate = "UPDATE ContextTriggerRule SET description='" + rDesc + "' WHERE rowId = " + __intToString(rowId); - - std::vector dummy; - ret = __dbManager.executeSync(qUpdate.c_str(), &dummy); - if (ret) { - _D("Rule%lld description is updated", rowId); - } else { - _W("Failed to update description of rule%lld", rowId); - } - } - - return rowId; - } - } - - return -1; -} - -int RuleManager::__verifyRule(CtxJson1& rule, const char* creator) -{ - ContextMonitor* ctxMonitor = ContextMonitor::getInstance(); - IF_FAIL_RETURN_TAG(ctxMonitor, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed"); - - // Event - CtxJson1 event; - rule.get(NULL, TRIG_RULE_KEY_EVENT, &event); - - std::list eventKey; - event.getKeys(&eventKey); - IF_FAIL_RETURN_TAG(eventKey.size() == 1, ERR_INVALID_PARAMETER, _E, "Invalid event"); - - std::string eventName = *eventKey.begin(); - IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(eventName), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", eventName.c_str()); - - if (!ctxMonitor->isAllowed(creator, eventName.c_str())) { - _W("Permission denied for '%s'", eventName.c_str()); - return ERR_PERMISSION_DENIED; - } - - // Conditions - CtxJson1 cond; - for (int i = 0; rule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &cond); i++) { - std::list condKey; - cond.getKeys(&condKey); - IF_FAIL_RETURN_TAG(condKey.size() == 1, ERR_INVALID_PARAMETER, _E, "Invalid condition"); - - std::string condName = *condKey.begin(); - IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(condName), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", condName.c_str()); - - if (!ctxMonitor->isAllowed(creator, condName.c_str())) { - _W("Permission denied for '%s'", condName.c_str()); - return ERR_PERMISSION_DENIED; - } - } - - return ERR_NONE; -} - -int RuleManager::addRule(std::string creator, const char* pkgId, CtxJson1 rule, CtxJson1* ruleId) -{ - bool ret; - int64_t rid; - - // Check if all items are supported && allowed to access - int err = __verifyRule(rule, creator.c_str()); - IF_FAIL_RETURN(err == ERR_NONE, err); - - // Check if duplicated rule exits - if ((rid = __getDuplicatedRuleId(pkgId, rule)) > 0) { - // Save rule id - ruleId->set(NULL, TRIG_KEY_RULE_ID, rid); - _D("Duplicated rule found"); - return ERR_NONE; - } - - // Insert rule to rule table, get rule id - CtxJson1 record; - std::string description; - rule.get(NULL, TRIG_RULE_KEY_DESCRIPTION, &description); - - CtxJson1 details = rule.str(); - details.remove(NULL, TRIG_RULE_KEY_DESCRIPTION); - record.set(NULL, "details", details.str()); - - record.set(NULL, "creator", creator); - if (pkgId) { - record.set(NULL, "packageId", pkgId); - } - record.set(NULL, "description", description); - - ret = __dbManager.insertSync(RULE_TABLE, record, &rid); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert rule to db failed"); - - // Save rule id - ruleId->set(NULL, TRIG_KEY_RULE_ID, rid); - - _D("Add rule%d succeeded", (int)rid); - return ERR_NONE; -} - - -int RuleManager::removeRule(int ruleId) -{ - bool ret; - - // Delete rule from DB - std::string query = "DELETE FROM 'ContextTriggerRule' where rowId = "; - query += __intToString(ruleId); - - std::vector record; - ret = __dbManager.executeSync(query.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Remove rule from db failed"); - - _D("Remove rule%d succeeded", ruleId); - - return ERR_NONE; -} - -int RuleManager::enableRule(int ruleId) -{ - int error; - std::string query; - std::vector record; - std::vector dummy; - std::string pkgId; - CtxJson1 jRule; - std::string tmp; - std::string idStr = __intToString(ruleId); - - Rule* rule; - - // Get rule CtxJson1 by rule id; - query = "SELECT details, packageId FROM ContextTriggerRule WHERE rowId = "; - query += idStr; - error = (__dbManager.executeSync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed"); - - record[0].get(NULL, "details", &tmp); - jRule = tmp; - record[0].get(NULL, "packageId", &pkgId); - - // Create a rule instance - rule = new(std::nothrow) Rule(ruleId, jRule, pkgId.c_str(), this); - IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance"); - - // Start the rule - error = rule->start(); - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", ruleId); - - // Update db to set 'enabled' - query = "UPDATE ContextTriggerRule SET status = 2 WHERE rowId = "; - query += idStr; - error = (__dbManager.executeSync(query.c_str(), &dummy))? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed"); - - // Add rule instance to __ruleMap - __ruleMap[ruleId] = rule; - - _D(YELLOW("Enable Rule%d succeeded"), ruleId); - return ERR_NONE; - -CATCH: - delete rule; - rule = NULL; - - return error; -} - -int RuleManager::disableRule(int ruleId) -{ - bool ret; - int error; - - auto it = __ruleMap.find(ruleId); - bool paused = (it == __ruleMap.end()); - - // For 'enabled' rule, not 'paused' - if (!paused) { - // Stop the rule - Rule* rule = static_cast(it->second); - error = rule->stop(); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId); - - // Remove rule instance from __ruleMap - delete rule; - __ruleMap.erase(it); - } - - // Update db to set 'disabled' // TODO skip while clear uninstalled rule - std::string query = "UPDATE ContextTriggerRule SET status = 0 WHERE rowId = "; - query += __intToString(ruleId); - std::vector record; - ret = __dbManager.executeSync(query.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed"); - - _D(YELLOW("Disable Rule%d succeeded"), ruleId); - return ERR_NONE; -} - -int RuleManager::pauseRule(int ruleId) -{ - bool ret; - int error; - - auto it = __ruleMap.find(ruleId); - IF_FAIL_RETURN_TAG(it != __ruleMap.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found"); - - // Stop the rule - Rule* rule = static_cast(it->second); - error = rule->stop(); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId); - - // Update db to set 'paused' - std::string query = "UPDATE ContextTriggerRule SET status = 1 WHERE rowId = "; - - query += __intToString(ruleId); - std::vector record; - ret = __dbManager.executeSync(query.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed"); - - // Remove rule instance from __ruleMap - delete rule; - __ruleMap.erase(it); - - _D(YELLOW("Pause Rule%d"), ruleId); - return ERR_NONE; -} - -int RuleManager::checkRule(std::string pkgId, int ruleId) -{ - // Get package id - std::string q = "SELECT packageId FROM ContextTriggerRule WHERE rowId ="; - q += __intToString(ruleId); - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query package id by rule id failed"); - - if (record.size() == 0) { - return ERR_NO_DATA; - } - - std::string p; - record[0].get(NULL, "packageId", &p); - - if (p.compare(pkgId) == 0) { - return ERR_NONE; - } - - return ERR_NO_DATA; -} - -bool RuleManager::isRuleEnabled(int ruleId) -{ - std::string q = "SELECT status FROM ContextTriggerRule WHERE rowId ="; - q += __intToString(ruleId); - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query enabled by rule id failed"); - - int status; - record[0].get(NULL, "status", &status); - - return (status != 0); -} - -int RuleManager::getRuleById(std::string pkgId, int ruleId, CtxJson1* requestResult) -{ - std::string q = "SELECT description FROM ContextTriggerRule WHERE (packageId = '"; - q += pkgId; - q += "') and (rowId = "; - q += __intToString(ruleId); - q += ")"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query rule by rule id failed"); - - if (record.size() == 0) { - return ERR_NO_DATA; - } else if (record.size() != 1) { - return ERR_OPERATION_FAILED; - } - - std::string description; - record[0].get(NULL, "description", &description); - - (*requestResult).set(NULL, TRIG_KEY_RULE_ID, ruleId); - (*requestResult).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description); - - return ERR_NONE; -} - -int RuleManager::getRuleIds(std::string pkgId, CtxJson1* requestResult) -{ - (*requestResult) = RULE_IDS_JSON; - - std::string q = "SELECT rowId, status FROM ContextTriggerRule WHERE (packageId = '"; - q += pkgId; - q += "')"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rules failed"); - - std::vector::iterator vecEnd = record.end(); - for (std::vector::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) { - CtxJson1 elem = *vecPos; - std::string id; - int status; - - elem.get(NULL, "rowId", &id); - elem.get(NULL, "status", &status); - - if (status >= 1) { - (*requestResult).append(NULL, TRIG_KEY_ENABLED_IDS, __stringToInt(id)); - } else if (status == 0) { - (*requestResult).append(NULL, TRIG_KEY_DISABLED_IDS, __stringToInt(id)); - } - } - - return ERR_NONE; -} diff --git a/src/agent/legacy/trigger/RuleManager.h b/src/agent/legacy/trigger/RuleManager.h deleted file mode 100644 index 2187aa2..0000000 --- a/src/agent/legacy/trigger/RuleManager.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_RULE_MANAGER_H_ -#define _CONTEXT_TRIGGER_RULE_MANAGER_H_ - -#include -#include -#include - -namespace ctx { - - class CtxJson1; - -namespace trigger { - - class Trigger; - class Rule; - - class RuleManager { - public: - RuleManager(); - ~RuleManager(); - - bool init(); - int addRule(std::string creator, const char* pkgId, CtxJson1 rule, CtxJson1* ruleId); - int removeRule(int ruleId); - int enableRule(int ruleId); - int disableRule(int ruleId); - int getRuleById(std::string pkgId, int ruleId, CtxJson1* requestResult); - int getRuleIds(std::string pkgId, CtxJson1* requestResult); - int checkRule(std::string pkgId, int ruleId); - bool isRuleEnabled(int ruleId); - int pauseRuleWithItem(std::string& subject); - int pauseRule(int ruleId); - int resumeRuleWithItem(std::string& subject); - void handleRuleOfUninstalledPackage(std::string pkgId); - - static bool isUninstalledPackage(std::string pkgId); - - private: - bool __reenableRule(void); - int __verifyRule(CtxJson1& rule, const char* creator); - int64_t __getDuplicatedRuleId(std::string pkgId, CtxJson1& rule); - bool __ruleEquals(CtxJson1& lRule, CtxJson1& rRule); - int __getUninstalledApp(void); - int __clearRuleOfUninstalledPackage(bool isInit = false); - void __applyTemplates(void); - - std::set __uninstalledPackages; - std::map __ruleMap; - DatabaseManager __dbManager; - }; /* class RuleManager */ - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_RULE_MANAGER_H_ */ diff --git a/src/agent/legacy/trigger/TemplateManager.cpp b/src/agent/legacy/trigger/TemplateManager.cpp deleted file mode 100644 index 6a952a1..0000000 --- a/src/agent/legacy/trigger/TemplateManager.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include -#include "../ContextManager.h" -#include "RuleManager.h" -#include "TemplateManager.h" - -using namespace ctx; -using namespace ctx::trigger; - -TemplateManager *TemplateManager::__instance = NULL; -ContextManager *TemplateManager::__contextMgr = NULL; -RuleManager *TemplateManager::__ruleMgr = NULL; - -static std::string __intToString(int i) -{ - std::ostringstream convert; - convert << i; - std::string str = convert.str(); - return str; -} - -TemplateManager::TemplateManager() -{ -} - -TemplateManager::~TemplateManager() -{ -} - -void TemplateManager::setManager(ContextManager* ctxMgr, RuleManager* ruleMgr) -{ - __contextMgr = ctxMgr; - __ruleMgr = ruleMgr; -} - -TemplateManager* TemplateManager::getInstance() -{ - IF_FAIL_RETURN_TAG(__contextMgr, NULL, _E, "Context manager is needed"); - IF_FAIL_RETURN_TAG(__ruleMgr, NULL, _E, "Rule manager is needed"); - - IF_FAIL_RETURN(!__instance, __instance); - - __instance = new(std::nothrow) TemplateManager(); - IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory alllocation failed"); - - return __instance; -} - -void TemplateManager::destroy() -{ - IF_FAIL_VOID(__instance); - - __instance->applyTemplates(); - - delete __instance; - __instance = NULL; -} - -bool TemplateManager::init() -{ - std::string q = std::string("CREATE TABLE IF NOT EXISTS ContextTriggerTemplate ") - + "(name TEXT DEFAULT '' NOT NULL PRIMARY KEY, operation INTEGER DEFAULT 3 NOT NULL, " - + "attributes TEXT DEFAULT '' NOT NULL, options TEXT DEFAULT '' NOT NULL, owner TEXT DEFAULT '' NOT NULL)"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed"); - - // Apply templates - applyTemplates(); - - return true; -} - -void TemplateManager::applyTemplates() -{ - std::string subject; - int operation; - CtxJson1 attributes; - CtxJson1 options; - std::string owner; - std::string query; - query.clear(); - - while (__contextMgr->popTriggerTemplate(subject, operation, attributes, options)) { - registerTemplate(subject, operation, attributes, options, ""); - } -} - -void TemplateManager::registerTemplate(std::string subject, int operation, CtxJson1 attributes, CtxJson1 options, std::string owner) -{ - _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str()); - _J("Attr", attributes); - _J("Opt", options); - - std::string query = "UPDATE ContextTriggerTemplate SET operation=" + __intToString(operation) - + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner - + "' WHERE name='" + subject + "'; "; - - query += "INSERT OR IGNORE INTO ContextTriggerTemplate (name, operation, attributes, options, owner) VALUES ('" - + subject + "', " + __intToString(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '" - + owner + "'); "; - - std::vector record; - bool ret = __dbManager.executeSync(query.c_str(), &record); - IF_FAIL_VOID_TAG(ret, _E, "Update template db failed"); - - if (!owner.empty()) { - __ruleMgr->resumeRuleWithItem(subject); - } -} - -void TemplateManager::unregisterTemplate(std::string subject) -{ - _D("[Remove template] Subject: %s", subject.c_str()); - std::string query = "DELETE FROM ContextTriggerTemplate WHERE name = '" + subject + "'; "; - - std::vector record; - bool ret = __dbManager.executeSync(query.c_str(), &record); - IF_FAIL_VOID_TAG(ret, _E, "Update template db failed"); - - __ruleMgr->pauseRuleWithItem(subject); -} - - -std::string TemplateManager::__addTemplate(std::string &subject, int &operation, CtxJson1 &attributes, CtxJson1 &options, std::string &owner) -{ - _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str()); - _J("Attr", attributes); - _J("Opt", options); - - std::string query = "UPDATE ContextTriggerTemplate SET operation=" + __intToString(operation) - + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner - + "' WHERE name='" + subject + "'; "; - - query += "INSERT OR IGNORE INTO ContextTriggerTemplate (name, operation, attributes, options, owner) VALUES ('" - + subject + "', " + __intToString(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '" - + owner + "'); "; - - return query; -} - -std::string TemplateManager::__removeTemplate(std::string &subject) -{ - _D("[Remove template] Subject: %s", subject.c_str()); - std::string query = "DELETE FROM ContextTriggerTemplate WHERE name = '" + subject + "'; "; - - return query; -} - -int TemplateManager::getTemplate(std::string &subject, CtxJson1* tmpl) -{ - if (!__contextMgr->isSupported(subject.c_str())) - return ERR_NOT_SUPPORTED; - - // Update latest template information - std::string q = "SELECT * FROM ContextTriggerTemplate WHERE name = '" + subject + "'"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query template failed"); - IF_FAIL_RETURN_TAG(record.size() > 0, ERR_NOT_SUPPORTED, _E, "Template(%s) not found", subject.c_str()); - IF_FAIL_RETURN_TAG(record.size() == 1, ERR_OPERATION_FAILED, _E, "Tepmlate duplicated"); - - (*tmpl) = *record.begin(); - - std::string optStr; - std::string attrStr; - tmpl->get(NULL, TRIG_TMPL_KEY_OPTION, &optStr); - tmpl->get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attrStr); - - CtxJson1 opt = optStr; - CtxJson1 attr = attrStr; - - tmpl->set(NULL, TRIG_TMPL_KEY_OPTION, opt); - tmpl->set(NULL, TRIG_TMPL_KEY_ATTRIBUTE, attr); - - return ERR_NONE; -} diff --git a/src/agent/legacy/trigger/TemplateManager.h b/src/agent/legacy/trigger/TemplateManager.h deleted file mode 100644 index 69c0e06..0000000 --- a/src/agent/legacy/trigger/TemplateManager.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_ -#define _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_ - -#include -#include - -namespace ctx { - - class ContextManager; - -namespace trigger { - - class RuleManager; - - class TemplateManager { - public: - static TemplateManager* getInstance(); - static void setManager(ContextManager* ctxMgr, RuleManager* ruleMgr); - static void destroy(); - - bool init(); - void applyTemplates(); - int getTemplate(std::string &subject, CtxJson1* tmpl); - void registerTemplate(std::string subject, int operation, CtxJson1 attributes, CtxJson1 options, std::string owner); - void unregisterTemplate(std::string subject); - - private: - TemplateManager(); - TemplateManager(const TemplateManager& other); - ~TemplateManager(); - - static TemplateManager *__instance; - static ContextManager *__contextMgr; - static RuleManager *__ruleMgr; - - DatabaseManager __dbManager; - - std::string __addTemplate(std::string &subject, int &operation, CtxJson1 &attributes, CtxJson1 &options, std::string &owner); - std::string __removeTemplate(std::string &subject); - - }; /* class TemplateManager */ - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_ */ diff --git a/src/agent/legacy/trigger/Trigger.cpp b/src/agent/legacy/trigger/Trigger.cpp deleted file mode 100644 index 762bdea..0000000 --- a/src/agent/legacy/trigger/Trigger.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#include -#include -#include "Trigger.h" -#include "ContextMonitor.h" -#include "TemplateManager.h" -#include "RuleManager.h" - -using namespace ctx; -using namespace ctx::trigger; - -Trigger::Trigger() : - __ruleMgr(NULL) -{ -} - -Trigger::~Trigger() -{ -} - -bool Trigger::init(ContextManager* ctxMgr) -{ - // Do the necessary initialization process. - // This function is called from the main thread during the service launching process. - _D("Context Trigger Init"); - __processInitialize(ctxMgr); - - return true; -} - -void Trigger::release() -{ - // Release the occupied resources. - // This function is called from the main thread during the service termination process. - - _D("Template Manager Destroy"); - TemplateManager::destroy(); - - _D("Rule Manager Release"); - delete __ruleMgr; - __ruleMgr = NULL; - - _D("Context Monitor Destroy"); - ContextMonitor::destroy(); -} - -bool Trigger::assignRequest(RequestInfo* request) -{ - std::string subject = request->getSubject(); - if (subject != SUBJ_TRIGGER_ADD && subject != SUBJ_TRIGGER_REMOVE && - subject != SUBJ_TRIGGER_ENABLE && subject != SUBJ_TRIGGER_DISABLE && - subject != SUBJ_TRIGGER_GET && subject != SUBJ_TRIGGER_GET_RULE_IDS && - subject != SUBJ_TRIGGER_GET_TEMPLATE) { - return false; - } - - __processRequest(request); - return true; -} - -void Trigger::__processRequest(RequestInfo* request) -{ - // Process the request, and reply to the client if necessary. - const char* reqSubj = request->getSubject(); - _D("Request is %s", reqSubj); - std::string subject(reqSubj); - - if (subject == SUBJ_TRIGGER_ADD) { - __addRule(request); - } else if (subject == SUBJ_TRIGGER_REMOVE) { - __removeRule(request); - } else if (subject == SUBJ_TRIGGER_ENABLE) { - __enableRule(request); - } else if (subject == SUBJ_TRIGGER_DISABLE) { - __disableRule(request); - } else if (subject == SUBJ_TRIGGER_GET) { - __getRuleById(request); - } else if (subject == SUBJ_TRIGGER_GET_RULE_IDS) { - __getRuleIds(request); - } else if (subject == SUBJ_TRIGGER_GET_TEMPLATE) { - __getTemplate(request); - } else { - _E("Invalid request"); - } - - delete request; -} - -void Trigger::__processInitialize(ContextManager* mgr) -{ - // Context Monitor - ContextMonitor::setContextManager(mgr); - - // Rule Manager - __ruleMgr = new(std::nothrow) RuleManager(); - IF_FAIL_VOID_TAG(__ruleMgr, _E, "Memory allocation failed"); - - // Template Manager - TemplateManager::setManager(mgr, __ruleMgr); - TemplateManager* tmplMgr = TemplateManager::getInstance(); - IF_FAIL_VOID_TAG(tmplMgr, _E, "Memory allocation failed"); - - // Initialization - if (!tmplMgr->init()) { - _E("Template manager initialization failed"); - raise(SIGTERM); - } - - if (!__ruleMgr->init()) { - _E("Context trigger initialization failed"); - raise(SIGTERM); - } -} - -void Trigger::__addRule(RequestInfo* request) -{ - CtxJson1 ruleId; - - const char* client = request->getClient(); - if (client == NULL) { - request->reply(ERR_OPERATION_FAILED); - return; - } - - const char* pkgId = request->getPackageId(); - - int error = __ruleMgr->addRule(client, pkgId, request->getDescription(), &ruleId); - _I("'%s' adds a rule (Error: %#x)", request->getClient(), error); - - request->reply(error, ruleId); -} - -void Trigger::__removeRule(RequestInfo* request) -{ - int id; - int error; - - const char* pkgId = request->getPackageId(); - - CtxJson1 ruleId = request->getDescription(); - ruleId.get(NULL, TRIG_KEY_RULE_ID, &id); - - error = __ruleMgr->checkRule((pkgId)? pkgId : "", id); - if (error != ERR_NONE) { - request->reply(error); - return; - } - - bool ret = __ruleMgr->isRuleEnabled(id); - if (ret) { - request->reply(ERR_RULE_ENABLED); - return; - } - - error = __ruleMgr->removeRule(id); - _I("'%s' removes rule%d (Error: %#x)", request->getClient(), id, error); - request->reply(error); -} - -void Trigger::__enableRule(RequestInfo* request) -{ - int id; - int error; - - const char* pkgId = request->getPackageId(); - - CtxJson1 ruleId = request->getDescription(); - ruleId.get(NULL, TRIG_KEY_RULE_ID, &id); - - error = __ruleMgr->checkRule((pkgId)? pkgId : "", id); - if (error != ERR_NONE) { - request->reply(error); - return; - } - - bool ret = __ruleMgr->isRuleEnabled(id); - if (ret) { - request->reply(ERR_RULE_ENABLED); - return; - } - - error = __ruleMgr->enableRule(id); - _I("'%s' enables rule%d (Error: %#x)", request->getClient(), id, error); - request->reply(error); -} - -void Trigger::__disableRule(RequestInfo* request) -{ - int id; - int error; - - const char* pkgId = request->getPackageId(); - - CtxJson1 ruleId = request->getDescription(); - ruleId.get(NULL, TRIG_KEY_RULE_ID, &id); - - error = __ruleMgr->checkRule((pkgId)? pkgId : "", id); - if (error != ERR_NONE) { - request->reply(error); - return; - } - - bool ret = __ruleMgr->isRuleEnabled(id); - if (!ret) { - request->reply(ERR_RULE_NOT_ENABLED); - return; - } - - error = __ruleMgr->disableRule(id); - _I("'%s' disables rule%d (Error: %#x)", request->getClient(), id, error); - request->reply(error); -} - -void Trigger::__getRuleById(RequestInfo* request) -{ - int error; - - CtxJson1 option = request->getDescription(); - int id; - option.get(NULL, TRIG_KEY_RULE_ID, &id); - - const char* pkgId = request->getPackageId(); - - CtxJson1 readData; - error = __ruleMgr->getRuleById((pkgId)? pkgId : "", id, &readData); - - CtxJson1 dummy; - request->reply(error, dummy, readData); -} - -void Trigger::__getRuleIds(RequestInfo* request) -{ - int error; - - const char* pkgId = request->getPackageId(); - - CtxJson1 readData; - error = __ruleMgr->getRuleIds((pkgId)? pkgId : "", &readData); - - CtxJson1 dummy; - request->reply(error, dummy, readData); -} - -void Trigger::__getTemplate(RequestInfo* request) -{ - int error; - - CtxJson1 option = request->getDescription(); - std::string name; - option.get(NULL, TRIG_TMPL_KEY_SUBJECT, &name); - - TemplateManager* tmplMgr = TemplateManager::getInstance(); - if (!tmplMgr) { - _E("Memory allocation failed"); - request->reply(ERR_OUT_OF_MEMORY); - return; - } - - CtxJson1 tmpl; - error = tmplMgr->getTemplate(name, &tmpl); - - CtxJson1 dummy; - request->reply(error, dummy, tmpl); -} diff --git a/src/agent/legacy/trigger/Trigger.h b/src/agent/legacy/trigger/Trigger.h deleted file mode 100644 index 161c99e..0000000 --- a/src/agent/legacy/trigger/Trigger.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * 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. - */ - -#ifndef _CONTEXT_TRIGGER_TRIGGER_H_ -#define _CONTEXT_TRIGGER_TRIGGER_H_ - -#include "../Request.h" - -namespace ctx { - - class client_request; - class ContextManager; - -namespace trigger { - - class RuleManager; - - class Trigger { - public: - Trigger(); - ~Trigger(); - - bool init(ContextManager* ctxMgr); - void release(); - - bool assignRequest(RequestInfo* request); - - private: - void __processRequest(RequestInfo* request); - void __processInitialize(ContextManager* mgr); - - void __addRule(RequestInfo* request); - void __removeRule(RequestInfo* request); - void __enableRule(RequestInfo* request); - void __disableRule(RequestInfo* request); - void __getRuleById(RequestInfo* request); - void __getRuleIds(RequestInfo* request); - void __getTemplate(RequestInfo* request); - - RuleManager* __ruleMgr; - }; - -} /* namespace trigger */ -} /* namespace ctx */ - -#endif /* End of _CONTEXT_TRIGGER_TRIGGER_H_ */ -- 2.7.4 From ec5ca263074a531be721dba12af971b8da948338 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Sat, 29 Jul 2017 18:59:44 +0900 Subject: [PATCH 11/16] Implement the agent daemon Change-Id: I7542bd9f11f899574d910d9d2adbab76e6fb18dd Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 5 + packaging/context-service.spec | 10 +- packaging/contextd-agent.service | 7 +- packaging/contextd-agent.socket | 7 ++ src/agent/AgentDBus.cpp | 69 ++++++++++++ src/agent/AgentDBus.h | 40 +++++++ src/agent/AgentMain.cpp | 36 ++++++- src/agent/AgentSocket.cpp | 227 +++++++++++++++++++++++++++++++++++++++ src/agent/AgentSocket.h | 50 +++++++++ src/agent/AgentUtil.cpp | 34 ++++++ src/agent/AgentUtil.h | 40 +++++++ src/agent/CMakeLists.txt | 10 +- src/agent/PluginLoader.cpp | 117 ++++++++++++++++++++ src/agent/PluginLoader.h | 47 ++++++++ src/server/CMakeLists.txt | 2 +- src/server/ServerMain.cpp | 70 +----------- src/shared/ServerBase.cpp | 76 +++++++++++++ src/shared/ServerBase.h | 33 ++++++ 18 files changed, 807 insertions(+), 73 deletions(-) create mode 100644 packaging/contextd-agent.socket create mode 100644 src/agent/AgentDBus.cpp create mode 100644 src/agent/AgentDBus.h create mode 100644 src/agent/AgentSocket.cpp create mode 100644 src/agent/AgentSocket.h create mode 100644 src/agent/AgentUtil.cpp create mode 100644 src/agent/AgentUtil.h create mode 100644 src/agent/PluginLoader.cpp create mode 100644 src/agent/PluginLoader.h create mode 100644 src/shared/ServerBase.cpp create mode 100644 src/shared/ServerBase.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d1849..549a8e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,12 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(context-service) INCLUDE(GNUInstallDirs) +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/src/shared +) + ADD_DEFINITIONS(-O2 -Wall -fPIC -fPIE -fdata-sections -ffunction-sections -fvisibility=hidden) +ADD_DEFINITIONS(-D_LIBDIR_="${LIBDIR}") ADD_DEFINITIONS(-fdiagnostics-color) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -pie -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections") SET(CMAKE_VERBOSE_MAKEFILE OFF) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index 130e273..ca3b359 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -8,8 +8,10 @@ Source0: %{name}-%{version}.tar.gz Source1: contextd.service Source2: org.tizen.context.conf Source3: contextd-agent.service +Source4: contextd-agent.socket BuildRequires: cmake +BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgconfig(libsystemd-login) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) @@ -49,7 +51,7 @@ export CXXFLAGS+=" -Wformat=2 -Wno-empty-body -fomit-frame-pointer -fno-optimize export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow" export CXXFLAGS+=" -Wnon-virtual-dtor -std=c++0x" -%cmake . +%cmake . -DLIBDIR=%{_libdir} make %{?_smp_mflags} %install @@ -62,8 +64,10 @@ ln -s ../contextd.service %{buildroot}%{_unitdir}/multi-user.target.wants/contex mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/dbus-1/system.d/ -mkdir -p %{buildroot}%{_unitdir_user} +mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants install -m 0644 %{SOURCE3} %{buildroot}%{_unitdir_user} +install -m 0644 %{SOURCE4} %{buildroot}%{_unitdir_user} +ln -s ../contextd-agent.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/contextd-agent.socket %files %manifest packaging/%{name}.manifest @@ -77,4 +81,6 @@ install -m 0644 %{SOURCE3} %{buildroot}%{_unitdir_user} %manifest packaging/%{name}.manifest %{_bindir}/contextd-agent %{_unitdir_user}/contextd-agent.service +%{_unitdir_user}/contextd-agent.socket +%{_unitdir_user}/*/contextd-agent.socket %license LICENSE diff --git a/packaging/contextd-agent.service b/packaging/contextd-agent.service index 8eb83c4..4e6819c 100644 --- a/packaging/contextd-agent.service +++ b/packaging/contextd-agent.service @@ -2,5 +2,10 @@ Description=Contextual Service Framework User-Level Agent Daemon [Service] -Type=simple +Type=notify ExecStart=/usr/bin/contextd-agent +Sockets=contextd-agent.socket +Restart=no + +[Install] +WantedBy=sockets.target diff --git a/packaging/contextd-agent.socket b/packaging/contextd-agent.socket new file mode 100644 index 0000000..71de9ef --- /dev/null +++ b/packaging/contextd-agent.socket @@ -0,0 +1,7 @@ +[Unit] +Description=Context-Agent Socket + +[Socket] +ListenStream=/run/user_ext/%U/.contextd-agent.socket +Service=contextd-agent.service +Accept=false diff --git a/src/agent/AgentDBus.cpp b/src/agent/AgentDBus.cpp new file mode 100644 index 0000000..fa952b0 --- /dev/null +++ b/src/agent/AgentDBus.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include +#include "AgentDBus.h" + +using namespace ctx; + +AgentDBus::AgentDBus() : + __connection(NULL) +{ + if (!__init()) + throw std::runtime_error("DBus connection failed"); + + _I("Connection established (%s)", g_dbus_connection_get_unique_name(__connection)); +} + +AgentDBus::~AgentDBus() +{ + __release(); +} + +GDBusConnection* AgentDBus::getConnection() +{ + return __connection; +} + +bool AgentDBus::__init() +{ + GError *gerr = NULL; + gchar *addr = NULL; + + addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr); + HANDLE_GERROR(gerr); + IF_FAIL_RETURN_TAG(addr, false, _E, "Getting address failed"); + + __connection = g_dbus_connection_new_for_address_sync(addr, + (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), + NULL, NULL, &gerr); + g_free(addr); + HANDLE_GERROR(gerr); + IF_FAIL_RETURN_TAG(__connection, false, _E, "Connection failed"); + + return true; +} + +void AgentDBus::__release() +{ + if (__connection) { + g_dbus_connection_flush_sync(__connection, NULL, NULL); + g_dbus_connection_close_sync(__connection, NULL, NULL); + g_object_unref(__connection); + } + + _I("Connection released"); +} diff --git a/src/agent/AgentDBus.h b/src/agent/AgentDBus.h new file mode 100644 index 0000000..345cb3e --- /dev/null +++ b/src/agent/AgentDBus.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONTEXT_AGENT_DBUS_H__ +#define __CONTEXT_AGENT_DBUS_H__ + +#include + +namespace ctx { + + class AgentDBus { + public: + AgentDBus(); + ~AgentDBus(); + + GDBusConnection* getConnection(); + + private: + bool __init(); + void __release(); + + GDBusConnection* __connection; + }; + +} + +#endif diff --git a/src/agent/AgentMain.cpp b/src/agent/AgentMain.cpp index fc1dc8d..fd271be 100644 --- a/src/agent/AgentMain.cpp +++ b/src/agent/AgentMain.cpp @@ -14,9 +14,43 @@ * limitations under the License. */ +#include #include +#include -int main(int argc, char* argv[]) +#include +#include "AgentDBus.h" +#include "AgentUtil.h" +#include "PluginLoader.h" +#include "AgentSocket.h" + +using namespace ctx; + +static MainLoop __mainLoop; + +static void __on_signal(int signum) +{ + _I(YELLOW("SIGNAL-%d: '%s'"), signum, strsignal(signum)); + __mainLoop.stop(); +} + +int main(int argc, char **argv) { + std::signal(SIGINT, __on_signal); + std::signal(SIGHUP, __on_signal); + std::signal(SIGTERM, __on_signal); + std::signal(SIGQUIT, __on_signal); + + AgentDBus agentDBus; + AgentUtil agentUtil(agentDBus); + PluginLoader pluginLoader(agentUtil); + AgentSocket agentSocket(pluginLoader); + + sd_notify(0, "READY=1"); + + __mainLoop.start(); + + sd_notify(0, "STOPPING=1"); + return EXIT_SUCCESS; } diff --git a/src/agent/AgentSocket.cpp b/src/agent/AgentSocket.cpp new file mode 100644 index 0000000..e8d45b9 --- /dev/null +++ b/src/agent/AgentSocket.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "PluginLoader.h" +#include "AgentSocket.h" + +#define PATH_LENGTH 48 +#define TERM_MSG_ID 0xFFFF + +using namespace ctx; + +struct CommandInfo { + PluginLoader* pluginLoader; + uint16_t id; + uint8_t length; + void* command; + + CommandInfo(PluginLoader* loader, uint16_t i, uint8_t len, char* cmd) : + pluginLoader(loader), id(i), length(len), command(NULL) + { + command = malloc(length); + + if (!command) + throw std::bad_alloc(); + + memcpy(command, cmd, length); + } + + ~CommandInfo() + { + free(command); + } +}; + +static gboolean __send_command(gpointer data) +{ + CommandInfo* info = static_cast(data); + + info->pluginLoader->send(info->id, info->length, info->command); + + delete info; + + return G_SOURCE_REMOVE; +} + +static bool __set_close_on_exec(int fd) +{ + if (::fcntl(fd, F_SETFL, FD_CLOEXEC) == -1) + return false; + + return true; +} + +static int __get_socket_fd(const char* path) +{ + int n = sd_listen_fds(0); + IF_FAIL_RETURN_TAG(n > 0, E_ACCESS, _E, "sd_listen_fds() failed"); + + for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) { + if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path, 0) > 0) { + __set_close_on_exec(fd); + return fd; + } + } + + return E_ACCESS; +} + +AgentSocket::AgentSocket(PluginLoader& loader) : + __sockFd(-1), + __listening(false), + __listeningThread(NULL), + __pluginLoader(loader) +{ + if (!__init()) { + __release(); + throw std::runtime_error("Socket connection failed"); + } + + _I("Listening..."); +} + +AgentSocket::~AgentSocket() +{ + __release(); +} + +bool AgentSocket::__init() +{ + char path[PATH_LENGTH]; + g_snprintf(path, PATH_LENGTH, CTX_AGENT_SOCKET, static_cast(getuid())); + + _D("Socket Path: %s", path); + + __sockFd = __get_socket_fd(path); + IF_FAIL_RETURN_TAG(__sockFd > 0, false, _E, "Failed to get the socket fd"); + + __listening.store(true); + __listeningThread = g_thread_new(NULL, __listen, this); + IF_FAIL_RETURN_TAG(__listeningThread, false, _E, "Thread creation failed"); + + return true; +} + +gpointer AgentSocket::__listen(gpointer data) +{ + static_cast(data)->__listen(); + return NULL; +} + +void AgentSocket::__listen() +{ + int msgsock = 0; + + while (__listening.load()) { + msgsock = accept(__sockFd, 0, 0); + + if (msgsock < 0) { + _D("accept() failed"); + continue; + } + + if (!__readCommand(msgsock)) { + close(msgsock); + break; + } + + close(msgsock); + } +} + +bool AgentSocket::__readCommand(int msgsock) +{ + uint16_t id = 0; + uint8_t length = 0; + int rval = 0; + char buf[CTX_AGENT_COMMAND_LIMIT] = {0}; + + rval = read(msgsock, &id, sizeof(id)); + IF_FAIL_RETURN_TAG(rval == sizeof(id), false, _E, "read() failed"); + + if (id == TERM_MSG_ID) { + _D("Stop listening..."); + return false; + } + + rval = read(msgsock, &length, sizeof(length)); + IF_FAIL_RETURN_TAG(rval == sizeof(length), false, _E, "read() failed"); + + rval = read(msgsock, buf, length); + IF_FAIL_RETURN_TAG(rval == static_cast(length), false, _E, "read() failed"); + + + buf[length] = '\0'; + + CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, buf); + g_idle_add(__send_command, info); + + return true; +} + +void AgentSocket::__release() +{ + if (!__listening.load()) + return; + + __listening.store(false); + __terminate(); + + if (__listeningThread) + g_thread_join(__listeningThread); + + close(__sockFd); +} + +bool AgentSocket::__terminate() +{ + int sock = -1; + sockaddr_un addr; + char path[PATH_LENGTH]; + const uint16_t termMsg = TERM_MSG_ID; + + g_snprintf(path, PATH_LENGTH, CTX_AGENT_SOCKET, static_cast(getuid())); + IF_FAIL_RETURN_TAG(strlen(path) < sizeof(addr.sun_path), false, _E, "Invalid path"); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + IF_FAIL_RETURN_TAG(sock > 0, false, _E, "socket creation failed"); + + bzero(&addr, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + addr.sun_path[sizeof(path)] = '\0'; + + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) < 0) { + close(sock); + _E("Connection failed"); + return false; + } + + if (write(sock, &termMsg, sizeof(termMsg)) < 0) { + close(sock); + _E("Sending failed"); + return false; + } + + close(sock); + return true; +} diff --git a/src/agent/AgentSocket.h b/src/agent/AgentSocket.h new file mode 100644 index 0000000..d3f1ebd --- /dev/null +++ b/src/agent/AgentSocket.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONTEXT_AGENT_SOCKET_H__ +#define __CONTEXT_AGENT_SOCKET_H__ + +#include +#include + +namespace ctx { + + class PluginLoader; + + class AgentSocket { + public: + AgentSocket(PluginLoader& loader); + ~AgentSocket(); + + private: + bool __init(); + void __release(); + + void __listen(); + bool __readCommand(int msgsock); + bool __terminate(); + + static gpointer __listen(gpointer data); + + int __sockFd; + std::atomic_bool __listening; + GThread* __listeningThread; + PluginLoader& __pluginLoader; + }; + +} + +#endif diff --git a/src/agent/AgentUtil.cpp b/src/agent/AgentUtil.cpp new file mode 100644 index 0000000..a7bdee7 --- /dev/null +++ b/src/agent/AgentUtil.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include "AgentDBus.h" +#include "AgentUtil.h" + +using namespace ctx; + +AgentUtil::AgentUtil(AgentDBus& agentDBus) : + __agentDBus(agentDBus) +{ +} + +AgentUtil::~AgentUtil() +{ +} + +GDBusConnection* AgentUtil::getDBusConnection() +{ + return __agentDBus.getConnection(); +} diff --git a/src/agent/AgentUtil.h b/src/agent/AgentUtil.h new file mode 100644 index 0000000..008162f --- /dev/null +++ b/src/agent/AgentUtil.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONTEXT_AGENT_UTIL_H__ +#define __CONTEXT_AGENT_UTIL_H__ + +#include +#include + +namespace ctx { + + class AgentDBus; + + class AgentUtil : public IAgentUtil { + public: + AgentUtil(AgentDBus& agentDBus); + ~AgentUtil(); + + GDBusConnection* getDBusConnection(); + + private: + AgentDBus& __agentDBus; + }; + +} + +#endif diff --git a/src/agent/CMakeLists.txt b/src/agent/CMakeLists.txt index 69d426e..cbe2063 100644 --- a/src/agent/CMakeLists.txt +++ b/src/agent/CMakeLists.txt @@ -2,9 +2,15 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET(target "contextd-agent") -SET(DEPS glib-2.0 gio-2.0 gmodule-2.0 dlog capi-base-common) +SET(DEPS glib-2.0 gio-2.0 gmodule-2.0 libsystemd-daemon dlog capi-base-common) -FILE(GLOB_RECURSE SRCS *.cpp) +SET(INCDIR "${CMAKE_INSTALL_INCLUDEDIR}/context-service") + +INCLUDE_DIRECTORIES( + ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private +) + +FILE(GLOB SRCS *.cpp ../shared/*.cpp) MESSAGE("Sources: ${SRCS}") INCLUDE(FindPkgConfig) diff --git a/src/agent/PluginLoader.cpp b/src/agent/PluginLoader.cpp new file mode 100644 index 0000000..c49b617 --- /dev/null +++ b/src/agent/PluginLoader.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include +#include +#include +#include +#include "AgentUtil.h" +#include "PluginLoader.h" + +#define PLUGIN_DIR _LIBDIR_ "/" CTX_AGENT_PLUGIN_DIR + +using namespace ctx; + +PluginLoader::PluginLoader(AgentUtil& agentUtil) : + __agentUtil(agentUtil) +{ + if (!__load()) { + __unload(); + throw std::runtime_error("Plugin loading failed"); + } + + _I("%u plugins loaded", __plugins.size()); +} + +PluginLoader::~PluginLoader() +{ + __unload(); +} + +void PluginLoader::send(uint16_t id, uint8_t length, const void* command) +{ + for (auto& agent : __plugins) { + if (agent->getId() == id) { + agent->doAction(length, command); + return; + } + } + + _W("Agent not found"); +} + +bool PluginLoader::__load() +{ + DIR* dir = NULL; + struct dirent* entry = NULL; + struct stat fileStat; + + _D("Scanning %s", PLUGIN_DIR); + + dir = opendir(PLUGIN_DIR); + IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open: %s", PLUGIN_DIR); + + while ((entry = readdir(dir))) { + std::string filePath(PLUGIN_DIR "/"); + filePath.append(entry->d_name); + + if (lstat(filePath.c_str(), &fileStat) != 0) + continue; + + if (!S_ISREG(fileStat.st_mode)) + continue; + + if (!__load(filePath)) { + closedir(dir); + _E("Failed to load %s", filePath.c_str()); + return false; + } + } + + closedir(dir); + return true; +} + +bool PluginLoader::__load(const std::string& filePath) +{ + _D("Loading plugins from %s", filePath.c_str()); + + GModule *soHandle = g_module_open(filePath.c_str(), G_MODULE_BIND_LAZY); + IF_FAIL_RETURN_TAG(soHandle, false, _E, "%s", g_module_error()); + + create_plugins_t createPlugins; + if (!g_module_symbol(soHandle, CTX_AGENT_CREATE_FUNC_SYM, (gpointer*)&createPlugins) || !createPlugins) { + _E("%s", g_module_error()); + g_module_close(soHandle); + return false; + } + + IAgentPlugin** plugins = createPlugins(&__agentUtil); + for (int i = 0; plugins[i] != NULL; ++i) { + __plugins.push_back(plugins[i]); + } + + return true; +} + +void PluginLoader::__unload() +{ + for (auto& plugin : __plugins) { + delete plugin; + } + + __plugins.clear(); +} diff --git a/src/agent/PluginLoader.h b/src/agent/PluginLoader.h new file mode 100644 index 0000000..557c22a --- /dev/null +++ b/src/agent/PluginLoader.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONTEXT_AGENT_PLUGIN_LOADER_H__ +#define __CONTEXT_AGENT_PLUGIN_LOADER_H__ + +#include +#include +#include +#include + +namespace ctx { + + class AgentUtil; + + class PluginLoader { + public: + PluginLoader(AgentUtil& agentUtil); + ~PluginLoader(); + + void send(uint16_t id, uint8_t length, const void* command); + + private: + bool __load(); + bool __load(const std::string& filePath); + void __unload(); + + AgentUtil& __agentUtil; + std::vector __plugins; + }; + +} + +#endif diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index b0c8ba2..0ec7782 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -26,7 +26,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private ) -FILE(GLOB_RECURSE SRCS *.cpp) +FILE(GLOB SRCS *.cpp ../shared/*.cpp) MESSAGE("Sources: ${SRCS}") INCLUDE(FindPkgConfig) diff --git a/src/server/ServerMain.cpp b/src/server/ServerMain.cpp index 312574d..ae62b7c 100644 --- a/src/server/ServerMain.cpp +++ b/src/server/ServerMain.cpp @@ -17,53 +17,18 @@ #include #include #include -#include -#include -#include #include #include +#include #include "DBusConnector.h" #include "ServiceLoader.h" #include "ActiveUserMonitor.h" #include "AlarmInitializer.h" -#define NEW_FAIL_LIMIT 3 - using namespace ctx; -namespace { - class MainLoop { - public: - static bool start(); - static void stop(); - private: - MainLoop() {} - static GMainLoop* __mainLoop; - }; -} - -GMainLoop* MainLoop::__mainLoop = NULL; - -bool MainLoop::start() -{ - __mainLoop = g_main_loop_new(NULL, FALSE); - IF_FAIL_RETURN_TAG(__mainLoop, false, _E, E_STR_ALLOC); - - _I(CYAN("Starting...")); - g_main_loop_run(__mainLoop); - - g_main_loop_unref(__mainLoop); - - return true; -} - -void MainLoop::stop() -{ - _I(PURPLE("Terminating...")); - g_main_loop_quit(__mainLoop); -} - +static MainLoop __mainLoop; static ServiceLoader __serviceLoader; static ActiveUserMonitor __activeUserMonitor(&__serviceLoader); static AlarmInitializer __alarmInit; @@ -89,7 +54,7 @@ static gboolean __stop_service(gpointer data) _I("Unloading services"); __serviceLoader.stopAll(); - MainLoop::stop(); + __mainLoop.stop(); return G_SOURCE_REMOVE; } @@ -114,43 +79,16 @@ static void __on_signal(int signum) } } -static void __on_terminate() -{ - try { - auto unknown = std::current_exception(); - if (unknown) { - std::rethrow_exception(unknown); - } - } catch (const std::exception& e) { - _E(RED("Unexpected exception: %s"), e.what()); - } catch (...) { - _E(RED("Unknown exception")); - } -} - -static void __on_new_failed() -{ - static unsigned failCount = 0; - _E_ALLOC; - failCount += 1; - if (failCount >= NEW_FAIL_LIMIT) - throw std::bad_alloc(); -} - int main(int argc, char* argv[]) { std::signal(SIGINT, __on_signal); std::signal(SIGHUP, __on_signal); std::signal(SIGTERM, __on_signal); std::signal(SIGQUIT, __on_signal); - std::signal(SIGABRT, __on_signal); - - std::set_terminate(__on_terminate); - std::set_new_handler(__on_new_failed); DBusConnector dbusConnector(__bus_acquired, __bus_lost); - MainLoop::start(); + __mainLoop.start(); return EXIT_SUCCESS; } diff --git a/src/shared/ServerBase.cpp b/src/shared/ServerBase.cpp new file mode 100644 index 0000000..2f60ced --- /dev/null +++ b/src/shared/ServerBase.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include +#include +#include +#include "ServerBase.h" + +#define NEW_FAIL_LIMIT 3 + +using namespace ctx; + +static void __on_terminate() +{ + try { + auto unknown = std::current_exception(); + if (unknown) { + std::rethrow_exception(unknown); + } + } catch (const std::exception& e) { + _E(RED("Unexpected exception: %s"), e.what()); + } catch (...) { + _E(RED("Unknown exception")); + } +} + +static void __on_new_failed() +{ + static unsigned failCount = 0; + _E_ALLOC; + failCount += 1; + if (failCount >= NEW_FAIL_LIMIT) + throw std::bad_alloc(); +} + +MainLoop::MainLoop() : + __mainLoop(NULL) +{ + std::set_terminate(__on_terminate); + std::set_new_handler(__on_new_failed); +} + +bool MainLoop::start() +{ + __mainLoop = g_main_loop_new(NULL, FALSE); + IF_FAIL_RETURN_TAG(__mainLoop, false, _E, E_STR_ALLOC); + + _I(CYAN("Starting...")); + g_main_loop_run(__mainLoop); + + g_main_loop_unref(__mainLoop); + __mainLoop = NULL; + + return true; +} + +void MainLoop::stop() +{ + if (__mainLoop && g_main_loop_is_running(__mainLoop)) { + _I(PURPLE("Terminating...")); + g_main_loop_quit(__mainLoop); + } +} diff --git a/src/shared/ServerBase.h b/src/shared/ServerBase.h new file mode 100644 index 0000000..e3bf1e4 --- /dev/null +++ b/src/shared/ServerBase.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONEXT_SERVER_BASE_H__ +#define __CONEXT_SERVER_BASE_H__ + +#include + +namespace ctx { + class MainLoop { + public: + MainLoop(); + bool start(); + void stop(); + private: + GMainLoop* __mainLoop; + }; +} + +#endif -- 2.7.4 From 9190326aa5a4972126a4e779503ccb1fdf5658d2 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 1 Aug 2017 19:34:52 +0900 Subject: [PATCH 12/16] agent daemon self-terminates when it is idle Change-Id: I483ae9f0ce613694967552928919e90a83ea1bca Signed-off-by: Mu-Woong Lee --- src/agent/PluginLoader.cpp | 50 +++++++++++++++++++++++++++++++++++++++++----- src/agent/PluginLoader.h | 8 +++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/agent/PluginLoader.cpp b/src/agent/PluginLoader.cpp index c49b617..da09815 100644 --- a/src/agent/PluginLoader.cpp +++ b/src/agent/PluginLoader.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -21,11 +22,13 @@ #include "AgentUtil.h" #include "PluginLoader.h" -#define PLUGIN_DIR _LIBDIR_ "/" CTX_AGENT_PLUGIN_DIR +#define PLUGIN_DIR _LIBDIR_ "/" CTX_AGENT_PLUGIN_DIR +#define IDLE_EXIT_DELAY 5 using namespace ctx; PluginLoader::PluginLoader(AgentUtil& agentUtil) : + __exitSrcId(0), __agentUtil(agentUtil) { if (!__load()) { @@ -43,14 +46,27 @@ PluginLoader::~PluginLoader() void PluginLoader::send(uint16_t id, uint8_t length, const void* command) { - for (auto& agent : __plugins) { - if (agent->getId() == id) { - agent->doAction(length, command); - return; + auto exitOnIdle = [this]() { + if (__exitSrcId > 0) { + g_source_remove(__exitSrcId); + __exitSrcId = 0; } + + if (__isIdle()) + __exitSrcId = g_timeout_add_seconds(IDLE_EXIT_DELAY, __exit, this); + }; + + for (auto& agent : __plugins) { + if (agent->getId() != id) + continue; + + agent->doAction(length, command); + exitOnIdle(); + return; } _W("Agent not found"); + exitOnIdle(); } bool PluginLoader::__load() @@ -115,3 +131,27 @@ void PluginLoader::__unload() __plugins.clear(); } + +bool PluginLoader::__isIdle() +{ + for (auto* plugin : __plugins) { + if (!plugin->isIdle()) + return false; + } + + return true; +} + +gboolean PluginLoader::__exit(gpointer data) +{ + PluginLoader* loader = static_cast(data); + + if (loader->__isIdle()) { + _I("All plugins are idle."); + raise(SIGTERM); + } + + loader->__exitSrcId = 0; + + return G_SOURCE_REMOVE; +} diff --git a/src/agent/PluginLoader.h b/src/agent/PluginLoader.h index 557c22a..db06e36 100644 --- a/src/agent/PluginLoader.h +++ b/src/agent/PluginLoader.h @@ -38,8 +38,14 @@ namespace ctx { bool __load(const std::string& filePath); void __unload(); - AgentUtil& __agentUtil; + // true, if all plugins are idle. + bool __isIdle(); + + static gboolean __exit(gpointer data); + + guint __exitSrcId; std::vector __plugins; + AgentUtil& __agentUtil; }; } -- 2.7.4 From 97a36ac553b22894aabc0c308b9e35cdb793011e Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 1 Aug 2017 20:44:54 +0900 Subject: [PATCH 13/16] Add defence code to handle socket read failure Change-Id: Ic8e1f638d900c7d29804a93bcc1c09a80fde7f45 Signed-off-by: Mu-Woong Lee --- src/agent/AgentSocket.cpp | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/agent/AgentSocket.cpp b/src/agent/AgentSocket.cpp index e8d45b9..f9d6fb5 100644 --- a/src/agent/AgentSocket.cpp +++ b/src/agent/AgentSocket.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -152,27 +153,43 @@ bool AgentSocket::__readCommand(int msgsock) { uint16_t id = 0; uint8_t length = 0; - int rval = 0; - char buf[CTX_AGENT_COMMAND_LIMIT] = {0}; - - rval = read(msgsock, &id, sizeof(id)); - IF_FAIL_RETURN_TAG(rval == sizeof(id), false, _E, "read() failed"); + char command[CTX_AGENT_COMMAND_LIMIT] = {0}; + + auto safeRead = [&msgsock](char* buf, size_t count)->bool { + do { + int rc = read(msgsock, buf, count); + if (rc < 0) { + if (errno == EAGAIN) { + continue; + } else { + _E("Socket read error: %d", errno); + return false; + } + } + count -= rc; + buf += rc; + } while (count > 0); + return true; + }; + + bool success; + + success = safeRead(reinterpret_cast(&id), sizeof(id)); + IF_FAIL_RETURN(success, false); if (id == TERM_MSG_ID) { _D("Stop listening..."); return false; } - rval = read(msgsock, &length, sizeof(length)); - IF_FAIL_RETURN_TAG(rval == sizeof(length), false, _E, "read() failed"); - - rval = read(msgsock, buf, length); - IF_FAIL_RETURN_TAG(rval == static_cast(length), false, _E, "read() failed"); - + success = safeRead(reinterpret_cast(&length), sizeof(length)); + IF_FAIL_RETURN(success, false); + IF_FAIL_RETURN_TAG(length > 0 && length <= CTX_AGENT_COMMAND_LIMIT, false, _E, "Invalid command"); - buf[length] = '\0'; + success = safeRead(command, length); + IF_FAIL_RETURN(success, false); - CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, buf); + CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, command); g_idle_add(__send_command, info); return true; -- 2.7.4 From 089e5401275aa6d1241317e771a4fcb48d6ad2ac Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 2 Aug 2017 12:50:14 +0900 Subject: [PATCH 14/16] Version 4.0.2 Change-Id: I63e5aa6cae87d3a24317e2352d968a6e4999a356 Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index ca3b359..b254aa0 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -1,6 +1,6 @@ Name: context-service Summary: Tizen Contextual Service Framework -Version: 4.0.1 +Version: 4.0.2 Release: 1 Group: Service/Context License: Apache-2.0 -- 2.7.4 From bcb997cda692784a3c9c827a262288dbaa48b306 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 3 Aug 2017 13:33:28 +0900 Subject: [PATCH 15/16] context-agent requires session-utils Change-Id: Icf7ee16cc8a595749c0eb2bff17d3f9be5bbb87a Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index b254aa0..176a5d5 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -37,6 +37,7 @@ This is a systemd service that contains all features provided by the Tizen Conte %package -n context-agent Summary: User-level agent service of the Tizen Contextual Service Framework +Requires: session-utils %description -n context-agent This is a systemd service that runs in the user session to assist the main service daemon of the Contextual Service Framework. -- 2.7.4 From d0c457008b8ca4d188f5c66b62e6265f643ec9ae Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 7 Aug 2017 11:34:09 +0900 Subject: [PATCH 16/16] Fix memory leaks: ServiceRunner::~ServiceRunner deletes its service instance Change-Id: Icff41cd89140d58fd60ad6ea92fb939dcc2bf047 Signed-off-by: Mu-Woong Lee --- src/server/ServiceRunner.cpp | 49 ++++++++++++++++++++++---------------------- src/server/ServiceRunner.h | 4 ++-- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/server/ServiceRunner.cpp b/src/server/ServiceRunner.cpp index eb0b058..1bcddb6 100644 --- a/src/server/ServiceRunner.cpp +++ b/src/server/ServiceRunner.cpp @@ -25,8 +25,8 @@ using namespace ctx; ServiceRunner::ServiceRunner(GDBusConnection* conn, IService* service) : - serviceInstance(service), - started(false), + __serviceInstance(service), + __started(false), __uid(0), __connection(conn), __objPath(CTX_DBUS_PATH "/"), @@ -34,12 +34,13 @@ ServiceRunner::ServiceRunner(GDBusConnection* conn, IService* service) : __nodeInfo(NULL), __registrationId(0) { - __objPath += serviceInstance->getServiceName(); - __interface += serviceInstance->getServiceName(); + __objPath += __serviceInstance->getServiceName(); + __interface += __serviceInstance->getServiceName(); } ServiceRunner::~ServiceRunner() { + delete __serviceInstance; } GMainContext* ServiceRunner::getMainContext() @@ -54,14 +55,14 @@ GDBusConnection* ServiceRunner::getConnection() IService* ServiceRunner::getService() { - return serviceInstance; + return __serviceInstance; } bool ServiceRunner::start(uid_t uid) { - IF_FAIL_RETURN(!started, true); + IF_FAIL_RETURN(!__started, true); - _I(CYAN("Starting '%s'"), serviceInstance->getServiceName()); + _I(CYAN("Starting '%s'"), __serviceInstance->getServiceName()); if (!__init(uid)) { _E("Starting failed"); @@ -69,17 +70,17 @@ bool ServiceRunner::start(uid_t 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'"), serviceInstance->getServiceName()); + _I(PURPLE("Stopping '%s'"), __serviceInstance->getServiceName()); __release(__uid); } @@ -103,7 +104,7 @@ bool ServiceRunner::__init(uid_t uid) vtable.set_property = NULL; std::string introspection("" + serviceInstance->getMethodSpecs() + ""; + introspection += __interface + "'>" + __serviceInstance->getMethodSpecs() + ""; __nodeInfo = g_dbus_node_info_new_for_xml(introspection.c_str(), NULL); IF_FAIL_RETURN_TAG(__nodeInfo, false, _E, "NodeInfo creation failed"); @@ -161,9 +162,9 @@ ServiceClient* ServiceRunner::__getClient(const std::string& busName) ServiceClient* client = __createClient(busName); IF_FAIL_RETURN(client, NULL); - IMethodCallHandler* callHandler = serviceInstance->createMethodCallHandler(client); + IMethodCallHandler* callHandler = __serviceInstance->createMethodCallHandler(client); if (!callHandler) { - _E("%s's method call handler cannot be NULL.", serviceInstance->getServiceName()); + _E("%s's method call handler cannot be NULL.", __serviceInstance->getServiceName()); delete client; return NULL; } @@ -186,7 +187,7 @@ void ServiceRunner::__onNameOwnerChanged(GDBusConnection* conn, const gchar* sen void ServiceRunner::__removeClient(const std::string& busName) { - _I("'%s' lost '%s'", serviceInstance->getServiceName(), busName.c_str()); + _I("'%s' lost '%s'", __serviceInstance->getServiceName(), busName.c_str()); auto iter = __clients.find(busName); IF_FAIL_VOID(iter != __clients.end()); @@ -219,24 +220,24 @@ SystemServiceRunner::SystemServiceRunner(GDBusConnection* conn, IService* servic void SystemServiceRunner::notifyUserNew(uid_t uid) { - if (started) - static_cast(serviceInstance)->onUserActivated(uid); + if (__started) + static_cast(__serviceInstance)->onUserActivated(uid); } void SystemServiceRunner::notifyUserRemoved(uid_t uid) { - if (started) - static_cast(serviceInstance)->onUserDeactivated(uid); + if (__started) + static_cast(__serviceInstance)->onUserDeactivated(uid); } bool SystemServiceRunner::__prepare(uid_t uid) { - return static_cast(serviceInstance)->prepare(); + return static_cast(__serviceInstance)->prepare(); } void SystemServiceRunner::__cleanup(uid_t uid) { - static_cast(serviceInstance)->cleanup(); + static_cast(__serviceInstance)->cleanup(); } ServiceClient* SystemServiceRunner::__createClient(const std::string& busName) @@ -266,12 +267,12 @@ void UserServiceRunner::notifyUserRemoved(uid_t uid) bool UserServiceRunner::__prepare(uid_t uid) { - return static_cast(serviceInstance)->prepare(uid); + return static_cast(__serviceInstance)->prepare(uid); } void UserServiceRunner::__cleanup(uid_t uid) { - static_cast(serviceInstance)->cleanup(uid); + static_cast(__serviceInstance)->cleanup(uid); } ServiceClient* UserServiceRunner::__createClient(const std::string& busName) @@ -284,7 +285,7 @@ ServiceClient* UserServiceRunner::__createClient(const std::string& busName) } if (!util::is_normal_user(client->getUid())) { - _W("%s does not support container users.", serviceInstance->getServiceName()); + _W("%s does not support container users.", __serviceInstance->getServiceName()); delete client; return NULL; } diff --git a/src/server/ServiceRunner.h b/src/server/ServiceRunner.h index 0e7cf3d..d291f59 100644 --- a/src/server/ServiceRunner.h +++ b/src/server/ServiceRunner.h @@ -46,8 +46,8 @@ namespace ctx { protected: ServiceRunner(GDBusConnection* conn, IService* service); - IService* serviceInstance; - bool started; + IService* __serviceInstance; + bool __started; private: static void __onMethodCalled(GDBusConnection* conn, const gchar* sender, -- 2.7.4