Import the legacy sensor-recorder implementation from context-provider 42/130042/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 19 May 2017 02:16:56 +0000 (11:16 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 19 May 2017 02:24:23 +0000 (11:24 +0900)
Change-Id: I626238fc6def0458cab6192ebb7fd40c32549c52
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
45 files changed:
src/server/CMakeLists.txt
src/server/legacy/ClientInfo.cpp [new file with mode: 0644]
src/server/legacy/ClientInfo.h [new file with mode: 0644]
src/server/legacy/CreateProvider.cpp [new file with mode: 0644]
src/server/legacy/Querier.cpp [new file with mode: 0644]
src/server/legacy/Querier.h [new file with mode: 0644]
src/server/legacy/SensorLogger.cpp [new file with mode: 0644]
src/server/legacy/SensorLogger.h [new file with mode: 0644]
src/server/legacy/SensorProvider.cpp [new file with mode: 0644]
src/server/legacy/SensorProvider.h [new file with mode: 0644]
src/server/legacy/SensorProxy.cpp [new file with mode: 0644]
src/server/legacy/SensorProxy.h [new file with mode: 0644]
src/server/legacy/TimeUtil.cpp [new file with mode: 0644]
src/server/legacy/TimeUtil.h [new file with mode: 0644]
src/server/legacy/TypesInternal.h [new file with mode: 0644]
src/server/legacy/UninstallMonitor.cpp [new file with mode: 0644]
src/server/legacy/UninstallMonitor.h [new file with mode: 0644]
src/server/legacy/heartrate/HeartRate.cpp [new file with mode: 0644]
src/server/legacy/heartrate/HeartRate.h [new file with mode: 0644]
src/server/legacy/heartrate/HeartRateLogger.cpp [new file with mode: 0644]
src/server/legacy/heartrate/HeartRateLogger.h [new file with mode: 0644]
src/server/legacy/heartrate/HeartRateQuerier.cpp [new file with mode: 0644]
src/server/legacy/heartrate/HeartRateQuerier.h [new file with mode: 0644]
src/server/legacy/pedometer/Pedometer.cpp [new file with mode: 0644]
src/server/legacy/pedometer/Pedometer.h [new file with mode: 0644]
src/server/legacy/pedometer/PedometerLogger.cpp [new file with mode: 0644]
src/server/legacy/pedometer/PedometerLogger.h [new file with mode: 0644]
src/server/legacy/pedometer/PedometerQuerier.cpp [new file with mode: 0644]
src/server/legacy/pedometer/PedometerQuerier.h [new file with mode: 0644]
src/server/legacy/pressure/Pressure.cpp [new file with mode: 0644]
src/server/legacy/pressure/Pressure.h [new file with mode: 0644]
src/server/legacy/pressure/PressureLogger.cpp [new file with mode: 0644]
src/server/legacy/pressure/PressureLogger.h [new file with mode: 0644]
src/server/legacy/pressure/PressureQuerier.cpp [new file with mode: 0644]
src/server/legacy/pressure/PressureQuerier.h [new file with mode: 0644]
src/server/legacy/sleep/Sleep.cpp [new file with mode: 0644]
src/server/legacy/sleep/Sleep.h [new file with mode: 0644]
src/server/legacy/sleep/SleepDetector.cpp [new file with mode: 0644]
src/server/legacy/sleep/SleepDetector.h [new file with mode: 0644]
src/server/legacy/sleep/SleepLogger.cpp [new file with mode: 0644]
src/server/legacy/sleep/SleepLogger.h [new file with mode: 0644]
src/server/legacy/sleep/SleepMonitor.cpp [new file with mode: 0644]
src/server/legacy/sleep/SleepMonitor.h [new file with mode: 0644]
src/server/legacy/sleep/SleepQuerier.cpp [new file with mode: 0644]
src/server/legacy/sleep/SleepQuerier.h [new file with mode: 0644]

index 64a741f..df2de9c 100644 (file)
@@ -2,7 +2,7 @@ SET(target "${PROJECT_NAME}-server-genuine")
 
 SET(DEPS "${DEPS} context-common-server")
 
-FILE(GLOB_RECURSE SRCS *.cpp ../shared/*.cpp)
+FILE(GLOB SRCS *.cpp ../shared/*.cpp)
 MESSAGE("Sources: ${SRCS}")
 
 INCLUDE(FindPkgConfig)
diff --git a/src/server/legacy/ClientInfo.cpp b/src/server/legacy/ClientInfo.cpp
new file mode 100644 (file)
index 0000000..6c5955d
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * 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 <sqlite3.h>
+#include <Types.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "SensorProvider.h"
+#include "ClientInfo.h"
+
+using namespace ctx;
+
+unsigned int ClientInfo::__refCnt = 0;
+DatabaseManager *ClientInfo::__dbMgr = NULL;
+UninstallMonitor *ClientInfo::__uninstallMonitor = NULL;
+
+ClientInfo::ClientInfo()
+{
+       if (++__refCnt != 1)
+               return;
+
+       __uninstallMonitor = new(std::nothrow) UninstallMonitor();
+       IF_FAIL_VOID_TAG(__uninstallMonitor, _E, "Memory allocation failed");
+
+       __dbMgr = new(std::nothrow) DatabaseManager();
+       IF_FAIL_VOID_TAG(__dbMgr, _E, "Memory allocation failed");
+
+       bool ret = __dbMgr->executeSync(
+                       "CREATE TABLE IF NOT EXISTS " CLIENT_INFO " (" \
+                               KEY_SUBJECT " TEXT NOT NULL," \
+                               KEY_PKG_ID " TEXT NOT NULL," \
+                               KEY_OPTION " TEXT NOT NULL," \
+                               KEY_RETENTION " INTEGER NOT NULL," \
+                               "PRIMARY KEY (" KEY_SUBJECT "," KEY_PKG_ID ")" \
+                       ")", NULL);
+
+       IF_FAIL_VOID_TAG(ret, _E, "Table creation failed");
+}
+
+ClientInfo::~ClientInfo()
+{
+       if (--__refCnt != 0)
+               return;
+
+       delete __dbMgr;
+       __dbMgr = NULL;
+
+       delete __uninstallMonitor;
+       __uninstallMonitor = NULL;
+}
+
+int ClientInfo::get(std::string subject, std::string pkgId, Json& option)
+{
+       IF_FAIL_RETURN_TAG(__dbMgr, ERR_OPERATION_FAILED, _W, "DB not initialized");
+
+       bool ret;
+       std::string optStr;
+       std::vector<Json> records;
+       char *query = sqlite3_mprintf(
+                       "SELECT " KEY_OPTION " FROM " CLIENT_INFO " WHERE " \
+                       KEY_SUBJECT "='%q' AND " KEY_PKG_ID "='%q'",
+                       subject.c_str(), pkgId.c_str());
+
+       ret = __dbMgr->executeSync(query, &records);
+       sqlite3_free(query);
+
+       IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
+       IF_FAIL_RETURN(!records.empty(), ERR_NO_DATA);
+       IF_FAIL_RETURN(records[0].get(NULL, KEY_OPTION, &optStr), ERR_OPERATION_FAILED);
+
+       option = optStr;
+
+       return ERR_NONE;
+}
+
+int ClientInfo::get(std::string subject, std::vector<Json>& options)
+{
+       IF_FAIL_RETURN_TAG(__dbMgr, ERR_OPERATION_FAILED, _W, "DB not initialized");
+
+       bool ret;
+       std::string optStr;
+       std::vector<Json> records;
+       char *query = sqlite3_mprintf(
+                       "SELECT " KEY_OPTION " FROM " CLIENT_INFO " WHERE " \
+                       KEY_SUBJECT "='%q'",
+                       subject.c_str());
+
+       ret = __dbMgr->executeSync(query, &records);
+       sqlite3_free(query);
+
+       IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
+       IF_FAIL_RETURN(!records.empty(), ERR_NO_DATA);
+
+       for (Json& jObj : records) {
+               if (!jObj.get(NULL, KEY_OPTION, &optStr))
+                       continue;
+               options.push_back(Json(optStr));
+       }
+
+       return ERR_NONE;
+}
+
+bool ClientInfo::exist(std::string subject)
+{
+       IF_FAIL_RETURN_TAG(__dbMgr, ERR_OPERATION_FAILED, _W, "DB not initialized");
+
+       bool ret;
+       std::vector<Json> records;
+       char *query = sqlite3_mprintf(
+                       "SELECT " KEY_PKG_ID " FROM " CLIENT_INFO " WHERE " \
+                       KEY_SUBJECT "='%q' LIMIT 1",
+                       subject.c_str());
+
+       ret = __dbMgr->executeSync(query, &records);
+       sqlite3_free(query);
+
+       IF_FAIL_RETURN(ret, false);
+       IF_FAIL_RETURN(!records.empty(), false);
+
+       return true;
+}
+
+bool ClientInfo::set(std::string subject, std::string pkgId, Json option, int retentionPeriod)
+{
+       IF_FAIL_RETURN_TAG(__dbMgr, false, _W, "DB not initialized");
+
+       bool ret;
+       char *query = sqlite3_mprintf(
+                       "INSERT INTO " CLIENT_INFO " VALUES ('%q', '%q', '%q', %d)",
+                       subject.c_str(), pkgId.c_str(), option.str().c_str(), retentionPeriod);
+
+       ret = __dbMgr->executeSync(query, NULL);
+       sqlite3_free(query);
+
+       return ret;
+}
+
+bool ClientInfo::remove(std::string subject, std::string pkgId)
+{
+       IF_FAIL_RETURN_TAG(__dbMgr, false, _W, "DB not initialized");
+
+       bool ret;
+       char *query = sqlite3_mprintf(
+                       "DELETE FROM " CLIENT_INFO " WHERE " \
+                       KEY_SUBJECT "='%q' AND " KEY_PKG_ID "='%q'",
+                       subject.c_str(), pkgId.c_str());
+
+       ret = __dbMgr->executeSync(query, NULL);
+       sqlite3_free(query);
+
+       return ret;
+}
+
+void ClientInfo::getParam(std::vector<Json> &options, const char *key, float *min, float *max)
+{
+       double val;
+
+       for (Json& opt : options) {
+               if (!opt.get(NULL, key, &val))
+                       continue;
+               if (min)
+                       *min = MIN(*min, static_cast<float>(val));
+               if (max)
+                       *max = MAX(*max, static_cast<float>(val));
+       }
+}
+
+void ClientInfo::purgeClient(std::string pkgId)
+{
+       IF_FAIL_VOID_TAG(__dbMgr, _W, "DB not initialized");
+
+       bool ret;
+       std::string subject;
+       std::vector<Json> records;
+
+       char *query = sqlite3_mprintf(
+                       "SELECT " KEY_SUBJECT " FROM " CLIENT_INFO " WHERE " KEY_PKG_ID "='%q'",
+                       pkgId.c_str());
+
+       ret = __dbMgr->executeSync(query, &records);
+       sqlite3_free(query);
+       IF_FAIL_VOID(ret);
+
+       for (Json& jObj : records) {
+               if (!jObj.get(NULL, KEY_SUBJECT, &subject))
+                       continue;
+               _I("Stop recording '%s' for '%s'", subject.c_str(), pkgId.c_str());
+               SensorProvider::removeClient(subject, pkgId);
+       }
+}
diff --git a/src/server/legacy/ClientInfo.h b/src/server/legacy/ClientInfo.h
new file mode 100644 (file)
index 0000000..e3ee643
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_CLIENT_INFO_H__
+#define __CONTEXT_CLIENT_INFO_H__
+
+#include <string>
+#include <vector>
+#include <Json.h>
+#include <DatabaseManager.h>
+#include "UninstallMonitor.h"
+
+namespace ctx {
+
+       class ClientInfo {
+       public:
+               ClientInfo();
+               ~ClientInfo();
+
+               int get(std::string subject, std::string pkgId, Json& option);
+               int get(std::string subject, std::vector<Json>& options);
+               bool exist(std::string subject);
+
+               bool set(std::string subject, std::string pkgId, Json option, int retentionPeriod);
+               bool remove(std::string subject, std::string pkgId);
+
+               void getParam(std::vector<Json>& options, const char *key, float *min, float *max);
+
+               static void purgeClient(std::string pkgId);
+
+       private:
+               static unsigned int __refCnt;
+               static DatabaseManager *__dbMgr;
+               static UninstallMonitor *__uninstallMonitor;
+       };
+}
+
+#endif /* _CONTEXT_CLIENT_INFO_H_ */
diff --git a/src/server/legacy/CreateProvider.cpp b/src/server/legacy/CreateProvider.cpp
new file mode 100644 (file)
index 0000000..73e9f19
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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 <SensorRecorderTypes.h>
+#include <CreateProvider.h>
+#include "pedometer/Pedometer.h"
+#include "pressure/Pressure.h"
+#include "sleep/Sleep.h"
+#include "heartrate/HeartRate.h"
+
+using namespace ctx;
+
+extern "C" SO_EXPORT ContextProvider* CreateProvider(const char *subject)
+{
+       ADD_PROVIDER(SUBJ_SENSOR_PEDOMETER, PedometerProvider);
+       ADD_PROVIDER(SUBJ_SENSOR_PRESSURE,  PressureProvider);
+       ADD_PROVIDER(SUBJ_SENSOR_SLEEP_MONITOR,  SleepProvider);
+       ADD_PROVIDER(SUBJ_SENSOR_HEART_RATE,  HeartRateProvider);
+
+       return NULL;
+}
diff --git a/src/server/legacy/Querier.cpp b/src/server/legacy/Querier.cpp
new file mode 100644 (file)
index 0000000..feec0b3
--- /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.
+ */
+
+#include <Types.h>
+#include <SensorRecorderTypes.h>
+#include "Querier.h"
+
+using namespace ctx;
+
+Querier::Querier(ContextProvider *provider, Json option) :
+       __provider(provider),
+       __option(option)
+{
+}
+
+Querier::~Querier()
+{
+}
+
+int Querier::query(const char *sql)
+{
+       return __dbMgr.execute(0, sql, this) ? ERR_NONE : ERR_OPERATION_FAILED;
+}
+
+int Querier::queryRaw(int startTime, int endTime)
+{
+       return ERR_INVALID_PARAMETER;
+}
+
+int Querier::query(int startTime, int endTime)
+{
+       return ERR_INVALID_PARAMETER;
+}
+
+int Querier::query(int startTime, int endTime, int anchor, int interval)
+{
+       _D("Ignore anchor & interval");
+       return query(startTime, endTime);
+}
+
+void Querier::onTableCreated(unsigned int queryId, int error)
+{
+}
+
+void Querier::onInserted(unsigned int queryId, int error, int64_t rowId)
+{
+}
+
+void Querier::onExecuted(unsigned int queryId, int error, std::vector<Json>& records)
+{
+       Json response;
+       __convertToResponse(records, response);
+       __provider->replyToRead(__option, error, response);
+       delete this;
+}
+
+void Querier::__convertToResponse(std::vector<Json> &sqlResult, Json &response)
+{
+       std::list<std::string> keys;
+       std::string val;
+
+       response.set(NULL, KEY_RESULT_SIZE, static_cast<int>(sqlResult.size()));
+
+       for (Json &tuple : sqlResult) {
+               tuple.getKeys(&keys);
+               for (std::string &key : keys) {
+                       tuple.get(NULL, key.c_str(), &val);
+                       response.append(NULL, key.c_str(), val);
+               }
+               keys.clear();
+       }
+}
diff --git a/src/server/legacy/Querier.h b/src/server/legacy/Querier.h
new file mode 100644 (file)
index 0000000..0eed203
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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_QUERIER_H__
+#define __CONTEXT_QUERIER_H__
+
+#include <ContextProvider.h>
+#include <DatabaseManager.h>
+
+namespace ctx {
+
+       class Querier : public IDatabaseListener {
+       public:
+               Querier(ContextProvider *provider, Json option);
+               virtual ~Querier();
+
+               virtual int queryRaw(int startTime, int endTime);
+               virtual int query(int startTime, int endTime);
+               virtual int query(int startTime, int endTime, int anchor, int interval);
+
+       protected:
+               int query(const char *sql);
+               void onTableCreated(unsigned int queryId, int error);
+               void onInserted(unsigned int queryId, int error, int64_t rowId);
+               void onExecuted(unsigned int queryId, int error, std::vector<Json>& records);
+
+       private:
+               void __convertToResponse(std::vector<Json> &sqlResult, Json &response);
+
+               DatabaseManager __dbMgr;
+               ContextProvider *__provider;
+               Json __option;
+       };
+}
+
+#endif /* __CONTEXT_QUERIER_H__ */
diff --git a/src/server/legacy/SensorLogger.cpp b/src/server/legacy/SensorLogger.cpp
new file mode 100644 (file)
index 0000000..6bc92ea
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "TimeUtil.h"
+#include "SensorLogger.h"
+
+using namespace ctx;
+
+SensorLogger::SensorLogger() :
+       __lastRemovalTime(0)
+{
+}
+
+SensorLogger::~SensorLogger()
+{
+}
+
+void SensorLogger::flushCache(bool force)
+{
+}
+
+bool SensorLogger::executeQuery(const char *query)
+{
+       return __dbMgr.execute(0, query, NULL);
+}
+
+void SensorLogger::removeExpired(const char *subject, const char *tableName, const char *timeKey)
+{
+       uint64_t timestamp = TimeUtil::getTime();
+
+       if (timestamp - __lastRemovalTime < SEC_TO_MS(SECONDS_PER_HOUR))
+               return;
+
+       char *query = sqlite3_mprintf(
+                       "DELETE FROM %s WHERE %s < " \
+                       "%llu - (SELECT MAX(" KEY_RETENTION ") * 1000 FROM " CLIENT_INFO \
+                       " WHERE " KEY_SUBJECT "='%s')",
+                       tableName, timeKey, timestamp, subject);
+
+       __dbMgr.execute(0, query, NULL);
+       sqlite3_free(query);
+
+       __lastRemovalTime = timestamp;
+}
diff --git a/src/server/legacy/SensorLogger.h b/src/server/legacy/SensorLogger.h
new file mode 100644 (file)
index 0000000..76d7ec6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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_LOGGER_H__
+#define __CONTEXT_SENSOR_LOGGER_H__
+
+#include <DatabaseManager.h>
+
+namespace ctx {
+
+       class SensorLogger {
+       public:
+               SensorLogger();
+               virtual ~SensorLogger();
+
+               virtual bool start() = 0;
+               virtual void stop() = 0;
+               virtual void flushCache(bool force = false);
+
+       protected:
+               bool executeQuery(const char *query);
+
+               virtual void removeExpired(const char *subject, const char *tableName, const char *timeKey);
+
+       private:
+               uint64_t __lastRemovalTime;
+               DatabaseManager __dbMgr;
+       };
+}
+
+#endif /* __CONTEXT_SENSOR_LOGGER_H__ */
diff --git a/src/server/legacy/SensorProvider.cpp b/src/server/legacy/SensorProvider.cpp
new file mode 100644 (file)
index 0000000..47d5269
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * 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 <ctime>
+#include <cmath>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "SensorProvider.h"
+
+using namespace ctx;
+
+std::map<std::string, SensorProvider*> SensorProvider::__providerMap;
+
+SensorProvider::SensorProvider(const char *subject) :
+       ContextProvider(subject),
+       sensorLogger(NULL)
+{
+       __providerMap[subject] = this;
+}
+
+SensorProvider::~SensorProvider()
+{
+       __providerMap.erase(getSubject());
+       delete sensorLogger;
+}
+
+int SensorProvider::subscribe(Json option, Json *requestResult)
+{
+       return ERR_NONE;
+}
+
+int SensorProvider::unsubscribe(Json option)
+{
+       return ERR_NONE;
+}
+
+int SensorProvider::read(Json option, Json *requestResult)
+{
+       int endTime = static_cast<int>(time(NULL)) + 1;
+       int startTime = endTime - DEFAULT_QUERY_PERIOD - 1;
+       int anchor = -1;
+       int interval = -1;
+
+       if (option.get(NULL, KEY_START_TIME, &startTime))
+               IF_FAIL_RETURN(startTime >= 0, ERR_INVALID_PARAMETER);
+
+       if (option.get(NULL, KEY_END_TIME, &endTime))
+               IF_FAIL_RETURN(endTime >= 0, ERR_INVALID_PARAMETER);
+
+       if (option.get(NULL, KEY_ANCHOR, &anchor))
+               IF_FAIL_RETURN(anchor >= 0, ERR_INVALID_PARAMETER);
+
+       if (option.get(NULL, KEY_INTERVAL, &interval))
+               IF_FAIL_RETURN(interval >= 0, ERR_INVALID_PARAMETER);
+
+       if (endTime >= 0 && startTime >= endTime)
+               return ERR_INVALID_PARAMETER;
+
+       if (interval > 0 && anchor < 0)
+               anchor = endTime;
+
+       if (anchor >= 0 && interval < 0)
+               interval = static_cast<int>(ceil(static_cast<double>(endTime - startTime) / SECONDS_PER_MINUTE));
+
+       int ret;
+       Querier *querier = getQuerier(option);
+       IF_FAIL_RETURN(querier, ERR_OPERATION_FAILED);
+
+       sensorLogger->flushCache(true);
+
+       if (interval == 0)
+               ret = querier->queryRaw(startTime, endTime);
+       else if (interval > 0)
+               ret = querier->query(startTime, endTime, anchor, interval * SECONDS_PER_MINUTE);
+       else
+               ret = querier->query(startTime, endTime);
+
+       if (ret != ERR_NONE)
+               delete querier;
+
+       return ret;
+}
+
+int SensorProvider::write(Json data, Json *requestResult)
+{
+       IF_FAIL_RETURN(sensorLogger, ERR_OPERATION_FAILED);
+
+       std::string operation;
+       std::string pkgId;
+       Json option;
+       int retentionPeriod = DEFAULT_RETENTION;
+
+       _J("Data", data);
+
+       IF_FAIL_RETURN(data.get(NULL, KEY_OPERATION, &operation), ERR_INVALID_PARAMETER);
+       IF_FAIL_RETURN(data.get(NULL, KEY_CLIENT_PKG_ID, &pkgId), ERR_INVALID_PARAMETER);
+
+       data.get(NULL, KEY_OPTION, &option);
+
+       if (option.get(NULL, KEY_RETENTION, &retentionPeriod)) {
+               retentionPeriod *= SECONDS_PER_HOUR;
+               option.remove(NULL, KEY_RETENTION);
+       }
+
+       IF_FAIL_RETURN(verifyOption(option), ERR_INVALID_PARAMETER);
+
+       if (operation == VAL_START)
+               return __addClient(pkgId, retentionPeriod, option);
+       else if (operation == VAL_STOP)
+               return __removeClient(pkgId);
+
+       return ERR_NOT_SUPPORTED;
+}
+
+bool SensorProvider::verifyOption(Json option)
+{
+       std::list<std::string> keys;
+       option.getKeys(&keys);
+       return keys.size() == 0;
+}
+
+int SensorProvider::__addClient(std::string pkgId, int retentionPeriod, Json option)
+{
+       Json tmp;
+       int ret;
+
+       /* Validate the retention period */
+       IF_FAIL_RETURN(retentionPeriod > 0 && retentionPeriod <= MAX_RETENTION_PERIOD, ERR_INVALID_PARAMETER);
+
+       /* Check if the app already started Sensor recording */
+       ret = __clientInfo.get(getSubject(), pkgId, tmp);
+       IF_FAIL_RETURN(ret != ERR_NONE, ERR_ALREADY_STARTED);
+       IF_FAIL_RETURN(ret == ERR_NO_DATA, ERR_OPERATION_FAILED);
+
+       /* Store the app's request */
+       if (!__clientInfo.set(getSubject(), pkgId, option, retentionPeriod))
+               return ERR_OPERATION_FAILED;
+
+       /* If not listening the sensor yet, start */
+       sensorLogger->start();
+
+       return ERR_NONE;
+}
+
+int SensorProvider::__removeClient(std::string pkgId)
+{
+       std::vector<Json> options;
+       int ret;
+
+       /* Remove the app's request first */
+       IF_FAIL_RETURN(__clientInfo.remove(getSubject(), pkgId), ERR_OPERATION_FAILED);
+
+       /* Check if there is no client anymore */
+       ret = __clientInfo.get(getSubject(), options);
+
+       if (ret == ERR_NONE) {
+               /* Still, one or more clients exist */
+               /* If necessary, the logger restarts its logging logic with updated parameters */
+               sensorLogger->start();
+               return ERR_NONE;
+
+       } else if (ret == ERR_NO_DATA) {
+               /* No client */
+               sensorLogger->stop();
+               return ERR_NONE;
+       }
+
+       return ERR_OPERATION_FAILED;
+}
+
+void SensorProvider::removeClient(std::string subject, std::string pkgId)
+{
+       __providerMap[subject]->__removeClient(pkgId);
+}
diff --git a/src/server/legacy/SensorProvider.h b/src/server/legacy/SensorProvider.h
new file mode 100644 (file)
index 0000000..5b806a0
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_PROVIDER_H__
+#define __CONTEXT_SENSOR_PROVIDER_H__
+
+#include <map>
+#include <ContextProvider.h>
+#include "ClientInfo.h"
+#include "SensorLogger.h"
+#include "Querier.h"
+
+namespace ctx {
+
+       class SensorProvider : public ContextProvider {
+       public:
+               SensorProvider(const char *subject);
+               virtual ~SensorProvider();
+
+               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);
+
+               static void removeClient(std::string subject, std::string pkgId);
+
+       protected:
+               virtual Querier* getQuerier(Json option) = 0;
+               virtual bool verifyOption(Json option);
+
+               SensorLogger *sensorLogger;
+
+       private:
+               int __addClient(std::string pkgId, int retentionPeriod, Json option);
+               int __removeClient(std::string pkgId);
+
+               ClientInfo __clientInfo;
+
+               static std::map<std::string, SensorProvider*> __providerMap;
+       };
+}
+
+#endif /* _CONTEXT_SENSOR_PROVIDER_H_ */
diff --git a/src/server/legacy/SensorProxy.cpp b/src/server/legacy/SensorProxy.cpp
new file mode 100644 (file)
index 0000000..98dd0a6
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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 <Types.h>
+#include "SensorProxy.h"
+
+#define SENSOR_EVENT(X) (((int)(X) << 16) | 0x01)
+
+using namespace ctx;
+
+SensorProxy::SensorProxy() :
+       sensorHandle(-1),
+       sensorType(UNKNOWN_SENSOR),
+       powerSave(true),
+       samplingInterval(0),
+       batchLatency(0),
+       userData(NULL)
+{
+}
+
+SensorProxy::~SensorProxy()
+{
+       unlisten();
+}
+
+void SensorProxy::setSensor(sensor_type_t type)
+{
+       sensorType = type;
+}
+
+void SensorProxy::setPowerSave(bool ps)
+{
+       powerSave = ps;
+}
+
+void SensorProxy::setSamplingInterval(unsigned int interval)
+{
+       samplingInterval = interval;
+}
+
+void SensorProxy::setBatchLatency(unsigned int latency)
+{
+       batchLatency = latency;
+}
+
+void SensorProxy::setUserData(void *data)
+{
+       userData = data;
+}
+
+bool SensorProxy::listen()
+{
+       _D("#Sensor = %#x", sensorType);
+
+       sensor_t sensor = sensord_get_sensor(sensorType);
+       IF_FAIL_RETURN_TAG(sensor, false, _E, "Getting sensor failed");
+
+       sensorHandle = sensord_connect(sensor);
+       IF_FAIL_RETURN_TAG(sensorHandle >= 0, false, _E, "Connection failed");
+
+       if (!sensord_register_event(sensorHandle, SENSOR_EVENT(sensorType), samplingInterval, batchLatency, __eventCb, this)) {
+               _E("Event registration failed");
+               sensord_disconnect(sensorHandle);
+               sensorHandle = -1;
+               return false;
+       }
+
+       if (!sensord_start(sensorHandle, powerSave ? SENSOR_OPTION_DEFAULT : SENSOR_OPTION_ALWAYS_ON)) {
+               _E("Starting failed");
+               sensord_unregister_event(sensorHandle, SENSOR_EVENT(sensorType));
+               sensord_disconnect(sensorHandle);
+               sensorHandle = -1;
+               return false;
+       }
+
+       return true;
+}
+
+void SensorProxy::unlisten()
+{
+       IF_FAIL_VOID(sensorHandle >= 0);
+
+       sensord_stop(sensorHandle);
+       sensord_unregister_event(sensorHandle, SENSOR_EVENT(sensorType));
+       sensord_disconnect(sensorHandle);
+       sensorHandle = -1;
+}
+
+void SensorProxy::flush()
+{
+       IF_FAIL_VOID(sensorHandle >= 0);
+       sensord_flush(sensorHandle);
+}
+
+bool SensorProxy::isRunning()
+{
+       return sensorHandle >= 0;
+}
+
+bool SensorProxy::isSupported(sensor_type_t type)
+{
+       sensor_t sensor = sensord_get_sensor(type);
+       return (sensor != NULL);
+}
+
+void SensorProxy::__eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData)
+{
+       SensorProxy *instance = static_cast<SensorProxy*>(cbData);
+       instance->onEvent(eventData);
+}
diff --git a/src/server/legacy/SensorProxy.h b/src/server/legacy/SensorProxy.h
new file mode 100644 (file)
index 0000000..7ae1c87
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_PROXY_H__
+#define __CONTEXT_SENSOR_PROXY_H__
+
+#include <sensor_internal.h>
+
+namespace ctx {
+
+       class SensorProxy {
+       public:
+               SensorProxy();
+               virtual ~SensorProxy();
+
+               void setSensor(sensor_type_t type);
+               void setPowerSave(bool ps);
+               void setSamplingInterval(unsigned int interval);
+               void setBatchLatency(unsigned int latency);
+               void setUserData(void *data);
+
+               bool listen();
+               void unlisten();
+               bool isRunning();
+               void flush();
+
+       protected:
+               int sensorHandle;
+               sensor_type_t sensorType;
+               bool powerSave;
+               unsigned int samplingInterval;
+               unsigned int batchLatency;
+               void *userData;
+
+               static bool isSupported(sensor_type_t type);
+
+               virtual void onEvent(sensor_data_t *eventData) = 0;
+
+       private:
+               static void __eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData);
+       };
+
+}
+
+#endif /* __CONTEXT_SENSOR_PROXY_H__ */
diff --git a/src/server/legacy/TimeUtil.cpp b/src/server/legacy/TimeUtil.cpp
new file mode 100644 (file)
index 0000000..2e37da6
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 <time.h>
+#include "TypesInternal.h"
+#include "TimeUtil.h"
+
+/* NOTE: CLOCK_BOOTTIME is defined in linux/time.h.
+         But if it is included, we encounters the redefinition error of timespec. */
+#define CLOCK_BOOTTIME 7
+
+#define DIFF(X, Y)     ((X) > (Y) ? (X) - (Y) : (Y) - (X))
+#define SEC_TO_MSEC(X) ((uint64_t)(X) * 1000ull)
+#define USEC_TO_MSEC(X)        ((uint64_t)(X) / 1000ull)
+#define NSEC_TO_MSEC(X)        ((uint64_t)(X) / 1000000ull)
+#define EPSILON        3ull
+
+using namespace ctx;
+
+TimeUtil::TimeUtil()
+{
+}
+
+uint64_t TimeUtil::getTime()
+{
+       struct timespec ts;
+       uint64_t epochInMSec;
+
+       clock_gettime(CLOCK_REALTIME_COARSE, &ts);
+       epochInMSec = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
+
+       return epochInMSec;
+}
+
+uint64_t TimeUtil::getTime(unsigned long long sensorTimestamp)
+{
+       uint64_t currentEpoch = getTime();
+       uint64_t sensorTimeMSec = USEC_TO_MSEC(sensorTimestamp);
+
+       bool isEpoch = DIFF(currentEpoch, sensorTimeMSec) < SEC_TO_MSEC(SECONDS_PER_DAY);
+
+       if (isEpoch)
+               return sensorTimeMSec;
+
+
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+
+       uint64_t currentMonotonic = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
+       bool isMonotonic = currentMonotonic + EPSILON > sensorTimeMSec;
+
+       if (isMonotonic)
+               return currentEpoch - currentMonotonic + sensorTimeMSec;
+
+
+       clock_gettime(CLOCK_BOOTTIME, &ts);
+       uint64_t currentBootTime = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
+
+       return currentEpoch - currentBootTime + sensorTimeMSec;
+}
diff --git a/src/server/legacy/TimeUtil.h b/src/server/legacy/TimeUtil.h
new file mode 100644 (file)
index 0000000..bdacf06
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_TIME_UTIL_H__
+#define __CONTEXT_TIME_UTIL_H__
+
+#include <stdint.h>
+
+namespace ctx {
+
+       class TimeUtil {
+       public:
+               static uint64_t getTime();
+               static uint64_t getTime(unsigned long long sensorTimestamp);
+
+       private:
+               TimeUtil();
+       };
+
+}
+
+#endif /* __CONTEXT_TIME_UTIL_H__ */
diff --git a/src/server/legacy/TypesInternal.h b/src/server/legacy/TypesInternal.h
new file mode 100644 (file)
index 0000000..0bd3cb5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_INTERNAL_H__
+#define __CONTEXT_SENSOR_RECORDER_TYPES_INTERNAL_H__
+
+/* Tables */
+#define CLIENT_INFO                    "SensorClientInfo"
+
+#define PEDOMETER_RECORD               "SensorPedometerRecord"
+#define PRESSURE_RECORD                        "SensorPressureRecord"
+#define SLEEP_MONITOR_RECORD   "SensorSleepMonitorRecord"
+#define HEART_RATE_RECORD              "SensorHeartRateRecord"
+
+/* Privileges */
+#define PRIV_HEALTHINFO                "healthinfo"
+
+/* Constants */
+#define SECONDS_PER_MINUTE     60
+#define SECONDS_PER_HOUR       3600
+#define SECONDS_PER_DAY                86400
+
+#define MAX_RETENTION_PERIOD   2678400                         /* 1 month (31 days) */
+#define DEFAULT_RETENTION              SECONDS_PER_HOUR        /* 1 hour */
+#define DEFAULT_QUERY_PERIOD   SECONDS_PER_DAY         /* 1 day */
+
+/* Time Conversions */
+#define SEC_TO_MS(X)   ((X) * 1000)
+
+/* SQL Helper */
+#define TIME_QUANTIZER(key)    "ROUND((CAST(" key " AS REAL) - %llu)/CAST(%llu AS REAL) + 0.5)"
+
+#endif /* __CONTEXT_SENSOR_RECORDER_TYPES_INTERNAL_H__ */
diff --git a/src/server/legacy/UninstallMonitor.cpp b/src/server/legacy/UninstallMonitor.cpp
new file mode 100644 (file)
index 0000000..026ea10
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 "ClientInfo.h"
+#include "UninstallMonitor.h"
+
+using namespace ctx;
+
+UninstallMonitor::UninstallMonitor() :
+       __dbusSignalId(-1),
+       __dbusWatcher(DBusType::SYSTEM)
+{
+       __dbusSignalId = __dbusWatcher.watch(NULL,
+                       "/org/tizen/pkgmgr/signal", "org.tizen.pkgmgr.signal", "uninstall", this);
+}
+
+UninstallMonitor::~UninstallMonitor()
+{
+       if (__dbusSignalId > 0)
+               __dbusWatcher.unwatch(__dbusSignalId);
+}
+
+void UninstallMonitor::onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param)
+{
+       const gchar *pkgId = NULL;
+       const gchar *key = NULL;
+       const gchar *val = NULL;
+
+       g_variant_get(param, "(u&s&s&s&s&s&s)", NULL, NULL, NULL, &pkgId, NULL, &key, &val);
+       _D("%s, %s, %s", pkgId, key, val);
+
+       IF_FAIL_VOID(pkgId && STR_EQ(key, "end") && STR_EQ(val, "ok"));
+
+       _I("'%s' has been removed", pkgId);
+       ClientInfo::purgeClient(pkgId);
+}
diff --git a/src/server/legacy/UninstallMonitor.h b/src/server/legacy/UninstallMonitor.h
new file mode 100644 (file)
index 0000000..baa3659
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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_UNINSTALL_MONITOR_H__
+#define __CONTEXT_UNINSTALL_MONITOR_H__
+
+#include <DBusSignalWatcher.h>
+
+namespace ctx {
+
+       class UninstallMonitor : public IDBusSignalListener {
+       public:
+               UninstallMonitor();
+               ~UninstallMonitor();
+
+               void onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param);
+
+       private:
+               int64_t __dbusSignalId;
+               DBusSignalWatcher __dbusWatcher;
+       };
+
+}
+
+#endif /* __CONTEXT_UNINSTALL_MONITOR_H__ */
diff --git a/src/server/legacy/heartrate/HeartRate.cpp b/src/server/legacy/heartrate/HeartRate.cpp
new file mode 100644 (file)
index 0000000..3afa98e
--- /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.
+ */
+
+#include <SensorRecorderTypes.h>
+#include <Util.h>
+#include "../TypesInternal.h"
+#include "HeartRateLogger.h"
+#include "HeartRateQuerier.h"
+#include "HeartRate.h"
+
+using namespace ctx;
+
+HeartRateProvider::HeartRateProvider() :
+       SensorProvider(SUBJ_SENSOR_HEART_RATE)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) HeartRateLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+HeartRateProvider::~HeartRateProvider()
+{
+}
+
+void HeartRateProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+       privilege.push_back(PRIV_HEALTHINFO);
+}
+
+bool HeartRateProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.heart_rate_monitor");
+}
+
+Querier* HeartRateProvider::getQuerier(Json option)
+{
+       HeartRateQuerier *querier = new(std::nothrow) HeartRateQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
+
+bool HeartRateProvider::verifyOption(Json option)
+{
+       std::list<std::string> keys;
+       option.getKeys(&keys);
+
+       IF_FAIL_RETURN(keys.size() <= 1, false);
+
+       int interval = 0;
+       if (option.get(NULL, KEY_INTERVAL, &interval)) {
+               if (interval < MIN_MEASURING_INTERVAL || interval > MAX_MEASURING_INTERVAL)
+                       return false;
+       }
+
+       return true;
+}
diff --git a/src/server/legacy/heartrate/HeartRate.h b/src/server/legacy/heartrate/HeartRate.h
new file mode 100644 (file)
index 0000000..71f0812
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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_HEARTRATE_PROVIDER_H__
+#define __CONTEXT_HEARTRATE_PROVIDER_H__
+
+#include "../SensorProvider.h"
+
+namespace ctx {
+
+       class HeartRateProvider : public SensorProvider {
+       public:
+               HeartRateProvider();
+               ~HeartRateProvider();
+
+               bool isSupported();
+               void getPrivilege(std::vector<const char*> &privilege);
+
+       protected:
+               Querier* getQuerier(Json option);
+               bool verifyOption(Json option);
+       };
+}
+
+#endif /* _CONTEXT_HEARTRATE_PROVIDER_H_ */
diff --git a/src/server/legacy/heartrate/HeartRateLogger.cpp b/src/server/legacy/heartrate/HeartRateLogger.cpp
new file mode 100644 (file)
index 0000000..8ef6895
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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 <climits>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "../ClientInfo.h"
+#include "../TimeUtil.h"
+#include "HeartRateLogger.h"
+
+#define SAMPLING_INTERVAL      200             /* ms */
+#define VALID_HR_LB                    30              /* BPM */
+#define MIN_VALID_COUNT                3
+#define MEASURING_LIMIT                10000   /* ms */
+
+using namespace ctx;
+
+HeartRateLogger::HeartRateLogger() :
+       __timerMgr(NULL),
+       __timerId(-1),
+       __timerInterval(INT_MAX),
+       __expiredTime(0)
+{
+       setSensor(HRM_SENSOR);
+       setPowerSave(false);
+       setSamplingInterval(SAMPLING_INTERVAL);
+
+       /* Create the log table */
+       executeQuery(
+                       "CREATE TABLE IF NOT EXISTS " HEART_RATE_RECORD " (" \
+                               KEY_UNIV_TIME " INTEGER NOT NULL PRIMARY KEY, " \
+                               KEY_HEART_RATE " REAL NOT NULL" \
+                       ")");
+
+       ClientInfo clientInfo;
+       if (clientInfo.exist(SUBJ_SENSOR_HEART_RATE))
+               start();
+}
+
+HeartRateLogger::~HeartRateLogger()
+{
+       stop();
+}
+
+bool HeartRateLogger::start()
+{
+       std::vector<Json> options;
+       ClientInfo clientInfo;
+       float interval = MAX_MEASURING_INTERVAL;
+
+       if (clientInfo.get(SUBJ_SENSOR_HEART_RATE, options) != ERR_NONE)
+               return false;
+
+       clientInfo.getParam(options, KEY_INTERVAL, &interval, NULL);
+
+       if (!__timerMgr) {
+               __timerMgr = new(std::nothrow) TimerManager;
+               IF_FAIL_RETURN_TAG(__timerMgr, false, _E, "Memory allocation failed");
+       }
+
+       if (interval == __timerInterval)
+               return true;
+
+       __timerInterval = interval;
+
+       _I(GREEN("Start to record (at every %d minutes)"), __timerInterval);
+
+       if (__timerId > 0)
+               __timerMgr->remove(__timerId);
+
+       __timerId = __timerMgr->setFor(__timerInterval, this);
+
+       if (__timerId < 0) {
+               _E("Setting timer failed");
+               __timerInterval = INT_MAX;
+               return false;
+       }
+
+       return true;
+}
+
+void HeartRateLogger::stop()
+{
+       _I(GREEN("Stop recording"));
+
+       if (__timerMgr)
+               delete __timerMgr;
+
+       __timerMgr = NULL;
+       __timerId = -1;
+       __timerInterval = INT_MAX;
+
+       unlisten();
+}
+
+void HeartRateLogger::flushCache(bool force)
+{
+}
+
+bool HeartRateLogger::onTimerExpired(int timerId)
+{
+       IF_FAIL_RETURN(!isRunning(), true);
+
+       if (!listen())
+               _W("Starting sensor failed");
+
+       __expiredTime = TimeUtil::getTime();
+       _I("Measuring starts at %llu", __expiredTime);
+       return true;
+}
+
+void HeartRateLogger::onEvent(sensor_data_t *eventData)
+{
+       static int validCnt = 0;
+       uint64_t receivedTime = TimeUtil::getTime();
+
+       IF_FAIL_CATCH_TAG(receivedTime - __expiredTime < MEASURING_LIMIT, _I, "Measuring failed (timeout)");
+
+       if (eventData->values[0] > VALID_HR_LB)
+               ++validCnt;
+       else
+               validCnt = 0;
+
+       if (validCnt < MIN_VALID_COUNT)
+               return;
+
+       __record(eventData->values[0], receivedTime);
+
+CATCH:
+       removeExpired(SUBJ_SENSOR_HEART_RATE, HEART_RATE_RECORD, KEY_UNIV_TIME);
+       unlisten();
+}
+
+void HeartRateLogger::__record(float heartrate, uint64_t eventTime)
+{
+       char *query = sqlite3_mprintf(
+                       "INSERT INTO " HEART_RATE_RECORD \
+                               " (" KEY_UNIV_TIME ", " KEY_HEART_RATE ") VALUES (%llu, %.3f)",
+                       eventTime, heartrate);
+       executeQuery(query);
+       sqlite3_free(query);
+}
diff --git a/src/server/legacy/heartrate/HeartRateLogger.h b/src/server/legacy/heartrate/HeartRateLogger.h
new file mode 100644 (file)
index 0000000..fa12aa6
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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_HEARTRATE_LOGGER_H__
+#define __CONTEXT_HEARTRATE_LOGGER_H__
+
+#include <TimerManager.h>
+#include "../SensorLogger.h"
+#include "../SensorProxy.h"
+
+#define MIN_MEASURING_INTERVAL 10              /* minutes */
+#define MAX_MEASURING_INTERVAL 1440    /* minutes */
+
+namespace ctx {
+
+       class HeartRateLogger : public SensorLogger, public SensorProxy, public ITimerListener {
+       public:
+               HeartRateLogger();
+               ~HeartRateLogger();
+
+               bool start();
+               void stop();
+               void flushCache(bool force = false);
+
+       protected:
+               bool onTimerExpired(int timerId);
+               void onEvent(sensor_data_t *eventData);
+
+       private:
+               void __record(float heartrate, uint64_t eventTime);
+
+               TimerManager *__timerMgr;
+               int __timerId;
+               int __timerInterval;
+               uint64_t __expiredTime;
+       };
+}
+
+#endif /* __CONTEXT_HEARTRATE_LOGGER_H__ */
diff --git a/src/server/legacy/heartrate/HeartRateQuerier.cpp b/src/server/legacy/heartrate/HeartRateQuerier.cpp
new file mode 100644 (file)
index 0000000..1bae5a6
--- /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.
+ */
+
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "HeartRateQuerier.h"
+
+#define PROJECTION \
+       KEY_HEART_RATE ", " \
+       KEY_UNIV_TIME " AS " KEY_START_TIME ", " \
+       KEY_UNIV_TIME " AS " KEY_END_TIME
+
+using namespace ctx;
+
+HeartRateQuerier::HeartRateQuerier(ContextProvider *provider, Json option) :
+       Querier(provider, option)
+{
+}
+
+HeartRateQuerier::~HeartRateQuerier()
+{
+}
+
+int HeartRateQuerier::queryRaw(int startTime, int endTime)
+{
+       return query(startTime, endTime);
+}
+
+int HeartRateQuerier::query(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " HEART_RATE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
diff --git a/src/server/legacy/heartrate/HeartRateQuerier.h b/src/server/legacy/heartrate/HeartRateQuerier.h
new file mode 100644 (file)
index 0000000..335d902
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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_HEARTRATE_QUERIER_H__
+#define __CONTEXT_HEARTRATE_QUERIER_H__
+
+#include "../Querier.h"
+
+namespace ctx {
+
+       class HeartRateQuerier : public Querier {
+       public:
+               HeartRateQuerier(ContextProvider *provider, Json option);
+               ~HeartRateQuerier();
+
+               int queryRaw(int startTime, int endTime);
+               int query(int startTime, int endTime);
+       };
+}
+
+#endif /* __CONTEXT_HEARTRATE_QUERIER_H__ */
diff --git a/src/server/legacy/pedometer/Pedometer.cpp b/src/server/legacy/pedometer/Pedometer.cpp
new file mode 100644 (file)
index 0000000..8752754
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 <SensorRecorderTypes.h>
+#include <Util.h>
+#include "../TypesInternal.h"
+#include "PedometerLogger.h"
+#include "PedometerQuerier.h"
+#include "Pedometer.h"
+
+using namespace ctx;
+
+PedometerProvider::PedometerProvider() :
+       SensorProvider(SUBJ_SENSOR_PEDOMETER)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) PedometerLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+PedometerProvider::~PedometerProvider()
+{
+}
+
+void PedometerProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+       privilege.push_back(PRIV_HEALTHINFO);
+}
+
+bool PedometerProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.pedometer");
+}
+
+Querier* PedometerProvider::getQuerier(Json option)
+{
+       PedometerQuerier *querier = new(std::nothrow) PedometerQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
diff --git a/src/server/legacy/pedometer/Pedometer.h b/src/server/legacy/pedometer/Pedometer.h
new file mode 100644 (file)
index 0000000..7fee01f
--- /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_PEDOMETER_PROVIDER_H__
+#define __CONTEXT_PEDOMETER_PROVIDER_H__
+
+#include "../SensorProvider.h"
+
+namespace ctx {
+
+       class PedometerProvider : public SensorProvider {
+       public:
+               PedometerProvider();
+               ~PedometerProvider();
+
+               bool isSupported();
+               void getPrivilege(std::vector<const char*> &privilege);
+
+       protected:
+               Querier* getQuerier(Json option);
+       };
+}
+
+#endif /* _CONTEXT_PEDOMETER_PROVIDER_H_ */
diff --git a/src/server/legacy/pedometer/PedometerLogger.cpp b/src/server/legacy/pedometer/PedometerLogger.cpp
new file mode 100644 (file)
index 0000000..cc44856
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * 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 <inttypes.h>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "../ClientInfo.h"
+#include "../TimeUtil.h"
+#include "PedometerLogger.h"
+
+#define MIN_INTERVAL   60000
+
+using namespace ctx;
+
+PedometerLogger::PedometerLogger() :
+       __firstEvent(true)
+{
+       setSensor(HUMAN_PEDOMETER_SENSOR);
+       setPowerSave(false);
+
+       /* Create the log table */
+       executeQuery(
+                       "CREATE TABLE IF NOT EXISTS " PEDOMETER_RECORD " (" \
+                               KEY_START_TIME " INTEGER NOT NULL, " \
+                               KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \
+                               KEY_WALK_STEPS " INTEGER NOT NULL, " \
+                               KEY_RUN_STEPS " INTEGER NOT NULL, " \
+                               KEY_DISTANCE " REAL NOT NULL, " \
+                               KEY_CALORIES " REAL NOT NULL" \
+                       ")");
+
+       ClientInfo clientInfo;
+       if (clientInfo.exist(SUBJ_SENSOR_PEDOMETER))
+               start();
+}
+
+PedometerLogger::~PedometerLogger()
+{
+       stop();
+}
+
+bool PedometerLogger::start()
+{
+       IF_FAIL_RETURN_TAG(!isRunning(), true, _D, "Started already");
+       _I(GREEN("Start to record"));
+
+       if (listen()) {
+               flush();
+               return true;
+       }
+
+       return false;
+}
+
+void PedometerLogger::stop()
+{
+       IF_FAIL_VOID_TAG(isRunning(), _D, "Stopped already");
+       _I(GREEN("Stop recording"));
+
+       unlisten();
+       __firstEvent = true;
+
+       flushCache(true);
+}
+
+void PedometerLogger::flushCache(bool force)
+{
+       DataRecord record;
+       record.walkSteps = __lastRecord.walkSteps - __baseline.walkSteps;
+       record.runSteps  = __lastRecord.runSteps - __baseline.runSteps;
+       record.distance  = __lastRecord.distance - __baseline.distance;
+       record.calories  = __lastRecord.calories - __baseline.calories;
+
+       if (record.walkSteps + record.runSteps > 0) {
+               char *query = sqlite3_mprintf(
+                               "INSERT INTO " PEDOMETER_RECORD " (" \
+                                       KEY_START_TIME ", " \
+                                       KEY_END_TIME ", " \
+                                       KEY_WALK_STEPS ", " \
+                                       KEY_RUN_STEPS ", " \
+                                       KEY_DISTANCE ", " \
+                                       KEY_CALORIES ") " \
+                                       "VALUES (%llu, %llu, %u, %u, %.3f, %.3f)",
+                               __baseline.timestamp, __lastRecord.timestamp, record.walkSteps, record.runSteps, record.distance, record.calories);
+               executeQuery(query);
+               sqlite3_free(query);
+       }
+
+       __baseline = __lastRecord;
+}
+
+void PedometerLogger::onEvent(sensor_data_t *eventData)
+{
+       sensor_pedometer_data_t *pedometerData = reinterpret_cast<sensor_pedometer_data_t*>(eventData);
+       uint64_t timestamp = TimeUtil::getTime();
+
+       if (__firstEvent) {
+               __firstEvent = false;
+               __setRecord(__lastRecord, timestamp, pedometerData);
+               __baseline = __lastRecord;
+
+               _SD("Baseline: %u, %u, %.3f, %.3f",
+                               __baseline.walkSteps, __baseline.runSteps, __baseline.distance, __baseline.calories);
+
+       } else if (pedometerData->diffs_count == 0) {
+               _SD("Single: %.0f, %.0f, %.3f, %.3f",
+                               eventData->values[1], eventData->values[2], eventData->values[3], eventData->values[4]);
+               __recordSingle(pedometerData, timestamp);
+
+       } else {
+               _SD("Batch [%d]: %.0f, %.0f, %.3f, %.3f",
+                               pedometerData->diffs_count,
+                               eventData->values[1], eventData->values[2], eventData->values[3], eventData->values[4]);
+               __recordBatch(pedometerData, timestamp);
+       }
+
+       removeExpired(SUBJ_SENSOR_PEDOMETER, PEDOMETER_RECORD, KEY_END_TIME);
+}
+
+void PedometerLogger::__recordSingle(sensor_pedometer_data_t *eventData, uint64_t timestamp)
+{
+       if (timestamp - __baseline.timestamp >= MIN_INTERVAL)
+               flushCache();
+
+       __setRecord(__lastRecord, timestamp, eventData);
+}
+
+void PedometerLogger::__recordBatch(sensor_pedometer_data_t *eventData, uint64_t timestamp)
+{
+       flushCache();
+
+       std::string query("INSERT INTO " PEDOMETER_RECORD " (" \
+                               KEY_START_TIME ", " \
+                               KEY_END_TIME ", " \
+                               KEY_WALK_STEPS ", " \
+                               KEY_RUN_STEPS ", " \
+                               KEY_DISTANCE ", " \
+                               KEY_CALORIES ") VALUES ");
+       char buffer[256];
+
+       for (int i = 0; i < eventData->diffs_count; ++i) {
+               if (eventData->diffs[i].walk_steps + eventData->diffs[i].run_steps == 0) {
+                       _D("Skipping zero-count event");
+                       continue;
+               }
+
+               /* TODO: check the timestamps.. they look strange.. */
+               g_snprintf(buffer, sizeof(buffer), "(%" PRIu64 ", %" PRIu64 ", %d, %d, %.3f, %.3f),",
+                               i == 0 ? __baseline.timestamp : SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i-1].timestamp)),
+                               SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i].timestamp)),
+                               eventData->diffs[i].walk_steps,
+                               eventData->diffs[i].run_steps,
+                               eventData->diffs[i].distance,
+                               eventData->diffs[i].calories);
+               query += buffer;
+       }
+
+       query.resize(query.size() - 1);
+       IF_FAIL_VOID_TAG(query.at(query.size() - 1) == ')', _D, "No records");
+
+       executeQuery(query.c_str());
+
+       __setRecord(__lastRecord, timestamp, eventData);
+       __baseline = __lastRecord;
+}
+
+void PedometerLogger::__setRecord(DataRecord &record, uint64_t timestamp, sensor_pedometer_data_t *eventData)
+{
+       record.timestamp = timestamp;
+       record.walkSteps = static_cast<unsigned int>(eventData->values[1]);
+       record.runSteps  = static_cast<unsigned int>(eventData->values[2]);
+       record.distance  = eventData->values[3];
+       record.calories  = eventData->values[4];
+}
diff --git a/src/server/legacy/pedometer/PedometerLogger.h b/src/server/legacy/pedometer/PedometerLogger.h
new file mode 100644 (file)
index 0000000..f4b32f9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_PEDOMETER_LOGGER_H__
+#define __CONTEXT_PEDOMETER_LOGGER_H__
+
+#include "../SensorLogger.h"
+#include "../SensorProxy.h"
+
+namespace ctx {
+
+       class PedometerLogger : public SensorLogger, public SensorProxy {
+       public:
+               PedometerLogger();
+               ~PedometerLogger();
+
+               bool start();
+               void stop();
+               void flushCache(bool force = false);
+
+       protected:
+               void onEvent(sensor_data_t *eventData);
+
+       private:
+               struct DataRecord {
+                       uint64_t timestamp;
+                       unsigned int walkSteps;
+                       unsigned int runSteps;
+                       float distance;
+                       float calories;
+               };
+
+               void __recordSingle(sensor_pedometer_data_t *eventData, uint64_t timestamp);
+               void __recordBatch(sensor_pedometer_data_t *eventData, uint64_t timestamp);
+               void __setRecord(DataRecord &record, uint64_t timestamp, sensor_pedometer_data_t *eventData);
+
+               bool __firstEvent;
+               DataRecord __baseline;
+               DataRecord __lastRecord;
+       };
+}
+
+#endif /* __CONTEXT_PEDOMETER_LOGGER_H__ */
diff --git a/src/server/legacy/pedometer/PedometerQuerier.cpp b/src/server/legacy/pedometer/PedometerQuerier.cpp
new file mode 100644 (file)
index 0000000..3abf121
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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 <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "PedometerQuerier.h"
+
+#define PROJECTION \
+       "SUM(" KEY_WALK_STEPS " + " KEY_RUN_STEPS ") AS " KEY_STEPS ", " \
+       "SUM(" KEY_WALK_STEPS ") AS " KEY_WALK_STEPS ", " \
+       "SUM(" KEY_RUN_STEPS ") AS " KEY_RUN_STEPS ", " \
+       "SUM(" KEY_DISTANCE ") AS " KEY_DISTANCE ", " \
+       "SUM(" KEY_CALORIES ") AS " KEY_CALORIES ", " \
+       "MIN(" KEY_START_TIME ") AS " KEY_START_TIME ", " \
+       "MAX(" KEY_END_TIME ") AS " KEY_END_TIME
+
+#define PROJECTION_RAW \
+       KEY_WALK_STEPS " + " KEY_RUN_STEPS " AS " KEY_STEPS ", " \
+       KEY_WALK_STEPS ", " \
+       KEY_RUN_STEPS ", " \
+       KEY_DISTANCE ", " \
+       KEY_CALORIES ", " \
+       KEY_START_TIME ", " \
+       KEY_END_TIME
+
+using namespace ctx;
+
+PedometerQuerier::PedometerQuerier(ContextProvider *provider, Json option) :
+       Querier(provider, option)
+{
+}
+
+PedometerQuerier::~PedometerQuerier()
+{
+}
+
+int PedometerQuerier::queryRaw(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION_RAW \
+                       " FROM " PEDOMETER_RECORD \
+                       " WHERE " KEY_END_TIME " > %llu AND " KEY_END_TIME " <= %llu" \
+                       " ORDER BY " KEY_END_TIME " ASC",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PedometerQuerier::query(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PEDOMETER_RECORD \
+                       " WHERE " KEY_END_TIME " > %llu AND " KEY_END_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PedometerQuerier::query(int startTime, int endTime, int anchor, int interval)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PEDOMETER_RECORD \
+                       " WHERE " KEY_END_TIME " > %llu AND " KEY_END_TIME " <= %llu" \
+                       " GROUP BY " TIME_QUANTIZER(KEY_END_TIME) \
+                       " ORDER BY " KEY_END_TIME " ASC",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)),
+                       SEC_TO_MS(static_cast<uint64_t>(anchor)), SEC_TO_MS(static_cast<uint64_t>(interval)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
diff --git a/src/server/legacy/pedometer/PedometerQuerier.h b/src/server/legacy/pedometer/PedometerQuerier.h
new file mode 100644 (file)
index 0000000..21af1e1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_PEDOMETER_QUERIER_H__
+#define __CONTEXT_PEDOMETER_QUERIER_H__
+
+#include "../Querier.h"
+
+namespace ctx {
+
+       class PedometerQuerier : public Querier {
+       public:
+               PedometerQuerier(ContextProvider *provider, Json option);
+               ~PedometerQuerier();
+
+               int queryRaw(int startTime, int endTime);
+               int query(int startTime, int endTime);
+               int query(int startTime, int endTime, int anchor, int interval);
+       };
+}
+
+#endif /* __CONTEXT_PEDOMETER_QUERIER_H__ */
diff --git a/src/server/legacy/pressure/Pressure.cpp b/src/server/legacy/pressure/Pressure.cpp
new file mode 100644 (file)
index 0000000..76b60f4
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 <SensorRecorderTypes.h>
+#include <Util.h>
+#include "../TypesInternal.h"
+#include "PressureLogger.h"
+#include "PressureQuerier.h"
+#include "Pressure.h"
+
+using namespace ctx;
+
+PressureProvider::PressureProvider() :
+       SensorProvider(SUBJ_SENSOR_PRESSURE)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) PressureLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+PressureProvider::~PressureProvider()
+{
+}
+
+bool PressureProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.barometer");
+}
+
+Querier* PressureProvider::getQuerier(Json option)
+{
+       PressureQuerier *querier = new(std::nothrow) PressureQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
diff --git a/src/server/legacy/pressure/Pressure.h b/src/server/legacy/pressure/Pressure.h
new file mode 100644 (file)
index 0000000..419cfba
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_PRESSURE_PROVIDER_H__
+#define __CONTEXT_PRESSURE_PROVIDER_H__
+
+#include "../SensorProvider.h"
+
+namespace ctx {
+
+       class PressureProvider : public SensorProvider {
+       public:
+               PressureProvider();
+               ~PressureProvider();
+
+               bool isSupported();
+
+       protected:
+               Querier* getQuerier(Json option);
+       };
+}
+
+#endif /* _CONTEXT_PRESSURE_PROVIDER_H_ */
diff --git a/src/server/legacy/pressure/PressureLogger.cpp b/src/server/legacy/pressure/PressureLogger.cpp
new file mode 100644 (file)
index 0000000..0bb1fe4
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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 <inttypes.h>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "../ClientInfo.h"
+#include "../TimeUtil.h"
+#include "PressureLogger.h"
+
+#define SAMPLING_INTERVAL      60000
+#define BATCH_LATENCY          INT_MAX
+
+#define RESAMPLING_INTERVAL    20000
+#define CACHE_LIMIT                    20
+
+using namespace ctx;
+
+PressureLogger::PressureLogger()
+{
+       setSensor(PRESSURE_SENSOR);
+       setPowerSave(false);
+       setSamplingInterval(SAMPLING_INTERVAL);
+       setBatchLatency(BATCH_LATENCY);
+
+       /* Create the log table */
+       executeQuery(
+                       "CREATE TABLE IF NOT EXISTS " PRESSURE_RECORD " (" \
+                               KEY_UNIV_TIME " INTEGER NOT NULL PRIMARY KEY, " \
+                               KEY_PRESSURE " REAL NOT NULL" \
+                       ")");
+
+       ClientInfo clientInfo;
+       if (clientInfo.exist(SUBJ_SENSOR_PRESSURE))
+               start();
+}
+
+PressureLogger::~PressureLogger()
+{
+       stop();
+}
+
+bool PressureLogger::start()
+{
+       IF_FAIL_RETURN_TAG(!isRunning(), true, _D, "Started already");
+       _I(GREEN("Start to record"));
+
+       __lastEventTime = 0;
+       __cacheCount = 0;
+       __resetInsertionQuery();
+
+       return listen();
+}
+
+void PressureLogger::stop()
+{
+       IF_FAIL_VOID_TAG(isRunning(), _D, "Stopped already");
+       _I(GREEN("Stop recording"));
+
+       unlisten();
+       flushCache(true);
+}
+
+void PressureLogger::flushCache(bool force)
+{
+       IF_FAIL_VOID(force || __cacheCount > CACHE_LIMIT);
+
+       __insertionQuery.resize(__insertionQuery.size() - 1);
+       if (__insertionQuery.at(__insertionQuery.size() - 1) == ')')
+               executeQuery(__insertionQuery.c_str());
+
+       __cacheCount = 0;
+       __resetInsertionQuery();
+}
+
+void PressureLogger::onEvent(sensor_data_t *eventData)
+{
+       uint64_t eventTime = TimeUtil::getTime(eventData->timestamp);
+       __record(eventData->values[0], eventTime);
+       removeExpired(SUBJ_SENSOR_PRESSURE, PRESSURE_RECORD, KEY_UNIV_TIME);
+}
+
+void PressureLogger::__record(float pressure, uint64_t eventTime)
+{
+       IF_FAIL_VOID(eventTime - __lastEventTime >= RESAMPLING_INTERVAL);
+
+       char buffer[64];
+       g_snprintf(buffer, sizeof(buffer), "(%" PRIu64 ", %.5f),", eventTime, pressure);
+       _D("[%u] %s", __cacheCount, buffer);
+
+       __insertionQuery += buffer;
+       __lastEventTime = eventTime;
+       ++__cacheCount;
+
+       flushCache();
+}
+
+void PressureLogger::__resetInsertionQuery()
+{
+       __insertionQuery =
+               "INSERT INTO " PRESSURE_RECORD \
+                       " (" KEY_UNIV_TIME ", " KEY_PRESSURE ") VALUES ";
+}
diff --git a/src/server/legacy/pressure/PressureLogger.h b/src/server/legacy/pressure/PressureLogger.h
new file mode 100644 (file)
index 0000000..78b7fe5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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_PRESSURE_LOGGER_H__
+#define __CONTEXT_PRESSURE_LOGGER_H__
+
+#include "../SensorLogger.h"
+#include "../SensorProxy.h"
+
+namespace ctx {
+
+       class PressureLogger : public SensorLogger, public SensorProxy {
+       public:
+               PressureLogger();
+               ~PressureLogger();
+
+               bool start();
+               void stop();
+               void flushCache(bool force = false);
+
+       protected:
+               void onEvent(sensor_data_t *eventData);
+
+       private:
+               void __record(float pressure, uint64_t eventTime);
+               void __resetInsertionQuery();
+
+               uint64_t __lastEventTime;
+               uint32_t __cacheCount;
+               std::string __insertionQuery;
+       };
+}
+
+#endif /* __CONTEXT_PRESSURE_LOGGER_H__ */
diff --git a/src/server/legacy/pressure/PressureQuerier.cpp b/src/server/legacy/pressure/PressureQuerier.cpp
new file mode 100644 (file)
index 0000000..8d19638
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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 <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "PressureQuerier.h"
+
+#define PROJECTION \
+       "AVG(" KEY_PRESSURE ") AS " KEY_PRESSURE ", " \
+       "MIN(" KEY_PRESSURE ") AS " KEY_MIN_PRESSURE ", " \
+       "MAX(" KEY_PRESSURE ") AS " KEY_MAX_PRESSURE ", " \
+       "AVG(" KEY_PRESSURE ") AS " KEY_AVG_PRESSURE ", " \
+       "MIN(" KEY_UNIV_TIME ") AS " KEY_START_TIME ", " \
+       "MAX(" KEY_UNIV_TIME ") AS " KEY_END_TIME
+
+#define PROJECTION_RAW \
+       KEY_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_MIN_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_MAX_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_AVG_PRESSURE ", " \
+       KEY_UNIV_TIME " AS " KEY_START_TIME ", " \
+       KEY_UNIV_TIME " AS " KEY_END_TIME
+
+using namespace ctx;
+
+PressureQuerier::PressureQuerier(ContextProvider *provider, Json option) :
+       Querier(provider, option)
+{
+}
+
+PressureQuerier::~PressureQuerier()
+{
+}
+
+int PressureQuerier::queryRaw(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION_RAW \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PressureQuerier::query(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PressureQuerier::query(int startTime, int endTime, int anchor, int interval)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu" \
+                       " GROUP BY " TIME_QUANTIZER(KEY_UNIV_TIME) \
+                       " ORDER BY " KEY_END_TIME " ASC",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)),
+                       SEC_TO_MS(static_cast<uint64_t>(anchor)), SEC_TO_MS(static_cast<uint64_t>(interval)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
diff --git a/src/server/legacy/pressure/PressureQuerier.h b/src/server/legacy/pressure/PressureQuerier.h
new file mode 100644 (file)
index 0000000..1bd9aa6
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_PRESSURE_QUERIER_H__
+#define __CONTEXT_PRESSURE_QUERIER_H__
+
+#include "../Querier.h"
+
+namespace ctx {
+
+       class PressureQuerier : public Querier {
+       public:
+               PressureQuerier(ContextProvider *provider, Json option);
+               ~PressureQuerier();
+
+               int queryRaw(int startTime, int endTime);
+               int query(int startTime, int endTime);
+               int query(int startTime, int endTime, int anchor, int interval);
+       };
+}
+
+#endif /* __CONTEXT_PRESSURE_QUERIER_H__ */
diff --git a/src/server/legacy/sleep/Sleep.cpp b/src/server/legacy/sleep/Sleep.cpp
new file mode 100644 (file)
index 0000000..3ae40c9
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 <SensorRecorderTypes.h>
+#include <Util.h>
+#include "../TypesInternal.h"
+#include "SleepLogger.h"
+#include "SleepQuerier.h"
+#include "Sleep.h"
+
+using namespace ctx;
+
+SleepProvider::SleepProvider() :
+       SensorProvider(SUBJ_SENSOR_SLEEP_MONITOR)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) SleepLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+SleepProvider::~SleepProvider()
+{
+}
+
+void SleepProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+       privilege.push_back(PRIV_HEALTHINFO);
+}
+
+bool SleepProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.sleep_monitor");
+}
+
+Querier* SleepProvider::getQuerier(Json option)
+{
+       SleepQuerier *querier = new(std::nothrow) SleepQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
diff --git a/src/server/legacy/sleep/Sleep.h b/src/server/legacy/sleep/Sleep.h
new file mode 100644 (file)
index 0000000..c93310e
--- /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_SLEEP_PROVIDER_H__
+#define __CONTEXT_SLEEP_PROVIDER_H__
+
+#include "../SensorProvider.h"
+
+namespace ctx {
+
+       class SleepProvider : public SensorProvider {
+       public:
+               SleepProvider();
+               ~SleepProvider();
+
+               void getPrivilege(std::vector<const char*> &privilege);
+               bool isSupported();
+
+       protected:
+               Querier* getQuerier(Json option);
+       };
+}
+
+#endif /* _CONTEXT_SLEEP_PROVIDER_H_ */
diff --git a/src/server/legacy/sleep/SleepDetector.cpp b/src/server/legacy/sleep/SleepDetector.cpp
new file mode 100644 (file)
index 0000000..5367dac
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 <Types.h>
+#include "../TimeUtil.h"
+#include "SleepDetector.h"
+
+#define IDX_SLEEP_STATE        0
+
+using namespace ctx;
+
+SleepDetector::SleepDetector(SleepLogger *logger) :
+       __logger(logger)
+{
+       setSensor(HUMAN_SLEEP_DETECTOR_SENSOR);
+       setPowerSave(false);
+}
+
+SleepDetector::~SleepDetector()
+{
+}
+
+bool SleepDetector::start()
+{
+       _D("START");
+       return listen();
+}
+
+void SleepDetector::stop()
+{
+       _D("STOP");
+       unlisten();
+}
+
+void SleepDetector::onEvent(sensor_data_t *eventData)
+{
+       _D("%d at %llu", (int)eventData->values[0], eventData->timestamp);
+
+       uint64_t eventTime = TimeUtil::getTime(eventData->timestamp);
+
+       if (static_cast<int>(eventData->values[IDX_SLEEP_STATE]))
+               __logger->fallAsleep(eventTime);
+       else
+               __logger->wakeUp(eventTime);
+}
diff --git a/src/server/legacy/sleep/SleepDetector.h b/src/server/legacy/sleep/SleepDetector.h
new file mode 100644 (file)
index 0000000..104678c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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_SLEEP_DETECTOR_H__
+#define __CONTEXT_SLEEP_DETECTOR_H__
+
+#include "../SensorProxy.h"
+#include "SleepLogger.h"
+
+namespace ctx {
+
+       class SleepDetector : public SensorProxy {
+       public:
+               SleepDetector(SleepLogger *logger);
+               ~SleepDetector();
+
+               bool start();
+               void stop();
+
+       protected:
+               void onEvent(sensor_data_t *eventData);
+
+       private:
+               SleepLogger *__logger;
+       };
+}
+
+#endif /* __CONTEXT_SLEEP_DETECTOR_H__ */
diff --git a/src/server/legacy/sleep/SleepLogger.cpp b/src/server/legacy/sleep/SleepLogger.cpp
new file mode 100644 (file)
index 0000000..171df5b
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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 <inttypes.h>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "../ClientInfo.h"
+#include "../TimeUtil.h"
+#include "SleepDetector.h"
+#include "SleepMonitor.h"
+#include "SleepLogger.h"
+
+#define TIME_GAP 5000
+
+using namespace ctx;
+
+static SleepDetector *__sleepDetector = NULL;
+static SleepMonitor  *__sleepMonitor  = NULL;
+
+SleepLogger::SleepLogger() :
+       __startTime(0),
+       __endTime(0)
+{
+       __sleepDetector = NULL;
+       __sleepMonitor = NULL;
+
+       /* Create the log table */
+       executeQuery(
+                       "CREATE TABLE IF NOT EXISTS " SLEEP_MONITOR_RECORD " (" \
+                               KEY_START_TIME " INTEGER NOT NULL, " \
+                               KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \
+                               KEY_STATE " INTEGER NOT NULL DEFAULT 1" \
+                       ")");
+
+       ClientInfo clientInfo;
+       if (clientInfo.exist(SUBJ_SENSOR_SLEEP_MONITOR))
+               start();
+}
+
+SleepLogger::~SleepLogger()
+{
+       stop();
+}
+
+bool SleepLogger::start()
+{
+       if (!__sleepDetector) {
+               __sleepDetector = new(std::nothrow) SleepDetector(this);
+               __sleepMonitor = new(std::nothrow) SleepMonitor(this);
+
+               if (!__sleepDetector || !__sleepMonitor) {
+                       _E("Memory allocation failed");
+
+                       delete __sleepDetector;
+                       __sleepDetector = NULL;
+
+                       delete __sleepMonitor;
+                       __sleepMonitor = NULL;
+
+                       return false;
+               }
+       }
+
+       if (__sleepDetector->isRunning()) {
+               _D("Started already");
+               return true;
+       }
+
+       _I(GREEN("Start to record"));
+
+       __startTime = 0;
+       __endTime = 0;
+       __resetInsertionQuery();
+
+       return __sleepDetector->start();
+}
+
+void SleepLogger::stop()
+{
+       IF_FAIL_VOID_TAG(__sleepDetector, _D, "Stopped already");
+       _I(GREEN("Stop recording"));
+
+       __sleepDetector->stop();
+       __sleepMonitor->stop();
+
+       __appendQuery(__startTime, __endTime);
+       flushCache();
+
+       delete __sleepDetector;
+       __sleepDetector = NULL;
+
+       delete __sleepMonitor;
+       __sleepMonitor = NULL;
+}
+
+void SleepLogger::fallAsleep(uint64_t timestamp)
+{
+       _D("Fall asleep");
+       record(timestamp, TimeUtil::getTime(), STATE_SLEEP);
+       __sleepMonitor->start();
+}
+
+void SleepLogger::wakeUp(uint64_t timestamp)
+{
+       _D("Wake up");
+       __sleepMonitor->lazyStop();
+}
+
+void SleepLogger::record(uint64_t startTime, uint64_t endTime, int state)
+{
+       IF_FAIL_VOID(state == STATE_SLEEP);     /* For now, we don't need to record the awaken state */
+       IF_FAIL_VOID_TAG(startTime < endTime, _W, "Invalid parameter");
+
+       if (__startTime == 0) {
+               __startTime = startTime;
+               __endTime = endTime;
+               _D("Initial event: %llu ~ %llu", __startTime, __endTime);
+               return;
+       }
+
+       if (startTime < __endTime + TIME_GAP) {
+               __endTime = MAX(endTime, __endTime);
+               _D("Merged event: %llu ~ %llu", __startTime, __endTime);
+               return;
+       }
+
+       __appendQuery(__startTime, __endTime);
+       __startTime = startTime;
+       __endTime = endTime;
+       _D("Reset event: %llu ~ %llu", __startTime, __endTime);
+}
+
+void SleepLogger::flushCache(bool force)
+{
+       __insertionQuery.resize(__insertionQuery.size() - 1);
+       if (__insertionQuery.at(__insertionQuery.size() - 1) == ')')
+               executeQuery(__insertionQuery.c_str());
+
+       __resetInsertionQuery();
+}
+
+void SleepLogger::__resetInsertionQuery()
+{
+       __insertionQuery =
+               "INSERT INTO " SLEEP_MONITOR_RECORD \
+                       " (" KEY_START_TIME ", " KEY_END_TIME ") VALUES ";
+}
+
+void SleepLogger::__appendQuery(uint64_t startTime, uint64_t endTime)
+{
+       IF_FAIL_VOID(startTime > 0 && endTime > startTime);
+
+       char buffer[64];
+       g_snprintf(buffer, sizeof(buffer), "(%" PRIu64 ", %" PRIu64 "),", startTime, endTime);
+       __insertionQuery += buffer;
+}
diff --git a/src/server/legacy/sleep/SleepLogger.h b/src/server/legacy/sleep/SleepLogger.h
new file mode 100644 (file)
index 0000000..5bf25d1
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_SLEEP_LOGGER_H__
+#define __CONTEXT_SLEEP_LOGGER_H__
+
+#include "../SensorLogger.h"
+
+#define STATE_SLEEP    1
+#define STATE_WAKE     0
+
+namespace ctx {
+
+       class SleepLogger : public SensorLogger {
+       public:
+               SleepLogger();
+               ~SleepLogger();
+
+               bool start();
+               void stop();
+
+               void fallAsleep(uint64_t timestamp);
+               void wakeUp(uint64_t timestamp);
+
+               void record(uint64_t startTime, uint64_t endTime, int state);
+               void flushCache(bool force = false);
+
+       private:
+               void __resetInsertionQuery();
+               void __appendQuery(uint64_t startTime, uint64_t endTime);
+
+               std::string __insertionQuery;
+               uint64_t __startTime;
+               uint64_t __endTime;
+       };
+}
+
+#endif /* __CONTEXT_SLEEP_LOGGER_H__ */
diff --git a/src/server/legacy/sleep/SleepMonitor.cpp b/src/server/legacy/sleep/SleepMonitor.cpp
new file mode 100644 (file)
index 0000000..9b0b227
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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 <Types.h>
+#include "../TypesInternal.h"
+#include "../TimeUtil.h"
+#include "SleepMonitor.h"
+
+#define IDX_SLEEP_STATE        0
+#define IDX_REMAINING  6
+
+using namespace ctx;
+
+SleepMonitor::SleepMonitor(SleepLogger *logger) :
+       __logger(logger),
+       __lazyStopOn(false)
+{
+       setSensor(HUMAN_SLEEP_MONITOR_SENSOR);
+       setPowerSave(false);
+}
+
+SleepMonitor::~SleepMonitor()
+{
+}
+
+bool SleepMonitor::start()
+{
+       _D("START");
+       __lazyStopOn = false;
+       return listen();
+}
+
+void SleepMonitor::stop()
+{
+       _D("STOP");
+       unlisten();
+}
+
+void SleepMonitor::lazyStop()
+{
+       if (!isRunning())
+               return;
+
+       __lazyStopOn = true;
+}
+
+void SleepMonitor::onEvent(sensor_data_t *eventData)
+{
+       _D("%d at %llu", (int)eventData->values[IDX_SLEEP_STATE], eventData->timestamp);
+
+       uint64_t timestamp = TimeUtil::getTime(eventData->timestamp);
+       __logger->record(timestamp - SEC_TO_MS(SECONDS_PER_MINUTE), timestamp,
+                       static_cast<int>(eventData->values[IDX_SLEEP_STATE]));
+
+       if (static_cast<int>(eventData->values[IDX_REMAINING]) > 0)
+               return;
+
+       __logger->flushCache();
+
+       if (__lazyStopOn)
+               stop();
+}
diff --git a/src/server/legacy/sleep/SleepMonitor.h b/src/server/legacy/sleep/SleepMonitor.h
new file mode 100644 (file)
index 0000000..7aa37d9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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_SLEEP_MONITOR_H__
+#define __CONTEXT_SLEEP_MONITOR_H__
+
+#include "../SensorProxy.h"
+#include "SleepLogger.h"
+
+namespace ctx {
+
+       class SleepMonitor : public SensorProxy {
+       public:
+               SleepMonitor(SleepLogger *logger);
+               ~SleepMonitor();
+
+               bool start();
+               void stop();
+
+               void lazyStop();
+
+       protected:
+               void onEvent(sensor_data_t *eventData);
+
+       private:
+               SleepLogger *__logger;
+               bool __lazyStopOn;
+       };
+}
+
+#endif /* __CONTEXT_SLEEP_MONITOR_H__ */
diff --git a/src/server/legacy/sleep/SleepQuerier.cpp b/src/server/legacy/sleep/SleepQuerier.cpp
new file mode 100644 (file)
index 0000000..1a8f8dc
--- /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.
+ */
+
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "SleepQuerier.h"
+
+#define PROJECTION \
+       KEY_STATE ", " \
+       KEY_START_TIME  ", " \
+       KEY_END_TIME
+
+using namespace ctx;
+
+SleepQuerier::SleepQuerier(ContextProvider *provider, Json option) :
+       Querier(provider, option)
+{
+}
+
+SleepQuerier::~SleepQuerier()
+{
+}
+
+int SleepQuerier::queryRaw(int startTime, int endTime)
+{
+       return query(startTime, endTime);
+}
+
+int SleepQuerier::query(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " SLEEP_MONITOR_RECORD \
+                       " WHERE " KEY_END_TIME " > %llu AND " KEY_START_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
diff --git a/src/server/legacy/sleep/SleepQuerier.h b/src/server/legacy/sleep/SleepQuerier.h
new file mode 100644 (file)
index 0000000..7ba674f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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_SLEEP_QUERIER_H__
+#define __CONTEXT_SLEEP_QUERIER_H__
+
+#include "../Querier.h"
+
+namespace ctx {
+
+       class SleepQuerier : public Querier {
+       public:
+               SleepQuerier(ContextProvider *provider, Json option);
+               ~SleepQuerier();
+
+               int queryRaw(int startTime, int endTime);
+               int query(int startTime, int endTime);
+       };
+}
+
+#endif /* __CONTEXT_SLEEP_QUERIER_H__ */