#include <ContextProvider.h>
#include <ProviderTypes.h>
#include <MyPlaceTypes.h>
+#include <SensorRecorderTypes.h>
#define LIB_DIRECTORY "/usr/lib/context-service/"
#define LIB_PREFIX "libctx-prvd-"
{SUBJ_VIDEO_STATS, "media-stats"},
{SUBJ_STATE_MESSAGE, "message"},
{SUBJ_PLACE_DETECTION, "my-place"},
+ {SUBJ_SENSOR, "sensor"},
{SUBJ_SOCIAL_STATS, "social-stats"},
{SUBJ_STATE_BATTERY, "system"},
{SUBJ_STATE_CHARGER, "system"},
BuildRequires: pkgconfig(capi-media-sound-manager)
BuildRequires: pkgconfig(capi-network-bluetooth)
BuildRequires: pkgconfig(capi-network-wifi)
-BuildRequires: pkgconfig(libcore-context-manager)
+BuildRequires: pkgconfig(sensor)
+BuildRequires: pkgconfig(motion)
%if "%{?BUILD_PROFILE}" == "mobile"
BuildRequires: pkgconfig(msg-service)
ADD_SUBDIRECTORY(app-stats)
ADD_SUBDIRECTORY(custom)
ADD_SUBDIRECTORY(headphone)
+ADD_SUBDIRECTORY(sensor)
ADD_SUBDIRECTORY(system)
ADD_SUBDIRECTORY(time)
ADD_SUBDIRECTORY(wifi)
ADD_SUBDIRECTORY(message)
#ADD_SUBDIRECTORY(my-place)
ADD_SUBDIRECTORY(social-stats)
-ENDIF("${PROFILE}" STREQUAL "mobile")
+ENDIF("${PROFILE}" STREQUAL "mobile")
\ No newline at end of file
--- /dev/null
+SET(target "${target_prefix}-sensor")
+
+SET(DEPS ${DEPS}
+ sensor
+)
+
+FILE(GLOB SRCS *.cpp)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PKG_SENSOR REQUIRED ${DEPS})
+
+FOREACH(flag ${PKG_SENSOR_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${PKG_SENSOR_LDFLAGS} ${target_shared})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir})
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sqlite3.h>
+#include <Types.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "ClientInfo.h"
+
+using namespace ctx;
+
+unsigned int ClientInfo::__refCnt = 0;
+DatabaseManager *ClientInfo::__dbMgr = NULL;
+
+ClientInfo::ClientInfo()
+{
+ ++__refCnt;
+
+ if (__dbMgr)
+ return;
+
+ __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;
+}
+
+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 (auto 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;
+}
--- /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>
+
+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);
+
+ private:
+ static unsigned int __refCnt;
+ static DatabaseManager *__dbMgr;
+ };
+}
+
+#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.h"
+#include "Pressure.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);
+
+ 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 <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 <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "ClientInfo.h"
+#include "PedometerLogger.h"
+
+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()
+{
+}
+
+bool PedometerLogger::start()
+{
+ if (SensorProxy::isRunning())
+ return true;
+
+ _I(GREEN("Start to record"));
+
+ if (SensorProxy::start()) {
+ flush();
+ return true;
+ }
+
+ return false;
+}
+
+void PedometerLogger::stop()
+{
+ _I(GREEN("Stop recording"));
+
+ SensorProxy::stop();
+ __firstEvent = true;
+}
+
+void PedometerLogger::onEvent(sensor_data_t *eventData)
+{
+ sensor_pedometer_data_t *pedometerData = reinterpret_cast<sensor_pedometer_data_t*>(eventData);
+ uint64_t timestamp = getTime();
+
+ if (__firstEvent) {
+ _D("Baseline event");
+ __firstEvent = false;
+ } else if (pedometerData->diffs_count == 0) {
+ _D("Single event");
+ __recordSingle(pedometerData, timestamp);
+ } else {
+ _D("Batch event");
+ __recordBatch(pedometerData, timestamp);
+ }
+
+ __baseline.timestamp = timestamp;
+ __baseline.walkSteps = eventData->values[1];
+ __baseline.runSteps = eventData->values[2];
+ __baseline.distance = eventData->values[3];
+ __baseline.calories = eventData->values[4];
+
+ _D("Baseline: %u, %u, %.3f, %.3f",
+ __baseline.walkSteps, __baseline.runSteps, __baseline.distance, __baseline.calories);
+
+ removeExpired(SUBJ_SENSOR_PEDOMETER, PEDOMETER_RECORD, KEY_END_TIME);
+}
+
+void PedometerLogger::__recordSingle(sensor_pedometer_data_t *eventData, uint64_t timestamp)
+{
+ DataRecord record;
+ record.walkSteps = static_cast<unsigned int>(eventData->values[1]) - __baseline.walkSteps;
+ record.runSteps = static_cast<unsigned int>(eventData->values[2]) - __baseline.runSteps;
+ record.distance = eventData->values[3] - __baseline.distance;
+ record.calories = eventData->values[4] - __baseline.calories;
+
+ IF_FAIL_VOID_TAG(record.walkSteps + record.runSteps > 0, _D, "Skipping zero-count event");
+
+ 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, timestamp, record.walkSteps, record.runSteps, record.distance, record.calories);
+ executeQuery(query);
+ sqlite3_free(query);
+}
+
+void PedometerLogger::__recordBatch(sensor_pedometer_data_t *eventData, uint64_t timestamp)
+{
+ 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), "(%llu, %llu, %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());
+}
--- /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();
+
+ 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);
+
+ bool __firstEvent;
+ DataRecord __baseline;
+ };
+}
+
+#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
+
+using namespace ctx;
+
+PedometerQuerier::PedometerQuerier(ContextProvider *provider, Json option) :
+ Querier(provider, option)
+{
+}
+
+PedometerQuerier::~PedometerQuerier()
+{
+}
+
+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 ROUND((" KEY_END_TIME " - %llu) / %llu + 0.5)" \
+ " 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 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 <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "ClientInfo.h"
+#include "PressureLogger.h"
+
+#define INSERTION_THRESHOLD 20000
+#define SAMPLING_INTERVAL 60000
+#define BATCH_LATENCY INT_MAX
+#define MAX_QUERY_LENGTH 1000
+
+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()
+{
+}
+
+bool PressureLogger::start()
+{
+ if (SensorProxy::isRunning())
+ return true;
+
+ _I(GREEN("Start to record"));
+
+ __lastInsertionTime = getTime();
+ __resetInsertionQuery();
+
+ return SensorProxy::start();
+}
+
+void PressureLogger::stop()
+{
+ _I(GREEN("Stop recording"));
+
+ SensorProxy::stop();
+}
+
+void PressureLogger::onEvent(sensor_data_t *eventData)
+{
+ uint64_t receivedTime = getTime();
+ __record(eventData, receivedTime);
+ removeExpired(SUBJ_SENSOR_PRESSURE, PRESSURE_RECORD, KEY_UNIV_TIME);
+}
+
+void PressureLogger::__record(sensor_data_t *eventData, uint64_t receivedTime)
+{
+ char buffer[64];
+ g_snprintf(buffer, sizeof(buffer), "(%llu, %.5f),",
+ getTime(eventData->timestamp), eventData->values[0]);
+
+ __insertionQuery += buffer;
+
+ if (receivedTime - __lastInsertionTime < INSERTION_THRESHOLD && __insertionQuery.size() < MAX_QUERY_LENGTH)
+ return;
+
+ __insertionQuery.resize(__insertionQuery.size() - 1);
+ if (__insertionQuery.at(__insertionQuery.size() - 1) == ')')
+ executeQuery(__insertionQuery.c_str());
+
+ __lastInsertionTime = receivedTime;
+ __resetInsertionQuery();
+}
+
+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();
+
+ protected:
+ void onEvent(sensor_data_t *eventData);
+
+ private:
+ void __record(sensor_data_t *eventData, uint64_t receivedTime);
+ void __resetInsertionQuery();
+
+ uint64_t __lastInsertionTime;
+ 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 ROUND((" KEY_UNIV_TIME " - %llu) / %llu + 0.5)" \
+ " 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 <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)
+{
+ return ERR_INVALID_PARAMETER;
+}
+
+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 <time.h>
+#include <sys/time.h>
+#include <cmath>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "SensorLogger.h"
+
+using namespace ctx;
+
+SensorLogger::SensorLogger() :
+ __lastRemovalTime(0)
+{
+}
+
+SensorLogger::~SensorLogger()
+{
+}
+
+uint64_t SensorLogger::getTime()
+{
+ struct timeval tv;
+ double timestamp;
+
+ gettimeofday(&tv, NULL);
+ timestamp = tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
+ return static_cast<uint64_t>(round(timestamp));
+}
+
+uint64_t SensorLogger::getTime(unsigned long long monotonic)
+{
+ struct timespec ts;
+ double timestamp;
+ uint64_t currentTime = getTime();
+
+ if (abs(currentTime / 1000 - monotonic / 1000000) < SECONDS_PER_DAY)
+ return static_cast<uint64_t>(round(monotonic / 1000.0));
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ timestamp = static_cast<double>(currentTime) - (ts.tv_sec * 1000000000.0 + ts.tv_nsec) / 1000000.0 + monotonic / 1000.0;
+ return static_cast<uint64_t>(round(timestamp));
+}
+
+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 = 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;
+
+ protected:
+ uint64_t getTime();
+ uint64_t getTime(unsigned long long monotonic);
+ 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;
+
+SensorProvider::SensorProvider(const char *subject) :
+ ContextProvider(subject),
+ sensorLogger(NULL)
+{
+}
+
+SensorProvider::~SensorProvider()
+{
+ 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);
+
+ 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;
+ 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);
+
+ if (data.get(NULL, KEY_RETENTION, &retentionPeriod))
+ retentionPeriod *= SECONDS_PER_HOUR;
+
+ /* TODO: remove the operation & pkg id from the json */
+
+ if (operation == VAL_START)
+ return __addClient(pkgId, retentionPeriod, data);
+ else if (operation == VAL_STOP)
+ return __removeClient(pkgId);
+
+ return ERR_NOT_SUPPORTED;
+}
+
+int SensorProvider::__addClient(std::string pkgId, int retentionPeriod, Json option)
+{
+ Json tmp;
+ int ret;
+
+ /* 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_FAIL_RETURN(ret != ERR_NONE, ERR_NONE);
+ IF_FAIL_RETURN(ret == ERR_NO_DATA, ERR_OPERATION_FAILED);
+
+ /* Stop listening */
+ sensorLogger->stop();
+
+ return ERR_NONE;
+}
--- /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 <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);
+
+ protected:
+ virtual Querier* getQuerier(Json option) = 0;
+
+ SensorLogger *sensorLogger;
+
+ private:
+ int __addClient(std::string pkgId, int retentionPeriod, Json option);
+ int __removeClient(std::string pkgId);
+
+ ClientInfo __clientInfo;
+ };
+}
+
+#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()
+{
+ stop();
+}
+
+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::start()
+{
+ _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::stop()
+{
+ 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);
+
+ virtual bool start();
+ virtual void stop();
+ 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);
+
+ bool isRunning();
+
+ 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.
+ */
+
+#ifndef __CONTEXT_SENSOR_RECORDER_TYPES_INTERNAL_H__
+#define __CONTEXT_SENSOR_RECORDER_TYPES_INTERNAL_H__
+
+/* Tables */
+#define PEDOMETER_RECORD "SensorPedometerRecord"
+#define PRESSURE_RECORD "SensorPressureRecord"
+#define CLIENT_INFO "SensorClientInfo"
+
+/* Privileges */
+#define PRIV_HEALTHINFO "healthinfo"
+
+/* Constants */
+#define SECONDS_PER_MINUTE 60
+#define SECONDS_PER_HOUR 3600
+#define SECONDS_PER_DAY 86400
+
+/* Default Parameters */
+#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)
+
+#endif /* __CONTEXT_SENSOR_RECORDER_TYPES_INTERNAL_H__ */