From: Somin Kim Date: Mon, 11 Jan 2016 09:31:25 +0000 (+0900) Subject: Added trigger rule class. X-Git-Tag: submit/tizen/20160118.014643^2~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e17762697ef5a0710f2c01ff3f9fc68e76ed5d75;p=platform%2Fcore%2Fcontext%2Fcontext-service.git Added trigger rule class. - Removed script generator, clips handler. - Timer event/condition not working - Condition not working Change-Id: I7e22e692825f7ddf25539d583d10389428cc2471 Signed-off-by: Somin Kim --- diff --git a/src/context_mgr_impl.h b/src/context_mgr_impl.h index f884761..5281595 100644 --- a/src/context_mgr_impl.h +++ b/src/context_mgr_impl.h @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/src/context_trigger/action_manager.cpp b/src/context_trigger/action_manager.cpp new file mode 100644 index 0000000..ccf7b4e --- /dev/null +++ b/src/context_trigger/action_manager.cpp @@ -0,0 +1,214 @@ +/* + * 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 +#include +#include "../dbus_server_impl.h" +//#include +//#include +//#include +#include "action_manager.h" + +static void trigger_action_app_control(ctx::json& action); +static void trigger_action_notification(ctx::json& action, std::string app_id); // TODO appid? creator? +static void trigger_action_dbus_call(ctx::json& action); + +void ctx::action_manager::trigger_action(ctx::json& action, std::string creator) +{ + std::string type; + action.get(NULL, CT_RULE_ACTION_TYPE, &type); + + if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) { + trigger_action_app_control(action); + } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) { + trigger_action_notification(action, creator); + } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) { + trigger_action_dbus_call(action); + } +} + +void trigger_action_app_control(ctx::json& action) +{ + int error; + std::string appctl_str; + action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str); + + char* str = static_cast(malloc(appctl_str.length())); + if (str == NULL) { + _E("Memory allocation failed"); + return; + } + appctl_str.copy(str, appctl_str.length(), 0); + bundle_raw* encoded = reinterpret_cast(str); + bundle* appctl_bundle = bundle_decode(encoded, appctl_str.length()); + + app_control_h app = NULL; + app_control_create(&app); + app_control_import_from_bundle(app, appctl_bundle); + + 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(appctl_bundle); + 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 trigger_action_notification(ctx::json& action, std::string app_id) // TODO appid? creator? +{ + int error; + notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI); + std::string title; + if (action.get(NULL, CT_RULE_ACTION_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(NULL, CT_RULE_ACTION_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 image_path; + if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &image_path)) { + error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, image_path.c_str()); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Set notification icon image failed(%d)", error); + } + } + + std::string appctl_str; + char* str = NULL; + bundle_raw* encoded = NULL; + bundle* appctl_bundle = NULL; + app_control_h app = NULL; + if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str)) { + str = static_cast(malloc(appctl_str.length())); + if (str == NULL) { + _E("Memory allocation failed"); + notification_free(notification); + return; + } + appctl_str.copy(str, appctl_str.length(), 0); + encoded = reinterpret_cast(str); + appctl_bundle = bundle_decode(encoded, appctl_str.length()); + + app_control_create(&app); + app_control_import_from_bundle(app, appctl_bundle); + + 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 (!app_id.empty()) { + error = notification_set_pkgname(notification, app_id.c_str()); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Set pkgname(%s) failed(%d)", app_id.c_str(), error); + } + } + + 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); + } + + 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); + } + + if (!silent) { + error = notification_set_sound(notification, NOTIFICATION_SOUND_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); + } + } + } + + error = notification_post(notification); + if (error != NOTIFICATION_ERROR_NONE) { + _E("Post notification failed(%d)", error); + } else { + _D("Post notification succeeded"); + } + + bundle_free(appctl_bundle); + 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 trigger_action_dbus_call(ctx::json& action) +{ + std::string bus_name, object, iface, method; + GVariant *param = NULL; + + action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name); + IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name"); + + action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object); + IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path"); + + action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface); + IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name"); + + action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method); + IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name"); + + action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, ¶m); + + ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), param); +} diff --git a/src/context_trigger/action_manager.h b/src/context_trigger/action_manager.h new file mode 100644 index 0000000..0bce8ea --- /dev/null +++ b/src/context_trigger/action_manager.h @@ -0,0 +1,34 @@ +/* + * 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_ACTION_MANAGER_H__ +#define __CONTEXT_ACTION_MANAGER_H__ + +#include + +namespace ctx { + + class json; + + namespace action_manager { + + void trigger_action(ctx::json& action, std::string creator); + + } + +} /* namespace ctx */ + +#endif /* End of __CONTEXT_ACTION_MANAGER_H__ */ diff --git a/src/context_trigger/clips_handler.cpp b/src/context_trigger/clips_handler.cpp deleted file mode 100644 index 2f2b749..0000000 --- a/src/context_trigger/clips_handler.cpp +++ /dev/null @@ -1,263 +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 "clips_handler.h" -#include "rule_manager.h" - -extern "C" -{ -#include -} - -static void* env = NULL; -static ctx::rule_manager* rule_mgr = NULL; -static int string_to_int(std::string str); - -ctx::clips_handler::clips_handler(ctx::rule_manager* rm) -{ - rule_mgr = rm; - init_environment(); - _D(YELLOW("Clips handler initialized")); -} - -ctx::clips_handler::~clips_handler() -{ - if (env) { - DestroyEnvironment(env); - env = NULL; - } - - _D(YELLOW("Clips handler destroyed")); -} - -int ctx::clips_handler::init_environment(void) -{ - if (env) { - _D("Clips environment already created"); - return ERR_NONE; - } - - env = CreateEnvironment(); - if (!env) { - _E("Create environment failed"); - return ERR_OPERATION_FAILED; - } - - char* func_name = strdup("execute_action"); - char* restrictions = strdup("1s"); - - if (func_name == NULL || restrictions == NULL) { - _E("Memory allocation failed"); - free(func_name); - free(restrictions); - return ERR_OUT_OF_MEMORY; - } - - EnvDefineFunction2(env, func_name, 'i', PTIEF execute_action, func_name, restrictions); - free(func_name); - free(restrictions); - - return ERR_NONE; -} - -int ctx::clips_handler::define_template(std::string& script) -{ - IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Deftemplate failed"); - return ERR_NONE; -} - -int ctx::clips_handler::define_class(std::string& script) -{ - IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defclass failed"); - return ERR_NONE; -} - -int ctx::clips_handler::define_rule(std::string& script) -{ - IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defrule failed"); - return ERR_NONE; -} - -int ctx::clips_handler::env_build(std::string& script) -{ - ASSERT_NOT_NULL(env); - if (script.length() == 0) - return ERR_INVALID_PARAMETER; - - _I("EnvBuild script (%s)", script.c_str()); - int ret = EnvBuild(env, script.c_str()); - - return (ret == 1)? ERR_NONE : ERR_OPERATION_FAILED; -} - -int ctx::clips_handler::run_environment() -{ - ASSERT_NOT_NULL(env); - - int fired_rule_num = EnvRun(env, -1); - IF_FAIL_RETURN(fired_rule_num >= 0, ERR_OPERATION_FAILED); - - return ERR_NONE; -} - -int ctx::clips_handler::add_fact(std::string& fact) -{ - ASSERT_NOT_NULL(env); - if (fact.length() == 0) - return ERR_INVALID_PARAMETER; - - void* assert_fact = EnvAssertString(env, fact.c_str()); - IF_FAIL_RETURN_TAG(assert_fact, ERR_OPERATION_FAILED, _E, "Fact assertion failed"); - - return ERR_NONE; -} - -int ctx::clips_handler::route_string_command(std::string& script) -{ - ASSERT_NOT_NULL(env); - if (script.length() == 0) - return ERR_INVALID_PARAMETER; - - int error; - if (RouteCommand(env, script.c_str(), TRUE)){ - _D("Route command succeeded(%s).", script.c_str()); - error = ERR_NONE; - } else { - _E("Route command failed"); - error = ERR_OPERATION_FAILED; - } - - return error; -} - -int ctx::clips_handler::make_instance(std::string& script) -{ - ASSERT_NOT_NULL(env); - if (script.length() == 0) - return ERR_INVALID_PARAMETER; - - int error; - if (EnvMakeInstance(env, script.c_str())){ - _D("Make instance succeeded - %s", script.c_str()); - error = ERR_NONE; - } else { - _E("Make instance failed"); - error = ERR_OPERATION_FAILED; - } - - return error; -} - -int ctx::clips_handler::unmake_instance(std::string& instance_name) -{ - ASSERT_NOT_NULL(env); - if (instance_name.length() == 0) - return ERR_INVALID_PARAMETER; - - void* instance = find_instance_internal(instance_name); - if (!instance) { - _E("Cannot find instance(%s).", instance_name.c_str()); - return ERR_INVALID_PARAMETER; - } - - if (!EnvUnmakeInstance(env, instance)){ - _E("Unmake instance failed"); - return ERR_OPERATION_FAILED; - } - - _D("Unmake instance succeeded(%s).", instance_name.c_str()); - return ERR_NONE; -} - -int ctx::clips_handler::execute_action(void) -{ - ASSERT_NOT_NULL(env); - - const char* result = EnvRtnLexeme(env, 1); - if (!result) { - _E("Failed to get returned rule id"); - return ERR_OPERATION_FAILED; - } - std::string rule_id = result; - std::string id_str = rule_id.substr(4); - - int id = string_to_int(id_str); - rule_mgr->on_rule_triggered(id); - - return ERR_NONE; -} - -bool ctx::clips_handler::find_instance(std::string& instance_name) -{ - ASSERT_NOT_NULL(env); - - if (find_instance_internal(instance_name)) { - _D("[%s] already exists", instance_name.c_str()); - return true; - } - - return false; -} - -void* ctx::clips_handler::find_instance_internal(std::string& instance_name) -{ - void* instance = EnvFindInstance(env, NULL, instance_name.c_str(), TRUE); - return instance; -} - -int string_to_int(std::string str) -{ - int i; - std::istringstream convert(str); - - if (!(convert >> i)) - i = 0; - - return i; -} - -bool ctx::clips_handler::define_global_variable_string(std::string variable_name, std::string value) -{ - std::string script = "(defglobal ?*"; - script += variable_name; - script += "* = \""; - script += value; - script += "\")"; - - IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, false, _E, "Defglobal failed"); - return true; -} - -bool ctx::clips_handler::set_global_variable_string(std::string variable_name, std::string value) -{ - ASSERT_NOT_NULL(env); - if (variable_name.length() == 0) - return false; - - DATA_OBJECT data; - SetType(data, STRING); - SetValue(data, EnvAddSymbol(env, value.c_str())) ; - - int ret = EnvSetDefglobalValue(env, variable_name.c_str(), &data); - - IF_FAIL_RETURN_TAG(ret == 1, false, _E, "Set global variable(%s) failed", variable_name.c_str()); - return true; -} diff --git a/src/context_trigger/clips_handler.h b/src/context_trigger/clips_handler.h deleted file mode 100644 index 0ebb747..0000000 --- a/src/context_trigger/clips_handler.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 __CLIPS_HANDLER_H__ -#define __CLIPS_HANDLER_H__ - -namespace ctx { - - class json; - class rule_manager; - - class clips_handler { - public: - clips_handler(ctx::rule_manager* rm); - ~clips_handler(); - - int define_template(std::string& script); - int define_class(std::string& script); - int define_rule(std::string& script); - int run_environment(); - int add_fact(std::string& fact); - int route_string_command(std::string& fact); - int make_instance(std::string& script); - int unmake_instance(std::string& instance_name); - static int execute_action(void); - bool find_instance(std::string& instance_name); - bool define_global_variable_string(std::string variable_name, std::string value); - bool set_global_variable_string(std::string variable_name, std::string value); - - private: - clips_handler(); - int init_environment(void); - int env_build(std::string& script); - void* find_instance_internal(std::string& instance_name); - - }; /* class clips_handler */ - -} /* namespace ctx */ - -#endif /* End of __CLIPS_HANDLER_H__ */ diff --git a/src/context_trigger/context_listener_iface.h b/src/context_trigger/context_listener_iface.h new file mode 100644 index 0000000..657f07f --- /dev/null +++ b/src/context_trigger/context_listener_iface.h @@ -0,0 +1,35 @@ +/* + * 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_LISTENER_INTERFACE_H__ +#define __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__ + +namespace ctx { + /* Forward Declaration */ + class json; + + class context_listener_iface { + public: + virtual ~context_listener_iface() {} + + virtual void on_event_received(std::string name, ctx::json option, ctx::json data) = 0; + + virtual void on_condition_received(std::string name, ctx::json option, ctx::json data) = 0; + }; + +} /* namespace ctx */ + +#endif /* End of __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__ */ diff --git a/src/context_trigger/context_monitor.cpp b/src/context_trigger/context_monitor.cpp index 98c5167..b86d3dc 100644 --- a/src/context_trigger/context_monitor.cpp +++ b/src/context_trigger/context_monitor.cpp @@ -15,13 +15,13 @@ */ #include -#include -#include -#include "trigger.h" #include "../access_control/privilege.h" +#include "../context_mgr_impl.h" #include "context_monitor.h" #include "fact_request.h" +#include "timer.h" #include "timer_types.h" +#include "context_listener_iface.h" static int last_rid; static int last_err; @@ -50,41 +50,38 @@ ctx::context_monitor::~context_monitor() delete timer; } -bool ctx::context_monitor::init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr) +bool ctx::context_monitor::init(ctx::context_manager_impl* ctx_mgr) { _context_mgr = ctx_mgr; - _trigger = tr; - timer = new(std::nothrow) trigger_timer(_trigger); - IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed"); +/* timer = new(std::nothrow) trigger_timer(_trigger); TODO + IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");*/ return true; } -int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::json event) +int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener) { if (subject.compare(TIMER_EVENT_SUBJECT) == 0) { // option is event json in case of ON_TIME - return timer->subscribe(event); +// return timer->subscribe(event); + return ERR_NONE; } - ctx::json eoption = NULL; - event.get(NULL, CT_RULE_EVENT_OPTION, &eoption); - - int req_id = _subscribe(subject.c_str(), &eoption, true); + int req_id = _subscribe(subject.c_str(), &option, listener, true); IF_FAIL_RETURN_TAG(req_id > 0, ERR_OPERATION_FAILED, _E, "Subscribe event failed"); _D(YELLOW("Subscribe event(rule%d). req%d"), rule_id, req_id); return ERR_NONE; } -int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wait_response) +int ctx::context_monitor::_subscribe(const char* subject, json* option, context_listener_iface* listener, bool wait_response) { IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER); int rid = find_sub(subject, option); if (rid > 0) { - increase_sub(rid); + add_listener(rid, listener); _D("Duplicated request for %s", subject); return rid; } @@ -96,7 +93,7 @@ int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wai IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed"); send_request(req); //TODO: what happens if the request actually takes more time than the timeout - add_sub(rid, subject, option); + add_sub(rid, subject, option, listener); IF_FAIL_RETURN_TAG(wait_response, rid, _D, "Ignoring response for %s", subject); @@ -109,22 +106,20 @@ int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wai return rid; } -int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option) +int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener) { if (subject.compare(TIMER_EVENT_SUBJECT) == 0) { - return timer->unsubscribe(option); +// return timer->unsubscribe(option); + return ERR_NONE; } - ctx::json eoption = NULL; - option.get(NULL, CT_RULE_EVENT_OPTION, &eoption); - - int rid = find_sub(subject.c_str(), &eoption); + int rid = find_sub(subject.c_str(), &option); if (rid < 0) { _D("Invalid unsubscribe request"); return ERR_INVALID_PARAMETER; } - if (decrease_sub(rid) <= 0) { + if (remove_listener(rid, listener) <= 0) { _unsubscribe(subject.c_str(), rid); } _D(YELLOW("Unsubscribe event(rule%d). req%d"), rule_id, rid); @@ -149,22 +144,23 @@ bool ctx::context_monitor::send_request(fact_request* req) int ctx::context_monitor::read(std::string subject, json option, ctx::json* result) { - bool ret; if (subject.compare(TIMER_CONDITION_SUBJECT) == 0) { - return timer->read(result); +// return timer->read(result); TODO + return ERR_NONE; } - context_fact fact; - ret = _read(subject.c_str(), &option, fact); +/* context_fact fact; + bool ret = _read(subject.c_str(), &option, fact); IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Read fact failed"); *result = fact.get_data(); - +*/ return ERR_NONE; } -bool ctx::context_monitor::_read(const char* subject, json* option, context_fact& fact) +/*bool ctx::context_monitor::_read(const char* subject, json* option, context_fact& fact) { + // TODO implement read async IF_FAIL_RETURN(subject, false); int rid = generate_req_id(); @@ -187,7 +183,7 @@ bool ctx::context_monitor::_read(const char* subject, json* option, context_fact return true; } - +*/ bool ctx::context_monitor::is_supported(std::string subject) { if (subject.compare(TIMER_EVENT_SUBJECT) == 0 @@ -202,8 +198,8 @@ bool ctx::context_monitor::is_allowed(const char *client, const char *subject) { if (STR_EQ(subject, TIMER_EVENT_SUBJECT)) return true; - //TODO: re-implement above in the proper 3.0 style - // return privilege_manager::is_allowed(client, PRIV_ALARM_SET); + //TODO: re-implement above in the proper 3.0 style + // return privilege_manager::is_allowed(client, PRIV_ALARM_SET); if (STR_EQ(subject, TIMER_CONDITION_SUBJECT)) return true; @@ -220,6 +216,7 @@ bool ctx::context_monitor::get_fact_definition(std::string &subject, int &operat int ctx::context_monitor::find_sub(const char* subject, json* option) { + // @return request id json opt_j; if (option) { opt_j = *option; @@ -234,13 +231,13 @@ int ctx::context_monitor::find_sub(const char* subject, json* option) return -1; } -bool ctx::context_monitor::add_sub(int sid, const char* subject, json* option) +bool ctx::context_monitor::add_sub(int sid, const char* subject, json* option, context_listener_iface* listener) { subscr_info_s *info = new(std::nothrow) subscr_info_s(sid, subject, option); IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed"); + info->listener_list.push_back(listener); subscr_map[sid] = info; - return true; } @@ -262,29 +259,41 @@ void ctx::context_monitor::remove_sub(const char* subject, json* option) void ctx::context_monitor::remove_sub(int sid) { + subscr_info_s* info = subscr_map[sid]; + info->listener_list.clear(); + + delete info; subscr_map.erase(sid); return; } -int ctx::context_monitor::increase_sub(int sid) +int ctx::context_monitor::add_listener(int sid, context_listener_iface* listener) { + // @return number of listeners for the corresponding sid subscr_map_t::iterator it = subscr_map.find(sid); subscr_info_s* info = it->second; - info->cnt++; + info->listener_list.push_back(listener); - return info->cnt; + return info->listener_list.size(); } -int ctx::context_monitor::decrease_sub(int sid) +int ctx::context_monitor::remove_listener(int sid, context_listener_iface* listener) { + // @return number of listeners for the corresponding sid subscr_map_t::iterator it = subscr_map.find(sid); subscr_info_s* info = it->second; - info->cnt--; - return info->cnt; + for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) { + if (*it2 == listener) { + info->listener_list.erase(it2); + break; + } + } + + return info->listener_list.size(); } void ctx::context_monitor::reply_result(int req_id, int error, json* request_result, json* fact) @@ -299,8 +308,12 @@ void ctx::context_monitor::publish_fact(int req_id, int error, const char* subje { _D(YELLOW("Fact received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str()); - // TODO: deliver fact to each rule instance + subscr_map_t::iterator it = subscr_map.find(req_id); + IF_FAIL_VOID_TAG(it != subscr_map.end(), _E, "Request id not found"); + + subscr_info_s* info = it->second; + for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) { + (*it2)->on_event_received(subject, *option, *fact); + } - // TODO Remove - _trigger->push_fact(req_id, error, subject, *option, *fact); } diff --git a/src/context_trigger/context_monitor.h b/src/context_trigger/context_monitor.h index 3fc6f01..f53157e 100644 --- a/src/context_trigger/context_monitor.h +++ b/src/context_trigger/context_monitor.h @@ -20,49 +20,49 @@ #include #include #include -#include "../context_mgr_impl.h" -#include "fact.h" -#include "timer.h" namespace ctx { - class json; - class context_fact; class fact_request; + class context_manager_impl; + class context_listener_iface; + class trigger_timer; class context_monitor { public: context_monitor(); ~context_monitor(); - bool init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr); + bool init(ctx::context_manager_impl* ctx_mgr); - int subscribe(int rule_id, std::string subject, ctx::json event); - int unsubscribe(int rule_id, std::string subject, ctx::json option); + int subscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener); + int unsubscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener); int read(std::string subject, json option, ctx::json* result); bool is_supported(std::string subject); bool is_allowed(const char *client, const char *subject); - void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL); - void publish_fact(int req_id, int error, const char *subject, json *option, json *fact); + void reply_result(int req_id, int error, json *request_result = NULL, ctx::json *fact = NULL); + void publish_fact(int req_id, int error, const char *subject, json *option, ctx::json *fact); bool get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options); private: - int _subscribe(const char* subject, json* option, bool wait_response); + int _subscribe(const char* subject, ctx::json* option, context_listener_iface* listener, bool wait_response); void _unsubscribe(const char *subject, int subscription_id); - bool _read(const char *subject, json *option, context_fact& fact); +// bool _read(const char *subject, ctx::json *option, context_fact& fact); - ctx::context_trigger* _trigger; ctx::trigger_timer* timer; static context_manager_impl *_context_mgr; + typedef std::list listener_list_t; + struct subscr_info_s { int sid; - int cnt; std::string subject; ctx::json option; + listener_list_t listener_list; + subscr_info_s(int id, const char *subj, ctx::json *opt) - : sid(id), cnt(1), subject(subj) + : sid(id), subject(subj) { if (opt) option = *opt; @@ -72,12 +72,12 @@ namespace ctx { typedef std::map subscr_map_t; subscr_map_t subscr_map; - int find_sub(const char *subject, json *option); - bool add_sub(int sid, const char *subject, json *option); - void remove_sub(const char *subject, json *option); + int find_sub(const char *subject, ctx::json *option); + bool add_sub(int sid, const char *subject, ctx::json *option, context_listener_iface* listener); + void remove_sub(const char *subject, ctx::json *option); void remove_sub(int sid); - int increase_sub(int sid); - int decrease_sub(int sid); + int add_listener(int sid, context_listener_iface* listener); + int remove_listener(int sid, context_listener_iface* listener); static bool send_request(fact_request* req); }; /* class context_monitor */ diff --git a/src/context_trigger/rule.cpp b/src/context_trigger/rule.cpp new file mode 100644 index 0000000..7d15056 --- /dev/null +++ b/src/context_trigger/rule.cpp @@ -0,0 +1,136 @@ +/* + * 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 "action_manager.h" +#include "rule_evaluator.h" +#include "context_monitor.h" + +#define CONTEXT_RULE_EVENT "event" +#define CONTEXT_RULE_CONDITION "condition" +#define CONTEXT_RULE_NAME "name" +#define CONTEXT_RULE_OPTION "option" +#define CONTEXT_RULE_DATA "data" + +ctx::trigger_rule::trigger_rule() +{ +} + +ctx::trigger_rule::trigger_rule(int i, ctx::json& d, const char* cr, context_monitor* cm) + : ctx_monitor(cm) + , id(i) + , creator(cr) +{ + // Statement + statement = d.str(); + + // Event + ctx::json e; + d.get(NULL, CT_RULE_EVENT, &e); + event = new(std::nothrow) context_item_s(e); + + // Condition + int cond_num = d.array_get_size(NULL, CT_RULE_CONDITION); + for (int j = 0; j < cond_num; j++) { + ctx::json c; + d.get_array_elem(NULL, CT_RULE_CONDITION, j, &c); + condition.push_back(new(std::nothrow) context_item_s(c)); + } + + // Action + ctx::json a; + d.get(NULL, CT_RULE_ACTION, &a); + action = a.str(); +} + +ctx::trigger_rule::~trigger_rule() +{ + // Release resources + delete event; + for (std::list::iterator it = condition.begin(); it != condition.end(); ++it) { + delete *it; + } +} + +int ctx::trigger_rule::start(void) +{ + // Subscribe event + int error = ctx_monitor->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 ctx::trigger_rule::stop(void) +{ + // Unsubscribe event + int error = ctx_monitor->unsubscribe(id, event->name, event->option, this); + IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id); + + return error; +} + +void ctx::trigger_rule::on_event_received(std::string name, ctx::json option, ctx::json data) +{ + clear_result(); + _D("Rule%d received event data", id); + + // Set event data + result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_NAME, name); + result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_OPTION, option); + result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_DATA, data); + + if (condition.size() == 0) { + on_context_data_prepared(data); + return; + } + + for (std::list::iterator it = condition.begin(); it != condition.end(); ++it) { + // TODO send read request for each condition + } + + // TODO timer set +} + +void ctx::trigger_rule::on_condition_received(std::string name, ctx::json option, ctx::json data) +{ + // Set condition data + ctx::json item; + item.set(NULL, CONTEXT_RULE_NAME, name); + item.set(NULL, CONTEXT_RULE_OPTION, option); + item.set(NULL, CONTEXT_RULE_DATA, data); + result.array_append(NULL, CONTEXT_RULE_CONDITION, item); + + if (result.array_get_size(NULL, CONTEXT_RULE_CONDITION) == (int) condition.size()) { + on_context_data_prepared(data); + } +} + +void ctx::trigger_rule::clear_result() +{ + result = json(); + // TODO timer cancel +} + +void ctx::trigger_rule::on_context_data_prepared(ctx::json& data) +{ + if (ctx::rule_evaluator::evaluate_rule(statement, data)) { + ctx::action_manager::trigger_action(action, creator); + } + + clear_result(); +} diff --git a/src/context_trigger/rule.h b/src/context_trigger/rule.h new file mode 100644 index 0000000..43b3109 --- /dev/null +++ b/src/context_trigger/rule.h @@ -0,0 +1,74 @@ +/* + * 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 "context_listener_iface.h" + +namespace ctx { + + class context_monitor; + + class trigger_rule : public context_listener_iface { + private: + struct context_item_s { + std::string name; + ctx::json option; + context_item_s(ctx::json item) { + std::string n; + item.get(NULL, CT_RULE_EVENT_ITEM, &n); + name = n; + + ctx::json o; + if (item.get(NULL, CT_RULE_EVENT_OPTION, &o)) + option = o.str(); + } + }; + + typedef struct context_item_s* context_item_t; + ctx::json statement; + context_item_t event; + std::list condition; + ctx::json action; + ctx::json result; + + context_monitor* ctx_monitor; + + void clear_result(void); + void on_context_data_prepared(ctx::json& data); + + public: + int id; + std::string creator; + + trigger_rule(); + trigger_rule(int i, ctx::json& d, const char* c, context_monitor* cm); + ~trigger_rule(); + + int start(void); + int stop(void); + + void on_event_received(std::string name, ctx::json option, ctx::json data); + void on_condition_received(std::string name, ctx::json option, ctx::json data); + + }; + +} /* namespace ctx */ + +#endif /* End of __CONTEXT_TRIGGER_RULE_H__ */ diff --git a/src/context_trigger/rule_evaluator.cpp b/src/context_trigger/rule_evaluator.cpp new file mode 100644 index 0000000..7a9a65f --- /dev/null +++ b/src/context_trigger/rule_evaluator.cpp @@ -0,0 +1,23 @@ +/* + * 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_evaluator.h" + +bool ctx::rule_evaluator::evaluate_rule(ctx::json& rule, ctx::json& data) +{ + return true; +} diff --git a/src/context_trigger/rule_evaluator.h b/src/context_trigger/rule_evaluator.h new file mode 100644 index 0000000..e116fc1 --- /dev/null +++ b/src/context_trigger/rule_evaluator.h @@ -0,0 +1,32 @@ +/* + * 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_RULE_EVALUATOR_H__ +#define __CONTEXT_RULE_EVALUATOR_H__ + +namespace ctx { + + class json; + + namespace rule_evaluator { + + bool evaluate_rule(ctx::json& rule, ctx::json& data); + + } + +} /* namespace ctx */ + +#endif /* End of __CONTEXT_RULE_EVALUATOR_H__ */ diff --git a/src/context_trigger/rule_manager.cpp b/src/context_trigger/rule_manager.cpp index 588d7b1..a4d8a44 100644 --- a/src/context_trigger/rule_manager.cpp +++ b/src/context_trigger/rule_manager.cpp @@ -15,54 +15,26 @@ */ #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include "../dbus_server_impl.h" #include #include "rule_manager.h" -#include "script_generator.h" -#include "trigger.h" +#include "context_monitor.h" +#include "rule.h" #define RULE_TABLE "context_trigger_rule" -#define EVENT_TABLE "context_trigger_event" -#define CONDITION_TABLE "context_trigger_condition" #define TEMPLATE_TABLE "context_trigger_template" #define RULE_TABLE_COLUMNS "enabled INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL, creator_app_id TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT '', details TEXT DEFAULT '' NOT NULL" -#define EVENT_TABLE_COLUMNS "rule_id INTEGER references context_trigger_rule(row_id) ON DELETE CASCADE NOT NULL, name TEXT DEFAULT '' NOT NULL, instance_name TEXT DEFAULT ''" -#define CONDITION_TABLE_COLUMNS "rule_id INTEGER references context_trigger_rule(row_id) ON DELETE CASCADE NOT NULL, name TEXT DEFAULT '' NOT NULL, option TEXT DEFAULT '', instance_name TEXT DEFAULT ''" #define CREATE_TEMPLATE_TABLE "CREATE TABLE IF NOT EXISTS context_trigger_template (name TEXT DEFAULT '' NOT NULL PRIMARY KEY, operation INTEGER DEFAULT 3 NOT NULL, attributes TEXT DEFAULT '' NOT NULL, options TEXT DEFAULT '' NOT NULL)" -#define QUERY_TEMPLATE_TABLE "SELECT name, operation, attributes, options FROM context_trigger_template" #define FOREIGN_KEYS_ON "PRAGMA foreign_keys = ON" #define DELETE_RULE_STATEMENT "DELETE FROM 'context_trigger_rule' where row_id = " #define UPDATE_RULE_ENABLED_STATEMENT "UPDATE context_trigger_rule SET enabled = 1 WHERE row_id = " #define UPDATE_RULE_DISABLED_STATEMENT "UPDATE context_trigger_rule SET enabled = 0 WHERE row_id = " -#define QUERY_NAME_INSTANCE_NAME_AND_ATTRIBUTES_BY_RULE_ID_STATEMENT "SELECT context_trigger_condition.name, instance_name, attributes FROM context_trigger_condition JOIN context_trigger_template ON (context_trigger_condition.name = context_trigger_template.name) WHERE rule_id = " -#define QUERY_CONDITION_TEMPLATES_OF_INVOKED_EVENT_STATEMENT "SELECT DISTINCT context_trigger_condition.name, instance_name, option, attributes, options FROM context_trigger_condition JOIN context_trigger_template ON (context_trigger_condition.name = context_trigger_template.name) WHERE rule_id IN (SELECT row_id FROM context_trigger_rule WHERE enabled = 1 AND row_id IN (SELECT rule_id FROM context_trigger_event WHERE context_trigger_event.instance_name = '" -#define QUERY_RULE_BY_RULE_ID "SELECT details FROM context_trigger_rule WHERE row_id = " -#define QUERY_EVENT_TEMPLATE_BY_RULE_ID "SELECT name, attributes, options FROM context_trigger_template WHERE name IN (SELECT name FROM context_trigger_event WHERE rule_id = " -#define QUERY_CONDITION_BY_RULE_ID "SELECT name, option FROM context_trigger_condition WHERE rule_id = " +#define QUERY_RULE_AND_CREATOR_BY_RULE_ID "SELECT details, creator_app_id FROM context_trigger_rule WHERE row_id = " #define INSTANCE_NAME_DELIMITER "/" -#define EVENT_KEY_PREFIX "?" - -static ctx::context_trigger* trigger = NULL; -static int enb_rule_cnt = 0; static int string_to_int(std::string str) { @@ -83,50 +55,27 @@ static std::string int_to_string(int i) return str; } -static bool convert_str_to_json(ctx::json* val, const char* path, const char* key) -{ - // TODO: - IF_FAIL_RETURN(val, false); - - std::string buf; - IF_FAIL_RETURN(val->get(path, key, &buf), false); - - ctx::json temp = buf; - IF_FAIL_RETURN(val->set(path, key, temp), false); - - return true; -} - ctx::rule_manager::rule_manager() { } ctx::rule_manager::~rule_manager() { - destroy_clips(); } -bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr) +bool ctx::rule_manager::init(ctx::context_manager_impl* ctx_mgr) { bool ret; int error; - clips_h = NULL; - trigger = tr; - ret = c_monitor.init(ctx_mgr, tr); + ret = ctx_monitor.init(ctx_mgr); IF_FAIL_RETURN_TAG(ret, false, _E, "Context monitor initialization failed"); // Create tables into db (rule, event, condition, action, template) ret = db_manager::create_table(1, RULE_TABLE, RULE_TABLE_COLUMNS, NULL, NULL); IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed"); - ret = db_manager::create_table(2, EVENT_TABLE, EVENT_TABLE_COLUMNS, NULL, NULL); - IF_FAIL_RETURN_TAG(ret, false, _E, "Create event table failed"); - - ret = db_manager::create_table(3, CONDITION_TABLE, CONDITION_TABLE_COLUMNS, NULL, NULL); - IF_FAIL_RETURN_TAG(ret, false, _E, "Create condition table failed"); - - ret = db_manager::execute(4, CREATE_TEMPLATE_TABLE, NULL); + ret = db_manager::execute(2, CREATE_TEMPLATE_TABLE, NULL); IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed"); // Foreign keys on @@ -136,6 +85,7 @@ bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::context_manager_impl apply_templates(); + // Before re-enable rules, handle uninstalled app's rules if (get_uninstalled_app() > 0) { error = clear_rule_of_uninstalled_app(true); IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization"); @@ -154,7 +104,7 @@ void ctx::rule_manager::apply_templates(void) std::string q_update; std::string q_insert = "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options) VALUES"; - while (c_monitor.get_fact_definition(subject, operation, attributes, options)) { + while (ctx_monitor.get_fact_definition(subject, operation, attributes, options)) { _D("Subject: %s, Ops: %d", subject.c_str(), operation); _J("Attr", attributes); _J("Opt", options); @@ -239,9 +189,9 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init) } creator_list += ")"; - // After event received, disable all the enabled rules of uninstalled apps + // After event received, disable all the enabled rules of uninstalled apps // TODO register uninstalled apps app_id when before trigger if (!is_init) { - std::string q1 = "SELECT row_id, details FROM context_trigger_rule WHERE enabled = 1 and ("; + std::string q1 = "SELECT row_id FROM context_trigger_rule WHERE enabled = 1 and ("; q1 += creator_list; q1 += ")"; @@ -252,8 +202,10 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init) std::vector::iterator vec_end = record.end(); for (std::vector::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) { ctx::json elem = *vec_pos; - error = disable_uninstalled_rule(elem); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules" ); + int rule_id; + elem.get(NULL, "row_id", &rule_id); + error = disable_rule(rule_id); + IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule" ); } _D("Uninstalled apps' rules are disabled"); } @@ -270,113 +222,6 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init) return ERR_NONE; } -int ctx::rule_manager::disable_uninstalled_rule(ctx::json& rule_info) -{ - int error; - bool ret; - - int rule_id; - rule_info.get(NULL, "row_id", &rule_id); - - // For event with options - std::string r1; - rule_info.get(NULL, "details", &r1); - ctx::json rule = r1; - ctx::json event; - rule.get(NULL, CT_RULE_EVENT, &event); - std::string ename; - event.get(NULL, CT_RULE_EVENT_ITEM, &ename); - - // Unsubscribe event - error = c_monitor.unsubscribe(rule_id, ename, event); - IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to unsubscribe %s of rule%d: %d", ename.c_str(), rule_id, error); - - // Undef rule in clips - std::string id_str = int_to_string(rule_id); - std::string script = script_generator::generate_undefrule(id_str); - error = clips_h->route_string_command(script); - IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to undefine rule%d: %d", rule_id, error); - - // Remove condition instances - std::string q3 = "SELECT name, instance_name FROM context_trigger_condition WHERE rule_id = "; - q3 += id_str; - std::vector name_record; - ret = db_manager::execute_sync(q3.c_str(), &name_record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query condition table of rule%d failed: %d", rule_id, error); - - std::vector::iterator vec_end = name_record.end(); - for (std::vector::iterator vec_pos = name_record.begin(); vec_pos != vec_end; ++vec_pos) { - ctx::json elem = *vec_pos; - - std::string cname; - std::string ciname; - elem.get(NULL, "name", &cname); - elem.get(NULL, "instance_name", &ciname); - - if (cname.compare(ciname) != 0) { - cond_cnt_map[ciname]--; - - if (cond_cnt_map[ciname] == 0) { - error = clips_h->unmake_instance(ciname); - IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to unmake instance %s of rule%d: %d", ciname.c_str(), rule_id, error); - - cond_cnt_map.erase(ciname); - } - } - } - - if (--enb_rule_cnt <= 0) { - enb_rule_cnt = 0; - destroy_clips(); - } - return ERR_NONE; -} - -bool ctx::rule_manager::initialize_clips(void) -{ - if (clips_h) { - _D("CLIPS handler already initialized"); - return true; - } - - clips_h = new(std::nothrow) clips_handler(this); - IF_FAIL_RETURN_TAG(clips_h, false, _E, "CLIPS handler initialization failed"); - - // Load all templates from DB - std::vector record; - bool ret = db_manager::execute_sync(QUERY_TEMPLATE_TABLE, &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Query template table failed"); - - // Make scripts for deftemplate, defclass, make-instance and load them to clips - std::vector::iterator vec_end = record.end(); - for (std::vector::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) { - ctx::json tmpl = *vec_pos; - convert_str_to_json(&tmpl, NULL, "attributes"); - convert_str_to_json(&tmpl, NULL, "options"); - - std::string deftemplate_str = script_generator::generate_deftemplate(tmpl); - int error = clips_h->define_template(deftemplate_str); - IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Deftemplate failed"); - - std::string defclass_str = script_generator::generate_defclass(tmpl); - error = clips_h->define_class(defclass_str); - IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Defclass failed"); - - std::string makeinstance_str = script_generator::generate_makeinstance(tmpl); - error = clips_h->make_instance(makeinstance_str); - IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Makeinstance failed"); - } - - _D(YELLOW("Deftemplate, Defclass, Make-instance completed")); - return true; -} - -void ctx::rule_manager::destroy_clips(void) -{ - delete clips_h; - clips_h = NULL; -} - bool ctx::rule_manager::reenable_rule(void) { int error; @@ -395,8 +240,6 @@ bool ctx::rule_manager::reenable_rule(void) error = enable_rule(row_id); if (error != ERR_NONE) { _E("Re-enable rule%d failed(%d)", row_id, error); - } else { - _D("Re-enable rule%d succeeded", row_id); } } @@ -459,14 +302,11 @@ bool ctx::rule_manager::rule_item_equals(ctx::json& litem, ctx::json& ritem) if (lei.compare(rei)) return false; - // Compare option + // Compare option // TODO test ctx::json loption, roption; - std::string linst, rinst; litem.get(NULL, CT_RULE_EVENT_OPTION, &loption); ritem.get(NULL, CT_RULE_EVENT_OPTION, &roption); - linst = get_instance_name(lei, loption); - rinst = get_instance_name(rei, roption); - if (linst.compare(rinst)) + if (loption != roption) return false; int ledac, redac; @@ -616,10 +456,10 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator) std::string e_name; rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &e_name); - IF_FAIL_RETURN_TAG(c_monitor.is_supported(e_name), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", e_name.c_str()); + IF_FAIL_RETURN_TAG(ctx_monitor.is_supported(e_name), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", e_name.c_str()); if (creator) { - if (!c_monitor.is_allowed(creator, e_name.c_str())) { + if (!ctx_monitor.is_allowed(creator, e_name.c_str())) { _W("Permission denied for '%s'", e_name.c_str()); return ERR_PERMISSION_DENIED; } @@ -630,9 +470,9 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator) std::string c_name; it.get(NULL, CT_RULE_CONDITION_ITEM, &c_name); - IF_FAIL_RETURN_TAG(c_monitor.is_supported(c_name), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", c_name.c_str()); + IF_FAIL_RETURN_TAG(ctx_monitor.is_supported(c_name), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", c_name.c_str()); - if (!c_monitor.is_allowed(creator, c_name.c_str())) { + if (!ctx_monitor.is_allowed(creator, c_name.c_str())) { _W("Permission denied for '%s'", c_name.c_str()); return ERR_PERMISSION_DENIED; } @@ -643,7 +483,6 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator) int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::json rule, ctx::json* rule_id) { - // * Insert rule to DB bool ret; int64_t rid; @@ -659,7 +498,7 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js return ERR_NONE; } - // Insert rule to rule table, get rule id and save it to json parameter + // Insert rule to rule table, get rule id ctx::json r_record; std::string description; ctx::json details; @@ -677,48 +516,6 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js // Save rule id rule_id->set(NULL, CT_RULE_ID, rid); - // Insert event & conditions of a rule into each table - ctx::json e_record; - std::string e_name; - ctx::json e_option_j; - std::string e_inst; - - rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &e_name); - rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_OPTION, &e_option_j); - e_inst = get_instance_name(e_name, e_option_j); - - e_record.set(NULL, "rule_id", rid); - e_record.set(NULL, "name", e_name); - e_record.set(NULL, "instance_name", e_inst); - ret = db_manager::insert(1, EVENT_TABLE, e_record, NULL); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert event to db failed"); - - ctx::json it; - for (int i = 0; rule.get_array_elem(CT_RULE_DETAILS, CT_RULE_CONDITION, i, &it); i++){ - ctx::json c_record; - std::string c_name; - ctx::json c_option; - char* c_option_str; - ctx::json tmp_option; - std::string c_inst; - - it.get(NULL, CT_RULE_CONDITION_ITEM, &c_name); - it.get(NULL, CT_RULE_CONDITION_OPTION, &tmp_option); - c_inst = get_instance_name(c_name, tmp_option); - c_option.set(NULL, CT_RULE_CONDITION_OPTION, tmp_option); - c_option_str = c_option.dup_cstr(); - - c_record.set(NULL, "rule_id", rid); - c_record.set(NULL, "name", c_name); - c_record.set(NULL, "option", (c_option_str)? c_option_str : ""); - c_record.set(NULL, "instance_name", c_inst); - - ret = db_manager::insert(2, CONDITION_TABLE, c_record, NULL); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert conditions to db failed"); - - free(c_option_str); - } - _D("Add rule%d succeeded", (int)rid); return ERR_NONE; } @@ -726,9 +523,9 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js int ctx::rule_manager::remove_rule(int rule_id) { - // Delete rule from DB bool ret; + // Delete rule from DB std::string query = DELETE_RULE_STATEMENT; query += int_to_string(rule_id); std::vector record; @@ -740,94 +537,34 @@ int ctx::rule_manager::remove_rule(int rule_id) int ctx::rule_manager::enable_rule(int rule_id) { - if (enb_rule_cnt == 0) { - IF_FAIL_RETURN_TAG(initialize_clips(), ERR_OPERATION_FAILED, _E, "Failed to init clips"); - } - - // Subscribe event int error; std::string query; - std::string ename; - std::string script; - std::string tmp; - - ctx::json jrule; - ctx::json jetemplate; - ctx::json jevent; - ctx::json inst_names; - std::vector rule_record; - std::vector etmpl_record; - std::vector cond_record; std::vector record; - std::vector::iterator vec_end; - + std::string creator_app_id; + ctx::json jrule; + std::string tmp; std::string id_str = int_to_string(rule_id); + trigger_rule* rule; + // Get rule json by rule id; - query = QUERY_RULE_BY_RULE_ID; - query += int_to_string(rule_id); + query = QUERY_RULE_AND_CREATOR_BY_RULE_ID; + query += id_str; error = (db_manager::execute_sync(query.c_str(), &rule_record))? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query rule by rule id failed"); + IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed"); rule_record[0].get(NULL, "details", &tmp); jrule = tmp; - jrule.get(NULL, CT_RULE_EVENT, &jevent); - - // Get event template by rule id - query = QUERY_EVENT_TEMPLATE_BY_RULE_ID; - query += int_to_string(rule_id); - query += ")"; - error = (db_manager::execute_sync(query.c_str(), &etmpl_record))? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query event template by rule id failed"); - - jetemplate = etmpl_record[0].str(); - convert_str_to_json(&jetemplate, NULL, "attributes"); - convert_str_to_json(&jetemplate, NULL, "options"); - - // Query name, instance name & attributes for conditions of the rule - query = QUERY_NAME_INSTANCE_NAME_AND_ATTRIBUTES_BY_RULE_ID_STATEMENT; - query += id_str; - error = (db_manager::execute_sync(query.c_str(), &cond_record))? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query condition's names, instance names, attributes by rule id failed"); - - vec_end = cond_record.end(); - for (std::vector::iterator vec_pos = cond_record.begin(); vec_pos != vec_end; ++vec_pos) { - ctx::json elem = *vec_pos; - - std::string cname; - std::string ciname; - elem.get(NULL, "name", &cname); - elem.get(NULL, "instance_name", &ciname); - convert_str_to_json(&elem, NULL, "attributes"); - - // For defrule script generation - inst_names.set(NULL, cname.c_str(), ciname); - - if (cname.compare(ciname) != 0) { - if (!clips_h->find_instance(ciname)) { - std::string makeinst_script = script_generator::generate_makeinstance(elem); - error = (makeinst_script.length() > 0)? ERR_NONE : ERR_OPERATION_FAILED; - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Make instance script generation failed"); - error = clips_h->make_instance(makeinst_script); - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Add condition instance([%s]) failed", ciname.c_str()); - - cond_cnt_map[ciname] = 1; - } else { - cond_cnt_map[ciname]++; - } - } - } + rule_record[0].get(NULL, "creator_app_id", &creator_app_id); - // Subscribe event - jetemplate.get(NULL, "name", &ename); - error = c_monitor.subscribe(rule_id, ename, jevent); - IF_FAIL_CATCH(error == ERR_NONE); + // Create a rule instance + rule = new(std::nothrow) trigger_rule(rule_id, jrule, creator_app_id.c_str(), &ctx_monitor); + IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance"); - // Generate defrule script and execute it - script = script_generator::generate_defrule(id_str, jetemplate, jrule, inst_names); - error = clips_h->define_rule(script); - IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Defrule failed"); + // Start the rule + error = rule->start(); + IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", rule_id); // Update db to set 'enabled' query = UPDATE_RULE_ENABLED_STATEMENT; @@ -835,445 +572,45 @@ int ctx::rule_manager::enable_rule(int rule_id) error = (db_manager::execute_sync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED; IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed"); - enb_rule_cnt++; - _D(YELLOW("Enable Rule%d succeeded"), rule_id); + // Add rule instance to rule_map + rule_map[rule_id] = rule; + _D(YELLOW("Enable Rule%d succeeded"), rule_id); return ERR_NONE; CATCH: - if (enb_rule_cnt <= 0) { - enb_rule_cnt = 0; - destroy_clips(); - } + delete rule; + rule = NULL; return error; } -std::string ctx::rule_manager::get_instance_name(std::string name, ctx::json& option) -{ - std::string inst_name = name; - std::vector record_tmpl; - ctx::json tmpl_c; - std::list option_keys; - - // Get template for the option - std::string q = "SELECT options FROM context_trigger_template WHERE name = '"; - q += name; - q += "'"; - db_manager::execute_sync(q.c_str(), &record_tmpl); - - convert_str_to_json(&record_tmpl[0], NULL, "options"); - record_tmpl[0].get(NULL, "options", &tmpl_c); - - tmpl_c.get_keys(&option_keys); - - for (std::list::iterator it = option_keys.begin(); it != option_keys.end(); ++it) { - std::string key = (*it); - std::string val_str; - int val; - - if (option.get(NULL, key.c_str(), &val_str)) { - inst_name += INSTANCE_NAME_DELIMITER; - inst_name += val_str; - } else if (option.get(NULL, key.c_str(), &val)) { - inst_name += INSTANCE_NAME_DELIMITER; - inst_name += int_to_string(val); - } else { - inst_name += INSTANCE_NAME_DELIMITER; - } - } - - return inst_name; -} - int ctx::rule_manager::disable_rule(int rule_id) { - int error; bool ret; - - // For event with options - // Get rule json by rule id; - std::string q1 = QUERY_RULE_BY_RULE_ID; - q1 += int_to_string(rule_id); - std::vector rule_record; - ret = db_manager::execute_sync(q1.c_str(), &rule_record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rule by rule id failed"); - std::string r1; - rule_record[0].get(NULL, "details", &r1); - ctx::json rule = r1; - ctx::json event; - rule.get(NULL, CT_RULE_EVENT, &event); - std::string ename; - event.get(NULL, CT_RULE_EVENT_ITEM, &ename); - - // Unsubscribe event - error = c_monitor.unsubscribe(rule_id, ename, event); - IF_FAIL_RETURN(error == ERR_NONE, ERR_OPERATION_FAILED); - - // Undef rule in clips - std::string id_str = int_to_string(rule_id); - std::string script = script_generator::generate_undefrule(id_str); - error = clips_h->route_string_command(script); - IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Undefrule failed"); - - // Update db to set 'disabled' - std::string q2 = UPDATE_RULE_DISABLED_STATEMENT; - q2 += id_str; - std::vector record; - ret = db_manager::execute_sync(q2.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed"); - - // Remove condition instances - std::string q3 = "SELECT name, instance_name FROM context_trigger_condition WHERE rule_id = "; - q3 += id_str; - std::vector name_record; - ret = db_manager::execute_sync(q3.c_str(), &name_record); - IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query condition's name, instance names by rule id failed"); - - std::vector::iterator vec_end = name_record.end(); - for (std::vector::iterator vec_pos = name_record.begin(); vec_pos != vec_end; ++vec_pos) { - ctx::json elem = *vec_pos; - - std::string cname; - std::string ciname; - elem.get(NULL, "name", &cname); - elem.get(NULL, "instance_name", &ciname); - - if (cname.compare(ciname) != 0) { - cond_cnt_map[ciname]--; - - if (cond_cnt_map[ciname] == 0) { - error = clips_h->unmake_instance(ciname); - IF_FAIL_RETURN(error == ERR_NONE, error); - - cond_cnt_map.erase(ciname); - } - } - } - - if (--enb_rule_cnt <= 0) { - enb_rule_cnt = 0; - destroy_clips(); - } - return ERR_NONE; -} - -void ctx::rule_manager::make_condition_option_based_on_event_data(ctx::json& ctemplate, ctx::json& edata, ctx::json* coption) -{ - std::list option_keys; - ctemplate.get_keys(&option_keys); - - for (std::list::iterator it = option_keys.begin(); it != option_keys.end(); ++it) { - std::string key = (*it); - - std::string coption_valstr; - if (coption->get(NULL, key.c_str(), &coption_valstr)) { - if (coption_valstr.find(EVENT_KEY_PREFIX) == 0) { - std::string event_key = coption_valstr.substr(1, coption_valstr.length() - 1); - - std::string e_valstr; - int e_val; - if (edata.get(NULL, event_key.c_str(), &e_valstr)) { - coption->set(NULL, key.c_str(), e_valstr); - } else if (edata.get(NULL, event_key.c_str(), &e_val)) { - coption->set(NULL, key.c_str(), e_val); - } - } - } - } -} - -void ctx::rule_manager::on_event_received(std::string item, ctx::json option, ctx::json data) -{ - _D(YELLOW("Event(%s(%s) - %s) is invoked."), item.c_str(), option.str().c_str(), data.str().c_str()); - // TODO: Check permission of an event(item), if permission denied, return - - int err; - bool ret; - - // Generate event fact script - std::string q1 = "SELECT attributes, options FROM context_trigger_template WHERE name = '"; - q1 += item; - q1 += "'"; - std::vector etemplate_record; - db_manager::execute_sync(q1.c_str(), &etemplate_record); - - ctx::json etemplate = etemplate_record[0]; - convert_str_to_json(&etemplate, NULL, "attributes"); - convert_str_to_json(&etemplate, NULL, "options"); - - std::string eventfact_str = script_generator::generate_fact(item, etemplate, option, data); - - // Get Conditions template of invoked event (db query) - std::string e_inst = get_instance_name(item, option); - std::string query = QUERY_CONDITION_TEMPLATES_OF_INVOKED_EVENT_STATEMENT; - query += e_inst; - query += "'))"; - std::vector conds; - ret = db_manager::execute_sync(query.c_str(), &conds); - IF_FAIL_VOID_TAG(ret, _E, "Query condition templates of invoked event failed"); - - int cond_num = conds.size(); - for (int i = 0; i < cond_num; i++) { - convert_str_to_json(&conds[i], NULL, "options"); - convert_str_to_json(&conds[i], NULL, "attributes"); - - std::string cname; - conds[i].get(NULL, "name", &cname); - - std::string ciname; - conds[i].get(NULL, "instance_name", &ciname); - - std::string coption_str; - conds[i].get(NULL, "option", &coption_str); - ctx::json coption = NULL; - if (!coption_str.empty()) { - ctx::json coption_tmp = coption_str; - coption_tmp.get(NULL, CT_RULE_CONDITION_OPTION, &coption); - } - - // Check if the condition uses event data key as an option - if (ciname.find(EVENT_KEY_PREFIX) != std::string::npos) { - make_condition_option_based_on_event_data(conds[i], data, &coption); //TODO: conds[i] -> "options" - } - - // TODO: Check permission of a condition(cname), if permission granted, read condition data. (or, condition data should be empty json) - - // Get Context Data - ctx::json condition_data; - err = c_monitor.read(cname, coption, &condition_data); - if (err != ERR_NONE) - return; - _D(YELLOW("Condition(%s(%s) - %s)."), cname.c_str(), coption.str().c_str(), condition_data.str().c_str()); - - // Generate ModifyInstance script // TODO: conds[i] => "attributes" - std::string modifyinst_script = script_generator::generate_modifyinstance(ciname, conds[i], condition_data); - - err = clips_h->route_string_command(modifyinst_script); - IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Modify condition instance failed"); - } - - // Add fact and Run environment - err = clips_h->add_fact(eventfact_str); - IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Assert event fact failed"); - - err = clips_h->run_environment(); - IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Run environment failed"); - - // Retract event fact - std::string retract_command = "(retract *)"; - err = clips_h->route_string_command(retract_command); - IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Retract event fact failed"); - - // Clear uninstalled apps' rules if triggered - if (uninstalled_apps.size() > 0) { - err = clear_rule_of_uninstalled_app(); - IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Failed to clear uninstalled apps' rules"); - } -} - -static void trigger_action_app_control(ctx::json& action) -{ int error; - std::string appctl_str; - action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str); - char* str = static_cast(malloc(appctl_str.length())); - if (str == NULL) { - _E("Memory allocation failed"); - return; - } - appctl_str.copy(str, appctl_str.length(), 0); - bundle_raw* encoded = reinterpret_cast(str); - bundle* appctl_bundle = bundle_decode(encoded, appctl_str.length()); + rule_map_t::iterator it = rule_map.find(rule_id); + IF_FAIL_RETURN_TAG(it != rule_map.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found"); - app_control_h app = NULL; - app_control_create(&app); - app_control_import_from_bundle(app, appctl_bundle); + // Stop the rule + trigger_rule* rule = static_cast(it->second); + error = rule->stop(); + IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id); - 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(appctl_bundle); - 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); - } -} - -static void trigger_action_notification(ctx::json& action, std::string app_id) -{ - int error; - notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI); - std::string title; - if (action.get(NULL, CT_RULE_ACTION_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(NULL, CT_RULE_ACTION_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 image_path; - if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &image_path)) { - error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, image_path.c_str()); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set notification icon image failed(%d)", error); - } - } - - std::string appctl_str; - char* str = NULL; - bundle_raw* encoded = NULL; - bundle* appctl_bundle = NULL; - app_control_h app = NULL; - if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str)) { - str = static_cast(malloc(appctl_str.length())); - if (str == NULL) { - _E("Memory allocation failed"); - notification_free(notification); - return; - } - appctl_str.copy(str, appctl_str.length(), 0); - encoded = reinterpret_cast(str); - appctl_bundle = bundle_decode(encoded, appctl_str.length()); - - app_control_create(&app); - app_control_import_from_bundle(app, appctl_bundle); - - 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 (!app_id.empty()) { - error = notification_set_pkgname(notification, app_id.c_str()); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Set pkgname(%s) failed(%d)", app_id.c_str(), error); - } - } - - 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); - } - - 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); - } - - if (!silent) { - error = notification_set_sound(notification, NOTIFICATION_SOUND_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); - } - } - } - - error = notification_post(notification); - if (error != NOTIFICATION_ERROR_NONE) { - _E("Post notification failed(%d)", error); - } else { - _D("Post notification succeeded"); - } - - bundle_free(appctl_bundle); - 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); - } -} - -static void trigger_action_dbus_call(ctx::json& action) -{ - std::string bus_name, object, iface, method; - GVariant *param = NULL; - - action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name); - IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name"); - - action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object); - IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path"); - - action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface); - IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name"); - - action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method); - IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name"); - - action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, ¶m); - - ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), param); -} - -void ctx::rule_manager::on_rule_triggered(int rule_id) -{ - std::string q = "SELECT details, creator_app_id FROM context_trigger_rule WHERE row_id ="; - q += int_to_string(rule_id); + // Update db to set 'disabled' // TODO skip while clear uninstalled rule + std::string query = UPDATE_RULE_DISABLED_STATEMENT; + query += int_to_string(rule_id); std::vector record; - db_manager::execute_sync(q.c_str(), &record); - if (record.empty()) { - _E("Rule%d not exist", rule_id); - return; - } + ret = db_manager::execute_sync(query.c_str(), &record); + IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed"); - // If rule's creator is uninstalled, skip action - std::string app_id; - record[0].get(NULL, "creator_app_id", &app_id); - if (is_uninstalled_package(app_id)) { - _D(YELLOW("Rule%d's creator(%s) is uninstalled. Skip action."), rule_id, app_id.c_str()); - uninstalled_apps.insert(app_id); - return; - } + // Remove rule instance from rule_map + delete rule; + rule_map.erase(it); - _D(YELLOW("Rule%d is triggered"), rule_id); - - // Do action - std::string details_str; - record[0].get(NULL, "details", &details_str); - ctx::json details = details_str; - ctx::json action; - details.get(NULL, CT_RULE_ACTION, &action); - - std::string type; - if (action.get(NULL, CT_RULE_ACTION_TYPE, &type)) { - if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) { - trigger_action_app_control(action); - } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) { - trigger_action_notification(action, app_id); - } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) { - trigger_action_dbus_call(action); - } - } + _D(YELLOW("Disable Rule%d succeeded"), rule_id); + return ERR_NONE; } int ctx::rule_manager::check_rule(std::string creator, int rule_id) diff --git a/src/context_trigger/rule_manager.h b/src/context_trigger/rule_manager.h index 8a83ccd..dc200cc 100644 --- a/src/context_trigger/rule_manager.h +++ b/src/context_trigger/rule_manager.h @@ -18,19 +18,22 @@ #define __RULE_MANAGER_H__ #include -#include "clips_handler.h" +#include #include "context_monitor.h" namespace ctx { class json; class context_trigger; + class context_manager_impl; + class context_monitor; + class trigger_rule; class rule_manager { public: rule_manager(); ~rule_manager(); - bool init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr); + bool init(ctx::context_manager_impl* ctx_mgr); int add_rule(std::string creator, const char* app_id, ctx::json rule, ctx::json* rule_id); int remove_rule(int rule_id); int enable_rule(int rule_id); @@ -40,12 +43,8 @@ namespace ctx { int check_rule(std::string creator, int rule_id); bool is_rule_enabled(int rule_id); - void on_event_received(std::string item, ctx::json option, ctx::json data); - void on_rule_triggered(int rule_id); - private: - clips_handler* clips_h; - context_monitor c_monitor; + ctx::context_monitor ctx_monitor; void apply_templates(void); bool reenable_rule(void); @@ -54,17 +53,14 @@ namespace ctx { bool rule_data_arr_elem_equals(ctx::json& lelem, ctx::json& relem); bool rule_item_equals(ctx::json& litem, ctx::json& ritem); bool rule_equals(ctx::json& lrule, ctx::json& rrule); - std::string get_instance_name(std::string name, ctx::json& condition); - void make_condition_option_based_on_event_data(ctx::json& ctemplate, ctx::json& edata, ctx::json* coption); int get_uninstalled_app(void); bool is_uninstalled_package(std::string app_id); int clear_rule_of_uninstalled_app(bool is_init = false); - int disable_uninstalled_rule(ctx::json& rule_info); - bool initialize_clips(void); - void destroy_clips(void); - std::map cond_cnt_map; // std::set uninstalled_apps; + + typedef std::map rule_map_t; + rule_map_t rule_map; }; /* class rule_manager */ } /* namespace ctx */ diff --git a/src/context_trigger/script_generator.cpp b/src/context_trigger/script_generator.cpp deleted file mode 100644 index fd2ee72..0000000 --- a/src/context_trigger/script_generator.cpp +++ /dev/null @@ -1,513 +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 "script_generator.h" -#include "timer_types.h" - -#define EVENT_WEEKDAY "(or (eq ?DayOfWeek \"Mon\") (eq ?DayOfWeek \"Tue\") (eq ?DayOfWeek \"Wed\") (eq ?DayOfWeek \"Thu\") (eq ?DayOfWeek \"Fri\"))" -#define EVENT_WEEKEND "(or (eq ?DayOfWeek \"Sat\") (eq ?DayOfWeek \"Sun\"))" -#define CONDITION_WEEKDAY "(or (eq (send [%s] get-DayOfWeek) \"Mon\") (eq (send [%s] get-DayOfWeek) \"Tue\") (eq (send [%s] get-DayOfWeek) \"Wed\") (eq (send [%s] get-DayOfWeek) \"Thu\") (eq (send [%s] get-DayOfWeek) \"Fri\"))" -#define CONDITION_WEEKEND "(or (eq (send [%s] get-DayOfWeek) \"Sat\") (eq (send [%s] get-DayOfWeek) \"Sun\"))" - -static std::string generate_initial_fact(ctx::json& event_tmpl, ctx::json& option); -static std::string generate_event_data(ctx::json& event); -static std::string generate_condition_data(std::string rule_id, ctx::json& conditions, std::string rule_op, ctx::json& inst_names); - -static std::string int_to_string(int i) -{ - std::ostringstream convert; - convert << i; - std::string str = convert.str(); - return str; -} - -static std::string convert_condition_weekday_weekend(std::string inst_name, std::string day) -{ - std::string buf = (day.compare(TIMER_WEEKDAY) == 0)? CONDITION_WEEKDAY : CONDITION_WEEKEND; - - size_t pos = 0; - while ((pos = buf.find("%s", pos)) != std::string::npos) { - buf.replace(pos, 2, inst_name); - pos += inst_name.length(); - } - - return buf; -} - -std::string ctx::script_generator::generate_deftemplate(ctx::json& tmpl) -{ - std::string script; - std::string name; - ctx::json attrs; - ctx::json options; - std::list attr_keys; - std::list option_keys; - std::set slot; - - tmpl.get(NULL, "name", &name); - tmpl.get(NULL, "attributes", &attrs); - tmpl.get(NULL, "options", &options); - - attrs.get_keys(&attr_keys); - options.get_keys(&option_keys); - - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - slot.insert(*it); - } - - for (std::list::iterator it = option_keys.begin(); it != option_keys.end(); ++it) { - slot.insert(*it); - } - - //template name is "itemname" - script = "(deftemplate "; - script += name; - script += " "; - - for (std::set::iterator it = slot.begin(); it != slot.end(); ++it){ - script += "(slot "; - script += *it; - script += " (default nil))"; - } - script += ")\n"; - - return script; -} - -std::string ctx::script_generator::generate_defclass(ctx::json& tmpl) -{ - std::string script; - std::string name; - ctx::json attrs; - std::list attr_keys; - - tmpl.get(NULL, "name", &name); - tmpl.get(NULL, "attributes", &attrs); - - attrs.get_keys(&attr_keys); - - //class name is "C.itemname" - script = "(defclass C."; - script += name; - script += " (is-a USER) (role concrete) "; - - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - script += "(slot " + (*it) + " (default nil)(create-accessor read-write))"; - } - script += ")\n"; - - return script; -} - -std::string ctx::script_generator::generate_makeinstance(ctx::json& tmpl) -{ - std::string script; - std::string name; - ctx::json attrs; - std::list attr_keys; - - tmpl.get(NULL, "name", &name); - tmpl.get(NULL, "attributes", &attrs); - - attrs.get_keys(&attr_keys); - - std::string instance_name; - if (!tmpl.get(NULL, "instance_name", &instance_name)) { - // For default instance w/o option - instance_name = name; - } - - //instance name is "[itemname]" - script = "([" + instance_name + "] of C." + name; - - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - script += " (" + (*it) + " 0)"; - } - script += ")\n"; - - return script; -} - -std::string ctx::script_generator::generate_undefrule(std::string rule_id) -{ - std::string script; - script = "(undefrule rule"; - script += rule_id; - script += ")"; - - return script; -} - -std::string ctx::script_generator::generate_defrule(std::string rule_id, ctx::json& event_tmpl, ctx::json& rule, ctx::json& inst_names) -{ - std::string script; - ctx::json option = NULL; - rule.get(CT_RULE_EVENT, CT_RULE_EVENT_OPTION, &option); - - script = "(defrule rule" + rule_id + " "; - script += generate_initial_fact(event_tmpl, option); - script += " => "; - - int eventdata_num = rule.array_get_size(CT_RULE_EVENT, CT_RULE_DATA_ARR); - int condition_num = rule.array_get_size(NULL, CT_RULE_CONDITION); - - if (condition_num > 0) { - // case1: condition exists - script += "(if "; - - if (eventdata_num > 0) { - ctx::json event; - rule.get(NULL, CT_RULE_EVENT, &event); - script += "(and "; - script += generate_event_data(event); - } - - // condition - ctx::json conditions; - rule.get(NULL, CT_RULE_CONDITION, &conditions); - std::string rule_op; - rule.get(NULL, CT_RULE_OPERATOR, &rule_op); - script += generate_condition_data(rule_id, conditions, rule_op, inst_names); - - if (eventdata_num > 0) - script += ")"; - - script = script + " then (execute_action rule" + rule_id + "))"; - } else if (eventdata_num > 0) { - // case2: no conditions, but event data - ctx::json event; - rule.get(NULL, CT_RULE_EVENT, &event); - - script += "(if "; - script += generate_event_data(event); - script = script + " then (execute_action rule" + rule_id + "))"; - } else { - // case3: only action - script = script + " (execute_action rule" + rule_id + ")"; - } - - script += ")"; - _D("Defrule script generated: %s", script.c_str()); - return script; -} - -std::string generate_initial_fact(ctx::json& event_tmpl, ctx::json& option) -{ - std::string script; - std::string e_name; - ctx::json attrs; - ctx::json options; - std::list attr_keys; - std::list option_keys; - - event_tmpl.get(NULL, "name", &e_name); - event_tmpl.get(NULL, "attributes", &attrs); - event_tmpl.get(NULL, "options", &options); - - attrs.get_keys(&attr_keys); - options.get_keys(&option_keys); - - script += "(" + e_name + " "; - // options - for (std::list::iterator it = option_keys.begin(); it != option_keys.end(); ++it) { - std::string opt_key = (*it); - script += "(" + opt_key + " "; - - std::string val_str; - int val; - if (option.get(NULL, opt_key.c_str(), &val_str)) { - script += val_str; - } else if (option.get(NULL, opt_key.c_str(), &val)) { - script += int_to_string(val); - } else { - script += "?" + opt_key; - } - script += ")"; - } - - // attributes - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - std::string attr_key = (*it); - script += "(" + attr_key + " ?" + attr_key + ")"; - } - script += ")"; - - return script; -} - -std::string generate_event_data(ctx::json& event) -{ - std::string ename; - event.get(NULL, CT_RULE_EVENT_ITEM, &ename); - - std::string script; - int edata_count = event.array_get_size(NULL, CT_RULE_DATA_ARR); - - if (edata_count > 1) { - std::string item_op; - event.get(NULL, CT_RULE_EVENT_OPERATOR, &item_op); - script += "("; - script += item_op; - script += " "; - } - - ctx::json edata; - for (int i = 0; event.get_array_elem(NULL, CT_RULE_DATA_ARR, i, &edata); i++) { - std::string key_name; - if (ename.compare(TIMER_EVENT_SUBJECT) == 0) { - edata.get(NULL, CT_RULE_DATA_KEY, &key_name); - } - - int valuecount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR); - int opcount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR); - std::string key; - edata.get(NULL, CT_RULE_DATA_KEY, &key); - - if (valuecount != opcount) { - _E("Invalid event data. (Value count:%d, Operator count: %d)", valuecount, opcount); - return ""; - } - - if (valuecount > 1) { - script += "("; - - std::string key_op; - edata.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op); - script += key_op; - script += " "; - } - - for (int j = 0; j < valuecount; j++){ - std::string val_op; - std::string val; - edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &val_op); - edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, j, &val); - - if (key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) { - if (val.compare("\"" TIMER_WEEKDAY "\"") == 0) { - script += (val_op.compare("eq") == 0)? EVENT_WEEKDAY : EVENT_WEEKEND; - continue; - } else if (val.compare("\"" TIMER_WEEKEND "\"") == 0) { - script += (val_op.compare("eq") == 0)? EVENT_WEEKEND : EVENT_WEEKDAY; - continue; - } - } - - script += "("; - script += val_op; - script += " ?"; - script += key; - script += " "; - script += val; - script += ")"; - } - - if (valuecount > 1) { - script += ")"; - } - } - - if (edata_count > 1) { - script += ")"; - } - - return script; -} - -std::string generate_condition_data(std::string rule_id, ctx::json& conditions, std::string rule_op, ctx::json& inst_names) -{ - std::string script; - - ctx::json conds; - conds.set(NULL, CT_RULE_CONDITION, conditions); - - int conds_count = conds.array_get_size(NULL, CT_RULE_CONDITION); - if (conds_count > 1) { - script += "("; - script += rule_op; // operator between each condition item - script += " "; - } - - ctx::json it; - for (int i = 0; conds.get_array_elem(NULL, CT_RULE_CONDITION, i, &it); i++) { - std::string cond_name; - it.get(NULL, CT_RULE_CONDITION_ITEM, &cond_name); - - std::string inst_name; - inst_names.get(NULL, cond_name.c_str(), &inst_name); - - int data_count = it.array_get_size(NULL, CT_RULE_DATA_ARR); - - if (data_count > 1) { - std::string item_op; - it.get(NULL, CT_RULE_CONDITION_OPERATOR, &item_op); - script += "("; - script += item_op; // operator between data keys of a condition item - script += " "; - } - - ctx::json data; - for (int j = 0; it.get_array_elem(NULL, CT_RULE_DATA_ARR, j, &data); j++) { - std::string key_name; - data.get(NULL, CT_RULE_DATA_KEY, &key_name); - int dval_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR); - int dvalop_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR); - - if (dval_count != dvalop_count) { - _E("Invalid condition data. (Data value count %d, Data value operator count %d)", dval_count, dvalop_count); - } - - if (dval_count > 1) { - std::string dkey_op; - data.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &dkey_op); - - script += "("; - script += dkey_op; // operator between comparison data values of a condition data key - script += " " ; - } - - for (int k = 0; k < dval_count; k++) { - std::string dval_op; - std::string dval; - data.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, k, &dval_op); - data.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, k, &dval); - - if (inst_name.compare(TIMER_CONDITION_SUBJECT) == 0 && key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) { - if (dval.compare("\"" TIMER_WEEKDAY "\"") == 0) { - script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKDAY : TIMER_WEEKEND); - continue; - } else if (dval.compare("\"" TIMER_WEEKEND "\"") == 0) { - script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKEND : TIMER_WEEKDAY); - continue; - } - } - - script += "("; - script += dval_op; - script += " (send ["; - script += inst_name; - script += "] get-"; - script += key_name; - script += ") "; - script += dval; - script += ")"; - } - - if (dval_count > 1) { - script += ")"; - } - } - - if (data_count > 1 ) { - script += ")"; - } - } - - if (conds_count > 1) { - script += ")"; - } - - return script; -} - -std::string ctx::script_generator::generate_fact(std::string item_name, ctx::json& event_tmpl, ctx::json& option, ctx::json& data) -{ - // Generate Fact script for invoked event - std::string script = "(" + item_name + " "; - ctx::json attrs; - ctx::json options; - std::list attr_keys; - std::list option_keys; - - event_tmpl.get(NULL, "attributes", &attrs); - event_tmpl.get(NULL, "options", &options); - - attrs.get_keys(&attr_keys); - options.get_keys(&option_keys); - - for (std::list::iterator it = option_keys.begin(); it != option_keys.end(); ++it) { - std::string opt_key = (*it); - std::string val_str; - int value; - - script += "(" + opt_key + " "; - - if (option.get(NULL, opt_key.c_str(), &val_str)) { // string type data - script += val_str; - } else if (option.get(NULL, opt_key.c_str(), &value)) { // integer type data - script += int_to_string(value); - } else { - script += "nil"; - } - script += ")"; - } - - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - std::string attr_key = (*it); - std::string val_str; - int value; - - script += "(" + attr_key + " "; - if (data.get(NULL, attr_key.c_str(), &val_str)) { // string type data - script += "\"" + val_str + "\""; - } else if (data.get(NULL, attr_key.c_str(), &value)) { // integer type data - script += int_to_string(value); - } else { - script += "nil"; - } - script += ")"; - } - script += ")"; - - return script; -} - -std::string ctx::script_generator::generate_modifyinstance(std::string instance_name, ctx::json& cond_tmpl, ctx::json& data) -{ - std::string script = "(modify-instance [" + instance_name + "] "; - ctx::json attrs; - std::list attr_keys; - - cond_tmpl.get(NULL, "attributes", &attrs); - attrs.get_keys(&attr_keys); - - // attributes - for (std::list::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) { - std::string attr_key = (*it); - std::string val_str; - int value; - - script += "(" + attr_key + " "; - if (data.get(NULL, attr_key.c_str(), &val_str)) { // string type data - script += "\"" + val_str + "\""; - } else if (data.get(NULL, attr_key.c_str(), &value)) { // integer type data - script += int_to_string(value); - } else { - script += "nil"; - } - script += ")"; - } - script += ")"; - - return script; -} diff --git a/src/context_trigger/script_generator.h b/src/context_trigger/script_generator.h deleted file mode 100644 index 4b2d1ac..0000000 --- a/src/context_trigger/script_generator.h +++ /dev/null @@ -1,36 +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_SCRIPT_GENERATOR_H__ -#define __CONTEXT_SCRIPT_GENERATOR_H__ - -namespace ctx { - - namespace script_generator { - - std::string generate_deftemplate(ctx::json& tmpl); - std::string generate_defclass(ctx::json& tmpl); - std::string generate_makeinstance(ctx::json& tmpl); - std::string generate_undefrule(std::string rule_id); - std::string generate_defrule(std::string rule_id, ctx::json& event_tmpl, ctx::json& rule, ctx::json& inst_names); - std::string generate_fact(std::string item_name, ctx::json& event_tmpl, ctx::json& option, ctx::json& data); - std::string generate_modifyinstance(std::string instance_name, ctx::json& cond_tmpl, ctx::json& data); - - } - -} /* namespace ctx */ - -#endif /* End of __CONTEXT_SCRIPT_GENERATOR_H__ */ diff --git a/src/context_trigger/timer.cpp b/src/context_trigger/timer.cpp index 5209a6e..c2aaf31 100644 --- a/src/context_trigger/timer.cpp +++ b/src/context_trigger/timer.cpp @@ -289,7 +289,7 @@ void ctx::trigger_timer::on_timer_expired(int hour, int min, int day_of_week) result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, convert_day_of_week_to_string(day_of_week)); ctx::json dummy = NULL; - trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result); +// trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result); // TODO deliver event } int ctx::trigger_timer::subscribe(ctx::json option) diff --git a/src/context_trigger/trigger.cpp b/src/context_trigger/trigger.cpp index 0c4c53f..1caffe2 100644 --- a/src/context_trigger/trigger.cpp +++ b/src/context_trigger/trigger.cpp @@ -84,29 +84,12 @@ void ctx::context_trigger::process_request(ctx::request_info* request) } } -// TODO remove -void ctx::context_trigger::push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data) -{ - context_fact *fact = new(std::nothrow) context_fact(req_id, error, subject, option, data); - IF_FAIL_VOID_TAG(fact, _E, "Memory allocation failed"); - - process_fact(fact); - -} - -// TODO: remove -void ctx::context_trigger::process_fact(ctx::context_fact* fact) -{ - // Process the context fact. - rule_mgr->on_event_received(fact->get_subject(), fact->get_option(), fact->get_data()); -} - void ctx::context_trigger::process_initialize(ctx::context_manager_impl* mgr) { rule_mgr = new(std::nothrow) rule_manager(); IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed"); - bool ret = rule_mgr->init(this, mgr); + bool ret = rule_mgr->init(mgr); if (!ret) { _E("Context trigger initialization failed."); raise(SIGTERM); diff --git a/src/context_trigger/trigger.h b/src/context_trigger/trigger.h index 28d4373..0396f1f 100644 --- a/src/context_trigger/trigger.h +++ b/src/context_trigger/trigger.h @@ -34,11 +34,9 @@ namespace ctx { void release(); bool assign_request(ctx::request_info* request); - void push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data); // TODO remove private: void process_request(ctx::request_info* request); - void process_fact(ctx::context_fact* fact); void process_initialize(ctx::context_manager_impl* mgr); void add_rule(ctx::request_info* request);