From 541bd72c1f228f932f73127f4049294f83303bf1 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 19 Apr 2016 16:24:03 +0900 Subject: [PATCH 01/16] Replace runtime-info and system-settings APIs with vconf to reduce memory consumption Change-Id: If4dc0a132608bec3c610fafca5a9072fa777b65b Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 2 -- packaging/context-service.spec | 2 -- src/trigger/ActionManager.cpp | 20 ++++++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1513748..29f2f85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,12 +14,10 @@ SET(DEPS vconf capi-system-info capi-system-device - capi-system-runtime-info capi-appfw-app-manager capi-appfw-package-manager appsvc notification - capi-system-system-settings cynara-creds-gdbus cynara-client cynara-session diff --git a/packaging/context-service.spec b/packaging/context-service.spec index a8af397..c659ba1 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -13,12 +13,10 @@ BuildRequires: sed BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-device) -BuildRequires: pkgconfig(capi-system-runtime-info) BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-appfw-package-manager) BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(notification) -BuildRequires: pkgconfig(capi-system-system-settings) BuildRequires: pkgconfig(cynara-creds-gdbus) BuildRequires: pkgconfig(cynara-client) diff --git a/src/trigger/ActionManager.cpp b/src/trigger/ActionManager.cpp index ffb5f4a..5db4ddd 100644 --- a/src/trigger/ActionManager.cpp +++ b/src/trigger/ActionManager.cpp @@ -20,8 +20,7 @@ #include #include #include -#include -#include +#include #include #include #include "../DBusServer.h" @@ -140,16 +139,21 @@ void __triggerActionNotification(ctx::Json& action, std::string pkgId) } } + int status; bool silent = true; - error = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_SOUND_SILENT_MODE, &silent); - if (error != SYSTEM_SETTINGS_ERROR_NONE) { - _E("Get system setting(silent mode) failed(%d)", error); + error = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &status); + if (error < 0) { + _E("vconf error (%d)", error); + } else { + silent = (status == 0); } bool vibration = true; - error = runtime_info_get_value_bool(RUNTIME_INFO_KEY_VIBRATION_ENABLED, &vibration); - if (error != RUNTIME_INFO_ERROR_NONE) { - _E("Get runtime info(vibration) failed(%d)", error); + error = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &status); + if (error < 0) { + _E("vconf error (%d)", error); + } else { + vibration = (status != 0); } if (!silent) { -- 2.7.4 From 559469cda8e3dca8bad7c7cffb8031ebf8dde2a6 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 19 Apr 2016 19:59:53 +0900 Subject: [PATCH 02/16] Disable TV profile build explicitly Change-Id: Ied7fcbdd1a584a9c1d4b99ef294b7febf9260e97 Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index c659ba1..ccba421 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -8,6 +8,12 @@ Source0: %{name}-%{version}.tar.gz Source1: context-service.service Source2: org.tizen.context.conf +%define BUILD_PROFILE %{?profile}%{!?profile:%{?tizen_profile_name}} + +%if "%{?BUILD_PROFILE}" == "tv" +ExcludeArch: %{arm} aarch64 %ix86 x86_64 +%endif + BuildRequires: cmake BuildRequires: sed BuildRequires: pkgconfig(vconf) -- 2.7.4 From d910688ae8f629cdd81fecac6266351b099c7e9d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 20 Apr 2016 20:12:48 +0900 Subject: [PATCH 03/16] Update License text Change-Id: I2d9bfeb8d226559ca0764f46cc5efcf837696c11 Signed-off-by: Mu-Woong Lee --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 1b01074..d6bdc8d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved. Apache License Version 2.0, January 2004 @@ -188,7 +188,7 @@ Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -- 2.7.4 From 0eb030aa5f4eb9c352fe1f6b99b749593a819125 Mon Sep 17 00:00:00 2001 From: Somin Kim Date: Wed, 20 Apr 2016 17:21:05 +0900 Subject: [PATCH 04/16] Modify notification action behavior related to sound, vibration Change-Id: I95f501065cb473d6de011aa2d9fa1fe08a2bcd7a Signed-off-by: Somin Kim --- src/trigger/ActionManager.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/trigger/ActionManager.cpp b/src/trigger/ActionManager.cpp index 5db4ddd..f0e50fc 100644 --- a/src/trigger/ActionManager.cpp +++ b/src/trigger/ActionManager.cpp @@ -139,34 +139,25 @@ void __triggerActionNotification(ctx::Json& action, std::string pkgId) } } - int status; - bool silent = true; - error = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &status); + int soundOn = 0; + error = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &soundOn); if (error < 0) { _E("vconf error (%d)", error); - } else { - silent = (status == 0); + } 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); + } } - bool vibration = true; - error = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &status); + int vibrationOn = 0; + error = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibrationOn); if (error < 0) { _E("vconf error (%d)", error); - } else { - vibration = (status != 0); - } - - if (!silent) { - error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL); + } else if (vibrationOn) { + error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL); if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification sound failed(%d)", error); - } - - if (vibration) { - error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification vibration failed(%d)", error); - } + _E("Set notification vibration failed(%d)", error); } } -- 2.7.4 From ce6b88d82564d9a9a2c78218f99d42f1068f13ea Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 25 Apr 2016 16:17:30 +0900 Subject: [PATCH 05/16] Apply launch-time loading routine for providers It will be modified to load only the necessary providers on demand. Change-Id: I81f622c42dd3ae5d0615feb2aa1592006e67c6f0 Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 15 +++--- packaging/context-service.spec | 3 +- src/ContextManager.cpp | 22 +------- src/ContextManager.h | 2 + src/ProviderLoader.cpp | 116 +++++++++++++++++++++++++++++++++++++++++ src/ProviderLoader.h | 39 ++++++++++++++ 6 files changed, 167 insertions(+), 30 deletions(-) create mode 100644 src/ProviderLoader.cpp create mode 100644 src/ProviderLoader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 29f2f85..9c142e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,8 @@ SET(DEPS cynara-creds-gdbus cynara-client cynara-session - context-provider + libcontext-server + context ) # Common Options @@ -30,21 +31,19 @@ INCLUDE_DIRECTORIES( /usr/include /usr/include/glib-2.0 ) -ADD_DEFINITIONS(-O2 -Wall -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden) -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-section -Wl,--print-gc-section") +ADD_DEFINITIONS(-O2 -Wall -fPIC -fPIE -fdata-sections -ffunction-sections -fvisibility=hidden) +ADD_DEFINITIONS(-DLOG_TAG="CONTEXT") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -pie -Wl,--as-needed -Wl,--gc-section -Wl,--print-gc-section") # Building Daemon pkg_check_modules(daemon_pkg REQUIRED ${DEPS}) -SET(DAEMON_EXTRA_CFLAGS -fPIE) FOREACH(flag ${daemon_pkg_CFLAGS}) - SET(DAEMON_EXTRA_CFLAGS "${DAEMON_EXTRA_CFLAGS} ${flag}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") ENDFOREACH(flag) ADD_EXECUTABLE(${target} ${SRCS}) -TARGET_LINK_LIBRARIES(${target} ${daemon_pkg_LDFLAGS} -pie) -SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${DAEMON_EXTRA_CFLAGS}) -SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CONTEXT\"") +TARGET_LINK_LIBRARIES(${target} ${daemon_pkg_LDFLAGS} -ldl) # Installing Daemon INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index ccba421..f9e2e8d 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -28,8 +28,9 @@ BuildRequires: pkgconfig(cynara-creds-gdbus) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) +BuildRequires: pkgconfig(libcontext-server) BuildRequires: pkgconfig(context) -BuildRequires: pkgconfig(context-provider) +Requires: context-provider Requires(preun): /usr/bin/systemctl Requires(post): /usr/bin/systemctl diff --git a/src/ContextManager.cpp b/src/ContextManager.cpp index 119fcff..39b0ded 100644 --- a/src/ContextManager.cpp +++ b/src/ContextManager.cpp @@ -29,12 +29,6 @@ #include "ContextManager.h" #include "trigger/TemplateManager.h" -/* Context Providers */ -#include -#include -#include -#include - using namespace ctx; struct TriggerItemFormat { @@ -76,21 +70,7 @@ ContextManager::~ContextManager() bool ContextManager::init() { - bool ret; - - ret = initDeviceContextProvider(); - IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: DeviceContextProvider"); - - ret = initStatisticsContextProvider(); - IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: StatisticsContextProvider"); - - ret = initPlaceContextProvider(); - IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: PlaceContextProvider"); - -// ret = initCustomContextProvider(); -// IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: CustomContextProvider"); - - __initialized = true; + __initialized = __providerLoader.loadAll(); return true; } diff --git a/src/ContextManager.h b/src/ContextManager.h index e2518bc..884dd71 100644 --- a/src/ContextManager.h +++ b/src/ContextManager.h @@ -19,6 +19,7 @@ #include #include +#include "ProviderLoader.h" namespace ctx { @@ -60,6 +61,7 @@ namespace ctx { bool __initialized; std::map __providerHandleMap; + ProviderLoader __providerLoader; friend class Server; diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp new file mode 100644 index 0000000..b8c5bf6 --- /dev/null +++ b/src/ProviderLoader.cpp @@ -0,0 +1,116 @@ +/* + * 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 +#include "ProviderLoader.h" + +#define PROVIDER_SO_PATH "/usr/lib/context" + +using namespace ctx; + +typedef bool (*create_t)(); + +static bool getSharedObjectPaths(const char *dirPath, std::set &soNames) +{ + DIR *dir = NULL; + struct dirent dirEntry; + struct dirent *result; + int error; + + dir = opendir(dirPath); + IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open '%s'", dirPath); + + while (true) { + error = readdir_r(dir, &dirEntry, &result); + + if (error != 0) + continue; + + if (result == NULL) + break; + + if (dirEntry.d_type != DT_REG) + continue; + + soNames.insert(dirEntry.d_name); + } + + closedir(dir); + return true; +} + +ProviderLoader::ProviderLoader() +{ +} + +ProviderLoader::~ProviderLoader() +{ + __unload(); +} + +ContextProvider* ProviderLoader::load(const char *subject) +{ + /* TODO: Implement */ + return NULL; +} + +ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) +{ + _I("Load '%s' from '%s'", subject, soPath); + + void *soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); + IF_FAIL_RETURN_TAG(soHandle, NULL, _E, "%s", dlerror()); + + create_t create = reinterpret_cast(dlsym(soHandle, "create")); + if (!create) { + _E("%s", dlerror()); + dlclose(soHandle); + return NULL; + } + + /* TODO: Update this part for dynamic loading */ + create(); + + return NULL; +} + +void ProviderLoader::__unload() +{ + /* TODO: Implement */ +} + +bool ProviderLoader::loadAll() +{ + /* TODO: Remove this function. This is a temporary solution. */ + std::set soNames; + std::string soPath; + + if (!getSharedObjectPaths(PROVIDER_SO_PATH, soNames)) { + return false; + } + + for (std::set::iterator it = soNames.begin(); it != soNames.end(); ++it) { + soPath = PROVIDER_SO_PATH; + soPath = soPath + "/" + (*it); + __load(soPath.c_str(), NULL); + } + + return true; +} diff --git a/src/ProviderLoader.h b/src/ProviderLoader.h new file mode 100644 index 0000000..fedca25 --- /dev/null +++ b/src/ProviderLoader.h @@ -0,0 +1,39 @@ +/* + * 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_ + +namespace ctx { + + class ContextProvider; + + class ProviderLoader { + public: + ProviderLoader(); + ~ProviderLoader(); + + ContextProvider* load(const char *subject); + bool loadAll(); + + private: + ContextProvider* __load(const char *soPath, const char *subject); + void __unload(); + }; + +} + +#endif /* _CONTEXT_PROVIDER_LOADER_H_ */ -- 2.7.4 From 20b891aabac9c1967b48e154543e4253e1832060 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 26 Apr 2016 11:55:20 +0900 Subject: [PATCH 06/16] Add library file list loader & statis trigger template loader Change-Id: I69796755f74e443d83b4a633614832706c8c2c0f Signed-off-by: Mu-Woong Lee --- packaging/context-service.spec | 1 + src/ContextManager.cpp | 1 + src/ProviderLoader.cpp | 76 ++++++++++++++++++++--------------------- src/ProviderLoader.h | 23 +++++++++++++ src/trigger/TemplateManager.cpp | 9 ++++- 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index f9e2e8d..5495f55 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -30,6 +30,7 @@ BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(libcontext-server) BuildRequires: pkgconfig(context) +BuildRequires: context-provider-devel Requires: context-provider Requires(preun): /usr/bin/systemctl diff --git a/src/ContextManager.cpp b/src/ContextManager.cpp index 39b0ded..75478a8 100644 --- a/src/ContextManager.cpp +++ b/src/ContextManager.cpp @@ -61,6 +61,7 @@ ContextManager::ContextManager() : __initialized(false) { ContextProvider::__setContextManager(this); + __providerLoader.init(); } ContextManager::~ContextManager() diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp index b8c5bf6..c48a992 100644 --- a/src/ProviderLoader.cpp +++ b/src/ProviderLoader.cpp @@ -15,46 +15,19 @@ */ #include -#include #include #include #include +#include #include "ProviderLoader.h" -#define PROVIDER_SO_PATH "/usr/lib/context" +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) using namespace ctx; typedef bool (*create_t)(); -static bool getSharedObjectPaths(const char *dirPath, std::set &soNames) -{ - DIR *dir = NULL; - struct dirent dirEntry; - struct dirent *result; - int error; - - dir = opendir(dirPath); - IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open '%s'", dirPath); - - while (true) { - error = readdir_r(dir, &dirEntry, &result); - - if (error != 0) - continue; - - if (result == NULL) - break; - - if (dirEntry.d_type != DT_REG) - continue; - - soNames.insert(dirEntry.d_name); - } - - closedir(dir); - return true; -} +std::map ProviderLoader::__providerLibMap; ProviderLoader::ProviderLoader() { @@ -99,18 +72,45 @@ void ProviderLoader::__unload() bool ProviderLoader::loadAll() { /* TODO: Remove this function. This is a temporary solution. */ - std::set soNames; - std::string soPath; + std::set soPaths; - if (!getSharedObjectPaths(PROVIDER_SO_PATH, soNames)) { - return false; + for (auto it : __providerLibMap) { + std::string path = LIB_DIRECTORY; + path = path + LIB_PREFIX + it.second + LIB_EXTENSION; + soPaths.insert(path); } - for (std::set::iterator it = soNames.begin(); it != soNames.end(); ++it) { - soPath = PROVIDER_SO_PATH; - soPath = soPath + "/" + (*it); - __load(soPath.c_str(), NULL); + for (std::set::iterator it = soPaths.begin(); it != soPaths.end(); ++it) { + __load((*it).c_str(), NULL); } return true; } + +bool ProviderLoader::init() +{ + int size = ARRAY_SIZE(subjectLibraryList); + + for (int i = 0; i < size; ++i) { + __providerLibMap[subjectLibraryList[i].subject] = subjectLibraryList[i].library; + } + + return true; +} + +bool ProviderLoader::popTriggerTemplate(std::string &subject, int &operation, Json &attribute, Json &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/ProviderLoader.h b/src/ProviderLoader.h index fedca25..7623b89 100644 --- a/src/ProviderLoader.h +++ b/src/ProviderLoader.h @@ -17,10 +17,28 @@ #ifndef _CONTEXT_PROVIDER_LOADER_H_ #define _CONTEXT_PROVIDER_LOADER_H_ +#include + namespace ctx { class ContextProvider; + struct CompareSubjectName { + bool operator()(const char *left, const char *right) const { + const char *pl = left; + const char *pr = right; + while (pl != NULL && pr != NULL) { + if (*pl < *pr) + return true; + if (*pl > *pr) + return false; + ++pl; + ++pr; + } + return false; + } + }; + class ProviderLoader { public: ProviderLoader(); @@ -29,9 +47,14 @@ namespace ctx { ContextProvider* load(const char *subject); bool loadAll(); + static bool init(); + static bool popTriggerTemplate(std::string &subject, int &operation, Json &attribute, Json &option); + private: ContextProvider* __load(const char *soPath, const char *subject); void __unload(); + + static std::map __providerLibMap; }; } diff --git a/src/trigger/TemplateManager.cpp b/src/trigger/TemplateManager.cpp index 51dcb6c..b33e10a 100644 --- a/src/trigger/TemplateManager.cpp +++ b/src/trigger/TemplateManager.cpp @@ -96,10 +96,11 @@ void TemplateManager::applyTemplates() Json attributes; Json options; std::string owner; - bool unregister; + //bool unregister; std::string query; query.clear(); + /* while(__contextMgr->popTriggerItem(subject, operation, attributes, options, owner, unregister)) { if (unregister) { unregisterTemplate(subject); @@ -107,6 +108,12 @@ void TemplateManager::applyTemplates() registerTemplate(subject, operation, attributes, options, owner); } } + */ + + /* FIXME */ + while (ProviderLoader::popTriggerTemplate(subject, operation, attributes, options)) { + registerTemplate(subject, operation, attributes, options, ""); + } } void TemplateManager::registerTemplate(std::string subject, int operation, Json attributes, Json options, std::string owner) -- 2.7.4 From 242f8ef4a571d2287a396518be5f8c1e7a182dc5 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 26 Apr 2016 17:10:28 +0900 Subject: [PATCH 07/16] Apply on-demand loading of provider objects This patch only allows on-demand loading & creation of providers. 'destroy-on-idle' logic also needs to be implemented. Plus, implicit dummy subscribers for the data loggers need to be implemented. Change-Id: Id97871568d97d832b281c2c531af8495ce29f373 Signed-off-by: Mu-Woong Lee --- src/ContextManager.cpp | 180 +++++++++------------------------------- src/ContextManager.h | 16 +--- src/ProviderHandler.cpp | 88 ++++++++++++++------ src/ProviderHandler.h | 21 +++-- src/ProviderLoader.cpp | 60 +++++++------- src/ProviderLoader.h | 18 ++-- src/trigger/TemplateManager.cpp | 2 +- 7 files changed, 159 insertions(+), 226 deletions(-) diff --git a/src/ContextManager.cpp b/src/ContextManager.cpp index 75478a8..0e918a9 100644 --- a/src/ContextManager.cpp +++ b/src/ContextManager.cpp @@ -19,49 +19,23 @@ #include #include -#include #include #include -#include "Server.h" + #include "access_control/Privilege.h" +#include "trigger/TemplateManager.h" +#include "Server.h" #include "Request.h" #include "ProviderHandler.h" +#include "ProviderLoader.h" #include "ContextManager.h" -#include "trigger/TemplateManager.h" using namespace ctx; -struct TriggerItemFormat { - std::string subject; - int operation; - Json attributes; - Json options; - std::string owner; - bool unregister; - TriggerItemFormat(std::string subj, int ops, Json attr, Json opt, std::string own) : - subject(subj), - operation(ops), - attributes(attr), - options(opt), - owner(own) - { - unregister = false; - } - - TriggerItemFormat(std::string subj) : - subject(subj) - { - unregister = true; - } -}; - -static std::list __triggerItemList; - -ContextManager::ContextManager() : - __initialized(false) +ContextManager::ContextManager() { ContextProvider::__setContextManager(this); - __providerLoader.init(); + ProviderLoader::init(); } ContextManager::~ContextManager() @@ -71,111 +45,24 @@ ContextManager::~ContextManager() bool ContextManager::init() { - __initialized = __providerLoader.loadAll(); return true; } void ContextManager::release() { - for (auto& it : __providerHandleMap) { - delete it.second; - } - __providerHandleMap.clear(); -} - -bool ContextManager::registerProvider(const char *subject, const char *privilege, ContextProvider *provider) -{ - if (__providerHandleMap.find(subject) != __providerHandleMap.end()) { - _E("The provider for the subject '%s' is already registered.", subject); - return false; - } - - _SI("Subj: %s, Priv: %s", subject, privilege); - - ProviderHandler *handle = new(std::nothrow) ProviderHandler(subject, privilege, provider); - IF_FAIL_RETURN_TAG(handle, false, _E, "Memory allocation failed"); - - __providerHandleMap[subject] = handle; - return true; -} - -bool ContextManager::unregisterProvider(const char *subject) -{ - auto it = __providerHandleMap.find(subject); - if (it == __providerHandleMap.end()) { - _E("The provider for the subject '%s' is not found.", subject); - return false; - } - - delete it->second; - __providerHandleMap.erase(it); - - return true; -} - -bool ContextManager::registerTriggerItem(const char *subject, int operation, Json attributes, Json options, const char* owner) -{ - IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter"); - - if (!__initialized) { - __triggerItemList.push_back(TriggerItemFormat(subject, operation, attributes, options, (owner)? owner : "")); - } else { - trigger::TemplateManager* tmplMgr = trigger::TemplateManager::getInstance(); - IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed"); - tmplMgr->registerTemplate(subject, operation, attributes, options, owner); - } - - return true; -} - -bool ContextManager::unregisterTriggerItem(const char *subject) -{ - IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter"); - - if (!__initialized) { - __triggerItemList.push_back(TriggerItemFormat(subject)); - } else { - trigger::TemplateManager* tmplMgr = trigger::TemplateManager::getInstance(); - IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed"); - tmplMgr->unregisterTemplate(subject); - } - - return true; -} - -bool ContextManager::popTriggerItem(std::string &subject, int &operation, Json &attributes, Json &options, std::string& owner, bool& unregister) -{ - IF_FAIL_RETURN(!__triggerItemList.empty(), false); - - TriggerItemFormat format = __triggerItemList.front(); - __triggerItemList.pop_front(); - - subject = format.subject; - operation = format.operation; - attributes = format.attributes; - options = format.options; - owner = format.owner; - unregister = format.unregister; - - return true; + ProviderHandler::purge(); } void ContextManager::assignRequest(RequestInfo* request) { - if (__handleCustomRequest(request)) { - delete request; - return; - } - - auto it = __providerHandleMap.find(request->getSubject()); - if (it == __providerHandleMap.end()) { - _W("Unsupported subject"); + ProviderHandler *handle = ProviderHandler::getInstance(request->getSubject(), true); + if (!handle || !handle->isSupported()) { request->reply(ERR_NOT_SUPPORTED); delete request; return; } - if (!it->second->isAllowed(request->getCredentials())) { + if (!handle->isAllowed(request->getCredentials())) { _W("Permission denied"); request->reply(ERR_PERMISSION_DENIED); delete request; @@ -184,17 +71,17 @@ void ContextManager::assignRequest(RequestInfo* request) switch (request->getType()) { case REQ_SUBSCRIBE: - it->second->subscribe(request); + handle->subscribe(request); break; case REQ_UNSUBSCRIBE: - it->second->unsubscribe(request); + handle->unsubscribe(request); break; case REQ_READ: case REQ_READ_SYNC: - it->second->read(request); + handle->read(request); break; case REQ_WRITE: - it->second->write(request); + handle->write(request); break; case REQ_SUPPORT: request->reply(ERR_NONE); @@ -208,16 +95,24 @@ void ContextManager::assignRequest(RequestInfo* request) bool ContextManager::isSupported(const char *subject) { - auto it = __providerHandleMap.find(subject); - return (it != __providerHandleMap.end()); + 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 */ - auto it = __providerHandleMap.find(subject); - IF_FAIL_RETURN(it != __providerHandleMap.end(), false); - return it->second->isAllowed(creds); + + ProviderHandler *handle = ProviderHandler::getInstance(subject, true); + + if (!handle) + return false; + + return handle->isAllowed(creds); } void ContextManager::__publish(const char* subject, Json &option, int error, Json &dataUpdated) @@ -225,10 +120,10 @@ void ContextManager::__publish(const char* subject, Json &option, int error, Jso _I("Publishing '%s'", subject); _J("Option", option); - auto it = __providerHandleMap.find(subject); - IF_FAIL_VOID(it != __providerHandleMap.end()); + ProviderHandler *handle = ProviderHandler::getInstance(subject, false); + IF_FAIL_VOID_TAG(handle, _W, "No corresponding provider"); - it->second->publish(option, error, dataUpdated); + handle->publish(option, error, dataUpdated); } void ContextManager::__replyToRead(const char* subject, Json &option, int error, Json &dataRead) @@ -237,10 +132,10 @@ void ContextManager::__replyToRead(const char* subject, Json &option, int error, _J("Option", option); _J("Data", dataRead); - auto it = __providerHandleMap.find(subject); - IF_FAIL_VOID(it != __providerHandleMap.end()); + ProviderHandler *handle = ProviderHandler::getInstance(subject, false); + IF_FAIL_VOID_TAG(handle, _W, "No corresponding provider"); - it->second->replyToRead(option, error, dataRead); + handle->replyToRead(option, error, dataRead); } struct PublishedData { @@ -301,6 +196,12 @@ bool ContextManager::replyToRead(const char* subject, Json& option, int error, J return true; } +bool ContextManager::popTriggerTemplate(std::string &subject, int &operation, Json &attribute, Json &option) +{ + return ProviderLoader::popTriggerTemplate(subject, operation, attribute, option); +} + +/* bool ContextManager::__handleCustomRequest(RequestInfo* request) { std::string subject = request->getSubject(); @@ -308,7 +209,6 @@ bool ContextManager::__handleCustomRequest(RequestInfo* request) subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_REMOVE || subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_PUBLISH, false); -#if 0 const char* pkg_id = request->getPackageId(); if (pkg_id == NULL) { request->reply(ERR_OPERATION_FAILED); @@ -341,6 +241,6 @@ bool ContextManager::__handleCustomRequest(RequestInfo* request) } request->reply(error); -#endif return true; } +*/ diff --git a/src/ContextManager.h b/src/ContextManager.h index 884dd71..a6ebf57 100644 --- a/src/ContextManager.h +++ b/src/ContextManager.h @@ -19,14 +19,12 @@ #include #include -#include "ProviderLoader.h" namespace ctx { /* Forward declaration */ class Credentials; class RequestInfo; - class ProviderHandler; class ContextManager : public IContextManager { public: @@ -38,16 +36,13 @@ namespace ctx { void assignRequest(ctx::RequestInfo *request); bool isSupported(const char *subject); bool isAllowed(const Credentials *creds, const char *subject); - bool popTriggerItem(std::string &subject, int &operation, ctx::Json &attributes, ctx::Json &options, std::string &owner, bool& unregister); /* From the interface class */ - bool registerProvider(const char *subject, const char *privilege, ContextProvider *provider); - bool unregisterProvider(const char *subject); - bool registerTriggerItem(const char *subject, int operation, ctx::Json attributes, ctx::Json options, const char *owner = NULL); - bool unregisterTriggerItem(const char *subject); bool publish(const char *subject, ctx::Json &option, int error, ctx::Json &dataUpdated); bool replyToRead(const char *subject, ctx::Json &option, int error, ctx::Json &dataRead); + bool popTriggerTemplate(std::string &subject, int &operation, Json &attribute, Json &option); + private: ContextManager(); @@ -56,13 +51,6 @@ namespace ctx { void __publish(const char *subject, ctx::Json &option, int error, ctx::Json &dataUpdated); void __replyToRead(const char *subject, ctx::Json &option, int error, ctx::Json &dataRead); - /* For custom request */ - bool __handleCustomRequest(ctx::RequestInfo* request); - - bool __initialized; - std::map __providerHandleMap; - ProviderLoader __providerLoader; - friend class Server; }; /* class ContextManager */ diff --git a/src/ProviderHandler.cpp b/src/ProviderHandler.cpp index 8742495..a9521a2 100644 --- a/src/ProviderHandler.cpp +++ b/src/ProviderHandler.cpp @@ -22,10 +22,10 @@ using namespace ctx; -ProviderHandler::ProviderHandler(const char *subject, const char *privilege, ContextProvider *provider) : - __subject(subject), - __privilege(privilege), - __provider(provider) +std::map ProviderHandler::__instanceMap; + +ProviderHandler::ProviderHandler(const char *subject) : + __subject(subject) { } @@ -44,27 +44,65 @@ ProviderHandler::~ProviderHandler() delete __provider; } -bool ProviderHandler::isAllowed(const Credentials *creds) +/* TODO: Return proper error code */ +ProviderHandler* ProviderHandler::getInstance(const char *subject, bool force) { - IF_FAIL_RETURN(creds, true); /* In case of internal requests */ - return privilege_manager::isAllowed(creds, __privilege); + 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(); } -ContextProvider* ProviderHandler::__getProvider(RequestInfo *request) +bool ProviderHandler::isSupported() { - /* TODO: When implementing dynamic so loading... */ - return __provider; + return __provider->isSupported(); +} + +bool ProviderHandler::isAllowed(const Credentials *creds) +{ + 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, request->getId()); - ContextProvider *provider = __getProvider(request); - IF_FAIL_VOID(provider); - Json requestResult; - int error = provider->subscribe(request->getDescription().str(), &requestResult); + int error = __provider->subscribe(request->getDescription().str(), &requestResult); if (!request->reply(error, requestResult) || error != ERR_NONE) { delete request; @@ -102,12 +140,8 @@ void ProviderHandler::unsubscribe(RequestInfo *request) return; } - /* Get the provider */ - ContextProvider *provider = __getProvider(request); - IF_FAIL_VOID(provider); - /* Stop detecting the subject */ - int error = provider->unsubscribe(reqFound->getDescription()); + int error = __provider->unsubscribe(reqFound->getDescription()); request->reply(error); delete request; delete reqFound; @@ -117,11 +151,8 @@ void ProviderHandler::read(RequestInfo *request) { _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); - ContextProvider *provider = __getProvider(request); - IF_FAIL_VOID(provider); - Json requestResult; - int error = provider->read(request->getDescription().str(), &requestResult); + int error = __provider->read(request->getDescription().str(), &requestResult); if (!request->reply(error, requestResult) || error != ERR_NONE) { delete request; @@ -135,11 +166,8 @@ void ProviderHandler::write(RequestInfo *request) { _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); - ContextProvider *provider = __getProvider(request); - IF_FAIL_VOID(provider); - Json requestResult; - int error = provider->write(request->getDescription(), &requestResult); + int error = __provider->write(request->getDescription(), &requestResult); request->reply(error, requestResult); delete request; @@ -180,6 +208,12 @@ bool ProviderHandler::replyToRead(Json &option, int error, Json &dataRead) return true; } +bool ProviderHandler::__loadProvider() +{ + __provider = __loader.load(__subject); + return (__provider != NULL); +} + ProviderHandler::RequestList::iterator ProviderHandler::__findRequest(RequestList &reqList, Json &option) { diff --git a/src/ProviderHandler.h b/src/ProviderHandler.h index d8cea26..634819e 100644 --- a/src/ProviderHandler.h +++ b/src/ProviderHandler.h @@ -19,7 +19,9 @@ #include #include +#include #include +#include "ProviderLoader.h" namespace ctx { @@ -27,12 +29,11 @@ namespace ctx { class RequestInfo; class ProviderHandler { - public: typedef std::list RequestList; + typedef std::map InstanceMap; - ProviderHandler(const char *subject, const char *privilege, ContextProvider *provider); - ~ProviderHandler(); - + public: + bool isSupported(); bool isAllowed(const Credentials *creds); void subscribe(RequestInfo *request); @@ -43,14 +44,22 @@ namespace ctx { bool publish(ctx::Json &option, int error, ctx::Json &dataUpdated); bool replyToRead(ctx::Json &option, int error, ctx::Json &dataRead); + static ProviderHandler* getInstance(const char *subject, bool force); + static void purge(); + private: const char *__subject; - const char *__privilege; ContextProvider *__provider; RequestList __subscribeRequests; RequestList __readRequests; + ProviderLoader __loader; + + static InstanceMap __instanceMap; + + ProviderHandler(const char *subject); + ~ProviderHandler(); - ContextProvider* __getProvider(RequestInfo *request); + bool __loadProvider(); RequestList::iterator __findRequest(RequestList &reqList, Json &option); RequestList::iterator __findRequest(RequestList &reqList, std::string client, int reqId); RequestList::iterator __findRequest(RequestList::iterator begin, RequestList::iterator end, Json &option); diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp index c48a992..e99ba10 100644 --- a/src/ProviderLoader.cpp +++ b/src/ProviderLoader.cpp @@ -25,11 +25,12 @@ using namespace ctx; -typedef bool (*create_t)(); +typedef ContextProvider* (*create_t)(const char *subject); std::map ProviderLoader::__providerLibMap; -ProviderLoader::ProviderLoader() +ProviderLoader::ProviderLoader() : + __soHandle(NULL) { } @@ -40,51 +41,51 @@ ProviderLoader::~ProviderLoader() ContextProvider* ProviderLoader::load(const char *subject) { - /* TODO: Implement */ - return NULL; + ProviderLibMap::iterator it = __providerLibMap.find(subject); + if (it == __providerLibMap.end()) { + _W("No provider for '%s'", subject); + return NULL; + } + + std::string path = LIB_DIRECTORY; + path = path + LIB_PREFIX + it->second + LIB_EXTENSION; + + return __load(path.c_str(), subject); } ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) { _I("Load '%s' from '%s'", subject, soPath); - void *soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); - IF_FAIL_RETURN_TAG(soHandle, NULL, _E, "%s", dlerror()); + __soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); + IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", dlerror()); - create_t create = reinterpret_cast(dlsym(soHandle, "create")); + create_t create = reinterpret_cast(dlsym(__soHandle, "create")); if (!create) { _E("%s", dlerror()); - dlclose(soHandle); + dlclose(__soHandle); + __soHandle = NULL; return NULL; } - /* TODO: Update this part for dynamic loading */ - create(); + ContextProvider *prvd = create(subject); + if (!prvd) { + _W("No provider for '%s'", subject); + dlclose(__soHandle); + __soHandle = NULL; + return NULL; + } - return NULL; + return prvd; } void ProviderLoader::__unload() { - /* TODO: Implement */ -} - -bool ProviderLoader::loadAll() -{ - /* TODO: Remove this function. This is a temporary solution. */ - std::set soPaths; - - for (auto it : __providerLibMap) { - std::string path = LIB_DIRECTORY; - path = path + LIB_PREFIX + it.second + LIB_EXTENSION; - soPaths.insert(path); - } + if (!__soHandle) + return; - for (std::set::iterator it = soPaths.begin(); it != soPaths.end(); ++it) { - __load((*it).c_str(), NULL); - } - - return true; + dlclose(__soHandle); + __soHandle = NULL; } bool ProviderLoader::init() @@ -93,6 +94,7 @@ bool ProviderLoader::init() 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; diff --git a/src/ProviderLoader.h b/src/ProviderLoader.h index 7623b89..1eb303d 100644 --- a/src/ProviderLoader.h +++ b/src/ProviderLoader.h @@ -25,27 +25,26 @@ namespace ctx { struct CompareSubjectName { bool operator()(const char *left, const char *right) const { - const char *pl = left; - const char *pr = right; - while (pl != NULL && pr != NULL) { - if (*pl < *pr) + while (*left != '\0' && *right != '\0') { + if (*left < *right) return true; - if (*pl > *pr) + if (*left > *right) return false; - ++pl; - ++pr; + ++left; + ++right; } return false; } }; class ProviderLoader { + typedef std::map ProviderLibMap; + public: ProviderLoader(); ~ProviderLoader(); ContextProvider* load(const char *subject); - bool loadAll(); static bool init(); static bool popTriggerTemplate(std::string &subject, int &operation, Json &attribute, Json &option); @@ -54,7 +53,8 @@ namespace ctx { ContextProvider* __load(const char *soPath, const char *subject); void __unload(); - static std::map __providerLibMap; + void *__soHandle; + static ProviderLibMap __providerLibMap; }; } diff --git a/src/trigger/TemplateManager.cpp b/src/trigger/TemplateManager.cpp index b33e10a..08745e6 100644 --- a/src/trigger/TemplateManager.cpp +++ b/src/trigger/TemplateManager.cpp @@ -111,7 +111,7 @@ void TemplateManager::applyTemplates() */ /* FIXME */ - while (ProviderLoader::popTriggerTemplate(subject, operation, attributes, options)) { + while (__contextMgr->popTriggerTemplate(subject, operation, attributes, options)) { registerTemplate(subject, operation, attributes, options, ""); } } -- 2.7.4 From e03a14c13ad702d4d838eb8115697f104ccc858d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 27 Apr 2016 17:20:37 +0900 Subject: [PATCH 08/16] Add PolicyManager for enabling usage loggers at launch time Change-Id: I754e7962f88b65f61a41d5c644d2a4b19d2ded38 Signed-off-by: Mu-Woong Lee --- src/Server.cpp | 11 ++++++- src/policy/PolicyManager.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++ src/policy/PolicyManager.h | 48 ++++++++++++++++++++++++++++ src/policy/PolicyRequest.cpp | 48 ++++++++++++++++++++++++++++ src/policy/PolicyRequest.h | 37 ++++++++++++++++++++++ 5 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 src/policy/PolicyManager.cpp create mode 100644 src/policy/PolicyManager.h create mode 100644 src/policy/PolicyRequest.cpp create mode 100644 src/policy/PolicyRequest.h diff --git a/src/Server.cpp b/src/Server.cpp index 2617a4f..04a043c 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -23,6 +23,7 @@ #include "DBusServer.h" #include "ContextManager.h" #include "trigger/Trigger.h" +#include "policy/PolicyManager.h" #include "Server.h" static GMainLoop *mainloop = NULL; @@ -30,6 +31,7 @@ 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; /* TODO: re-organize activation & deactivation processes */ @@ -60,6 +62,10 @@ void ctx::Server::activate() result = __contextMgr->init(); 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"); + _I("Init Context Trigger"); __contextTrigger = new(std::nothrow) ctx::trigger::Trigger(); IF_FAIL_CATCH_TAG(__contextTrigger, _E, "Memory allocation failed"); @@ -84,7 +90,10 @@ void ctx::Server::release() if (__contextTrigger) __contextTrigger->release(); - _I("Release Analyzer Manager"); + _I("Release Policy Manager"); + delete __policyMgr; + + _I("Release Context Manager"); if (__contextMgr) __contextMgr->release(); diff --git a/src/policy/PolicyManager.cpp b/src/policy/PolicyManager.cpp new file mode 100644 index 0000000..c742254 --- /dev/null +++ b/src/policy/PolicyManager.cpp @@ -0,0 +1,74 @@ +/* + * 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 "../ContextManager.h" +#include "PolicyRequest.h" +#include "PolicyManager.h" + +using namespace ctx; + +PolicyManager::PolicyManager(ContextManager *contextMgr) : + __contextMgr(contextMgr) +{ + __init(); +} + +PolicyManager::~PolicyManager() +{ + __release(); +} + +void PolicyManager::__init() +{ + __subscribe(SUBJ_APP_LOGGER, __ridAppLogging); + __subscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); + __subscribe(SUBJ_SOCIAL_LOGGER, __ridSocialLogging); + + __subscribe(SUBJ_PLACE_DETECTION, __ridPlaceDetection); +} + +void PolicyManager::__release() +{ + __unsubscribe(SUBJ_APP_LOGGER, __ridAppLogging); + __unsubscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); + __unsubscribe(SUBJ_SOCIAL_LOGGER, __ridSocialLogging); + + __unsubscribe(SUBJ_PLACE_DETECTION, __ridPlaceDetection); +} + +void PolicyManager::__subscribe(const char *subject, int &reqId) +{ + static int rid = 0; + ++rid; + + reqId = rid; + + PolicyRequest *req = new(std::nothrow) PolicyRequest(REQ_SUBSCRIBE, reqId, subject, NULL); + IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed"); + + __contextMgr->assignRequest(req); +} + +void PolicyManager::__unsubscribe(const char *subject, int reqId) +{ + PolicyRequest *req = new(std::nothrow) PolicyRequest(REQ_UNSUBSCRIBE, reqId, subject, NULL); + IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed"); + + __contextMgr->assignRequest(req); +} diff --git a/src/policy/PolicyManager.h b/src/policy/PolicyManager.h new file mode 100644 index 0000000..e9d2d09 --- /dev/null +++ b/src/policy/PolicyManager.h @@ -0,0 +1,48 @@ +/* + * 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_ + +namespace ctx { + + class ContextManger; + + class PolicyManager { + public: + ~PolicyManager(); + + private: + PolicyManager(ContextManager *contextMgr); + + void __init(); + void __release(); + + void __subscribe(const char *subject, int &reqId); + void __unsubscribe(const char *subject, int reqId); + + ContextManager *__contextMgr; + int __ridAppLogging; + int __ridMediaLogging; + int __ridSocialLogging; + int __ridPlaceDetection; + + friend class Server; + }; + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_POLICY_MANAGER_H_ */ diff --git a/src/policy/PolicyRequest.cpp b/src/policy/PolicyRequest.cpp new file mode 100644 index 0000000..466dc2e --- /dev/null +++ b/src/policy/PolicyRequest.cpp @@ -0,0 +1,48 @@ +/* + * 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() +{ +} + +bool PolicyRequest::reply(int error) +{ + return true; +} + +bool PolicyRequest::reply(int error, ctx::Json &requestResult) +{ + return true; +} + +bool PolicyRequest::reply(int error, ctx::Json &requestResult, ctx::Json &dataRead) +{ + return true; +} + +bool PolicyRequest::publish(int error, ctx::Json &data) +{ + return true; +} diff --git a/src/policy/PolicyRequest.h b/src/policy/PolicyRequest.h new file mode 100644 index 0000000..940b203 --- /dev/null +++ b/src/policy/PolicyRequest.h @@ -0,0 +1,37 @@ +/* + * 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(); + + bool reply(int error); + bool reply(int error, ctx::Json &requestResult); + bool reply(int error, ctx::Json &requestResult, ctx::Json &dataRead); + bool publish(int error, ctx::Json &data); + }; + +} /* namespace ctx */ + +#endif /* End of _CONTEXT_POLICY_REQUEST_H_ */ -- 2.7.4 From b5726fa74193bd213d4420bc4d9dea3c3bd4f678 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 27 Apr 2016 18:40:14 +0900 Subject: [PATCH 09/16] Disable launch-time loading of social stats logger & place detector Change-Id: I361c68a50ce67a3afbb04fab259bad9f9b5b67f5 Signed-off-by: Mu-Woong Lee --- src/policy/PolicyManager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/policy/PolicyManager.cpp b/src/policy/PolicyManager.cpp index c742254..dba2674 100644 --- a/src/policy/PolicyManager.cpp +++ b/src/policy/PolicyManager.cpp @@ -38,18 +38,20 @@ void PolicyManager::__init() { __subscribe(SUBJ_APP_LOGGER, __ridAppLogging); __subscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); - __subscribe(SUBJ_SOCIAL_LOGGER, __ridSocialLogging); +#if 0 __subscribe(SUBJ_PLACE_DETECTION, __ridPlaceDetection); +#endif } void PolicyManager::__release() { __unsubscribe(SUBJ_APP_LOGGER, __ridAppLogging); __unsubscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); - __unsubscribe(SUBJ_SOCIAL_LOGGER, __ridSocialLogging); +#if 0 __unsubscribe(SUBJ_PLACE_DETECTION, __ridPlaceDetection); +#endif } void PolicyManager::__subscribe(const char *subject, int &reqId) -- 2.7.4 From c9c83b8775fcbff00f21ab633bea31ae1b54774c Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 11:56:00 +0900 Subject: [PATCH 10/16] Each provider handler is self-destructed if there is no remaining request Change-Id: I688b0bd36cd56eb91e754d2a5acd55ab14996557 Signed-off-by: Mu-Woong Lee --- src/ProviderHandler.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++------- src/ProviderHandler.h | 12 +++++++--- src/ProviderLoader.cpp | 2 +- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/ProviderHandler.cpp b/src/ProviderHandler.cpp index a9521a2..c7ab57e 100644 --- a/src/ProviderHandler.cpp +++ b/src/ProviderHandler.cpp @@ -20,17 +20,23 @@ #include "Request.h" #include "ProviderHandler.h" +#define DELETE_DELAY 10 + using namespace ctx; std::map ProviderHandler::__instanceMap; -ProviderHandler::ProviderHandler(const char *subject) : - __subject(subject) +ProviderHandler::ProviderHandler(const std::string &subject) : + __subject(subject), + __deleteScheduled(false) { + _D("Subject: %s", __subject.c_str()); } ProviderHandler::~ProviderHandler() { + _D("Subject: %s", __subject.c_str()); + for (RequestInfo*& info : __subscribeRequests) { delete info; } @@ -45,7 +51,7 @@ ProviderHandler::~ProviderHandler() } /* TODO: Return proper error code */ -ProviderHandler* ProviderHandler::getInstance(const char *subject, bool force) +ProviderHandler* ProviderHandler::getInstance(std::string subject, bool force) { InstanceMap::iterator it = __instanceMap.find(subject); @@ -99,7 +105,7 @@ bool ProviderHandler::isAllowed(const Credentials *creds) void ProviderHandler::subscribe(RequestInfo *request) { - _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->subscribe(request->getDescription().str(), &requestResult); @@ -114,7 +120,7 @@ void ProviderHandler::subscribe(RequestInfo *request) void ProviderHandler::unsubscribe(RequestInfo *request) { - _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _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()); @@ -145,11 +151,14 @@ void ProviderHandler::unsubscribe(RequestInfo *request) 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, request->getId()); + _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->read(request->getDescription().str(), &requestResult); @@ -164,13 +173,16 @@ void ProviderHandler::read(RequestInfo *request) void ProviderHandler::write(RequestInfo *request) { - _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->write(request->getDescription(), &requestResult); request->reply(error, requestResult); delete request; + + /* If idle, self destruct */ + __scheduleToDelete(); } bool ProviderHandler::publish(Json &option, int error, Json &dataUpdated) @@ -205,15 +217,46 @@ bool ProviderHandler::replyToRead(Json &option, int error, Json &dataRead) __readRequests.erase(prev); } + /* If idle, self destruct */ + __scheduleToDelete(); + return true; } bool ProviderHandler::__loadProvider() { - __provider = __loader.load(__subject); + __provider = __loader.load(__subject.c_str()); return (__provider != NULL); } +bool ProviderHandler::__idle() +{ + return __subscribeRequests.empty() && __readRequests.empty(); +} + +void ProviderHandler::__scheduleToDelete() +{ + if (!__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, Json &option) { diff --git a/src/ProviderHandler.h b/src/ProviderHandler.h index 634819e..a86e2ef 100644 --- a/src/ProviderHandler.h +++ b/src/ProviderHandler.h @@ -44,26 +44,32 @@ namespace ctx { bool publish(ctx::Json &option, int error, ctx::Json &dataUpdated); bool replyToRead(ctx::Json &option, int error, ctx::Json &dataRead); - static ProviderHandler* getInstance(const char *subject, bool force); + static ProviderHandler* getInstance(std::string subject, bool force); static void purge(); private: - const char *__subject; + std::string __subject; ContextProvider *__provider; RequestList __subscribeRequests; RequestList __readRequests; ProviderLoader __loader; + bool __deleteScheduled; static InstanceMap __instanceMap; - ProviderHandler(const char *subject); + ProviderHandler(const std::string &subject); ~ProviderHandler(); bool __loadProvider(); + bool __idle(); + void __scheduleToDelete(); + RequestList::iterator __findRequest(RequestList &reqList, Json &option); RequestList::iterator __findRequest(RequestList &reqList, std::string client, int reqId); RequestList::iterator __findRequest(RequestList::iterator begin, RequestList::iterator end, Json &option); + static gboolean __deletor(gpointer data); + }; /* class ProviderHandler */ } /* namespace ctx */ diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp index e99ba10..b84ae93 100644 --- a/src/ProviderLoader.cpp +++ b/src/ProviderLoader.cpp @@ -55,7 +55,7 @@ ContextProvider* ProviderLoader::load(const char *subject) ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) { - _I("Load '%s' from '%s'", subject, soPath); + _SI("Load '%s' from '%s'", subject, soPath); __soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", dlerror()); -- 2.7.4 From 440c73a713c81457e77f99caa05e6bed42b1c243 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 14:52:44 +0900 Subject: [PATCH 11/16] Add some missing self-destruction scheduling points of ProviderHandler Change-Id: I4ba6c014f5d4f6341c481b1f93541a1041c44f7f Signed-off-by: Mu-Woong Lee --- src/ProviderHandler.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ProviderHandler.cpp b/src/ProviderHandler.cpp index c7ab57e..a99f6de 100644 --- a/src/ProviderHandler.cpp +++ b/src/ProviderHandler.cpp @@ -20,7 +20,7 @@ #include "Request.h" #include "ProviderHandler.h" -#define DELETE_DELAY 10 +#define DELETE_DELAY 20 using namespace ctx; @@ -85,11 +85,17 @@ void ProviderHandler::purge() 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; @@ -112,6 +118,8 @@ void ProviderHandler::subscribe(RequestInfo *request) if (!request->reply(error, requestResult) || error != ERR_NONE) { delete request; + /* If idle, self destruct */ + __scheduleToDelete(); return; } @@ -165,6 +173,8 @@ void ProviderHandler::read(RequestInfo *request) if (!request->reply(error, requestResult) || error != ERR_NONE) { delete request; + /* If idle, self destruct */ + __scheduleToDelete(); return; } -- 2.7.4 From bfa023b7f3a0e0cde10c1c4dc14005478062cf30 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 15:31:50 +0900 Subject: [PATCH 12/16] Monitor WiFi state continuously For usage logging, the current WiFi address needs to be tracked continuously. Change-Id: I1b584cb86db2a1ef1c2ff97d0a49e4e923fabc3f Signed-off-by: Mu-Woong Lee --- src/policy/PolicyManager.cpp | 4 ++++ src/policy/PolicyManager.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/policy/PolicyManager.cpp b/src/policy/PolicyManager.cpp index dba2674..76cd5e3 100644 --- a/src/policy/PolicyManager.cpp +++ b/src/policy/PolicyManager.cpp @@ -36,6 +36,9 @@ PolicyManager::~PolicyManager() void PolicyManager::__init() { + /* TODO: WiFi API has multi-session support issue. + The issue should be fixed, or walkarouned first. */ + __subscribe(SUBJ_STATE_WIFI, __ridWifiState); __subscribe(SUBJ_APP_LOGGER, __ridAppLogging); __subscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); @@ -46,6 +49,7 @@ void PolicyManager::__init() void PolicyManager::__release() { + __unsubscribe(SUBJ_STATE_WIFI, __ridWifiState); __unsubscribe(SUBJ_APP_LOGGER, __ridAppLogging); __unsubscribe(SUBJ_MEDIA_LOGGER, __ridMediaLogging); diff --git a/src/policy/PolicyManager.h b/src/policy/PolicyManager.h index e9d2d09..f402016 100644 --- a/src/policy/PolicyManager.h +++ b/src/policy/PolicyManager.h @@ -35,6 +35,7 @@ namespace ctx { void __unsubscribe(const char *subject, int reqId); ContextManager *__contextMgr; + int __ridWifiState; int __ridAppLogging; int __ridMediaLogging; int __ridSocialLogging; -- 2.7.4 From 61851610933101af4dac429af34e75634079ea32 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 15:33:19 +0900 Subject: [PATCH 13/16] Implement PolicyRequest::getClient() member function It should not return NULL. Change-Id: I9bb2508937aad266a8c9cd73a22dcced89856de2 Signed-off-by: Mu-Woong Lee --- src/policy/PolicyRequest.cpp | 5 +++++ src/policy/PolicyRequest.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/policy/PolicyRequest.cpp b/src/policy/PolicyRequest.cpp index 466dc2e..63cf8ae 100644 --- a/src/policy/PolicyRequest.cpp +++ b/src/policy/PolicyRequest.cpp @@ -27,6 +27,11 @@ PolicyRequest::~PolicyRequest() { } +const char* PolicyRequest::getClient() +{ + return "POLICY"; +} + bool PolicyRequest::reply(int error) { return true; diff --git a/src/policy/PolicyRequest.h b/src/policy/PolicyRequest.h index 940b203..2ed28c7 100644 --- a/src/policy/PolicyRequest.h +++ b/src/policy/PolicyRequest.h @@ -26,6 +26,8 @@ namespace ctx { PolicyRequest(int type, int reqId, const char *subj, const char *desc); ~PolicyRequest(); + const char* getClient(); + bool reply(int error); bool reply(int error, ctx::Json &requestResult); bool reply(int error, ctx::Json &requestResult, ctx::Json &dataRead); -- 2.7.4 From 5ddf11df43638c7e63962db784ed545a5af0cd69 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 16:31:05 +0900 Subject: [PATCH 14/16] Switch to gmodule from linux dl functions Change-Id: I09541f9cf01581796a6b724287e4e7b6a1953b76 Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 3 ++- packaging/context-service.spec | 1 + src/ProviderLoader.cpp | 20 +++++++++++--------- src/ProviderLoader.h | 3 ++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c142e7..5ee65eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ MESSAGE("Sources: ${SRCS}") # Dependencies SET(DEPS + gmodule-2.0 vconf capi-system-info capi-system-device @@ -43,7 +44,7 @@ FOREACH(flag ${daemon_pkg_CFLAGS}) ENDFOREACH(flag) ADD_EXECUTABLE(${target} ${SRCS}) -TARGET_LINK_LIBRARIES(${target} ${daemon_pkg_LDFLAGS} -ldl) +TARGET_LINK_LIBRARIES(${target} ${daemon_pkg_LDFLAGS}) # Installing Daemon INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/packaging/context-service.spec b/packaging/context-service.spec index 5495f55..091dfb2 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -16,6 +16,7 @@ ExcludeArch: %{arm} aarch64 %ix86 x86_64 BuildRequires: cmake BuildRequires: sed +BuildRequires: pkgconfig(gmodule-2.0) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-device) diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp index b84ae93..10006a3 100644 --- a/src/ProviderLoader.cpp +++ b/src/ProviderLoader.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include #include #include #include @@ -57,21 +56,24 @@ ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) { _SI("Load '%s' from '%s'", subject, soPath); - __soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); - IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", dlerror()); + __soHandle = g_module_open(soPath, G_MODULE_BIND_LAZY); + IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", g_module_error()); - create_t create = reinterpret_cast(dlsym(__soHandle, "create")); - if (!create) { - _E("%s", dlerror()); - dlclose(__soHandle); + gpointer symbol; + + if (!g_module_symbol(__soHandle, "create", &symbol) || symbol == NULL) { + _E("%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); - dlclose(__soHandle); + g_module_close(__soHandle); __soHandle = NULL; return NULL; } @@ -84,7 +86,7 @@ void ProviderLoader::__unload() if (!__soHandle) return; - dlclose(__soHandle); + g_module_close(__soHandle); __soHandle = NULL; } diff --git a/src/ProviderLoader.h b/src/ProviderLoader.h index 1eb303d..ab5a427 100644 --- a/src/ProviderLoader.h +++ b/src/ProviderLoader.h @@ -17,6 +17,7 @@ #ifndef _CONTEXT_PROVIDER_LOADER_H_ #define _CONTEXT_PROVIDER_LOADER_H_ +#include #include namespace ctx { @@ -53,7 +54,7 @@ namespace ctx { ContextProvider* __load(const char *soPath, const char *subject); void __unload(); - void *__soHandle; + GModule *__soHandle; static ProviderLibMap __providerLibMap; }; -- 2.7.4 From f0970750de2492417c1792331abd608d75ebc167 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 28 Apr 2016 17:59:23 +0900 Subject: [PATCH 15/16] Prevent unloading non-unloadable providers Change-Id: Ieaabddfac925042e8097a17c326c9262fe39329c Signed-off-by: Mu-Woong Lee --- src/ProviderHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProviderHandler.cpp b/src/ProviderHandler.cpp index a99f6de..b7f17dc 100644 --- a/src/ProviderHandler.cpp +++ b/src/ProviderHandler.cpp @@ -246,7 +246,7 @@ bool ProviderHandler::__idle() void ProviderHandler::__scheduleToDelete() { - if (!__deleteScheduled && __idle()) { + 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); -- 2.7.4 From 745d9e2ca6bc2d06ce2e668f9726382ecfd1f565 Mon Sep 17 00:00:00 2001 From: Somin Kim Date: Mon, 2 May 2016 17:18:42 +0900 Subject: [PATCH 16/16] Check if item is supported before template request Change-Id: I27d14eebf3adbc6a2946a8c7a92392f0dd4fc2fa Signed-off-by: Somin Kim --- src/trigger/TemplateManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/trigger/TemplateManager.cpp b/src/trigger/TemplateManager.cpp index 08745e6..5a2b945 100644 --- a/src/trigger/TemplateManager.cpp +++ b/src/trigger/TemplateManager.cpp @@ -179,6 +179,9 @@ std::string TemplateManager::__removeTemplate(std::string &subject) int TemplateManager::getTemplate(std::string &subject, Json* tmpl) { + if (!__contextMgr->isSupported(subject.c_str())) + return ERR_NOT_SUPPORTED; + // Update latest template information std::string q = "SELECT * FROM context_trigger_template WHERE name = '" + subject + "'"; -- 2.7.4