SET(DEPS "${DEPS} context-common-server")
-FILE(GLOB_RECURSE SRCS *.cpp ../shared/*.cpp)
+FILE(GLOB SRCS *.cpp ../shared/*.cpp)
MESSAGE("Sources: ${SRCS}")
INCLUDE(FindPkgConfig)
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_SENSOR_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_SENSOR_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CONTEXT_SENSOR_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_SENSOR_RECORDER_TYPES_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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];
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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 ";
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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();
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */