{SUBJ_APP_STATS, "app-stats"},
{SUBJ_STATE_CALL, "call"},
{SUBJ_STATE_CONTACTS, "contacts"},
- // {SUBJ_CUSTOM, ""},
+ {SUBJ_CUSTOM, "custom"},
{SUBJ_STATE_EMAIL, "email"},
{SUBJ_PLACE_GEOFENCE, "geofence"},
{SUBJ_STATE_HEADPHONE, "headphone"},
"}",
NULL
},
+ {
+ SUBJ_CUSTOM,
+ OPS_SUBSCRIBE,
+ "{}",
+ NULL
+ },
{
SUBJ_STATE_EMAIL,
OPS_SUBSCRIBE,
#define SUBJ_PLACE_GEOFENCE "place/geofence"
#define SUBJ_PLACE_DETECTION PLACE_DETECTION_SUBJECT
+#define SUBJ_CUSTOM "custom"
+
/* Data & Option Keys */
#define KEY_QUERY_RESULT "QueryResult"
#define KEY_RESULT_SIZE "ResultSize"
Name: context-provider
Summary: Context Provider
-Version: 0.9.0
+Version: 0.9.1
Release: 1
Group: Service/Context
License: Apache-2.0
ADD_SUBDIRECTORY(shared)
ADD_SUBDIRECTORY(activity)
ADD_SUBDIRECTORY(app-stats)
-#ADD_SUBDIRECTORY(custom)
+ADD_SUBDIRECTORY(custom)
ADD_SUBDIRECTORY(headphone)
ADD_SUBDIRECTORY(system)
ADD_SUBDIRECTORY(time)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-# prvd_cdef, prvd_deps, and prvd_srcs need to be set properly
+SET(target "${target_prefix}-custom")
-# Common Profile
-FILE(GLOB prvd_srcs ./*.cpp)
+#SET(DEPS ${DEPS}
+#)
+
+FILE(GLOB SRCS *.cpp)
+#FILE(GLOB SRCS CreateProvider.cpp CustomManager.cpp CustomProvider.cpp)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PKG_CUSTOM REQUIRED ${DEPS})
+
+FOREACH(flag ${PKG_CUSTOM_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${PKG_CUSTOM_LDFLAGS} ${target_shared})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir})
--- /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 <CreateProvider.h>
+#include "CustomManager.h"
+
+using namespace ctx;
+
+extern "C" SO_EXPORT ContextProvider* CreateProvider(const char *subject)
+{
+ static CustomManager *__customMgr = NULL;
+
+ if (!__customMgr) {
+ __customMgr = new(std::nothrow) CustomManager;
+ IF_FAIL_RETURN_TAG(__customMgr, NULL, _E, "Memory allocation failed");
+ }
+
+ /* Request from client */
+ if (STR_EQ(SUBJ_CUSTOM, subject)) {
+ return __customMgr;
+ }
+
+ /* Request for each custom provider */
+ return __customMgr->getProvider(subject);
+}
+++ /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 <ContextManager.h>
-#include "CustomBase.h"
-
-ctx::CustomBase::CustomBase(std::string subject, std::string name, ctx::Json tmpl, std::string owner) :
- __subject(subject),
- __name(name),
- __tmpl(tmpl),
- __owner(owner)
-{
-}
-
-ctx::CustomBase::~CustomBase()
-{
-}
-
-bool ctx::CustomBase::isSupported()
-{
- return true;
-}
-
-void ctx::CustomBase::submitTriggerItem()
-{
- context_manager::registerTriggerItem(__subject.c_str(), OPS_SUBSCRIBE | OPS_READ,
- __tmpl.str(), NULL, __owner.c_str());
-}
-
-void ctx::CustomBase::unsubmitTriggerItem()
-{
- context_manager::unregisterTriggerItem(__subject.c_str());
-}
-
-int ctx::CustomBase::subscribe(const char *subject, ctx::Json option, ctx::Json *requestResult)
-{
- return ERR_NONE;
-
-}
-
-int ctx::CustomBase::unsubscribe(const char *subject, ctx::Json option)
-{
- return ERR_NONE;
-}
-
-int ctx::CustomBase::read(const char *subject, ctx::Json option, ctx::Json *requestResult)
-{
- ctx::Json data = __latest.str();
- ctx::context_manager::replyToRead(__subject.c_str(), NULL, ERR_NONE, data);
- return ERR_NONE;
-}
-
-int ctx::CustomBase::write(const char *subject, ctx::Json data, ctx::Json *requestResult)
-{
- return ERR_NONE;
-}
-
-void ctx::CustomBase::handleUpdate(ctx::Json data)
-{
- // Store latest state
- __latest = data.str();
- ctx::context_manager::publish(__subject.c_str(), NULL, ERR_NONE, data);
-}
-
-const char* ctx::CustomBase::getSubject()
-{
- return __subject.c_str();
-}
-
-std::string ctx::CustomBase::getOwner()
-{
- return __owner;
-}
-
-ctx::Json ctx::CustomBase::getTemplate()
-{
- return __tmpl;
-}
+++ /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_CUSTOM_BASE_H_
-#define _CONTEXT_CUSTOM_BASE_H_
-
-#include <Json.h>
-#include <ContextProvider.h>
-#include <Types.h>
-
-namespace ctx {
-
- class CustomBase : public ContextProvider {
- public:
- CustomBase(std::string subject, std::string name, ctx::Json tmpl, std::string owner);
- ~CustomBase();
-
- int subscribe(const char *subject, ctx::Json option, ctx::Json *requestResult);
- int unsubscribe(const char *subject, ctx::Json option);
- int read(const char *subject, ctx::Json option, ctx::Json *requestResult);
- int write(const char *subject, ctx::Json data, ctx::Json *requestResult);
-
- static bool isSupported();
- void submitTriggerItem();
- void unsubmitTriggerItem();
-
- void handleUpdate(ctx::Json data);
-
- const char* getSubject();
- std::string getOwner();
- ctx::Json getTemplate();
-
- private:
- std::string __subject;
- std::string __name;
- ctx::Json __tmpl;
- std::string __owner;
- ctx::Json __latest;
- };
-}
-
-#endif /* End of _CONTEXT_CUSTOM_BASE_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 <map>
-#include <vector>
-#include <Types.h>
-#include <ContextManager.h>
-#include <ContextProvider.h>
-#include <DatabaseManager.h>
-#include <CustomContextProvider.h>
-#include "CustomBase.h"
-
-static std::map<std::string, ctx::CustomBase*> __customMap;
-static ctx::DatabaseManager __dbManager;
-
-static bool __isValidFact(std::string subject, ctx::Json& fact);
-static bool __checkValueInt(ctx::Json& tmpl, std::string key, int value);
-static bool __checkValueString(ctx::Json& tmpl, std::string key, std::string value);
-
-void registerProvider(const char *subject, const char *privilege)
-{
- ctx::ContextProviderInfo providerInfo(ctx::custom_context_provider::create,
- ctx::custom_context_provider::destroy,
- const_cast<char*>(subject), privilege);
- ctx::context_manager::registerProvider(subject, providerInfo);
- __customMap[subject]->submitTriggerItem();
-}
-
-void unregisterProvider(const char* subject)
-{
- __customMap[subject]->unsubmitTriggerItem();
- ctx::context_manager::unregisterProvider(subject);
-}
-
-SO_EXPORT ctx::ContextProvider* ctx::custom_context_provider::create(void *data)
-{
- // Already created in addItem() function. Return corresponding custom provider
- return __customMap[static_cast<const char*>(data)];
-}
-
-SO_EXPORT void ctx::custom_context_provider::destroy(void *data)
-{
- std::map<std::string, ctx::CustomBase*>::iterator it = __customMap.find(static_cast<char*>(data));
- if (it != __customMap.end()) {
- delete it->second;
- __customMap.erase(it);
- }
-}
-
-SO_EXPORT bool ctx::initCustomContextProvider()
-{
- // Create custom template db
- std::string q = std::string("CREATE TABLE IF NOT EXISTS context_trigger_custom_template ")
- + "(subject TEXT DEFAULT '' NOT NULL PRIMARY KEY, name TEXT DEFAULT '' NOT NULL, operation INTEGER DEFAULT 3 NOT NULL, "
- + "attributes TEXT DEFAULT '' NOT NULL, owner TEXT DEFAULT '' NOT NULL)";
-
- std::vector<Json> record;
- bool ret = __dbManager.executeSync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
-
- // Register custom items
- std::string qSelect = "SELECT * FROM context_trigger_custom_template";
- ret = __dbManager.executeSync(qSelect.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates");
- IF_FAIL_RETURN(record.size() > 0, true);
-
- int error;
- std::vector<Json>::iterator vedEnd = record.end();
- for (auto vecPos = record.begin(); vecPos != vedEnd; ++vecPos) {
- ctx::Json elem = *vecPos;
- std::string subject;
- std::string name;
- std::string attributes;
- std::string owner;
- elem.get(NULL, "subject", &subject);
- elem.get(NULL, "name", &name);
- elem.get(NULL, "attributes", &attributes);
- elem.get(NULL, "owner", &owner);
-
- error = ctx::custom_context_provider::addItem(subject, name, ctx::Json(attributes), owner.c_str(), true);
- if (error != ERR_NONE) {
- _E("Failed to add custom item(%s): %#x", subject.c_str(), error);
- }
- }
-
- return true;
-}
-
-SO_EXPORT int ctx::custom_context_provider::addItem(std::string subject, std::string name, ctx::Json tmpl, const char* owner, bool isInit)
-{
- std::map<std::string, ctx::CustomBase*>::iterator it;
- it = __customMap.find(subject);
-
- if (it != __customMap.end()) {
- if ((it->second)->getTemplate() != tmpl) { // Same item name, but different template
- return ERR_DATA_EXIST;
- }
- // Same item name with same template
- return ERR_NONE;
- }
-
- // Create custom base
- ctx::CustomBase* custom = new(std::nothrow) CustomBase(subject, name, tmpl, owner);
- IF_FAIL_RETURN_TAG(custom, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
- __customMap[subject] = custom;
-
- registerProvider(custom->getSubject(), NULL);
-
- // Add item to custom template db
- if (!isInit) {
- std::string q = "INSERT OR IGNORE INTO context_trigger_custom_template (subject, name, attributes, owner) VALUES ('"
- + subject + "', '" + name + "', '" + tmpl.str() + "', '" + owner + "'); ";
- std::vector<Json> record;
- bool ret = __dbManager.executeSync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates");
- }
-
- return ERR_NONE;
-}
-
-SO_EXPORT int ctx::custom_context_provider::removeItem(std::string subject)
-{
- std::map<std::string, ctx::CustomBase*>::iterator it;
- it = __customMap.find(subject);
- IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
-
- unregisterProvider(subject.c_str());
-
- // Remove item from custom template db
- std::string q = "DELETE FROM context_trigger_custom_template WHERE subject = '" + subject + "'";
- std::vector<Json> record;
- bool ret = __dbManager.executeSync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates");
-
- return ERR_NONE;
-}
-
-SO_EXPORT int ctx::custom_context_provider::publishData(std::string subject, ctx::Json fact)
-{
- std::map<std::string, ctx::CustomBase*>::iterator it;
- it = __customMap.find(subject);
- IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
-
- bool ret = __isValidFact(subject, fact);
- IF_FAIL_RETURN_TAG(ret, ERR_INVALID_DATA, _E, "Invalid fact(%s)", subject.c_str());
-
- __customMap[subject]->handleUpdate(fact);
- return ERR_NONE;
-}
-
-bool __isValidFact(std::string subject, ctx::Json& fact)
-{
- ctx::Json tmpl = __customMap[subject]->getTemplate();
- IF_FAIL_RETURN_TAG(tmpl != EMPTY_JSON_OBJECT, false, _E, "Failed to get template");
-
- bool ret;
- std::list<std::string> keys;
- fact.getKeys(&keys);
-
- for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
- std::string key = *it;
-
- std::string type;
- tmpl.get(key.c_str(), "type", &type);
- if (type == "integer") {
- int val;
- ret = fact.get(NULL, key.c_str(), &val);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
-
- ret = __checkValueInt(tmpl, key, val);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
- } else if (type == "string") {
- std::string val_str;
- ret = fact.get(NULL, key.c_str(), &val_str);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
-
- ret = __checkValueString(tmpl, key, val_str);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
- } else {
- _E("Custom fact: invalid data type");
- return false;
- }
- }
-
- return true;
-}
-
-bool __checkValueInt(ctx::Json& tmpl, std::string key, int value)
-{
- int min, max;
-
- if (tmpl.get(key.c_str(), "min", &min)) {
- IF_FAIL_RETURN(value >= min, false);
- }
-
- if (tmpl.get(key.c_str(), "max", &max)) {
- IF_FAIL_RETURN(value <= max, false);
- }
-
- return true;
-}
-
-bool __checkValueString(ctx::Json& tmpl, std::string key, std::string value)
-{
- // case1: any value is accepted
- if (tmpl.getSize(key.c_str(), "values") <= 0)
- return true;
-
- // case2: check acceptable value
- std::string tmplValue;
- for (int i = 0; tmpl.getAt(key.c_str(), "values", i, &tmplValue); i++) {
- if (tmplValue == value)
- 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.
+ */
+
+#include <map>
+#include <Util.h>
+#include <DatabaseManager.h>
+#include "CustomManager.h"
+#include "CustomProvider.h"
+#include "CustomTypes.h"
+
+using namespace ctx;
+
+static std::map<std::string, CustomProvider*> __customMap;
+static DatabaseManager __dbManager;
+
+static bool __isValidFact(std::string subject, Json& fact);
+static bool __checkValueInt(Json& tmpl, std::string key, int value);
+static bool __checkValueString(Json& tmpl, std::string key, std::string value);
+
+CustomManager::CustomManager() :
+ BasicProvider(SUBJ_CUSTOM)
+{
+ __initialize();
+}
+
+CustomManager::~CustomManager()
+{
+ /* Custom provider instances will be deleted by Provider Handler */
+ __customMap.clear();
+}
+
+bool CustomManager::isSupported()
+{
+ return true;
+}
+
+bool CustomManager::unloadable()
+{
+ return false;
+}
+
+int CustomManager::subscribe()
+{
+ return ERR_NONE;
+}
+
+int CustomManager::unsubscribe()
+{
+ return ERR_NONE;
+}
+
+int CustomManager::write(Json data, Json *requestResult)
+{
+ int error = ERR_NONE;
+ std::string req;
+ data.get(NULL, CUSTOM_KEY_REQ, &req);
+
+ std::string packageId;
+ std::string name;
+ data.get(NULL, CUSTOM_KEY_PACKAGE_ID, &packageId);
+ data.get(NULL, CUSTOM_KEY_NAME, &name);
+ std::string subj = std::string(SUBJ_CUSTOM) + CUSTOM_SEPERATOR + packageId + CUSTOM_SEPERATOR + name;
+
+ if (req == CUSTOM_REQ_TYPE_ADD) {
+ Json tmpl;
+ data.get(NULL, CUSTOM_KEY_ATTRIBUTES, &tmpl);
+
+ error = __addCustomItem(subj, name, tmpl, packageId);
+ } else if (req == CUSTOM_REQ_TYPE_REMOVE) {
+ error = __removeCustomItem(subj);
+ if (error == ERR_NONE) {
+ requestResult->set(NULL, CUSTOM_KEY_SUBJECT, subj);
+ }
+ } else if (req == CUSTOM_REQ_TYPE_PUBLISH) {
+ Json fact;
+ data.get(NULL, CUSTOM_KEY_FACT, &fact);
+
+ error = __publishData(subj, fact);
+ }
+
+ return error;
+}
+
+ContextProvider* CustomManager::getProvider(const char* subject)
+{
+ auto it = __customMap.find(subject);
+ IF_FAIL_RETURN_TAG(it != __customMap.end(), NULL, _E, "'%s' not found", subject);
+
+ CustomProvider* custom = static_cast<CustomProvider*>(it->second);
+ return custom;
+}
+
+bool CustomManager::__initialize()
+{
+ /* Create custom template table */
+ std::vector<Json> record;
+ bool ret = __dbManager.executeSync(CUSTOM_TEMPLATE_TABLE_SCHEMA, &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
+
+ /* Register custom items */
+ std::string qSelect = "SELECT * FROM context_trigger_custom_template";
+ ret = __dbManager.executeSync(qSelect.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates");
+ IF_FAIL_RETURN(record.size() > 0, true);
+
+ int error;
+ std::vector<Json>::iterator vedEnd = record.end();
+ for (auto vecPos = record.begin(); vecPos != vedEnd; ++vecPos) {
+ Json elem = *vecPos;
+ std::string subject;
+ std::string name;
+ std::string attributes;
+ std::string owner;
+ elem.get(NULL, CUSTOM_KEY_SUBJECT, &subject);
+ elem.get(NULL, CUSTOM_KEY_NAME, &name);
+ elem.get(NULL, CUSTOM_KEY_ATTRIBUTES, &attributes);
+ elem.get(NULL, CUSTOM_KEY_OWNER, &owner);
+
+ error = __addCustomItem(subject.c_str(), name, Json(attributes), owner, true);
+ if (error != ERR_NONE) {
+ _E("Failed to add custom item(%s): %#x", subject.c_str(), error);
+ }
+ }
+
+ return true;
+}
+
+int CustomManager::__addCustomItem(std::string subject, std::string name, Json tmpl, std::string owner, bool isInit)
+{
+ std::map<std::string, CustomProvider*>::iterator it;
+ it = __customMap.find(subject);
+
+ if (it != __customMap.end()) {
+ if ((it->second)->getTemplate() != tmpl) { /* Same item name, different template */
+ return ERR_DATA_EXIST;
+ }
+
+ return ERR_NONE; /* Same item */
+ }
+
+ /* Create custom provider */
+ CustomProvider* custom = new(std::nothrow) CustomProvider(subject.c_str(), name, tmpl, owner);
+ IF_FAIL_RETURN_TAG(custom, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+ __customMap[subject] = custom;
+
+ /* Register provider handler & template */
+ registerCustomProvider(subject.c_str(), OPS_SUBSCRIBE | OPS_READ, tmpl, NULL, owner.c_str());
+
+ /* Insert item to custom template db */
+ if (!isInit) {
+ std::string q = "INSERT OR IGNORE INTO context_trigger_custom_template (subject, name, attributes, owner) VALUES ('"
+ + subject + "', '" + name + "', '" + tmpl.str() + "', '" + owner + "'); ";
+ std::vector<Json> record;
+ bool ret = __dbManager.executeSync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query custom templates");
+ }
+
+ return ERR_NONE;
+}
+
+int CustomManager::__removeCustomItem(std::string subject)
+{
+ std::map<std::string, CustomProvider*>::iterator it;
+ it = __customMap.find(subject);
+ IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
+
+ /* Unregister provider handler & template */
+ unregisterCustomProvider(subject.c_str());
+ __customMap.erase(it);
+
+ /* Delete item from custom template db */
+ std::string q = "DELETE FROM context_trigger_custom_template WHERE subject = '" + subject + "'";
+ std::vector<Json> record;
+ bool ret = __dbManager.executeSync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query custom templates");
+
+ return ERR_NONE;
+}
+
+int CustomManager::__publishData(std::string subject, Json fact)
+{
+ std::map<std::string, CustomProvider*>::iterator it;
+ it = __customMap.find(subject);
+ IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
+
+ bool ret = __isValidFact(subject, fact);
+ IF_FAIL_RETURN_TAG(ret, ERR_INVALID_DATA, _E, "Invalid fact(%s)", subject.c_str());
+
+ __customMap[subject]->handleUpdate(fact);
+ return ERR_NONE;
+}
+
+bool __isValidFact(std::string subject, Json& fact)
+{
+ Json tmpl = __customMap[subject]->getTemplate();
+ IF_FAIL_RETURN_TAG(tmpl != EMPTY_JSON_OBJECT, false, _E, "Failed to get template");
+
+ bool ret;
+ std::list<std::string> keys;
+ fact.getKeys(&keys);
+
+ for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
+ std::string key = *it;
+
+ std::string type;
+ tmpl.get(key.c_str(), "type", &type);
+ if (type == "integer") {
+ int val;
+ ret = fact.get(NULL, key.c_str(), &val);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
+
+ ret = __checkValueInt(tmpl, key, val);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
+ } else if (type == "string") {
+ std::string val_str;
+ ret = fact.get(NULL, key.c_str(), &val_str);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
+
+ ret = __checkValueString(tmpl, key, val_str);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
+ } else {
+ _E("Custom fact: invalid data type");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool __checkValueInt(Json& tmpl, std::string key, int value)
+{
+ int min, max;
+
+ if (tmpl.get(key.c_str(), "min", &min)) {
+ IF_FAIL_RETURN(value >= min, false);
+ }
+
+ if (tmpl.get(key.c_str(), "max", &max)) {
+ IF_FAIL_RETURN(value <= max, false);
+ }
+
+ return true;
+}
+
+bool __checkValueString(Json& tmpl, std::string key, std::string value)
+{
+ /* case1: any value is accepted */
+ if (tmpl.getSize(key.c_str(), "values") <= 0)
+ return true;
+
+ /* case2: check acceptable value */
+ std::string tmplValue;
+ for (int i = 0; tmpl.getAt(key.c_str(), "values", i, &tmplValue); i++) {
+ if (tmplValue == value)
+ 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_CUSTOM_MANAGER_H_
+#define _CONTEXT_CUSTOM_MANAGER_H_
+
+#include <CustomRegister.h>
+#include <BasicProvider.h>
+#include <ProviderTypes.h>
+
+namespace ctx {
+
+ class CustomManager : public BasicProvider, CustomRegister {
+ public:
+ CustomManager();
+ ~CustomManager();
+
+ int subscribe();
+ int unsubscribe();
+ int write(Json data, Json *requestResult);
+
+ bool isSupported();
+
+ bool unloadable();
+
+ ContextProvider* getProvider(const char* subject);
+
+ private:
+ bool __initialize();
+ int __addCustomItem(std::string subject, std::string name, ctx::Json tmpl, std::string owner, bool isInit = false);
+ int __removeCustomItem(std::string subject);
+ int __publishData(std::string, ctx::Json fact);
+ };
+}
+
+#endif /* End of _CONTEXT_CUSTOM_MANAGER_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 "CustomProvider.h"
+
+using namespace ctx;
+
+CustomProvider::CustomProvider(const char* subject, std::string name, Json tmpl, std::string owner) :
+ BasicProvider(subject),
+ __name(name),
+ __tmpl(tmpl),
+ __owner(owner)
+{
+}
+
+CustomProvider::~CustomProvider()
+{
+}
+
+bool CustomProvider::isSupported()
+{
+ return true;
+}
+
+bool CustomProvider::unloadable()
+{
+ return false;
+}
+
+int CustomProvider::subscribe()
+{
+ return ERR_NONE;
+
+}
+
+int CustomProvider::unsubscribe()
+{
+ return ERR_NONE;
+}
+
+int CustomProvider::read()
+{
+ Json data = __latest.str();
+
+ replyToRead(NULL, ERR_NONE, data);
+ return ERR_NONE;
+}
+
+void CustomProvider::handleUpdate(Json data)
+{
+ /* Store latest state for read request */
+ __latest = data.str();
+
+ publish(NULL, ERR_NONE, data);
+}
+
+std::string CustomProvider::getOwner()
+{
+ return __owner;
+}
+
+Json CustomProvider::getTemplate()
+{
+ return __tmpl;
+}
--- /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_CUSTOM_PROVIDER_H_
+#define _CONTEXT_CUSTOM_PROVIDER_H_
+
+#include <ProviderTypes.h>
+#include <BasicProvider.h>
+
+namespace ctx {
+
+ class CustomProvider : public BasicProvider {
+ public:
+ CustomProvider(const char* subject, std::string name, ctx::Json tmpl, std::string owner);
+ ~CustomProvider();
+
+ int subscribe();
+ int unsubscribe();
+ int read();
+
+ bool isSupported();
+
+ bool unloadable();
+
+ void handleUpdate(ctx::Json data);
+
+ std::string getOwner();
+ ctx::Json getTemplate();
+
+ private:
+ std::string __name;
+ ctx::Json __tmpl;
+ std::string __owner;
+ ctx::Json __latest;
+ };
+}
+
+#endif /* End of _CONTEXT_CUSTOM_PROVIDER_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_CUSTOM_TYPES_H_
+#define _CONTEXT_CUSTOM_TYPES_H_
+
+#include <ProviderTypes.h>
+
+#define CUSTOM_KEY_REQ "req"
+#define CUSTOM_KEY_PACKAGE_ID "packageId"
+#define CUSTOM_KEY_NAME "name"
+#define CUSTOM_KEY_ATTRIBUTES "attributes"
+#define CUSTOM_KEY_FACT "fact"
+#define CUSTOM_KEY_SUBJECT "subject"
+#define CUSTOM_KEY_OWNER "owner"
+
+#define CUSTOM_REQ_TYPE_ADD "add"
+#define CUSTOM_REQ_TYPE_REMOVE "remove"
+#define CUSTOM_REQ_TYPE_PUBLISH "publish"
+
+#define CUSTOM_SEPERATOR "/"
+
+#define MEDIA_TABLE_NAME "Log_MediaPlayback"
+
+#define CUSTOM_TEMPLATE_TABLE_SCHEMA \
+ "CREATE TABLE IF NOT EXISTS context_trigger_custom_template " \
+ "(subject TEXT DEFAULT '' NOT NULL PRIMARY KEY, name TEXT DEFAULT '' NOT NULL," \
+ " operation INTEGER DEFAULT 3 NOT NULL, attributes TEXT DEFAULT '' NOT NULL, " \
+ " owner TEXT DEFAULT '' NOT NULL)"
+
+
+#endif /* End of _CONTEXT_CUSTOM_TYPES_H_ */