This patch just imports the legacy code files.
Change-Id: I6acd7303a4792faf864ef3e77e84bff35217fe64
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(target "ctx-client")
+
+FILE(GLOB_RECURSE SRCS *.cpp)
+MESSAGE("Sources: ${SRCS}")
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${LIB_PKG_LDFLAGS})
+TARGET_LINK_LIBRARIES(${target} ctx-shared)
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
--- /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 <Types.h>
+#include <DBusTypes.h>
+#include <ScopeMutex.h>
+#include <DBusClient.h>
+
+using namespace ctx;
+
+static const gchar __introspection[] =
+ "<node>"
+ " <interface name='" DBUS_IFACE "'>"
+ " <method name='" METHOD_RESPOND "'>"
+ " <arg type='i' name='" ARG_REQID "' direction='in'/>"
+ " <arg type='s' name='" ARG_SUBJECT "' direction='in'/>"
+ " <arg type='i' name='" ARG_RESULT_ERR "' direction='in'/>"
+ " <arg type='s' name='" ARG_OUTPUT "' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+GDBusConnection *DBusClient::__connection = NULL;
+GDBusNodeInfo *DBusClient::__nodeInfo = NULL;
+std::atomic_int DBusClient::__instanceCount(0);
+std::map<std::string, IDBusClientListener*> DBusClient::__listenerMap;
+
+SO_EXPORT DBusClient::DBusClient()
+{
+ ++__instanceCount;
+}
+
+SO_EXPORT DBusClient::~DBusClient()
+{
+ if (--__instanceCount == 0)
+ __release();
+}
+
+void DBusClient::__onMethodCalled(GDBusConnection *conn, const gchar *sender,
+ const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer userData)
+{
+ IF_FAIL_VOID_TAG(STR_EQ(name, METHOD_RESPOND), _W, "Invalid method: %s", name);
+
+ gint reqId = 0;
+ const gchar *subject = NULL;
+ gint error = 0;
+ const gchar *data = NULL;
+
+ g_variant_get(param, "(i&si&s)", &reqId, &subject, &error, &data);
+ _D("[Response] ReqId: %d, Subject: %s, Error: %d", reqId, subject, error);
+ IF_FAIL_VOID_TAG(subject && data, _W, "Invalid parameter");
+
+ auto it = __listenerMap.find(subject);
+ it->second->onPublish(subject, reqId, error, data);
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+}
+
+bool DBusClient::__init()
+{
+ static GMutex mutex;
+ ScopeMutex sm(&mutex);
+
+ if (__connection)
+ return true;
+
+ GError *gerr = NULL;
+ gchar *addr = NULL;
+ GDBusInterfaceVTable vtable;
+ guint regId;
+
+ __nodeInfo = g_dbus_node_info_new_for_xml(__introspection, NULL);
+ IF_FAIL_RETURN_TAG(__nodeInfo != NULL, false, _E, "Initialization failed");
+
+ addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SESSION, NULL, &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_CATCH_TAG(addr != NULL, _E, "Getting address failed");
+ _SD("Address: %s", addr);
+
+ __connection = g_dbus_connection_new_for_address_sync(addr,
+ (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+ NULL, NULL, &gerr);
+ g_free(addr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_CATCH_TAG(__connection != NULL, _E, "Connection failed");
+
+ vtable.method_call = __onMethodCalled;
+ vtable.get_property = NULL;
+ vtable.set_property = NULL;
+
+ regId = g_dbus_connection_register_object(__connection, DBUS_PATH,
+ __nodeInfo->interfaces[0], &vtable, NULL, NULL, &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_CATCH_TAG(regId > 0, _E, "Object registration failed");
+
+ _I("DBus connection established");
+ _D("DBus name: %s", g_dbus_connection_get_unique_name(__connection));
+ return true;
+
+CATCH:
+ __release();
+ return false;
+}
+
+void DBusClient::__release()
+{
+ if (__connection) {
+ g_dbus_connection_flush_sync(__connection, NULL, NULL);
+ g_dbus_connection_close_sync(__connection, NULL, NULL);
+ g_object_unref(__connection);
+ __connection = NULL;
+ }
+
+ if (__nodeInfo) {
+ g_dbus_node_info_unref(__nodeInfo);
+ __nodeInfo = NULL;
+ }
+
+ _I("DBus connection released");
+}
+
+int DBusClient::__request(int type, int reqId, const char *subject, const char *input,
+ std::string *result, std::string *outputData)
+{
+ _D("Requesting: %d, %d, %s", type, reqId, subject);
+
+ if (input == NULL)
+ input = EMPTY_JSON_OBJECT;
+
+ GVariant *param = g_variant_new("(isiss)", type, "", reqId, subject, input);
+ IF_FAIL_RETURN_TAG(param, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ GError *err = NULL;
+ GVariant *response = g_dbus_connection_call_sync(__connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+ METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &err);
+ HANDLE_GERROR(err);
+ IF_FAIL_RETURN_TAG(response, ERR_OPERATION_FAILED, _E, "Method call failed");
+
+ gint error = ERR_OPERATION_FAILED;
+ const gchar *resultStr = NULL;
+ const gchar *dataStr = NULL;
+
+ g_variant_get(response, "(i&s&s)", &error, &resultStr, &dataStr);
+
+ if (result && resultStr)
+ *result = resultStr;
+
+ if (outputData && dataStr)
+ *outputData = dataStr;
+
+ g_variant_unref(response);
+
+ return error;
+}
+
+int DBusClient::__request(int type, int reqId, const char* subject, const char* input)
+{
+ _D("Requesting: %d, %d, %s", type, reqId, subject);
+
+ if (input == NULL)
+ input = EMPTY_JSON_OBJECT;
+
+ GVariant *param = g_variant_new("(isiss)", type, "", reqId, subject, input);
+ IF_FAIL_RETURN_TAG(param, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ GError *err = NULL;
+ g_dbus_connection_call(__connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+ METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err);
+
+ if (err) {
+ HANDLE_GERROR(err);
+ return ERR_OPERATION_FAILED;
+ }
+
+ return ERR_NONE;
+}
+
+int DBusClient::__generateReqId()
+{
+ static GMutex mutex;
+ static int reqId = 0;
+
+ ctx::ScopeMutex sm(&mutex);
+
+ /* Overflow handling */
+ if (++reqId < 0)
+ reqId = 1;
+
+ return reqId;
+}
+
+SO_EXPORT void DBusClient::addListener(std::string subject, IDBusClientListener *listener)
+{
+ _D("Registering the listener for '%s'", subject.c_str());
+
+ static GMutex mutex;
+ ctx::ScopeMutex sm(&mutex);
+
+ __listenerMap[subject] = listener;
+}
+
+SO_EXPORT int DBusClient::isSupported(std::string subject)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+
+ return __request(REQ_SUPPORT, __generateReqId(), subject.c_str(), NULL, NULL, NULL);
+}
+
+SO_EXPORT int DBusClient::subscribe(std::string subject, Json option, int *reqId, Json *result)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+ ASSERT_NOT_NULL(reqId);
+
+ *reqId = __generateReqId();
+
+ _I("[Subscribe] ReqId: %d, Subject: %s", *reqId, subject.c_str());
+
+ std::string resultStr;
+ int error = __request(REQ_SUBSCRIBE, *reqId, subject.c_str(), option.str().c_str(), &resultStr, NULL);
+
+ if (result)
+ *result = resultStr;
+
+ _D("Error: %#x", error);
+ _SD("Result: %s", resultStr.c_str());
+
+ return error;
+}
+
+SO_EXPORT int DBusClient::unsubscribe(std::string subject, int reqId)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+
+ _I("[Unsubscribe] ReqId: %d, Subject: %s", reqId, subject.c_str());
+
+ return __request(REQ_UNSUBSCRIBE, reqId, subject.c_str(), NULL, NULL, NULL);
+}
+
+SO_EXPORT int DBusClient::read(std::string subject, Json option, int *reqId, Json *result)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+ ASSERT_NOT_NULL(reqId);
+
+ *reqId = __generateReqId();
+
+ _I("[Read] ReqId: %d, Subject: %s", *reqId, subject.c_str());
+
+ std::string resultStr;
+ int error = __request(REQ_READ, *reqId, subject.c_str(), option.str().c_str(), &resultStr, NULL);
+
+ if (result)
+ *result = resultStr;
+
+ _D("Error: %#x", error);
+ _SD("Result: %s", resultStr.c_str());
+
+ return error;
+}
+
+SO_EXPORT int DBusClient::readSync(std::string subject, Json option, int *reqId, Json *outputData)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+ ASSERT_NOT_NULL(reqId);
+ ASSERT_NOT_NULL(outputData);
+
+ *reqId = __generateReqId();
+
+ _I("[ReadSync] ReqId: %d, Subject: %s", *reqId, subject.c_str());
+
+ std::string output;
+ int error = __request(REQ_READ_SYNC, *reqId, subject.c_str(), option.str().c_str(), NULL, &output);
+
+ *outputData = output;
+
+ _D("Error: %#x", error);
+ _SD("Data: %s", output.c_str());
+
+ return error;
+}
+
+SO_EXPORT int DBusClient::write(std::string subject, Json inputData)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+
+ int reqId = __generateReqId();
+
+ _I("[Write] ReqId: %d, Subject: %s", reqId, subject.c_str());
+ _SD("Data: %s", inputData.str().c_str());
+
+ int error = __request(REQ_WRITE, reqId, subject.c_str(), inputData.str().c_str());
+ _D("Error: %#x", error);
+
+ return error;
+}
+
+SO_EXPORT int DBusClient::write(std::string subject, Json inputData, Json *result)
+{
+ IF_FAIL_RETURN(__init(), ERR_OPERATION_FAILED);
+
+ int reqId = __generateReqId();
+
+ _I("[Write with reply] ReqId: %d, Subject: %s", reqId, subject.c_str());
+ _SD("Data: %s", inputData.str().c_str());
+
+ std::string resultStr;
+ int error = __request(REQ_WRITE, reqId, subject.c_str(), inputData.str().c_str(), &resultStr, NULL);
+
+ if (result)
+ *result = resultStr;
+
+ _D("Error: %#x", error);
+ _SD("Result: %s", resultStr.c_str());
+
+ return error;
+}
+
+SO_EXPORT int DBusClient::call(const char *method)
+{
+ int ret = ERR_NONE;
+ GError *err = NULL;
+
+ GVariant *response = g_dbus_connection_call_sync(__connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+ method, NULL, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &err);
+
+ if (response) {
+ g_variant_unref(response);
+ return ERR_NONE;
+ }
+
+ ret = ERR_OPERATION_FAILED;
+ if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
+ ret = ERR_PERMISSION_DENIED;
+
+ HANDLE_GERROR(err);
+ 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 <IDBusClientListener.h>
+
+using namespace ctx;
+
+IDBusClientListener::~IDBusClientListener()
+{
+}
--- /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_CONTEXT_PROVIDER_H_
+#define _CONTEXT_CONTEXT_PROVIDER_H_
+
+#include <vector>
+#include <Types.h>
+#include <Json.h>
+
+#define OPS_SUBSCRIBE 1
+#define OPS_READ 2
+#define OPS_WRITE 4
+
+namespace ctx {
+
+ class IContextManager;
+
+ class SO_EXPORT ContextProvider {
+ public:
+ virtual ~ContextProvider();
+
+ const char* getSubject();
+
+ virtual bool isSupported();
+ virtual int subscribe(Json option, Json *requestResult);
+ virtual int unsubscribe(Json option);
+ virtual int read(Json option, Json *requestResult);
+ virtual int write(Json data, Json *requestResult);
+
+ virtual void getPrivilege(std::vector<const char*> &privilege);
+
+ virtual bool unloadable();
+
+ bool publish(Json option, int error, Json dataUpdated);
+ bool replyToRead(Json option, int error, Json dataRead);
+
+ protected:
+ ContextProvider(const char *subject);
+
+ private:
+ static void __setContextManager(IContextManager *contextMgr);
+
+ static IContextManager *__contextMgr;
+
+ const char *__subject;
+
+ friend class ContextManager;
+
+ }; /* class ContextProvider */
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_CONTEXT_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_REGISTER_H_
+#define _CONTEXT_CUSTOM_REGISTER_H_
+
+#include <Types.h>
+#include <Json.h>
+
+namespace ctx {
+
+ class ICustomRegister;
+
+ class SO_EXPORT CustomRegister {
+ public:
+ virtual ~CustomRegister();
+
+ bool registerCustomProvider(const char* subject, int operation, Json attribute, Json option, const char* owner = NULL);
+ bool unregisterCustomProvider(const char* subject);
+
+ protected:
+ CustomRegister();
+
+ private:
+ static void __setCustomRegister(ICustomRegister *customRegister);
+
+ static ICustomRegister *__customRegister;
+
+ friend class ContextManager;
+
+ }; /* class CustomRegister */
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_CUSTOM_REGISTER_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.
+ */
+
+#ifndef __CONTEXT_DBUS_CLIENT_H__
+#define __CONTEXT_DBUS_CLIENT_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <string>
+#include <map>
+#include <atomic>
+#include <IDBusClientListener.h>
+
+namespace ctx {
+
+ class DBusClient {
+ public:
+ DBusClient();
+ ~DBusClient();
+
+ void addListener(std::string subject, IDBusClientListener *listener);
+
+ int isSupported(std::string subject);
+
+ int subscribe(std::string subject, Json option, int *reqId, Json *result);
+ int unsubscribe(std::string subject, int reqId);
+ int read(std::string subject, Json option, int *reqId, Json *result);
+ int readSync(std::string subject, Json option, int *reqId, Json *outputData);
+ int write(std::string subject, Json inputData);
+ int write(std::string subject, Json inputData, Json *result);
+
+ int call(const char *method);
+
+ private:
+ static void __onMethodCalled(GDBusConnection *conn, const gchar *sender,
+ const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer userData);
+
+ bool __init();
+ void __release();
+ int __request(int type, int reqId, const char *subject, const char *input,
+ std::string *result, std::string *outputData);
+ int __request(int type, int reqId, const char *subject, const char *input);
+ int __generateReqId();
+
+
+ static GDBusConnection *__connection;
+ static GDBusNodeInfo *__nodeInfo;
+ static std::atomic_int __instanceCount;
+ static std::map<std::string, IDBusClientListener*> __listenerMap;
+
+ }; /* class ctx::DBusClient */
+
+} /* namespace ctx */
+
+#endif // __CONTEXT_DBUS_CLIENT_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.
+ */
+
+#ifndef _CONTEXT_DBUS_SIGNAL_WATCHER_H_
+#define _CONTEXT_DBUS_SIGNAL_WATCHER_H_
+
+#include <sys/types.h>
+#include <gio/gio.h>
+#include <IDBusSignalListener.h>
+
+namespace ctx {
+
+ enum class DBusType {
+ SYSTEM,
+ SESSION
+ };
+
+ class DBusSignalWatcher {
+ public:
+ DBusSignalWatcher(DBusType type);
+ ~DBusSignalWatcher();
+
+ /**
+ * @brief Subscribes to signals.
+ * @param[in] sender Sensor name to match on. NULL to listen from all senders.
+ * @param[in] path Object path to match on. NULL to match on all object paths.
+ * @param[in] iface D-Bus interface name to match on. NULL to match on all interfaces.
+ * @param[in] name D-Bus signal name to match on. NULL to match on all signals.
+ * @param[in] listener Listener object to receive matching signals.
+ * @return A subscription identifier that can be used with signal_unsubscribe().
+ * If failed, a negative value.
+ */
+ int64_t watch(const char *sender, const char *path, const char *iface, const char *name, IDBusSignalListener *listener);
+ void unwatch(int64_t signal_id);
+
+ private:
+ void __openBus(GBusType type, GDBusConnection *&bus);
+ void __closeBus(GDBusConnection *&bus);
+
+ static GMutex __mutex;
+ static unsigned int __systemBusCnt;
+ static unsigned int __sessionBusCnt;
+ static GDBusConnection *__systemBus;
+ static GDBusConnection *__sessionBus;
+
+ DBusType __busType;
+ };
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_DBUS_SIGNAL_WATCHER_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.
+ */
+
+#ifndef _CONTEXT_DBUS_TYPES_H_
+#define _CONTEXT_DBUS_TYPES_H_
+
+#define DBUS_DEST "org.tizen.context"
+#define DBUS_PATH "/org/tizen/context"
+#define DBUS_IFACE "org.tizen.context"
+#define DBUS_TIMEOUT 3000
+
+#define METHOD_REQUEST "Request"
+#define METHOD_RESPOND "Respond"
+#define SIGNAL_LAUNCHED "Launched"
+
+#define METHOD_CHK_PRIV "ChkPriv"
+#define METHOD_CHK_PRIV_APPLAUNCH METHOD_CHK_PRIV "AppLaunch"
+#define METHOD_CHK_PRIV_CALL METHOD_CHK_PRIV "Call"
+#define METHOD_CHK_PRIV_NOTIFICATION METHOD_CHK_PRIV "Notification"
+
+#define ARG_REQTYPE "type"
+#define ARG_COOKIE "cookie"
+#define ARG_REQID "req_id"
+#define ARG_SUBJECT "subject"
+#define ARG_INPUT "input"
+
+#define ARG_RESULT_ERR "r_err"
+#define ARG_RESULT_ADD "r_add"
+#define ARG_OUTPUT "output"
+
+enum RequestType {
+ REQ_SUBSCRIBE = 1,
+ REQ_UNSUBSCRIBE,
+ REQ_READ,
+ REQ_READ_SYNC,
+ REQ_WRITE,
+ REQ_SUPPORT,
+};
+
+#endif /* _CONTEXT_DBUS_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.
+ */
+
+#ifndef _CONTEXT_DATABASE_MANAGER_H_
+#define _CONTEXT_DATABASE_MANAGER_H_
+
+#include <IDatabaseListener.h>
+
+namespace ctx {
+
+ class DatabaseManager {
+ public:
+ DatabaseManager();
+ ~DatabaseManager();
+
+ /**
+ * @brief Creates a table if not exists. Async.
+ * @details The column @c rowId is created by default, thus do not use the same column name.
+ * It is the primary of the auto-increment integer type.
+ * @param[in] queryId This number will be returned through IDatabaseListener::onTableCreated().
+ * @param[in] tableName A table name to be created.
+ * @param[in] columns Columns. In SQL format. INTEGER, REAL, and TEXT types are allowed.
+ * @param[in] option Additional options. Allows NULL.
+ * @param[in] listener A listener object to receive the result. Allows NULL.
+ */
+ bool createTable(unsigned int queryId, const char *tableName, const char *columns, const char *option = NULL, IDatabaseListener *listener = NULL);
+
+ /**
+ * @brief Inserts a record to a table. Async.
+ * @param[in] queryId This number will be returned through IDatabaseListener::onInserted().
+ * @param[in] tableName A table name in which the record is inserted.
+ * @param[in] record A json object containing key, value pairs.
+ * @param[in] listener A listener object to receive the result. Allows NULL.
+ */
+ bool insert(unsigned int queryId, const char *tableName, Json record, IDatabaseListener *listener = NULL);
+
+ /**
+ * @brief Executes a SQL query. Async.
+ * @param[in] queryId This number will be returned through IDatabaseListener::onExecuted().
+ * @param[in] query A query to be executed.
+ * @param[in] listener A listener object to receive the result.
+ */
+ bool execute(unsigned int queryId, const char *query, IDatabaseListener *listener = NULL);
+
+ /**
+ * @brief creates a table if not exists. Async.
+ * @param[in] tableName A table name to be created.
+ * @param[in] columns Columns. In SQL format. INTEGER, REAL, and TEXT types are allowed.
+ * @param[in] option Additional options. Allows NULL.
+ */
+ bool createTableSync(const char *tableName, const char *columns, const char *option = NULL);
+
+ /**
+ * @brief Inserts a record to a table. Sync.
+ * @attention This blocks the current thread.
+ * @param[in] tableName A table name in which the record is inserted.
+ * @param[in] record A json object containing key, value pairs.
+ * @param[out] rowId The row id of the inserted record. If fails, a negative integer.
+ */
+ bool insertSync(const char *tableName, Json record, int64_t *rowId);
+
+ /**
+ * @brief Executes a SQL query. Sync.
+ * @attention This blocks the current thread.
+ * @param[in] query A query to be executed.
+ * @param[out] records Query result.
+ */
+ bool executeSync(const char *query, std::vector<Json> *records);
+
+ private:
+ static bool __init();
+ static void __release();
+
+ friend class Server;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_DATABASE_MANAGER_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.
+ */
+
+#ifndef _CONTEXT_ERROR_TYPES_H_
+#define _CONTEXT_ERROR_TYPES_H_
+
+#include <tizen_error.h>
+
+/* Internal Error Codes
+ * Please define the necessary error codes here.
+ * Note that, these error codes must be aligned with the error enums defined in all API headers.
+ */
+#define ERR_NONE TIZEN_ERROR_NONE
+#define ERR_INVALID_PARAMETER TIZEN_ERROR_INVALID_PARAMETER
+#define ERR_INVALID_OPERATION TIZEN_ERROR_INVALID_OPERATION
+#define ERR_OUT_OF_MEMORY TIZEN_ERROR_OUT_OF_MEMORY
+#define ERR_PERMISSION_DENIED TIZEN_ERROR_PERMISSION_DENIED
+#define ERR_NOT_SUPPORTED TIZEN_ERROR_NOT_SUPPORTED
+#define ERR_NO_DATA TIZEN_ERROR_NO_DATA
+#define ERR_ALREADY_STARTED (TIZEN_ERROR_CONTEXT | 0x01)
+#define ERR_NOT_STARTED (TIZEN_ERROR_CONTEXT | 0x02)
+#define ERR_OUT_OF_RANGE (TIZEN_ERROR_CONTEXT | 0x03)
+#define ERR_OPERATION_FAILED (TIZEN_ERROR_CONTEXT | 0x04)
+#define ERR_RULE_ENABLED (TIZEN_ERROR_CONTEXT | 0x05)
+#define ERR_RULE_NOT_ENABLED (TIZEN_ERROR_CONTEXT | 0x06)
+#define ERR_INVALID_RULE (TIZEN_ERROR_CONTEXT | 0x07)
+#define ERR_RULE_NOT_EXIST (TIZEN_ERROR_CONTEXT | 0x08)
+#define ERR_DATA_EXIST (TIZEN_ERROR_CONTEXT | 0X09)
+#define ERR_INVALID_DATA (TIZEN_ERROR_CONTEXT | 0X0a)
+
+#endif /* _CONTEXT_ERROR_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.
+ */
+
+#ifndef _EVENT_DRIVEN_THREAD_H_
+#define _EVENT_DRIVEN_THREAD_H_
+
+#include <glib.h>
+#include <Types.h>
+
+class SO_EXPORT EventDrivenThread {
+
+ typedef struct thread_info_s* thread_info_t;
+
+public:
+ virtual ~EventDrivenThread();
+
+ bool start();
+ bool stop();
+ bool isRunning();
+
+protected:
+ EventDrivenThread();
+
+ virtual void onEvent(int type, void* data) = 0;
+
+ bool pushEvent(int type, void* data);
+
+private:
+ static gpointer __threadFunc(gpointer data);
+
+ void __run();
+
+ thread_info_t __threadInfo;
+
+}; /* class EventDrivenThread */
+
+#endif /* _EVENT_DRIVEN_THREAD_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.
+ */
+
+#ifndef _CONTEXT_I_CONTEXT_MANAGER_H_
+#define _CONTEXT_I_CONTEXT_MANAGER_H_
+
+#include <Types.h>
+#include <Json.h>
+
+namespace ctx {
+
+ class ContextProvider;
+
+ class SO_EXPORT IContextManager {
+ public:
+ virtual ~IContextManager();
+
+ virtual bool publish(const char *subject, Json &option, int error, Json &dataUpdated) = 0;
+ virtual bool replyToRead(const char *subject, Json &option, int error, Json &dataRead) = 0;
+ }; /* class IContextManager */
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_I_CONTEXT_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.
+ */
+
+#ifndef _CONTEXT_I_CUSTOM_REGISTER_H_
+#define _CONTEXT_I_CUSTOM_REGISTER_H_
+
+#include <Types.h>
+#include <Json.h>
+
+namespace ctx {
+
+ class CustomRegister;
+
+ class SO_EXPORT ICustomRegister {
+ public:
+ virtual ~ICustomRegister(){};
+
+ virtual bool registerCustomProvider(const char *subject, int operation, Json &attribute, Json &option, const char* owner = NULL) = 0;
+ virtual bool unregisterCustomProvider(const char *subject) = 0;
+ }; /* class ICustomRegister */
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_I_CUSTOM_REGISTER_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.
+ */
+
+#ifndef _CONTEXT_I_DBUS_CLIENT_LISTENER_H_
+#define _CONTEXT_I_DBUS_CLIENT_LISTENER_H_
+
+#ifndef SO_EXPORT
+#define SO_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+#include <string>
+#include <Json.h>
+
+namespace ctx {
+
+ class SO_EXPORT IDBusClientListener {
+ public:
+ virtual ~IDBusClientListener();
+ virtual void onPublish(std::string subject, int reqId, int error, Json event) = 0;
+ };
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_I_DBUS_CLIENT_LISTENER_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.
+ */
+
+#ifndef _CONTEXT_I_DBUS_SIGNAL_LISTENER_H_
+#define _CONTEXT_I_DBUS_SIGNAL_LISTENER_H_
+
+#include <glib.h>
+#include <Types.h>
+
+namespace ctx {
+
+ class SO_EXPORT IDBusSignalListener {
+ public:
+ virtual ~IDBusSignalListener();
+
+ /**
+ * @brief Called when receiving a signal.
+ * @param[in] sender The unique bus name of the sender of the signal.
+ * @param[in] path The object path that the signal was emitted on.
+ * @param[in] iface The name of the interface.
+ * @param[in] name The name of the signal.
+ * @param[in] param A GVariant tuple with parameters of the signal.
+ */
+ virtual void onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param) = 0;
+ };
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_I_DBUS_SIGNAL_LISTENER_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.
+ */
+
+#ifndef _CONTEXT_I_DATABASE_LISTENER_H_
+#define _CONTEXT_I_DATABASE_LISTENER_H_
+
+#include <vector>
+#include <Json.h>
+#include <Types.h>
+
+namespace ctx {
+
+ class SO_EXPORT IDatabaseListener {
+ public:
+ virtual ~IDatabaseListener();
+
+ /**
+ * @brief Called when a table creation is done.
+ * @param[in] queryId The query id passed through ctx::DatabaseManager::createTable().
+ * @param[in] error Error code. If success, 0. Otherwise, a negative value.
+ */
+ virtual void onTableCreated(unsigned int queryId, int error) = 0;
+
+ /**
+ * @brief Called when a record insertion is done.
+ * @param[in] queryId The query id passed through ctx::DatabaseManager::insert().
+ * @param[in] error Error code. If success, 0. Otherwise, a negative value.
+ * @param[in] rowId The row id of the inserted record.
+ */
+ virtual void onInserted(unsigned int queryId, int error, int64_t rowId) = 0;
+
+ /**
+ * @brief Called when a query execution is done.
+ * @param[in] queryId The query id passed through ctx::DatabaseManager::execute().
+ * @param[in] error Error code. If success, 0. Otherwise, a negative value.
+ * @param[in] records Data records retreived.
+ */
+ virtual void onExecuted(unsigned int queryId, int error, std::vector<Json>& records) = 0;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_I_DATABASE_LISTENER_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.
+ */
+
+#ifndef _CONTEXT_I_TIMER_LISTENER_H_
+#define _CONTEXT_I_TIMER_LISTENER_H_
+
+#include <Types.h>
+
+namespace ctx {
+
+ class SO_EXPORT ITimerListener {
+ public:
+ virtual ~ITimerListener();
+
+ /**
+ * @brief Called when a timer is expired.
+ * @param[in] timer_id The expired timers' ID
+ * @return @c true, if the timer needs to be repeated.@n
+ * @c false, if the timer does not need to be repeated anymore.
+ */
+ virtual bool onTimerExpired(int timerId) = 0;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_I_TIMER_LISTENER_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.
+ */
+
+#ifndef _CONTEXT_JSON_H_
+#define _CONTEXT_JSON_H_
+
+#include <sys/types.h>
+#include <glib.h>
+#include <string>
+#include <list>
+
+#define _J(cmt, jobj) \
+do { \
+ _SD("%s: %s", (cmt), jobj.str().c_str()); \
+} while (0)
+
+#define EMPTY_JSON_OBJECT "{}"
+
+namespace ctx {
+
+ class Json {
+ public:
+ Json();
+ Json(const char *s);
+ Json(const std::string &s);
+
+ /* This Json(const Json &j) only copies the reference to the underlying Json node.
+ * Therefore, changes applied to a Json object affect the other.
+ * If you need to create a 'real' copy of a Json, which can be manipulated separately,
+ * utilize the str() function, e.g., ctx::Json copy(original.str());
+ */
+ Json(const Json &j);
+
+ ~Json();
+
+ Json& operator=(const char *s);
+ Json& operator=(const std::string &s);
+
+ /* This operator=(const Json &j) only copies the reference to the underlying Json node.
+ * Therefore, changes applied to a Json object affect the other.
+ * If you need to create a 'real' copy of a Json, which can be manipulated separately,
+ * utilize the str() function, e.g., ctx::Json copy = original.str();
+ */
+ Json& operator=(const Json &j);
+
+ bool operator==(const Json &rhs);
+ bool operator!=(const Json &rhs);
+
+ std::string str();
+
+ bool getKeys(std::list<std::string> *list);
+ bool valid();
+
+ bool set(const char *path, const char *key, Json &val);
+ bool set(const char *path, const char *key, int val);
+ bool set(const char *path, const char *key, int64_t val);
+ bool set(const char *path, const char *key, double val);
+ bool set(const char *path, const char *key, std::string val);
+ bool set(const char *path, const char *key, GVariant *val);
+
+ bool get(const char *path, const char *key, Json *val);
+ bool get(const char *path, const char *key, int *val);
+ bool get(const char *path, const char *key, int64_t *val);
+ bool get(const char *path, const char *key, double *val);
+ bool get(const char *path, const char *key, std::string *val);
+ bool get(const char *path, const char *key, GVariant **val);
+
+ bool remove(const char *path, const char *key);
+
+ /* Array operations */
+ int getSize(const char *path, const char *key);
+
+ bool append(const char *path, const char *key, Json &val);
+ bool append(const char *path, const char *key, int val);
+ bool append(const char *path, const char *key, int64_t val);
+ bool append(const char *path, const char *key, double val);
+ bool append(const char *path, const char *key, std::string val);
+
+ bool setAt(const char *path, const char *key, int index, Json &val);
+ bool setAt(const char *path, const char *key, int index, int val);
+ bool setAt(const char *path, const char *key, int index, int64_t val);
+ bool setAt(const char *path, const char *key, int index, double val);
+ bool setAt(const char *path, const char *key, int index, std::string val);
+
+ bool getAt(const char *path, const char *key, int index, Json *val);
+ bool getAt(const char *path, const char *key, int index, int *val);
+ bool getAt(const char *path, const char *key, int index, int64_t *val);
+ bool getAt(const char *path, const char *key, int index, double *val);
+ bool getAt(const char *path, const char *key, int index, std::string *val);
+
+ private:
+ typedef struct _JsonNode json_node_t;
+ json_node_t *__jsonNode;
+
+ void __parse(const char *s);
+ void __release();
+ char* __strDup();
+
+ /* For json vs json comparison */
+ bool __getMembers(json_node_t *node, std::list<std::string> &list);
+ bool __nodeEq(json_node_t *lhs, json_node_t *rhs);
+ bool __valueEq(json_node_t *lhs, json_node_t *rhs);
+ bool __objectEq(json_node_t *lhs, json_node_t *rhs);
+ bool __arrayEq(json_node_t *lhs, json_node_t *rhs);
+ };
+
+} /* namespace ctx */
+
+#endif // _CONTEXT_JSON_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_MYPLACE_TYPES_H_
+#define _CONTEXT_MYPLACE_TYPES_H_
+
+#include <string>
+#include <map>
+#include <ctime>
+#include <ProviderTypes.h>
+
+#define PLACE_DETECTION_SUBJECT SUBJ_PLACE_DETECTION
+
+#define PLACE_DETECTION_REQUEST "Request"
+#define PLACE_DETECTION_REQUEST_CONSENT "UserConsent"
+#define PLACE_DETECTION_REQUEST_LIST "PlacesList"
+
+#define MYPLACE_SETTING_VALUE_TRUE "true"
+#define MYPLACE_SETTING_VALUE_FALSE "false"
+
+#define PLACE_DATA_READ "PlacesList"
+#define PLACE_CATEG_ID "CategId"
+#define PLACE_CATEG_CONFIDENCE "CategConfidence"
+#define PLACE_NAME "Name"
+#define PLACE_LOCATION "Location"
+#define PLACE_LOCATION_LATITUDE "Latitude"
+#define PLACE_LOCATION_LONGITUDE "Longitude"
+#define PLACE_LOCATION_ACCURACY "Accuracy"
+#define PLACE_WIFI_APS "WifiAPs"
+#define PLACE_WIFI_AP_MAC "Mac"
+#define PLACE_WIFI_AP_NETWORK_NAME "Network"
+#define PLACE_CREATE_DATE "CreateDate"
+
+namespace ctx {
+
+ enum PlaceCategId {
+ PLACE_CATEG_ID_NONE = 0,
+ PLACE_CATEG_ID_HOME = 1,
+ PLACE_CATEG_ID_WORK = 2,
+ PLACE_CATEG_ID_OTHER = 3
+ };
+
+ struct Location {
+ double latitude;
+ double longitude;
+ double accuracy; // [m]
+
+ Location(double latitude_ = 0.0, double longitude_ = 0.0, double accuracy_ = -1.0)
+ : latitude(latitude_), longitude(longitude_), accuracy(accuracy_) {}
+
+ }; /* struct Location */
+
+ typedef float confidence_t;
+
+ class Place {
+
+ public:
+ PlaceCategId categId; // category of a place (work/home/other)
+ confidence_t categConfidence; // confidence of the above category - between [0,1]
+ std::string name; // for now: "work"/"home"/"other"
+ bool locationValid;
+ Location location; // makes sense if locationValid == true;
+ std::map<std::string, std::string> wifiAps; // WiFi APs MAC addresses to corresponding network name map
+ time_t createDate; // The last update time of this place
+
+ }; /* class Place */
+
+ bool operator==(const Place &p1, const Place &p2);
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_MYPLACE_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.
+ */
+
+#ifndef _CONTEXT_PROVIDER_TYPES_H_
+#define _CONTEXT_PROVIDER_TYPES_H_
+
+/* Privileges */
+#define PRIV_ALARM "alarm.set"
+#define PRIV_NETWORK "network.get"
+#define PRIV_TELEPHONY "telephony"
+#define PRIV_MESSAGE "message.read"
+#define PRIV_CONTACT "contact.read"
+#define PRIV_LOCATION "location"
+#define PRIV_APP_HISTORY "apphistory.read"
+#define PRIV_MEDIA_HISTORY "mediahistory.read"
+#define PRIV_CALL_HISTORY "callhistory.read"
+
+
+/* FW-wide Data Logger Parameters */
+#define LOG_RETENTION_PERIOD 7776000 /* 90 days in secs */
+
+
+/* FW-wide Default Values */
+#define DEFAULT_TIME_SPAN 30
+#define DEFAULT_LIMIT 10
+
+
+/* Subjects */
+/* TODO: Cleanup the below namings */
+#define SUBJ_STATE_BATTERY "system/battery"
+#define SUBJ_STATE_CHARGER "system/charger"
+#define SUBJ_STATE_HEADPHONE "system/headphone"
+#define SUBJ_STATE_WIFI "system/wifi"
+#define SUBJ_STATE_USB "system/usb"
+#define SUBJ_STATE_GPS "system/gps"
+#define SUBJ_STATE_PSMODE "system/psmode"
+#define SUBJ_STATE_ALARM "device/alarm"
+#define SUBJ_STATE_TIME "device/time"
+
+#define SUBJ_STATE_CALL "social/call"
+#define SUBJ_STATE_EMAIL "social/email"
+#define SUBJ_STATE_MESSAGE "social/message"
+#define SUBJ_STATE_CONTACTS "social/contacts"
+
+#define SUBJ_ACTIVITY "activity/"
+#define SUBJ_ACTIVITY_IN_VEHICLE SUBJ_ACTIVITY "in_vehicle"
+#define SUBJ_ACTIVITY_RUNNING SUBJ_ACTIVITY "running"
+#define SUBJ_ACTIVITY_STATIONARY SUBJ_ACTIVITY "stationary"
+#define SUBJ_ACTIVITY_WALKING SUBJ_ACTIVITY "walking"
+
+#define SUBJ_APP_STATS "stats/app/"
+#define SUBJ_APP_LOGGER SUBJ_APP_STATS "logger"
+#define SUBJ_APP_RECENTLY_USED SUBJ_APP_STATS "recently"
+#define SUBJ_APP_FREQUENTLY_USED SUBJ_APP_STATS "often"
+#define SUBJ_APP_RARELY_USED SUBJ_APP_STATS "rarely"
+#define SUBJ_APP_PEAK_TIME SUBJ_APP_STATS "peak_time"
+#define SUBJ_APP_COMMON_SETTING SUBJ_APP_STATS "setting"
+#define SUBJ_APP_FREQUENCY SUBJ_APP_STATS "frequency"
+
+#define SUBJ_BATTERY_STATS "stats/battery/"
+#define SUBJ_BATTERY_LOGGER SUBJ_BATTERY_STATS "logger"
+#define SUBJ_BATTERY_USAGE SUBJ_BATTERY_STATS "history"
+#define SUBJ_BATTERY_RECENT_USAGE SUBJ_BATTERY_STATS "since_last_charge"
+
+#define SUBJ_MEDIA_LOGGER "stats/media/logger"
+#define SUBJ_MUSIC_STATS "stats/music/"
+#define SUBJ_MUSIC_PEAK_TIME SUBJ_MUSIC_STATS "peak_time"
+#define SUBJ_MUSIC_COMMON_SETTING SUBJ_MUSIC_STATS "setting"
+#define SUBJ_MUSIC_FREQUENCY SUBJ_MUSIC_STATS "frequency"
+#define SUBJ_VIDEO_STATS "stats/video/"
+#define SUBJ_VIDEO_PEAK_TIME SUBJ_VIDEO_STATS "peak_time"
+#define SUBJ_VIDEO_COMMON_SETTING SUBJ_VIDEO_STATS "setting"
+#define SUBJ_VIDEO_FREQUENCY SUBJ_VIDEO_STATS "frequency"
+
+#define SUBJ_SOCIAL_STATS "stats/contact/"
+#define SUBJ_SOCIAL_FREQ_ADDRESS SUBJ_SOCIAL_STATS "often"
+#define SUBJ_SOCIAL_FREQUENCY SUBJ_SOCIAL_STATS "frequency"
+
+#define SUBJ_PLACE_GEOFENCE "place/geofence"
+#define SUBJ_PLACE_DETECTION "place/myplace"
+
+#define SUBJ_CUSTOM "custom"
+
+/* Data & Option Keys */
+#define KEY_CLIENT_PKG_ID "_ClientPkgId_" /* Special key for internal use */
+#define KEY_QUERY_RESULT "QueryResult"
+#define KEY_RESULT_SIZE "ResultSize"
+#define KEY_COL_ROW_ID "rowId"
+#define KEY_TIME_SPAN "TimeSpan"
+#define KEY_START_TIME "StartTime"
+#define KEY_END_TIME "EndTime"
+#define KEY_LAST_TIME "LastTime"
+#define KEY_TOTAL_COUNT "TotalCount"
+#define KEY_TOTAL_AMOUNT "TotalAmount"
+#define KEY_AVERAGE_COUNT "AvgCount"
+#define KEY_DURATION "Duration"
+#define KEY_TOTAL_DURATION "TotalDuration"
+#define KEY_DAY_OF_WEEK "DayOfWeek"
+#define KEY_HOUR_OF_DAY "HourOfDay"
+#define KEY_TIME_OF_DAY "TimeOfDay"
+#define KEY_TOTAL_COUNT "TotalCount"
+#define KEY_APP_ID "AppId"
+#define KEY_PKG_ID "PkgId"
+#define KEY_AUDIO_JACK "AudioJack"
+#define KEY_SYSTEM_VOLUME "SystemVolume"
+#define KEY_MEDIA_VOLUME "MediaVolume"
+#define KEY_BSSID "BSSID"
+#define KEY_UNIV_TIME "UTC"
+#define KEY_LOCAL_TIME "LocalTime"
+#define KEY_RANK "Rank"
+#define KEY_COMMUNICATION_TYPE "CommunicationType"
+#define KEY_USED_TIME "UsedTime"
+
+#define KEY_EVENT "Event"
+#define KEY_STATE "State"
+#define KEY_TYPE "Type"
+#define KEY_LEVEL "Level"
+#define KEY_ACCURACY "Accuracy"
+#define KEY_BSSID "BSSID"
+#define KEY_MEDIUM "Medium"
+#define KEY_ADDRESS "Address"
+#define KEY_IS_CONNECTED "IsConnected"
+#define KEY_IS_ENABLED "IsEnabled"
+#define KEY_IS_CHARGING "IsCharging"
+#define KEY_DETECTED "Detected"
+#define KEY_DAY_OF_MONTH "DayOfMonth"
+#define KEY_PLACE_ID "PlaceId"
+
+
+/* Data & Option Values */
+#define VAL_TRUE 1
+#define VAL_FALSE 0
+#define VAL_ENTER "Enter"
+#define VAL_EXIT "Exit"
+#define VAL_DISABLED "Disabled"
+#define VAL_CONNECTED "Connected"
+#define VAL_UNCONNECTED "Unconnected"
+#define VAL_SEARCHING "Searching"
+#define VAL_EMPTY "Empty"
+#define VAL_CRITICAL "Critical"
+#define VAL_LOW "Low"
+#define VAL_NORMAL "Normal"
+#define VAL_HIGH "High"
+#define VAL_FULL "Full"
+#define VAL_HEADSET "Headset"
+#define VAL_BLUETOOTH "Bluetooth"
+#define VAL_IDLE "Idle"
+#define VAL_CONNECTING "Connecting"
+#define VAL_CONNECTED "Connected"
+#define VAL_HELD "Held"
+#define VAL_DIALING "Dialing"
+#define VAL_VOICE "Voice"
+#define VAL_VIDEO "Video"
+#define VAL_SENT "Sent"
+#define VAL_RECEIVED "Received"
+#define VAL_SMS "SMS"
+#define VAL_MMS "MMS"
+#define VAL_MY_PROFILE "MyProfile"
+#define VAL_PERSON "Person"
+#define VAL_CHANGED "Changed"
+#define VAL_DETECTED "Detected"
+#define VAL_UNCERTAIN "Uncertain"
+#define VAL_IN "In"
+#define VAL_OUT "Out"
+
+#define VAL_ACTIVE VAL_CONNECTED
+#define VAL_ALERTING VAL_CONNECTING
+#define VAL_INCOMING VAL_CONNECTING
+
+
+#endif /* _CONTEXT_PROVIDER_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.
+ */
+
+#ifndef _CONTEXT_SCOPE_MUTEX_H_
+#define _CONTEXT_SCOPE_MUTEX_H_
+
+#include <glib.h>
+
+namespace ctx {
+
+ class ScopeMutex {
+ private:
+ GMutex *__mutex;
+
+ public:
+ ScopeMutex(GMutex *m);
+ ~ScopeMutex();
+ };
+
+} /* namespace ctx */
+
+#endif // _CONTEXT_SCOPE_MUTEX_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_SENSOR_RECORDER_TYPES_H__
+#define __CONTEXT_SENSOR_RECORDER_TYPES_H__
+
+#include <ProviderTypes.h>
+
+/* Sensor Subjects */
+#define SUBJ_SENSOR "sensor/"
+#define SUBJ_SENSOR_HEART_RATE SUBJ_SENSOR "heart_rate"
+#define SUBJ_SENSOR_PEDOMETER SUBJ_SENSOR "pedometer"
+#define SUBJ_SENSOR_SLEEP_MONITOR SUBJ_SENSOR "sleep_monitor"
+#define SUBJ_SENSOR_PRESSURE SUBJ_SENSOR "pressure"
+#define SUBJ_SENSOR_EXERCISE SUBJ_SENSOR "exercise"
+
+/* Keys */
+#define KEY_SUBJECT "Subject"
+#define KEY_OPERATION "Operation"
+#define KEY_OPTION "Option"
+
+#define KEY_RETENTION "Retention"
+#define KEY_INTERVAL "Interval"
+#define KEY_ANCHOR "Anchor"
+
+#define KEY_STEPS "Steps"
+#define KEY_WALK_STEPS "WalkSteps"
+#define KEY_RUN_STEPS "RunSteps"
+#define KEY_DISTANCE "Dist"
+#define KEY_CALORIES "Cal"
+#define KEY_PRESSURE "Pressure"
+#define KEY_AVG_PRESSURE "AvgPressure"
+#define KEY_MIN_PRESSURE "MinPressure"
+#define KEY_MAX_PRESSURE "MaxPressure"
+#define KEY_SLEEP_STATE KEY_STATE
+#define KEY_HEART_RATE "HeartRate"
+
+/* Values */
+#define VAL_START "Start"
+#define VAL_STOP "Stop"
+
+#endif /* __CONTEXT_SENSOR_RECORDER_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.
+ */
+
+#ifndef _CONTEXT_SHARED_VARS_H_
+#define _CONTEXT_SHARED_VARS_H_
+
+#include <glib.h>
+#include <string>
+#include <map>
+
+namespace ctx {
+
+ /*
+ * TODO: Maybe later, it would be possible to extend this to support a sort of
+ * 'update observation' feature, i.e., getting notifications when a variable is updated.
+ */
+ class SharedVars {
+ public:
+ enum VarId {
+ WIFI_BSSID,
+ };
+
+ SharedVars();
+ ~SharedVars();
+
+ const std::string& set(VarId id, std::string value) const;
+ std::string get(VarId id);
+ void clear(VarId id);
+
+ private:
+ static GMutex __mutex;
+ static std::map<VarId, std::string> __varsMap;
+ };
+
+}
+
+#endif
--- /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_TIMER_H_
+#define _CONTEXT_TIMER_H_
+
+#include <glib.h>
+#include <string>
+#include <set>
+#include <map>
+#include <ITimerListener.h>
+
+#define DAYS_PER_WEEK 7
+#define DOW_MON "Mon"
+#define DOW_TUE "Tue"
+#define DOW_WED "Wed"
+#define DOW_THU "Thu"
+#define DOW_FRI "Fri"
+#define DOW_SAT "Sat"
+#define DOW_SUN "Sun"
+#define DOW_WEEKDAY "Weekday"
+#define DOW_WEEKEND "Weekend"
+#define DOW_EVERYDAY "Everyday"
+
+namespace ctx {
+
+ enum class DayOfWeek {
+ SUN = 0x01,
+ MON = 0x02,
+ TUE = 0x04,
+ WED = 0x08,
+ THU = 0x10,
+ FRI = 0x20,
+ SAT = 0x40,
+ WEEKDAY = MON | TUE | WED | THU | FRI,
+ WEEKEND = SAT | SUN,
+ EVERYDAY = SUN | MON | TUE | WED | THU | FRI | SAT
+ };
+
+ class TimerManager {
+ public:
+ TimerManager();
+ ~TimerManager();
+
+ static std::string dowToStr(int dow);
+ static int dowToInt(std::string dow);
+
+ /**
+ * @brief Sets a repeated timer for a given interval of time (s).
+ * @details It is recommended to minize the number of timers initiated, to reduce battery consumptions.
+ * If it is possible to share a timer for multiple purposes, please do that.
+ * @param[in] interval Timer interval. The first timer will be expired after @c interval minutes,
+ * and will be repeated until the listener returns @c false.
+ * @param[in] listener A listner object to be notified.
+ * @return Timer ID. A negative integer if failed to set a timer.
+ */
+ int setFor(int interval, ITimerListener *listener);
+
+ /**
+ * @brief Sets a timer that will be expired at a specific time, at designated days of week.
+ * @details It is recommended to minize the number of timers initiated, to reduce battery consumptions.
+ * If it is possible to share a timer for multiple purposes, please do that.
+ * @param[in] hour Hour
+ * @param[in] min Minute
+ * @param[in] dow The timer will expire at hour:min:00, at every day(s) of week designated here.
+ * @param[in] listener Listener object.
+ * @return Timer ID. A negative integer if failed to set a timer.
+ */
+ int setAt(int hour, int min, DayOfWeek dow, ITimerListener *listener);
+
+ /**
+ * @brief Removes the timer specified by @c timerId.
+ */
+ void remove(int timerId);
+
+ private:
+ static int __onAlarmExpired(int alarmId, void *userdata);
+
+ bool __init();
+ void __release();
+ void __remove(int timerId);
+
+ static unsigned int __instanceCnt;
+ static GMutex __mutex;
+ static std::map<int, std::pair<ITimerListener*, TimerManager*>> __listenerMap;
+
+ std::set<int> __alarms;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_TIMER_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_RULE_TYPES_H_
+#define _CONTEXT_TRIGGER_RULE_TYPES_H_
+
+#include <ProviderTypes.h>
+
+#define TRIG_RULE_REF_KEY_PREFIX "?"
+
+/* Rule Key */
+#define TRIG_RULE_KEY_DESCRIPTION "description"
+#define TRIG_RULE_KEY_EVENT "event"
+#define TRIG_RULE_KEY_CONDITION "condition"
+#define TRIG_RULE_KEY_ACTION "action"
+#define TRIG_RULE_KEY_OPTION "option"
+#define TRIG_RULE_KEY_COMPARISON "comparison"
+#define TRIG_RULE_KEY_OPERATOR "operator"
+#define TRIG_RULE_KEY_VALUE "value"
+#define TRIG_RULE_KEY_APP_LAUNCH "appLaunch"
+#define TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL "appControl"
+#define TRIG_RULE_KEY_NOTIFICATION "notification"
+#define TRIG_RULE_KEY_NOTI_TITLE "title"
+#define TRIG_RULE_KEY_NOTI_CONTENT "content"
+#define TRIG_RULE_KEY_NOTI_ICON_PATH "iconPath"
+#define TRIG_RULE_KEY_NOTI_APP_CONTROL "appControl"
+#define TRIG_RULE_KEY_DBUS_CALL "dbusCall"
+#define TRIG_RULE_KEY_DBUS_NAME "name"
+#define TRIG_RULE_KEY_DBUS_OBJECT "object"
+#define TRIG_RULE_KEY_DBUS_INTERFACE "interafce"
+#define TRIG_RULE_KEY_DBUS_METHOD "method"
+#define TRIG_RULE_KEY_DBUS_PARAMETER "parameter"
+
+/* Internal Rule Key */
+#define _TRIG_RULE_KEY_EXTRA "_extra"
+#define _TRIG_RULE_KEY_RULE_LOGICAL_OP "_ruleOp"
+#define _TRIG_RULE_KEY_EVENT_LOGICAL_OP "_eventOp"
+#define _TRIG_RULE_KEY_CONDITION_LOGICAL_OP "_condOp"
+
+/* Comparison Operator */
+#define TRIG_RULE_OP_EQUAL_TO "=="
+#define TRIG_RULE_OP_NOT_EQUAL_TO "!="
+#define TRIG_RULE_OP_GREATER_THAN ">"
+#define TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO ">="
+#define TRIG_RULE_OP_LESS_THAN "<"
+#define TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO "<="
+#define TRIG_RULE_OP_ONE_OF "oneOf"
+#define TRIG_RULE_OP_NONE_OF "noneOf"
+#define TRIG_RULE_OP_IN "in"
+#define TRIG_RULE_OP_NOT_IN "notIn"
+//#define TRIG_RULE_OP_CONTAIN "contain"
+
+/* Old Rule Keys */
+#define TRIG_RULE_LOGICAL_CONJUNCTION "and"
+#define TRIG_RULE_LOGICAL_DISJUNCTION "or"
+
+#endif /* _CONTEXT_TRIGGER_RULE_TYPES_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_TYPES_H_
+#define _CONTEXT_TRIGGER_TYPES_H_
+
+/* Request Subject */
+#define SUBJ_TRIGGER_ADD "trigger/add"
+#define SUBJ_TRIGGER_REMOVE "trigger/remove"
+#define SUBJ_TRIGGER_ENABLE "trigger/enable"
+#define SUBJ_TRIGGER_DISABLE "trigger/disable"
+#define SUBJ_TRIGGER_GET "trigger/get"
+#define SUBJ_TRIGGER_GET_RULE_IDS "trigger/getRuleIds"
+#define SUBJ_TRIGGER_GET_TEMPLATE "trigger/tepmlate/get"
+#define SUBJ_TRIGGER_CUSTOM "custom"
+
+/* Response Types */
+#define TRIG_KEY_RULE_ID "id"
+#define TRIG_KEY_ENABLED_IDS "enabledRuleIds"
+#define TRIG_KEY_DISABLED_IDS "disabledRuleIds"
+
+/* Template Types */
+#define TRIG_TMPL_KEY_SUBJECT "subject"
+#define TRIG_TMPL_KEY_OWNER "owner"
+#define TRIG_TMPL_KEY_OPTION "options"
+#define TRIG_TMPL_KEY_ATTRIBUTE "attributes"
+#define TRIG_TMPL_KEY_MIN "minimum"
+#define TRIG_TMPL_KEY_MAX "maximum"
+#define TRIG_TMPL_KEY_TYPE "type"
+#define TRIG_TMPL_TYPE_INTEGER "integer"
+#define TRIG_TMPL_TYPE_STRING "string"
+#define TRIG_TMPL_TYPE_ENUM "enum"
+#define TRIG_TMPL_TYPE_DOUBLE "double"
+
+/* Custom Request Types */
+#define TRIG_CUSTOM_PREFIX SUBJ_TRIGGER_CUSTOM
+#define TRIG_CUSTOM_KEY_REQ "req"
+#define TRIG_CUSTOM_REQ_ADD "add"
+#define TRIG_CUSTOM_REQ_REMOVE "remove"
+#define TRIG_CUSTOM_REQ_PUBLISH "publish"
+
+/* Custom Fact Types */
+#define TRIG_CUSTOM_KEY_NAME "name"
+#define TRIG_CUSTOM_KEY_FACT "fact"
+
+/* Etc */
+#define TRIG_SUBJECT_SEPERATOR "/"
+
+#endif /* _CONTEXT_TRIGGER_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.
+ */
+
+#ifndef _CONTEXT_TYPES_H_
+#define _CONTEXT_TYPES_H_
+
+#include <dlog.h>
+#include <ErrorTypes.h>
+
+#define SO_EXPORT __attribute__ ((visibility("default")))
+
+/* Logging and Error Handling */
+#define _I SLOGI
+#define _D SLOGD
+#define _W SLOGW
+#define _E SLOGE
+#define _SI SECURE_SLOGI
+#define _SD SECURE_SLOGD
+#define _SW SECURE_LOGW
+#define _SE SECURE_SLOGE
+
+/* Color code for dlog */
+#define RED(X) "\033[0;31m" X "\033[0m"
+#define GREEN(X) "\033[0;32m" X "\033[0m"
+#define YELLOW(X) "\033[0;33m" X "\033[0m"
+#define BLUE(X) "\033[0;34m" X "\033[0m"
+#define PURPLE(X) "\033[0;35m" X "\033[0m"
+#define CYAN(X) "\033[0;36m" X "\033[0m"
+
+#define REPLACE_NULL(X) ((X) ? (X) : "")
+#define STR_EQ(X, Y) (g_strcmp0((X), (Y)) == 0)
+
+#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0)
+
+#define IF_FAIL_RETURN(cond, ret) \
+ do { if (!(cond)) { return ret; } } while (0)
+
+#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0)
+
+#define IF_FAIL_VOID(cond) \
+ do { if (!(cond)) { return; } } while (0)
+
+#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0)
+
+#define IF_FAIL_CATCH(cond) \
+ do { if (!(cond)) { goto CATCH; } } while (0)
+
+#define IS_FAILED(X) ((X) != ERR_NONE)
+
+#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, ERR_INVALID_PARAMETER, _E, "Parameter null")
+
+#define HANDLE_GERROR(Err) \
+ do { if ((Err)) { _E("GError: %s", Err->message); g_error_free(Err); Err = NULL; } } while (0)
+
+#endif /* _CONTEXT_TYPES_H_ */
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(target "ctx-server")
+
+FILE(GLOB_RECURSE SRCS *.cpp)
+MESSAGE("Sources: ${SRCS}")
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${LIB_PKG_LDFLAGS})
+TARGET_LINK_LIBRARIES(${target} ctx-shared)
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
--- /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 <IContextManager.h>
+#include <ContextProvider.h>
+
+using namespace ctx;
+
+IContextManager *ContextProvider::__contextMgr = NULL;
+
+ContextProvider::ContextProvider(const char *subject) :
+ __subject(subject)
+{
+}
+
+ContextProvider::~ContextProvider()
+{
+}
+
+const char* ContextProvider::getSubject()
+{
+ return __subject;
+}
+
+bool ContextProvider::isSupported()
+{
+ return true;
+}
+
+int ContextProvider::subscribe(Json option, Json *requestResult)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ContextProvider::unsubscribe(Json option)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ContextProvider::read(Json option, Json *requestResult)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ContextProvider::write(Json data, Json *requestResult)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+void ContextProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+}
+
+bool ContextProvider::unloadable()
+{
+ return true;
+}
+
+bool ContextProvider::publish(Json option, int error, Json dataUpdated)
+{
+ return __contextMgr->publish(__subject, option, error, dataUpdated);
+}
+
+bool ContextProvider::replyToRead(Json option, int error, Json dataRead)
+{
+ return __contextMgr->replyToRead(__subject, option, error, dataRead);
+}
+
+void ContextProvider::__setContextManager(IContextManager *contextMgr)
+{
+ __contextMgr = contextMgr;
+}
--- /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 <ICustomRegister.h>
+#include <CustomRegister.h>
+
+using namespace ctx;
+
+ICustomRegister *CustomRegister::__customRegister = NULL;
+
+CustomRegister::CustomRegister()
+{
+}
+
+CustomRegister::~CustomRegister()
+{
+}
+
+bool CustomRegister::registerCustomProvider(const char* subject, int operation, Json attribute, Json option, const char* owner)
+{
+ return __customRegister->registerCustomProvider(subject, operation, attribute, option, owner);
+}
+
+bool CustomRegister::unregisterCustomProvider(const char* subject)
+{
+ return __customRegister->unregisterCustomProvider(subject);
+}
+
+void CustomRegister::__setCustomRegister(ICustomRegister *customRegister)
+{
+ __customRegister = customRegister;
+}
--- /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 <Types.h>
+#include <DBusTypes.h>
+#include <ScopeMutex.h>
+#include <DBusSignalWatcher.h>
+
+using namespace ctx;
+
+GMutex DBusSignalWatcher::__mutex;
+unsigned int DBusSignalWatcher::__systemBusCnt = 0;
+unsigned int DBusSignalWatcher::__sessionBusCnt = 0;
+GDBusConnection *DBusSignalWatcher::__systemBus = NULL;
+GDBusConnection *DBusSignalWatcher::__sessionBus = NULL;
+
+static void __signal_cb(GDBusConnection *conn, const gchar *sender,
+ const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, gpointer userdata)
+{
+ IF_FAIL_VOID_TAG(userdata, _W, "user_data cannot be null");
+ IDBusSignalListener *listener = static_cast<IDBusSignalListener*>(userdata);
+ listener->onSignal(sender, path, iface, name, param);
+}
+
+SO_EXPORT DBusSignalWatcher::DBusSignalWatcher(DBusType type) :
+ __busType(type)
+{
+ ScopeMutex sm(&__mutex);
+
+ if (__busType == DBusType::SYSTEM) {
+ if (__systemBusCnt++ == 0)
+ __openBus(G_BUS_TYPE_SYSTEM, __systemBus);
+ } else {
+ if (__sessionBusCnt++ == 0)
+ __openBus(G_BUS_TYPE_SESSION, __sessionBus);
+ }
+}
+
+SO_EXPORT DBusSignalWatcher::~DBusSignalWatcher()
+{
+ ScopeMutex sm(&__mutex);
+
+ if (__busType == DBusType::SYSTEM) {
+ if (--__systemBusCnt == 0)
+ __closeBus(__systemBus);
+ } else {
+ if (--__sessionBusCnt == 0)
+ __closeBus(__sessionBus);
+ }
+}
+
+SO_EXPORT int64_t DBusSignalWatcher::watch(const char *sender, const char *path, const char *iface, const char *name, IDBusSignalListener *listener)
+{
+ GDBusConnection *bus = (__busType == DBusType::SYSTEM ? __systemBus : __sessionBus);
+ IF_FAIL_RETURN_TAG(bus, -1, _E, "Dbus not connected");
+
+ guint sid = g_dbus_connection_signal_subscribe(bus,
+ sender, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+ __signal_cb, listener, NULL);
+
+ return static_cast<int64_t>(sid);
+}
+
+SO_EXPORT void DBusSignalWatcher::unwatch(int64_t signal_id)
+{
+ IF_FAIL_VOID_TAG(signal_id >= 0, _W, "Invalid parameter");
+ GDBusConnection *bus = (__busType == DBusType::SYSTEM ? __systemBus : __sessionBus);
+ g_dbus_connection_signal_unsubscribe(bus, static_cast<guint>(signal_id));
+}
+
+void DBusSignalWatcher::__openBus(GBusType type, GDBusConnection *&bus)
+{
+ GError *gerr = NULL;
+ gchar *addr = g_dbus_address_get_for_bus_sync(type, NULL, &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_VOID(addr);
+
+ bus = g_dbus_connection_new_for_address_sync(addr,
+ (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+ NULL, NULL, &gerr);
+ g_free(addr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_VOID(bus);
+
+ _D("%s Bus Connected", type == G_BUS_TYPE_SYSTEM ? "SYSTEM" : "SESSION");
+}
+
+void DBusSignalWatcher::__closeBus(GDBusConnection *&bus)
+{
+ IF_FAIL_VOID(bus);
+
+ g_dbus_connection_close_sync(bus, NULL, NULL);
+ g_object_unref(bus);
+ bus = NULL;
+
+ _D("%s Bus Closed", __busType == DBusType::SYSTEM ? "SYSTEM" : "SESSION");
+}
--- /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 <tzplatform_config.h>
+#include <ScopeMutex.h>
+#include <DatabaseManager.h>
+#include "DatabaseThread.h"
+
+#define CONTEXT_DB_PATH tzplatform_mkpath(TZ_USER_DB, ".context-service.db")
+
+using namespace ctx;
+
+static unsigned int __refCount = 0;
+static GMutex __mutex;
+static DatabaseThread *__databaseThread = NULL;
+
+SO_EXPORT DatabaseManager::DatabaseManager()
+{
+ ScopeMutex sm(&__mutex);
+
+ if (++__refCount > 1)
+ return;
+
+ if (!__databaseThread->start())
+ _E("Failed to start Database thread");
+}
+
+SO_EXPORT DatabaseManager::~DatabaseManager()
+{
+ ScopeMutex sm(&__mutex);
+
+ if (--__refCount > 0)
+ return;
+
+ __databaseThread->stop();
+}
+
+SO_EXPORT bool DatabaseManager::__init()
+{
+ __databaseThread = new(std::nothrow) DatabaseThread();
+ IF_FAIL_RETURN_TAG(__databaseThread, false, _E, "Memory allocation failed");
+
+ if (__databaseThread->open(CONTEXT_DB_PATH))
+ return true;
+
+ _E("Database initialization failed");
+ delete __databaseThread;
+ __databaseThread = NULL;
+ return false;
+}
+
+SO_EXPORT void DatabaseManager::__release()
+{
+ if (!__databaseThread)
+ return;
+
+ __databaseThread->stop();
+ __databaseThread->close();
+
+ delete __databaseThread;
+ __databaseThread = NULL;
+}
+
+SO_EXPORT bool DatabaseManager::createTable(unsigned int queryId, const char *tableName, const char *columns, const char *option, IDatabaseListener *listener)
+{
+ return __databaseThread->createTable(queryId, tableName, columns, option, listener);
+}
+
+SO_EXPORT bool DatabaseManager::insert(unsigned int queryId, const char *tableName, Json record, IDatabaseListener *listener)
+{
+ return __databaseThread->insert(queryId, tableName, record, listener);
+}
+
+SO_EXPORT bool DatabaseManager::execute(unsigned int queryId, const char *query, IDatabaseListener *listener)
+{
+ return __databaseThread->execute(queryId, query, listener);
+}
+
+SO_EXPORT bool DatabaseManager::createTableSync(const char *tableName, const char *columns, const char *option)
+{
+ return __databaseThread->createTableSync(tableName, columns, option);
+}
+
+SO_EXPORT bool DatabaseManager::insertSync(const char *tableName, Json record, int64_t *rowId)
+{
+ return __databaseThread->insertSync(tableName, record, rowId);
+}
+
+SO_EXPORT bool DatabaseManager::executeSync(const char *query, std::vector<Json> *records)
+{
+ return __databaseThread->executeSync(query, records);
+}
--- /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 <Types.h>
+#include <ScopeMutex.h>
+#include "DatabaseThread.h"
+
+using namespace ctx;
+
+DatabaseThread::DatabaseThread() :
+ __databaseHandle(NULL)
+{
+ g_mutex_init(&__execMutex);
+}
+
+DatabaseThread::~DatabaseThread()
+{
+ g_mutex_clear(&__execMutex);
+}
+
+bool DatabaseThread::open(const char *dbPath)
+{
+ sqlite3 *db = NULL;
+ char *err = NULL;
+ int ret;
+
+ ret = sqlite3_open(dbPath, &db);
+ IF_FAIL_RETURN_TAG(ret == SQLITE_OK, false, _E, "Path: %s / Error: %s", dbPath, sqlite3_errmsg(db));
+
+ ret = sqlite3_exec(db, "PRAGMA journal_mode = WAL", NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ _E("Setting journal mode failed: %s", err);
+ sqlite3_free(err);
+ sqlite3_close(db);
+ return false;
+ }
+
+ __databaseHandle = db;
+ return true;
+}
+
+void DatabaseThread::close()
+{
+ sqlite3_close(__databaseHandle);
+}
+
+bool DatabaseThread::createTable(unsigned int queryId, const char *tableName, const char *columns, const char *option, IDatabaseListener *listener)
+{
+ QueryInfo *info = new(std::nothrow) QueryInfo;
+ IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+
+ info->query = __composeCreate(tableName, columns, option);
+ info->id = queryId;
+ info->listener = listener;
+
+ if (!pushEvent(QUERY_CREATE_TABLE, info)) {
+ delete info;
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseThread::insert(unsigned int queryId, const char *tableName, Json record, IDatabaseListener *listener)
+{
+ std::string query = __composeInsert(tableName, record);
+ IF_FAIL_RETURN(!query.empty(), false);
+
+ QueryInfo *info = new(std::nothrow) QueryInfo;
+ IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+
+ info->query = query;
+ info->id = queryId;
+ info->listener = listener;
+
+ if (!pushEvent(QUERY_INSERT, info)) {
+ delete info;
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseThread::execute(unsigned int queryId, const char *query, IDatabaseListener *listener)
+{
+ IF_FAIL_RETURN(query, false);
+
+ QueryInfo *info = new(std::nothrow) QueryInfo;
+ IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+
+ info->id = queryId;
+ info->query = query;
+ info->listener = listener;
+
+ if (!pushEvent(QUERY_EXECUTE, info)) {
+ delete info;
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseThread::createTableSync(const char *tableName, const char *columns, const char *option)
+{
+ std::string query = __composeCreate(tableName, columns, option);
+ IF_FAIL_RETURN(!query.empty(), false);
+ _SD("SQL: %s", query.c_str());
+
+ char *err = NULL;
+ int ret;
+ {
+ ScopeMutex sm(&__execMutex);
+ ret = sqlite3_exec(__databaseHandle, query.c_str(), NULL, NULL, &err);
+ }
+
+ if (ret != SQLITE_OK) {
+ _E("DB Error: %s", err);
+ sqlite3_free(err);
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseThread::insertSync(const char *tableName, Json record, int64_t *rowId)
+{
+ IF_FAIL_RETURN(tableName && rowId, false);
+
+ std::string query = __composeInsert(tableName, record);
+ IF_FAIL_RETURN(!query.empty(), false);
+ _SD("SQL: %s", query.c_str());
+
+ std::vector<Json> queryResult;
+ char *err = NULL;
+ int ret;
+ {
+ ScopeMutex sm(&__execMutex);
+ ret = sqlite3_exec(__databaseHandle, query.c_str(), __executionCb, &queryResult, &err);
+ }
+
+ if (ret != SQLITE_OK) {
+ _E("DB Error: %s", err);
+ sqlite3_free(err);
+ return false;
+ }
+
+ IF_FAIL_RETURN_TAG(!queryResult.empty(), false, _E, "No row id");
+
+ *rowId = -1;
+ queryResult.at(0).get(NULL, "seq", rowId);
+ _D("RowId: %lld", *rowId);
+
+ return true;
+}
+
+bool DatabaseThread::executeSync(const char *query, std::vector<Json> *records)
+{
+ IF_FAIL_RETURN(query, false);
+
+ _SD("SQL: %s", query);
+
+ char *err = NULL;
+ int ret;
+ {
+ ScopeMutex sm(&__execMutex);
+ ret = sqlite3_exec(__databaseHandle, query, __executionCb, records, &err);
+ }
+
+ if (ret != SQLITE_OK) {
+ _E("DB Error: %s", err);
+ sqlite3_free(err);
+ return false;
+ }
+
+ return true;
+}
+
+void DatabaseThread::onEvent(int type, void* data)
+{
+ IF_FAIL_VOID(data);
+ QueryInfo *info = static_cast<QueryInfo*>(data);
+
+ __execute(static_cast<QueryType>(type), info->id, info->query.c_str(), info->listener);
+
+ deleteEvent(type, data);
+}
+
+void DatabaseThread::deleteEvent(int type, void* data)
+{
+ IF_FAIL_VOID(data);
+ QueryInfo *info = static_cast<QueryInfo*>(data);
+ delete info;
+}
+
+std::string DatabaseThread::__composeCreate(const char *tableName, const char *columns, const char *option)
+{
+ std::string query;
+ query = "CREATE TABLE IF NOT EXISTS ";
+ query = query + tableName + " (rowId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + columns + ")";
+ if (option) {
+ query = query + " " + option;
+ }
+ query += ";";
+ return query;
+}
+
+std::string DatabaseThread::__composeInsert(const char *tableName, Json record)
+{
+ std::string cols;
+ std::string vals;
+ std::list<std::string> keys;
+
+ IF_FAIL_RETURN_TAG(record.getKeys(&keys), "", _E, "Invalid record");
+
+ for (auto it = keys.begin(); it != keys.end(); ++it) {
+ std::string s;
+ int64_t i;
+ if (record.get(NULL, (*it).c_str(), &s)) {
+ cols = cols + *it + ",";
+
+ char* buf = sqlite3_mprintf("%Q", s.c_str());
+ IF_FAIL_RETURN_TAG(buf, "", _E, "Memory allocation failed");
+
+ vals = vals + buf + ",";
+ sqlite3_free(buf);
+
+ } else if (record.get(NULL, (*it).c_str(), &i)) {
+ cols = cols + *it + ",";
+ vals = vals + std::to_string(i) + ",";
+ }
+ }
+
+ IF_FAIL_RETURN_TAG(!cols.empty(), "", _E, "Invalid record");
+
+ cols.erase(cols.size() - 1);
+ vals.erase(vals.size() - 1);
+
+ std::string query = "INSERT INTO ";
+ query = query + tableName + " (" + cols + ") VALUES (" + vals + ");";
+ query = query + "SELECT seq FROM sqlite_sequence WHERE name='" + tableName + "';";
+
+ return query;
+}
+
+void DatabaseThread::__execute(QueryType type, unsigned int queryId, const char *query, IDatabaseListener *listener)
+{
+ _SD("SQL(%d): %s", queryId, query);
+
+ std::vector<Json> *queryResult = new(std::nothrow) std::vector<Json>;
+ IF_FAIL_VOID_TAG(queryResult, _E, "Memory allocation failed");
+
+ char *err = NULL;
+ int ret;
+
+ {
+ ScopeMutex sm(&__execMutex);
+ ret = sqlite3_exec(__databaseHandle, query, __executionCb, queryResult, &err);
+ }
+
+ if (ret != SQLITE_OK) {
+ _E("DB Error: %s", err);
+ sqlite3_free(err);
+ __dispatchResult(type, queryId, listener, ERR_OPERATION_FAILED, queryResult);
+ return;
+ }
+
+ __dispatchResult(type, queryId, listener, ERR_NONE, queryResult);
+ return;
+}
+
+void DatabaseThread::__dispatchResult(QueryType type, unsigned int queryId, IDatabaseListener *listener, int error, std::vector<Json> *result)
+{
+ QueryResult *qr = new(std::nothrow) QueryResult();
+ IF_FAIL_VOID_TAG(qr, _E, "Memory allocation failed");
+
+ qr->type = type;
+ qr->id = queryId;
+ qr->listener = listener;
+ qr->error = error;
+ qr->result = result;
+
+ g_idle_add(__dispatcher, qr);
+}
+
+int DatabaseThread::__executionCb(void *userData, int dim, char **value, char **column)
+{
+ IF_FAIL_RETURN(userData, 0);
+
+ std::vector<Json> *records = static_cast<std::vector<Json>*>(userData);
+ Json row;
+ bool columnNull = false;
+
+ for (int i = 0; i < dim; ++i) {
+ if (!value[i]) {
+ columnNull = true;
+ _W(RED("Null columns exist"));
+ break;
+ }
+
+ row.set(NULL, column[i], value[i]);
+ }
+
+ if (!columnNull) {
+ records->push_back(row);
+ }
+
+ return 0;
+}
+
+gboolean DatabaseThread::__dispatcher(gpointer data)
+{
+ QueryResult *qr = static_cast<QueryResult*>(data);
+
+ if (qr->listener) {
+ switch (qr->type) {
+ case QUERY_CREATE_TABLE:
+ qr->listener->onTableCreated(qr->id, qr->error);
+ break;
+ case QUERY_INSERT:
+ {
+ int64_t rowId = -1;
+ if (qr->error == ERR_NONE && qr->result && !qr->result->empty()) {
+ qr->result->at(0).get(NULL, "seq", &rowId);
+ _D("RowId: %d", rowId);
+ }
+ qr->listener->onInserted(qr->id, qr->error, rowId);
+ }
+ break;
+ case QUERY_EXECUTE:
+ qr->listener->onExecuted(qr->id, qr->error, *(qr->result));
+ break;
+ default:
+ _W("Unknown query type: %d", qr->type);
+ }
+ }
+
+ delete qr->result;
+ delete qr;
+ return FALSE;
+}
--- /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_DATABASE_THREAD_H_
+#define _CONTEXT_DATABASE_THREAD_H_
+
+#include <sqlite3.h>
+#include <EventDrivenThread.h>
+#include <IDatabaseListener.h>
+
+namespace ctx {
+
+ class DatabaseThread : public EventDrivenThread {
+ public:
+ DatabaseThread();
+ ~DatabaseThread();
+
+ bool open(const char *dbPath);
+ void close();
+
+ bool createTable(unsigned int queryId, const char *tableName, const char *columns, const char *option = NULL, IDatabaseListener *listener = NULL);
+ bool insert(unsigned int queryId, const char *tableName, Json record, IDatabaseListener *listener = NULL);
+ bool execute(unsigned int queryId, const char *query, IDatabaseListener *listener = NULL);
+ bool createTableSync(const char *tableName, const char *columns, const char *option = NULL);
+ bool insertSync(const char *tableName, Json record, int64_t *rowId);
+ bool executeSync(const char *query, std::vector<Json> *records);
+
+ private:
+ enum QueryType {
+ QUERY_CREATE_TABLE = 1,
+ QUERY_INSERT,
+ QUERY_EXECUTE,
+ };
+
+ struct QueryInfo {
+ unsigned int id;
+ IDatabaseListener *listener;
+ std::string query;
+ };
+
+ struct QueryResult {
+ int type;
+ unsigned int id;
+ int error;
+ IDatabaseListener *listener;
+ std::vector<Json> *result;
+ };
+
+ void onEvent(int type, void* data);
+ void deleteEvent(int type, void* data);
+
+ std::string __composeCreate(const char *tableName, const char *columns, const char *option);
+ std::string __composeInsert(const char *tableName, Json record);
+
+ void __execute(QueryType type, unsigned int queryId, const char *query, IDatabaseListener *listener);
+ void __dispatchResult(QueryType type, unsigned int queryId, IDatabaseListener *listener, int error, std::vector<Json> *result);
+
+ static int __executionCb(void *userData, int dim, char **value, char **column);
+ static gboolean __dispatcher(gpointer data);
+
+ sqlite3 *__databaseHandle;
+ GMutex __execMutex;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_DATABASE_THREAD_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 <new>
+#include <atomic>
+#include <Types.h>
+#include <EventDrivenThread.h>
+
+struct thread_info_s {
+ GThread *thread;
+ std::atomic_bool isRunning;
+ GAsyncQueue *eventQueue;
+ thread_info_s() : thread(NULL), isRunning(false), eventQueue(NULL) {}
+};
+
+struct event_message_s {
+ int type;
+ void* data;
+ bool term;
+ event_message_s() : type(-1), data(NULL), term(false) {}
+};
+
+EventDrivenThread::EventDrivenThread() :
+ __threadInfo(NULL)
+{
+}
+
+EventDrivenThread::~EventDrivenThread()
+{
+ if (__threadInfo) {
+ stop();
+ delete __threadInfo;
+ }
+}
+
+bool EventDrivenThread::start()
+{
+ if (!__threadInfo) {
+ __threadInfo = new(std::nothrow) thread_info_s;
+ }
+
+ IF_FAIL_RETURN_TAG(__threadInfo, false, _E, "Memory allocation failed");
+
+ if (!isRunning()) {
+
+ __threadInfo->eventQueue = g_async_queue_new();
+
+ if (__threadInfo->eventQueue == NULL) {
+ _E("Memory allocation failed");
+ return false;
+ }
+
+ __threadInfo->isRunning = true;
+
+ __threadInfo->thread = g_thread_new(NULL, __threadFunc, static_cast<gpointer>(this));
+
+ if (__threadInfo->thread == NULL) {
+ _E(RED("Thread creation failed"));
+ __threadInfo->isRunning = false;
+ g_async_queue_unref(__threadInfo->eventQueue);
+ return false;
+ }
+
+ _I(PURPLE("A thread initiated"));
+ }
+
+ return true;
+}
+
+bool EventDrivenThread::stop()
+{
+ if (!isRunning())
+ return true;
+
+ event_message_s* event = new(std::nothrow) event_message_s;
+ IF_FAIL_RETURN_TAG(event, false, _E, "Memory allocation failed");
+
+ event->term = true;
+ g_async_queue_push(__threadInfo->eventQueue, event);
+ g_thread_join(__threadInfo->thread);
+ g_async_queue_unref(__threadInfo->eventQueue);
+ return true;
+}
+
+bool EventDrivenThread::isRunning()
+{
+ return __threadInfo->isRunning.load();
+}
+
+bool EventDrivenThread::pushEvent(int type, void* data)
+{
+ if (!isRunning())
+ return false;
+
+ event_message_s* event = new(std::nothrow) event_message_s;
+ IF_FAIL_RETURN_TAG(event, false, _E, "Memory allocation failed");
+
+ event->type = type;
+ event->data = data;
+ g_async_queue_push(__threadInfo->eventQueue, event);
+ return true;
+}
+
+gpointer EventDrivenThread::__threadFunc(gpointer data)
+{
+ static_cast<EventDrivenThread*>(data)->__run();
+ return NULL;
+}
+
+void EventDrivenThread::__run()
+{
+ event_message_s *event = NULL;
+
+ while (isRunning()) {
+ event = static_cast<event_message_s*>(g_async_queue_pop(__threadInfo->eventQueue));
+ if (event->term) {
+ __threadInfo->isRunning = false;
+ } else {
+ onEvent(event->type, event->data);
+ }
+ delete event;
+ }
+}
--- /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 <ContextProvider.h>
+#include <IContextManager.h>
+
+ctx::IContextManager::~IContextManager()
+{
+}
--- /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 <IDBusSignalListener.h>
+
+ctx::IDBusSignalListener::~IDBusSignalListener()
+{
+}
--- /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 <IDatabaseListener.h>
+
+ctx::IDatabaseListener::~IDatabaseListener()
+{
+}
--- /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 <ITimerListener.h>
+
+ctx::ITimerListener::~ITimerListener()
+{
+}
--- /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 <Types.h>
+#include <ScopeMutex.h>
+#include <SharedVars.h>
+
+#define EMPTY_STRING ""
+
+using namespace ctx;
+
+GMutex SharedVars::__mutex;
+std::map<SharedVars::VarId, std::string> SharedVars::__varsMap;
+
+SO_EXPORT SharedVars::SharedVars()
+{
+}
+
+SO_EXPORT SharedVars::~SharedVars()
+{
+}
+
+SO_EXPORT const std::string& SharedVars::set(SharedVars::VarId id, std::string value) const
+{
+ ScopeMutex sm(&__mutex);
+ _D("var[%d] = %s", id, value.c_str());
+ __varsMap[id] = value;
+ return __varsMap[id];
+}
+
+SO_EXPORT std::string SharedVars::get(SharedVars::VarId id)
+{
+ ScopeMutex sm(&__mutex);
+ auto it = __varsMap.find(id);
+ if (it != __varsMap.end())
+ return it->second;
+ else
+ return EMPTY_STRING;
+}
+
+SO_EXPORT void SharedVars::clear(SharedVars::VarId id)
+{
+ ScopeMutex sm(&__mutex);
+ _D("Remove var[%d]", id);
+ __varsMap.erase(id);
+}
--- /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 <cmath>
+#include <map>
+#include <alarm.h>
+#include <Types.h>
+#include <ScopeMutex.h>
+#include <TimerManager.h>
+
+#define IDENTIFIER "contextd"
+#define EMPTY_STRING ""
+
+using namespace ctx;
+
+unsigned int TimerManager::__instanceCnt = 0;
+GMutex TimerManager::__mutex;
+std::map<int, std::pair<ITimerListener*, TimerManager*>> TimerManager::__listenerMap;
+
+SO_EXPORT TimerManager::TimerManager()
+{
+ ScopeMutex sm(&__mutex);
+
+ if (__instanceCnt++ == 0)
+ __init();
+}
+
+SO_EXPORT TimerManager::~TimerManager()
+{
+ ScopeMutex sm(&__mutex);
+
+ for (int i : __alarms) {
+ __remove(i);
+ }
+
+ if (--__instanceCnt == 0)
+ __release();
+}
+
+SO_EXPORT std::string TimerManager::dowToStr(int dow)
+{
+ static const char *dowStr[] = {
+ DOW_SUN, DOW_MON, DOW_TUE, DOW_WED, DOW_THU, DOW_FRI, DOW_SAT
+ };
+
+ if (static_cast<DayOfWeek>(dow) == DayOfWeek::WEEKDAY)
+ return DOW_WEEKDAY;
+
+ if (static_cast<DayOfWeek>(dow) == DayOfWeek::WEEKEND)
+ return DOW_WEEKEND;
+
+ if (static_cast<DayOfWeek>(dow) == DayOfWeek::EVERYDAY)
+ return DOW_EVERYDAY;
+
+ int d = log2(static_cast<double>(dow));
+ if (d >= 0 && d < DAYS_PER_WEEK)
+ return dowStr[d];
+
+ return EMPTY_STRING;
+}
+
+SO_EXPORT int TimerManager::dowToInt(std::string dow)
+{
+ if (dow == DOW_SUN) return static_cast<int>(DayOfWeek::SUN);
+ if (dow == DOW_MON) return static_cast<int>(DayOfWeek::MON);
+ if (dow == DOW_TUE) return static_cast<int>(DayOfWeek::TUE);
+ if (dow == DOW_WED) return static_cast<int>(DayOfWeek::WED);
+ if (dow == DOW_THU) return static_cast<int>(DayOfWeek::THU);
+ if (dow == DOW_FRI) return static_cast<int>(DayOfWeek::FRI);
+ if (dow == DOW_SAT) return static_cast<int>(DayOfWeek::SAT);
+ if (dow == DOW_WEEKDAY) return static_cast<int>(DayOfWeek::WEEKDAY);
+ if (dow == DOW_WEEKEND) return static_cast<int>(DayOfWeek::WEEKEND);
+ if (dow == DOW_EVERYDAY) return static_cast<int>(DayOfWeek::EVERYDAY);
+ return 0;
+}
+
+SO_EXPORT int TimerManager::setFor(int interval, ITimerListener *listener)
+{
+ IF_FAIL_RETURN_TAG(interval > 0 && listener, -1, _E, "Invalid parameter");
+
+ int alarmId;
+ int result;
+
+ result = alarmmgr_add_periodic_alarm_withcb(interval, QUANTUMIZE, __onAlarmExpired, NULL, &alarmId);
+ IF_FAIL_RETURN_TAG(result == ALARMMGR_RESULT_SUCCESS, -1, _E, "Alarm setting failed");
+
+ ScopeMutex sm(&__mutex);
+ __listenerMap[alarmId] = std::make_pair(listener, this);
+ __alarms.insert(alarmId);
+
+ _D("Timer %d was set for %dm interval", alarmId, interval);
+ return alarmId;
+}
+
+SO_EXPORT int TimerManager::setAt(int hour, int min, DayOfWeek dow, ITimerListener *listener)
+{
+ IF_FAIL_RETURN_TAG(
+ hour < 24 && hour >= 0 &&
+ min < 60 && min >= 0 &&
+ static_cast<int>(dow) > 0 &&
+ static_cast<int>(dow) <= static_cast<int>(DayOfWeek::EVERYDAY) &&
+ listener, -1, _E, "Invalid parameter");
+
+ int repeat = 0;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::SUN))
+ repeat |= ALARM_WDAY_SUNDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::MON))
+ repeat |= ALARM_WDAY_MONDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::TUE))
+ repeat |= ALARM_WDAY_TUESDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::WED))
+ repeat |= ALARM_WDAY_WEDNESDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::THU))
+ repeat |= ALARM_WDAY_THURSDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::FRI))
+ repeat |= ALARM_WDAY_FRIDAY;
+ if (static_cast<int>(dow) & static_cast<int>(DayOfWeek::SAT))
+ repeat |= ALARM_WDAY_SATURDAY;
+
+ alarm_entry_t *alarmInfo = alarmmgr_create_alarm();
+ IF_FAIL_RETURN_TAG(alarmInfo, -1, _E, "Memory allocation failed");
+
+ time_t currentTime;
+ struct tm currentTm;
+ time(¤tTime);
+ tzset();
+ localtime_r(¤tTime, ¤tTm);
+
+ alarm_date_t alarmTime;
+ alarmTime.year = currentTm.tm_year + 1900;
+ alarmTime.month = currentTm.tm_mon + 1;
+ alarmTime.day = currentTm.tm_mday;
+ alarmTime.hour = hour;
+ alarmTime.min = min;
+ alarmTime.sec = 0;
+
+ alarmmgr_set_time(alarmInfo, alarmTime);
+ alarmmgr_set_repeat_mode(alarmInfo, ALARM_REPEAT_MODE_WEEKLY, repeat);
+ alarmmgr_set_type(alarmInfo, ALARM_TYPE_VOLATILE);
+
+ int alarmId;
+ int ret = alarmmgr_add_alarm_with_localtime(alarmInfo, NULL, &alarmId);
+ alarmmgr_free_alarm(alarmInfo);
+
+ IF_FAIL_RETURN_TAG(ret == ALARMMGR_RESULT_SUCCESS, -1, _E, "Alarm setting failed");
+
+ ScopeMutex sm(&__mutex);
+ __listenerMap[alarmId] = std::make_pair(listener, this);
+ __alarms.insert(alarmId);
+
+ _D("Timer %d was set at %02d:%02d:00 (day of week: %#x)", alarmId, hour, min, dow);
+ return alarmId;
+}
+
+SO_EXPORT void TimerManager::remove(int timerId)
+{
+ ScopeMutex sm(&__mutex);
+ __remove(timerId);
+ __alarms.erase(timerId);
+}
+
+void TimerManager::__remove(int timerId)
+{
+ auto it = __listenerMap.find(timerId);
+ if (it != __listenerMap.end()) {
+ __listenerMap.erase(it);
+ alarmmgr_remove_alarm(timerId);
+ _D("Timer %d was removed", timerId);
+ }
+}
+
+bool TimerManager::__init()
+{
+ int result = alarmmgr_init(IDENTIFIER);
+ IF_FAIL_RETURN_TAG(result == ALARMMGR_RESULT_SUCCESS, false, _E, "Alarm manager initialization failed");
+
+ result = alarmmgr_set_cb(__onAlarmExpired, NULL);
+ if (result != ALARMMGR_RESULT_SUCCESS) {
+ alarmmgr_fini();
+ _E("Alarm callback registration failed");
+ return false;
+ }
+
+ alarmmgr_remove_all();
+ _D("Timer initialized");
+ return true;
+}
+
+void TimerManager::__release()
+{
+ alarmmgr_remove_all();
+ alarmmgr_fini();
+ __listenerMap.clear();
+ _D("Timer released");
+}
+
+int TimerManager::__onAlarmExpired(int alarmId, void *userdata)
+{
+ ITimerListener *listener = NULL;
+ TimerManager *timer = NULL;
+
+ {
+ ScopeMutex sm(&__mutex);
+ auto it = __listenerMap.find(alarmId);
+ IF_FAIL_RETURN_TAG(it != __listenerMap.end(), 0, _W, "Unknown Alarm %d", alarmId);
+ listener = it->second.first;
+ timer = it->second.second;
+ }
+
+ _D("Timer %d expired", alarmId);
+
+ if (listener->onTimerExpired(alarmId))
+ return 0;
+
+ _D("Stop repeating TimerManager %d", alarmId);
+ timer->remove(alarmId);
+ return 0;
+}
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(target "ctx-shared")
+
+FILE(GLOB_RECURSE SRCS *.cpp)
+MESSAGE("Sources: ${SRCS}")
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${LIB_PKG_LDFLAGS})
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
--- /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 <cstdio>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <locale>
+#include <iomanip>
+#include <json-glib/json-glib.h>
+#include <Types.h>
+#include <Json.h>
+
+#define PATH_DELIM '.'
+#define MAX_PRECISION 15
+#define GVAR_VALUES "values"
+#define GVAR_TYPES "types"
+
+using namespace ctx;
+
+static std::string __double_to_string(double in)
+{
+ /* Locale-independent double-to-string conversion */
+ int prec = MAX_PRECISION;
+ std::string out;
+ std::ostringstream ostr;
+
+ ostr.imbue(std::locale("C"));
+ ostr << std::setprecision(prec) << in;
+ out = ostr.str();
+
+ if (out.find('e') == std::string::npos)
+ return out;
+
+ /* If 'out' is in scientific notation */
+ ostr.clear();
+ ostr.str(std::string());
+ ostr.imbue(std::locale("C"));
+
+ /* Get the number of fraction digits to precisely print the number */
+ double number = in * 10;
+ while (static_cast<int>(number) == 0) {
+ number *= 10;
+ ++prec;
+ }
+
+ ostr << std::fixed << std::setprecision(prec) << in;
+ out = ostr.str();
+
+ /* Remove trailing '0' */
+ std::size_t found = out.find_last_not_of("0");
+ if (found != std::string::npos)
+ out.erase(found + 1);
+
+ /* If 'out' ends with '.' */
+ if (out.back() == '.')
+ out.erase(out.end() - 1);
+
+ return out;
+}
+
+static double __string_to_double(const char* in)
+{
+ IF_FAIL_RETURN_TAG(in, 0, _E, "Parameter NULL");
+
+ double out;
+
+ /* Locale-independent string-to-double conversion */
+ std::istringstream istr(in);
+ istr.imbue(std::locale("C"));
+ istr >> out;
+
+ return out;
+}
+
+SO_EXPORT Json::Json() :
+ __jsonNode(NULL)
+{
+ JsonObject *obj = json_object_new();
+ IF_FAIL_VOID_TAG(obj, _E, "Json object construction failed");
+
+ __jsonNode = json_node_new(JSON_NODE_OBJECT);
+ if (!__jsonNode) {
+ json_object_unref(obj);
+ _E("Json object construction failed");
+ }
+
+ json_node_set_object(__jsonNode, obj);
+ json_object_unref(obj);
+}
+
+SO_EXPORT Json::Json(const Json &j)
+ : __jsonNode(NULL)
+{
+ __jsonNode = json_node_copy(j.__jsonNode);
+ IF_FAIL_VOID_TAG(__jsonNode, _E, "Json object construction failed");
+}
+
+SO_EXPORT Json::Json(const char *s)
+ : __jsonNode(NULL)
+{
+ if (s) {
+ __parse(s);
+ } else {
+ __parse(EMPTY_JSON_OBJECT);
+ }
+}
+
+SO_EXPORT Json::Json(const std::string &s)
+ : __jsonNode(NULL)
+{
+ if (s.empty()) {
+ __parse(EMPTY_JSON_OBJECT);
+ } else {
+ __parse(s.c_str());
+ }
+}
+
+SO_EXPORT Json::~Json()
+{
+ __release();
+}
+
+void Json::__parse(const char *s)
+{
+ gboolean result;
+ JsonParser *parser = NULL;
+ JsonNode *root = NULL;
+
+ parser = json_parser_new();
+ IF_FAIL_VOID_TAG(parser, _E, "Memory allocation failed");
+
+ result = json_parser_load_from_data(parser, s, -1, NULL);
+ IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
+
+ root = json_parser_get_root(parser);
+ IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
+
+ __jsonNode = json_node_copy(root);
+ IF_FAIL_CATCH_TAG(__jsonNode, _E, "Copying failed");
+
+CATCH:
+ if (parser)
+ g_object_unref(parser);
+}
+
+void Json::__release()
+{
+ if (__jsonNode) {
+ json_node_free(__jsonNode);
+ __jsonNode = NULL;
+ }
+}
+
+SO_EXPORT bool Json::valid()
+{
+ return (__jsonNode != NULL);
+}
+
+SO_EXPORT Json& Json::operator=(const Json &j)
+{
+ __release();
+ __jsonNode = json_node_copy(j.__jsonNode);
+ if (!__jsonNode) {
+ _E("Json object copy failed");
+ }
+ return *this;
+}
+
+SO_EXPORT Json& Json::operator=(const char *s)
+{
+ __release();
+ if (s) {
+ __parse(s);
+ } else {
+ __parse(EMPTY_JSON_OBJECT);
+ }
+ return *this;
+}
+
+SO_EXPORT Json& Json::operator=(const std::string &s)
+{
+ __release();
+ if (s.empty()) {
+ __parse(EMPTY_JSON_OBJECT);
+ } else {
+ __parse(s.c_str());
+ }
+ return *this;
+}
+
+SO_EXPORT bool Json::operator==(const Json &rhs)
+{
+ return __nodeEq(__jsonNode, rhs.__jsonNode);
+}
+
+SO_EXPORT bool Json::operator!=(const Json &rhs)
+{
+ return !operator==(rhs);
+}
+
+char* Json::__strDup()
+{
+ IF_FAIL_RETURN_TAG(__jsonNode, NULL, _E, "Json object not initialized");
+
+ JsonGenerator *jgen = NULL;
+ char *output = NULL;
+
+ jgen = json_generator_new();
+ IF_FAIL_CATCH(jgen);
+
+ json_generator_set_root(jgen, __jsonNode);
+ output = json_generator_to_data(jgen, NULL);
+ IF_FAIL_CATCH(output);
+
+ g_object_unref(jgen);
+ return output;
+
+CATCH:
+ if (jgen) {
+ g_object_unref(jgen);
+ }
+
+ _E("Memory allocation failed");
+ return NULL;
+}
+
+SO_EXPORT std::string Json::str()
+{
+ std::string output;
+ char *_s = __strDup();
+ IF_FAIL_RETURN(_s, output = EMPTY_JSON_OBJECT);
+
+ output = _s;
+ g_free(_s);
+
+ return output;
+}
+
+static std::vector<std::string> __tokenize_path(std::string path)
+{
+ std::vector<std::string> tokens;
+ std::size_t begin = 0;
+ std::size_t end = path.find(PATH_DELIM, 0);
+
+ while (end != std::string::npos) {
+ tokens.push_back(path.substr(begin, end - begin));
+ begin = end + 1;
+ end = path.find(PATH_DELIM, begin);
+ }
+
+ tokens.push_back(path.substr(begin));
+ return tokens;
+}
+
+static JsonObject* __traverse(JsonNode *jnode, const char *path, bool force)
+{
+ IF_FAIL_RETURN_TAG(jnode, NULL, _E, "Invalid parameter");
+
+ unsigned int depth = 0;
+ std::vector<std::string> pathToken;
+ JsonObject *jobj = NULL;
+ JsonObject *childObj = NULL;
+ JsonNode *childNode = NULL;
+
+ jobj = json_node_get_object(jnode);
+ IF_FAIL_RETURN(jobj, NULL);
+
+ if (path)
+ pathToken = __tokenize_path(path);
+
+ for (depth = 0; depth < pathToken.size(); depth++) {
+ if (!json_object_has_member(jobj, pathToken[depth].c_str())) {
+ if (!force) {
+ return NULL;
+ }
+ childObj = json_object_new();
+ IF_FAIL_RETURN_TAG(childObj, NULL, _E, "Memory allocation failed");
+ json_object_set_object_member(jobj, pathToken[depth].c_str(), childObj);
+ }
+ childNode = json_object_get_member(jobj, pathToken[depth].c_str());
+ IF_FAIL_RETURN(childNode && json_node_get_node_type(childNode) == JSON_NODE_OBJECT, NULL);
+
+ jobj = json_node_get_object(childNode);
+ IF_FAIL_RETURN(jobj, NULL);
+ }
+
+ return jobj;
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, Json &val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key))
+ json_object_remove_member(jobj, key);
+
+ json_object_set_member(jobj, key, val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, int val)
+{
+ return set(path, key, static_cast<int64_t>(val));
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key))
+ json_object_remove_member(jobj, key);
+
+ json_object_set_int_member(jobj, key, val);
+ return true;
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, double val)
+{
+ return set(path, key, __double_to_string(val));
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key)) {
+ json_object_remove_member(jobj, key);
+ }
+
+ json_object_set_string_member(jobj, key, val.c_str());
+ return true;
+}
+
+SO_EXPORT bool Json::set(const char *path, const char *key, GVariant *val)
+{
+#if JSON_CHECK_VERSION(0, 14, 0)
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ const gchar *typeStr = g_variant_get_type_string(val);
+ IF_FAIL_RETURN_TAG(typeStr, false, _E, "GVariant manipulation failed");
+
+ json_node_t *node = json_gvariant_serialize(val);
+ IF_FAIL_RETURN_TAG(node, false, _E, "GVariant manipulation failed");
+
+ Json gvarJson;
+ gvarJson.set(NULL, GVAR_TYPES, std::string(typeStr));
+ json_object_set_member(json_node_get_object(gvarJson.__jsonNode), GVAR_VALUES, node);
+
+ return set(path, key, gvarJson);
+#else
+ _E("Insufficient version of json-glib(" JSON_VERSION_S ")");
+ return false;
+#endif
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, Json *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = NULL;
+ JsonNode *node = NULL;
+
+ jobj = __traverse(__jsonNode, path, false);
+ IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), false);
+
+ node = json_object_dup_member(jobj, key);
+ IF_FAIL_RETURN_TAG(node, false, _E, "Memory allocation failed");
+
+ if (val->__jsonNode) {
+ json_node_free(val->__jsonNode);
+ }
+ val->__jsonNode = node;
+
+ return true;
+}
+
+static JsonNode* __get_value_node(JsonNode *jnode, const char *path, const char *key)
+{
+ JsonNode *node = NULL;
+ JsonObject *jobj = NULL;
+ JsonNodeType ntype;
+
+ jobj = __traverse(jnode, path, false);
+ IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), NULL);
+
+ node = json_object_get_member(jobj, key);
+ ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN(ntype == JSON_NODE_VALUE, NULL);
+
+ return node;
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, int *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ int64_t v;
+
+ if (get(path, key, &v)) {
+ *val = v;
+ return true;
+ }
+
+ return false;
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, int64_t *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ //TODO: if the string is not a number?
+ *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, double *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_DOUBLE) {
+ *val = json_node_get_double(node);
+ } else if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ *val = __string_to_double(json_node_get_string(node));
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, std::string *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ IF_FAIL_RETURN(vtype == G_TYPE_STRING, false);
+
+ const char *str_val = json_node_get_string(node);
+ IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+ *val = str_val;
+ return true;
+}
+
+SO_EXPORT bool Json::get(const char *path, const char *key, GVariant **val)
+{
+#if JSON_CHECK_VERSION(0, 14, 0)
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ bool ret;
+ Json gvarJson;
+ ret = get(path, key, &gvarJson);
+ IF_FAIL_RETURN(ret, false);
+
+ std::string gvarTypes;
+ ret = gvarJson.get(NULL, GVAR_TYPES, &gvarTypes);
+ IF_FAIL_RETURN(ret, false);
+
+ Json gvarValues;
+ ret = gvarJson.get(NULL, GVAR_VALUES, &gvarValues);
+ IF_FAIL_RETURN(ret, false);
+
+ GError *gerr = NULL;
+ *val = json_gvariant_deserialize(gvarValues.__jsonNode, gvarTypes.c_str(), &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_RETURN(*val, false);
+
+ return true;
+#else
+ _E("Insufficient version of json-glib(" JSON_VERSION_S ")");
+ *val = NULL;
+ return false;
+#endif
+}
+
+SO_EXPORT bool Json::remove(const char *path, const char *key)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key))
+ json_object_remove_member(jobj, key);
+
+ return true;
+}
+
+static JsonArray* __get_array(JsonNode *jnode, const char *path, const char *key, bool force)
+{
+ JsonNode *node = NULL;
+ JsonArray *arr = NULL;
+ JsonObject *jobj = NULL;
+
+ jobj = __traverse(jnode, path, force);
+ IF_FAIL_RETURN(jobj, NULL);
+
+ if (!json_object_has_member(jobj, key)) {
+ if (force) {
+ arr = json_array_new();
+ IF_FAIL_RETURN_TAG(arr, NULL, _E, "Memory allocation failed");
+ json_object_set_array_member(jobj, key, arr);
+ } else {
+ return NULL;
+ }
+ }
+ node = json_object_get_member(jobj, key);
+ IF_FAIL_RETURN_TAG(node && json_node_get_node_type(node) == JSON_NODE_ARRAY,
+ NULL, _W, "Type mismatched: %s", key);
+
+ return json_node_get_array(node);
+}
+
+SO_EXPORT int Json::getSize(const char *path, const char *key)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, -1, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, -1, _E, "Invalid parameter");
+
+ JsonArray *jarr = __get_array(__jsonNode, path, key, false);
+ IF_FAIL_RETURN_TAG(jarr, -1, _D, "Mismatched data type");
+
+ return json_array_get_length(jarr);
+}
+
+SO_EXPORT bool Json::append(const char *path, const char *key, Json &val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __get_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_element(arr, val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+SO_EXPORT bool Json::append(const char *path, const char *key, int val)
+{
+ return append(path, key, static_cast<int64_t>(val));
+}
+
+SO_EXPORT bool Json::append(const char *path, const char *key, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __get_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_int_element(arr, val);
+ return true;
+}
+
+SO_EXPORT bool Json::append(const char *path, const char *key, double val)
+{
+ return append(path, key, __double_to_string(val));
+}
+
+SO_EXPORT bool Json::append(const char *path, const char *key, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __get_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_string_element(arr, val.c_str());
+ return true;
+}
+
+static JsonNode* __get_array_elem(JsonNode *jnode, const char *path, const char *key, int index)
+{
+ JsonArray *jarr = __get_array(jnode, path, key, false);
+ IF_FAIL_RETURN_TAG(jarr, NULL, _W, "Mismatched data type");
+
+ int size = json_array_get_length(jarr);
+ IF_FAIL_RETURN(size > index, NULL);
+
+ JsonNode *node = json_array_get_element(jarr, index);
+ IF_FAIL_RETURN_TAG(node, NULL, _E, "Failed to get an array element");
+
+ return node;
+}
+
+SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, Json &val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(val.__jsonNode && key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+
+ JsonObject *obj = json_node_get_object(val.__jsonNode);
+ IF_FAIL_RETURN_TAG(obj, false, _E, "Getting object failed");
+
+ json_node_set_object(node, obj);
+ json_node_free(val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, int val)
+{
+ return setAt(path, key, index, static_cast<int64_t>(val));
+}
+
+SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+ IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+
+ json_node_set_int(node, val);
+ return true;
+}
+
+SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, double val)
+{
+ return setAt(path, key, index, __double_to_string(val));
+}
+
+SO_EXPORT bool Json::setAt(const char *path, const char *key, int index, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+ IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+
+ json_node_set_string(node, val.c_str());
+ return true;
+}
+
+SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, Json *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNode *nodeCopy = json_node_copy(node);
+ IF_FAIL_RETURN_TAG(nodeCopy, false, _E, "Memory allocation failed");
+
+ if (val->__jsonNode) {
+ json_node_free(val->__jsonNode);
+ }
+ val->__jsonNode = nodeCopy;
+
+ return true;
+}
+
+SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, int *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ int64_t v;
+ if (getAt(path, key, index, &v)) {
+ *val = v;
+ return true;
+ }
+
+ return false;
+}
+
+SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, int64_t *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
+ } else {
+ _E("Type mismatched: %s", key);
+ return false;
+ }
+
+ return true;
+}
+
+SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, double *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_DOUBLE) {
+ *val = json_node_get_double(node);
+ } else if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ *val = __string_to_double(json_node_get_string(node));
+ } else {
+ _E("Type mismatched: %s", key);
+ return false;
+ }
+
+ return true;
+}
+
+SO_EXPORT bool Json::getAt(const char *path, const char *key, int index, std::string *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __get_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ IF_FAIL_RETURN_TAG(vtype == G_TYPE_STRING, false, _E, "Type mismatched: %s", key);
+
+ const char *str_val = json_node_get_string(node);
+ IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+ *val = str_val;
+ return true;
+}
+
+bool Json::__getMembers(json_node_t *node, std::list<std::string> &list)
+{
+ IF_FAIL_RETURN(node, false);
+ list.clear();
+
+ JsonObject *jobj = json_node_get_object(node);
+ IF_FAIL_RETURN_TAG(jobj, false, _E, "Getting Json object failed");
+
+ GList *members = json_object_get_members(jobj);
+ IF_FAIL_RETURN(members, true);
+
+ for (GList *it = g_list_first(members); it; it = g_list_next(it)) {
+ const char *key = static_cast<const char*>(it->data);
+ if (!key) {
+ list.clear();
+ g_list_free(members);
+ _E("Member list extraction failed");
+ return false;
+ }
+
+ list.push_back(key);
+ }
+
+ g_list_free(members);
+ return true;
+}
+
+SO_EXPORT bool Json::getKeys(std::list<std::string>* list)
+{
+ IF_FAIL_RETURN_TAG(list, false, _E, "Invalid parameter");
+ return __getMembers(__jsonNode, *list);
+}
+
+bool Json::__nodeEq(json_node_t *lhs, json_node_t *rhs)
+{
+ IF_FAIL_RETURN(lhs && rhs, false);
+
+ JsonNodeType ltype = json_node_get_node_type(lhs);
+ JsonNodeType rtype = json_node_get_node_type(rhs);
+ IF_FAIL_RETURN(ltype == rtype, false);
+
+ switch (ltype) {
+ case JSON_NODE_VALUE:
+ IF_FAIL_RETURN(__valueEq(lhs, rhs), false);
+ break;
+ case JSON_NODE_OBJECT:
+ IF_FAIL_RETURN(__objectEq(lhs, rhs), false);
+ break;
+ case JSON_NODE_ARRAY:
+ IF_FAIL_RETURN(__arrayEq(lhs, rhs), false);
+ break;
+ default:
+ _W("Unsupported type");
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::__valueEq(json_node_t *lhs, json_node_t *rhs)
+{
+ GType ltype = json_node_get_value_type(lhs);
+ GType rtype = json_node_get_value_type(rhs);
+ IF_FAIL_RETURN(ltype == rtype, false);
+
+ switch (ltype) {
+ case G_TYPE_INT64:
+ return json_node_get_int(lhs) == json_node_get_int(rhs);
+ case G_TYPE_DOUBLE:
+ return json_node_get_double(lhs) == json_node_get_double(rhs);
+ case G_TYPE_STRING:
+ return STR_EQ(json_node_get_string(lhs), json_node_get_string(rhs));
+ default:
+ _W("Unsupported type");
+ return false;
+ }
+}
+
+bool Json::__objectEq(json_node_t *lhs, json_node_t *rhs)
+{
+ std::list<std::string> lm, rm;
+ IF_FAIL_RETURN(__getMembers(lhs, lm), false);
+ IF_FAIL_RETURN(__getMembers(rhs, rm), false);
+ IF_FAIL_RETURN(lm.size() == rm.size(), false);
+
+ lm.sort();
+ rm.sort();
+
+ std::list<std::string>::iterator lit, rit;
+ lit = lm.begin();
+ rit = rm.begin();
+
+ while (lit != lm.end()) {
+ IF_FAIL_RETURN(*lit == *rit, false);
+
+ json_node_t *lhsChild = json_object_get_member(json_node_get_object(lhs), (*lit).c_str());
+ json_node_t *rhsChild = json_object_get_member(json_node_get_object(rhs), (*rit).c_str());
+ IF_FAIL_RETURN(__nodeEq(lhsChild, rhsChild), false);
+
+ ++lit;
+ ++rit;
+ }
+
+ return true;
+}
+
+bool Json::__arrayEq(json_node_t *lhs, json_node_t *rhs)
+{
+ JsonArray *larr = json_node_get_array(lhs);
+ JsonArray *rarr = json_node_get_array(rhs);
+
+ int size = json_array_get_length(larr);
+ IF_FAIL_RETURN(size == static_cast<int>(json_array_get_length(rarr)), false);
+
+ for (int i = 0; i < size; ++i) {
+ json_node_t *lhsChild = json_array_get_element(larr, i);
+ json_node_t *rhsChild = json_array_get_element(rarr, i);
+ IF_FAIL_RETURN(__nodeEq(lhsChild, rhsChild), false);
+ }
+
+ return true;
+}
--- /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 <MyPlaceTypes.h>
+#include <Types.h>
+
+SO_EXPORT bool ctx::operator==(const ctx::Place &p1, const ctx::Place &p2)
+{
+ bool ret = p1.categId == p2.categId
+ && p1.categConfidence == p2.categConfidence
+ && p1.name == p2.name
+ && p1.createDate == p2.createDate
+ && p1.locationValid == p2.locationValid;
+ if (ret && p1.locationValid) {
+ // Check location only if it is valid / filled
+ if (p1.location.latitude != p2.location.latitude
+ || p1.location.longitude != p2.location.longitude
+ || p1.location.accuracy != p2.location.accuracy) {
+ ret = false;
+ }
+ }
+ if (ret) {
+ for (std::pair<std::string, std::string> ap : p1.wifiAps) {
+ // Check only MAC addresses because network names are only addition.
+ if (p2.wifiAps.find(ap.first) == p2.wifiAps.end()) {
+ ret = false;
+ 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 <Types.h>
+#include <ScopeMutex.h>
+
+SO_EXPORT ctx::ScopeMutex::ScopeMutex(GMutex *m) :
+ __mutex(m)
+{
+ g_mutex_lock(__mutex);
+}
+
+SO_EXPORT ctx::ScopeMutex::~ScopeMutex()
+{
+ g_mutex_unlock(__mutex);
+}