Integrate the legacy context-common code and headers (1/2) 53/122053/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 30 Mar 2017 04:46:58 +0000 (13:46 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 30 Mar 2017 04:46:58 +0000 (13:46 +0900)
This patch just imports the legacy code files.

Change-Id: I6acd7303a4792faf864ef3e77e84bff35217fe64
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
45 files changed:
common/client/CMakeLists.txt [new file with mode: 0644]
common/client/DBusClient.cpp [new file with mode: 0644]
common/client/IDBusClientListener.cpp [new file with mode: 0644]
common/include/ContextProvider.h [new file with mode: 0644]
common/include/CustomRegister.h [new file with mode: 0644]
common/include/DBusClient.h [new file with mode: 0644]
common/include/DBusSignalWatcher.h [new file with mode: 0644]
common/include/DBusTypes.h [new file with mode: 0644]
common/include/DatabaseManager.h [new file with mode: 0644]
common/include/ErrorTypes.h [new file with mode: 0644]
common/include/EventDrivenThread.h [new file with mode: 0644]
common/include/IContextManager.h [new file with mode: 0644]
common/include/ICustomRegister.h [new file with mode: 0644]
common/include/IDBusClientListener.h [new file with mode: 0644]
common/include/IDBusSignalListener.h [new file with mode: 0644]
common/include/IDatabaseListener.h [new file with mode: 0644]
common/include/ITimerListener.h [new file with mode: 0644]
common/include/Json.h [new file with mode: 0644]
common/include/MyPlaceTypes.h [new file with mode: 0644]
common/include/ProviderTypes.h [new file with mode: 0644]
common/include/ScopeMutex.h [new file with mode: 0644]
common/include/SensorRecorderTypes.h [new file with mode: 0644]
common/include/SharedVars.h [new file with mode: 0644]
common/include/TimerManager.h [new file with mode: 0644]
common/include/TriggerRuleTypes.h [new file with mode: 0644]
common/include/TriggerTypes.h [new file with mode: 0644]
common/include/Types.h [new file with mode: 0644]
common/server/CMakeLists.txt [new file with mode: 0644]
common/server/ContextProvider.cpp [new file with mode: 0644]
common/server/CustomRegistser.cpp [new file with mode: 0644]
common/server/DBusSignalWatcher.cpp [new file with mode: 0644]
common/server/DatabaseManager.cpp [new file with mode: 0644]
common/server/DatabaseThread.cpp [new file with mode: 0644]
common/server/DatabaseThread.h [new file with mode: 0644]
common/server/EventDrivenThread.cpp [new file with mode: 0644]
common/server/IContextManager.cpp [new file with mode: 0644]
common/server/IDBusSignalListener.cpp [new file with mode: 0644]
common/server/IDatabaseListener.cpp [new file with mode: 0644]
common/server/ITimerListener.cpp [new file with mode: 0644]
common/server/SharedVars.cpp [new file with mode: 0644]
common/server/TimerManager.cpp [new file with mode: 0644]
common/shared/CMakeLists.txt [new file with mode: 0644]
common/shared/Json.cpp [new file with mode: 0644]
common/shared/MyPlaceTypes.cpp [new file with mode: 0644]
common/shared/ScopeMutex.cpp [new file with mode: 0644]

diff --git a/common/client/CMakeLists.txt b/common/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0b99d48
--- /dev/null
@@ -0,0 +1,13 @@
+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})
diff --git a/common/client/DBusClient.cpp b/common/client/DBusClient.cpp
new file mode 100644 (file)
index 0000000..85c9d75
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * 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;
+}
diff --git a/common/client/IDBusClientListener.cpp b/common/client/IDBusClientListener.cpp
new file mode 100644 (file)
index 0000000..0da37b2
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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()
+{
+}
diff --git a/common/include/ContextProvider.h b/common/include/ContextProvider.h
new file mode 100644 (file)
index 0000000..2d89262
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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_ */
diff --git a/common/include/CustomRegister.h b/common/include/CustomRegister.h
new file mode 100644 (file)
index 0000000..5134613
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_ */
diff --git a/common/include/DBusClient.h b/common/include/DBusClient.h
new file mode 100644 (file)
index 0000000..c865e80
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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__
diff --git a/common/include/DBusSignalWatcher.h b/common/include/DBusSignalWatcher.h
new file mode 100644 (file)
index 0000000..6b035ed
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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_ */
diff --git a/common/include/DBusTypes.h b/common/include/DBusTypes.h
new file mode 100644 (file)
index 0000000..1921e30
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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_ */
diff --git a/common/include/DatabaseManager.h b/common/include/DatabaseManager.h
new file mode 100644 (file)
index 0000000..a0fe0ad
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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_ */
diff --git a/common/include/ErrorTypes.h b/common/include/ErrorTypes.h
new file mode 100644 (file)
index 0000000..1e2e81c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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_ */
diff --git a/common/include/EventDrivenThread.h b/common/include/EventDrivenThread.h
new file mode 100644 (file)
index 0000000..54b6efa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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_ */
diff --git a/common/include/IContextManager.h b/common/include/IContextManager.h
new file mode 100644 (file)
index 0000000..4bb2561
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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_ */
diff --git a/common/include/ICustomRegister.h b/common/include/ICustomRegister.h
new file mode 100644 (file)
index 0000000..eca3596
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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_ */
diff --git a/common/include/IDBusClientListener.h b/common/include/IDBusClientListener.h
new file mode 100644 (file)
index 0000000..1463425
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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_ */
diff --git a/common/include/IDBusSignalListener.h b/common/include/IDBusSignalListener.h
new file mode 100644 (file)
index 0000000..ed70efe
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_ */
diff --git a/common/include/IDatabaseListener.h b/common/include/IDatabaseListener.h
new file mode 100644 (file)
index 0000000..96205cb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_ */
diff --git a/common/include/ITimerListener.h b/common/include/ITimerListener.h
new file mode 100644 (file)
index 0000000..a8bbe9f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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_ */
diff --git a/common/include/Json.h b/common/include/Json.h
new file mode 100644 (file)
index 0000000..31a9d11
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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_
diff --git a/common/include/MyPlaceTypes.h b/common/include/MyPlaceTypes.h
new file mode 100644 (file)
index 0000000..2593649
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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_ */
diff --git a/common/include/ProviderTypes.h b/common/include/ProviderTypes.h
new file mode 100644 (file)
index 0000000..d720922
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 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_ */
diff --git a/common/include/ScopeMutex.h b/common/include/ScopeMutex.h
new file mode 100644 (file)
index 0000000..a17bc2a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_
diff --git a/common/include/SensorRecorderTypes.h b/common/include/SensorRecorderTypes.h
new file mode 100644 (file)
index 0000000..7ad6d0c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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__ */
diff --git a/common/include/SharedVars.h b/common/include/SharedVars.h
new file mode 100644 (file)
index 0000000..4171e1a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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
diff --git a/common/include/TimerManager.h b/common/include/TimerManager.h
new file mode 100644 (file)
index 0000000..d8338f2
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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_ */
diff --git a/common/include/TriggerRuleTypes.h b/common/include/TriggerRuleTypes.h
new file mode 100644 (file)
index 0000000..886d119
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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_ */
diff --git a/common/include/TriggerTypes.h b/common/include/TriggerTypes.h
new file mode 100644 (file)
index 0000000..85f688b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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_ */
diff --git a/common/include/Types.h b/common/include/Types.h
new file mode 100644 (file)
index 0000000..aaadd57
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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_ */
diff --git a/common/server/CMakeLists.txt b/common/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..31c854b
--- /dev/null
@@ -0,0 +1,13 @@
+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})
diff --git a/common/server/ContextProvider.cpp b/common/server/ContextProvider.cpp
new file mode 100644 (file)
index 0000000..ac2758c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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;
+}
diff --git a/common/server/CustomRegistser.cpp b/common/server/CustomRegistser.cpp
new file mode 100644 (file)
index 0000000..313d685
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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;
+}
diff --git a/common/server/DBusSignalWatcher.cpp b/common/server/DBusSignalWatcher.cpp
new file mode 100644 (file)
index 0000000..c03c781
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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");
+}
diff --git a/common/server/DatabaseManager.cpp b/common/server/DatabaseManager.cpp
new file mode 100644 (file)
index 0000000..008c450
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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);
+}
diff --git a/common/server/DatabaseThread.cpp b/common/server/DatabaseThread.cpp
new file mode 100644 (file)
index 0000000..66e622e
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * 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;
+}
diff --git a/common/server/DatabaseThread.h b/common/server/DatabaseThread.h
new file mode 100644 (file)
index 0000000..4e3b608
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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_ */
diff --git a/common/server/EventDrivenThread.cpp b/common/server/EventDrivenThread.cpp
new file mode 100644 (file)
index 0000000..6718ecc
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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;
+       }
+}
diff --git a/common/server/IContextManager.cpp b/common/server/IContextManager.cpp
new file mode 100644 (file)
index 0000000..1a02a57
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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()
+{
+}
diff --git a/common/server/IDBusSignalListener.cpp b/common/server/IDBusSignalListener.cpp
new file mode 100644 (file)
index 0000000..7296733
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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()
+{
+}
diff --git a/common/server/IDatabaseListener.cpp b/common/server/IDatabaseListener.cpp
new file mode 100644 (file)
index 0000000..9eea63e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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()
+{
+}
diff --git a/common/server/ITimerListener.cpp b/common/server/ITimerListener.cpp
new file mode 100644 (file)
index 0000000..03f7e79
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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()
+{
+}
diff --git a/common/server/SharedVars.cpp b/common/server/SharedVars.cpp
new file mode 100644 (file)
index 0000000..dbcc36d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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);
+}
diff --git a/common/server/TimerManager.cpp b/common/server/TimerManager.cpp
new file mode 100644 (file)
index 0000000..46d2179
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * 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(&currentTime);
+       tzset();
+       localtime_r(&currentTime, &currentTm);
+
+       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;
+}
diff --git a/common/shared/CMakeLists.txt b/common/shared/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9e52d5b
--- /dev/null
@@ -0,0 +1,12 @@
+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})
diff --git a/common/shared/Json.cpp b/common/shared/Json.cpp
new file mode 100644 (file)
index 0000000..2f8a1b8
--- /dev/null
@@ -0,0 +1,925 @@
+/*
+ * 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;
+}
diff --git a/common/shared/MyPlaceTypes.cpp b/common/shared/MyPlaceTypes.cpp
new file mode 100644 (file)
index 0000000..c5c2600
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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;
+}
diff --git a/common/shared/ScopeMutex.cpp b/common/shared/ScopeMutex.cpp
new file mode 100644 (file)
index 0000000..8bc0b51
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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);
+}