Add sensor recorder provides (pedometer & pressure supported) 13/76713/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 27 Jun 2016 04:33:19 +0000 (13:33 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 27 Jun 2016 04:33:19 +0000 (13:33 +0900)
Change-Id: Ib1177eb9b595b9b1bdc3b10f3b010b984c2cb6fc
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
28 files changed:
include/ProviderList.h
packaging/context-provider.spec
src/CMakeLists.txt
src/sensor/CMakeLists.txt [new file with mode: 0644]
src/sensor/ClientInfo.cpp [new file with mode: 0644]
src/sensor/ClientInfo.h [new file with mode: 0644]
src/sensor/CreateProvider.cpp [new file with mode: 0644]
src/sensor/Pedometer.cpp [new file with mode: 0644]
src/sensor/Pedometer.h [new file with mode: 0644]
src/sensor/PedometerLogger.cpp [new file with mode: 0644]
src/sensor/PedometerLogger.h [new file with mode: 0644]
src/sensor/PedometerQuerier.cpp [new file with mode: 0644]
src/sensor/PedometerQuerier.h [new file with mode: 0644]
src/sensor/Pressure.cpp [new file with mode: 0644]
src/sensor/Pressure.h [new file with mode: 0644]
src/sensor/PressureLogger.cpp [new file with mode: 0644]
src/sensor/PressureLogger.h [new file with mode: 0644]
src/sensor/PressureQuerier.cpp [new file with mode: 0644]
src/sensor/PressureQuerier.h [new file with mode: 0644]
src/sensor/Querier.cpp [new file with mode: 0644]
src/sensor/Querier.h [new file with mode: 0644]
src/sensor/SensorLogger.cpp [new file with mode: 0644]
src/sensor/SensorLogger.h [new file with mode: 0644]
src/sensor/SensorProvider.cpp [new file with mode: 0644]
src/sensor/SensorProvider.h [new file with mode: 0644]
src/sensor/SensorProxy.cpp [new file with mode: 0644]
src/sensor/SensorProxy.h [new file with mode: 0644]
src/sensor/TypesInternal.h [new file with mode: 0644]

index 7218956..a159c44 100644 (file)
@@ -20,6 +20,7 @@
 #include <ContextProvider.h>
 #include <ProviderTypes.h>
 #include <MyPlaceTypes.h>
+#include <SensorRecorderTypes.h>
 
 #define LIB_DIRECTORY  "/usr/lib/context-service/"
 #define LIB_PREFIX             "libctx-prvd-"
@@ -42,6 +43,7 @@ const struct {
        {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"},
index 4af42f5..36421d4 100644 (file)
@@ -28,7 +28,8 @@ BuildRequires: pkgconfig(pkgmgr-info)
 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)
index 967c384..3dfad81 100644 (file)
@@ -8,6 +8,7 @@ ADD_SUBDIRECTORY(activity)
 ADD_SUBDIRECTORY(app-stats)
 ADD_SUBDIRECTORY(custom)
 ADD_SUBDIRECTORY(headphone)
+ADD_SUBDIRECTORY(sensor)
 ADD_SUBDIRECTORY(system)
 ADD_SUBDIRECTORY(time)
 ADD_SUBDIRECTORY(wifi)
@@ -21,4 +22,4 @@ ADD_SUBDIRECTORY(media-stats)
 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
diff --git a/src/sensor/CMakeLists.txt b/src/sensor/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c00256a
--- /dev/null
@@ -0,0 +1,19 @@
+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})
diff --git a/src/sensor/ClientInfo.cpp b/src/sensor/ClientInfo.cpp
new file mode 100644 (file)
index 0000000..6a94f01
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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;
+}
diff --git a/src/sensor/ClientInfo.h b/src/sensor/ClientInfo.h
new file mode 100644 (file)
index 0000000..a52cd27
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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_ */
diff --git a/src/sensor/CreateProvider.cpp b/src/sensor/CreateProvider.cpp
new file mode 100644 (file)
index 0000000..47d5ee9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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;
+}
diff --git a/src/sensor/Pedometer.cpp b/src/sensor/Pedometer.cpp
new file mode 100644 (file)
index 0000000..cac1e89
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SensorRecorderTypes.h>
+#include <Util.h>
+#include "TypesInternal.h"
+#include "PedometerLogger.h"
+#include "PedometerQuerier.h"
+#include "Pedometer.h"
+
+using namespace ctx;
+
+PedometerProvider::PedometerProvider() :
+       SensorProvider(SUBJ_SENSOR_PEDOMETER)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) PedometerLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+PedometerProvider::~PedometerProvider()
+{
+}
+
+void PedometerProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+       privilege.push_back(PRIV_HEALTHINFO);
+}
+
+bool PedometerProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.pedometer");
+}
+
+Querier* PedometerProvider::getQuerier(Json option)
+{
+       PedometerQuerier *querier = new(std::nothrow) PedometerQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
diff --git a/src/sensor/Pedometer.h b/src/sensor/Pedometer.h
new file mode 100644 (file)
index 0000000..d4773fe
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PEDOMETER_PROVIDER_H__
+#define __CONTEXT_PEDOMETER_PROVIDER_H__
+
+#include "SensorProvider.h"
+
+namespace ctx {
+
+       class PedometerProvider : public SensorProvider {
+       public:
+               PedometerProvider();
+               ~PedometerProvider();
+
+               bool isSupported();
+               void getPrivilege(std::vector<const char*> &privilege);
+
+       protected:
+               Querier* getQuerier(Json option);
+       };
+}
+
+#endif /* _CONTEXT_PEDOMETER_PROVIDER_H_ */
diff --git a/src/sensor/PedometerLogger.cpp b/src/sensor/PedometerLogger.cpp
new file mode 100644 (file)
index 0000000..b091e58
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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());
+}
diff --git a/src/sensor/PedometerLogger.h b/src/sensor/PedometerLogger.h
new file mode 100644 (file)
index 0000000..e1d021b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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__ */
diff --git a/src/sensor/PedometerQuerier.cpp b/src/sensor/PedometerQuerier.cpp
new file mode 100644 (file)
index 0000000..37fa7de
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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;
+}
diff --git a/src/sensor/PedometerQuerier.h b/src/sensor/PedometerQuerier.h
new file mode 100644 (file)
index 0000000..5cdc506
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_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__ */
diff --git a/src/sensor/Pressure.cpp b/src/sensor/Pressure.cpp
new file mode 100644 (file)
index 0000000..b50caa2
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SensorRecorderTypes.h>
+#include <Util.h>
+#include "TypesInternal.h"
+#include "PressureLogger.h"
+#include "PressureQuerier.h"
+#include "Pressure.h"
+
+using namespace ctx;
+
+PressureProvider::PressureProvider() :
+       SensorProvider(SUBJ_SENSOR_PRESSURE)
+{
+       IF_FAIL_VOID(isSupported());
+
+       sensorLogger = new(std::nothrow) PressureLogger();
+       IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+PressureProvider::~PressureProvider()
+{
+}
+
+bool PressureProvider::isSupported()
+{
+       return util::getSystemInfoBool("tizen.org/feature/sensor.barometer");
+}
+
+Querier* PressureProvider::getQuerier(Json option)
+{
+       PressureQuerier *querier = new(std::nothrow) PressureQuerier(this, option);
+       IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+       return querier;
+}
diff --git a/src/sensor/Pressure.h b/src/sensor/Pressure.h
new file mode 100644 (file)
index 0000000..d12efac
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PRESSURE_PROVIDER_H__
+#define __CONTEXT_PRESSURE_PROVIDER_H__
+
+#include "SensorProvider.h"
+
+namespace ctx {
+
+       class PressureProvider : public SensorProvider {
+       public:
+               PressureProvider();
+               ~PressureProvider();
+
+               bool isSupported();
+
+       protected:
+               Querier* getQuerier(Json option);
+       };
+}
+
+#endif /* _CONTEXT_PRESSURE_PROVIDER_H_ */
diff --git a/src/sensor/PressureLogger.cpp b/src/sensor/PressureLogger.cpp
new file mode 100644 (file)
index 0000000..0dcaca9
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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 ";
+}
diff --git a/src/sensor/PressureLogger.h b/src/sensor/PressureLogger.h
new file mode 100644 (file)
index 0000000..45d0c68
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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__ */
diff --git a/src/sensor/PressureQuerier.cpp b/src/sensor/PressureQuerier.cpp
new file mode 100644 (file)
index 0000000..5e01662
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "TypesInternal.h"
+#include "PressureQuerier.h"
+
+#define PROJECTION \
+       "AVG(" KEY_PRESSURE ") AS " KEY_PRESSURE ", " \
+       "MIN(" KEY_PRESSURE ") AS " KEY_MIN_PRESSURE ", " \
+       "MAX(" KEY_PRESSURE ") AS " KEY_MAX_PRESSURE ", " \
+       "AVG(" KEY_PRESSURE ") AS " KEY_AVG_PRESSURE ", " \
+       "MIN(" KEY_UNIV_TIME ") AS " KEY_START_TIME ", " \
+       "MAX(" KEY_UNIV_TIME ") AS " KEY_END_TIME
+
+#define PROJECTION_RAW \
+       KEY_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_MIN_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_MAX_PRESSURE ", " \
+       KEY_PRESSURE " AS " KEY_AVG_PRESSURE ", " \
+       KEY_UNIV_TIME " AS " KEY_START_TIME ", " \
+       KEY_UNIV_TIME " AS " KEY_END_TIME
+
+using namespace ctx;
+
+PressureQuerier::PressureQuerier(ContextProvider *provider, Json option) :
+       Querier(provider, option)
+{
+}
+
+PressureQuerier::~PressureQuerier()
+{
+}
+
+int PressureQuerier::queryRaw(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION_RAW \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PressureQuerier::query(int startTime, int endTime)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+                       SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+       int ret = Querier::query(sql);
+       sqlite3_free(sql);
+
+       return ret;
+}
+
+int PressureQuerier::query(int startTime, int endTime, int anchor, int interval)
+{
+       char *sql = sqlite3_mprintf(
+                       "SELECT " PROJECTION \
+                       " FROM " PRESSURE_RECORD \
+                       " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu" \
+                       " GROUP BY 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;
+}
diff --git a/src/sensor/PressureQuerier.h b/src/sensor/PressureQuerier.h
new file mode 100644 (file)
index 0000000..be1788c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PRESSURE_QUERIER_H__
+#define __CONTEXT_PRESSURE_QUERIER_H__
+
+#include "Querier.h"
+
+namespace ctx {
+
+       class PressureQuerier : public Querier {
+       public:
+               PressureQuerier(ContextProvider *provider, Json option);
+               ~PressureQuerier();
+
+               int queryRaw(int startTime, int endTime);
+               int query(int startTime, int endTime);
+               int query(int startTime, int endTime, int anchor, int interval);
+       };
+}
+
+#endif /* __CONTEXT_PRESSURE_QUERIER_H__ */
diff --git a/src/sensor/Querier.cpp b/src/sensor/Querier.cpp
new file mode 100644 (file)
index 0000000..7cc0b9b
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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();
+       }
+}
diff --git a/src/sensor/Querier.h b/src/sensor/Querier.h
new file mode 100644 (file)
index 0000000..0eed203
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_QUERIER_H__
+#define __CONTEXT_QUERIER_H__
+
+#include <ContextProvider.h>
+#include <DatabaseManager.h>
+
+namespace ctx {
+
+       class Querier : public IDatabaseListener {
+       public:
+               Querier(ContextProvider *provider, Json option);
+               virtual ~Querier();
+
+               virtual int queryRaw(int startTime, int endTime);
+               virtual int query(int startTime, int endTime);
+               virtual int query(int startTime, int endTime, int anchor, int interval);
+
+       protected:
+               int query(const char *sql);
+               void onTableCreated(unsigned int queryId, int error);
+               void onInserted(unsigned int queryId, int error, int64_t rowId);
+               void onExecuted(unsigned int queryId, int error, std::vector<Json>& records);
+
+       private:
+               void __convertToResponse(std::vector<Json> &sqlResult, Json &response);
+
+               DatabaseManager __dbMgr;
+               ContextProvider *__provider;
+               Json __option;
+       };
+}
+
+#endif /* __CONTEXT_QUERIER_H__ */
diff --git a/src/sensor/SensorLogger.cpp b/src/sensor/SensorLogger.cpp
new file mode 100644 (file)
index 0000000..e2462ab
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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;
+}
diff --git a/src/sensor/SensorLogger.h b/src/sensor/SensorLogger.h
new file mode 100644 (file)
index 0000000..eef4df3
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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__ */
diff --git a/src/sensor/SensorProvider.cpp b/src/sensor/SensorProvider.cpp
new file mode 100644 (file)
index 0000000..e205246
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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;
+}
diff --git a/src/sensor/SensorProvider.h b/src/sensor/SensorProvider.h
new file mode 100644 (file)
index 0000000..4a1cf5b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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_ */
diff --git a/src/sensor/SensorProxy.cpp b/src/sensor/SensorProxy.cpp
new file mode 100644 (file)
index 0000000..f927ec1
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <Types.h>
+#include "SensorProxy.h"
+
+#define SENSOR_EVENT(X) (((int)(X) << 16) | 0x01)
+
+using namespace ctx;
+
+SensorProxy::SensorProxy() :
+       sensorHandle(-1),
+       sensorType(UNKNOWN_SENSOR),
+       powerSave(true),
+       samplingInterval(0),
+       batchLatency(0),
+       userData(NULL)
+{
+}
+
+SensorProxy::~SensorProxy()
+{
+       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);
+}
diff --git a/src/sensor/SensorProxy.h b/src/sensor/SensorProxy.h
new file mode 100644 (file)
index 0000000..d264668
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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__ */
diff --git a/src/sensor/TypesInternal.h b/src/sensor/TypesInternal.h
new file mode 100644 (file)
index 0000000..a39a452
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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__ */