2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "humanactivitymonitor/humanactivitymonitor_manager.h"
19 #include <activity_recognition.h>
20 #include <gesture_recognition.h>
21 #include <location_batch.h>
23 #include <sensor_internal.h>
24 #include <system_info.h>
27 #include "common/logger.h"
28 #include "common/optional.h"
29 #include "common/picojson.h"
30 #include "common/scope_exit.h"
31 #include "common/tools.h"
34 namespace humanactivitymonitor {
36 using common::PlatformResult;
37 using common::ErrorCode;
38 using common::tools::ReportError;
39 using common::tools::ReportSuccess;
41 typedef std::map<sensor_recorder_data_e, const std::string&> SensorRecorderDataMap;
42 typedef std::map<sensor_recorder_query_e, const std::string&> SensorRecorderQueryMap;
46 const std::string kActivityTypePedometer = "PEDOMETER";
47 const std::string kActivityTypeWristUp = "WRIST_UP";
48 const std::string kActivityTypeHrm = "HRM";
49 const std::string kActivityTypeSleepMonitor = "SLEEP_MONITOR";
50 const std::string kActivityTypePressure = "PRESSURE";
51 const std::string kActivityTypeSleepDetector = "SLEEP_DETECTOR";
52 const std::string kActivityTypeStressMonitor = "STRESS_MONITOR";
54 const std::string kSleepStateAwake = "AWAKE";
55 const std::string kSleepStateAsleep = "ASLEEP";
56 const std::string kSleepStateUnknown = "UNKNOWN";
58 const std::string kCallbackInterval = "callbackInterval";
59 const std::string kSampleInterval = "sampleInterval";
61 const std::string kStatus = "status";
62 const std::string kTimestamp = "timestamp";
63 const std::string kStressScore = "stressScore";
65 const std::string kStepStatus = "stepStatus";
66 const std::string kSpeed = "speed";
67 const std::string kWalkingFrequency = "walkingFrequency";
68 const std::string kCumulativeDistance = "cumulativeDistance";
69 const std::string kCumulativeCalorie = "cumulativeCalorie";
70 const std::string kCumulativeTotalStepCount = "cumulativeTotalStepCount";
71 const std::string kCumulativeWalkStepCount = "cumulativeWalkStepCount";
72 const std::string kCumulativeRunStepCount = "cumulativeRunStepCount";
73 const std::string kStepCountDifferences = "stepCountDifferences";
74 const std::string kStepCountDifference = "stepCountDifference";
76 const std::string kAccumulativeDistance = "accumulativeDistance";
77 const std::string kAccumulativeCalorie = "accumulativeCalorie";
78 const std::string kAccumulativeTotalStepCount = "accumulativeTotalStepCount";
79 const std::string kAccumulativeWalkStepCount = "accumulativeWalkStepCount";
80 const std::string kAccumulativeRunStepCount = "accumulativeRunStepCount";
82 const std::string kRecordedStartTime = "startTime";
83 const std::string kRecordedEndTime = "endTime";
84 const std::string kRecordedHeartRate = "heartRate";
86 const std::string kRecordedDistance = "distance";
87 const std::string kRecordedCalorie = "calorie";
88 const std::string kRecordedTotalStepCount = "totalStepCount";
89 const std::string kRecordedWalkStepCount = "walkStepCount";
90 const std::string kRecordedRunStepCount = "runStepCount";
92 const std::string kRecordedMin = "min";
93 const std::string kRecordedMax = "max";
94 const std::string kRecordedAverage = "average";
96 const std::string kRecordedAnchorTime = "anchorTime";
97 const std::string kRecordedInterval = "interval";
99 ErrorCode getErrorCode(const int errorCode) {
102 case SENSOR_ERROR_IO_ERROR:
103 return ErrorCode::IO_ERR;
104 case SENSOR_ERROR_NOT_SUPPORTED:
105 return ErrorCode::NOT_SUPPORTED_ERR;
106 case SENSOR_ERROR_PERMISSION_DENIED:
107 return ErrorCode::PERMISSION_DENIED_ERR;
108 case SENSOR_ERROR_NOT_AVAILABLE:
109 return ErrorCode::SERVICE_NOT_AVAILABLE_ERR;
110 case SENSOR_ERROR_NO_DATA:
111 return ErrorCode::NOT_FOUND_ERR;
112 case SENSOR_ERROR_INVALID_PARAMETER:
113 return ErrorCode::INVALID_VALUES_ERR;
114 case SENSOR_ERROR_OUT_OF_MEMORY:
115 case SENSOR_ERROR_OPERATION_FAILED:
116 case SENSOR_ERROR_NOT_NEED_CALIBRATION:
118 return ErrorCode::ABORT_ERR;
122 // helper structure, allows easier access to data values
123 struct PedometerDataWrapper : public sensor_pedometer_data_t {
124 inline float steps() const {
128 inline float walk_steps() const {
132 inline float run_steps() const {
136 inline float distance() const {
140 inline float calories() const {
144 inline float speed() const {
148 inline float frequency() const {
152 inline sensor_pedometer_state_e state() const {
153 return static_cast<sensor_pedometer_state_e>(values[7]);
157 static int64_t getCurrentTimeStamp(unsigned long long evTime) {
160 unsigned long long systemCurrentTime = 0;
161 unsigned long long realCurrentTime = 0;
162 unsigned long long timeDiff = 0;
163 int64_t timeStamp = 0;
165 // get current system monotonic time
166 clock_gettime(CLOCK_MONOTONIC, &t);
168 ((unsigned long long)(t.tv_sec) * 1000000000LL + t.tv_nsec) / 1000000; // convert millisecond
169 timeDiff = (systemCurrentTime - (evTime / 1000));
171 // get current epoch time(millisecond)
172 clock_gettime(CLOCK_REALTIME, &t);
173 realCurrentTime = ((unsigned long long)(t.tv_sec) * 1000000000LL + t.tv_nsec) / 1000000;
174 timeStamp = static_cast<int64_t>(realCurrentTime - timeDiff);
179 void InsertStepDifference(float step_difference, int64_t timestamp, picojson::array* out) {
184 d.insert(std::make_pair(kStepCountDifference, picojson::value(step_difference)));
185 d.insert(std::make_pair(kTimestamp, picojson::value(static_cast<float>(timestamp))));
187 out->push_back(picojson::value{d});
190 std::string FromSensorPedometerState(sensor_pedometer_state_e e) {
192 case SENSOR_PEDOMETER_STATE_STOP:
195 case SENSOR_PEDOMETER_STATE_WALK:
198 case SENSOR_PEDOMETER_STATE_RUN:
201 case SENSOR_PEDOMETER_STATE_UNKNOWN:
207 PlatformResult ConvertRecordedTime(void* data, picojson::object* obj) {
208 ScopeLogger("convert_recorded_time");
210 time_t start_time, end_time;
212 int ret = sensor_recorder_data_get_time(data, &start_time, &end_time);
213 if (SENSOR_ERROR_NONE != ret) {
214 return LogAndCreateResult(getErrorCode(ret), "Failed to get time",
215 ("Failed to get time, error: %d (%s)", ret, get_error_message(ret)));
218 obj->insert(std::make_pair(kRecordedStartTime, picojson::value(static_cast<double>(start_time))));
219 obj->insert(std::make_pair(kRecordedEndTime, picojson::value(static_cast<double>(end_time))));
221 return PlatformResult(ErrorCode::NO_ERROR);
224 PlatformResult ConvertRecordedInt(void* data, picojson::object* obj,
225 const SensorRecorderDataMap& map) {
228 int ret = SENSOR_ERROR_NONE;
231 for (auto& it : map) {
232 ret = sensor_recorder_data_get_int(data, it.first, &tmp);
233 if (SENSOR_ERROR_NONE != ret) {
234 return LogAndCreateResult(
235 getErrorCode(ret), "Failed to get int value",
236 ("Failed to get int value, error: %d (%s)", ret, get_error_message(ret)));
239 obj->insert(std::make_pair(it.second, picojson::value(static_cast<double>(tmp))));
242 return PlatformResult(ErrorCode::NO_ERROR);
245 PlatformResult ConvertRecordedDouble(void* data, picojson::object* obj,
246 const SensorRecorderDataMap& map) {
249 int ret = SENSOR_ERROR_NONE;
252 for (auto& it : map) {
253 ret = sensor_recorder_data_get_double(data, it.first, &tmp);
254 if (SENSOR_ERROR_NONE != ret) {
255 return LogAndCreateResult(
256 getErrorCode(ret), "Failed to get double value",
257 ("Failed to get double value, error: %d (%s)", ret, get_error_message(ret)));
260 obj->insert(std::make_pair(it.second, picojson::value(static_cast<double>(tmp))));
263 return PlatformResult(ErrorCode::NO_ERROR);
268 const std::string kActivityTypeGps = "GPS";
270 class HumanActivityMonitorManager::Monitor {
272 class GestureMonitor;
275 class PedometerMonitor;
277 explicit Monitor(const std::string& t) : type_(t) {
278 ScopeLogger("type %s", type().c_str());
282 ScopeLogger("type %s", type().c_str());
285 std::string type() const {
289 JsonCallback& event_callback() {
290 return event_callback_;
293 PlatformResult SetListener(JsonCallback callback, const picojson::value& args) {
294 ScopeLogger("type %s", type().c_str());
296 auto result = IsSupported();
301 result = SetListenerImpl(args);
306 event_callback_ = callback;
310 PlatformResult UnsetListener() {
311 ScopeLogger("type %s", type().c_str());
313 auto result = IsSupported();
318 result = UnsetListenerImpl();
323 event_callback_ = nullptr;
327 PlatformResult GetData(picojson::value* data) {
328 ScopeLogger("type %s", type().c_str());
330 auto result = IsSupported();
335 return GetDataImpl(data);
338 PlatformResult StartDataRecorder(int interval, int retention_period) {
339 ScopeLogger("type %s", type().c_str());
341 auto result = IsSupported();
346 return StartDataRecorderImpl(interval, retention_period);
349 PlatformResult StopDataRecorder() {
350 ScopeLogger("type %s", type().c_str());
352 return StopDataRecorderImpl();
355 PlatformResult ReadRecorderData(picojson::array* data, const picojson::value& query) {
356 ScopeLogger("type %s", type().c_str());
358 auto result = IsSupported();
363 return ReadRecorderDataImpl(data, query);
367 virtual PlatformResult IsSupportedImpl(bool* supported) const {
368 ScopeLogger("type %s", type().c_str());
370 return PlatformResult(ErrorCode::NO_ERROR);
373 virtual PlatformResult SetListenerImpl(const picojson::value& args) {
374 ScopeLogger("type %s", type().c_str());
375 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
378 virtual PlatformResult UnsetListenerImpl() {
379 ScopeLogger("type %s", type().c_str());
380 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
383 virtual PlatformResult GetDataImpl(picojson::value* data) const {
384 ScopeLogger("type %s", type().c_str());
385 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
388 virtual PlatformResult StartDataRecorderImpl(int interval, int retention_period) const {
389 ScopeLogger("type %s", type().c_str());
390 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
393 virtual PlatformResult StopDataRecorderImpl() const {
394 ScopeLogger("type %s", type().c_str());
395 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
398 virtual PlatformResult ReadRecorderDataImpl(picojson::array* data, const picojson::value& query) {
399 ScopeLogger("type %s", type().c_str());
400 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
404 PlatformResult IsSupported() {
405 ScopeLogger("type %s", type().c_str());
407 if (!is_supported_) {
408 bool is_supported = false;
409 auto res = IsSupportedImpl(&is_supported);
413 is_supported_ = is_supported;
417 if (*is_supported_) {
418 return PlatformResult(ErrorCode::NO_ERROR);
420 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR");
426 common::optional<bool> is_supported_;
427 JsonCallback event_callback_;
430 class HumanActivityMonitorManager::Monitor::GestureMonitor
431 : public HumanActivityMonitorManager::Monitor {
433 explicit GestureMonitor(const std::string& t) : Monitor(t), handle_(nullptr) {
434 ScopeLogger("type %s", type().c_str());
437 virtual ~GestureMonitor() override {
438 ScopeLogger("type %s", type().c_str());
443 virtual PlatformResult IsSupportedImpl(bool* s) const override {
444 ScopeLogger("type %s", type().c_str());
446 bool supported = false;
448 int ret = gesture_is_supported(GESTURE_WRIST_UP, &supported);
449 if (GESTURE_ERROR_NONE != ret) {
450 if (ret == GESTURE_ERROR_NOT_SUPPORTED) {
451 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "WRIST_UP gesture check failed",
452 ("gesture_is_supported(GESTURE_WRIST_UP), error: %d (%s)", ret,
453 get_error_message(ret)));
455 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "WRIST_UP gesture check failed",
456 ("gesture_is_supported(GESTURE_WRIST_UP), error: %d (%s)", ret,
457 get_error_message(ret)));
462 return PlatformResult(ErrorCode::NO_ERROR);
465 virtual PlatformResult SetListenerImpl(const picojson::value&) override {
466 ScopeLogger("type %s", type().c_str());
469 int ret = gesture_create(&handle_);
470 if (GESTURE_ERROR_NONE != ret) {
471 return LogAndCreateResult(
472 ErrorCode::UNKNOWN_ERR, "Failed to create WRIST_UP listener",
473 ("Failed to create WRIST_UP handle, error: %d (%s)", ret, get_error_message(ret)));
476 ret = gesture_start_recognition(handle_, GESTURE_WRIST_UP, GESTURE_OPTION_DEFAULT,
477 OnWristUpEvent, this);
478 if (GESTURE_ERROR_NONE != ret) {
479 return LogAndCreateResult(
480 ErrorCode::UNKNOWN_ERR, "Failed to start WRIST_UP listener",
481 ("Failed to start WRIST_UP listener, error: %d (%s)", ret, get_error_message(ret)));
485 return PlatformResult(ErrorCode::NO_ERROR);
488 virtual PlatformResult UnsetListenerImpl() override {
489 ScopeLogger("type %s", type().c_str());
492 int ret = gesture_stop_recognition(handle_);
493 if (GESTURE_ERROR_NONE != ret) {
494 LoggerE("Failed to stop WRIST_UP detection, error: %d", ret);
497 ret = gesture_release(handle_);
498 if (GESTURE_ERROR_NONE != ret) {
499 LoggerE("Failed to release WRIST_UP handle, error: %d", ret);
505 return PlatformResult(ErrorCode::NO_ERROR);
508 // GetData is not supported by gesture monitor
511 static void OnWristUpEvent(gesture_type_e gesture, const gesture_data_h data, double timestamp,
512 gesture_error_e error, void* user_data) {
515 auto monitor = static_cast<GestureMonitor*>(user_data);
516 auto& callback = monitor->event_callback();
519 LoggerE("No WRIST_UP event callback registered, skipping.");
523 picojson::value v = picojson::value(picojson::object());
530 class HumanActivityMonitorManager::Monitor::SensorMonitor
531 : public HumanActivityMonitorManager::Monitor {
533 using SensorEventConverter =
534 std::function<PlatformResult(sensor_event_s* event, picojson::object* o)>;
535 using SensorRecordedConverter = std::function<PlatformResult(void* data, picojson::object* o)>;
537 SensorMonitor(const std::string& t, sensor_type_e s, const SensorEventConverter& c,
538 const SensorRecordedConverter& r)
541 converter_recorded_(r),
544 recorded_data_(nullptr) {
545 ScopeLogger("type %s", type().c_str());
548 virtual ~SensorMonitor() override {
549 ScopeLogger("type %s", type().c_str());
554 virtual PlatformResult IsSupportedImpl(bool* s) const override {
555 ScopeLogger("type %s", type().c_str());
557 bool supported = false;
559 int ret = sensor_is_supported(sensor_, &supported);
560 if (SENSOR_ERROR_NONE != ret) {
561 return LogAndCreateResult(
562 ErrorCode::UNKNOWN_ERR, "Sensor support check failed",
563 ("sensor_is_supported(%d), error: %d (%s)", sensor_, ret, get_error_message(ret)));
567 return PlatformResult(ErrorCode::NO_ERROR);
570 virtual PlatformResult SetListenerImpl(const picojson::value& args) override {
571 ScopeLogger("type %s", type().c_str());
574 sensor_h sensor_handle = nullptr;
575 int ret = sensor_get_default_sensor(sensor_, &sensor_handle);
577 if (SENSOR_ERROR_NONE != ret) {
578 return LogAndCreateResult(
579 ErrorCode::UNKNOWN_ERR, "Failed to get default sensor",
580 ("Failed to get (%d) sensor, error: %d (%s)", sensor_, ret, get_error_message(ret)));
583 ret = sensor_create_listener(sensor_handle, &handle_);
584 if (SENSOR_ERROR_NONE != ret) {
585 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to create sensor listener",
586 ("Failed to create (%d) sensor listener, error: %d (%s)", sensor_,
587 ret, get_error_message(ret)));
590 ret = sensor_listener_set_option(handle_, SENSOR_OPTION_ALWAYS_ON);
591 if (SENSOR_ERROR_NONE != ret) {
592 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set sensor listener option",
593 ("Failed to set (%d) sensor listener option, error: %d (%s)",
594 sensor_, ret, get_error_message(ret)));
598 auto& js_interval = args.get(kCallbackInterval);
600 if (js_interval.is<double>()) {
601 interval = js_interval.get<double>();
602 LoggerD("callbackInterval: %d", interval);
605 ret = sensor_listener_set_event_cb(handle_, interval, OnSensorEvent, this);
606 if (SENSOR_ERROR_NONE != ret) {
607 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set sensor listener",
608 ("Failed to set (%d) sensor listener, error: %d (%s)", sensor_,
609 ret, get_error_message(ret)));
612 ret = sensor_listener_start(handle_);
613 if (SENSOR_ERROR_NONE != ret) {
614 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to start sensor listener",
615 ("Failed to start (%d) sensor listener, error: %d (%s)", sensor_,
616 ret, get_error_message(ret)));
620 return PlatformResult(ErrorCode::NO_ERROR);
623 virtual PlatformResult UnsetListenerImpl() override {
624 ScopeLogger("type %s", type().c_str());
627 int ret = sensor_listener_stop(handle_);
628 if (SENSOR_ERROR_NONE != ret) {
629 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to stop sensor listener",
630 ("Failed to stop (%d) sensor listener, error: %d (%s)", sensor_,
631 ret, get_error_message(ret)));
634 ret = sensor_listener_unset_event_cb(handle_);
635 if (SENSOR_ERROR_NONE != ret) {
636 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to unset sensor listener",
637 ("Failed to unset (%d) sensor listener, error: %d (%s)", sensor_,
638 ret, get_error_message(ret)));
641 ret = sensor_destroy_listener(handle_);
642 if (SENSOR_ERROR_NONE != ret) {
643 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to destroy sensor listener",
644 ("Failed to destroy (%d) sensor listener, error: %d (%s)",
645 sensor_, ret, get_error_message(ret)));
651 return PlatformResult(ErrorCode::NO_ERROR);
654 virtual PlatformResult GetDataImpl(picojson::value* data) const override {
655 ScopeLogger("type %s", type().c_str());
658 return LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "SERVICE_NOT_AVAILABLE_ERR");
661 sensor_event_s event = {0};
662 int ret = sensor_listener_read_data(handle_, &event);
664 if (SENSOR_ERROR_NONE != ret) {
665 return LogAndCreateResult(
666 ErrorCode::UNKNOWN_ERR, "Failed to get sensor data",
667 ("Failed to get (%d) sensor data, error: %d (%s)", sensor_, ret, get_error_message(ret)));
670 if (SENSOR_HUMAN_PEDOMETER == sensor_) {
671 // read data of pedometer does not have valid diff[] , so diff_count set 0
672 const auto pedometer_data = (PedometerDataWrapper*)(&event);
673 pedometer_data->diffs_count = 0;
676 *data = picojson::value(picojson::object());
677 auto result = converter_(&event, &data->get<picojson::object>());
682 return PlatformResult(ErrorCode::NO_ERROR);
685 virtual PlatformResult StartDataRecorderImpl(int interval, int retention_period) const override {
686 ScopeLogger("type %s", type().c_str());
688 sensor_recorder_option_h option = nullptr;
690 int ret = sensor_recorder_create_option(&option);
691 if (SENSOR_ERROR_NONE != ret) {
692 return LogAndCreateResult(getErrorCode(ret), "Failed to create recorder option",
693 ("Failed to create (%d) recorder option, error: %d (%s)", sensor_,
694 ret, get_error_message(ret)));
698 sensor_recorder_destroy_option(option);
701 auto result = SetOptions(&option, interval, retention_period);
706 ret = sensor_recorder_start(sensor_, option);
707 if (SENSOR_ERROR_NONE != ret) {
708 return LogAndCreateResult(
709 getErrorCode(ret), "Failed to start recording",
710 ("Failed to start (%d) recording, error: %d (%s)", sensor_, ret, get_error_message(ret)));
713 return PlatformResult(ErrorCode::NO_ERROR);
716 virtual PlatformResult StopDataRecorderImpl() const override {
717 ScopeLogger("type %s", type().c_str());
719 int ret = sensor_recorder_stop(sensor_);
720 if (SENSOR_ERROR_NONE != ret) {
721 return LogAndCreateResult(
722 getErrorCode(ret), "Failed to stop recording",
723 ("Failed to stop (%d) recording, error: %d (%s)", sensor_, ret, get_error_message(ret)));
726 return PlatformResult(ErrorCode::NO_ERROR);
729 virtual PlatformResult ReadRecorderDataImpl(picojson::array* data,
730 const picojson::value& query) override {
731 ScopeLogger("type %s", type().c_str());
733 std::lock_guard<std::mutex> lock(mutex_);
734 this->recorded_data_ = data;
736 sensor_recorder_query_h query_h = nullptr;
737 int ret = sensor_recorder_create_query(&query_h);
738 if (SENSOR_ERROR_NONE != ret) {
739 return LogAndCreateResult(
740 getErrorCode(ret), "Failed to create query",
741 ("Failed to create (%d) query, error: %d (%s)", sensor_, ret, get_error_message(ret)));
745 sensor_recorder_destroy_query(query_h);
748 if (!query.is<picojson::null>()) {
749 auto result = SetQuery(&query_h, query);
756 sensor_recorder_read_sync(sensor_, query_h, SensorRecordedDataCb, static_cast<void*>(this));
757 if (SENSOR_ERROR_NONE != ret) {
758 return LogAndCreateResult(getErrorCode(ret), "Failed to read recorded data",
759 ("Failed to read (%d) recorded data, error: %d (%s)", sensor_, ret,
760 get_error_message(ret)));
763 return PlatformResult(ErrorCode::NO_ERROR);
766 void addRecordedData(picojson::value* data) {
768 recorded_data_->push_back(*data);
771 SensorEventConverter converter_;
772 SensorRecordedConverter converter_recorded_;
775 static void OnSensorEvent(sensor_h, sensor_event_s* event, void* user_data) {
778 auto monitor = static_cast<SensorMonitor*>(user_data);
779 auto& callback = monitor->event_callback();
782 LoggerE("No sensor event callback registered, skipping.");
786 picojson::value sensor_data{picojson::object{}};
788 auto result = monitor->converter_(event, &sensor_data.get<picojson::object>());
790 LoggerE("Failed to convert sensor data: %s", result.message().c_str());
794 callback(&sensor_data);
797 static bool SensorRecordedDataCb(sensor_type_e type, void* data, int remains,
798 sensor_error_e error, void* user_data) {
801 auto monitor = static_cast<SensorMonitor*>(user_data);
803 picojson::value val = picojson::value(picojson::object());
804 picojson::object* obj = &val.get<picojson::object>();
806 auto result = monitor->converter_recorded_(data, obj);
808 monitor->addRecordedData(&val);
811 return true; // continue
814 PlatformResult SetOptions(sensor_recorder_option_h* option, int interval,
815 int retention_period) const {
818 int ret = SENSOR_ERROR_NONE;
820 if (SENSOR_HRM == sensor_) {
821 ret = sensor_recorder_option_set_int(*option, SENSOR_RECORDER_OPTION_INTERVAL, interval);
823 if (SENSOR_ERROR_NONE != ret) {
824 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set recorder option",
825 ("Failed to set (%d) recorder option, error: %d (%s)", sensor_,
826 ret, get_error_message(ret)));
830 ret = sensor_recorder_option_set_int(*option, SENSOR_RECORDER_OPTION_RETENTION_PERIOD,
832 if (SENSOR_ERROR_NONE != ret) {
833 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set recorder option",
834 ("Failed to set (%d) recorder option, error: %d (%s)", sensor_, ret,
835 get_error_message(ret)));
838 return PlatformResult(ErrorCode::NO_ERROR);
841 PlatformResult SetQuery(sensor_recorder_query_h* query_h, const picojson::value& query) const {
844 SensorRecorderQueryMap map_query{
845 {SENSOR_RECORDER_QUERY_START_TIME, kRecordedStartTime},
846 {SENSOR_RECORDER_QUERY_END_TIME, kRecordedEndTime},
849 if (SENSOR_HUMAN_PEDOMETER == sensor_ || SENSOR_PRESSURE == sensor_) {
850 map_query.insert(std::make_pair(SENSOR_RECORDER_QUERY_ANCHOR_TIME, kRecordedAnchorTime));
851 map_query.insert(std::make_pair(SENSOR_RECORDER_QUERY_TIME_INTERVAL, kRecordedInterval));
854 for (auto& it : map_query) {
856 if (query.get(it.second).is<double>()) {
857 val = query.get(it.second).get<double>();
860 if (SENSOR_RECORDER_QUERY_TIME_INTERVAL != it.first) {
861 ret = sensor_recorder_query_set_time(*query_h, it.first, val);
863 ret = sensor_recorder_query_set_int(*query_h, it.first, val);
865 if (SENSOR_ERROR_NONE != ret) {
866 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set query parameter",
867 ("Failed to set (%d) query parameter, error: %d (%s)",
868 sensor_, ret, get_error_message(ret)));
874 return PlatformResult(ErrorCode::NO_ERROR);
877 sensor_type_e sensor_;
878 sensor_listener_h handle_;
879 picojson::array* recorded_data_;
883 class HumanActivityMonitorManager::Monitor::PedometerMonitor
884 : public HumanActivityMonitorManager::Monitor::SensorMonitor {
890 : SensorMonitor(kActivityTypePedometer, SENSOR_HUMAN_PEDOMETER, nullptr, nullptr),
891 is_first_read(true) {
893 converter_ = [this](sensor_event_s* event, picojson::object* data) -> PlatformResult {
895 ScopeLogger("Entered into asynchronous function, convert_pedometer");
897 const auto pedometer_data = (PedometerDataWrapper*)event;
899 static PedometerDataWrapper initial_pedometer_data;
901 if (this->is_first_read) {
902 initial_pedometer_data = *pedometer_data;
903 this->is_first_read = false;
906 static float steps_so_far = 0.0;
908 const auto state = pedometer_data->state();
910 data->insert(std::make_pair(kStepStatus, picojson::value(FromSensorPedometerState(state))));
911 data->insert(std::make_pair(kSpeed, picojson::value(pedometer_data->speed())));
912 data->insert(std::make_pair(kWalkingFrequency, picojson::value(pedometer_data->frequency())));
914 data->insert(std::make_pair(
916 picojson::value(pedometer_data->distance() - initial_pedometer_data.distance())));
917 data->insert(std::make_pair(
919 picojson::value(pedometer_data->calories() - initial_pedometer_data.calories())));
920 data->insert(std::make_pair(
921 kCumulativeTotalStepCount,
922 picojson::value(pedometer_data->steps() - initial_pedometer_data.steps())));
923 data->insert(std::make_pair(
924 kCumulativeWalkStepCount,
925 picojson::value(pedometer_data->walk_steps() - initial_pedometer_data.walk_steps())));
926 data->insert(std::make_pair(
927 kCumulativeRunStepCount,
928 picojson::value(pedometer_data->run_steps() - initial_pedometer_data.run_steps())));
931 std::make_pair(kAccumulativeDistance, picojson::value(pedometer_data->distance())));
933 std::make_pair(kAccumulativeCalorie, picojson::value(pedometer_data->calories())));
935 std::make_pair(kAccumulativeTotalStepCount, picojson::value(pedometer_data->steps())));
936 data->insert(std::make_pair(kAccumulativeWalkStepCount,
937 picojson::value(pedometer_data->walk_steps())));
939 std::make_pair(kAccumulativeRunStepCount, picojson::value(pedometer_data->run_steps())));
942 data->insert(std::make_pair(kStepCountDifferences, picojson::value{picojson::array{}}))
943 .first->second.get<picojson::array>();
944 LoggerD("pedometer_data->diffs_count: %d", pedometer_data->diffs_count);
945 if (pedometer_data->diffs_count > 0) {
946 for (int i = 0; i < pedometer_data->diffs_count; ++i) {
947 InsertStepDifference(pedometer_data->diffs[i].steps,
948 getCurrentTimeStamp(pedometer_data->diffs[i].timestamp) / 1000,
952 InsertStepDifference(steps_so_far > 0.0 ? pedometer_data->steps() - steps_so_far : 0.0,
953 getCurrentTimeStamp(pedometer_data->timestamp) / 1000, &diffs);
956 steps_so_far = pedometer_data->steps();
958 return PlatformResult(ErrorCode::NO_ERROR);
961 converter_recorded_ = [](void* data, picojson::object* obj) -> PlatformResult {
962 ScopeLogger("Entered into asynchronous function, convert_recorded_pedometer");
964 SensorRecorderDataMap map_int{{SENSOR_RECORDER_DATA_STEPS, kRecordedTotalStepCount},
965 {SENSOR_RECORDER_DATA_WALK_STEPS, kRecordedWalkStepCount},
966 {SENSOR_RECORDER_DATA_RUN_STEPS, kRecordedRunStepCount}};
968 SensorRecorderDataMap map_double{{SENSOR_RECORDER_DATA_DISTANCE, kRecordedDistance},
969 {SENSOR_RECORDER_DATA_CALORIE, kRecordedCalorie}};
971 auto result = ConvertRecordedInt(data, obj, map_int);
976 result = ConvertRecordedDouble(data, obj, map_double);
981 return ConvertRecordedTime(data, obj);
985 virtual ~PedometerMonitor() {
989 virtual PlatformResult SetListenerImpl(const picojson::value& args) override {
991 is_first_read = true;
992 return HumanActivityMonitorManager::Monitor::SensorMonitor::SetListenerImpl(args);
996 class HumanActivityMonitorManager::Monitor::GpsMonitor
997 : public HumanActivityMonitorManager::Monitor {
999 explicit GpsMonitor(const std::string& t) : Monitor(t), handle_(nullptr) {
1000 ScopeLogger("type %s", type().c_str());
1003 virtual ~GpsMonitor() override {
1004 ScopeLogger("type %s", type().c_str());
1005 UnsetListenerImpl();
1009 virtual PlatformResult IsSupportedImpl(bool* s) const override {
1010 ScopeLogger("type %s", type().c_str());
1013 ret = system_info_get_platform_bool("http://tizen.org/feature/location.batch", s);
1014 if (SYSTEM_INFO_ERROR_NONE != ret) {
1015 return LogAndCreateResult(
1016 ErrorCode::UNKNOWN_ERR, "Failed to get location.batch feature",
1017 ("system_info_get_platform_bool error: %d (%s)", ret, get_error_message(ret)));
1019 return PlatformResult(ErrorCode::NO_ERROR);
1022 virtual PlatformResult SetListenerImpl(const picojson::value& args) override {
1023 ScopeLogger("type %s", type().c_str());
1028 int ret = location_manager_create(LOCATIONS_METHOD_GPS, &handle_);
1029 if (LOCATIONS_ERROR_NONE != ret) {
1030 return LogAndCreateResult(
1031 ErrorCode::UNKNOWN_ERR, "Failed to create location manager",
1032 ("Failed to create location manager, error: %d (%s)", ret, get_error_message(ret)));
1035 ret = location_manager_set_setting_changed_cb(LOCATIONS_METHOD_GPS, OnGpsSettingEvent, this);
1036 if (LOCATIONS_ERROR_NONE != ret) {
1037 return LogAndCreateResult(
1038 ErrorCode::UNKNOWN_ERR, "Failed to set setting listener",
1039 ("Failed to set setting listener, error: %d (%s)", ret, get_error_message(ret)));
1042 ret = location_manager_stop_batch(handle_);
1043 if (LOCATIONS_ERROR_NONE != ret) {
1044 return LogAndCreateResult(
1045 ErrorCode::UNKNOWN_ERR, "Failed to stop location manager",
1046 ("Failed to stop location manager, error: %d (%s)", ret, get_error_message(ret)));
1050 int callback_interval = static_cast<int>(args.get(kCallbackInterval).get<double>() / 1000);
1051 int sample_interval = static_cast<int>(args.get(kSampleInterval).get<double>() / 1000);
1052 LoggerD("callbackInterval: %d, sampleInterval: %d", callback_interval, sample_interval);
1054 ret = location_manager_set_location_batch_cb(handle_, OnGpsEvent,
1055 sample_interval, // batch_interval
1056 callback_interval, // batch_period
1058 if (LOCATIONS_ERROR_NONE != ret) {
1059 if (LOCATIONS_ERROR_INVALID_PARAMETER == ret) {
1060 return LogAndCreateResult(
1061 ErrorCode::INVALID_VALUES_ERR, "Failed to set location listener",
1062 ("Failed to set location listener, error: %d (%s)", ret, get_error_message(ret)));
1064 return LogAndCreateResult(
1065 ErrorCode::UNKNOWN_ERR, "Failed to set location listener",
1066 ("Failed to set location listener, error: %d (%s)", ret, get_error_message(ret)));
1069 ret = location_manager_start_batch(handle_);
1070 if (LOCATIONS_ERROR_NONE != ret) {
1071 return LogAndCreateResult(
1072 ErrorCode::UNKNOWN_ERR, "Failed to start location manager",
1073 ("Failed to start location manager, error: %d (%s)", ret, get_error_message(ret)));
1076 return PlatformResult(ErrorCode::NO_ERROR);
1079 virtual PlatformResult UnsetListenerImpl() override {
1080 ScopeLogger("type %s", type().c_str());
1083 int ret = location_manager_stop_batch(handle_);
1084 if (LOCATIONS_ERROR_NONE != ret) {
1085 return LogAndCreateResult(
1086 ErrorCode::UNKNOWN_ERR, "Failed to stop location manager",
1087 ("Failed to stop location manager, error: %d (%s)", ret, get_error_message(ret)));
1090 ret = location_manager_unset_setting_changed_cb(LOCATIONS_METHOD_GPS);
1091 if (LOCATIONS_ERROR_NONE != ret) {
1092 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
1093 "Failed to unset location setting changed cb",
1094 ("Failed to unset location setting changed cb, error: %d (%s)",
1095 ret, get_error_message(ret)));
1098 ret = location_manager_destroy(handle_);
1099 if (LOCATIONS_ERROR_NONE != ret) {
1100 return LogAndCreateResult(
1101 ErrorCode::UNKNOWN_ERR, "Failed to destroy location manager",
1102 ("Failed to destroy location manager, error: %d (%s)", ret, get_error_message(ret)));
1108 return PlatformResult(ErrorCode::NO_ERROR);
1111 virtual PlatformResult GetDataImpl(picojson::value* data) const override {
1112 ScopeLogger("type %s", type().c_str());
1115 return LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "SERVICE_NOT_AVAILABLE_ERR");
1118 double altitude = 0.0, latitude = 0.0, longitude = 0.0, climb = 0.0, direction = 0.0,
1119 speed = 0.0, horizontal = 0.0, vertical = 0.0;
1120 location_accuracy_level_e level = LOCATIONS_ACCURACY_NONE;
1121 time_t timestamp = 0;
1124 location_manager_get_location(handle_, &altitude, &latitude, &longitude, &climb, &direction,
1125 &speed, &level, &horizontal, &vertical, ×tamp);
1126 if (LOCATIONS_ERROR_NONE != ret) {
1127 return LogAndCreateResult(
1128 ErrorCode::UNKNOWN_ERR, "Failed to get location",
1129 ("Failed to get location, error: %d (%s)", ret, get_error_message(ret)));
1132 *data = picojson::value(picojson::array());
1133 ConvertGpsEvent(latitude, longitude, altitude, speed, direction, horizontal, vertical,
1134 timestamp, &data->get<picojson::array>());
1136 return PlatformResult(ErrorCode::NO_ERROR);
1140 static void OnGpsSettingEvent(location_method_e method, bool enable, void* user_data) {
1143 if (LOCATIONS_METHOD_GPS != method) {
1144 LoggerD("Location method different from GPS");
1148 auto monitor = static_cast<GpsMonitor*>(user_data);
1149 auto& callback = monitor->event_callback();
1152 LoggerE("No GPS event callback registered, skipping.");
1157 picojson::value val{picojson::object{}};
1158 auto& obj = val.get<picojson::object>();
1161 PlatformResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "GPS service is not available"),
1162 &obj, ("GPS service is not available"));
1168 static void OnGpsEvent(int num_of_location, void* user_data) {
1171 auto monitor = static_cast<GpsMonitor*>(user_data);
1172 auto& callback = monitor->event_callback();
1175 LoggerE("No GPS event callback registered, skipping.");
1179 if (0 == num_of_location) {
1180 LoggerE("No GPS locations available, skipping.");
1184 picojson::value gps_info{picojson::array{}};
1185 int ret = location_manager_foreach_location_batch(monitor->handle_, ConvertGpsEvent,
1186 &gps_info.get<picojson::array>());
1187 if (LOCATIONS_ERROR_NONE != ret) {
1188 LoggerE("Failed to convert location, error: %d", ret);
1192 picojson::value out{picojson::object{}};
1193 (out.get<picojson::object>())["gpsInfo"] = gps_info;
1198 static bool ConvertGpsEvent(double latitude, double longitude, double altitude, double speed,
1199 double direction, double horizontal, double vertical,
1200 time_t timestamp, void* user_data) {
1203 auto gps_info_array = static_cast<picojson::array*>(user_data);
1205 picojson::value gps_info{picojson::object{}};
1206 auto& gps_info_o = gps_info.get<picojson::object>();
1208 gps_info_o["latitude"] = picojson::value(latitude);
1209 gps_info_o["longitude"] = picojson::value(longitude);
1210 gps_info_o["altitude"] = picojson::value(altitude);
1211 gps_info_o["speed"] = picojson::value(speed);
1212 // TODO(r.galka): errorRange not available in CAPI
1213 gps_info_o["errorRange"] = picojson::value(horizontal);
1214 gps_info_o[kTimestamp] = picojson::value(static_cast<double>(timestamp));
1216 gps_info_array->push_back(gps_info);
1221 location_manager_h handle_;
1224 class HumanActivityMonitorManager::ActivityRecognition {
1226 PlatformResult AddListener(const std::string& type, JsonCallback callback, long* watch_id) {
1229 activity_type_e activity_type = ToActivityType(type);
1230 auto result = IsSupported(activity_type);
1236 activity_h handle = nullptr;
1237 int ret = activity_create(&handle);
1238 if (ACTIVITY_ERROR_NONE != ret) {
1239 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to create activity",
1240 ("activity_create() error: %d - %s", ret, get_error_message(ret)));
1243 const auto id = GetNextId();
1244 auto data = std::make_shared<ActivityData>(id, callback, handle);
1246 ret = activity_start_recognition(handle, activity_type, OnActivityRecognitionEvent, data.get());
1247 if (ACTIVITY_ERROR_NONE != ret) {
1248 return LogAndCreateResult(
1249 ErrorCode::UNKNOWN_ERR, "Failed to start activity recognition",
1250 ("activity_start_recognition() error: %d - %s", ret, get_error_message(ret)));
1253 activity_data_.insert(std::make_pair(id, data));
1259 PlatformResult RemoveListener(long watch_id) {
1262 const auto it = activity_data_.find(watch_id);
1264 if (activity_data_.end() != it) {
1265 activity_data_.erase(it);
1268 return PlatformResult(ErrorCode::NO_ERROR);
1272 struct ActivityData {
1273 ActivityData(long id, const JsonCallback& cb, activity_h h)
1274 : watch_id(id), callback(cb), handle(h) {
1279 activity_stop_recognition(handle);
1280 activity_release(handle);
1285 JsonCallback callback;
1289 static long GetNextId() {
1294 static void OnActivityRecognitionEvent(activity_type_e type, const activity_data_h data,
1295 double timestamp, activity_error_e callback_error,
1299 auto activity_data = static_cast<ActivityData*>(user_data);
1300 JsonCallback callback = activity_data->callback;
1302 picojson::value val{picojson::object{}};
1303 auto& obj = val.get<picojson::object>();
1305 std::make_pair("watchId", picojson::value(static_cast<double>(activity_data->watch_id))));
1307 if (ACTIVITY_ERROR_NONE != callback_error) {
1308 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "System operation has failed"), &obj,
1309 ("activity_recognition_cb() has failed with error code %d - %s",
1310 callback_error, get_error_message(callback_error)));
1315 activity_accuracy_e accuracy = ACTIVITY_ACCURACY_MID;
1317 int ret = activity_get_accuracy(data, &accuracy);
1318 if (ret != ACTIVITY_ERROR_NONE) {
1319 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "System operation has failed"), &obj,
1320 ("activity_get_accuracy() has failed with error code %d - %s", ret,
1321 get_error_message(ret)));
1325 timestamp = std::floor(timestamp);
1326 SLoggerD("Activity type: (%d)", type);
1327 SLoggerD("Activity accuracy: (%d)", accuracy);
1328 SLoggerD("Activity timestamp: (%f)", timestamp);
1330 picojson::value result{picojson::object{}};
1331 auto& result_obj = result.get<picojson::object>();
1333 result_obj.insert(std::make_pair("type", picojson::value(FromActivityType(type))));
1334 result_obj.insert(std::make_pair("accuracy", picojson::value(FromActivityAccuracy(accuracy))));
1335 result_obj.insert(std::make_pair(kTimestamp, picojson::value(timestamp)));
1337 ReportSuccess(result, obj);
1341 PlatformResult IsSupported(activity_type_e type) {
1344 bool supported = false;
1345 int ret = activity_is_supported(type, &supported);
1347 if (ret == ACTIVITY_ERROR_NOT_SUPPORTED || !supported) {
1348 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, "Activity type is not supported",
1349 ("Type %d not supported", type));
1350 } else if (ret != ACTIVITY_ERROR_NONE) {
1351 return LogAndCreateResult(
1352 ErrorCode::UNKNOWN_ERR, "activity_is_supported failed",
1353 ("activity_is_supported error %d - %s", ret, get_error_message(ret)));
1355 return PlatformResult(ErrorCode::NO_ERROR);
1359 #define ACTIVITY_TYPE_E \
1360 X(ACTIVITY_STATIONARY, "STATIONARY") \
1361 X(ACTIVITY_WALK, "WALKING") \
1362 X(ACTIVITY_RUN, "RUNNING") \
1363 X(ACTIVITY_IN_VEHICLE, "IN_VEHICLE") \
1364 XD(static_cast<activity_type_e>(-1), "unknown")
1366 #define ACTIVITY_ACCURACY_E \
1367 X(ACTIVITY_ACCURACY_LOW, "LOW") \
1368 X(ACTIVITY_ACCURACY_MID, "MEDIUM") \
1369 X(ACTIVITY_ACCURACY_HIGH, "HIGH") \
1370 XD(static_cast<activity_accuracy_e>(-1), "unknown")
1377 LoggerE("Unknown value: %d, returning default: %s", e, s); \
1380 static std::string FromActivityType(activity_type_e e) {
1383 switch (e) { ACTIVITY_TYPE_E }
1386 static std::string FromActivityAccuracy(activity_accuracy_e e) {
1389 switch (e) { ACTIVITY_ACCURACY_E }
1396 if (e == s) return v;
1398 LoggerE("Unknown value: %s, returning default: %d", e.c_str(), v); \
1401 static activity_type_e ToActivityType(const std::string& e) {
1410 #undef ACTIVITY_ACCURACY_E
1411 #undef ACTIVITY_TYPE_E
1413 std::map<long, std::shared_ptr<ActivityData>> activity_data_;
1416 PlatformResult SleepStateToString(int state, std::string* sleep_state) {
1417 ScopeLogger("%d", state);
1420 case SENSOR_SLEEP_STATE_WAKE:
1421 *sleep_state = kSleepStateAwake;
1423 case SENSOR_SLEEP_STATE_SLEEP:
1424 *sleep_state = kSleepStateAsleep;
1426 case SENSOR_SLEEP_STATE_UNKNOWN:
1427 *sleep_state = kSleepStateUnknown;
1430 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown sleep state",
1431 ("Unknown sleep state: %d", state));
1433 return PlatformResult(ErrorCode::NO_ERROR);
1435 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
1436 "Cannot return sleep state, return pointer is null");
1439 HumanActivityMonitorManager::HumanActivityMonitorManager()
1440 : activity_recognition_(std::make_shared<ActivityRecognition>()) {
1443 auto convert_hrm = [](sensor_event_s* event, picojson::object* data) -> PlatformResult {
1444 ScopeLogger("Entered into asynchronous function, convert_hrm");
1446 LoggerD("Sensor event:");
1447 LoggerD("|- accuracy: %d", event->accuracy);
1448 LoggerD("|- timestamp: %llu", event->timestamp);
1449 LoggerD("|- value_count: %d", event->value_count);
1451 if (event->value_count < 2) {
1452 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "To few values of HRM event");
1455 LoggerD("|- values[0][HR ]: %f", event->values[0]);
1456 LoggerD("|- values[2][RRI]: %f", event->values[2]);
1458 float hr = floor(event->values[0] + 0.5); // heart beat rate 0 ~ 220 integer (bpm)
1460 // there are no public native api documentation for peak to peak interval.
1461 // but RRI = (60 / HR) * 1000
1463 // in capi, rri is in values[2], but it is not documented because value can be unstable
1464 // and it is not available on all devices. On solis it works fine.
1466 float rri = floor(event->values[2] + 0.5); // rr-interval 0 ~ 5000 integer (ms)
1468 data->insert(std::make_pair("heartRate", picojson::value(static_cast<double>(hr))));
1469 data->insert(std::make_pair("rRInterval", picojson::value(static_cast<double>(rri))));
1471 return PlatformResult(ErrorCode::NO_ERROR);
1474 auto convert_sleep = [](sensor_event_s* event, picojson::object* data) -> PlatformResult {
1475 ScopeLogger("Entered into asynchronous function, convert_sleep");
1477 if (event->value_count < 1) {
1478 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "To few values of SLEEP event");
1481 sensor_sleep_state_e state = static_cast<sensor_sleep_state_e>(event->values[0]);
1482 std::string sleep_state;
1483 PlatformResult result = SleepStateToString(state, &sleep_state);
1488 data->insert(std::make_pair(kStatus, picojson::value(sleep_state)));
1489 data->insert(std::make_pair(
1490 kTimestamp, picojson::value(static_cast<double>(getCurrentTimeStamp(event->timestamp)))));
1492 return PlatformResult(ErrorCode::NO_ERROR);
1495 auto convert_sleep_detector = [](sensor_event_s* event,
1496 picojson::object* data) -> PlatformResult {
1497 ScopeLogger("convert_sleep_detector");
1499 if (event->value_count < 1) {
1500 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "To few values of SLEEP event");
1503 sensor_sleep_state_e state = static_cast<sensor_sleep_state_e>(event->values[0]);
1504 std::string sleep_state;
1505 PlatformResult result = SleepStateToString(state, &sleep_state);
1510 data->insert(std::make_pair(kStatus, picojson::value(sleep_state)));
1512 return PlatformResult(ErrorCode::NO_ERROR);
1515 auto convert_stress = [](sensor_event_s* event, picojson::object* data) -> PlatformResult {
1516 ScopeLogger("convert_stress");
1518 if (event->value_count < 1) {
1519 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "To few values of STRESS event");
1522 float stress_score = event->values[0];
1523 data->insert(std::make_pair(kStressScore, picojson::value(static_cast<double>(stress_score))));
1525 return PlatformResult(ErrorCode::NO_ERROR);
1528 auto convert_recorded_hrm = [](void* data, picojson::object* obj) -> PlatformResult {
1529 ScopeLogger("Entered into asynchronous function, convert_recorded_hrm");
1531 SensorRecorderDataMap map_int{
1532 {SENSOR_RECORDER_DATA_HEART_RATE, kRecordedHeartRate},
1535 auto result = ConvertRecordedInt(data, obj, map_int);
1540 return ConvertRecordedTime(data, obj);
1543 auto convert_recorded_sleep_monitor = [](void* data, picojson::object* obj) -> PlatformResult {
1544 ScopeLogger("Entered into asynchronous function, convert_recorded_sleep_monitor");
1547 int ret = sensor_recorder_data_get_int(data, SENSOR_RECORDER_DATA_SLEEP_STATE, &state);
1548 if (SENSOR_ERROR_NONE != ret) {
1549 return LogAndCreateResult(
1550 getErrorCode(ret), "Failed to get int value",
1551 ("Failed to get int value, error: %d (%s)", ret, get_error_message(ret)));
1554 std::string sleep_state;
1555 PlatformResult result = SleepStateToString(state, &sleep_state);
1560 obj->insert(std::make_pair(kStatus, picojson::value(sleep_state)));
1562 return ConvertRecordedTime(data, obj);
1565 auto convert_recorded_pressure = [](void* data, picojson::object* obj) -> PlatformResult {
1566 ScopeLogger("Entered into asynchronous function, convert_recorded_pressure");
1568 SensorRecorderDataMap map_double{{SENSOR_RECORDER_DATA_MAX_PRESSURE, kRecordedMax},
1569 {SENSOR_RECORDER_DATA_MIN_PRESSURE, kRecordedMin},
1570 {SENSOR_RECORDER_DATA_AVERAGE_PRESSURE, kRecordedAverage}};
1572 auto result = ConvertRecordedDouble(data, obj, map_double);
1577 return ConvertRecordedTime(data, obj);
1581 std::make_pair(kActivityTypePedometer, std::make_shared<Monitor::PedometerMonitor>()));
1582 monitors_.insert(std::make_pair(kActivityTypeWristUp,
1583 std::make_shared<Monitor::GestureMonitor>(kActivityTypeWristUp)));
1584 monitors_.insert(std::make_pair(kActivityTypeSleepDetector,
1585 std::make_shared<Monitor::SensorMonitor>(
1586 kActivityTypeSleepDetector, SENSOR_HUMAN_SLEEP_DETECTOR,
1587 convert_sleep_detector, nullptr)));
1588 monitors_.insert(std::make_pair(
1589 kActivityTypeStressMonitor,
1590 std::make_shared<Monitor::SensorMonitor>(
1591 kActivityTypeStressMonitor, SENSOR_HUMAN_STRESS_MONITOR, convert_stress, nullptr)));
1592 monitors_.insert(std::make_pair(
1593 kActivityTypeHrm, std::make_shared<Monitor::SensorMonitor>(
1594 kActivityTypeHrm, SENSOR_HRM, convert_hrm, convert_recorded_hrm)));
1596 std::make_pair(kActivityTypeGps, std::make_shared<Monitor::GpsMonitor>(kActivityTypeGps)));
1597 monitors_.insert(std::make_pair(kActivityTypeSleepMonitor,
1598 std::make_shared<Monitor::SensorMonitor>(
1599 kActivityTypeSleepMonitor, SENSOR_HUMAN_SLEEP_MONITOR,
1600 convert_sleep, convert_recorded_sleep_monitor)));
1601 monitors_.insert(std::make_pair(kActivityTypePressure, std::make_shared<Monitor::SensorMonitor>(
1602 kActivityTypePressure, SENSOR_PRESSURE,
1603 nullptr, convert_recorded_pressure)));
1606 HumanActivityMonitorManager::~HumanActivityMonitorManager() {
1610 PlatformResult HumanActivityMonitorManager::Init() {
1612 return PlatformResult(ErrorCode::NO_ERROR);
1615 PlatformResult HumanActivityMonitorManager::IsSupported(const std::string& type) {
1616 return this->GetMonitor(type)->IsSupported();
1619 PlatformResult HumanActivityMonitorManager::SetListener(const std::string& type,
1620 JsonCallback callback,
1621 const picojson::value& args) {
1623 return GetMonitor(type)->SetListener(callback, args);
1626 PlatformResult HumanActivityMonitorManager::UnsetListener(const std::string& type) {
1628 return GetMonitor(type)->UnsetListener();
1631 PlatformResult HumanActivityMonitorManager::GetHumanActivityData(const std::string& type,
1632 picojson::value* data) {
1634 return GetMonitor(type)->GetData(data);
1637 PlatformResult HumanActivityMonitorManager::AddActivityRecognitionListener(const std::string& type,
1638 JsonCallback callback,
1641 return activity_recognition_->AddListener(type, callback, watch_id);
1644 PlatformResult HumanActivityMonitorManager::RemoveActivityRecognitionListener(const long watch_id) {
1646 return activity_recognition_->RemoveListener(watch_id);
1649 PlatformResult HumanActivityMonitorManager::StartDataRecorder(const std::string& type, int interval,
1650 int retention_period) {
1652 return GetMonitor(type)->StartDataRecorder(interval, retention_period);
1655 PlatformResult HumanActivityMonitorManager::StopDataRecorder(const std::string& type) {
1657 return GetMonitor(type)->StopDataRecorder();
1660 PlatformResult HumanActivityMonitorManager::ReadRecorderData(const std::string& type,
1661 picojson::array* data,
1662 const picojson::value& query) {
1664 return GetMonitor(type)->ReadRecorderData(data, query);
1667 std::shared_ptr<HumanActivityMonitorManager::Monitor> HumanActivityMonitorManager::GetMonitor(
1668 const std::string& type) {
1671 const auto it = monitors_.find(type);
1673 if (monitors_.end() != it) {
1676 return std::make_shared<Monitor>(type); // return default unsupported monitor
1680 } // namespace humanactivitymonitor
1681 } // namespace extension