[HAM] GPS implementation
authorRafal Galka <r.galka@samsung.com>
Thu, 14 May 2015 15:28:16 +0000 (17:28 +0200)
committerRafal Galka <r.galka@samsung.com>
Thu, 14 May 2015 15:28:16 +0000 (17:28 +0200)
Change-Id: I55a6b32cec10c11560545c2ddc8e66c69c706ff6

packaging/webapi-plugins.spec
src/humanactivitymonitor/humanactivitymonitor.gyp
src/humanactivitymonitor/humanactivitymonitor_api.js
src/humanactivitymonitor/humanactivitymonitor_manager.cc
src/humanactivitymonitor/humanactivitymonitor_manager.h

index efc4b45e7149457ad4e74d7ddb44d42f0a5c6585..7c305928e1ebc3d20b4ee75216d0ef8f77406df7 100755 (executable)
@@ -343,6 +343,7 @@ BuildRequires: pkgconfig(capi-web-url-download)
 %if 0%{?tizen_feature_ham_support}
 BuildRequires: pkgconfig(libcore-context-manager)
 BuildRequires: pkgconfig(capi-system-sensor)
+BuildRequires: pkgconfig(capi-location-manager)
 %endif
 
 %if 0%{?tizen_feature_power_support}
index 5640779e8d49f174febc2868768256927d78c7e6..2eca3ba500cb8f060daf41a26ca25c7f4da22f56 100755 (executable)
@@ -24,6 +24,7 @@
             'packages': [
               'libcore-context-manager',
               'capi-system-sensor',
+              'capi-location-manager',
             ]
           },
         }],
index daa9a1256c0eb115ddd165bc823885ec60f3cc49..75cac484c4d6d89be0520ba1afd8f7469c2b98d2 100644 (file)
@@ -98,7 +98,11 @@ HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
         native_.callIfPossible(args.changedCallback, new HumanActivityHRMData(result));
         break;
       case HumanActivityType.GPS:
-        // TODO(r.galka) implement
+        var gpsInfo = [];
+        for (var i = 0, max = result.length; i < max; i++) {
+          gpsInfo.push(new HumanActivityGPSInfo(result[i]));
+        }
+        native_.callIfPossible(args.changedCallback, new HumanActivityGPSInfoArray(gpsInfo));
         break;
     }
 
@@ -208,18 +212,18 @@ HumanActivityHRMData.prototype = new HumanActivityData();
 HumanActivityHRMData.prototype.constructor = HumanActivityHRMData;
 
 
-function HumanActivityGPSInfo() {
-  SetReadOnlyProperty(this, 'latitude', null);
-  SetReadOnlyProperty(this, 'longitude', null);
-  SetReadOnlyProperty(this, 'altitude', null);
-  SetReadOnlyProperty(this, 'speed', null);
-  SetReadOnlyProperty(this, 'errorRange', null);
-  SetReadOnlyProperty(this, 'timestamp', null);
+function HumanActivityGPSInfo(data) {
+  SetReadOnlyProperty(this, 'latitude', data.latitude);
+  SetReadOnlyProperty(this, 'longitude', data.longitude);
+  SetReadOnlyProperty(this, 'altitude', data.altitude);
+  SetReadOnlyProperty(this, 'speed', data.speed);
+  SetReadOnlyProperty(this, 'errorRange', data.errorRange);
+  SetReadOnlyProperty(this, 'timestamp', data.timestamp);
 }
 
 
-function HumanActivityGPSInfoArray() {
-  SetReadOnlyProperty(this, 'gpsInfo', null);
+function HumanActivityGPSInfoArray(data) {
+  SetReadOnlyProperty(this, 'gpsInfo', data);
 }
 
 HumanActivityGPSInfoArray.prototype = new HumanActivityData();
index 450a7cbe18dfc135ed7f8897c4555e45b5409ab5..f3fc15db622f11d5e74f77705eeca7b1a67acb73 100644 (file)
@@ -19,6 +19,7 @@ HumanActivityMonitorManager::HumanActivityMonitorManager() {}
 HumanActivityMonitorManager::~HumanActivityMonitorManager() {
   UnsetWristUpListener();
   UnsetHrmListener();
+  UnsetGpsListener();
 }
 
 PlatformResult HumanActivityMonitorManager::Init() {
@@ -55,7 +56,7 @@ PlatformResult HumanActivityMonitorManager::IsSupported(
                             "HRM sensor check failed");
     }
   } else if (type == kActivityTypeGps) {
-    // TODO(r.galka) implement when available in platform
+    supported = location_manager_is_supported_method(LOCATIONS_METHOD_GPS);
   } else {
     return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR);
   }
@@ -75,8 +76,6 @@ PlatformResult HumanActivityMonitorManager::SetListener(
     return result;
   }
 
-  int ret;
-
   // PEDOMETER
   if (type == kActivityTypePedometer) {
     // TODO(r.galka) Not Supported in current implementation.
@@ -94,8 +93,10 @@ PlatformResult HumanActivityMonitorManager::SetListener(
 
   // GPS
   if (type == kActivityTypeGps) {
-    // TODO(r.galka) implement
+    return SetGpsListener(callback);
   }
+
+  return PlatformResult(ErrorCode::UNKNOWN_ERR, "Undefined activity type");
 }
 
 PlatformResult HumanActivityMonitorManager::UnsetListener(
@@ -123,8 +124,10 @@ PlatformResult HumanActivityMonitorManager::UnsetListener(
 
   // GPS
   if (type == kActivityTypeGps) {
-    // TODO(r.galka) implement
+    return UnsetGpsListener();
   }
+
+  return PlatformResult(ErrorCode::UNKNOWN_ERR, "Undefined activity type");
 }
 
 // WRIST_UP
@@ -304,5 +307,121 @@ void HumanActivityMonitorManager::OnHrmSensorEvent(
   manager->hrm_event_callback_(&hrm_data);
 }
 
+// GPS
+PlatformResult HumanActivityMonitorManager::SetGpsListener(
+    JsonCallback callback) {
+  int ret;
+
+  ret = location_manager_create(LOCATIONS_METHOD_GPS, &location_handle_);
+  if (ret != LOCATIONS_ERROR_NONE) {
+    LOGGER(ERROR) << "Failed to create location manager, error: " << ret;
+    return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                          "Failed to create location manager");
+  }
+
+  ret = location_manager_set_location_batch_cb(location_handle_,
+                                               OnGpsEvent,
+                                               1, // batch_interval
+                                               120, // batch_period
+                                               this);
+  if (ret != LOCATIONS_ERROR_NONE) {
+    LOGGER(ERROR) << "Failed to set location listener, error: " << ret;
+    return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                          "Failed to set location listener");
+  }
+
+  ret = location_manager_start_batch(location_handle_);
+  if (ret != LOCATIONS_ERROR_NONE) {
+    LOGGER(ERROR) << "Failed to start location manager, error: " << ret;
+    return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                          "Failed to start location manager");
+  }
+
+  gps_event_callback_ = callback;
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult HumanActivityMonitorManager::UnsetGpsListener() {
+  int ret;
+
+  if (location_handle_) {
+    ret = location_manager_stop_batch(location_handle_);
+    if (ret != LOCATIONS_ERROR_NONE) {
+      LOGGER(ERROR) << "Failed to stop location manager, error: " << ret;
+      return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                            "Failed to stop location manager");
+    }
+
+    ret = location_manager_unset_location_batch_cb(location_handle_);
+    if (ret != LOCATIONS_ERROR_NONE) {
+      LOGGER(ERROR) << "Failed to unset location listener, error: " << ret;
+      return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                            "Failed to unset location listener");
+    }
+
+    ret = location_manager_destroy(location_handle_);
+    if (ret != LOCATIONS_ERROR_NONE) {
+      LOGGER(ERROR) << "Failed to destroy location manager, error: " << ret;
+      return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                            "Failed to destroy location manager");
+    }
+  }
+
+  gps_event_callback_ = nullptr;
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+static bool ConvertGpsEvent(double latitude, double longitude, double altitude,
+                            double speed, double direction, double horizontal,
+                            double vertical, time_t timestamp,
+                            void* user_data) {
+  picojson::array* gps_info_array = static_cast<picojson::array*>(user_data);
+
+  picojson::value gps_info = picojson::value(picojson::object());
+  picojson::object& gps_info_o = gps_info.get<picojson::object>();
+
+  gps_info_o["latitude"] = picojson::value(latitude);
+  gps_info_o["longitude"] = picojson::value(longitude);
+  gps_info_o["altitude"] = picojson::value(altitude);
+  gps_info_o["speed"] = picojson::value(speed);
+  // TODO(r.galka) errorRange not available in CAPI
+  gps_info_o["errorRange"] = picojson::value(static_cast<double>(0));
+  gps_info_o["timestamp"] = picojson::value(static_cast<double>(timestamp));
+
+  gps_info_array->push_back(gps_info);
+
+  return true;
+}
+
+void HumanActivityMonitorManager::OnGpsEvent(int num_of_location,
+                                             void *user_data) {
+  HumanActivityMonitorManager* manager =
+      static_cast<HumanActivityMonitorManager*>(user_data);
+
+  if (!manager->gps_event_callback_) {
+    LOGGER(ERROR) << "No GPS event callback registered, skipping.";
+    return;
+  }
+
+  if (0 == num_of_location) {
+    LOGGER(ERROR) << "No GPS locations available, skipping.";
+    return;
+  }
+
+  picojson::value gps_info = picojson::value(picojson::array());
+  int ret = location_manager_foreach_location_batch(
+      manager->location_handle_,
+      ConvertGpsEvent,
+      &gps_info.get<picojson::array>());
+  if (ret != LOCATIONS_ERROR_NONE) {
+    LOGGER(ERROR) << "Failed to convert location, error: " << ret;
+    return;
+  }
+
+  manager->gps_event_callback_(&gps_info);
+}
+
 }  // namespace humanactivitymonitor
 }  // namespace extension
index 8b32a615a480a96b2fe23fbc5be4c5aa59e56d8c..45c1328eeffef74195f4623cd70cb3c8e217f908 100644 (file)
@@ -8,6 +8,7 @@
 #include <functional>
 #include <sensor.h>
 #include <gesture_recognition.h>
+#include <location_batch.h>
 #include <string>
 
 #include "common/picojson.h"
@@ -58,7 +59,14 @@ class HumanActivityMonitorManager {
   common::PlatformResult UnsetHrmListener();
   static void OnHrmSensorEvent(sensor_h sensor,
                                sensor_event_s *event,
-                               void *data);
+                               void *user_data);
+
+  // GPS
+  location_manager_h location_handle_;
+  JsonCallback gps_event_callback_;
+  common::PlatformResult SetGpsListener(JsonCallback callback);
+  common::PlatformResult UnsetGpsListener();
+  static void OnGpsEvent(int num_of_location, void *user_data);
 };
 
 } // namespace humanactivitymonitor