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 <gesture_recognition.h>
21 #include "common/logger.h"
24 namespace humanactivitymonitor {
26 using common::PlatformResult;
27 using common::ErrorCode;
29 HumanActivityMonitorManager::HumanActivityMonitorManager() {
33 HumanActivityMonitorManager::~HumanActivityMonitorManager() {
35 UnsetWristUpListener();
40 PlatformResult HumanActivityMonitorManager::Init() {
42 return PlatformResult(ErrorCode::NO_ERROR);
45 PlatformResult HumanActivityMonitorManager::IsSupported(
46 const std::string& type) {
49 if (supported_.count(type)) {
50 return LogAndCreateResult(supported_[type]
52 : ErrorCode::NOT_SUPPORTED_ERR);
56 bool supported = false;
57 if (type == kActivityTypePedometer) {
58 // TODO(r.galka) no native api for pedometer
59 // so just pass it for not supported.
60 } else if (type == kActivityTypeWristUp) {
61 ret = gesture_is_supported(GESTURE_WRIST_UP, &supported);
62 if (ret != SENSOR_ERROR_NONE) {
63 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
64 "WRIST_UP gesture check failed",
65 ("gesture_is_supported(GESTURE_WRIST_UP), error: %d",ret));
67 } else if (type == kActivityTypeHrm) {
68 ret = sensor_is_supported(SENSOR_HRM, &supported);
69 if (ret != SENSOR_ERROR_NONE) {
70 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
71 "HRM sensor check failed",
72 ("sensor_is_supported(HRM), error: %d",ret));
74 } else if (type == kActivityTypeGps) {
75 supported = location_manager_is_supported_method(LOCATIONS_METHOD_GPS);
77 return LogAndCreateResult(ErrorCode::TYPE_MISMATCH_ERR);
80 supported_[type] = supported;
82 return LogAndCreateResult(supported_[type]
84 : ErrorCode::NOT_SUPPORTED_ERR);
87 PlatformResult HumanActivityMonitorManager::SetListener(
88 const std::string& type, JsonCallback callback) {
90 PlatformResult result = IsSupported(type);
95 if (type == kActivityTypePedometer) {
96 // TODO(r.galka) Not Supported in current implementation.
99 if (type == kActivityTypeWristUp) {
100 return SetWristUpListener(callback);
103 if (type == kActivityTypeHrm) {
104 return SetHrmListener(callback);
107 if (type == kActivityTypeGps) {
108 return SetGpsListener(callback);
111 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Undefined activity type");
114 PlatformResult HumanActivityMonitorManager::UnsetListener(
115 const std::string& type) {
117 PlatformResult result = IsSupported(type);
122 if (type == kActivityTypePedometer) {
123 // TODO(r.galka) Not Supported in current implementation.
126 if (type == kActivityTypeWristUp) {
127 return UnsetWristUpListener();
130 if (type == kActivityTypeHrm) {
131 return UnsetHrmListener();
134 if (type == kActivityTypeGps) {
135 return UnsetGpsListener();
138 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Undefined activity type");
141 PlatformResult HumanActivityMonitorManager::GetHumanActivityData(
142 const std::string& type,
143 picojson::value* data) {
146 if (type == kActivityTypePedometer) {
147 // TODO(r.galka) Not Supported in current implementation.
150 if (type == kActivityTypeWristUp) {
151 return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR);
154 if (type == kActivityTypeHrm) {
155 return GetHrmData(data);
158 if (type == kActivityTypeGps) {
159 return GetGpsData(data);
162 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Undefined activity type");
166 PlatformResult HumanActivityMonitorManager::SetWristUpListener(
167 JsonCallback callback) {
171 ret = gesture_create(&gesture_handle_);
172 if (ret != GESTURE_ERROR_NONE) {
173 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
174 "Failed to create WRIST_UP listener",
175 ("Failed to create WRIST_UP handle, error: %d",ret));
178 ret = gesture_start_recognition(gesture_handle_,
180 GESTURE_OPTION_DEFAULT,
183 if (ret != GESTURE_ERROR_NONE) {
184 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
185 "Failed to start WRIST_UP listener",
186 ("Failed to start WRIST_UP listener, error: %d",ret));
189 wrist_up_event_callback_ = callback;
191 return PlatformResult(ErrorCode::NO_ERROR);
194 PlatformResult HumanActivityMonitorManager::UnsetWristUpListener() {
197 if (gesture_handle_) {
198 int ret = gesture_stop_recognition(gesture_handle_);
199 if (ret != GESTURE_ERROR_NONE) {
200 LOGGER(ERROR) << "Failed to stop WRIST_UP detection, error: " << ret;
203 ret = gesture_release(gesture_handle_);
204 if (ret != GESTURE_ERROR_NONE) {
205 LOGGER(ERROR) << "Failed to release WRIST_UP handle, error: " << ret;
209 wrist_up_event_callback_ = nullptr;
211 return PlatformResult(ErrorCode::NO_ERROR);
214 void HumanActivityMonitorManager::OnWristUpEvent(gesture_type_e gesture,
215 const gesture_data_h data,
217 gesture_error_e error,
220 HumanActivityMonitorManager* manager =
221 static_cast<HumanActivityMonitorManager*>(user_data);
223 if (!manager->wrist_up_event_callback_) {
224 LOGGER(ERROR) << "No WRIST_UP event callback registered, skipping.";
228 picojson::value v = picojson::value(); // null value
229 manager->wrist_up_event_callback_(&v);
233 PlatformResult HumanActivityMonitorManager::SetHrmListener(
234 JsonCallback callback) {
239 ret = sensor_get_default_sensor(SENSOR_HRM, &hrm_sensor);
240 if (ret != SENSOR_ERROR_NONE) {
241 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
242 "Failed to get HRM sensor",
243 ("Failed to get HRM sensor, error: %d",ret));
246 ret = sensor_create_listener(hrm_sensor, &hrm_sensor_listener_);
247 if (ret != SENSOR_ERROR_NONE) {
248 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
249 "Failed to create HRM sensor listener",
250 ("Failed to create HRM sensor listener, error: %d",ret));
253 ret = sensor_listener_set_event_cb(hrm_sensor_listener_,
257 if (ret != SENSOR_ERROR_NONE) {
258 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
259 "Failed to set HRM sensor listener",
260 ("Failed to set HRM sensor listener, error: %d",ret));
263 ret = sensor_listener_start(hrm_sensor_listener_);
264 if (ret != SENSOR_ERROR_NONE) {
265 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
266 "Failed to start HRM sensor listener",
267 ("Failed to start HRM sensor listener, error: %d",ret));
270 hrm_event_callback_ = callback;
272 return PlatformResult(ErrorCode::NO_ERROR);
275 PlatformResult HumanActivityMonitorManager::UnsetHrmListener() {
278 if (hrm_sensor_listener_) {
279 int ret = sensor_listener_stop(hrm_sensor_listener_);
280 if (ret != SENSOR_ERROR_NONE) {
281 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
282 "Failed to stop HRM sensor",
283 ("Failed to stop HRM sensor, error: "%d,ret));
286 ret = sensor_listener_unset_event_cb(hrm_sensor_listener_);
287 if (ret != SENSOR_ERROR_NONE) {
288 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
289 "Failed to unset HRM sensor listener",
290 ("Failed to unset HRM sensor listener, error: %d",ret));
293 ret = sensor_destroy_listener(hrm_sensor_listener_);
294 if (ret != SENSOR_ERROR_NONE) {
295 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
296 "Failed to destroy HRM sensor listener",
297 ("Failed to destroy HRM sensor listener, error: %d",ret));
301 hrm_event_callback_ = nullptr;
303 return PlatformResult(ErrorCode::NO_ERROR);
306 static PlatformResult ConvertHrmEvent(sensor_event_s* event,
307 picojson::object* data) {
308 LOGGER(DEBUG) << "Sensor event:";
309 LOGGER(DEBUG) << " |- accuracy: " << event->accuracy;
310 LOGGER(DEBUG) << " |- timestamp: " << event->timestamp;
311 LOGGER(DEBUG) << " |- value_count: " << event->value_count;
313 if (event->value_count < 2) {
314 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "To few values of HRM event");
317 LOGGER(DEBUG) << " |- values[0]: " << event->values[0];
318 LOGGER(DEBUG) << " |- values[1]: " << event->values[1];
320 float hr = floor( event->values[0] + 0.5); // heart beat rate 0 ~ 220 integer (bpm)
322 // there are no public native api for peak to peak interval.
323 // but RRI = (60 / HR) * 1000
324 // or unofficially values[1] is rri (0 ~ 5000 ms)
325 float rri = floor(event->values[1] + 0.5);
328 (*data)["heartRate"] = picojson::value(static_cast<double>(hr));
329 (*data)["rRInterval"] = picojson::value(static_cast<double>(rri));
331 return PlatformResult(ErrorCode::NO_ERROR);
334 void HumanActivityMonitorManager::OnHrmSensorEvent(
335 sensor_h /*sensor*/, sensor_event_s *event, void *user_data) {
338 HumanActivityMonitorManager* manager =
339 static_cast<HumanActivityMonitorManager*>(user_data);
341 if (!manager->hrm_event_callback_) {
342 LOGGER(ERROR) << "No HRM event callback registered, skipping.";
346 picojson::value hrm_data = picojson::value(picojson::object());
347 PlatformResult result = ConvertHrmEvent(event,
348 &hrm_data.get<picojson::object>());
350 LOGGER(ERROR) << "Failed to convert HRM data: " << result.message();
354 manager->hrm_event_callback_(&hrm_data);
357 PlatformResult HumanActivityMonitorManager::GetHrmData(picojson::value* data) {
359 if (!hrm_sensor_listener_) {
360 return LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR);
365 sensor_event_s event;
366 ret = sensor_listener_read_data(hrm_sensor_listener_, &event);
367 if (ret != SENSOR_ERROR_NONE) {
368 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
369 "Failed to get HRM sensor data",
370 ("Failed to get HRM sensor data, error: %d",ret));
373 *data = picojson::value(picojson::object());
374 PlatformResult result = ConvertHrmEvent(&event,
375 &data->get<picojson::object>());
380 return PlatformResult(ErrorCode::NO_ERROR);
384 PlatformResult HumanActivityMonitorManager::SetGpsListener(
385 JsonCallback callback) {
389 ret = location_manager_create(LOCATIONS_METHOD_GPS, &location_handle_);
390 if (ret != LOCATIONS_ERROR_NONE) {
391 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
392 "Failed to create location manager",
393 ("Failed to create location manager, error: %d",ret));
396 ret = location_manager_set_location_batch_cb(location_handle_,
401 if (ret != LOCATIONS_ERROR_NONE) {
402 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
403 "Failed to set location listener",
404 ("Failed to set location listener, error: %d",ret));
407 ret = location_manager_start_batch(location_handle_);
408 if (ret != LOCATIONS_ERROR_NONE) {
409 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
410 "Failed to start location manager",
411 ("Failed to start location manager, error: %d",ret));
414 gps_event_callback_ = callback;
416 return PlatformResult(ErrorCode::NO_ERROR);
419 PlatformResult HumanActivityMonitorManager::UnsetGpsListener() {
422 if (location_handle_) {
423 int ret = location_manager_stop_batch(location_handle_);
424 if (ret != LOCATIONS_ERROR_NONE) {
425 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
426 "Failed to stop location manager",
427 ("Failed to stop location manager, error: %d",ret));
430 ret = location_manager_unset_location_batch_cb(location_handle_);
431 if (ret != LOCATIONS_ERROR_NONE) {
432 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
433 "Failed to unset location listener",
434 ("Failed to unset location listener, error: %d",ret));
437 ret = location_manager_destroy(location_handle_);
438 if (ret != LOCATIONS_ERROR_NONE) {
439 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
440 "Failed to destroy location manager",
441 ("Failed to destroy location manager, error: %d",ret));
445 gps_event_callback_ = nullptr;
447 return PlatformResult(ErrorCode::NO_ERROR);
450 static bool ConvertGpsEvent(double latitude, double longitude, double altitude,
451 double speed, double direction, double horizontal,
452 double vertical, time_t timestamp,
455 picojson::array* gps_info_array = static_cast<picojson::array*>(user_data);
457 picojson::value gps_info = picojson::value(picojson::object());
458 picojson::object& gps_info_o = gps_info.get<picojson::object>();
460 gps_info_o["latitude"] = picojson::value(latitude);
461 gps_info_o["longitude"] = picojson::value(longitude);
462 gps_info_o["altitude"] = picojson::value(altitude);
463 gps_info_o["speed"] = picojson::value(speed);
464 // TODO(r.galka) errorRange not available in CAPI
465 gps_info_o["errorRange"] = picojson::value(static_cast<double>(0));
466 gps_info_o["timestamp"] = picojson::value(static_cast<double>(timestamp));
468 gps_info_array->push_back(gps_info);
473 void HumanActivityMonitorManager::OnGpsEvent(int num_of_location,
476 HumanActivityMonitorManager* manager =
477 static_cast<HumanActivityMonitorManager*>(user_data);
479 if (!manager->gps_event_callback_) {
480 LOGGER(ERROR) << "No GPS event callback registered, skipping.";
484 if (0 == num_of_location) {
485 LOGGER(ERROR) << "No GPS locations available, skipping.";
489 picojson::value gps_info = picojson::value(picojson::array());
490 int ret = location_manager_foreach_location_batch(
491 manager->location_handle_,
493 &gps_info.get<picojson::array>());
494 if (ret != LOCATIONS_ERROR_NONE) {
495 LOGGER(ERROR) << "Failed to convert location, error: " << ret;
499 manager->gps_event_callback_(&gps_info);
502 PlatformResult HumanActivityMonitorManager::GetGpsData(picojson::value* data) {
504 if (!location_handle_) {
505 return LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR);
509 double altitude, latitude, longitude, climb,
510 direction, speed, horizontal, vertical;
511 location_accuracy_level_e level;
513 ret = location_manager_get_location(location_handle_, &altitude, &latitude,
514 &longitude, &climb, &direction, &speed,
515 &level, &horizontal, &vertical,
517 if (ret != LOCATIONS_ERROR_NONE) {
518 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to get location",
519 ("Failed to get location, error: %d",ret));
522 *data = picojson::value(picojson::array());
523 ConvertGpsEvent(latitude, longitude, altitude, speed, direction, horizontal,
524 vertical, timestamp, &data->get<picojson::array>());
526 return PlatformResult(ErrorCode::NO_ERROR);
529 } // namespace humanactivitymonitor
530 } // namespace extension