From: Mu-Woong Lee Date: Thu, 30 Jun 2016 01:20:10 +0000 (+0900) Subject: sensor: add the sensor recorder for sleep monitor X-Git-Tag: accepted/tizen/common/20160705.170009~1^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3c71bf5261569be97a762751a8fd46467ea8d8f9;p=platform%2Fcore%2Fcontext%2Fcontext-provider.git sensor: add the sensor recorder for sleep monitor Change-Id: Ifc16ed955e9bce1284de202c1983626a68a4c675 Signed-off-by: Mu-Woong Lee --- diff --git a/src/sensor/CreateProvider.cpp b/src/sensor/CreateProvider.cpp index 141ea0e..768ba81 100644 --- a/src/sensor/CreateProvider.cpp +++ b/src/sensor/CreateProvider.cpp @@ -18,6 +18,7 @@ #include #include "pedometer/Pedometer.h" #include "pressure/Pressure.h" +#include "sleep/Sleep.h" using namespace ctx; @@ -25,6 +26,7 @@ extern "C" SO_EXPORT ContextProvider* CreateProvider(const char *subject) { ADD_PROVIDER(SUBJ_SENSOR_PEDOMETER, PedometerProvider); ADD_PROVIDER(SUBJ_SENSOR_PRESSURE, PressureProvider); + ADD_PROVIDER(SUBJ_SENSOR_SLEEP_MONITOR, SleepProvider); return NULL; } diff --git a/src/sensor/sleep/Sleep.cpp b/src/sensor/sleep/Sleep.cpp new file mode 100644 index 0000000..3ae40c9 --- /dev/null +++ b/src/sensor/sleep/Sleep.cpp @@ -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 +#include +#include "../TypesInternal.h" +#include "SleepLogger.h" +#include "SleepQuerier.h" +#include "Sleep.h" + +using namespace ctx; + +SleepProvider::SleepProvider() : + SensorProvider(SUBJ_SENSOR_SLEEP_MONITOR) +{ + IF_FAIL_VOID(isSupported()); + + sensorLogger = new(std::nothrow) SleepLogger(); + IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed"); +} + +SleepProvider::~SleepProvider() +{ +} + +void SleepProvider::getPrivilege(std::vector &privilege) +{ + privilege.push_back(PRIV_HEALTHINFO); +} + +bool SleepProvider::isSupported() +{ + return util::getSystemInfoBool("tizen.org/feature/sensor.sleep_monitor"); +} + +Querier* SleepProvider::getQuerier(Json option) +{ + SleepQuerier *querier = new(std::nothrow) SleepQuerier(this, option); + IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed"); + return querier; +} diff --git a/src/sensor/sleep/Sleep.h b/src/sensor/sleep/Sleep.h new file mode 100644 index 0000000..c93310e --- /dev/null +++ b/src/sensor/sleep/Sleep.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_SLEEP_PROVIDER_H__ +#define __CONTEXT_SLEEP_PROVIDER_H__ + +#include "../SensorProvider.h" + +namespace ctx { + + class SleepProvider : public SensorProvider { + public: + SleepProvider(); + ~SleepProvider(); + + void getPrivilege(std::vector &privilege); + bool isSupported(); + + protected: + Querier* getQuerier(Json option); + }; +} + +#endif /* _CONTEXT_SLEEP_PROVIDER_H_ */ diff --git a/src/sensor/sleep/SleepDetector.cpp b/src/sensor/sleep/SleepDetector.cpp new file mode 100644 index 0000000..5367dac --- /dev/null +++ b/src/sensor/sleep/SleepDetector.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "../TimeUtil.h" +#include "SleepDetector.h" + +#define IDX_SLEEP_STATE 0 + +using namespace ctx; + +SleepDetector::SleepDetector(SleepLogger *logger) : + __logger(logger) +{ + setSensor(HUMAN_SLEEP_DETECTOR_SENSOR); + setPowerSave(false); +} + +SleepDetector::~SleepDetector() +{ +} + +bool SleepDetector::start() +{ + _D("START"); + return listen(); +} + +void SleepDetector::stop() +{ + _D("STOP"); + unlisten(); +} + +void SleepDetector::onEvent(sensor_data_t *eventData) +{ + _D("%d at %llu", (int)eventData->values[0], eventData->timestamp); + + uint64_t eventTime = TimeUtil::getTime(eventData->timestamp); + + if (static_cast(eventData->values[IDX_SLEEP_STATE])) + __logger->fallAsleep(eventTime); + else + __logger->wakeUp(eventTime); +} diff --git a/src/sensor/sleep/SleepDetector.h b/src/sensor/sleep/SleepDetector.h new file mode 100644 index 0000000..104678c --- /dev/null +++ b/src/sensor/sleep/SleepDetector.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_SLEEP_DETECTOR_H__ +#define __CONTEXT_SLEEP_DETECTOR_H__ + +#include "../SensorProxy.h" +#include "SleepLogger.h" + +namespace ctx { + + class SleepDetector : public SensorProxy { + public: + SleepDetector(SleepLogger *logger); + ~SleepDetector(); + + bool start(); + void stop(); + + protected: + void onEvent(sensor_data_t *eventData); + + private: + SleepLogger *__logger; + }; +} + +#endif /* __CONTEXT_SLEEP_DETECTOR_H__ */ diff --git a/src/sensor/sleep/SleepLogger.cpp b/src/sensor/sleep/SleepLogger.cpp new file mode 100644 index 0000000..81f1547 --- /dev/null +++ b/src/sensor/sleep/SleepLogger.cpp @@ -0,0 +1,165 @@ +/* + * 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 +#include +#include "../TypesInternal.h" +#include "../ClientInfo.h" +#include "../TimeUtil.h" +#include "SleepDetector.h" +#include "SleepMonitor.h" +#include "SleepLogger.h" + +#define TIME_GAP 5000 + +using namespace ctx; + +SleepLogger::SleepLogger() : + __sleepDetector(NULL), + __sleepMonitor(NULL), + __startTime(0), + __endTime(0) +{ + /* Create the log table */ + executeQuery( + "CREATE TABLE IF NOT EXISTS " SLEEP_MONITOR_RECORD " (" \ + KEY_START_TIME " INTEGER NOT NULL, " \ + KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \ + KEY_STATE " INTEGER NOT NULL DEFAULT 1" \ + ")"); + + ClientInfo clientInfo; + if (clientInfo.exist(SUBJ_SENSOR_SLEEP_MONITOR)) + start(); +} + +SleepLogger::~SleepLogger() +{ + stop(); +} + +bool SleepLogger::start() +{ + if (!__sleepDetector) { + __sleepDetector = new(std::nothrow) SleepDetector(this); + __sleepMonitor = new(std::nothrow) SleepMonitor(this); + + if (!__sleepDetector || !__sleepMonitor) { + _E("Memory allocation failed"); + + delete __sleepDetector; + __sleepDetector = NULL; + + delete __sleepMonitor; + __sleepMonitor = NULL; + + return false; + } + } + + if (__sleepDetector->isRunning()) { + _D("Started already"); + return true; + } + + _I(GREEN("Start to record")); + + __startTime = 0; + __endTime = 0; + __resetInsertionQuery(); + + return dynamic_cast(__sleepDetector)->start(); +} + +void SleepLogger::stop() +{ + IF_FAIL_VOID_TAG(__sleepDetector, _D, "Stopped already"); + _I(GREEN("Stop recording")); + + dynamic_cast(__sleepDetector)->stop(); + dynamic_cast(__sleepMonitor)->stop(); + + __appendQuery(__startTime, __endTime); + flush(); + + delete __sleepDetector; + __sleepDetector = NULL; + + delete __sleepMonitor; + __sleepMonitor = NULL; +} + +void SleepLogger::fallAsleep(uint64_t timestamp) +{ + _D("Fall asleep"); + record(timestamp, TimeUtil::getTime(), STATE_SLEEP); + dynamic_cast(__sleepMonitor)->start(); +} + +void SleepLogger::wakeUp(uint64_t timestamp) +{ + _D("Wake up"); + dynamic_cast(__sleepMonitor)->lazyStop(); +} + +void SleepLogger::record(uint64_t startTime, uint64_t endTime, int state) +{ + IF_FAIL_VOID(state == STATE_SLEEP); /* For now, we don't need to record the awaken state */ + IF_FAIL_VOID_TAG(startTime < endTime, _W, "Invalid parameter"); + + if (__startTime == 0) { + __startTime = startTime; + __endTime = endTime; + _D("Initial event: %llu ~ %llu", __startTime, __endTime); + return; + } + + if (startTime < __endTime + TIME_GAP) { + __endTime = MAX(endTime, __endTime); + _D("Merged event: %llu ~ %llu", __startTime, __endTime); + return; + } + + __appendQuery(__startTime, __endTime); + __startTime = startTime; + __endTime = endTime; + _D("Reset event: %llu ~ %llu", __startTime, __endTime); +} + +void SleepLogger::flush() +{ + __insertionQuery.resize(__insertionQuery.size() - 1); + if (__insertionQuery.at(__insertionQuery.size() - 1) == ')') + executeQuery(__insertionQuery.c_str()); + + __resetInsertionQuery(); +} + +void SleepLogger::__resetInsertionQuery() +{ + __insertionQuery = + "INSERT INTO " SLEEP_MONITOR_RECORD \ + " (" KEY_START_TIME ", " KEY_END_TIME ") VALUES "; +} + +void SleepLogger::__appendQuery(uint64_t startTime, uint64_t endTime) +{ + IF_FAIL_VOID(startTime > 0 && endTime > startTime); + + char buffer[64]; + g_snprintf(buffer, sizeof(buffer), "(%llu, %llu),", startTime, endTime); + __insertionQuery += buffer; +} diff --git a/src/sensor/sleep/SleepLogger.h b/src/sensor/sleep/SleepLogger.h new file mode 100644 index 0000000..12f5dd2 --- /dev/null +++ b/src/sensor/sleep/SleepLogger.h @@ -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. + */ + +#ifndef __CONTEXT_SLEEP_LOGGER_H__ +#define __CONTEXT_SLEEP_LOGGER_H__ + +#include "../SensorLogger.h" +#include "../SensorProxy.h" + +#define STATE_SLEEP 1 +#define STATE_WAKE 0 + +namespace ctx { + + class SleepLogger : public SensorLogger { + public: + SleepLogger(); + ~SleepLogger(); + + bool start(); + void stop(); + + void fallAsleep(uint64_t timestamp); + void wakeUp(uint64_t timestamp); + + void record(uint64_t startTime, uint64_t endTime, int state); + void flush(); + + private: + void __resetInsertionQuery(); + void __appendQuery(uint64_t startTime, uint64_t endTime); + + std::string __insertionQuery; + SensorProxy *__sleepDetector; + SensorProxy *__sleepMonitor; + uint64_t __startTime; + uint64_t __endTime; + }; +} + +#endif /* __CONTEXT_SLEEP_LOGGER_H__ */ diff --git a/src/sensor/sleep/SleepMonitor.cpp b/src/sensor/sleep/SleepMonitor.cpp new file mode 100644 index 0000000..c851ca4 --- /dev/null +++ b/src/sensor/sleep/SleepMonitor.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "../TypesInternal.h" +#include "../TimeUtil.h" +#include "SleepMonitor.h" + +#define IDX_SLEEP_STATE 0 +#define IDX_REMAINING 6 + +using namespace ctx; + +SleepMonitor::SleepMonitor(SleepLogger *logger) : + __logger(logger), + __lazyStopOn(false) +{ + setSensor(HUMAN_SLEEP_MONITOR_SENSOR); + setPowerSave(false); +} + +SleepMonitor::~SleepMonitor() +{ +} + +bool SleepMonitor::start() +{ + _D("START"); + __lazyStopOn = false; + return listen(); +} + +void SleepMonitor::stop() +{ + _D("STOP"); + unlisten(); +} + +void SleepMonitor::lazyStop() +{ + if (!isRunning()) + return; + + __lazyStopOn = true; +} + +void SleepMonitor::onEvent(sensor_data_t *eventData) +{ + _D("%d at %llu", (int)eventData->values[IDX_SLEEP_STATE], eventData->timestamp); + + uint64_t timestamp = TimeUtil::getTime(eventData->timestamp); + __logger->record(timestamp - SEC_TO_MS(SECONDS_PER_MINUTE), timestamp, + static_cast(eventData->values[IDX_SLEEP_STATE])); + + if (static_cast(eventData->values[IDX_REMAINING]) > 0) + return; + + __logger->flush(); + + if (__lazyStopOn) + stop(); +} diff --git a/src/sensor/sleep/SleepMonitor.h b/src/sensor/sleep/SleepMonitor.h new file mode 100644 index 0000000..7aa37d9 --- /dev/null +++ b/src/sensor/sleep/SleepMonitor.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_SLEEP_MONITOR_H__ +#define __CONTEXT_SLEEP_MONITOR_H__ + +#include "../SensorProxy.h" +#include "SleepLogger.h" + +namespace ctx { + + class SleepMonitor : public SensorProxy { + public: + SleepMonitor(SleepLogger *logger); + ~SleepMonitor(); + + bool start(); + void stop(); + + void lazyStop(); + + protected: + void onEvent(sensor_data_t *eventData); + + private: + SleepLogger *__logger; + bool __lazyStopOn; + }; +} + +#endif /* __CONTEXT_SLEEP_MONITOR_H__ */ diff --git a/src/sensor/sleep/SleepQuerier.cpp b/src/sensor/sleep/SleepQuerier.cpp new file mode 100644 index 0000000..1a8f8dc --- /dev/null +++ b/src/sensor/sleep/SleepQuerier.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "../TypesInternal.h" +#include "SleepQuerier.h" + +#define PROJECTION \ + KEY_STATE ", " \ + KEY_START_TIME ", " \ + KEY_END_TIME + +using namespace ctx; + +SleepQuerier::SleepQuerier(ContextProvider *provider, Json option) : + Querier(provider, option) +{ +} + +SleepQuerier::~SleepQuerier() +{ +} + +int SleepQuerier::queryRaw(int startTime, int endTime) +{ + return query(startTime, endTime); +} + +int SleepQuerier::query(int startTime, int endTime) +{ + char *sql = sqlite3_mprintf( + "SELECT " PROJECTION \ + " FROM " SLEEP_MONITOR_RECORD \ + " WHERE " KEY_END_TIME " > %llu AND " KEY_START_TIME " <= %llu", + SEC_TO_MS(static_cast(startTime)), SEC_TO_MS(static_cast(endTime))); + + int ret = Querier::query(sql); + sqlite3_free(sql); + + return ret; +} diff --git a/src/sensor/sleep/SleepQuerier.h b/src/sensor/sleep/SleepQuerier.h new file mode 100644 index 0000000..7ba674f --- /dev/null +++ b/src/sensor/sleep/SleepQuerier.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_SLEEP_QUERIER_H__ +#define __CONTEXT_SLEEP_QUERIER_H__ + +#include "../Querier.h" + +namespace ctx { + + class SleepQuerier : public Querier { + public: + SleepQuerier(ContextProvider *provider, Json option); + ~SleepQuerier(); + + int queryRaw(int startTime, int endTime); + int query(int startTime, int endTime); + }; +} + +#endif /* __CONTEXT_SLEEP_QUERIER_H__ */