int type;
std::string uri;
ctx_sched_job_context_h jobContext;
+ std::set<std::string> conjunctionKeys;
std::set<std::string> disjunctionKeys;
_context_trigger_rule_entry_s(int c, int t, const char* u) :
EXPORT_API int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(rule && rule_id);
+
+ int err = ctx_sched_add_job(SCHED, rule->job, rule_id);
+
+ if (err == E_PARAM)
+ return E_INV_RULE;
+
+ return err;
}
EXPORT_API int context_trigger_remove_rule(int rule_id)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ int err = ctx_sched_remove_job(SCHED, rule_id);
+
+ if (err == E_RULE_ON)
+ return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
+ else if (err == E_PARAM)
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+
+ return err;
}
EXPORT_API int context_trigger_enable_rule(int rule_id)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ int err = ctx_sched_start_job(SCHED, rule_id);
+
+ if (err == E_PARAM)
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+
+ return err;
}
EXPORT_API int context_trigger_disable_rule(int rule_id)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ int err = ctx_sched_stop_job(SCHED, rule_id);
+
+ if (err == E_PARAM)
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+
+ return err;
+}
+
+static bool __foreach_job_cb(ctx_sched_h scheduler, ctx_sched_job_h job, void *user_data)
+{
+ auto jobs = static_cast<std::vector<ctx_sched_job_h>*>(user_data);
+ jobs->push_back(job);
+ return true;
}
EXPORT_API int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enabled_rule_count, int** disabled_rule_ids, int* disabled_rule_count)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
+
+ std::vector<ctx_sched_job_h> jobs;
+
+ int err = ctx_sched_foreach_job(SCHED, __foreach_job_cb, &jobs);
+
+ if (err == E_NO_DATA) {
+ *enabled_rule_ids = NULL;
+ *enabled_rule_count = 0;
+ *disabled_rule_ids = NULL;
+ *disabled_rule_count = 0;
+ return E_NONE;
+ }
+
+ IF_FAIL_RETURN(IS_SUCCESS(err), err);
+
+ std::vector<int> startedJobIds;
+ std::vector<int> stoppedJobIds;
+
+ for (auto& job : jobs) {
+ bool started = false;
+ int jobId = 0;
+
+ ctx_sched_job_is_started(job, &started);
+ ctx_sched_job_get_id(job, &jobId);
+ ctx_sched_job_destroy(job);
+
+ if (started)
+ startedJobIds.push_back(jobId);
+ else
+ stoppedJobIds.push_back(jobId);
+ }
+
+ *enabled_rule_count = startedJobIds.size();
+
+ if (*enabled_rule_count > 0)
+ *enabled_rule_ids = static_cast<int*>(g_memdup(startedJobIds.data(), startedJobIds.size() * sizeof(int)));
+ else
+ *enabled_rule_ids = NULL;
+
+ *disabled_rule_count = stoppedJobIds.size();
+
+ if (*disabled_rule_count > 0)
+ *disabled_rule_ids = static_cast<int*>(g_memdup(stoppedJobIds.data(), stoppedJobIds.size() * sizeof(int)));
+ else
+ *disabled_rule_ids = NULL;
+
+ return E_NONE;
}
EXPORT_API int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(rule);
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ ctx_sched_job_h job = NULL;
+
+ int err = ctx_sched_get_job(SCHED, rule_id, &job);
+
+ if (err == E_PARAM)
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+ else if (err != E_NONE)
+ return err;
+
+ *rule = new(std::nothrow) _context_trigger_rule_h(job);
+ if (*rule == NULL) {
+ _E_ALLOC;
+ ctx_sched_job_destroy(job);
+ return E_NO_MEM;
+ }
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(rule);
+ IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+
+ *rule = new(std::nothrow) _context_trigger_rule_h();
+ ASSERT_ALLOC(*rule);
+ if ((*rule)->job == NULL) {
+ _E_ALLOC;
+ delete *rule;
+ return E_NO_MEM;
+ }
+
+ ctx_sched_job_set_disjunction((*rule)->job, logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION);
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_destroy(context_trigger_rule_h rule)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(rule);
+
+ delete rule;
+
+ return E_NONE;
+}
+
+static int __set_event(context_trigger_rule_h rule, context_trigger_rule_entry_h event)
+{
+ IF_FAIL_RETURN(event->jobContext, E_PARAM);
+ IF_FAIL_RETURN_TAG(!rule->hasEvent, E_INV_RULE, _E, "The rule already has the event");
+
+ EventItem contextItem(event->type);
+ IF_FAIL_RETURN_TAG(contextItem.isValid(event->jobContext), E_INV_RULE, _E, "Incomplete event");
+
+ ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(event->jobContext);
+ ASSERT_ALLOC(dup);
+
+ int err = ctx_sched_job_add_trigger(rule->job, dup);
+ if (IS_FAILED(err)) {
+ ctx_sched_job_context_destroy(dup);
+ return err;
+ }
+
+ rule->hasEvent = true;
+
+ return E_NONE;
+}
+
+static int __add_condition(context_trigger_rule_h rule, context_trigger_rule_entry_h condition)
+{
+ IF_FAIL_RETURN(condition->jobContext, E_PARAM);
+
+ bool exist = (rule->conditions.find(condition->uri) != rule->conditions.end());
+ IF_FAIL_RETURN_TAG(!exist, E_INV_RULE, _E, "The same condition exists");
+
+ ConditionItem contextItem(condition->type);
+ IF_FAIL_RETURN_TAG(contextItem.isValid(condition->jobContext), E_INV_RULE, _E, "Incomplete condition");
+
+ ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(condition->jobContext);
+ ASSERT_ALLOC(dup);
+
+ int err = ctx_sched_job_add_requirement(rule->job, dup);
+ if (IS_FAILED(err)) {
+ ctx_sched_job_context_destroy(dup);
+ return err;
+ }
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(rule && entry);
+ IF_FAIL_RETURN_TAG(!rule->readOnly, E_PARAM,
+ _E, "A rule acquired by context_trigger_get_rule_by_id() is not allowed to be modified.");
+
+ if (entry->category == CATEGORY_EVENT)
+ return __set_event(rule, entry);
+ else
+ return __add_condition(rule, entry);
+}
+
+static bool __is_call_operation(app_control_h ctrl)
+{
+ char *op = NULL;
+ int err = app_control_get_operation(ctrl, &op);
+ IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _E, "Getting operation of app control failed");
+
+ bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
+ g_free(op);
+
+ return ret;
+}
+
+static bool __is_ui_app(app_control_h ctrl)
+{
+ char* appId = NULL;
+ int err = app_control_get_app_id(ctrl, &appId);
+
+ IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
+
+ pkgmgrinfo_appinfo_h appInfo;
+ err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
+ g_free(appId);
+
+ IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
+
+ char *appType = NULL;
+ pkgmgrinfo_appinfo_get_component_type(appInfo, &appType);
+
+ bool ret = STR_EQ(appType, "uiapp");
+
+ pkgmgrinfo_appinfo_destroy_appinfo(appInfo);
+
+ return ret;
}
EXPORT_API int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(rule && app_control);
+
+ if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/appmanager.launch")) {
+ _E("Privilege denied");
+ return E_ACCESS;
+ }
+
+ if (__is_call_operation(app_control) &&
+ !PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/call")) {
+ _E("Privilege denied");
+ return E_ACCESS;
+ }
+
+ IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
+ IF_FAIL_RETURN_TAG(__is_ui_app(app_control), E_INV_RULE, _E, "Invalid app-control");
+
+ bundle* bn = NULL;
+ app_control_export_as_bundle(app_control, &bn);
+ IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting failed");
+
+ int ret = ctx_sched_job_set_app_control(rule->job, bn);
+
+ if (ret == E_NONE)
+ rule->hasAction = true;
+
+ return ret;
}
-EXPORT_API int context_trigger_rule_set_action_notification(context_trigger_rule_h rule, const char* title, const char* content, const char* icon_path, app_control_h app_control)
+static bool __is_valid_app_control(app_control_h ctrl)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ if (!ctrl) return true;
+
+ char* appId = NULL;
+ int err = app_control_get_app_id(ctrl, &appId);
+ IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
+
+ pkgmgrinfo_appinfo_h appInfo;
+ err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
+ g_free(appId);
+ IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
+
+ pkgmgrinfo_appinfo_destroy_appinfo(appInfo);
+
+ return true;
+}
+
+EXPORT_API int context_trigger_rule_set_action_notification(context_trigger_rule_h rule,
+ const char* title, const char* content, const char* icon_path, app_control_h app_control)
+{
+ INIT_SCHED;
+ ASSERT_NOT_NULL(rule && title && content);
+
+ if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/notification")) {
+ _E("Privilege denied");
+ return E_ACCESS;
+ }
+
+ IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
+ IF_FAIL_RETURN_TAG(__is_valid_app_control(app_control), E_INV_RULE, _E, "Invalid app-control");
+
+ bundle* bn = NULL;
+ if (app_control) {
+ app_control_export_as_bundle(app_control, &bn);
+ IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting failed");
+ }
+
+ int ret = ctx_sched_job_set_notification(rule->job, title, content, icon_path, bn);
+
+ if (ret == E_NONE)
+ rule->hasAction = true;
+
+ return ret;
}
//LCOV_EXCL_START
EXPORT_API int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h rule,
const char *bus_name, const char *object_path, const char *interface_name, const char *method_name, GVariant *param)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
+ IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
+
+ int ret = ctx_sched_job_set_dbus(rule->job, bus_name, object_path, interface_name, method_name, param);
+
+ if (ret == E_NONE)
+ rule->hasAction = true;
+
+ return ret;
}
//LCOV_EXCL_STOP
EXPORT_API int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(rule && description);
+ IF_FAIL_RETURN(strlen(description) > 0, E_PARAM);
+
+ return ctx_sched_job_set_user_data(rule->job, description, strlen(description) + 1);
}
EXPORT_API int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(rule && description);
+
+ char* val = NULL;
+ size_t len = 0;
+ int err = ctx_sched_job_get_user_data(rule->job, &val, &len);
+ IF_FAIL_RETURN(IS_SUCCESS(err), err);
+ IF_FAIL_RETURN(val, E_NONE);
+
+ *description = val;
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_event_create(context_trigger_event_e event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(entry);
+ IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+
+ EventItem contextItem(event_item);
+ IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
+
+ if (contextItem.deprecated())
+ _DEPRECATED_EVENT(event_item);
+
+ IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
+
+ bool supported = false;
+ ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), &supported);
+ IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Event-%d is not supported", event_item);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, event_item, contextItem.getUri());
+ ASSERT_ALLOC(*entry);
+
+ ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
+
+ return E_NONE;
+}
+
+static bool __is_valid_pkg_id(const char* pkgId)
+{
+ IF_FAIL_RETURN(pkgId, false);
+
+ pkgmgrinfo_pkginfo_h pkgInfo;
+ int err = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, getuid(), &pkgInfo);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkgInfo);
+
+ return (PMINFO_R_OK == err);
}
EXPORT_API int context_trigger_rule_custom_event_create(const char* event_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(event_item && provider && entry);
+ IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+ std::string uri = __get_custom_uri(event_item, provider);
+
+ bool registered = false;
+ ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, ®istered);
+ IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", event_item);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, 0, uri.c_str());
+ ASSERT_ALLOC(*entry);
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(supported);
+
+ EventItem contextItem(event_item);
+ IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
+
+ return ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), supported);
}
EXPORT_API int context_trigger_rule_condition_create(context_trigger_condition_e condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(entry);
+ IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+
+ ConditionItem contextItem(condition_item);
+ IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
+
+ if (contextItem.deprecated())
+ _DEPRECATED_COND(condition_item);
+
+ IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
+
+ bool supported = false;
+ ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), &supported);
+ IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Condition-%d is not supported", condition_item);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, condition_item, contextItem.getUri());
+ ASSERT_ALLOC(*entry);
+
+ ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_custom_condition_create(const char* condition_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(condition_item && provider && entry);
+ IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+ IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+ std::string uri = __get_custom_uri(condition_item, provider);
+
+ bool registered = false;
+ ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, ®istered);
+ IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", condition_item);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, 0, uri.c_str());
+ ASSERT_ALLOC(*entry);
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(supported);
+
+ ConditionItem contextItem(condition_item);
+ IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
+
+ return ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), supported);
}
EXPORT_API int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(entry);
+
+ delete entry;
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(entry && option_key);
+
+ ContextItem* contextItem = __get_context_item(entry);
+ IF_FAIL_RETURN(contextItem, E_FAILED);
+
+ bool valid = contextItem->isValid(option_key, value);
+ delete contextItem;
+ IF_FAIL_RETURN(valid, E_INV_RULE);
+
+ ctx_sched_job_context_prepare_attribute_int(entry->jobContext, option_key);
+ return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, option_key, value);
}
EXPORT_API int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ _DEPRECATED_FUNC;
+ ASSERT_NOT_NULL(entry && option_key && value);
+
+ ContextItem* contextItem = __get_context_item(entry);
+ IF_FAIL_RETURN(contextItem, E_FAILED);
+
+ bool valid = contextItem->isValid(option_key, value);
+ delete contextItem;
+ IF_FAIL_RETURN(valid, E_INV_RULE);
+
+ ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
+ return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, value);
}
EXPORT_API int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ _DEPRECATED_FUNC;
+ ASSERT_NOT_NULL(entry && option_key && event_data_key);
+ IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
+
+ ConditionItem contextItem(entry->type);
+ IF_FAIL_RETURN(contextItem.isValid(option_key), E_INV_RULE);
+
+ ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
+ return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, event_data_key);
+}
+
+static bool __is_member_key(context_trigger_rule_entry_h entry, const char* key)
+{
+ if (entry->conjunctionKeys.find(key) != entry->conjunctionKeys.end() ||
+ entry->disjunctionKeys.find(key) != entry->disjunctionKeys.end()) {
+ _D("'%s' found", key);
+ return true;
+ }
+
+ _D("'%s' not found", key);
+ return false;
}
EXPORT_API int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry, context_trigger_logical_type_e logical_type, const char* key)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(entry && key);
+ IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+
+ ContextItem* contextItem = __get_context_item(entry);
+ IF_FAIL_RETURN(contextItem, E_FAILED);
+
+ bool valid = contextItem->isValid(key);
+ delete contextItem;
+ IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+ IF_FAIL_RETURN(!__is_member_key(entry, key), E_INV_RULE);
+
+ if (logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION)
+ entry->conjunctionKeys.insert(key);
+ else
+ entry->disjunctionKeys.insert(key);
+
+ return E_NONE;
}
EXPORT_API int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ _DEPRECATED_FUNC;
+ ASSERT_NOT_NULL(entry && key && op && event_data_key);
+ IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
+
+ ConditionItem contextItem(entry->type);
+ IF_FAIL_RETURN(contextItem.isValid(key), E_INV_RULE);
+ IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
+
+ ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
+
+ if (__getOpType(op) == OpType::EQ)
+ return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, event_data_key);
+
+ if (__getOpType(op) == OpType::NE)
+ return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, event_data_key);
+
+ _E("Invalid operator");
+ return E_INV_RULE;
}
EXPORT_API int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(entry && key && op);
+
+ ContextItem* contextItem = __get_context_item(entry);
+ IF_FAIL_RETURN(contextItem, E_FAILED);
+
+ bool valid = contextItem->isValid(key, value);
+ delete contextItem;
+ IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+ IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
+
+ ctx_sched_job_context_prepare_attribute_int(entry->jobContext, key);
+
+ if (__getOpType(op) == OpType::EQ)
+ return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, key, value);
+
+ if (__getOpType(op) == OpType::NE)
+ return ctx_sched_job_context_attribute_add_ne_int(entry->jobContext, key, value);
+
+ //TODO: Consider logical disjunction
+ if (__getOpType(op) == OpType::GT)
+ return ctx_sched_job_context_attribute_set_gt_int(entry->jobContext, key, value);
+
+ if (__getOpType(op) == OpType::GE)
+ return ctx_sched_job_context_attribute_set_ge_int(entry->jobContext, key, value);
+
+ if (__getOpType(op) == OpType::LT)
+ return ctx_sched_job_context_attribute_set_lt_int(entry->jobContext, key, value);
+
+ if (__getOpType(op) == OpType::LE)
+ return ctx_sched_job_context_attribute_set_le_int(entry->jobContext, key, value);
+
+ _E("Invalid operator");
+ return E_INV_RULE;
}
EXPORT_API int context_trigger_rule_entry_add_comparison_string(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* value)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ ASSERT_NOT_NULL(entry && key && op && value);
+
+ ContextItem* contextItem = __get_context_item(entry);
+ IF_FAIL_RETURN(contextItem, E_FAILED);
+
+ bool valid = contextItem->isValid(key, value);
+ delete contextItem;
+ IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+ IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
+
+ ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
+
+ if (__getOpType(op) == OpType::EQ)
+ return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, value);
+
+ if (__getOpType(op) == OpType::NE)
+ return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, value);
+
+ _E("Invalid operator");
+ return E_INV_RULE;
}
EXPORT_API int context_trigger_custom_register(const char* name, const char* attr_template)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(name && attr_template);
+
+ //TODO: Is it allowed to overwrite a template?
+ CustomTemplate::remove(name);
+
+ bool success = CustomTemplate::add(name, attr_template);
+ IF_FAIL_RETURN_TAG(success, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
+
+ const char* pkgId = __get_pkg_id();
+ IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
+
+ std::string uri = __get_custom_uri(name, pkgId);
+
+ int err = ctx_sched_custom_register(SCHED, uri.c_str());
+ IF_FAIL_RETURN(err == E_NONE, E_FAILED);
+
+ return E_NONE;
}
EXPORT_API int context_trigger_custom_unregister(const char* name)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(name);
+
+ CustomTemplate::remove(name);
+
+ const char* pkgId = __get_pkg_id();
+ IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
+
+ std::string uri = __get_custom_uri(name, pkgId);
+
+ ctx_sched_custom_unregister(SCHED, uri.c_str());
+
+ return E_NONE;
}
EXPORT_API int context_trigger_custom_publish(const char* name, const char* fact)
{
- return CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED;
+ INIT_SCHED;
+ ASSERT_NOT_NULL(name && fact);
+
+ CustomTemplate* customTemplate = CustomTemplate::get(name);
+ IF_FAIL_RETURN_TAG(customTemplate, E_PARAM, _E, "Unknown custom name");
+ IF_FAIL_RETURN(customTemplate->match(fact), CONTEXT_TRIGGER_ERROR_INVALID_DATA);
+
+ const char* pkgId = __get_pkg_id();
+ IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
+
+ std::string uri = __get_custom_uri(name, pkgId);
+
+ return ctx_sched_publish_context_json(SCHED, uri.c_str(), fact);
}