#include <cynara-creds-gdbus.h>
#include <cynara-session.h>
#include <app_manager.h>
+#include <package_manager.h>
#include <types_internal.h>
#include "peer_creds.h"
-ctx::credentials::credentials(char *_app_id, char *_client, char *_session, char *_user) :
+ctx::credentials::credentials(char *_app_id, char *_package_id, char *_client, char *_session, char *_user) :
app_id(_app_id),
+ package_id(_package_id),
client(_client),
session(_session),
user(_user)
ctx::credentials::~credentials()
{
g_free(app_id);
+ g_free(package_id);
g_free(client);
g_free(session);
g_free(user);
{
pid_t pid = 0;
char *app_id = NULL;
+ char *package_id = NULL;
gchar *client = NULL;
char *session = NULL;
gchar *user = NULL;
IF_FAIL_RETURN_TAG(err == CYNARA_API_SUCCESS, false, _E, "Peer credentialing failed");
app_manager_get_app_id(pid, &app_id);
- _D("AppId: %s", app_id);
+ package_manager_get_package_id_by_app_id(app_id, &package_id);
+ _D("AppId: %s, PackageId: %s", app_id, package_id);
err = cynara_creds_gdbus_get_client(connection, unique_name, CLIENT_METHOD_DEFAULT, &client);
IF_FAIL_CATCH_TAG(err == CYNARA_API_SUCCESS, _E, "Peer credentialing failed");
err = cynara_creds_gdbus_get_user(connection, unique_name, USER_METHOD_DEFAULT, &user);
IF_FAIL_CATCH_TAG(err == CYNARA_API_SUCCESS, _E, "Peer credentialing failed");
- *creds = new(std::nothrow) credentials(app_id, client, session, user);
+ *creds = new(std::nothrow) credentials(app_id, package_id, client, session, user);
IF_FAIL_CATCH_TAG(*creds, _E, "Memory allocation failed");
return true;
CATCH:
g_free(app_id);
+ g_free(package_id);
g_free(client);
g_free(session);
g_free(user);
class credentials {
public:
char *app_id;
+ char *package_id;
char *client; /* default: smack label */
char *session;
char *user; /* default: UID */
- credentials(char *_app_id, char *_client, char *_session, char *_user);
+ credentials(char *_app_id, char *_package_id, char *_client, char *_session, char *_user);
~credentials();
};
return NULL;
}
+const char* ctx::client_request::get_package_id()
+{
+ if (__credentials)
+ return __credentials->package_id;
+
+ return NULL;
+}
+
const char* ctx::client_request::get_client()
{
if (__credentials)
const credentials* get_credentials();
const char* get_app_id();
+ const char* get_package_id();
const char* get_client();
bool reply(int error);
bool reply(int error, ctx::json &request_result);
#include <list>
#include <types_internal.h>
+#include <context_trigger_types_internal.h>
#include <json.h>
#include <provider_iface.h>
#include "server.h"
#include <internal/device_context_provider.h>
#include <internal/statistics_context_provider.h>
#include <internal/place_context_provider.h>
+#include <internal/custom_context_provider.h>
struct trigger_item_format_s {
std::string subject;
int operation;
ctx::json attributes;
ctx::json options;
- trigger_item_format_s(std::string subj, int ops, ctx::json attr, ctx::json opt)
- : subject(subj), operation(ops), attributes(attr), options(opt) {}
+ std::string owner;
+ bool unregister;
+ trigger_item_format_s(std::string subj, int ops, ctx::json attr, ctx::json opt, std::string own)
+ : subject(subj), operation(ops), attributes(attr), options(opt), owner(own)
+ {
+ unregister = false;
+ }
+
+ trigger_item_format_s(std::string subj)
+ : subject(subj) {
+ unregister = true;
+ }
};
static std::list<trigger_item_format_s> __trigger_item_list;
ret = init_place_context_provider();
IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: place-context-provider");
+ ret = init_custom_context_provider();
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Initialization failed: custom-context-provider");
+
return true;
}
return true;
}
-bool ctx::context_manager_impl::register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options)
+bool ctx::context_manager_impl::unregister_provider(const char *subject)
+{
+ auto it = provider_handle_map.find(subject);
+ if (it == provider_handle_map.end()) {
+ _E("The provider for the subject '%s' is not found.", subject);
+ return false;
+ }
+
+ delete it->second;
+ provider_handle_map.erase(it);
+
+ return true;
+}
+
+bool ctx::context_manager_impl::register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options, const char* owner)
+{
+ IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter");
+ __trigger_item_list.push_back(trigger_item_format_s(subject, operation, attributes, options, (owner)? owner : ""));
+
+ return true;
+}
+
+bool ctx::context_manager_impl::unregister_trigger_item(const char *subject)
{
IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter");
- __trigger_item_list.push_back(trigger_item_format_s(subject, operation, attributes, options));
+ __trigger_item_list.push_back(trigger_item_format_s(subject));
+
return true;
}
-bool ctx::context_manager_impl::pop_trigger_item(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options)
+bool ctx::context_manager_impl::pop_trigger_item(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options, std::string& owner, bool& unregister)
{
IF_FAIL_RETURN(!__trigger_item_list.empty(), false);
operation = format.operation;
attributes = format.attributes;
options = format.options;
+ owner = format.owner;
+ unregister = format.unregister;
return true;
}
void ctx::context_manager_impl::assign_request(ctx::request_info* request)
{
+ if (handle_custom_request(request)) {
+ delete request;
+ return;
+ }
+
auto it = provider_handle_map.find(request->get_subject());
if (it == provider_handle_map.end()) {
_W("Unsupported subject");
return true;
}
+
+bool ctx::context_manager_impl::handle_custom_request(ctx::request_info* request)
+{
+ std::string subject = request->get_subject();
+ IF_FAIL_RETURN( subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_ADD ||
+ subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_REMOVE ||
+ subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_PUBLISH, false);
+
+ const char* pkg_id = request->get_package_id();
+ if (pkg_id == NULL) {
+ request->reply(ERR_OPERATION_FAILED);
+ return true;
+ }
+
+ ctx::json desc = request->get_description();
+ std::string name;
+ desc.get(NULL, CT_CUSTOM_NAME, &name);
+ std::string subj = pkg_id + std::string("::") + name;
+
+ int error = ERR_NONE;
+ if (subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_ADD) {
+ ctx::json tmpl;
+ desc.get(NULL, CT_CUSTOM_ATTRIBUTES, &tmpl);
+
+ error = ctx::custom_context_provider::add_item(subj, name, tmpl, pkg_id);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_REMOVE) {
+ error = ctx::custom_context_provider::remove_item(subj);
+ if (error == ERR_NONE) {
+ ctx::json data;
+ data.set(NULL, CT_CUSTOM_SUBJECT, subj);
+ request->reply(error, data);
+ }
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_PUBLISH) {
+ ctx::json fact;
+ desc.get(NULL, CT_CUSTOM_FACT, &fact);
+
+ error = ctx::custom_context_provider::publish_data(subj, fact);
+ }
+
+ request->reply(error);
+ return true;
+}
void assign_request(ctx::request_info *request);
bool is_supported(const char *subject);
bool is_allowed(const credentials *creds, const char *subject);
- bool pop_trigger_item(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options);
+ bool pop_trigger_item(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options, std::string &owner, bool& unregister);
/* From the interface class */
bool register_provider(const char *subject, context_provider_info &provider_info);
- bool register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options);
+ bool unregister_provider(const char *subject);
+ bool register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options, const char *owner = NULL);
+ bool unregister_trigger_item(const char *subject);
bool publish(const char *subject, ctx::json &option, int error, ctx::json &data_updated);
bool reply_to_read(const char *subject, ctx::json &option, int error, ctx::json &data_read);
void _publish(const char *subject, ctx::json &option, int error, ctx::json &data_updated);
void _reply_to_read(const char *subject, ctx::json &option, int error, ctx::json &data_read);
+ /* For custom request */
+ bool handle_custom_request(ctx::request_info* request);
}; /* class context_manager_impl */
} /* namespace ctx */
int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener)
{
int req_id = _subscribe(subject.c_str(), &option, listener);
- IF_FAIL_RETURN_TAG(req_id > 0, ERR_OPERATION_FAILED, _E, "Subscribe event failed");
+ IF_FAIL_RETURN_TAG(req_id > 0, req_id, _E, "Subscribe event failed");
_D(YELLOW("Subscribe event(rule%d). req%d"), rule_id, req_id);
return ERR_NONE;
fact_request *req = new(std::nothrow) fact_request(REQ_SUBSCRIBE,
rid, subject, option ? option->str().c_str() : NULL, this);
- IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
+ IF_FAIL_RETURN_TAG(req, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
_context_mgr->assign_request(req);
add_sub(REQ_SUBSCRIBE, rid, subject, option, listener);
if (last_err != ERR_NONE) {
remove_sub(REQ_SUBSCRIBE, rid);
_E("Subscription request failed: %#x", last_err);
- return -1;
+ return last_err;
}
return rid;
{
// Unsubscribe event
int error = ctx::context_monitor::get_instance()->unsubscribe(id, event->name, event->option, this);
+ if (error == ERR_NOT_SUPPORTED) {
+ _E("Stop rule%d (event not supported)");
+ return ERR_NONE;
+ }
IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
return error;
// Check if creator is uninstalled
if (ctx::rule_manager::is_uninstalled_package(creator)) {
_D("Creator(%s) of rule%d is uninstalled.", creator.c_str(), id);
- g_idle_add(handle_uninstalled_rule, &id);
+ g_idle_add(handle_uninstalled_rule, &creator);
return;
}
gboolean ctx::trigger_rule::handle_uninstalled_rule(gpointer data)
{
- int* rule_id = static_cast<int*>(data);
- rule_mgr->disable_rule(*rule_id);
- rule_mgr->remove_rule(*rule_id);
+ std::string* app_id = static_cast<std::string*>(data);
+ rule_mgr->handle_rule_of_uninstalled_app(*app_id);
return FALSE;
}
#include <app_manager.h>
#include "rule_manager.h"
#include "context_monitor.h"
-#include "template_manager.h"
#include "rule.h"
#include "timer.h"
return str;
}
-ctx::rule_manager::rule_manager(ctx::template_manager* tmpl_mgr)
-: _tmpl_mgr(tmpl_mgr)
+ctx::rule_manager::rule_manager()
{
}
int error;
// Create tables into db (rule, template)
- std::string q1 = std::string("enabled INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL,")
+ std::string q1 = std::string("status 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";
ret = db_manager::create_table(1, RULE_TABLE, q1.c_str(), NULL, NULL);
IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed");
- std::string q2 = std::string("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)";
- ret = db_manager::execute(2, q2.c_str(), NULL);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
-
- // Apply templates
- _tmpl_mgr->apply_templates();
-
// Before re-enable rules, handle uninstalled app's rules
if (get_uninstalled_app() > 0) {
error = clear_rule_of_uninstalled_app(true);
return ret;
}
+void ctx::rule_manager::handle_rule_of_uninstalled_app(std::string app_id)
+{
+ uninstalled_apps.insert(app_id);
+ clear_rule_of_uninstalled_app();
+}
+
int ctx::rule_manager::get_uninstalled_app(void)
{
// Return number 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 FROM context_trigger_rule WHERE enabled = 1 and (";
+ std::string q1 = "SELECT row_id FROM context_trigger_rule WHERE status = 2 and (";
q1 += creator_list;
q1 += ")";
return ERR_NONE;
}
+int ctx::rule_manager::pause_rule_with_item(std::string& subject)
+{
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=2) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
+ std::vector<json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query row_ids to be paused");
+ IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
+
+ _D("Pause rules related to %s", subject.c_str());
+ std::vector<json>::iterator vec_end = record.end();
+ for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
+ ctx::json elem = *vec_pos;
+ int row_id;
+ elem.get(NULL, "row_id", &row_id);
+
+ int error = pause_rule(row_id);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules using custom item");
+ }
+
+ return ERR_NONE;
+}
+
+int ctx::rule_manager::resume_rule_with_item(std::string& subject)
+{
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=1) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
+ std::vector<json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query paused rule ids failed");
+ IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
+
+ _D("Resume rules related to %s", subject.c_str());
+ std::string q_rowid;
+ std::vector<json>::iterator vec_end = record.end();
+ for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
+ ctx::json elem = *vec_pos;
+ int row_id;
+ elem.get(NULL, "row_id", &row_id);
+
+ int error = enable_rule(row_id);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to resume rule");
+ }
+
+ return ERR_NONE;
+}
+
bool ctx::rule_manager::reenable_rule(void)
{
int error;
- std::string q = "SELECT row_id FROM context_trigger_rule where enabled = 1";
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE status = 2";
std::vector<json> record;
bool ret = db_manager::execute_sync(q.c_str(), &record);
IF_FAIL_RETURN_TAG(ret, false, _E, "Query row_ids of enabled rules failed");
+ IF_FAIL_RETURN_TAG(record.size() > 0, true, _D, "No rule to re-enable");
+ _D(YELLOW("Re-enable rule started"));
+
+ std::string q_rowid;
std::vector<json>::iterator vec_end = record.end();
for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
ctx::json elem = *vec_pos;
elem.get(NULL, "row_id", &row_id);
error = enable_rule(row_id);
- if (error != ERR_NONE) {
+ if (error == ERR_NOT_SUPPORTED) {
+ q_rowid += "(row_id = " + int_to_string(row_id) + ") OR ";
+ } else if (error != ERR_NONE) {
_E("Re-enable rule%d failed(%d)", row_id, error);
}
}
+ q_rowid = q_rowid.substr(0, q_rowid.length() - 4);
+
+ // For rules which is failed to re-enable
+ std::string q_update = "UPDATE context_trigger_rule SET status = 1 WHERE " + q_rowid;
+ std::vector<json> record2;
+ ret = db_manager::execute_sync(q_update.c_str(), &record2);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update rules as paused");
return true;
}
if (lei.compare(rei))
return false;
- // Compare option // TODO test
+ // Compare option
ctx::json loption, roption;
litem.get(NULL, CT_RULE_EVENT_OPTION, &loption);
ritem.get(NULL, CT_RULE_EVENT_OPTION, &roption);
IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", rule_id);
// Update db to set 'enabled'
- query = "UPDATE context_trigger_rule SET enabled = 1 WHERE row_id = ";
+ query = "UPDATE context_trigger_rule SET status = 2 WHERE row_id = ";
query += id_str;
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");
int error;
rule_map_t::iterator it = rule_map.find(rule_id);
+ bool is_paused = (it == rule_map.end());
+
+ // For 'enabled' rule, not 'paused'
+ if (!is_paused) {
+ // Stop the rule
+ trigger_rule* rule = static_cast<trigger_rule*>(it->second);
+ error = rule->stop();
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id);
+
+ // Remove rule instance from rule_map
+ delete rule;
+ rule_map.erase(it);
+ }
+
+ // Update db to set 'disabled' // TODO skip while clear uninstalled rule
+ std::string query = "UPDATE context_trigger_rule SET status = 0 WHERE row_id = ";
+ query += int_to_string(rule_id);
+ std::vector<json> record;
+ ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
+
+ _D(YELLOW("Disable Rule%d succeeded"), rule_id);
+ return ERR_NONE;
+}
+
+int ctx::rule_manager::pause_rule(int rule_id)
+{
+ bool ret;
+ int error;
+
+ 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");
// Stop the rule
error = rule->stop();
IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id);
- // Update db to set 'disabled' // TODO skip while clear uninstalled rule
- std::string query = "UPDATE context_trigger_rule SET enabled = 0 WHERE row_id = ";
+ // Update db to set 'paused'
+ std::string query = "UPDATE context_trigger_rule SET status = 1 WHERE row_id = ";
query += int_to_string(rule_id);
std::vector<json> record;
delete rule;
rule_map.erase(it);
- _D(YELLOW("Disable Rule%d succeeded"), rule_id);
+ _D(YELLOW("Pause Rule%d"), rule_id);
return ERR_NONE;
}
bool ctx::rule_manager::is_rule_enabled(int rule_id)
{
- std::string q = "SELECT enabled FROM context_trigger_rule WHERE row_id =";
+ std::string q = "SELECT status FROM context_trigger_rule WHERE row_id =";
q += int_to_string(rule_id);
std::vector<json> record;
bool ret = db_manager::execute_sync(q.c_str(), &record);
IF_FAIL_RETURN_TAG(ret, false, _E, "Query enabled by rule id failed");
- int enabled;
- record[0].get(NULL, "enabled", &enabled);
+ int status;
+ record[0].get(NULL, "status", &status);
- if (enabled == 1)
- return true;
- else
- return false;
+ return (status != 0);
}
int ctx::rule_manager::get_rule_by_id(std::string creator, int rule_id, ctx::json* request_result)
{
(*request_result) = "{ \"" CT_RULE_ARRAY_ENABLED "\" : [ ] , \"" CT_RULE_ARRAY_DISABLED "\" : [ ] }";
- std::string q = "SELECT row_id, enabled FROM context_trigger_rule WHERE (creator = '";
+ std::string q = "SELECT row_id, status FROM context_trigger_rule WHERE (creator = '";
q += creator;
q += "')";
for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
ctx::json elem = *vec_pos;
std::string id;
- int enabled;
+ int status;
elem.get(NULL, "row_id", &id);
- elem.get(NULL, "enabled", &enabled);
+ elem.get(NULL, "status", &status);
- if (enabled == 1) {
+ if (status >= 1) {
(*request_result).array_append(NULL, CT_RULE_ARRAY_ENABLED, string_to_int(id));
- } else if (enabled == 0) {
+ } else if (status == 0) {
(*request_result).array_append(NULL, CT_RULE_ARRAY_DISABLED, string_to_int(id));
}
}
class json;
class context_trigger;
- class template_manager;
class trigger_rule;
class rule_manager {
public:
- rule_manager(ctx::template_manager* tmpl_mgr);
+ rule_manager();
~rule_manager();
bool init();
int get_rule_ids(std::string creator, ctx::json* request_result);
int check_rule(std::string creator, int rule_id);
bool is_rule_enabled(int rule_id);
+ int pause_rule_with_item(std::string& subject);
+ int pause_rule(int rule_id);
+ int resume_rule_with_item(std::string& subject);
+ void handle_rule_of_uninstalled_app(std::string app_id);
static bool is_uninstalled_package(std::string app_id);
private:
- ctx::template_manager* _tmpl_mgr;
-
bool reenable_rule(void);
int verify_rule(ctx::json& rule, const char* app_id);
int64_t get_duplicated_rule_id(std::string creator, ctx::json& rule);
#include <context_trigger_types_internal.h>
#include <db_mgr.h>
#include "../context_mgr_impl.h"
+#include "rule_manager.h"
#include "template_manager.h"
static std::string int_to_string(int i)
return str;
}
-ctx::template_manager::template_manager(ctx::context_manager_impl* ctx_mgr)
-: _context_mgr(ctx_mgr)
+ctx::template_manager::template_manager(ctx::context_manager_impl* ctx_mgr, ctx::rule_manager* rule_mgr)
+: _context_mgr(ctx_mgr), _rule_mgr(rule_mgr)
{
}
ctx::template_manager::~template_manager()
{
+ apply_templates();
}
-bool ctx::template_manager::get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options)
+bool ctx::template_manager::init()
{
- return _context_mgr->pop_trigger_item(subject, operation, attributes, options);
+ std::string q = std::string("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, owner TEXT DEFAULT '' NOT NULL)";
+
+ std::vector<json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
+
+ // Apply templates
+ apply_templates();
+
+ return true;
}
-void ctx::template_manager::apply_templates(void)
+void ctx::template_manager::apply_templates()
{
- // TODO remove templates if needed
std::string subject;
int operation;
ctx::json attributes;
ctx::json options;
- std::string q_update;
- std::string q_insert = "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options) VALUES";
- int cnt = 0;
+ std::string owner;
+ bool unregister;
+ std::string query;
+ query.clear();
+
+ while(_context_mgr->pop_trigger_item(subject, operation, attributes, options, owner, unregister)) {
+ if (unregister) {
+ query += remove_template(subject);
+ _rule_mgr->pause_rule_with_item(subject);
+ } else {
+ query += add_template(subject, operation, attributes, options, owner);
+ if (!owner.empty()) {
+ _rule_mgr->resume_rule_with_item(subject);
+ }
+ }
+ }
+ IF_FAIL_VOID(!query.empty());
- while (get_fact_definition(subject, operation, attributes, options)) {
- _D("Subject: %s, Ops: %d", subject.c_str(), operation);
- _J("Attr", attributes);
- _J("Opt", options);
+ std::vector<json> record;
+ bool ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_VOID_TAG(ret, _E, "Update template db failed");
+}
- q_update += "UPDATE context_trigger_template SET operation=" + int_to_string(operation)
- + ", attributes='" + attributes.str() + "', options='" + options.str() + "' WHERE name='" + subject + "';";
+std::string ctx::template_manager::add_template(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options, std::string &owner)
+{
+ _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str());
+ _J("Attr", attributes);
+ _J("Opt", options);
- q_insert += " ('" + subject + "', " + int_to_string(operation) + ", '" + attributes.str() + "', '" + options.str() + "'),";
- cnt++;
- }
- IF_FAIL_VOID(cnt > 0);
+ std::string query = "UPDATE context_trigger_template SET operation=" + int_to_string(operation)
+ + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner
+ + "' WHERE name='" + subject + "'; ";
- q_insert.erase(q_insert.end() - 1, q_insert.end());
- q_insert += ";";
+ query += "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options, owner) VALUES ('"
+ + subject + "', " + int_to_string(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '"
+ + owner + "'); ";
- bool ret = db_manager::execute(1, q_update.c_str(), NULL);
- IF_FAIL_VOID_TAG(ret, _E, "Update item definition failed");
+ return query;
+}
+
+std::string ctx::template_manager::remove_template(std::string &subject)
+{
+ _D("[Remove template] Subject: %s", subject.c_str());
+ std::string query = "DELETE FROM context_trigger_template WHERE name = '" + subject + "'; ";
- ret = db_manager::execute(2, q_insert.c_str(), NULL);
- IF_FAIL_VOID_TAG(ret, _E, "Insert item definition failed");
+ return query;
}
int ctx::template_manager::get_template(std::string &subject, ctx::json* tmpl)
namespace ctx {
class context_manager_impl;
-
+ class rule_manager;
class template_manager {
public:
- template_manager(ctx::context_manager_impl* ctx_mgr);
+ template_manager(ctx::context_manager_impl* ctx_mgr, ctx::rule_manager* rule_mgr);
~template_manager();
- void apply_templates(void);
- bool get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options);
+ bool init();
+ void apply_templates();
int get_template(std::string &subject, ctx::json* tmpl);
private:
context_manager_impl *_context_mgr;
+ rule_manager *_rule_mgr;
+
+ std::string add_template(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options, std::string &owner);
+ std::string remove_template(std::string &subject);
}; /* class template_manager */
#include <types_internal.h>
#include <context_trigger_types_internal.h>
#include "trigger.h"
-#include "rule_manager.h"
#include "context_monitor.h"
#include "template_manager.h"
+#include "rule_manager.h"
ctx::context_trigger::context_trigger()
: rule_mgr(NULL)
{
// Release the occupied resources.
// This function is called from the main thread during the service termination process.
- _D("Context Trigger Release");
- delete rule_mgr;
- rule_mgr = NULL;
-
_D("Template Manager Release");
delete tmpl_mgr;
tmpl_mgr = NULL;
+ _D("Rule Manager Release");
+ delete rule_mgr;
+ rule_mgr = NULL;
+
ctx::context_monitor::destroy();
}
void ctx::context_trigger::process_initialize(ctx::context_manager_impl* mgr)
{
+ // Context Monitor
ctx::context_monitor::set_context_manager(mgr);
- tmpl_mgr = new(std::nothrow) template_manager(mgr);
+ // Rule Manager
+ rule_mgr = new(std::nothrow) rule_manager();
+ IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed");
+
+ // Template Manager
+ tmpl_mgr = new(std::nothrow) template_manager(mgr, rule_mgr);
IF_FAIL_VOID_TAG(tmpl_mgr, _E, "Memory allocation failed");
- rule_mgr = new(std::nothrow) rule_manager(tmpl_mgr);
- IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed");
+ // Initialization
+ if (!tmpl_mgr->init()) {
+ _E("Template manager initialization failed");
+ raise(SIGTERM);
+ }
- bool ret = rule_mgr->init();
- if (!ret) {
- _E("Context trigger initialization failed.");
+ if (!rule_mgr->init()) {
+ _E("Context trigger initialization failed");
raise(SIGTERM);
}
}
namespace ctx {
- class rule_manager;
class template_manager;
+ class rule_manager;
class client_request;
class context_manager_impl;
class context_trigger {
return NULL;
}
+const char* ctx::request_info::get_package_id()
+{
+ return NULL;
+}
+
const char* ctx::request_info::get_client()
{
return NULL;
virtual const credentials* get_credentials();
virtual const char* get_app_id();
+ virtual const char* get_package_id();
/* TODO: remove this get_client() */
virtual const char* get_client();
virtual bool reply(int error) = 0;