2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <app_control_internal.h>
22 #include <pkgmgr-info.h>
24 #include <ContextTypes.h>
25 #include <SharedUtil.h>
26 #include <ScopeMutex.h>
27 #include <job_scheduler_internal.h>
28 #include <context_trigger.h>
29 #include <context_trigger_internal.h>
31 #include "PrivilegeChecker.h"
32 #include "ContextItem.h"
33 #include "CustomTemplate.h"
35 #define _DEPRECATED_FUNC _W("DEPRECATION WARNING: %s is deprecated and will be removed from next release.", __FUNCTION__)
36 #define _DEPRECATED_EVENT(id) _W("DEPRECATION WARNING: This event (%d) is deprecated and will be removed from next release.", (id))
37 #define _DEPRECATED_COND(id) _W("DEPRECATION WARNING: This condition (%d) is deprecated and will be removed from next release.", (id))
39 #define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, E_STR_ALLOC)
40 #define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
41 #define INIT_SCHED IF_FAIL_RETURN_TAG(__scheduler.get(), E_SUPPORT, _E, "Job scheduler is not supported")
42 #define SCHED __scheduler.get()
44 #define PKG_ID_LENGTH 128
48 CATEGORY_CONDITION = 2
56 GE, // greater than or equals to
58 LE // less than or equals to
61 typedef struct _context_trigger_rule_s {
66 std::set<std::string> conditions;
68 _context_trigger_rule_s() :
69 job(NULL), readOnly(false), hasEvent(false), hasAction(false)
71 ctx_sched_job_create_on_demand(&job);
74 _context_trigger_rule_s(ctx_sched_job_h j) :
75 job(j), readOnly(true), hasEvent(true), hasAction(true)
79 ~_context_trigger_rule_s()
81 ctx_sched_job_destroy(job);
83 } _context_trigger_rule_h;
86 typedef struct _context_trigger_rule_entry_s {
90 ctx_sched_job_context_h jobContext;
91 std::set<std::string> conjunctionKeys;
92 std::set<std::string> disjunctionKeys;
94 _context_trigger_rule_entry_s(int c, int t, const char* u) :
95 category(c), type(t), uri(u), jobContext(NULL)
97 if (category == CATEGORY_EVENT)
98 ctx_sched_job_trigger_create(uri.c_str(), &jobContext);
100 ctx_sched_job_requirement_create(uri.c_str(), false, &jobContext);
103 ~_context_trigger_rule_entry_s()
105 ctx_sched_job_context_destroy(jobContext);
107 } _context_trigger_rule_entry_h;
113 ctx_sched_h __scheduler;
116 Scheduler() : __scheduler(NULL) {}
120 ctx_sched_destroy(__scheduler);
125 if (__scheduler == NULL)
126 ctx_sched_create(&__scheduler);
133 static OpType __getOpType(const char* opStr)
135 if (STR_EQ(opStr, CONTEXT_TRIGGER_EQUAL_TO))
138 if (STR_EQ(opStr, CONTEXT_TRIGGER_NOT_EQUAL_TO))
141 if (STR_EQ(opStr, CONTEXT_TRIGGER_GREATER_THAN))
144 if (STR_EQ(opStr, CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO))
147 if (STR_EQ(opStr, CONTEXT_TRIGGER_LESS_THAN))
150 if (STR_EQ(opStr, CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO))
153 return OpType::UNDEFINED;
156 static std::string __get_custom_uri(std::string name, std::string provider)
158 std::string uri("http://");
159 uri += provider + "/context/custom/" + name;
163 static const char* __get_pkg_id()
165 static char pkgId[PKG_ID_LENGTH] = {0};
167 if (strlen(pkgId) > 0)
170 aul_app_get_pkgid_bypid(getpid(), pkgId, PKG_ID_LENGTH);
172 if (strlen(pkgId) > 0)
178 static ContextItem* __get_context_item(context_trigger_rule_entry_h entry)
180 ContextItem* contextItem = NULL;
182 if (entry->category == CATEGORY_EVENT)
183 contextItem = new(std::nothrow) EventItem(entry->type);
185 contextItem = new(std::nothrow) ConditionItem(entry->type);
193 static Scheduler __scheduler;
196 EXPORT_API int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
199 ASSERT_NOT_NULL(rule && rule_id);
201 int err = ctx_sched_add_job(SCHED, rule->job, rule_id);
209 EXPORT_API int context_trigger_remove_rule(int rule_id)
213 return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
215 int err = ctx_sched_remove_job(SCHED, rule_id);
217 if (err == E_RULE_ON)
218 return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
219 else if (err == E_PARAM)
220 return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
225 EXPORT_API int context_trigger_enable_rule(int rule_id)
229 return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
231 int err = ctx_sched_start_job(SCHED, rule_id);
234 return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
239 EXPORT_API int context_trigger_disable_rule(int rule_id)
243 return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
245 int err = ctx_sched_stop_job(SCHED, rule_id);
248 return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
253 static bool __foreach_job_cb(ctx_sched_h scheduler, ctx_sched_job_h job, void *user_data)
255 auto jobs = static_cast<std::vector<ctx_sched_job_h>*>(user_data);
256 jobs->push_back(job);
260 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)
263 ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
265 std::vector<ctx_sched_job_h> jobs;
267 int err = ctx_sched_foreach_job(SCHED, __foreach_job_cb, &jobs);
269 if (err == E_NO_DATA) {
270 *enabled_rule_ids = NULL;
271 *enabled_rule_count = 0;
272 *disabled_rule_ids = NULL;
273 *disabled_rule_count = 0;
277 IF_FAIL_RETURN(IS_SUCCESS(err), err);
279 std::vector<int> startedJobIds;
280 std::vector<int> stoppedJobIds;
282 for (auto& job : jobs) {
283 bool started = false;
286 ctx_sched_job_is_started(job, &started);
287 ctx_sched_job_get_id(job, &jobId);
288 ctx_sched_job_destroy(job);
291 startedJobIds.push_back(jobId);
293 stoppedJobIds.push_back(jobId);
296 *enabled_rule_count = startedJobIds.size();
298 if (*enabled_rule_count > 0)
299 *enabled_rule_ids = static_cast<int*>(g_memdup(startedJobIds.data(), startedJobIds.size() * sizeof(int)));
301 *enabled_rule_ids = NULL;
303 *disabled_rule_count = stoppedJobIds.size();
305 if (*disabled_rule_count > 0)
306 *disabled_rule_ids = static_cast<int*>(g_memdup(stoppedJobIds.data(), stoppedJobIds.size() * sizeof(int)));
308 *disabled_rule_ids = NULL;
313 EXPORT_API int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
316 ASSERT_NOT_NULL(rule);
318 return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
320 ctx_sched_job_h job = NULL;
322 int err = ctx_sched_get_job(SCHED, rule_id, &job);
325 return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
326 else if (err != E_NONE)
329 *rule = new(std::nothrow) _context_trigger_rule_h(job);
332 ctx_sched_job_destroy(job);
339 EXPORT_API int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
341 ASSERT_NOT_NULL(rule);
342 IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
344 *rule = new(std::nothrow) _context_trigger_rule_h();
346 if ((*rule)->job == NULL) {
352 ctx_sched_job_set_disjunction((*rule)->job, logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION);
357 EXPORT_API int context_trigger_rule_destroy(context_trigger_rule_h rule)
360 ASSERT_NOT_NULL(rule);
367 static int __set_event(context_trigger_rule_h rule, context_trigger_rule_entry_h event)
369 IF_FAIL_RETURN(event->jobContext, E_PARAM);
370 IF_FAIL_RETURN_TAG(!rule->hasEvent, E_INV_RULE, _E, "The rule already has the event");
372 EventItem contextItem(event->type);
373 IF_FAIL_RETURN_TAG(contextItem.isValid(event->jobContext), E_INV_RULE, _E, "Incomplete event");
375 ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(event->jobContext);
378 int err = ctx_sched_job_add_trigger(rule->job, dup);
379 if (IS_FAILED(err)) {
380 ctx_sched_job_context_destroy(dup);
384 rule->hasEvent = true;
389 static int __add_condition(context_trigger_rule_h rule, context_trigger_rule_entry_h condition)
391 IF_FAIL_RETURN(condition->jobContext, E_PARAM);
393 bool exist = (rule->conditions.find(condition->uri) != rule->conditions.end());
394 IF_FAIL_RETURN_TAG(!exist, E_INV_RULE, _E, "The same condition exists");
396 ConditionItem contextItem(condition->type);
397 IF_FAIL_RETURN_TAG(contextItem.isValid(condition->jobContext), E_INV_RULE, _E, "Incomplete condition");
399 ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(condition->jobContext);
402 int err = ctx_sched_job_add_requirement(rule->job, dup);
403 if (IS_FAILED(err)) {
404 ctx_sched_job_context_destroy(dup);
411 EXPORT_API int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
413 ASSERT_NOT_NULL(rule && entry);
414 IF_FAIL_RETURN_TAG(!rule->readOnly, E_PARAM,
415 _E, "A rule acquired by context_trigger_get_rule_by_id() is not allowed to be modified.");
417 if (entry->category == CATEGORY_EVENT)
418 return __set_event(rule, entry);
420 return __add_condition(rule, entry);
423 static bool __is_call_operation(app_control_h ctrl)
426 int err = app_control_get_operation(ctrl, &op);
427 IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _E, "Getting operation of app control failed");
429 bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
435 static bool __is_ui_app(app_control_h ctrl)
438 int err = app_control_get_app_id(ctrl, &appId);
440 IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
442 pkgmgrinfo_appinfo_h appInfo;
443 err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
446 IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
448 char *appType = NULL;
449 pkgmgrinfo_appinfo_get_component_type(appInfo, &appType);
451 bool ret = STR_EQ(appType, "uiapp");
453 pkgmgrinfo_appinfo_destroy_appinfo(appInfo);
458 EXPORT_API int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
461 ASSERT_NOT_NULL(rule && app_control);
463 if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/appmanager.launch")) {
464 _E("Privilege denied");
468 if (__is_call_operation(app_control) &&
469 !PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/call")) {
470 _E("Privilege denied");
474 IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
475 IF_FAIL_RETURN_TAG(__is_ui_app(app_control), E_INV_RULE, _E, "Invalid app-control");
478 app_control_export_as_bundle(app_control, &bn);
479 IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting failed");
481 int ret = ctx_sched_job_set_app_control(rule->job, bn);
484 rule->hasAction = true;
489 static bool __is_valid_app_control(app_control_h ctrl)
491 if (!ctrl) return true;
494 int err = app_control_get_app_id(ctrl, &appId);
495 IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
497 pkgmgrinfo_appinfo_h appInfo;
498 err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
500 IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
502 pkgmgrinfo_appinfo_destroy_appinfo(appInfo);
507 EXPORT_API int context_trigger_rule_set_action_notification(context_trigger_rule_h rule,
508 const char* title, const char* content, const char* icon_path, app_control_h app_control)
511 ASSERT_NOT_NULL(rule && title && content);
513 if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/notification")) {
514 _E("Privilege denied");
518 IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
519 IF_FAIL_RETURN_TAG(__is_valid_app_control(app_control), E_INV_RULE, _E, "Invalid app-control");
523 app_control_export_as_bundle(app_control, &bn);
524 IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting failed");
527 int ret = ctx_sched_job_set_notification(rule->job, title, content, icon_path, bn);
530 rule->hasAction = true;
536 EXPORT_API int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h rule,
537 const char *bus_name, const char *object_path, const char *interface_name, const char *method_name, GVariant *param)
539 ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
540 IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
542 int ret = ctx_sched_job_set_dbus(rule->job, bus_name, object_path, interface_name, method_name, param);
545 rule->hasAction = true;
551 EXPORT_API int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
553 ASSERT_NOT_NULL(rule && description);
554 IF_FAIL_RETURN(strlen(description) > 0, E_PARAM);
556 return ctx_sched_job_set_user_data(rule->job, description, strlen(description) + 1);
559 EXPORT_API int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
561 ASSERT_NOT_NULL(rule && description);
565 int err = ctx_sched_job_get_user_data(rule->job, &val, &len);
566 IF_FAIL_RETURN(IS_SUCCESS(err), err);
567 IF_FAIL_RETURN(val, E_NONE);
574 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)
577 ASSERT_NOT_NULL(entry);
578 IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
580 EventItem contextItem(event_item);
581 IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
583 if (contextItem.deprecated())
584 _DEPRECATED_EVENT(event_item);
586 IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
588 bool supported = false;
589 ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), &supported);
590 IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Event-%d is not supported", event_item);
592 *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, event_item, contextItem.getUri());
593 ASSERT_ALLOC(*entry);
595 ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
600 static bool __is_valid_pkg_id(const char* pkgId)
602 IF_FAIL_RETURN(pkgId, false);
604 pkgmgrinfo_pkginfo_h pkgInfo;
605 int err = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, getuid(), &pkgInfo);
606 pkgmgrinfo_pkginfo_destroy_pkginfo(pkgInfo);
608 return (PMINFO_R_OK == err);
611 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)
614 ASSERT_NOT_NULL(event_item && provider && entry);
615 IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
617 std::string uri = __get_custom_uri(event_item, provider);
619 bool registered = false;
620 ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, ®istered);
621 IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", event_item);
623 *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, 0, uri.c_str());
624 ASSERT_ALLOC(*entry);
629 EXPORT_API int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
632 ASSERT_NOT_NULL(supported);
634 EventItem contextItem(event_item);
635 IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
637 return ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), supported);
640 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)
643 ASSERT_NOT_NULL(entry);
644 IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
646 ConditionItem contextItem(condition_item);
647 IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
649 if (contextItem.deprecated())
650 _DEPRECATED_COND(condition_item);
652 IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
654 bool supported = false;
655 ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), &supported);
656 IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Condition-%d is not supported", condition_item);
658 *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, condition_item, contextItem.getUri());
659 ASSERT_ALLOC(*entry);
661 ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
666 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)
669 ASSERT_NOT_NULL(condition_item && provider && entry);
670 IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
671 IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
673 std::string uri = __get_custom_uri(condition_item, provider);
675 bool registered = false;
676 ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, ®istered);
677 IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", condition_item);
679 *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, 0, uri.c_str());
680 ASSERT_ALLOC(*entry);
685 EXPORT_API int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
688 ASSERT_NOT_NULL(supported);
690 ConditionItem contextItem(condition_item);
691 IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
693 return ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), supported);
696 EXPORT_API int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
699 ASSERT_NOT_NULL(entry);
706 EXPORT_API int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
708 ASSERT_NOT_NULL(entry && option_key);
710 ContextItem* contextItem = __get_context_item(entry);
711 IF_FAIL_RETURN(contextItem, E_FAILED);
713 bool valid = contextItem->isValid(option_key, value);
715 IF_FAIL_RETURN(valid, E_INV_RULE);
717 ctx_sched_job_context_prepare_attribute_int(entry->jobContext, option_key);
718 return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, option_key, value);
721 EXPORT_API int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
724 ASSERT_NOT_NULL(entry && option_key && value);
726 ContextItem* contextItem = __get_context_item(entry);
727 IF_FAIL_RETURN(contextItem, E_FAILED);
729 bool valid = contextItem->isValid(option_key, value);
731 IF_FAIL_RETURN(valid, E_INV_RULE);
733 ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
734 return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, value);
737 EXPORT_API int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
740 ASSERT_NOT_NULL(entry && option_key && event_data_key);
741 IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
743 ConditionItem contextItem(entry->type);
744 IF_FAIL_RETURN(contextItem.isValid(option_key), E_INV_RULE);
746 ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
747 return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, event_data_key);
750 static bool __is_member_key(context_trigger_rule_entry_h entry, const char* key)
752 if (entry->conjunctionKeys.find(key) != entry->conjunctionKeys.end() ||
753 entry->disjunctionKeys.find(key) != entry->disjunctionKeys.end()) {
754 _D("'%s' found", key);
758 _D("'%s' not found", key);
762 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)
764 ASSERT_NOT_NULL(entry && key);
765 IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
767 ContextItem* contextItem = __get_context_item(entry);
768 IF_FAIL_RETURN(contextItem, E_FAILED);
770 bool valid = contextItem->isValid(key);
772 IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
773 IF_FAIL_RETURN(!__is_member_key(entry, key), E_INV_RULE);
775 if (logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION)
776 entry->conjunctionKeys.insert(key);
778 entry->disjunctionKeys.insert(key);
783 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)
786 ASSERT_NOT_NULL(entry && key && op && event_data_key);
787 IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
789 ConditionItem contextItem(entry->type);
790 IF_FAIL_RETURN(contextItem.isValid(key), E_INV_RULE);
791 IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
793 ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
795 if (__getOpType(op) == OpType::EQ)
796 return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, event_data_key);
798 if (__getOpType(op) == OpType::NE)
799 return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, event_data_key);
801 _E("Invalid operator");
805 EXPORT_API int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
807 ASSERT_NOT_NULL(entry && key && op);
809 ContextItem* contextItem = __get_context_item(entry);
810 IF_FAIL_RETURN(contextItem, E_FAILED);
812 bool valid = contextItem->isValid(key, value);
814 IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
815 IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
817 ctx_sched_job_context_prepare_attribute_int(entry->jobContext, key);
819 if (__getOpType(op) == OpType::EQ)
820 return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, key, value);
822 if (__getOpType(op) == OpType::NE)
823 return ctx_sched_job_context_attribute_add_ne_int(entry->jobContext, key, value);
825 //TODO: Consider logical disjunction
826 if (__getOpType(op) == OpType::GT)
827 return ctx_sched_job_context_attribute_set_gt_int(entry->jobContext, key, value);
829 if (__getOpType(op) == OpType::GE)
830 return ctx_sched_job_context_attribute_set_ge_int(entry->jobContext, key, value);
832 if (__getOpType(op) == OpType::LT)
833 return ctx_sched_job_context_attribute_set_lt_int(entry->jobContext, key, value);
835 if (__getOpType(op) == OpType::LE)
836 return ctx_sched_job_context_attribute_set_le_int(entry->jobContext, key, value);
838 _E("Invalid operator");
842 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)
844 ASSERT_NOT_NULL(entry && key && op && value);
846 ContextItem* contextItem = __get_context_item(entry);
847 IF_FAIL_RETURN(contextItem, E_FAILED);
849 bool valid = contextItem->isValid(key, value);
851 IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
852 IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
854 ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
856 if (__getOpType(op) == OpType::EQ)
857 return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, value);
859 if (__getOpType(op) == OpType::NE)
860 return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, value);
862 _E("Invalid operator");
866 EXPORT_API int context_trigger_custom_register(const char* name, const char* attr_template)
869 ASSERT_NOT_NULL(name && attr_template);
871 //TODO: Is it allowed to overwrite a template?
872 CustomTemplate::remove(name);
874 bool success = CustomTemplate::add(name, attr_template);
875 IF_FAIL_RETURN_TAG(success, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
877 const char* pkgId = __get_pkg_id();
878 IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
880 std::string uri = __get_custom_uri(name, pkgId);
882 int err = ctx_sched_custom_register(SCHED, uri.c_str());
883 IF_FAIL_RETURN(err == E_NONE, E_FAILED);
888 EXPORT_API int context_trigger_custom_unregister(const char* name)
891 ASSERT_NOT_NULL(name);
893 CustomTemplate::remove(name);
895 const char* pkgId = __get_pkg_id();
896 IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
898 std::string uri = __get_custom_uri(name, pkgId);
900 ctx_sched_custom_unregister(SCHED, uri.c_str());
905 EXPORT_API int context_trigger_custom_publish(const char* name, const char* fact)
908 ASSERT_NOT_NULL(name && fact);
910 CustomTemplate* customTemplate = CustomTemplate::get(name);
911 IF_FAIL_RETURN_TAG(customTemplate, E_PARAM, _E, "Unknown custom name");
912 IF_FAIL_RETURN(customTemplate->match(fact), CONTEXT_TRIGGER_ERROR_INVALID_DATA);
914 const char* pkgId = __get_pkg_id();
915 IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
917 std::string uri = __get_custom_uri(name, pkgId);
919 return ctx_sched_publish_context_json(SCHED, uri.c_str(), fact);