-Mu-Woong Lee <muwoong.lee@samsung.com>
Somin Kim <somin926.kim@samsung.com>
+Mu-Woong Lee <muwoong.lee@samsung.com>
# Targets
SET(target ${PROJECT_NAME})
+# Dependencies
+SET(DEPS "gio-2.0 jsoncpp bundle pkgmgr-info capi-base-common capi-appfw-app-control")
+SET(DEPS "${DEPS} context-app-history-client context-job-scheduler-client")
+SET(DEPS "${DEPS} context-common-legacy")
+
# Source Lists
FILE(GLOB_RECURSE SRCS src/*.cpp)
MESSAGE("Sources: ${SRCS}")
-# Dependencies
-SET(DEPS "gio-2.0 jsoncpp context-common-legacy aul bundle capi-appfw-app-control pkgmgr-info context-app-history-client")
-
# Common Options
INCLUDE(FindPkgConfig)
INCLUDE_DIRECTORIES(
# Installing
INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
INSTALL(
- DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/context-service
- FILES_MATCHING
- PATTERN "*.h"
+ DIRECTORY ${CMAKE_SOURCE_DIR}/include/
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/context-service
+ FILES_MATCHING PATTERN "*.h"
)
SET(VERSION ${FULLVER})
Name: capi-context
Summary: Tizen Context Framework Native API
-Version: 1.0.2
+Version: 1.0.3
Release: 1
-Group: Service/Context
+Group: Service Framework/Context
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
BuildRequires: cmake
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(jsoncpp)
-BuildRequires: pkgconfig(aul)
+#BuildRequires: pkgconfig(aul)
BuildRequires: pkgconfig(bundle)
-BuildRequires: pkgconfig(capi-appfw-app-control)
BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(capi-appfw-app-control)
BuildRequires: pkgconfig(context-app-history-client)
+BuildRequires: pkgconfig(context-job-scheduler-client)
+
+# Legacy support
BuildRequires: pkgconfig(context-common-legacy)
Requires: context-agent
%build
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
-export CXXFLAGS+=" -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter"
-export CXXFLAGS+=" -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls"
+export CXXFLAGS+=" -Wall -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter"
+export CXXFLAGS+=" -Wformat=2 -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls"
export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
export CXXFLAGS+=" -Wnon-virtual-dtor -std=c++0x"
%package test
Summary: Tizen Context Framework Testsuite
-Group: Service/Context
+Group: Service Framework/Context
%description test
Tizen Context Framework Testsuite
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "ComparisonConverter.h"
-
-using namespace ctx;
-
-ComparisonConverter::ComparisonConverter(const char* type, CtxJson1& info) :
- __completed(false),
- __size(0),
- __logicalOp(TRIG_RULE_LOGICAL_DISJUNCTION),
- __type(type),
- __info(info.str()),
- __result(EMPTY_JSON_OBJECT)
-{
- __info.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &__key);
- __info.get(NULL, OLD_TRIG_RULE_KEY_OPERATOR, &__logicalOp);
- __size = __info.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
-}
-
-int ComparisonConverter::getResult(CtxJson1* result)
-{
- if (__result == EMPTY_JSON_OBJECT)
- return ERR_INVALID_RULE;
-
- *result = __result.str();
-
- return ERR_NONE;
-}
-
-void ComparisonConverter::__convertComparison()
-{
- IF_FAIL_VOID(!__convertEmptyComparison());
- IF_FAIL_VOID(!__convertSingleComparison());
- IF_FAIL_VOID(!__convertMultipleComparison());
-
- _E("Failed to convert comparison as new format");
-}
-
-bool ComparisonConverter::__convertEmptyComparison()
-{
- IF_FAIL_RETURN(__size == 0, false);
-
- CtxJson1 temp = EMPTY_JSON_OBJECT;
- __result.set(NULL, __key.c_str(), temp);
-
- return true;
-}
-
-bool ComparisonConverter::__convertSingleComparison()
-{
- IF_FAIL_RETURN(__size == 1, false);
-
- std::string op;
- __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, 0, &op);
-
- __setConvertedOperator(op);
- __setComparisonValue();
-
- return true;
-}
-
-bool ComparisonConverter::__convertMultipleComparison()
-{
- IF_FAIL_RETURN(__size > 1, false);
-
- if (__checkOneOf()) {
- return true;
- } else if (__checkNoneOf()) {
- return true;
- } else if (__checkEtc()) {
- return true;
- }
-
- return false;
-}
-
-bool ComparisonConverter::__checkOneOf()
-{
- // Or of {==, ...}
- IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
- IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_EQUAL_TO), false);
-
- __setConvertedOperator(TRIG_RULE_OP_ONE_OF);
- __setComparisonValueArray();
-
- return true;
-}
-
-bool ComparisonConverter::__checkNoneOf()
-{
- // And of {!=, ...}
- IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
- IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_NOT_EQUAL_TO), false);
-
- __setConvertedOperator(TRIG_RULE_OP_NONE_OF);
- __setComparisonValueArray();
-
- return true;
-}
-
-bool ComparisonConverter::__checkEtc()
-{
- return false;
-}
-
-void ComparisonConverter::__setConvertedOperator(std::string op)
-{
- __result.set(__key.c_str(), TRIG_RULE_KEY_OPERATOR, op);
-}
-
-void ComparisonConverter::__setComparisonValue()
-{
- std::string valStr;
- int val;
-
- if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &valStr)) {
- __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
- } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &val)) {
- __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
- }
-}
-
-void ComparisonConverter::__setComparisonValueArray()
-{
- std::string valStr;
- int val;
- // TODO sort
- for (int i = 0; i < __size; i++) {
- if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &valStr)) {
- __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
- } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val)) {
- __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
- }
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_COMPARISON_CONVERTER_H_
-#define _CONTEXT_COMPARISON_CONVERTER_H_
-
-#include <CtxJson1.h>
-#include "TriggerOldRuleTypes.h"
-
-namespace ctx {
-
- class ComparisonConverter {
- public:
- virtual ~ComparisonConverter() {};
-
- int getResult(CtxJson1* result);
-
- protected:
- bool __completed;
- int __size;
- std::string __logicalOp;
- std::string __type;
- CtxJson1 __info;
- CtxJson1 __result;
- std::string __key;
-
- ComparisonConverter(const char* type, CtxJson1& info);
- void __convertComparison();
- virtual int __getOperatorCount(std::string op) = 0;
- virtual bool __checkEtc();
- void __setConvertedOperator(std::string op);
-
- private:
- bool __convertEmptyComparison();
- bool __convertSingleComparison();
- bool __convertMultipleComparison();
- bool __checkOneOf();
- bool __checkNoneOf();
- void __setComparisonValue();
- void __setComparisonValueArray();
- };
-
-} /* namespace ctx */
-
-#endif /* _CONTEXT_COMPARISON_CONVERTER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <map>
-#include <list>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "IntComparisonConverter.h"
-
-using namespace ctx;
-
-IntComparisonConverter::IntComparisonConverter(CtxJson1 info) :
- ComparisonConverter(TRIG_TMPL_TYPE_INTEGER, info)
-{
- if (__size >= 2) {
- for (int i = 0; i < __size; i++) {
- int val;
- std::string op;
- __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val);
- __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
-
- __insertComparisonInfo(op, val);
- }
- __sort();
- }
-
- __convertComparison();
-}
-
-void IntComparisonConverter::__insertComparisonInfo(std::string op, int val)
-{
- IntComparisonMap::iterator it = __map.find(op);
- if (it == __map.end()) {
- IntList list;
- list.push_back(val);
- __map[op] = list;
- } else {
- it->second.push_back(val);
- }
-}
-
-void IntComparisonConverter::__sort()
-{
- for (IntComparisonMap::iterator it = __map.begin(); it != __map.end(); it++) {
- it->second.sort();
- }
-}
-
-int IntComparisonConverter::__getOperatorCount(std::string op)
-{
- return __map[op].size();
-}
-
-int IntComparisonConverter::__getMaxValue(std::string op)
-{
- return __map[op].back();
-}
-
-int IntComparisonConverter::__getMinValue(std::string op)
-{
- return __map[op].front();
-}
-
-bool IntComparisonConverter::__checkEtc()
-{
- // Simple version in, notIn
- IF_FAIL_RETURN(!__checkIn(), true);
- IF_FAIL_RETURN(!__checkNotIn(), true);
-
- return false;
-}
-
-
-bool IntComparisonConverter::__checkIn()
-{
- // And of { >= min, <= max }
- IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
- IF_FAIL_RETURN(__size == 2, false);
- IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) == 1
- && __getOperatorCount(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) == 1, false);
-
- int maxOfGE = __getMaxValue(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO);
- int minOfLE = __getMinValue(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO);
- IF_FAIL_RETURN(maxOfGE <= minOfLE, false);
-
- __setConvertedOperator(TRIG_RULE_OP_IN);
- __setComparisonValue(maxOfGE, minOfLE);
-
- return true;
-}
-
-bool IntComparisonConverter::__checkNotIn()
-{
- // Or of { < min, > max }
- IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
- IF_FAIL_RETURN(__size == 2, false);
- IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN) == 1
- && __getOperatorCount(TRIG_RULE_OP_LESS_THAN) == 1, false);
-
- int maxOfL = __getMaxValue(TRIG_RULE_OP_LESS_THAN);
- int minOfG = __getMinValue(TRIG_RULE_OP_GREATER_THAN);
- IF_FAIL_RETURN(maxOfL <= minOfG, false);
-
- __setConvertedOperator(TRIG_RULE_OP_NOT_IN);
- __setComparisonValue(maxOfL, minOfG);
-
- return true;
-}
-
-void IntComparisonConverter::__setComparisonValue(int val1, int val2)
-{
- __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val1);
- __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val2);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_INT_COMPARISON_CONVERTER_H_
-#define _CONTEXT_INT_COMPARISON_CONVERTER_H_
-
-#include <list>
-#include <CtxJson1.h>
-#include "ComparisonConverter.h"
-
-namespace ctx {
-
- class IntComparisonConverter : public ComparisonConverter {
- typedef std::list<int> IntList; // Integer value list
- typedef std::map<std::string, IntList> IntComparisonMap; // { operator, IntList }
-
- public:
- IntComparisonConverter(CtxJson1 info);
- ~IntComparisonConverter() {};
-
- private:
- IntComparisonMap __map;
-
- void __insertComparisonInfo(std::string op, int val);
- void __sort();
- int __getMaxValue(std::string op);
- int __getMinValue(std::string op);
-
- bool __checkIn();
- bool __checkNotIn();
- void __setComparisonValue(int val1, int val2);
- /* From CompariconConverter */
- int __getOperatorCount(std::string op);
- bool __checkEtc();
- };
-
-} /* namespace ctx */
-
-#endif /* _CONTEXT_INT_COMPARISON_CONVERTER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "StringComparisonConverter.h"
-
-using namespace ctx;
-
-StringComparisonConverter::StringComparisonConverter(CtxJson1 info) :
- ComparisonConverter(TRIG_TMPL_TYPE_STRING, info)
-{
- if (__size >= 2) {
- for (int i = 0; i < __size; i++) {
- std::string op;
- __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
-
- __map[op]++;
- }
- }
-
- __convertComparison();
-}
-
-
-int StringComparisonConverter::__getOperatorCount(std::string op)
-{
- return __map[op];
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_STRING_COMPARISON_CONVERTER_H_
-#define _CONTEXT_STRING_COMPARISON_CONVERTER_H_
-
-#include <map>
-#include <CtxJson1.h>
-#include "ComparisonConverter.h"
-
-namespace ctx {
-
- class StringComparisonConverter : public ComparisonConverter {
- typedef std::map<std::string, int> StringComparisonMap;
-
- public:
- StringComparisonConverter(CtxJson1 info);
- ~StringComparisonConverter() {};
-
- private:
- StringComparisonMap __map;
-
- /* From CompariconConverter */
- int __getOperatorCount(std::string op);
- };
-
-} /* namespace ctx */
-
-#endif /* _CONTEXT_STRING_COMPARISON_CONVERTER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
-#define _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
-
-/* Old Rule Keys */
-#define OLD_TRIG_RULE_KEY_EVENT "EVENT"
-#define OLD_TRIG_RULE_KEY_EVENT_ITEM "ITEM_NAME"
-#define OLD_TRIG_RULE_KEY_EVENT_OPERATOR "ITEM_OPERATOR"
-#define OLD_TRIG_RULE_KEY_EVENT_OPTION "OPTION"
-#define OLD_TRIG_RULE_KEY_OPERATOR "OPERATOR"
-#define OLD_TRIG_RULE_KEY_CONDITION "CONDITION"
-#define OLD_TRIG_RULE_KEY_CONDITION_ITEM "ITEM_NAME"
-#define OLD_TRIG_RULE_KEY_CONDITION_OPERATOR "ITEM_OPERATOR"
-#define OLD_TRIG_RULE_KEY_CONDITION_OPTION "OPTION"
-#define OLD_TRIG_RULE_KEY_DATA_ARR "DATA_ARR"
-#define OLD_TRIG_RULE_KEY_DATA_KEY "DATA_KEY"
-#define OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR "DATA_KEY_OPERATOR"
-#define OLD_TRIG_RULE_KEY_DATA_VALUE_ARR "DATA_VALUE_ARR"
-#define OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR "DATA_VALUE_OPER_ARR"
-
-#endif /* _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_ */
+++ /dev/null
-/*
- * 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 <map>
-#include <json/json.h>
-#include <ContextTypes.h>
-#include <Tuple.h>
-#include <app_history_internal.h>
-#include <app_history_types_internal.h>
-#include <AppHistoryTypes.h>
-#include <context_history.h>
-
-#define HISTORY_DEPRECATED_DATA "DEPRECATION WARNING: This history data type is deprecated and will be removed from next release"
-#define HISTORY_DEPRECATED_FILTER "DEPRECATION WARNING: This history filter is deprecated and will be removed from next release"
-#define TYPE_NUMERIC 0
-#define TYPE_STRING 1
-#define FILTER_KEY_LIMIT 10
-
-#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, "Memory allocation failed")
-#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
-
-// handles
-typedef struct _context_history_handle_s {
- /* At this point, this handle has no purpose.
- But, it will be used to support other functionalities later,
- e.g., async read or session management. */
- int tmp;
-} _cx_history_handle;
-
-typedef struct _context_history_filter_handle_s {
- Json::Value jfilter;
-} _cx_history_filter_handle;
-
-typedef struct _context_history_list_handle_s {
- ctx_history_cursor_h cursor;
-
- _context_history_list_handle_s() {
- cursor = NULL;
- }
-} _cx_history_list_handle;
-
-typedef struct _context_history_record_handle_s {
- std::vector<std::string> keys;
- std::shared_ptr<ctx::Tuple> tuple;
-} _cx_history_record_handle;
-
-static std::string convert_filter_to_string(context_history_filter_e filter_type);
-static std::string convert_data_to_string(context_history_data_e data_type);
-static bool check_record_key_data_type(int type, std::string key);
-static bool check_filter_data_int(context_history_filter_e filter_type, int val);
-static bool check_filter_data_string(context_history_filter_e filter_type, const char* val);
-static bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter);
-static int __getIndexOf(context_history_record_h record, const std::string& key);
-static bool history_is_deprecated(context_history_data_e data_type);
-static bool history_filter_is_deprecated(context_history_filter_e filter_type);
-
-// life-cycle
-EXPORT_API int context_history_create(context_history_h* handle)
-{
- ASSERT_NOT_NULL(handle);
-
- *handle = new(std::nothrow) _cx_history_handle();
- ASSERT_ALLOC(*handle);
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_destroy(context_history_h handle)
-{
- ASSERT_NOT_NULL(handle);
- delete handle;
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-// Read filter manipulation
-EXPORT_API int context_history_filter_create(context_history_filter_h* filter)
-{
- ASSERT_NOT_NULL(filter);
-
- *filter = new(std::nothrow) _cx_history_filter_handle();
- ASSERT_ALLOC(*filter);
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_destroy(context_history_filter_h filter)
-{
- ASSERT_NOT_NULL(filter);
- delete filter;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_set_int(context_history_filter_h filter, context_history_filter_e filter_type, int val)
-{
- ASSERT_NOT_NULL(filter);
-
- if (history_filter_is_deprecated(filter_type)) {
- _W(HISTORY_DEPRECATED_FILTER);
- }
-
- std::string filter_str = convert_filter_to_string(filter_type);
- if (filter_str.empty()) {
- return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
- }
-
- // Check filter and its data type
- IF_FAIL_RETURN_TAG(check_filter_data_int(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
-
- filter->jfilter[filter_str] = val;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_set_string(context_history_filter_h filter, context_history_filter_e filter_type, const char* val)
-{
- ASSERT_NOT_NULL(filter);
- ASSERT_NOT_NULL(val);
-
- _W("DEPRECATION WARNING: context_history_filter_set_string() is deprecated and will be removed from next release.");
- if (history_filter_is_deprecated(filter_type)) {
- _W(HISTORY_DEPRECATED_FILTER);
- }
-
- std::string filter_str = convert_filter_to_string(filter_type);
- if (filter_str.empty()) {
- return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
- }
-
- // Check filter and its data type
- IF_FAIL_RETURN_TAG(check_filter_data_string(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
-
- filter->jfilter[filter_str] = val;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_is_supported(context_history_data_e data_type, bool* supported)
-{
- ASSERT_NOT_NULL(supported);
-
- if (history_is_deprecated(data_type)) {
- _W(HISTORY_DEPRECATED_DATA);
- }
-
- std::string data_type_str = convert_data_to_string(data_type);
- if (data_type_str.empty()) {
- return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
- }
-
- return ctx_history_is_supported(data_type_str.c_str(), supported);
-}
-
-EXPORT_API int context_history_get_list(context_history_h handle, context_history_data_e data_type, context_history_filter_h filter, context_history_list_h* list)
-{
- ASSERT_NOT_NULL(handle);
- ASSERT_NOT_NULL(list);
- *list = NULL;
-
- if (history_is_deprecated(data_type)) {
- _W(HISTORY_DEPRECATED_DATA);
- }
- /*TODO: Boundary check for filter values has to be done*/
-
- std::string data_type_str = convert_data_to_string(data_type);
- if (data_type_str.empty()) {
- return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
- }
-
- // Check data type & filter
- if (filter)
- IF_FAIL_RETURN_TAG(check_invalid_filter(data_type, filter), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid filter key");
-
- *list = new(std::nothrow) _cx_history_list_handle();
- ASSERT_ALLOC(*list);
-
- std::string filterStr;
- if (filter) {
- Json::FastWriter fw;
- fw.omitEndingLineFeed();
- filterStr = fw.write(filter->jfilter);
- }
-
- int err = _ctx_history_query(data_type_str.c_str(), filterStr.c_str(), &((*list)->cursor));
- IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Query failed");
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-// Data object manipulation
-EXPORT_API int context_history_list_get_count(context_history_list_h list, int* count)
-{
- ASSERT_NOT_NULL(list && count);
-
- unsigned int value;
-
- int err = ctx_history_cursor_get_count(list->cursor, &value);
- IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get count failed");
-
- *count = value;
- return E_NONE;
-}
-
-EXPORT_API int context_history_list_get_current(context_history_list_h list, context_history_record_h* record)
-{
- ASSERT_NOT_NULL(list);
- ASSERT_NOT_NULL(record);
- *record = NULL;
-
- unsigned int position = 0;
- int err = ctx_history_cursor_get_position(list->cursor, &position);
- IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get position failed");
-
- *record = new(std::nothrow) _cx_history_record_handle();
- ASSERT_ALLOC(*record);
-
- (*record)->keys = list->cursor->keys;
- (*record)->tuple = list->cursor->tuples[position];
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_list_move_first(context_history_list_h list)
-{
- ASSERT_NOT_NULL(list);
- return ctx_history_cursor_first(list->cursor);
-}
-
-EXPORT_API int context_history_list_move_next(context_history_list_h list)
-{
- ASSERT_NOT_NULL(list);
- return ctx_history_cursor_next(list->cursor);
-}
-
-EXPORT_API int context_history_list_destroy(context_history_list_h list)
-{
- ASSERT_NOT_NULL(list);
- ctx_history_cursor_destroy(list->cursor);
- delete list;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_int(context_history_record_h record, const char* key, int* val)
-{
- ASSERT_NOT_NULL(record && val && key);
-
- // Check key and data type
- IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
- int index = __getIndexOf(record, key);
- IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
- int64_t value;
- IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &value), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
- *val = value;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_double(context_history_record_h record, const char* key, double* val)
-{
- ASSERT_NOT_NULL(record && val && key);
-
- // Check key and data type
- IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
- int index = __getIndexOf(record, key);
- IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
- IF_FAIL_RETURN_TAG(record->tuple->getAt(index, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_string(context_history_record_h record, const char* key, char** val)
-{
- ASSERT_NOT_NULL(record && val && key);
-
- // Check key and data type
- IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_STRING, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
- int index = __getIndexOf(record, key);
- IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
- std::string str;
- IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &str), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
- *val = g_strdup(str.c_str());
- ASSERT_ALLOC(*val);
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_destroy(context_history_record_h record)
-{
- ASSERT_NOT_NULL(record);
- delete record;
-
- return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-std::string convert_filter_to_string(context_history_filter_e filter_type)
-{
- std::string str;
- switch (filter_type) {
- case CONTEXT_HISTORY_FILTER_TIME_SPAN:
- str = KEY_TIME_SPAN;
- break;
- case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
- str = KEY_RESULT_SIZE;
- break;
- case CONTEXT_HISTORY_FILTER_APP_ID:
- str = KEY_APP_ID;
- break;
- case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
- str = KEY_DAY_OF_WEEK;
- break;
- case CONTEXT_HISTORY_FILTER_START_TIME:
- str = KEY_START_TIME;
- break;
- case CONTEXT_HISTORY_FILTER_END_TIME:
- str = KEY_END_TIME;
- break;
- case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
- str = KEY_BSSID;
- break;
- case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
- str = KEY_AUDIO_JACK;
- break;
- case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
- str = KEY_COMMUNICATION_TYPE;
- break;
- default:
- break;
- }
- return str;
-}
-
-std::string convert_data_to_string(context_history_data_e data_type)
-{
- std::string str;
- switch (data_type) {
- case CONTEXT_HISTORY_RECENTLY_USED_APP:
- str = SUBJ_APP_RECENTLY_USED;
- break;
- case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
- str = SUBJ_APP_FREQUENTLY_USED;
- break;
- case CONTEXT_HISTORY_RARELY_USED_APP:
- str = SUBJ_APP_RARELY_USED;
- break;
- case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
- str = SUBJ_APP_PEAK_TIME;
- break;
- case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
- str = SUBJ_MUSIC_PEAK_TIME;
- break;
- case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
- str = SUBJ_VIDEO_PEAK_TIME;
- break;
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
- str = SUBJ_APP_COMMON_SETTING;
- break;
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
- str = SUBJ_MUSIC_COMMON_SETTING;
- break;
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
- str = SUBJ_VIDEO_COMMON_SETTING;
- break;
- case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
- str = SUBJ_SOCIAL_FREQ_ADDRESS;
- break;
- case CONTEXT_HISTORY_BATTERY_USAGE:
- str = SUBJ_BATTERY_USAGE;
- break;
- case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
- str = SUBJ_BATTERY_RECENT_USAGE;
- break;
- default:
- break;
- }
- return str;
-}
-
-bool check_record_key_data_type(int type, std::string key)
-{
- if ((key.compare(CONTEXT_HISTORY_APP_ID) == 0) ||
- key.compare(CONTEXT_HISTORY_ADDRESS) == 0) {
- return (type == TYPE_STRING);
- }
-
- if ((key.compare(CONTEXT_HISTORY_TOTAL_COUNT) == 0) ||
- key.compare(CONTEXT_HISTORY_TOTAL_AMOUNT) == 0 ||
- key.compare(CONTEXT_HISTORY_TOTAL_DURATION) == 0 ||
- key.compare(CONTEXT_HISTORY_LAST_TIME) == 0 ||
- key.compare(CONTEXT_HISTORY_HOUR_OF_DAY) == 0 ||
- key.compare(CONTEXT_HISTORY_AUDIO_JACK) == 0 ||
- key.compare(CONTEXT_HISTORY_SYSTEM_VOLUME) == 0 ||
- key.compare(CONTEXT_HISTORY_MEDIA_VOLUME) == 0 ||
- key.compare(KEY_USED_TIME) == 0) { // Internal use for RecentBatteryUsage
- return (type == TYPE_NUMERIC);
- }
-
- return false;
-}
-
-bool check_filter_data_int(context_history_filter_e filter_type, int val)
-{
- switch (filter_type) {
- case CONTEXT_HISTORY_FILTER_TIME_SPAN:
- case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
- case CONTEXT_HISTORY_FILTER_START_TIME:
- case CONTEXT_HISTORY_FILTER_END_TIME:
- if (val > 0)
- return true;
- break;
- case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
- if (val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKDAYS ||
- val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKENDS ||
- val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_ALL)
- return true;
- break;
- case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
- if (val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_NOT_CONNECTED ||
- val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_CONNECTED)
- return true;
- break;
- case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
- if (val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_CALL ||
- val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_MESSAGE ||
- val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_ALL)
- return true;
- break;
- default:
- return false;
- }
- return false;
-}
-
-bool check_filter_data_string(context_history_filter_e filter_type, const char* val)
-{
- IF_FAIL_RETURN(val, false);
-
- switch (filter_type) {
- case CONTEXT_HISTORY_FILTER_APP_ID:
- case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
- return (g_strstr_len(val, -1, ";") == NULL);
-
- default:
- return false;
- }
-}
-
-bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter)
-{
- /* This should be aligned with context_history_filter_e */
- static const char *filter_key[FILTER_KEY_LIMIT] = {
- NULL,
- KEY_TIME_SPAN,
- KEY_RESULT_SIZE,
- KEY_APP_ID,
- KEY_DAY_OF_WEEK,
- KEY_START_TIME,
- KEY_END_TIME,
- KEY_BSSID,
- KEY_AUDIO_JACK,
- KEY_COMMUNICATION_TYPE,
- };
-
- bool allowed[FILTER_KEY_LIMIT] = {false};
-
- allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = true;
- allowed[CONTEXT_HISTORY_FILTER_START_TIME] = true;
- allowed[CONTEXT_HISTORY_FILTER_END_TIME] = true;
- allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = true;
-
- switch (data_type) {
- case CONTEXT_HISTORY_RECENTLY_USED_APP:
- case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
- allowed[CONTEXT_HISTORY_FILTER_WIFI_BSSID] = true;
- allowed[CONTEXT_HISTORY_FILTER_AUDIO_JACK] = true;
- break;
-
- case CONTEXT_HISTORY_RARELY_USED_APP:
- break;
-
- case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
- allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
- allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
- break;
-
- case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
- case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
- allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
- break;
-
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
- allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
- allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
- break;
-
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
- allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
- break;
-
- case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
- allowed[CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE] = true;
- break;
-
- case CONTEXT_HISTORY_BATTERY_USAGE:
- break;
-
- case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
- allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = false;
- allowed[CONTEXT_HISTORY_FILTER_START_TIME] = false;
- allowed[CONTEXT_HISTORY_FILTER_END_TIME] = false;
- break;
-
- default:
- return false;
- }
-
- bool found = true;
- std::vector<std::string> keys = filter->jfilter.getMemberNames();
-
- for (auto& key : keys) {
- found = false;
- for (int i = 1; i < FILTER_KEY_LIMIT; ++i) {
- if (allowed[i] && key == filter_key[i]) {
- found = true;
- break;
- }
- }
- if (found == true)
- continue;
-
- return false;
- }
-
- return true;
-}
-
-int __getIndexOf(context_history_record_h record, const std::string& key)
-{
- unsigned int i = 0;
-
- for (i = 0; i < record->keys.size(); ++i) {
- if (record->keys[i] == key) {
- return i;
- }
- }
- return -1;
-}
-
-bool history_is_deprecated(context_history_data_e data_type)
-{
- bool ret = false;
- switch (data_type) {
- case CONTEXT_HISTORY_RARELY_USED_APP:
- case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
- case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
- case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
- case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
- case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
- ret = true;
- break;
- default:
- break;
- }
- return ret;
-}
-
-bool history_filter_is_deprecated(context_history_filter_e filter_type)
-{
- bool ret = false;
- switch (filter_type) {
- case CONTEXT_HISTORY_FILTER_APP_ID:
- case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
- case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
- case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
- ret = true;
- break;
- default:
- break;
- }
- return ret;
-}
+++ /dev/null
-/*
- * 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 <sstream>
-//#include <iomanip>
-#include <app_control_internal.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-#include <context_trigger.h>
-#include <context_trigger_internal.h>
-#include <Types.h>
-#include <DBusTypes.h>
-#include <CtxJson1.h>
-#include <DBusClient.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "TriggerOldRuleTypes.h"
-#include "rule_validator.h"
-#include "rule_util.h"
-
-#define TRIGGER_DEPRECATED_FUNCTION_MSG "DEPRECATION WARNING: %s is deprecated and will be removed from next release."
-#define TRIGGER_DEPRECATED_EVENT_MSG "DEPRECATION WARNING: This event is deprecated and will be removed from next release."
-#define TRIGGER_DEPRECATED_CONDITION_MSG "DEPRECATION WARNING: This condition is deprecated and will be removed from next release."
-
-//#define DOUBLE_PRECISION 2
-#define TYPE_EVENT 1
-#define TYPE_CONDITION 2
-#define TYPE_OPTION TRIG_TMPL_KEY_OPTION
-#define TYPE_ATTRIBUTE TRIG_TMPL_KEY_ATTRIBUTE
-#define OLD_INITIAL_ENTRY "{ \"" OLD_TRIG_RULE_KEY_DATA_ARR "\" : [ ] }"
-#define INITIAL_REF "{ \"" TRIG_TMPL_KEY_OPTION "\" : [ ], \"" TRIG_TMPL_KEY_ATTRIBUTE "\" : [ ] }"
-#define INITIAL_RULE \
-"{ \"" TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" TRIG_RULE_KEY_EVENT "\" : { }, \"" TRIG_RULE_KEY_CONDITION "\" : [ ], \"" \
-TRIG_RULE_KEY_ACTION "\" : { }, \"" _TRIG_RULE_KEY_EXTRA "\": { } }"
-#define INITIAL_ENTRY "{ \"" TRIG_RULE_KEY_OPTION "\": { }, \"" TRIG_RULE_KEY_COMPARISON "\" : { } }"
-
-static ctx::DBusClient __dbusClient;
-
-static int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
-static int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
-static std::string convert_event_to_string(context_trigger_event_e item);
-static std::string convert_condition_to_string(context_trigger_condition_e item);
-static std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type);
-static std::string get_custom_item_subject(const char* provider, const char* item);
-static bool event_is_deprecated(context_trigger_event_e item);
-static bool condition_is_deprecated(context_trigger_condition_e item);
-
-//static std::string int_to_string(int value);
-//static std::string double_to_string(int value);
-
-typedef struct _context_trigger_rule_s {
- ctx::CtxJson1 jold_rule;
- ctx::CtxJson1 jrule; // description, event{}, condition[], action{}, _extra{}
- ctx::CtxJson1 jref;
-
- _context_trigger_rule_s() {
- jold_rule = EMPTY_JSON_OBJECT;
- jrule = INITIAL_RULE;
- jref = INITIAL_REF;
- }
-} _context_trigger_rule_h;
-
-typedef struct _context_trigger_rule_entry_s {
- int type;
- ctx::CtxJson1 jentry;
- ctx::CtxJson1 jref;
-
- _context_trigger_rule_entry_s(int t): type(t) {
- jentry = OLD_INITIAL_ENTRY;
-
- if (t == TYPE_CONDITION) {
- jref = INITIAL_REF;
- }
- }
-} _context_trigger_rule_entry_h;
-
-// Add a rule
-SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule && rule_id);
-
- // Err: No event
- if (!ctx::rule_util::isEventSet(rule->jrule)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // Err: No action
- if (!ctx::rule_util::isActionSet(rule->jrule)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // If condition size isn't greater than 1, update logical operator as default
- if ((rule->jrule).getSize(NULL, TRIG_RULE_KEY_CONDITION) <= 1) {
- (rule->jrule).set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, TRIG_RULE_LOGICAL_CONJUNCTION);
- }
-
- ctx::CtxJson1 jrule_id;
- int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
-
- if (error == ERR_NONE) {
- jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
- }
-
- return error;
-}
-
-// Remove a rule
-SO_EXPORT int context_trigger_remove_rule(int rule_id)
-{
- _D("BEGIN");
- if (rule_id <= 0)
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
- ctx::CtxJson1 jrule_id;
- jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
- int error = __dbusClient.write(SUBJ_TRIGGER_REMOVE, jrule_id, NULL);
-
- if (error == ERR_ALREADY_STARTED) { // Rule is still enabled.
- return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
- } else if (error == ERR_NO_DATA) {
- return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
- }
-
- return error;
-}
-
-// Enable a rule
-SO_EXPORT int context_trigger_enable_rule(int rule_id)
-{
- _D("BEGIN");
- if (rule_id <= 0)
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
- ctx::CtxJson1 jrule_id;
- jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-
- int req_id; // Useless in context_trigger
- int error = __dbusClient.subscribe(SUBJ_TRIGGER_ENABLE, jrule_id, &req_id, NULL);
-
- if (error == ERR_NO_DATA) {
- return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
- }
-
- return error;
-}
-
-// Disable a rule
-SO_EXPORT int context_trigger_disable_rule(int rule_id)
-{
- _D("BEGIN");
- if (rule_id <= 0)
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
- ctx::CtxJson1 jrule_id;
- jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
- int error = __dbusClient.write(SUBJ_TRIGGER_DISABLE, jrule_id, NULL);
-
- if (error == ERR_NO_DATA) {
- return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
- }
-
- return error;
-}
-
-SO_EXPORT int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enabled_rule_count, int** disabled_rule_ids, int* disabled_rule_count)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
-
- int req_id;
- ctx::CtxJson1 data_read;
- int error = __dbusClient.readSync(SUBJ_TRIGGER_GET_RULE_IDS, NULL, &req_id, &data_read);
-
- if (error != ERR_NONE) {
- return error;
- }
-
- // Enabled rules
- int* e_arr = NULL;
- *enabled_rule_count = data_read.getSize(NULL, TRIG_KEY_ENABLED_IDS);
-
- if (*enabled_rule_count > 0) {
- e_arr = static_cast<int*>(g_malloc((*enabled_rule_count) * sizeof(int)));
- IF_FAIL_RETURN_TAG(e_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
- int id;
- for (int i = 0; data_read.getAt(NULL, TRIG_KEY_ENABLED_IDS, i, &id); i++) {
- *(e_arr + i) = id;
- }
- }
- *enabled_rule_ids = e_arr;
-
- // Disabled rules
- int* d_arr = NULL;
- *disabled_rule_count = data_read.getSize(NULL, TRIG_KEY_DISABLED_IDS);
-
- if (*disabled_rule_count > 0) {
- d_arr = static_cast<int*>(g_malloc((*disabled_rule_count) * sizeof(int)));
- IF_FAIL_RETURN_TAG(d_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
- int id;
- for (int i = 0; data_read.getAt(NULL, TRIG_KEY_DISABLED_IDS, i, &id); i++) {
- *(d_arr + i) = id;
- }
- }
- *disabled_rule_ids = d_arr;
-
- return error;
-}
-
-
-SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule);
- if (rule_id <= 0)
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
- ctx::CtxJson1 option;
- option.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-
- int req_id;
- ctx::CtxJson1 data_read;
- int error = __dbusClient.readSync(SUBJ_TRIGGER_GET, option, &req_id, &data_read);
-
- if (error == ERR_NO_DATA) {
- return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
- } else if (error != ERR_NONE) {
- return error;
- }
-
- *rule = new(std::nothrow) _context_trigger_rule_h();
- (*rule)->jrule = data_read;
-
- return ERR_NONE;
-}
-
-// Rule creation
-SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule);
-
- std::string logical_str = convert_logical_type_to_string(logical_type);
- if (logical_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- *rule = new(std::nothrow) _context_trigger_rule_h();
- (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
-
- (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
-
- return ERR_NONE;
-}
-
-// Rule deletion
-SO_EXPORT int context_trigger_rule_destroy(context_trigger_rule_h rule)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule);
- delete rule;
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-
-SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule && entry);
-
- // Check if rule handle is created
- ctx::CtxJson1 extra;
- bool ret = (rule->jrule).get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER);
-
- if (entry->type == TYPE_EVENT) {
- // Err: More than one event
- ctx::CtxJson1 elem;
- if ((rule->jold_rule).get(NULL, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // Err: Check if all the mandatory options are added
- ret = ctx::rule_validator::check_option(entry->jentry);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- // Err: If referential conditions are registered priviously, check them
- std::string ename;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
- ret = ctx::rule_validator::check_referential_data(ename, rule->jref);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- ctx::CtxJson1 temp = (entry->jentry).str();
- ret = (rule->jold_rule).set(NULL, OLD_TRIG_RULE_KEY_EVENT, temp);
-
- int error = ctx::rule_util::setEvent(entry->jentry, &(rule->jrule));
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add event entry");
- } else if (entry->type == TYPE_CONDITION) {
- // Err: Condition without comparison data
- if ((entry->jentry).getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) < 1) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- ctx::CtxJson1 elem;
- for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- int val_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
- int op_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR);
-
- // Err: Condition without comparison data
- if (val_arr_size != op_arr_size || val_arr_size < 1 || op_arr_size < 1) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // Err: Check if all the mandatory options are added
- ret = ctx::rule_validator::check_option(entry->jentry);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- // If event is already added ....
- std::string ename;
- ret = (rule->jold_rule).get(OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
- if (ret) {
- // Err: Check referential information if exists
- ret = ctx::rule_validator::check_referential_data(ename, entry->jref);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
- } else {
- // If not, copy referential information to rule entry
- ctx::CtxJson1 info;
- for (int j = 0; (entry->jref).getAt(NULL, TYPE_OPTION, j, &info); j++) {
- (rule->jref).append(NULL, TYPE_OPTION, info);
- }
-
- for (int j = 0; (entry->jref).getAt(NULL, TYPE_ATTRIBUTE, j, &info); j++) {
- (rule->jref).append(NULL, TYPE_ATTRIBUTE, info);
- }
- }
- }
-
- ctx::CtxJson1 temp = (entry->jentry).str();
- ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
-
- ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
- } else {
- // Entry is not created
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-static bool is_call_operation(app_control_h app_control)
-{
- char *op = NULL;
- int err = app_control_get_operation(app_control, &op);
- IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _W, "Getting operation of app control failed");
-
- bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
- g_free(op);
-
- return ret;
-}
-
-SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule && app_control);
- int error;
-
- // Privilege check
- error = __dbusClient.call(METHOD_CHK_PRIV_APPLAUNCH);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
-
- if (is_call_operation(app_control)) {
- error = __dbusClient.call(METHOD_CHK_PRIV_CALL);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
- }
-
- // Err: if action arleady exists
- if (ctx::rule_util::isActionSet(rule->jrule)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // Err: service app
- char* app_id = NULL;
- error = app_control_get_app_id(app_control, &app_id);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
-
- pkgmgrinfo_appinfo_h app_info;
- error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
- g_free(app_id);
- IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
-
- // Service apps are not allowed to be launched (Mobile & Wearable)
- char *app_type = NULL;
- pkgmgrinfo_appinfo_get_component_type(app_info, &app_type);
- if (!strcmp(app_type, "svcapp")) {
- _E("Service application is restricted");
- pkgmgrinfo_appinfo_destroy_appinfo(app_info);
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
- pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-
- // Set app control
- bundle* appctl_bundle = NULL;
- error = app_control_to_bundle(app_control, &appctl_bundle);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
-
- bundle_raw* appctl_raw;
- int raw_length;
- error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
-
- std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, appctl_str);
- bundle_free_encoded_rawdata(&appctl_raw);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT 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)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule && title && content);
-
- // Privilege check
- int error = __dbusClient.call(METHOD_CHK_PRIV_NOTIFICATION);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
-
- // if action arleady exists
- if (ctx::rule_util::isActionSet(rule->jrule)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- // Err: App control check
- if (app_control) {
- char* app_id = NULL;
- error = app_control_get_app_id(app_control, &app_id);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
-
- pkgmgrinfo_appinfo_h app_info;
- error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
- g_free(app_id);
- IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
-
- pkgmgrinfo_appinfo_destroy_appinfo(app_info);
- }
-
- // Set title, content
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, title);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, content);
-
- // Set icon path
- if (icon_path) {
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, icon_path);
- }
-
- // Set app control
- if (app_control) {
- bundle* appctl_bundle = NULL;
- error = app_control_to_bundle(app_control, &appctl_bundle);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
-
- bundle_raw* appctl_raw;
- int raw_length;
- error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
-
- std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, appctl_str);
-
- bundle_free_encoded_rawdata(&appctl_raw);
- }
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT 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)
-{
- ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
-
- /* if action arleady exists */
- if (ctx::rule_util::isActionSet(rule->jrule)) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- /* Set basic dbus method call info */
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, bus_name);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, object_path);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, interface_name);
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, method_name);
-
- /* Set the parameters */
- if (param)
- (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Set description
-SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule);
-
- (rule->jrule).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Get rule description
-SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(rule && description);
-
- std::string val;
- (rule->jrule).get(NULL, TRIG_RULE_KEY_DESCRIPTION, &val);
-
- *description = strdup(val.c_str());
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Event creation
-SO_EXPORT 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)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry);
-
- if (event_is_deprecated(event_item)) {
- _W(TRIGGER_DEPRECATED_EVENT_MSG);
- }
-
- std::string eitem_str = convert_event_to_string(event_item);
- if (eitem_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = context_trigger_rule_event_create_internal(eitem_str.c_str(), logical_type, entry);
- return error;
-}
-
-SO_EXPORT 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)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(event_item && provider && entry);
-
- // Err: Invalid provider
- pkgmgrinfo_pkginfo_h pkg_info;
- int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
- pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
- IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
-
- std::string subject = get_custom_item_subject(provider, event_item);
- error = context_trigger_rule_event_create_internal(subject.c_str(), logical_type, entry, true);
-
- return error;
-}
-
-int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(event_item);
-
- // Err: Invalid logical operator
- std::string logical_str = convert_logical_type_to_string(logical_type);
- if (logical_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = ctx::rule_validator::request_template(event_item, is_custom);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
-
- *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_EVENT);
- (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, event_item);
- (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, logical_str);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Event availability check
-SO_EXPORT int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(supported);
-
- if (event_is_deprecated(event_item)) {
- _W(TRIGGER_DEPRECATED_EVENT_MSG);
- }
-
- *supported = false;
-
- std::string eitem_str = convert_event_to_string(event_item);
- if (eitem_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = __dbusClient.isSupported(eitem_str);
-
- if (error == ERR_NONE)
- *supported = true;
-
- if (error == ERR_NOT_SUPPORTED)
- return ERR_NONE;
-
- return error;
-}
-
-// Condition creation
-SO_EXPORT 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)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry);
-
- if (condition_is_deprecated(condition_item)) {
- _W(TRIGGER_DEPRECATED_CONDITION_MSG);
- }
-
- std::string citem_str = convert_condition_to_string(condition_item);
- if (citem_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = context_trigger_rule_condition_create_internal(citem_str.c_str(), logical_type, entry);
- return error;
-}
-
-SO_EXPORT 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)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(condition_item && provider && entry);
-
- // Err: Invalid provider
- pkgmgrinfo_pkginfo_h pkg_info;
- int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
- pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
- IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
-
- std::string subject = get_custom_item_subject(provider, condition_item);
- error = context_trigger_rule_condition_create_internal(subject.c_str(), logical_type, entry, true);
- return error;
-}
-
-int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(condition_item);
-
- std::string logical_str = convert_logical_type_to_string(logical_type);
- if (logical_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = ctx::rule_validator::request_template(condition_item, is_custom);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
-
- *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_CONDITION);
- (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, condition_item);
- (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, logical_str);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Condition availability check
-SO_EXPORT int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(supported);
-
- if (condition_is_deprecated(condition_item)) {
- _W(TRIGGER_DEPRECATED_CONDITION_MSG);
- }
-
- *supported = false;
-
- std::string citem_str = convert_condition_to_string(condition_item);
- if (citem_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- int error = __dbusClient.isSupported(citem_str);
-
- if (error == ERR_NONE)
- *supported = true;
-
- if (error == ERR_NOT_SUPPORTED)
- return ERR_NONE;
-
- return error;
-}
-
-// Rule data deletion
-SO_EXPORT int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry);
- delete entry;
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry && option_key);
-
- bool ret = true;
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
- ret = ctx::rule_validator::check_option_int(name, option_key, value);
- if (!ret) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
-{
- _D("BEGIN");
- _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
- ASSERT_NOT_NULL(entry && option_key && value);
-
- bool ret = true;
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
- ret = ctx::rule_validator::check_option_string(name, option_key, value);
- if (!ret) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
-{
- _D("BEGIN");
- _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
- ASSERT_NOT_NULL(entry && option_key && event_data_key);
-
- // Err: Only conditin can reference data from event
- if (entry->type != TYPE_CONDITION) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-
- // Err: Check if key is valid
- bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION, name, option_key);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- // Set reference information
- ret = ctx::rule_validator::set_ref_info(TYPE_OPTION, &(entry->jref), name, option_key, event_data_key);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-
- (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry, context_trigger_logical_type_e logical_type, const char* key)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry && key);
-
- std::string logical_str = convert_logical_type_to_string(logical_type);
- if (logical_str.empty()) {
- return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
- }
-
- // Err: Check if key is valid
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
- bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- // Err: Comparison key is already added
- ctx::CtxJson1 elem;
- for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- std::string elem_item;
- elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
- // Err: Comparison key is already added
- if (elem_item.compare(key) == 0) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
- }
-
- ctx::CtxJson1 data;
- data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, key);
- data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR, logical_str);
- (entry->jentry).append(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, data);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-static int context_trigger_rule_entry_add_comparison_string_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, std::string value)
-{
- ctx::CtxJson1 elem;
- for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- std::string elem_item;
- elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
-
- if (elem_item.compare(key) == 0) {
- std::string elem_val;
- std::string elem_op;
- for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
- elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
-
- // Err: Duplicated <operator, value>
- if (elem_val.compare(value) == 0 && elem_op.compare(op) == 0) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
- }
- elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value.c_str());
- elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
- (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
- }
- }
-
- // Comparison key not exist
- return CONTEXT_TRIGGER_ERROR_NO_DATA;
-}
-
-static int context_trigger_rule_entry_add_comparison_int_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, int value)
-{
- ctx::CtxJson1 elem;
- for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- std::string elem_item;
- elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
-
- if (elem_item.compare(key) == 0) {
- int elem_val;
- std::string elem_op;
- for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
- elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
-
- // Err: Duplicated <operator, value>
- if (elem_val == value && elem_op.compare(op) == 0) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
- }
- elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value);
- elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
- (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
- }
- }
-
- // Comparison key not exist
- return CONTEXT_TRIGGER_ERROR_NO_DATA;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
-{
- _D("BEGIN");
- _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
- ASSERT_NOT_NULL(entry && key && op && event_data_key);
-
- // Err: Only condition can reference data from event
- if (entry->type != TYPE_CONDITION) {
- return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
- }
-
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-
- // Err: Check if key is valid
- bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- // Err: Invalid operator
- std::string type = ctx::rule_validator::get_data_type_from_template(TYPE_ATTRIBUTE, name, key);
- ret = ctx::rule_validator::is_valid_operator(type, op);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
- IF_FAIL_RETURN(error == ERR_NONE, error);
-
- // Set reference information
- ret = ctx::rule_validator::set_ref_info(TYPE_ATTRIBUTE, &(entry->jref), name, key, event_data_key);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-
- return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry && key && op);
-
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
- bool ret = ctx::rule_validator::check_comparison_int(name, key, op, value);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- int error = context_trigger_rule_entry_add_comparison_int_internal(entry, key, op, value);
- return error;
-}
-/*
-SO_EXPORT int context_trigger_rule_entry_add_comparison_double(context_trigger_rule_entry_h entry, const char* key, const char* op, double value)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry && key && op);
-
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
- // TODO: check_comparison_double()
- bool ret = ctx::rule_validator::check_comparison_double(name, key, op, value);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- int error = context_trigger_rule_entry_add_comparison_internal(entry, key, op, double_to_string(value));
- return error;
-}
-*/
-SO_EXPORT int context_trigger_rule_entry_add_comparison_string(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* value)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(entry && key && op && value);
-
- std::string name;
- (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
- bool ret = ctx::rule_validator::check_comparison_string(name, key, op, value);
- IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
- int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, value);
- return error;
-}
-
-SO_EXPORT int context_trigger_custom_register(const char* name, const char* attr_template)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(name && attr_template);
-
- // Err: Invalid CtxJson1
- ctx::CtxJson1 jattr_template = attr_template;
- IF_FAIL_RETURN_TAG(jattr_template.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Failed to parse template");
-
- // Err: Invalid template
- bool ret = ctx::rule_validator::is_valid_template(jattr_template);
- IF_FAIL_RETURN_TAG(ret, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
-
- ctx::CtxJson1 data;
- data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_ADD);
- data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
- data.set(NULL, TRIG_TMPL_KEY_ATTRIBUTE, jattr_template);
-
- int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add custom item: %#x", error);
-
- return error;
-}
-
-SO_EXPORT int context_trigger_custom_unregister(const char* name)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(name);
-
- ctx::CtxJson1 data;
- data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_REMOVE);
- data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
-
- ctx::CtxJson1 subj;
- int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, &subj);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to remove custom item: %#x", error);
-
- std::string subject;
- subj.get(NULL, TRIG_TMPL_KEY_SUBJECT, &subject);
- ctx::rule_validator::remove_template(subject);
-
- return error;
-}
-
-SO_EXPORT int context_trigger_custom_publish(const char* name, const char* fact)
-{
- _D("BEGIN");
- ASSERT_NOT_NULL(name && fact);
-
- // Err: Invalid CtxJson1
- ctx::CtxJson1 jfact = fact;
- IF_FAIL_RETURN_TAG(jfact.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Cannot parse fact CtxJson1");
-
- ctx::CtxJson1 data;
- data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_PUBLISH);
- data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
- data.set(NULL, TRIG_CUSTOM_KEY_FACT, jfact);
-
- int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to publish custom data");
-
- return error;
-}
-
-std::string convert_event_to_string(context_trigger_event_e item)
-{
- std::string str;
- switch (item) {
- case CONTEXT_TRIGGER_EVENT_TIME:
- str = SUBJ_STATE_ALARM;
- break;
- case CONTEXT_TRIGGER_EVENT_BATTERY:
- str = SUBJ_STATE_BATTERY;
- break;
- case CONTEXT_TRIGGER_EVENT_CHARGER:
- str = SUBJ_STATE_CHARGER;
- break;
- case CONTEXT_TRIGGER_EVENT_GPS:
- str = SUBJ_STATE_GPS;
- break;
- case CONTEXT_TRIGGER_EVENT_HEADPHONE:
- str = SUBJ_STATE_HEADPHONE;
- break;
- case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
- str = SUBJ_STATE_PSMODE;
- break;
- case CONTEXT_TRIGGER_EVENT_USB:
- str = SUBJ_STATE_USB;
- break;
- case CONTEXT_TRIGGER_EVENT_WIFI:
- str = SUBJ_STATE_WIFI;
- break;
- case CONTEXT_TRIGGER_EVENT_CALL:
- str = SUBJ_STATE_CALL;
- break;
- case CONTEXT_TRIGGER_EVENT_EMAIL:
- str = SUBJ_STATE_EMAIL;
- break;
- case CONTEXT_TRIGGER_EVENT_MESSAGE:
- str = SUBJ_STATE_MESSAGE;
- break;
- case CONTEXT_TRIGGER_EVENT_CONTACTS:
- str = SUBJ_STATE_CONTACTS;
- break;
- case CONTEXT_TRIGGER_EVENT_ACTIVITY_STATIONARY:
- str = SUBJ_ACTIVITY_STATIONARY;
- break;
- case CONTEXT_TRIGGER_EVENT_ACTIVITY_WALKING:
- str = SUBJ_ACTIVITY_WALKING;
- break;
- case CONTEXT_TRIGGER_EVENT_ACTIVITY_RUNNING:
- str = SUBJ_ACTIVITY_RUNNING;
- break;
- case CONTEXT_TRIGGER_EVENT_ACTIVITY_IN_VEHICLE:
- str = SUBJ_ACTIVITY_IN_VEHICLE;
- break;
- case CONTEXT_TRIGGER_EVENT_PLACE:
- str = SUBJ_PLACE_GEOFENCE;
- break;
- default:
- break;
- }
- return str;
-}
-
-std::string convert_condition_to_string(context_trigger_condition_e item)
-{
- std::string str;
- switch (item) {
- case CONTEXT_TRIGGER_CONDITION_TIME:
- str = SUBJ_STATE_TIME;
- break;
- case CONTEXT_TRIGGER_CONDITION_BATTERY:
- str = SUBJ_STATE_BATTERY;
- break;
- case CONTEXT_TRIGGER_CONDITION_CHARGER:
- str = SUBJ_STATE_CHARGER;
- break;
- case CONTEXT_TRIGGER_CONDITION_GPS:
- str = SUBJ_STATE_GPS;
- break;
- case CONTEXT_TRIGGER_CONDITION_HEADPHONE:
- str = SUBJ_STATE_HEADPHONE;
- break;
- case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
- str = SUBJ_STATE_PSMODE;
- break;
- case CONTEXT_TRIGGER_CONDITION_USB:
- str = SUBJ_STATE_USB;
- break;
- case CONTEXT_TRIGGER_CONDITION_WIFI:
- str = SUBJ_STATE_WIFI;
- break;
- case CONTEXT_TRIGGER_CONDITION_CALL:
- str = SUBJ_STATE_CALL;
- break;
- case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
- str = SUBJ_APP_FREQUENCY;
- break;
- case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
- str = SUBJ_SOCIAL_FREQUENCY;
- break;
- case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
- str = SUBJ_MUSIC_FREQUENCY;
- break;
- case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
- str = SUBJ_VIDEO_FREQUENCY;
- break;
- default:
- break;
- }
- return str;
-}
-
-std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type)
-{
- std::string str;
- switch (logical_type) {
- case CONTEXT_TRIGGER_LOGICAL_CONJUNCTION:
- str = TRIG_RULE_LOGICAL_CONJUNCTION;
- break;
- case CONTEXT_TRIGGER_LOGICAL_DISJUNCTION:
- str = TRIG_RULE_LOGICAL_DISJUNCTION;
- break;
- default:
- break;
- }
- return str;
-}
-
-std::string get_custom_item_subject(const char* provider, const char* item)
-{
- std::string subject_name = std::string(TRIG_CUSTOM_PREFIX TRIG_SUBJECT_SEPERATOR) + provider + std::string(TRIG_SUBJECT_SEPERATOR) + item;
- return subject_name;
-}
-
-bool event_is_deprecated(context_trigger_event_e item)
-{
- bool ret = false;
- switch (item) {
- case CONTEXT_TRIGGER_EVENT_TIME:
- case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
- case CONTEXT_TRIGGER_EVENT_CALL:
- case CONTEXT_TRIGGER_EVENT_EMAIL:
- case CONTEXT_TRIGGER_EVENT_MESSAGE:
- ret = true;
- break;
- default:
- break;
- }
- return ret;
-}
-
-bool condition_is_deprecated(context_trigger_condition_e item)
-{
- bool ret = false;
- switch (item) {
- case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
- case CONTEXT_TRIGGER_CONDITION_CALL:
- case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
- case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
- case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
- case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
- ret = true;
- break;
- default:
- break;
- }
- return ret;
-}
-
-/*
-std::string int_to_string(int value)
-{
- std::ostringstream ostr;
- ostr << value;
- return ostr.str();
-}
-
-std::string double_to_string(int value)
-{
- std::ostringstream ostr;
- ostr.imbue(std::locale("C"));
- ostr << std::setprecision(DOUBLE_PRECISION) << std::fixed << value;
- return ostr.str();
-}*/
--- /dev/null
+/*
+ * 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 <map>
+#include <json/json.h>
+#include <ContextTypes.h>
+#include <Tuple.h>
+#include <app_history_internal.h>
+#include <app_history_types_internal.h>
+#include <AppHistoryTypes.h>
+#include <context_history.h>
+
+#define HISTORY_DEPRECATED_DATA "DEPRECATION WARNING: This history data type is deprecated and will be removed from next release"
+#define HISTORY_DEPRECATED_FILTER "DEPRECATION WARNING: This history filter is deprecated and will be removed from next release"
+#define TYPE_NUMERIC 0
+#define TYPE_STRING 1
+#define FILTER_KEY_LIMIT 10
+
+#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
+
+// handles
+typedef struct _context_history_handle_s {
+ /* At this point, this handle has no purpose.
+ But, it will be used to support other functionalities later,
+ e.g., async read or session management. */
+ int tmp;
+} _cx_history_handle;
+
+typedef struct _context_history_filter_handle_s {
+ Json::Value jfilter;
+} _cx_history_filter_handle;
+
+typedef struct _context_history_list_handle_s {
+ ctx_history_cursor_h cursor;
+
+ _context_history_list_handle_s() {
+ cursor = NULL;
+ }
+} _cx_history_list_handle;
+
+typedef struct _context_history_record_handle_s {
+ std::vector<std::string> keys;
+ std::shared_ptr<ctx::Tuple> tuple;
+} _cx_history_record_handle;
+
+static std::string convert_filter_to_string(context_history_filter_e filter_type);
+static std::string convert_data_to_string(context_history_data_e data_type);
+static bool check_record_key_data_type(int type, std::string key);
+static bool check_filter_data_int(context_history_filter_e filter_type, int val);
+static bool check_filter_data_string(context_history_filter_e filter_type, const char* val);
+static bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter);
+static int __getIndexOf(context_history_record_h record, const std::string& key);
+static bool history_is_deprecated(context_history_data_e data_type);
+static bool history_filter_is_deprecated(context_history_filter_e filter_type);
+
+// life-cycle
+EXPORT_API int context_history_create(context_history_h* handle)
+{
+ ASSERT_NOT_NULL(handle);
+
+ *handle = new(std::nothrow) _cx_history_handle();
+ ASSERT_ALLOC(*handle);
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_destroy(context_history_h handle)
+{
+ ASSERT_NOT_NULL(handle);
+ delete handle;
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+// Read filter manipulation
+EXPORT_API int context_history_filter_create(context_history_filter_h* filter)
+{
+ ASSERT_NOT_NULL(filter);
+
+ *filter = new(std::nothrow) _cx_history_filter_handle();
+ ASSERT_ALLOC(*filter);
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_destroy(context_history_filter_h filter)
+{
+ ASSERT_NOT_NULL(filter);
+ delete filter;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_set_int(context_history_filter_h filter, context_history_filter_e filter_type, int val)
+{
+ ASSERT_NOT_NULL(filter);
+
+ if (history_filter_is_deprecated(filter_type)) {
+ _W(HISTORY_DEPRECATED_FILTER);
+ }
+
+ std::string filter_str = convert_filter_to_string(filter_type);
+ if (filter_str.empty()) {
+ return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+ }
+
+ // Check filter and its data type
+ IF_FAIL_RETURN_TAG(check_filter_data_int(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
+
+ filter->jfilter[filter_str] = val;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_set_string(context_history_filter_h filter, context_history_filter_e filter_type, const char* val)
+{
+ ASSERT_NOT_NULL(filter);
+ ASSERT_NOT_NULL(val);
+
+ _W("DEPRECATION WARNING: context_history_filter_set_string() is deprecated and will be removed from next release.");
+ if (history_filter_is_deprecated(filter_type)) {
+ _W(HISTORY_DEPRECATED_FILTER);
+ }
+
+ std::string filter_str = convert_filter_to_string(filter_type);
+ if (filter_str.empty()) {
+ return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+ }
+
+ // Check filter and its data type
+ IF_FAIL_RETURN_TAG(check_filter_data_string(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
+
+ filter->jfilter[filter_str] = val;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_is_supported(context_history_data_e data_type, bool* supported)
+{
+ ASSERT_NOT_NULL(supported);
+
+ if (history_is_deprecated(data_type)) {
+ _W(HISTORY_DEPRECATED_DATA);
+ }
+
+ std::string data_type_str = convert_data_to_string(data_type);
+ if (data_type_str.empty()) {
+ return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+ }
+
+ return ctx_history_is_supported(data_type_str.c_str(), supported);
+}
+
+EXPORT_API int context_history_get_list(context_history_h handle, context_history_data_e data_type, context_history_filter_h filter, context_history_list_h* list)
+{
+ ASSERT_NOT_NULL(handle);
+ ASSERT_NOT_NULL(list);
+ *list = NULL;
+
+ if (history_is_deprecated(data_type)) {
+ _W(HISTORY_DEPRECATED_DATA);
+ }
+ /*TODO: Boundary check for filter values has to be done*/
+
+ std::string data_type_str = convert_data_to_string(data_type);
+ if (data_type_str.empty()) {
+ return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+ }
+
+ // Check data type & filter
+ if (filter)
+ IF_FAIL_RETURN_TAG(check_invalid_filter(data_type, filter), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid filter key");
+
+ *list = new(std::nothrow) _cx_history_list_handle();
+ ASSERT_ALLOC(*list);
+
+ std::string filterStr;
+ if (filter) {
+ Json::FastWriter fw;
+ fw.omitEndingLineFeed();
+ filterStr = fw.write(filter->jfilter);
+ }
+
+ int err = _ctx_history_query(data_type_str.c_str(), filterStr.c_str(), &((*list)->cursor));
+ IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Query failed");
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+// Data object manipulation
+EXPORT_API int context_history_list_get_count(context_history_list_h list, int* count)
+{
+ ASSERT_NOT_NULL(list && count);
+
+ unsigned int value;
+
+ int err = ctx_history_cursor_get_count(list->cursor, &value);
+ IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get count failed");
+
+ *count = value;
+ return E_NONE;
+}
+
+EXPORT_API int context_history_list_get_current(context_history_list_h list, context_history_record_h* record)
+{
+ ASSERT_NOT_NULL(list);
+ ASSERT_NOT_NULL(record);
+ *record = NULL;
+
+ unsigned int position = 0;
+ int err = ctx_history_cursor_get_position(list->cursor, &position);
+ IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get position failed");
+
+ *record = new(std::nothrow) _cx_history_record_handle();
+ ASSERT_ALLOC(*record);
+
+ (*record)->keys = list->cursor->keys;
+ (*record)->tuple = list->cursor->tuples[position];
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_list_move_first(context_history_list_h list)
+{
+ ASSERT_NOT_NULL(list);
+ return ctx_history_cursor_first(list->cursor);
+}
+
+EXPORT_API int context_history_list_move_next(context_history_list_h list)
+{
+ ASSERT_NOT_NULL(list);
+ return ctx_history_cursor_next(list->cursor);
+}
+
+EXPORT_API int context_history_list_destroy(context_history_list_h list)
+{
+ ASSERT_NOT_NULL(list);
+ ctx_history_cursor_destroy(list->cursor);
+ delete list;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_int(context_history_record_h record, const char* key, int* val)
+{
+ ASSERT_NOT_NULL(record && val && key);
+
+ // Check key and data type
+ IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+ int index = __getIndexOf(record, key);
+ IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+ int64_t value;
+ IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &value), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+ *val = value;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_double(context_history_record_h record, const char* key, double* val)
+{
+ ASSERT_NOT_NULL(record && val && key);
+
+ // Check key and data type
+ IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+ int index = __getIndexOf(record, key);
+ IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+ IF_FAIL_RETURN_TAG(record->tuple->getAt(index, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_string(context_history_record_h record, const char* key, char** val)
+{
+ ASSERT_NOT_NULL(record && val && key);
+
+ // Check key and data type
+ IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_STRING, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+ int index = __getIndexOf(record, key);
+ IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+ std::string str;
+ IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &str), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+ *val = g_strdup(str.c_str());
+ ASSERT_ALLOC(*val);
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_destroy(context_history_record_h record)
+{
+ ASSERT_NOT_NULL(record);
+ delete record;
+
+ return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+std::string convert_filter_to_string(context_history_filter_e filter_type)
+{
+ std::string str;
+ switch (filter_type) {
+ case CONTEXT_HISTORY_FILTER_TIME_SPAN:
+ str = KEY_TIME_SPAN;
+ break;
+ case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
+ str = KEY_RESULT_SIZE;
+ break;
+ case CONTEXT_HISTORY_FILTER_APP_ID:
+ str = KEY_APP_ID;
+ break;
+ case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+ str = KEY_DAY_OF_WEEK;
+ break;
+ case CONTEXT_HISTORY_FILTER_START_TIME:
+ str = KEY_START_TIME;
+ break;
+ case CONTEXT_HISTORY_FILTER_END_TIME:
+ str = KEY_END_TIME;
+ break;
+ case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+ str = KEY_BSSID;
+ break;
+ case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
+ str = KEY_AUDIO_JACK;
+ break;
+ case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+ str = KEY_COMMUNICATION_TYPE;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+std::string convert_data_to_string(context_history_data_e data_type)
+{
+ std::string str;
+ switch (data_type) {
+ case CONTEXT_HISTORY_RECENTLY_USED_APP:
+ str = SUBJ_APP_RECENTLY_USED;
+ break;
+ case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
+ str = SUBJ_APP_FREQUENTLY_USED;
+ break;
+ case CONTEXT_HISTORY_RARELY_USED_APP:
+ str = SUBJ_APP_RARELY_USED;
+ break;
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+ str = SUBJ_APP_PEAK_TIME;
+ break;
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+ str = SUBJ_MUSIC_PEAK_TIME;
+ break;
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+ str = SUBJ_VIDEO_PEAK_TIME;
+ break;
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+ str = SUBJ_APP_COMMON_SETTING;
+ break;
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+ str = SUBJ_MUSIC_COMMON_SETTING;
+ break;
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+ str = SUBJ_VIDEO_COMMON_SETTING;
+ break;
+ case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+ str = SUBJ_SOCIAL_FREQ_ADDRESS;
+ break;
+ case CONTEXT_HISTORY_BATTERY_USAGE:
+ str = SUBJ_BATTERY_USAGE;
+ break;
+ case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
+ str = SUBJ_BATTERY_RECENT_USAGE;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+bool check_record_key_data_type(int type, std::string key)
+{
+ if ((key.compare(CONTEXT_HISTORY_APP_ID) == 0) ||
+ key.compare(CONTEXT_HISTORY_ADDRESS) == 0) {
+ return (type == TYPE_STRING);
+ }
+
+ if ((key.compare(CONTEXT_HISTORY_TOTAL_COUNT) == 0) ||
+ key.compare(CONTEXT_HISTORY_TOTAL_AMOUNT) == 0 ||
+ key.compare(CONTEXT_HISTORY_TOTAL_DURATION) == 0 ||
+ key.compare(CONTEXT_HISTORY_LAST_TIME) == 0 ||
+ key.compare(CONTEXT_HISTORY_HOUR_OF_DAY) == 0 ||
+ key.compare(CONTEXT_HISTORY_AUDIO_JACK) == 0 ||
+ key.compare(CONTEXT_HISTORY_SYSTEM_VOLUME) == 0 ||
+ key.compare(CONTEXT_HISTORY_MEDIA_VOLUME) == 0 ||
+ key.compare(KEY_USED_TIME) == 0) { // Internal use for RecentBatteryUsage
+ return (type == TYPE_NUMERIC);
+ }
+
+ return false;
+}
+
+bool check_filter_data_int(context_history_filter_e filter_type, int val)
+{
+ switch (filter_type) {
+ case CONTEXT_HISTORY_FILTER_TIME_SPAN:
+ case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
+ case CONTEXT_HISTORY_FILTER_START_TIME:
+ case CONTEXT_HISTORY_FILTER_END_TIME:
+ if (val > 0)
+ return true;
+ break;
+ case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+ if (val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKDAYS ||
+ val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKENDS ||
+ val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_ALL)
+ return true;
+ break;
+ case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
+ if (val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_NOT_CONNECTED ||
+ val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_CONNECTED)
+ return true;
+ break;
+ case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+ if (val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_CALL ||
+ val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_MESSAGE ||
+ val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_ALL)
+ return true;
+ break;
+ default:
+ return false;
+ }
+ return false;
+}
+
+bool check_filter_data_string(context_history_filter_e filter_type, const char* val)
+{
+ IF_FAIL_RETURN(val, false);
+
+ switch (filter_type) {
+ case CONTEXT_HISTORY_FILTER_APP_ID:
+ case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+ return (g_strstr_len(val, -1, ";") == NULL);
+
+ default:
+ return false;
+ }
+}
+
+bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter)
+{
+ /* This should be aligned with context_history_filter_e */
+ static const char *filter_key[FILTER_KEY_LIMIT] = {
+ NULL,
+ KEY_TIME_SPAN,
+ KEY_RESULT_SIZE,
+ KEY_APP_ID,
+ KEY_DAY_OF_WEEK,
+ KEY_START_TIME,
+ KEY_END_TIME,
+ KEY_BSSID,
+ KEY_AUDIO_JACK,
+ KEY_COMMUNICATION_TYPE,
+ };
+
+ bool allowed[FILTER_KEY_LIMIT] = {false};
+
+ allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = true;
+ allowed[CONTEXT_HISTORY_FILTER_START_TIME] = true;
+ allowed[CONTEXT_HISTORY_FILTER_END_TIME] = true;
+ allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = true;
+
+ switch (data_type) {
+ case CONTEXT_HISTORY_RECENTLY_USED_APP:
+ case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
+ allowed[CONTEXT_HISTORY_FILTER_WIFI_BSSID] = true;
+ allowed[CONTEXT_HISTORY_FILTER_AUDIO_JACK] = true;
+ break;
+
+ case CONTEXT_HISTORY_RARELY_USED_APP:
+ break;
+
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+ allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
+ allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
+ break;
+
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+ allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
+ break;
+
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+ allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
+ allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
+ break;
+
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+ allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
+ break;
+
+ case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+ allowed[CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE] = true;
+ break;
+
+ case CONTEXT_HISTORY_BATTERY_USAGE:
+ break;
+
+ case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
+ allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = false;
+ allowed[CONTEXT_HISTORY_FILTER_START_TIME] = false;
+ allowed[CONTEXT_HISTORY_FILTER_END_TIME] = false;
+ break;
+
+ default:
+ return false;
+ }
+
+ bool found = true;
+ std::vector<std::string> keys = filter->jfilter.getMemberNames();
+
+ for (auto& key : keys) {
+ found = false;
+ for (int i = 1; i < FILTER_KEY_LIMIT; ++i) {
+ if (allowed[i] && key == filter_key[i]) {
+ found = true;
+ break;
+ }
+ }
+ if (found == true)
+ continue;
+
+ return false;
+ }
+
+ return true;
+}
+
+int __getIndexOf(context_history_record_h record, const std::string& key)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < record->keys.size(); ++i) {
+ if (record->keys[i] == key) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool history_is_deprecated(context_history_data_e data_type)
+{
+ bool ret = false;
+ switch (data_type) {
+ case CONTEXT_HISTORY_RARELY_USED_APP:
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+ case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+ case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+ case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+ ret = true;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+bool history_filter_is_deprecated(context_history_filter_e filter_type)
+{
+ bool ret = false;
+ switch (filter_type) {
+ case CONTEXT_HISTORY_FILTER_APP_ID:
+ case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+ case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+ case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+ ret = true;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <map>
-#include <list>
-#include <context_trigger.h>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include <TimerManager.h>
-#include "rule_validator.h"
-#include "rule_util.h"
-#include "ComparisonConverter.h"
-#include "IntComparisonConverter.h"
-#include "StringComparisonConverter.h"
-
-using namespace ctx;
-
-static bool __handleTimerEvent(CtxJson1& event);
-static int __arrangeDayOfWeek(CtxJson1& dayInfo);
-
-int ctx::rule_util::setEvent(CtxJson1& entry, CtxJson1* rule)
-{
- CtxJson1 tempEvent;
- std::string subject;
- entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &subject);
-
- CtxJson1 option;
- entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPTION, &option);
- tempEvent.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
-
- CtxJson1 elem;
- for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- CtxJson1 newElem;
-
- std::string key;
- elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
-
- std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
-
- ComparisonConverter* converter = NULL;
- if (type == TRIG_TMPL_TYPE_INTEGER) {
- converter = new(std::nothrow) IntComparisonConverter(elem);
- } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
- converter = new(std::nothrow) StringComparisonConverter(elem);
- }
- IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
- converter->getResult(&newElem);
-
- CtxJson1 detail;
- newElem.get(NULL, key.c_str(), &detail);
-
- std::string path = subject + "." + TRIG_RULE_KEY_COMPARISON;
- tempEvent.set(path.c_str(), key.c_str(), detail);
- delete converter;
- }
-
- // Handle Timer Event
- if (subject.compare(SUBJ_STATE_ALARM) == 0) {
- IF_FAIL_RETURN(__handleTimerEvent(tempEvent), ERR_INVALID_RULE);
- }
-
- rule->set(NULL, TRIG_RULE_KEY_EVENT, tempEvent);
-
- // Save event entry's logical to extra info (default and)
- std::string eventOp = TRIG_RULE_LOGICAL_CONJUNCTION;
- if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
- entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, &eventOp);
- }
- rule->set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, eventOp);
-
- return ERR_NONE;
-}
-
-int ctx::rule_util::addCondition(CtxJson1& entry, CtxJson1* rule)
-{
- CtxJson1 tempCond;
- std::string subject;
- entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &subject);
-
- CtxJson1 option;
- entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPTION, &option);
- tempCond.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
-
- CtxJson1 elem;
- for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
- CtxJson1 newElem;
-
- std::string key;
- elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
-
- std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
-
- ComparisonConverter* converter = NULL;
- if (type == TRIG_TMPL_TYPE_INTEGER) {
- converter = new(std::nothrow) IntComparisonConverter(elem);
- } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
- converter = new(std::nothrow) StringComparisonConverter(elem);
- }
- IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
- converter->getResult(&newElem);
-
- tempCond.set(subject.c_str(), TRIG_RULE_KEY_COMPARISON, newElem);
- delete converter;
- }
-
- rule->append(NULL, TRIG_RULE_KEY_CONDITION, tempCond);
-
- // Save event entry's logical to extra info (default and)
- std::string condOp = TRIG_RULE_LOGICAL_CONJUNCTION;
- if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
- entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, &condOp);
- }
- rule->append(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, condOp);
-
- return ERR_NONE;
-}
-
-bool __handleTimerEvent(CtxJson1& event)
-{
- CtxJson1 alarmComp;
- bool ret = event.get(SUBJ_STATE_ALARM, TRIG_RULE_KEY_COMPARISON, &alarmComp);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Invalid EVENT_TIME event");
-
- // Day processing
- CtxJson1 dayInfo;
- bool daySpecified = alarmComp.get(NULL, KEY_DAY_OF_WEEK, &dayInfo);
-
- if (daySpecified) {
- CtxJson1 newDayInfo;
- newDayInfo.set(NULL, TRIG_RULE_KEY_OPERATOR, TRIG_RULE_OP_ONE_OF);
-
- int dow = __arrangeDayOfWeek(dayInfo);
- IF_FAIL_RETURN_TAG(dow > 0, false, _E, "Invalid DayOfWeek info for EVENT_TIME");
-
- for (int i = 0 ; i < DAYS_PER_WEEK; i++) {
- int d = 0x01 << i;
- if (dow & d) {
- std::string day = TimerManager::dowToStr(d);
- newDayInfo.append(NULL, TRIG_RULE_KEY_VALUE, day);
-
- // Copy details as option
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, day);
- }
- }
- event.set(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_COMPARISON, KEY_DAY_OF_WEEK, newDayInfo);
- } else {
- // If DayOfWeek is not specified, regard it as Mon ~ Sun
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_MON);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_TUE);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_WED);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_THU);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_FRI);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SAT);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SUN);
- }
-
- // Time processing
- CtxJson1 timeInfo;
- alarmComp.get(NULL, KEY_TIME_OF_DAY, &timeInfo);
-
- int time;
- std::string timeOp;
- timeInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &timeOp);
-
- if (timeOp == TRIG_RULE_OP_EQUAL_TO) {
- timeInfo.get(NULL, TRIG_RULE_KEY_VALUE, &time);
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
- } else if (timeOp == TRIG_RULE_OP_ONE_OF) {
- for (int i = 0; timeInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &time); i++) {
- event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
- }
- }
-
- return true;
-}
-
-int __arrangeDayOfWeek(CtxJson1& dayInfo)
-{
- std::string dayOp;
- if (!dayInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &dayOp)) {
- return TimerManager::dowToInt(DOW_EVERYDAY);
- }
-
- int result = 0;
- if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO || dayOp == TRIG_RULE_OP_NOT_IN) {
- result = TimerManager::dowToInt(DOW_EVERYDAY);
- }
-
- int dow;
- std::string day;
- if (dayOp == TRIG_RULE_OP_EQUAL_TO) {
- dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
- dow = TimerManager::dowToInt(day);
- result |= dow;
- } else if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO) {
- dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
- dow = TimerManager::dowToInt(day);
- dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
- result &= dow;
- } else if (dayOp == TRIG_RULE_OP_ONE_OF) {
- for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
- dow = TimerManager::dowToInt(day);
- result |= dow;
- }
- } else if (dayOp == TRIG_RULE_OP_NONE_OF) {
- for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
- dow = TimerManager::dowToInt(day);
- dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
- result &= dow;
- }
- }
-
- _D("Requested day of week (%#x)", result);
- return result;
-}
-
-bool ctx::rule_util::isEventSet(CtxJson1& rule)
-{
- ctx::CtxJson1 event;
- if (rule.get(NULL, TRIG_RULE_KEY_EVENT, &event)) {
- if (event != EMPTY_JSON_OBJECT) {
- return true;
- }
- }
-
- return false;
-}
-
-bool ctx::rule_util::isActionSet(CtxJson1& rule)
-{
- ctx::CtxJson1 action;
- if (rule.get(NULL, TRIG_RULE_KEY_ACTION, &action)) {
- if (action != EMPTY_JSON_OBJECT) {
- return true;
- }
- }
-
- return false;
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CONTEXT_RULE_UTIL_H__
-#define __CONTEXT_RULE_UTIL_H__
-
-#include <CtxJson1.h>
-
-namespace ctx {
-
- namespace rule_util {
-
- int setEvent(CtxJson1& entry, CtxJson1* rule);
- int addCondition(CtxJson1& entry, CtxJson1* rule);
- bool isEventSet(CtxJson1& rule);
- bool isActionSet(CtxJson1& rule);
-
- }
-} /* namespace ctx */
-
-#endif /* __CONTEXT_RULE_UTIL_H__ */
+++ /dev/null
-/*
- * 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 <sstream>
-#include <string>
-#include <map>
-#include <Types.h>
-#include <context_trigger.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "DBusClient.h"
-#include "TriggerOldRuleTypes.h"
-#include "rule_validator.h"
-
-using namespace ctx;
-
-#define RULE_VALIDATOR_COND_NAME "name"
-#define RULE_VALIDATOR_KEY "key"
-#define RULE_VALIDATOR_TYPE "type"
-#define RULE_VALIDATOR_REF "ref"
-
-typedef std::map<std::string, CtxJson1> template_map_t;
-template_map_t template_map; // <name, template>
-
-static int string_to_int(std::string str);
-static bool check_value_int(CtxJson1& tmpl, std::string key, int value);
-static bool check_value_string(CtxJson1& tmpl, std::string key, std::string value);
-static bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value);
-static CtxJson1 get_template(std::string name);
-static bool check_template_int(CtxJson1& elem);
-static bool check_template_string(CtxJson1& elem);
-static bool check_template_enum(CtxJson1& elem);
-static std::string get_data_type(CtxJson1& elem, std::string& key);
-static bool is_equal_type(std::string& type1, std::string& type2);
-
-int string_to_int(std::string str)
-{
- int i;
- std::istringstream convert(str);
-
- if (!(convert >> i))
- i = 0;
-
- return i;
-}
-
-CtxJson1 get_template(std::string name)
-{
- rule_validator::request_template(name);
- return template_map[name];
-}
-
-int rule_validator::request_template(std::string name, bool mandatory)
-{
- if (!mandatory) {
- template_map_t::iterator it = template_map.find(name);
- IF_FAIL_RETURN(it == template_map.end(), ERR_NONE);
- }
-
- // Request template
- CtxJson1 request;
- request.set(NULL, TRIG_TMPL_KEY_SUBJECT, name);
-
- int req_id;
- CtxJson1 tmpl;
- DBusClient dbusClient;
- int error = dbusClient.readSync(SUBJ_TRIGGER_GET_TEMPLATE, request, &req_id, &tmpl);
- if (error == ERR_NOT_SUPPORTED) {
- template_map.erase(name);
- _E("Failed to get request: not supported");
- return ERR_NOT_SUPPORTED;
- }
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get request");
-
- template_map[name] = tmpl;
-
- return ERR_NONE;
-}
-
-void rule_validator::remove_template(std::string name)
-{
- template_map.erase(name);
-}
-
-// called by context_trigger_rule_add_entry()
-bool rule_validator::check_option(CtxJson1& item)
-{
- std::string name;
- item.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- // No option needed
- CtxJson1 opt_tmpl;
- tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
- std::list<std::string> opt_keys;
- IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
- if (opt_keys.size() <= 0) {
- return true;
- }
-
- // Err: Check if mandatory option is missed
- std::string val_str;
- int val;
- if (name == SUBJ_PLACE_GEOFENCE) {
- if (!(item.get(OLD_TRIG_RULE_KEY_EVENT_OPTION, CONTEXT_TRIGGER_PLACE_ID, &val)))
- return false;
- } else if (name == SUBJ_APP_FREQUENCY) {
- if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_APP_ID, &val_str)))
- return false;
- } else if (name == SUBJ_SOCIAL_FREQUENCY) {
- if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_ADDRESS, &val_str)))
- return false;
- }
-
- return true;
-}
-
-// called by context_trigger_rule_entry_add_option_int()
-bool rule_validator::check_option_int(std::string name, std::string key, int value)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- CtxJson1 opt_tmpl;
- tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
- // Err: Item with no option
- std::list<std::string> opt_keys;
- IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
- IF_FAIL_RETURN(opt_keys.size() > 0, false);
-
- // Err: Invalid option key or Invalid value type
- std::string t_type = get_data_type(opt_tmpl, key);
- IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
-
- // Err: Inappropriate value
- // a. normal case
- bool ret = check_value_int(opt_tmpl, key, value);
- IF_FAIL_RETURN(ret, false);
-
- return true;
-}
-
-// called by context_trigger_rule_entry_add_option_string()
-bool rule_validator::check_option_string(std::string name, std::string key, std::string value)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- CtxJson1 opt_tmpl;
- tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
- // Err: ';' for SQL injection
- IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
-
- // Err: Item with no option
- std::list<std::string> opt_keys;
- IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
- IF_FAIL_RETURN(opt_keys.size() > 0, false);
-
- // Err: Invalid option key or Invalid value type
- std::string t_type = get_data_type(opt_tmpl, key);
- IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
-
- // Err: Inappropriate value
- // a. spacial case
- if (t_type == TRIG_TMPL_TYPE_STRING && (name == SUBJ_APP_FREQUENCY || name == SUBJ_SOCIAL_FREQUENCY
- || name == SUBJ_MUSIC_FREQUENCY || name == SUBJ_VIDEO_FREQUENCY)
- && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
- std::size_t found = value.find("-");
- if (found == std::string::npos) {
- return false;
- }
-
- int t1 = string_to_int(value.substr(0, found-1));
- int t2 = string_to_int(value.substr(found+1, value.length()-1));
-
- if (!(t1 >= 0 && t1 < 24) || !(t2 >= 0 && t2 < 24)) {
- return false;
- }
-
- if (t1 >= t2) {
- return false;
- }
-
- return true;
- }
-
- // b. normal case
- bool ret = false;
- if (t_type == TRIG_TMPL_TYPE_STRING) {
- ret = check_value_string(opt_tmpl, key, value);
- } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
- ret = check_value_enum(opt_tmpl, key, value);
- }
-
- return ret;
-}
-
-// called by context_trigger_rule_entry_add_comparison_int()
-bool rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- CtxJson1 attr_tmpl;
- tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
-
- // Err: Invalid attribute key or Invalid value type
- std::string t_type = get_data_type(attr_tmpl, key);
- IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
-
- // Err: Invalid operator for the value
- // a. normal case
- bool ret = is_valid_operator(TRIG_TMPL_TYPE_INTEGER, op);
- IF_FAIL_RETURN(ret, false);
- // b. special case
- if (name == SUBJ_STATE_ALARM && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
- IF_FAIL_RETURN(op == CONTEXT_TRIGGER_EQUAL_TO, false);
- }
-
- // Err: Inappropriate value
- // a. normal case
- ret = check_value_int(attr_tmpl, key, value);
- IF_FAIL_RETURN(ret, false);
-
- return true;
-}
-
-// called by context_trigger_rule_entry_add_comparison_string()
-bool rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != CtxJson1(EMPTY_JSON_OBJECT), false);
-
- CtxJson1 attr_tmpl;
- tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
-
- // Err: ';' for SQL injection
- IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
-
- // Err: Invalid option key or Invalid value type
- std::string t_type = get_data_type(attr_tmpl, key);
- IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
-
- // Err: Invalid operator for the value
- bool ret = is_valid_operator(t_type, op);
- IF_FAIL_RETURN(ret, false);
-
- // Err: Inappropriate value
- // a. normal case
- if (t_type == TRIG_TMPL_TYPE_STRING) {
- ret = check_value_string(attr_tmpl, key, value);
- IF_FAIL_RETURN(ret, false);
- } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
- ret = check_value_enum(attr_tmpl, key, value);
- IF_FAIL_RETURN(ret, false);
- }
-
- return true;
-}
-
-bool rule_validator::check_valid_key(std::string type, std::string name, std::string key)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- // Err: Invalid key
- CtxJson1 tmp;
- bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
- IF_FAIL_RETURN(ret, false);
-
- return true;
-}
-
-bool check_value_int(CtxJson1& tmpl, std::string key, int value)
-{
- int min, max;
-
- if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MIN, &min)) {
- IF_FAIL_RETURN(value >= min, false);
- }
-
- if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MAX, &max)) {
- IF_FAIL_RETURN(value <= max, false);
- }
-
- return true;
-}
-
-bool check_value_string(CtxJson1& tmpl, std::string key, std::string value)
-{
- return true;
-}
-
-bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value)
-{
- std::string t_val;
- for (int i = 0; tmpl.getAt(key.c_str(), TRIG_TMPL_TYPE_ENUM, i, &t_val); i++) {
- if (t_val == value)
- return true;
- }
-
- return false;
-}
-
-// called by context_trigger_rule_entry_add_comparison()
-// called by context_trigger_rule_entry_add_option()
-bool rule_validator::set_ref_info(std::string type, CtxJson1* jref, std::string name, std::string key, std::string ref_data)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
- CtxJson1 detailed_tmpl;
- tmpl.get(NULL, type.c_str(), &detailed_tmpl);
-
- std::string dt = get_data_type(detailed_tmpl, key);
- IF_FAIL_RETURN(dt == TRIG_TMPL_TYPE_INTEGER || dt == TRIG_TMPL_TYPE_STRING || dt == TRIG_TMPL_TYPE_ENUM, false);
-
- CtxJson1 temp;
- temp.set(NULL, RULE_VALIDATOR_COND_NAME, name);
- temp.set(NULL, RULE_VALIDATOR_KEY, key);
- temp.set(NULL, RULE_VALIDATOR_TYPE, dt);
- temp.set(NULL, RULE_VALIDATOR_REF, ref_data);
-
- if (type == TRIG_TMPL_KEY_OPTION) {
- jref->append(NULL, TRIG_TMPL_KEY_OPTION, temp);
- } else if (type == TRIG_TMPL_KEY_ATTRIBUTE) {
- jref->append(NULL, TRIG_TMPL_KEY_ATTRIBUTE, temp);
- } else {
- return false;
- }
-
- return true;;
-}
-
-std::string get_data_type(CtxJson1& elem, std::string& key)
-{
- std::string data_type;
- bool ret = elem.get(key.c_str(), TRIG_TMPL_KEY_TYPE, &data_type);
- if (!ret) {
- int size = elem.getSize(key.c_str(), TRIG_TMPL_TYPE_ENUM);
- IF_FAIL_RETURN(size > 0, "");
- data_type = TRIG_TMPL_TYPE_ENUM;
- }
- IF_FAIL_RETURN(data_type == TRIG_TMPL_TYPE_INTEGER || data_type == TRIG_TMPL_TYPE_STRING || data_type == TRIG_TMPL_TYPE_ENUM, "");
-
- return data_type;
-}
-
-// called by context_trigger_rule_entry_add_comparison()
-std::string rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
-{
- CtxJson1 tmpl = get_template(name);
- IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, "");
-
- CtxJson1 detailed_tmpl;
- tmpl.get(NULL, type.c_str(), &detailed_tmpl);
-
- return get_data_type(detailed_tmpl, key);
-}
-
-// called by context_trigger_rule_add_entry()
-bool rule_validator::check_referential_data(std::string name, CtxJson1& ref_info)
-{
- std::map<std::string, std::string> type_map;
-
- CtxJson1 ref_data;
- for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_OPTION, i, &ref_data); i++) {
- std::string ref_key;
- ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
- std::string cond_type;
- ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
-
- if (type_map.count(ref_key) == 0) {
- type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
- }
-
- // Err: Invalid key or Value type not matched
- IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
- }
-
- for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_ATTRIBUTE, i, &ref_data); i++) {
- std::string ref_key;
- ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
- std::string cond_type;
- ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
-
- if (type_map.count(ref_key) == 0) {
- type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
- }
-
- // Err: Invalid key or Value type not matched
- IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
- }
-
- return true;
-}
-
-bool is_equal_type(std::string& type1, std::string& type2)
-{
- // This function regards TRIG_TMPL_TYPE_ENUM as TRIG_TMPL_TYPE_STRING for referential data
- if (type1 == type2) {
- return true;
- }
-
- if ((type1 == TRIG_TMPL_TYPE_STRING || type1 == TRIG_TMPL_TYPE_ENUM) && (type2 == TRIG_TMPL_TYPE_STRING || type2 == TRIG_TMPL_TYPE_ENUM)) {
- return true;
- }
-
- return false;
-}
-
-bool rule_validator::is_valid_operator(std::string type, std::string op)
-{
- if (op == CONTEXT_TRIGGER_EQUAL_TO || op == CONTEXT_TRIGGER_NOT_EQUAL_TO) {
- return true;
- }
-
- if (type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_DOUBLE) {
- if (op == CONTEXT_TRIGGER_GREATER_THAN || op == CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO ||
- op == CONTEXT_TRIGGER_LESS_THAN || op == CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO) {
- return true;
- }
- }
-
- return false;
-}
-
-// For custom item template
-bool rule_validator::is_valid_template(CtxJson1& attr_template)
-{
- IF_FAIL_RETURN_TAG(attr_template != EMPTY_JSON_OBJECT, false, _E, "Custom template: empty CtxJson1");
-
- bool ret;
- std::list<std::string> keys;
- attr_template.getKeys(&keys);
-
- for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
- std::string key = *it;
-
- std::string type = get_data_type(attr_template, key);
- IF_FAIL_RETURN_TAG(type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM,
- false, _E, "Custom template: invalid data type");
-
- CtxJson1 elem;
- attr_template.get(NULL, key.c_str(), &elem);
- if (type == TRIG_TMPL_TYPE_INTEGER) {
- ret = check_template_int(elem);
- IF_FAIL_RETURN(ret, false);
- } else if (type == TRIG_TMPL_TYPE_STRING) {
- ret = check_template_string(elem);
- IF_FAIL_RETURN(ret, false);
- } else if (type == TRIG_TMPL_TYPE_ENUM) {
- ret = check_template_enum(elem);
- IF_FAIL_RETURN(ret, false);
- }
- }
-
- return true;
-}
-
-bool check_template_int(CtxJson1& elem)
-{
- std::list<std::string> elem_keys;
- elem.getKeys(&elem_keys);
-
- bool min = false;
- bool max = false;
- int min_val = 0;
- int max_val = 0;
-
- for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
- std::string elem_key = *it2;
- if (elem_key == TRIG_TMPL_KEY_MIN) {
- min = elem.get(NULL, elem_key.c_str(), &min_val);
- IF_FAIL_RETURN_TAG(min, false, _E, "Custom template: failed to get integer type value");
- } else if (elem_key == TRIG_TMPL_KEY_MAX) {
- max = elem.get(NULL, elem_key.c_str(), &max_val);
- IF_FAIL_RETURN_TAG(max, false, _E, "Custom template: failed to get integer type value");
- } else {
- IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
- }
- }
-
- if (min && max) {
- IF_FAIL_RETURN_TAG(min_val <= max_val, false, _E, "Custom template: invalid min, max value");
- }
-
- return true;
-}
-
-bool check_template_string(CtxJson1& elem)
-{
- std::list<std::string> elem_keys;
- elem.getKeys(&elem_keys);
-
- for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
- std::string elem_key = *it2;
- IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
- }
-
- return true;
-}
-
-bool check_template_enum(CtxJson1& elem)
-{
- std::list<std::string> elem_keys;
- elem.getKeys(&elem_keys);
-
- for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
- std::string elem_key = *it2;
-
- if (elem_key == TRIG_TMPL_TYPE_ENUM) {
- int size = elem.getSize(NULL, TRIG_TMPL_TYPE_ENUM);
- IF_FAIL_RETURN_TAG(size > 0, false, _E, "Custom template: invalid enum");
-
- std::string val_str;
- for (int i = 0; i < size; i++) {
- bool ret = elem.getAt(NULL, TRIG_TMPL_TYPE_ENUM, i, &val_str);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Custom template: failed to get string type value");
- }
- } else {
- IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
- }
- }
-
- return true;
-}
+++ /dev/null
-/*
- * 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_VALIDATOR_H__
-#define __CONTEXT_RULE_VALIDATOR_H__
-
-#include <CtxJson1.h>
-
-namespace ctx {
- namespace rule_validator {
-
- int request_template(std::string name, bool mandatory = false);
- void remove_template(std::string name);
- bool check_option(ctx::CtxJson1 &item);
- bool check_option_int(std::string name, std::string key, int value);
- bool check_option_string(std::string name, std::string key, std::string value);
- bool check_option_reference(std::string event, ctx::CtxJson1 &item);
- bool check_comparison_int(std::string name, std::string key, std::string op, int value);
- bool check_comparison_string(std::string name, std::string key, std::string op, std::string value);
- bool check_valid_key(std::string type, std::string name, std::string key);
-
- bool set_ref_info(std::string type, ctx::CtxJson1 *jref, std::string name, std::string key, std::string ref_key);
- std::string get_data_type_from_template(std::string type, std::string name, std::string key);
- bool check_referential_data(std::string name, ctx::CtxJson1 &ref_info);
- bool is_valid_operator(std::string type, std::string op);
-
- bool is_valid_template(ctx::CtxJson1& attr_template);
- }
-} /* namespace ctx */
-
-#endif /* __CONTEXT_RULE_VALIDATOR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "ComparisonConverter.h"
+
+using namespace ctx;
+
+ComparisonConverter::ComparisonConverter(const char* type, CtxJson1& info) :
+ __completed(false),
+ __size(0),
+ __logicalOp(TRIG_RULE_LOGICAL_DISJUNCTION),
+ __type(type),
+ __info(info.str()),
+ __result(EMPTY_JSON_OBJECT)
+{
+ __info.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &__key);
+ __info.get(NULL, OLD_TRIG_RULE_KEY_OPERATOR, &__logicalOp);
+ __size = __info.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
+}
+
+int ComparisonConverter::getResult(CtxJson1* result)
+{
+ if (__result == EMPTY_JSON_OBJECT)
+ return ERR_INVALID_RULE;
+
+ *result = __result.str();
+
+ return ERR_NONE;
+}
+
+void ComparisonConverter::__convertComparison()
+{
+ IF_FAIL_VOID(!__convertEmptyComparison());
+ IF_FAIL_VOID(!__convertSingleComparison());
+ IF_FAIL_VOID(!__convertMultipleComparison());
+
+ _E("Failed to convert comparison as new format");
+}
+
+bool ComparisonConverter::__convertEmptyComparison()
+{
+ IF_FAIL_RETURN(__size == 0, false);
+
+ CtxJson1 temp = EMPTY_JSON_OBJECT;
+ __result.set(NULL, __key.c_str(), temp);
+
+ return true;
+}
+
+bool ComparisonConverter::__convertSingleComparison()
+{
+ IF_FAIL_RETURN(__size == 1, false);
+
+ std::string op;
+ __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, 0, &op);
+
+ __setConvertedOperator(op);
+ __setComparisonValue();
+
+ return true;
+}
+
+bool ComparisonConverter::__convertMultipleComparison()
+{
+ IF_FAIL_RETURN(__size > 1, false);
+
+ if (__checkOneOf()) {
+ return true;
+ } else if (__checkNoneOf()) {
+ return true;
+ } else if (__checkEtc()) {
+ return true;
+ }
+
+ return false;
+}
+
+bool ComparisonConverter::__checkOneOf()
+{
+ // Or of {==, ...}
+ IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+ IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_EQUAL_TO), false);
+
+ __setConvertedOperator(TRIG_RULE_OP_ONE_OF);
+ __setComparisonValueArray();
+
+ return true;
+}
+
+bool ComparisonConverter::__checkNoneOf()
+{
+ // And of {!=, ...}
+ IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+ IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_NOT_EQUAL_TO), false);
+
+ __setConvertedOperator(TRIG_RULE_OP_NONE_OF);
+ __setComparisonValueArray();
+
+ return true;
+}
+
+bool ComparisonConverter::__checkEtc()
+{
+ return false;
+}
+
+void ComparisonConverter::__setConvertedOperator(std::string op)
+{
+ __result.set(__key.c_str(), TRIG_RULE_KEY_OPERATOR, op);
+}
+
+void ComparisonConverter::__setComparisonValue()
+{
+ std::string valStr;
+ int val;
+
+ if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &valStr)) {
+ __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+ } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &val)) {
+ __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+ }
+}
+
+void ComparisonConverter::__setComparisonValueArray()
+{
+ std::string valStr;
+ int val;
+ // TODO sort
+ for (int i = 0; i < __size; i++) {
+ if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &valStr)) {
+ __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+ } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val)) {
+ __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_COMPARISON_CONVERTER_H_
+
+#include <CtxJson1.h>
+#include "TriggerOldRuleTypes.h"
+
+namespace ctx {
+
+ class ComparisonConverter {
+ public:
+ virtual ~ComparisonConverter() {};
+
+ int getResult(CtxJson1* result);
+
+ protected:
+ bool __completed;
+ int __size;
+ std::string __logicalOp;
+ std::string __type;
+ CtxJson1 __info;
+ CtxJson1 __result;
+ std::string __key;
+
+ ComparisonConverter(const char* type, CtxJson1& info);
+ void __convertComparison();
+ virtual int __getOperatorCount(std::string op) = 0;
+ virtual bool __checkEtc();
+ void __setConvertedOperator(std::string op);
+
+ private:
+ bool __convertEmptyComparison();
+ bool __convertSingleComparison();
+ bool __convertMultipleComparison();
+ bool __checkOneOf();
+ bool __checkNoneOf();
+ void __setComparisonValue();
+ void __setComparisonValueArray();
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_COMPARISON_CONVERTER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "IntComparisonConverter.h"
+
+using namespace ctx;
+
+IntComparisonConverter::IntComparisonConverter(CtxJson1 info) :
+ ComparisonConverter(TRIG_TMPL_TYPE_INTEGER, info)
+{
+ if (__size >= 2) {
+ for (int i = 0; i < __size; i++) {
+ int val;
+ std::string op;
+ __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val);
+ __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+ __insertComparisonInfo(op, val);
+ }
+ __sort();
+ }
+
+ __convertComparison();
+}
+
+void IntComparisonConverter::__insertComparisonInfo(std::string op, int val)
+{
+ IntComparisonMap::iterator it = __map.find(op);
+ if (it == __map.end()) {
+ IntList list;
+ list.push_back(val);
+ __map[op] = list;
+ } else {
+ it->second.push_back(val);
+ }
+}
+
+void IntComparisonConverter::__sort()
+{
+ for (IntComparisonMap::iterator it = __map.begin(); it != __map.end(); it++) {
+ it->second.sort();
+ }
+}
+
+int IntComparisonConverter::__getOperatorCount(std::string op)
+{
+ return __map[op].size();
+}
+
+int IntComparisonConverter::__getMaxValue(std::string op)
+{
+ return __map[op].back();
+}
+
+int IntComparisonConverter::__getMinValue(std::string op)
+{
+ return __map[op].front();
+}
+
+bool IntComparisonConverter::__checkEtc()
+{
+ // Simple version in, notIn
+ IF_FAIL_RETURN(!__checkIn(), true);
+ IF_FAIL_RETURN(!__checkNotIn(), true);
+
+ return false;
+}
+
+
+bool IntComparisonConverter::__checkIn()
+{
+ // And of { >= min, <= max }
+ IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+ IF_FAIL_RETURN(__size == 2, false);
+ IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) == 1
+ && __getOperatorCount(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) == 1, false);
+
+ int maxOfGE = __getMaxValue(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO);
+ int minOfLE = __getMinValue(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO);
+ IF_FAIL_RETURN(maxOfGE <= minOfLE, false);
+
+ __setConvertedOperator(TRIG_RULE_OP_IN);
+ __setComparisonValue(maxOfGE, minOfLE);
+
+ return true;
+}
+
+bool IntComparisonConverter::__checkNotIn()
+{
+ // Or of { < min, > max }
+ IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+ IF_FAIL_RETURN(__size == 2, false);
+ IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN) == 1
+ && __getOperatorCount(TRIG_RULE_OP_LESS_THAN) == 1, false);
+
+ int maxOfL = __getMaxValue(TRIG_RULE_OP_LESS_THAN);
+ int minOfG = __getMinValue(TRIG_RULE_OP_GREATER_THAN);
+ IF_FAIL_RETURN(maxOfL <= minOfG, false);
+
+ __setConvertedOperator(TRIG_RULE_OP_NOT_IN);
+ __setComparisonValue(maxOfL, minOfG);
+
+ return true;
+}
+
+void IntComparisonConverter::__setComparisonValue(int val1, int val2)
+{
+ __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val1);
+ __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val2);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_INT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_INT_COMPARISON_CONVERTER_H_
+
+#include <list>
+#include <CtxJson1.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+ class IntComparisonConverter : public ComparisonConverter {
+ typedef std::list<int> IntList; // Integer value list
+ typedef std::map<std::string, IntList> IntComparisonMap; // { operator, IntList }
+
+ public:
+ IntComparisonConverter(CtxJson1 info);
+ ~IntComparisonConverter() {};
+
+ private:
+ IntComparisonMap __map;
+
+ void __insertComparisonInfo(std::string op, int val);
+ void __sort();
+ int __getMaxValue(std::string op);
+ int __getMinValue(std::string op);
+
+ bool __checkIn();
+ bool __checkNotIn();
+ void __setComparisonValue(int val1, int val2);
+ /* From CompariconConverter */
+ int __getOperatorCount(std::string op);
+ bool __checkEtc();
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_INT_COMPARISON_CONVERTER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+StringComparisonConverter::StringComparisonConverter(CtxJson1 info) :
+ ComparisonConverter(TRIG_TMPL_TYPE_STRING, info)
+{
+ if (__size >= 2) {
+ for (int i = 0; i < __size; i++) {
+ std::string op;
+ __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+ __map[op]++;
+ }
+ }
+
+ __convertComparison();
+}
+
+
+int StringComparisonConverter::__getOperatorCount(std::string op)
+{
+ return __map[op];
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+#define _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+
+#include <map>
+#include <CtxJson1.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+ class StringComparisonConverter : public ComparisonConverter {
+ typedef std::map<std::string, int> StringComparisonMap;
+
+ public:
+ StringComparisonConverter(CtxJson1 info);
+ ~StringComparisonConverter() {};
+
+ private:
+ StringComparisonMap __map;
+
+ /* From CompariconConverter */
+ int __getOperatorCount(std::string op);
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_STRING_COMPARISON_CONVERTER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+#define _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+
+/* Old Rule Keys */
+#define OLD_TRIG_RULE_KEY_EVENT "EVENT"
+#define OLD_TRIG_RULE_KEY_EVENT_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_EVENT_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_EVENT_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_OPERATOR "OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION "CONDITION"
+#define OLD_TRIG_RULE_KEY_CONDITION_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_DATA_ARR "DATA_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_KEY "DATA_KEY"
+#define OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR "DATA_KEY_OPERATOR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_ARR "DATA_VALUE_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR "DATA_VALUE_OPER_ARR"
+
+#endif /* _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_ */
--- /dev/null
+/*
+ * 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 <sstream>
+//#include <iomanip>
+#include <app_control_internal.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <pkgmgr-info.h>
+#include <context_trigger.h>
+#include <context_trigger_internal.h>
+#include <Types.h>
+#include <DBusTypes.h>
+#include <CtxJson1.h>
+#include <DBusClient.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "TriggerOldRuleTypes.h"
+#include "rule_validator.h"
+#include "rule_util.h"
+
+#define TRIGGER_DEPRECATED_FUNCTION_MSG "DEPRECATION WARNING: %s is deprecated and will be removed from next release."
+#define TRIGGER_DEPRECATED_EVENT_MSG "DEPRECATION WARNING: This event is deprecated and will be removed from next release."
+#define TRIGGER_DEPRECATED_CONDITION_MSG "DEPRECATION WARNING: This condition is deprecated and will be removed from next release."
+
+//#define DOUBLE_PRECISION 2
+#define TYPE_EVENT 1
+#define TYPE_CONDITION 2
+#define TYPE_OPTION TRIG_TMPL_KEY_OPTION
+#define TYPE_ATTRIBUTE TRIG_TMPL_KEY_ATTRIBUTE
+#define OLD_INITIAL_ENTRY "{ \"" OLD_TRIG_RULE_KEY_DATA_ARR "\" : [ ] }"
+#define INITIAL_REF "{ \"" TRIG_TMPL_KEY_OPTION "\" : [ ], \"" TRIG_TMPL_KEY_ATTRIBUTE "\" : [ ] }"
+#define INITIAL_RULE \
+"{ \"" TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" TRIG_RULE_KEY_EVENT "\" : { }, \"" TRIG_RULE_KEY_CONDITION "\" : [ ], \"" \
+TRIG_RULE_KEY_ACTION "\" : { }, \"" _TRIG_RULE_KEY_EXTRA "\": { } }"
+#define INITIAL_ENTRY "{ \"" TRIG_RULE_KEY_OPTION "\": { }, \"" TRIG_RULE_KEY_COMPARISON "\" : { } }"
+
+static ctx::DBusClient __dbusClient;
+
+static int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
+static int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
+static std::string convert_event_to_string(context_trigger_event_e item);
+static std::string convert_condition_to_string(context_trigger_condition_e item);
+static std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type);
+static std::string get_custom_item_subject(const char* provider, const char* item);
+static bool event_is_deprecated(context_trigger_event_e item);
+static bool condition_is_deprecated(context_trigger_condition_e item);
+
+//static std::string int_to_string(int value);
+//static std::string double_to_string(int value);
+
+typedef struct _context_trigger_rule_s {
+ ctx::CtxJson1 jold_rule;
+ ctx::CtxJson1 jrule; // description, event{}, condition[], action{}, _extra{}
+ ctx::CtxJson1 jref;
+
+ _context_trigger_rule_s() {
+ jold_rule = EMPTY_JSON_OBJECT;
+ jrule = INITIAL_RULE;
+ jref = INITIAL_REF;
+ }
+} _context_trigger_rule_h;
+
+typedef struct _context_trigger_rule_entry_s {
+ int type;
+ ctx::CtxJson1 jentry;
+ ctx::CtxJson1 jref;
+
+ _context_trigger_rule_entry_s(int t): type(t) {
+ jentry = OLD_INITIAL_ENTRY;
+
+ if (t == TYPE_CONDITION) {
+ jref = INITIAL_REF;
+ }
+ }
+} _context_trigger_rule_entry_h;
+
+// Add a rule
+SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule && rule_id);
+
+ // Err: No event
+ if (!ctx::rule_util::isEventSet(rule->jrule)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // Err: No action
+ if (!ctx::rule_util::isActionSet(rule->jrule)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // If condition size isn't greater than 1, update logical operator as default
+ if ((rule->jrule).getSize(NULL, TRIG_RULE_KEY_CONDITION) <= 1) {
+ (rule->jrule).set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, TRIG_RULE_LOGICAL_CONJUNCTION);
+ }
+
+ ctx::CtxJson1 jrule_id;
+ int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
+
+ if (error == ERR_NONE) {
+ jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
+ }
+
+ return error;
+}
+
+// Remove a rule
+SO_EXPORT int context_trigger_remove_rule(int rule_id)
+{
+ _D("BEGIN");
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ ctx::CtxJson1 jrule_id;
+ jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+ int error = __dbusClient.write(SUBJ_TRIGGER_REMOVE, jrule_id, NULL);
+
+ if (error == ERR_ALREADY_STARTED) { // Rule is still enabled.
+ return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
+ } else if (error == ERR_NO_DATA) {
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+ }
+
+ return error;
+}
+
+// Enable a rule
+SO_EXPORT int context_trigger_enable_rule(int rule_id)
+{
+ _D("BEGIN");
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ ctx::CtxJson1 jrule_id;
+ jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+
+ int req_id; // Useless in context_trigger
+ int error = __dbusClient.subscribe(SUBJ_TRIGGER_ENABLE, jrule_id, &req_id, NULL);
+
+ if (error == ERR_NO_DATA) {
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+ }
+
+ return error;
+}
+
+// Disable a rule
+SO_EXPORT int context_trigger_disable_rule(int rule_id)
+{
+ _D("BEGIN");
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ ctx::CtxJson1 jrule_id;
+ jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+ int error = __dbusClient.write(SUBJ_TRIGGER_DISABLE, jrule_id, NULL);
+
+ if (error == ERR_NO_DATA) {
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+ }
+
+ return error;
+}
+
+SO_EXPORT int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enabled_rule_count, int** disabled_rule_ids, int* disabled_rule_count)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
+
+ int req_id;
+ ctx::CtxJson1 data_read;
+ int error = __dbusClient.readSync(SUBJ_TRIGGER_GET_RULE_IDS, NULL, &req_id, &data_read);
+
+ if (error != ERR_NONE) {
+ return error;
+ }
+
+ // Enabled rules
+ int* e_arr = NULL;
+ *enabled_rule_count = data_read.getSize(NULL, TRIG_KEY_ENABLED_IDS);
+
+ if (*enabled_rule_count > 0) {
+ e_arr = static_cast<int*>(g_malloc((*enabled_rule_count) * sizeof(int)));
+ IF_FAIL_RETURN_TAG(e_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ int id;
+ for (int i = 0; data_read.getAt(NULL, TRIG_KEY_ENABLED_IDS, i, &id); i++) {
+ *(e_arr + i) = id;
+ }
+ }
+ *enabled_rule_ids = e_arr;
+
+ // Disabled rules
+ int* d_arr = NULL;
+ *disabled_rule_count = data_read.getSize(NULL, TRIG_KEY_DISABLED_IDS);
+
+ if (*disabled_rule_count > 0) {
+ d_arr = static_cast<int*>(g_malloc((*disabled_rule_count) * sizeof(int)));
+ IF_FAIL_RETURN_TAG(d_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ int id;
+ for (int i = 0; data_read.getAt(NULL, TRIG_KEY_DISABLED_IDS, i, &id); i++) {
+ *(d_arr + i) = id;
+ }
+ }
+ *disabled_rule_ids = d_arr;
+
+ return error;
+}
+
+
+SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule);
+ if (rule_id <= 0)
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+ ctx::CtxJson1 option;
+ option.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+
+ int req_id;
+ ctx::CtxJson1 data_read;
+ int error = __dbusClient.readSync(SUBJ_TRIGGER_GET, option, &req_id, &data_read);
+
+ if (error == ERR_NO_DATA) {
+ return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+ } else if (error != ERR_NONE) {
+ return error;
+ }
+
+ *rule = new(std::nothrow) _context_trigger_rule_h();
+ (*rule)->jrule = data_read;
+
+ return ERR_NONE;
+}
+
+// Rule creation
+SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule);
+
+ std::string logical_str = convert_logical_type_to_string(logical_type);
+ if (logical_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ *rule = new(std::nothrow) _context_trigger_rule_h();
+ (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
+
+ (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
+
+ return ERR_NONE;
+}
+
+// Rule deletion
+SO_EXPORT int context_trigger_rule_destroy(context_trigger_rule_h rule)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule);
+ delete rule;
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+
+SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule && entry);
+
+ // Check if rule handle is created
+ ctx::CtxJson1 extra;
+ bool ret = (rule->jrule).get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER);
+
+ if (entry->type == TYPE_EVENT) {
+ // Err: More than one event
+ ctx::CtxJson1 elem;
+ if ((rule->jold_rule).get(NULL, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // Err: Check if all the mandatory options are added
+ ret = ctx::rule_validator::check_option(entry->jentry);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ // Err: If referential conditions are registered priviously, check them
+ std::string ename;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
+ ret = ctx::rule_validator::check_referential_data(ename, rule->jref);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ ctx::CtxJson1 temp = (entry->jentry).str();
+ ret = (rule->jold_rule).set(NULL, OLD_TRIG_RULE_KEY_EVENT, temp);
+
+ int error = ctx::rule_util::setEvent(entry->jentry, &(rule->jrule));
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add event entry");
+ } else if (entry->type == TYPE_CONDITION) {
+ // Err: Condition without comparison data
+ if ((entry->jentry).getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) < 1) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ ctx::CtxJson1 elem;
+ for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ int val_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
+ int op_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR);
+
+ // Err: Condition without comparison data
+ if (val_arr_size != op_arr_size || val_arr_size < 1 || op_arr_size < 1) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // Err: Check if all the mandatory options are added
+ ret = ctx::rule_validator::check_option(entry->jentry);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ // If event is already added ....
+ std::string ename;
+ ret = (rule->jold_rule).get(OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
+ if (ret) {
+ // Err: Check referential information if exists
+ ret = ctx::rule_validator::check_referential_data(ename, entry->jref);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+ } else {
+ // If not, copy referential information to rule entry
+ ctx::CtxJson1 info;
+ for (int j = 0; (entry->jref).getAt(NULL, TYPE_OPTION, j, &info); j++) {
+ (rule->jref).append(NULL, TYPE_OPTION, info);
+ }
+
+ for (int j = 0; (entry->jref).getAt(NULL, TYPE_ATTRIBUTE, j, &info); j++) {
+ (rule->jref).append(NULL, TYPE_ATTRIBUTE, info);
+ }
+ }
+ }
+
+ ctx::CtxJson1 temp = (entry->jentry).str();
+ ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
+
+ ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
+ } else {
+ // Entry is not created
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+static bool is_call_operation(app_control_h app_control)
+{
+ char *op = NULL;
+ int err = app_control_get_operation(app_control, &op);
+ IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _W, "Getting operation of app control failed");
+
+ bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
+ g_free(op);
+
+ return ret;
+}
+
+SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule && app_control);
+ int error;
+
+ // Privilege check
+ error = __dbusClient.call(METHOD_CHK_PRIV_APPLAUNCH);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+
+ if (is_call_operation(app_control)) {
+ error = __dbusClient.call(METHOD_CHK_PRIV_CALL);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+ }
+
+ // Err: if action arleady exists
+ if (ctx::rule_util::isActionSet(rule->jrule)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // Err: service app
+ char* app_id = NULL;
+ error = app_control_get_app_id(app_control, &app_id);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
+
+ pkgmgrinfo_appinfo_h app_info;
+ error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
+ g_free(app_id);
+ IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
+
+ // Service apps are not allowed to be launched (Mobile & Wearable)
+ char *app_type = NULL;
+ pkgmgrinfo_appinfo_get_component_type(app_info, &app_type);
+ if (!strcmp(app_type, "svcapp")) {
+ _E("Service application is restricted");
+ pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+ pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+
+ // Set app control
+ bundle* appctl_bundle = NULL;
+ error = app_control_to_bundle(app_control, &appctl_bundle);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
+
+ bundle_raw* appctl_raw;
+ int raw_length;
+ error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
+
+ std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, appctl_str);
+ bundle_free_encoded_rawdata(&appctl_raw);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT 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)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule && title && content);
+
+ // Privilege check
+ int error = __dbusClient.call(METHOD_CHK_PRIV_NOTIFICATION);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+
+ // if action arleady exists
+ if (ctx::rule_util::isActionSet(rule->jrule)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ // Err: App control check
+ if (app_control) {
+ char* app_id = NULL;
+ error = app_control_get_app_id(app_control, &app_id);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
+
+ pkgmgrinfo_appinfo_h app_info;
+ error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
+ g_free(app_id);
+ IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
+
+ pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+ }
+
+ // Set title, content
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, title);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, content);
+
+ // Set icon path
+ if (icon_path) {
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, icon_path);
+ }
+
+ // Set app control
+ if (app_control) {
+ bundle* appctl_bundle = NULL;
+ error = app_control_to_bundle(app_control, &appctl_bundle);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
+
+ bundle_raw* appctl_raw;
+ int raw_length;
+ error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
+
+ std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, appctl_str);
+
+ bundle_free_encoded_rawdata(&appctl_raw);
+ }
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+//LCOV_EXCL_START
+SO_EXPORT 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)
+{
+ ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
+
+ /* if action arleady exists */
+ if (ctx::rule_util::isActionSet(rule->jrule)) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ /* Set basic dbus method call info */
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, bus_name);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, object_path);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, interface_name);
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, method_name);
+
+ /* Set the parameters */
+ if (param)
+ (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
+// Set description
+SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule);
+
+ (rule->jrule).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Get rule description
+SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(rule && description);
+
+ std::string val;
+ (rule->jrule).get(NULL, TRIG_RULE_KEY_DESCRIPTION, &val);
+
+ *description = strdup(val.c_str());
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Event creation
+SO_EXPORT 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)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry);
+
+ if (event_is_deprecated(event_item)) {
+ _W(TRIGGER_DEPRECATED_EVENT_MSG);
+ }
+
+ std::string eitem_str = convert_event_to_string(event_item);
+ if (eitem_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = context_trigger_rule_event_create_internal(eitem_str.c_str(), logical_type, entry);
+ return error;
+}
+
+SO_EXPORT 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)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(event_item && provider && entry);
+
+ // Err: Invalid provider
+ pkgmgrinfo_pkginfo_h pkg_info;
+ int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+ IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+ std::string subject = get_custom_item_subject(provider, event_item);
+ error = context_trigger_rule_event_create_internal(subject.c_str(), logical_type, entry, true);
+
+ return error;
+}
+
+int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(event_item);
+
+ // Err: Invalid logical operator
+ std::string logical_str = convert_logical_type_to_string(logical_type);
+ if (logical_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = ctx::rule_validator::request_template(event_item, is_custom);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_EVENT);
+ (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, event_item);
+ (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, logical_str);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Event availability check
+SO_EXPORT int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(supported);
+
+ if (event_is_deprecated(event_item)) {
+ _W(TRIGGER_DEPRECATED_EVENT_MSG);
+ }
+
+ *supported = false;
+
+ std::string eitem_str = convert_event_to_string(event_item);
+ if (eitem_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = __dbusClient.isSupported(eitem_str);
+
+ if (error == ERR_NONE)
+ *supported = true;
+
+ if (error == ERR_NOT_SUPPORTED)
+ return ERR_NONE;
+
+ return error;
+}
+
+// Condition creation
+SO_EXPORT 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)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry);
+
+ if (condition_is_deprecated(condition_item)) {
+ _W(TRIGGER_DEPRECATED_CONDITION_MSG);
+ }
+
+ std::string citem_str = convert_condition_to_string(condition_item);
+ if (citem_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = context_trigger_rule_condition_create_internal(citem_str.c_str(), logical_type, entry);
+ return error;
+}
+
+SO_EXPORT 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)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(condition_item && provider && entry);
+
+ // Err: Invalid provider
+ pkgmgrinfo_pkginfo_h pkg_info;
+ int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+ IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+ std::string subject = get_custom_item_subject(provider, condition_item);
+ error = context_trigger_rule_condition_create_internal(subject.c_str(), logical_type, entry, true);
+ return error;
+}
+
+int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(condition_item);
+
+ std::string logical_str = convert_logical_type_to_string(logical_type);
+ if (logical_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = ctx::rule_validator::request_template(condition_item, is_custom);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
+ *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_CONDITION);
+ (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, condition_item);
+ (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, logical_str);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Condition availability check
+SO_EXPORT int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(supported);
+
+ if (condition_is_deprecated(condition_item)) {
+ _W(TRIGGER_DEPRECATED_CONDITION_MSG);
+ }
+
+ *supported = false;
+
+ std::string citem_str = convert_condition_to_string(condition_item);
+ if (citem_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ int error = __dbusClient.isSupported(citem_str);
+
+ if (error == ERR_NONE)
+ *supported = true;
+
+ if (error == ERR_NOT_SUPPORTED)
+ return ERR_NONE;
+
+ return error;
+}
+
+// Rule data deletion
+SO_EXPORT int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry);
+ delete entry;
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry && option_key);
+
+ bool ret = true;
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+ ret = ctx::rule_validator::check_option_int(name, option_key, value);
+ if (!ret) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
+{
+ _D("BEGIN");
+ _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+ ASSERT_NOT_NULL(entry && option_key && value);
+
+ bool ret = true;
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+ ret = ctx::rule_validator::check_option_string(name, option_key, value);
+ if (!ret) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
+{
+ _D("BEGIN");
+ _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+ ASSERT_NOT_NULL(entry && option_key && event_data_key);
+
+ // Err: Only conditin can reference data from event
+ if (entry->type != TYPE_CONDITION) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+
+ // Err: Check if key is valid
+ bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION, name, option_key);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ // Set reference information
+ ret = ctx::rule_validator::set_ref_info(TYPE_OPTION, &(entry->jref), name, option_key, event_data_key);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+
+ (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry, context_trigger_logical_type_e logical_type, const char* key)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry && key);
+
+ std::string logical_str = convert_logical_type_to_string(logical_type);
+ if (logical_str.empty()) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+ }
+
+ // Err: Check if key is valid
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+ bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ // Err: Comparison key is already added
+ ctx::CtxJson1 elem;
+ for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ std::string elem_item;
+ elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+ // Err: Comparison key is already added
+ if (elem_item.compare(key) == 0) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+ }
+
+ ctx::CtxJson1 data;
+ data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, key);
+ data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR, logical_str);
+ (entry->jentry).append(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, data);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+static int context_trigger_rule_entry_add_comparison_string_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, std::string value)
+{
+ ctx::CtxJson1 elem;
+ for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ std::string elem_item;
+ elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+
+ if (elem_item.compare(key) == 0) {
+ std::string elem_val;
+ std::string elem_op;
+ for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
+ elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
+
+ // Err: Duplicated <operator, value>
+ if (elem_val.compare(value) == 0 && elem_op.compare(op) == 0) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+ }
+ elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value.c_str());
+ elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
+ (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+ }
+ }
+
+ // Comparison key not exist
+ return CONTEXT_TRIGGER_ERROR_NO_DATA;
+}
+
+static int context_trigger_rule_entry_add_comparison_int_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, int value)
+{
+ ctx::CtxJson1 elem;
+ for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ std::string elem_item;
+ elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+
+ if (elem_item.compare(key) == 0) {
+ int elem_val;
+ std::string elem_op;
+ for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
+ elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
+
+ // Err: Duplicated <operator, value>
+ if (elem_val == value && elem_op.compare(op) == 0) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+ }
+ elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value);
+ elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
+ (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+ }
+ }
+
+ // Comparison key not exist
+ return CONTEXT_TRIGGER_ERROR_NO_DATA;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
+{
+ _D("BEGIN");
+ _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+ ASSERT_NOT_NULL(entry && key && op && event_data_key);
+
+ // Err: Only condition can reference data from event
+ if (entry->type != TYPE_CONDITION) {
+ return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+ }
+
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+
+ // Err: Check if key is valid
+ bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ // Err: Invalid operator
+ std::string type = ctx::rule_validator::get_data_type_from_template(TYPE_ATTRIBUTE, name, key);
+ ret = ctx::rule_validator::is_valid_operator(type, op);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
+ IF_FAIL_RETURN(error == ERR_NONE, error);
+
+ // Set reference information
+ ret = ctx::rule_validator::set_ref_info(TYPE_ATTRIBUTE, &(entry->jref), name, key, event_data_key);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+
+ return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry && key && op);
+
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+ bool ret = ctx::rule_validator::check_comparison_int(name, key, op, value);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ int error = context_trigger_rule_entry_add_comparison_int_internal(entry, key, op, value);
+ return error;
+}
+/*
+SO_EXPORT int context_trigger_rule_entry_add_comparison_double(context_trigger_rule_entry_h entry, const char* key, const char* op, double value)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry && key && op);
+
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+ // TODO: check_comparison_double()
+ bool ret = ctx::rule_validator::check_comparison_double(name, key, op, value);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ int error = context_trigger_rule_entry_add_comparison_internal(entry, key, op, double_to_string(value));
+ return error;
+}
+*/
+SO_EXPORT int context_trigger_rule_entry_add_comparison_string(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* value)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(entry && key && op && value);
+
+ std::string name;
+ (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+ bool ret = ctx::rule_validator::check_comparison_string(name, key, op, value);
+ IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+ int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, value);
+ return error;
+}
+
+SO_EXPORT int context_trigger_custom_register(const char* name, const char* attr_template)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(name && attr_template);
+
+ // Err: Invalid CtxJson1
+ ctx::CtxJson1 jattr_template = attr_template;
+ IF_FAIL_RETURN_TAG(jattr_template.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Failed to parse template");
+
+ // Err: Invalid template
+ bool ret = ctx::rule_validator::is_valid_template(jattr_template);
+ IF_FAIL_RETURN_TAG(ret, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
+
+ ctx::CtxJson1 data;
+ data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_ADD);
+ data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+ data.set(NULL, TRIG_TMPL_KEY_ATTRIBUTE, jattr_template);
+
+ int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add custom item: %#x", error);
+
+ return error;
+}
+
+SO_EXPORT int context_trigger_custom_unregister(const char* name)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(name);
+
+ ctx::CtxJson1 data;
+ data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_REMOVE);
+ data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+
+ ctx::CtxJson1 subj;
+ int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, &subj);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to remove custom item: %#x", error);
+
+ std::string subject;
+ subj.get(NULL, TRIG_TMPL_KEY_SUBJECT, &subject);
+ ctx::rule_validator::remove_template(subject);
+
+ return error;
+}
+
+SO_EXPORT int context_trigger_custom_publish(const char* name, const char* fact)
+{
+ _D("BEGIN");
+ ASSERT_NOT_NULL(name && fact);
+
+ // Err: Invalid CtxJson1
+ ctx::CtxJson1 jfact = fact;
+ IF_FAIL_RETURN_TAG(jfact.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Cannot parse fact CtxJson1");
+
+ ctx::CtxJson1 data;
+ data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_PUBLISH);
+ data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+ data.set(NULL, TRIG_CUSTOM_KEY_FACT, jfact);
+
+ int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to publish custom data");
+
+ return error;
+}
+
+std::string convert_event_to_string(context_trigger_event_e item)
+{
+ std::string str;
+ switch (item) {
+ case CONTEXT_TRIGGER_EVENT_TIME:
+ str = SUBJ_STATE_ALARM;
+ break;
+ case CONTEXT_TRIGGER_EVENT_BATTERY:
+ str = SUBJ_STATE_BATTERY;
+ break;
+ case CONTEXT_TRIGGER_EVENT_CHARGER:
+ str = SUBJ_STATE_CHARGER;
+ break;
+ case CONTEXT_TRIGGER_EVENT_GPS:
+ str = SUBJ_STATE_GPS;
+ break;
+ case CONTEXT_TRIGGER_EVENT_HEADPHONE:
+ str = SUBJ_STATE_HEADPHONE;
+ break;
+ case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
+ str = SUBJ_STATE_PSMODE;
+ break;
+ case CONTEXT_TRIGGER_EVENT_USB:
+ str = SUBJ_STATE_USB;
+ break;
+ case CONTEXT_TRIGGER_EVENT_WIFI:
+ str = SUBJ_STATE_WIFI;
+ break;
+ case CONTEXT_TRIGGER_EVENT_CALL:
+ str = SUBJ_STATE_CALL;
+ break;
+ case CONTEXT_TRIGGER_EVENT_EMAIL:
+ str = SUBJ_STATE_EMAIL;
+ break;
+ case CONTEXT_TRIGGER_EVENT_MESSAGE:
+ str = SUBJ_STATE_MESSAGE;
+ break;
+ case CONTEXT_TRIGGER_EVENT_CONTACTS:
+ str = SUBJ_STATE_CONTACTS;
+ break;
+ case CONTEXT_TRIGGER_EVENT_ACTIVITY_STATIONARY:
+ str = SUBJ_ACTIVITY_STATIONARY;
+ break;
+ case CONTEXT_TRIGGER_EVENT_ACTIVITY_WALKING:
+ str = SUBJ_ACTIVITY_WALKING;
+ break;
+ case CONTEXT_TRIGGER_EVENT_ACTIVITY_RUNNING:
+ str = SUBJ_ACTIVITY_RUNNING;
+ break;
+ case CONTEXT_TRIGGER_EVENT_ACTIVITY_IN_VEHICLE:
+ str = SUBJ_ACTIVITY_IN_VEHICLE;
+ break;
+ case CONTEXT_TRIGGER_EVENT_PLACE:
+ str = SUBJ_PLACE_GEOFENCE;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+std::string convert_condition_to_string(context_trigger_condition_e item)
+{
+ std::string str;
+ switch (item) {
+ case CONTEXT_TRIGGER_CONDITION_TIME:
+ str = SUBJ_STATE_TIME;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_BATTERY:
+ str = SUBJ_STATE_BATTERY;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_CHARGER:
+ str = SUBJ_STATE_CHARGER;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_GPS:
+ str = SUBJ_STATE_GPS;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_HEADPHONE:
+ str = SUBJ_STATE_HEADPHONE;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
+ str = SUBJ_STATE_PSMODE;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_USB:
+ str = SUBJ_STATE_USB;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_WIFI:
+ str = SUBJ_STATE_WIFI;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_CALL:
+ str = SUBJ_STATE_CALL;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
+ str = SUBJ_APP_FREQUENCY;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
+ str = SUBJ_SOCIAL_FREQUENCY;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
+ str = SUBJ_MUSIC_FREQUENCY;
+ break;
+ case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
+ str = SUBJ_VIDEO_FREQUENCY;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type)
+{
+ std::string str;
+ switch (logical_type) {
+ case CONTEXT_TRIGGER_LOGICAL_CONJUNCTION:
+ str = TRIG_RULE_LOGICAL_CONJUNCTION;
+ break;
+ case CONTEXT_TRIGGER_LOGICAL_DISJUNCTION:
+ str = TRIG_RULE_LOGICAL_DISJUNCTION;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+std::string get_custom_item_subject(const char* provider, const char* item)
+{
+ std::string subject_name = std::string(TRIG_CUSTOM_PREFIX TRIG_SUBJECT_SEPERATOR) + provider + std::string(TRIG_SUBJECT_SEPERATOR) + item;
+ return subject_name;
+}
+
+bool event_is_deprecated(context_trigger_event_e item)
+{
+ bool ret = false;
+ switch (item) {
+ case CONTEXT_TRIGGER_EVENT_TIME:
+ case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
+ case CONTEXT_TRIGGER_EVENT_CALL:
+ case CONTEXT_TRIGGER_EVENT_EMAIL:
+ case CONTEXT_TRIGGER_EVENT_MESSAGE:
+ ret = true;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+bool condition_is_deprecated(context_trigger_condition_e item)
+{
+ bool ret = false;
+ switch (item) {
+ case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
+ case CONTEXT_TRIGGER_CONDITION_CALL:
+ case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
+ case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
+ case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
+ case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
+ ret = true;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+/*
+std::string int_to_string(int value)
+{
+ std::ostringstream ostr;
+ ostr << value;
+ return ostr.str();
+}
+
+std::string double_to_string(int value)
+{
+ std::ostringstream ostr;
+ ostr.imbue(std::locale("C"));
+ ostr << std::setprecision(DOUBLE_PRECISION) << std::fixed << value;
+ return ostr.str();
+}*/
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <context_trigger.h>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include <TimerManager.h>
+#include "rule_validator.h"
+#include "rule_util.h"
+#include "ComparisonConverter.h"
+#include "IntComparisonConverter.h"
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+static bool __handleTimerEvent(CtxJson1& event);
+static int __arrangeDayOfWeek(CtxJson1& dayInfo);
+
+int ctx::rule_util::setEvent(CtxJson1& entry, CtxJson1* rule)
+{
+ CtxJson1 tempEvent;
+ std::string subject;
+ entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &subject);
+
+ CtxJson1 option;
+ entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPTION, &option);
+ tempEvent.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+ CtxJson1 elem;
+ for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ CtxJson1 newElem;
+
+ std::string key;
+ elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+ std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+ ComparisonConverter* converter = NULL;
+ if (type == TRIG_TMPL_TYPE_INTEGER) {
+ converter = new(std::nothrow) IntComparisonConverter(elem);
+ } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+ converter = new(std::nothrow) StringComparisonConverter(elem);
+ }
+ IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+ converter->getResult(&newElem);
+
+ CtxJson1 detail;
+ newElem.get(NULL, key.c_str(), &detail);
+
+ std::string path = subject + "." + TRIG_RULE_KEY_COMPARISON;
+ tempEvent.set(path.c_str(), key.c_str(), detail);
+ delete converter;
+ }
+
+ // Handle Timer Event
+ if (subject.compare(SUBJ_STATE_ALARM) == 0) {
+ IF_FAIL_RETURN(__handleTimerEvent(tempEvent), ERR_INVALID_RULE);
+ }
+
+ rule->set(NULL, TRIG_RULE_KEY_EVENT, tempEvent);
+
+ // Save event entry's logical to extra info (default and)
+ std::string eventOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+ if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+ entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, &eventOp);
+ }
+ rule->set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, eventOp);
+
+ return ERR_NONE;
+}
+
+int ctx::rule_util::addCondition(CtxJson1& entry, CtxJson1* rule)
+{
+ CtxJson1 tempCond;
+ std::string subject;
+ entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &subject);
+
+ CtxJson1 option;
+ entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPTION, &option);
+ tempCond.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+ CtxJson1 elem;
+ for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+ CtxJson1 newElem;
+
+ std::string key;
+ elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+ std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+ ComparisonConverter* converter = NULL;
+ if (type == TRIG_TMPL_TYPE_INTEGER) {
+ converter = new(std::nothrow) IntComparisonConverter(elem);
+ } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+ converter = new(std::nothrow) StringComparisonConverter(elem);
+ }
+ IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+ converter->getResult(&newElem);
+
+ tempCond.set(subject.c_str(), TRIG_RULE_KEY_COMPARISON, newElem);
+ delete converter;
+ }
+
+ rule->append(NULL, TRIG_RULE_KEY_CONDITION, tempCond);
+
+ // Save event entry's logical to extra info (default and)
+ std::string condOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+ if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+ entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, &condOp);
+ }
+ rule->append(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, condOp);
+
+ return ERR_NONE;
+}
+
+bool __handleTimerEvent(CtxJson1& event)
+{
+ CtxJson1 alarmComp;
+ bool ret = event.get(SUBJ_STATE_ALARM, TRIG_RULE_KEY_COMPARISON, &alarmComp);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Invalid EVENT_TIME event");
+
+ // Day processing
+ CtxJson1 dayInfo;
+ bool daySpecified = alarmComp.get(NULL, KEY_DAY_OF_WEEK, &dayInfo);
+
+ if (daySpecified) {
+ CtxJson1 newDayInfo;
+ newDayInfo.set(NULL, TRIG_RULE_KEY_OPERATOR, TRIG_RULE_OP_ONE_OF);
+
+ int dow = __arrangeDayOfWeek(dayInfo);
+ IF_FAIL_RETURN_TAG(dow > 0, false, _E, "Invalid DayOfWeek info for EVENT_TIME");
+
+ for (int i = 0 ; i < DAYS_PER_WEEK; i++) {
+ int d = 0x01 << i;
+ if (dow & d) {
+ std::string day = TimerManager::dowToStr(d);
+ newDayInfo.append(NULL, TRIG_RULE_KEY_VALUE, day);
+
+ // Copy details as option
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, day);
+ }
+ }
+ event.set(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_COMPARISON, KEY_DAY_OF_WEEK, newDayInfo);
+ } else {
+ // If DayOfWeek is not specified, regard it as Mon ~ Sun
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_MON);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_TUE);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_WED);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_THU);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_FRI);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SAT);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SUN);
+ }
+
+ // Time processing
+ CtxJson1 timeInfo;
+ alarmComp.get(NULL, KEY_TIME_OF_DAY, &timeInfo);
+
+ int time;
+ std::string timeOp;
+ timeInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &timeOp);
+
+ if (timeOp == TRIG_RULE_OP_EQUAL_TO) {
+ timeInfo.get(NULL, TRIG_RULE_KEY_VALUE, &time);
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+ } else if (timeOp == TRIG_RULE_OP_ONE_OF) {
+ for (int i = 0; timeInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &time); i++) {
+ event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+ }
+ }
+
+ return true;
+}
+
+int __arrangeDayOfWeek(CtxJson1& dayInfo)
+{
+ std::string dayOp;
+ if (!dayInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &dayOp)) {
+ return TimerManager::dowToInt(DOW_EVERYDAY);
+ }
+
+ int result = 0;
+ if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO || dayOp == TRIG_RULE_OP_NOT_IN) {
+ result = TimerManager::dowToInt(DOW_EVERYDAY);
+ }
+
+ int dow;
+ std::string day;
+ if (dayOp == TRIG_RULE_OP_EQUAL_TO) {
+ dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+ dow = TimerManager::dowToInt(day);
+ result |= dow;
+ } else if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO) {
+ dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+ dow = TimerManager::dowToInt(day);
+ dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+ result &= dow;
+ } else if (dayOp == TRIG_RULE_OP_ONE_OF) {
+ for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+ dow = TimerManager::dowToInt(day);
+ result |= dow;
+ }
+ } else if (dayOp == TRIG_RULE_OP_NONE_OF) {
+ for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+ dow = TimerManager::dowToInt(day);
+ dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+ result &= dow;
+ }
+ }
+
+ _D("Requested day of week (%#x)", result);
+ return result;
+}
+
+bool ctx::rule_util::isEventSet(CtxJson1& rule)
+{
+ ctx::CtxJson1 event;
+ if (rule.get(NULL, TRIG_RULE_KEY_EVENT, &event)) {
+ if (event != EMPTY_JSON_OBJECT) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ctx::rule_util::isActionSet(CtxJson1& rule)
+{
+ ctx::CtxJson1 action;
+ if (rule.get(NULL, TRIG_RULE_KEY_ACTION, &action)) {
+ if (action != EMPTY_JSON_OBJECT) {
+ return true;
+ }
+ }
+
+ return false;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_RULE_UTIL_H__
+#define __CONTEXT_RULE_UTIL_H__
+
+#include <CtxJson1.h>
+
+namespace ctx {
+
+ namespace rule_util {
+
+ int setEvent(CtxJson1& entry, CtxJson1* rule);
+ int addCondition(CtxJson1& entry, CtxJson1* rule);
+ bool isEventSet(CtxJson1& rule);
+ bool isActionSet(CtxJson1& rule);
+
+ }
+} /* namespace ctx */
+
+#endif /* __CONTEXT_RULE_UTIL_H__ */
--- /dev/null
+/*
+ * 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 <sstream>
+#include <string>
+#include <map>
+#include <Types.h>
+#include <context_trigger.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "DBusClient.h"
+#include "TriggerOldRuleTypes.h"
+#include "rule_validator.h"
+
+using namespace ctx;
+
+#define RULE_VALIDATOR_COND_NAME "name"
+#define RULE_VALIDATOR_KEY "key"
+#define RULE_VALIDATOR_TYPE "type"
+#define RULE_VALIDATOR_REF "ref"
+
+typedef std::map<std::string, CtxJson1> template_map_t;
+template_map_t template_map; // <name, template>
+
+static int string_to_int(std::string str);
+static bool check_value_int(CtxJson1& tmpl, std::string key, int value);
+static bool check_value_string(CtxJson1& tmpl, std::string key, std::string value);
+static bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value);
+static CtxJson1 get_template(std::string name);
+static bool check_template_int(CtxJson1& elem);
+static bool check_template_string(CtxJson1& elem);
+static bool check_template_enum(CtxJson1& elem);
+static std::string get_data_type(CtxJson1& elem, std::string& key);
+static bool is_equal_type(std::string& type1, std::string& type2);
+
+int string_to_int(std::string str)
+{
+ int i;
+ std::istringstream convert(str);
+
+ if (!(convert >> i))
+ i = 0;
+
+ return i;
+}
+
+CtxJson1 get_template(std::string name)
+{
+ rule_validator::request_template(name);
+ return template_map[name];
+}
+
+int rule_validator::request_template(std::string name, bool mandatory)
+{
+ if (!mandatory) {
+ template_map_t::iterator it = template_map.find(name);
+ IF_FAIL_RETURN(it == template_map.end(), ERR_NONE);
+ }
+
+ // Request template
+ CtxJson1 request;
+ request.set(NULL, TRIG_TMPL_KEY_SUBJECT, name);
+
+ int req_id;
+ CtxJson1 tmpl;
+ DBusClient dbusClient;
+ int error = dbusClient.readSync(SUBJ_TRIGGER_GET_TEMPLATE, request, &req_id, &tmpl);
+ if (error == ERR_NOT_SUPPORTED) {
+ template_map.erase(name);
+ _E("Failed to get request: not supported");
+ return ERR_NOT_SUPPORTED;
+ }
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get request");
+
+ template_map[name] = tmpl;
+
+ return ERR_NONE;
+}
+
+void rule_validator::remove_template(std::string name)
+{
+ template_map.erase(name);
+}
+
+// called by context_trigger_rule_add_entry()
+bool rule_validator::check_option(CtxJson1& item)
+{
+ std::string name;
+ item.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ // No option needed
+ CtxJson1 opt_tmpl;
+ tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+ std::list<std::string> opt_keys;
+ IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+ if (opt_keys.size() <= 0) {
+ return true;
+ }
+
+ // Err: Check if mandatory option is missed
+ std::string val_str;
+ int val;
+ if (name == SUBJ_PLACE_GEOFENCE) {
+ if (!(item.get(OLD_TRIG_RULE_KEY_EVENT_OPTION, CONTEXT_TRIGGER_PLACE_ID, &val)))
+ return false;
+ } else if (name == SUBJ_APP_FREQUENCY) {
+ if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_APP_ID, &val_str)))
+ return false;
+ } else if (name == SUBJ_SOCIAL_FREQUENCY) {
+ if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_ADDRESS, &val_str)))
+ return false;
+ }
+
+ return true;
+}
+
+// called by context_trigger_rule_entry_add_option_int()
+bool rule_validator::check_option_int(std::string name, std::string key, int value)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ CtxJson1 opt_tmpl;
+ tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+ // Err: Item with no option
+ std::list<std::string> opt_keys;
+ IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+ IF_FAIL_RETURN(opt_keys.size() > 0, false);
+
+ // Err: Invalid option key or Invalid value type
+ std::string t_type = get_data_type(opt_tmpl, key);
+ IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
+
+ // Err: Inappropriate value
+ // a. normal case
+ bool ret = check_value_int(opt_tmpl, key, value);
+ IF_FAIL_RETURN(ret, false);
+
+ return true;
+}
+
+// called by context_trigger_rule_entry_add_option_string()
+bool rule_validator::check_option_string(std::string name, std::string key, std::string value)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ CtxJson1 opt_tmpl;
+ tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+ // Err: ';' for SQL injection
+ IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
+
+ // Err: Item with no option
+ std::list<std::string> opt_keys;
+ IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+ IF_FAIL_RETURN(opt_keys.size() > 0, false);
+
+ // Err: Invalid option key or Invalid value type
+ std::string t_type = get_data_type(opt_tmpl, key);
+ IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
+
+ // Err: Inappropriate value
+ // a. spacial case
+ if (t_type == TRIG_TMPL_TYPE_STRING && (name == SUBJ_APP_FREQUENCY || name == SUBJ_SOCIAL_FREQUENCY
+ || name == SUBJ_MUSIC_FREQUENCY || name == SUBJ_VIDEO_FREQUENCY)
+ && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
+ std::size_t found = value.find("-");
+ if (found == std::string::npos) {
+ return false;
+ }
+
+ int t1 = string_to_int(value.substr(0, found-1));
+ int t2 = string_to_int(value.substr(found+1, value.length()-1));
+
+ if (!(t1 >= 0 && t1 < 24) || !(t2 >= 0 && t2 < 24)) {
+ return false;
+ }
+
+ if (t1 >= t2) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // b. normal case
+ bool ret = false;
+ if (t_type == TRIG_TMPL_TYPE_STRING) {
+ ret = check_value_string(opt_tmpl, key, value);
+ } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
+ ret = check_value_enum(opt_tmpl, key, value);
+ }
+
+ return ret;
+}
+
+// called by context_trigger_rule_entry_add_comparison_int()
+bool rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ CtxJson1 attr_tmpl;
+ tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
+
+ // Err: Invalid attribute key or Invalid value type
+ std::string t_type = get_data_type(attr_tmpl, key);
+ IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
+
+ // Err: Invalid operator for the value
+ // a. normal case
+ bool ret = is_valid_operator(TRIG_TMPL_TYPE_INTEGER, op);
+ IF_FAIL_RETURN(ret, false);
+ // b. special case
+ if (name == SUBJ_STATE_ALARM && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
+ IF_FAIL_RETURN(op == CONTEXT_TRIGGER_EQUAL_TO, false);
+ }
+
+ // Err: Inappropriate value
+ // a. normal case
+ ret = check_value_int(attr_tmpl, key, value);
+ IF_FAIL_RETURN(ret, false);
+
+ return true;
+}
+
+// called by context_trigger_rule_entry_add_comparison_string()
+bool rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != CtxJson1(EMPTY_JSON_OBJECT), false);
+
+ CtxJson1 attr_tmpl;
+ tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
+
+ // Err: ';' for SQL injection
+ IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
+
+ // Err: Invalid option key or Invalid value type
+ std::string t_type = get_data_type(attr_tmpl, key);
+ IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
+
+ // Err: Invalid operator for the value
+ bool ret = is_valid_operator(t_type, op);
+ IF_FAIL_RETURN(ret, false);
+
+ // Err: Inappropriate value
+ // a. normal case
+ if (t_type == TRIG_TMPL_TYPE_STRING) {
+ ret = check_value_string(attr_tmpl, key, value);
+ IF_FAIL_RETURN(ret, false);
+ } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
+ ret = check_value_enum(attr_tmpl, key, value);
+ IF_FAIL_RETURN(ret, false);
+ }
+
+ return true;
+}
+
+bool rule_validator::check_valid_key(std::string type, std::string name, std::string key)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ // Err: Invalid key
+ CtxJson1 tmp;
+ bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
+ IF_FAIL_RETURN(ret, false);
+
+ return true;
+}
+
+bool check_value_int(CtxJson1& tmpl, std::string key, int value)
+{
+ int min, max;
+
+ if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MIN, &min)) {
+ IF_FAIL_RETURN(value >= min, false);
+ }
+
+ if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MAX, &max)) {
+ IF_FAIL_RETURN(value <= max, false);
+ }
+
+ return true;
+}
+
+bool check_value_string(CtxJson1& tmpl, std::string key, std::string value)
+{
+ return true;
+}
+
+bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value)
+{
+ std::string t_val;
+ for (int i = 0; tmpl.getAt(key.c_str(), TRIG_TMPL_TYPE_ENUM, i, &t_val); i++) {
+ if (t_val == value)
+ return true;
+ }
+
+ return false;
+}
+
+// called by context_trigger_rule_entry_add_comparison()
+// called by context_trigger_rule_entry_add_option()
+bool rule_validator::set_ref_info(std::string type, CtxJson1* jref, std::string name, std::string key, std::string ref_data)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+ CtxJson1 detailed_tmpl;
+ tmpl.get(NULL, type.c_str(), &detailed_tmpl);
+
+ std::string dt = get_data_type(detailed_tmpl, key);
+ IF_FAIL_RETURN(dt == TRIG_TMPL_TYPE_INTEGER || dt == TRIG_TMPL_TYPE_STRING || dt == TRIG_TMPL_TYPE_ENUM, false);
+
+ CtxJson1 temp;
+ temp.set(NULL, RULE_VALIDATOR_COND_NAME, name);
+ temp.set(NULL, RULE_VALIDATOR_KEY, key);
+ temp.set(NULL, RULE_VALIDATOR_TYPE, dt);
+ temp.set(NULL, RULE_VALIDATOR_REF, ref_data);
+
+ if (type == TRIG_TMPL_KEY_OPTION) {
+ jref->append(NULL, TRIG_TMPL_KEY_OPTION, temp);
+ } else if (type == TRIG_TMPL_KEY_ATTRIBUTE) {
+ jref->append(NULL, TRIG_TMPL_KEY_ATTRIBUTE, temp);
+ } else {
+ return false;
+ }
+
+ return true;;
+}
+
+std::string get_data_type(CtxJson1& elem, std::string& key)
+{
+ std::string data_type;
+ bool ret = elem.get(key.c_str(), TRIG_TMPL_KEY_TYPE, &data_type);
+ if (!ret) {
+ int size = elem.getSize(key.c_str(), TRIG_TMPL_TYPE_ENUM);
+ IF_FAIL_RETURN(size > 0, "");
+ data_type = TRIG_TMPL_TYPE_ENUM;
+ }
+ IF_FAIL_RETURN(data_type == TRIG_TMPL_TYPE_INTEGER || data_type == TRIG_TMPL_TYPE_STRING || data_type == TRIG_TMPL_TYPE_ENUM, "");
+
+ return data_type;
+}
+
+// called by context_trigger_rule_entry_add_comparison()
+std::string rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
+{
+ CtxJson1 tmpl = get_template(name);
+ IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, "");
+
+ CtxJson1 detailed_tmpl;
+ tmpl.get(NULL, type.c_str(), &detailed_tmpl);
+
+ return get_data_type(detailed_tmpl, key);
+}
+
+// called by context_trigger_rule_add_entry()
+bool rule_validator::check_referential_data(std::string name, CtxJson1& ref_info)
+{
+ std::map<std::string, std::string> type_map;
+
+ CtxJson1 ref_data;
+ for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_OPTION, i, &ref_data); i++) {
+ std::string ref_key;
+ ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
+ std::string cond_type;
+ ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
+
+ if (type_map.count(ref_key) == 0) {
+ type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
+ }
+
+ // Err: Invalid key or Value type not matched
+ IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
+ }
+
+ for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_ATTRIBUTE, i, &ref_data); i++) {
+ std::string ref_key;
+ ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
+ std::string cond_type;
+ ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
+
+ if (type_map.count(ref_key) == 0) {
+ type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
+ }
+
+ // Err: Invalid key or Value type not matched
+ IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
+ }
+
+ return true;
+}
+
+bool is_equal_type(std::string& type1, std::string& type2)
+{
+ // This function regards TRIG_TMPL_TYPE_ENUM as TRIG_TMPL_TYPE_STRING for referential data
+ if (type1 == type2) {
+ return true;
+ }
+
+ if ((type1 == TRIG_TMPL_TYPE_STRING || type1 == TRIG_TMPL_TYPE_ENUM) && (type2 == TRIG_TMPL_TYPE_STRING || type2 == TRIG_TMPL_TYPE_ENUM)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool rule_validator::is_valid_operator(std::string type, std::string op)
+{
+ if (op == CONTEXT_TRIGGER_EQUAL_TO || op == CONTEXT_TRIGGER_NOT_EQUAL_TO) {
+ return true;
+ }
+
+ if (type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_DOUBLE) {
+ if (op == CONTEXT_TRIGGER_GREATER_THAN || op == CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO ||
+ op == CONTEXT_TRIGGER_LESS_THAN || op == CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// For custom item template
+bool rule_validator::is_valid_template(CtxJson1& attr_template)
+{
+ IF_FAIL_RETURN_TAG(attr_template != EMPTY_JSON_OBJECT, false, _E, "Custom template: empty CtxJson1");
+
+ bool ret;
+ std::list<std::string> keys;
+ attr_template.getKeys(&keys);
+
+ for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
+ std::string key = *it;
+
+ std::string type = get_data_type(attr_template, key);
+ IF_FAIL_RETURN_TAG(type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM,
+ false, _E, "Custom template: invalid data type");
+
+ CtxJson1 elem;
+ attr_template.get(NULL, key.c_str(), &elem);
+ if (type == TRIG_TMPL_TYPE_INTEGER) {
+ ret = check_template_int(elem);
+ IF_FAIL_RETURN(ret, false);
+ } else if (type == TRIG_TMPL_TYPE_STRING) {
+ ret = check_template_string(elem);
+ IF_FAIL_RETURN(ret, false);
+ } else if (type == TRIG_TMPL_TYPE_ENUM) {
+ ret = check_template_enum(elem);
+ IF_FAIL_RETURN(ret, false);
+ }
+ }
+
+ return true;
+}
+
+bool check_template_int(CtxJson1& elem)
+{
+ std::list<std::string> elem_keys;
+ elem.getKeys(&elem_keys);
+
+ bool min = false;
+ bool max = false;
+ int min_val = 0;
+ int max_val = 0;
+
+ for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+ std::string elem_key = *it2;
+ if (elem_key == TRIG_TMPL_KEY_MIN) {
+ min = elem.get(NULL, elem_key.c_str(), &min_val);
+ IF_FAIL_RETURN_TAG(min, false, _E, "Custom template: failed to get integer type value");
+ } else if (elem_key == TRIG_TMPL_KEY_MAX) {
+ max = elem.get(NULL, elem_key.c_str(), &max_val);
+ IF_FAIL_RETURN_TAG(max, false, _E, "Custom template: failed to get integer type value");
+ } else {
+ IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+ }
+ }
+
+ if (min && max) {
+ IF_FAIL_RETURN_TAG(min_val <= max_val, false, _E, "Custom template: invalid min, max value");
+ }
+
+ return true;
+}
+
+bool check_template_string(CtxJson1& elem)
+{
+ std::list<std::string> elem_keys;
+ elem.getKeys(&elem_keys);
+
+ for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+ std::string elem_key = *it2;
+ IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+ }
+
+ return true;
+}
+
+bool check_template_enum(CtxJson1& elem)
+{
+ std::list<std::string> elem_keys;
+ elem.getKeys(&elem_keys);
+
+ for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+ std::string elem_key = *it2;
+
+ if (elem_key == TRIG_TMPL_TYPE_ENUM) {
+ int size = elem.getSize(NULL, TRIG_TMPL_TYPE_ENUM);
+ IF_FAIL_RETURN_TAG(size > 0, false, _E, "Custom template: invalid enum");
+
+ std::string val_str;
+ for (int i = 0; i < size; i++) {
+ bool ret = elem.getAt(NULL, TRIG_TMPL_TYPE_ENUM, i, &val_str);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Custom template: failed to get string type value");
+ }
+ } else {
+ IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+ }
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ * 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_VALIDATOR_H__
+#define __CONTEXT_RULE_VALIDATOR_H__
+
+#include <CtxJson1.h>
+
+namespace ctx {
+ namespace rule_validator {
+
+ int request_template(std::string name, bool mandatory = false);
+ void remove_template(std::string name);
+ bool check_option(ctx::CtxJson1 &item);
+ bool check_option_int(std::string name, std::string key, int value);
+ bool check_option_string(std::string name, std::string key, std::string value);
+ bool check_option_reference(std::string event, ctx::CtxJson1 &item);
+ bool check_comparison_int(std::string name, std::string key, std::string op, int value);
+ bool check_comparison_string(std::string name, std::string key, std::string op, std::string value);
+ bool check_valid_key(std::string type, std::string name, std::string key);
+
+ bool set_ref_info(std::string type, ctx::CtxJson1 *jref, std::string name, std::string key, std::string ref_key);
+ std::string get_data_type_from_template(std::string type, std::string name, std::string key);
+ bool check_referential_data(std::string name, ctx::CtxJson1 &ref_info);
+ bool is_valid_operator(std::string type, std::string op);
+
+ bool is_valid_template(ctx::CtxJson1& attr_template);
+ }
+} /* namespace ctx */
+
+#endif /* __CONTEXT_RULE_VALIDATOR_H__ */