[HAM] Added gesture recognition functionality 43/117043/5
authorTomasz Marciniak <t.marciniak@samsung.com>
Tue, 28 Feb 2017 11:11:48 +0000 (12:11 +0100)
committerTomasz Marciniak <t.marciniak@samsung.com>
Wed, 29 Mar 2017 11:34:41 +0000 (13:34 +0200)
[Verification] Code compiles.

Change-Id: Iae7b4d5bdd80c3573196abaedc229c4f22706a7c
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
src/humanactivitymonitor/gesture_manager.cc [new file with mode: 0644]
src/humanactivitymonitor/gesture_manager.h [new file with mode: 0644]
src/humanactivitymonitor/humanactivitymonitor.gyp
src/humanactivitymonitor/humanactivitymonitor_api.js
src/humanactivitymonitor/humanactivitymonitor_instance.cc
src/humanactivitymonitor/humanactivitymonitor_instance.h

diff --git a/src/humanactivitymonitor/gesture_manager.cc b/src/humanactivitymonitor/gesture_manager.cc
new file mode 100644 (file)
index 0000000..050d79e
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    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 "humanactivitymonitor/gesture_manager.h"
+
+#include <gesture_recognition.h>
+
+#include "common/logger.h"
+#include "common/optional.h"
+#include "common/picojson.h"
+#include "common/tools.h"
+#include "common/scope_exit.h"
+#include "common/extension.h"
+
+namespace extension {
+namespace humanactivitymonitor {
+
+using common::PlatformResult;
+using common::ErrorCode;
+using common::tools::ReportError;
+using common::tools::ReportSuccess;
+
+namespace {
+
+const std::string kListenerId = "listenerId";
+const std::string kListener = "GestureRecognitionListener";
+const std::string kType = "type";
+const std::string kTimestamp = "timestamp";
+const std::string kAlwayOn = "alwaysOn";
+const std::string kAction = "action";
+const std::string kEvent = "event";
+const std::string kError = "error";
+const std::string kOnError = "onerror";
+const std::string kOnDetect = "ondetect";
+
+ErrorCode getErrorCode(int error) {
+  switch (error) {
+    case GESTURE_ERROR_NONE:
+      return ErrorCode::NO_ERROR;
+    case GESTURE_ERROR_INVALID_PARAMETER:
+      return ErrorCode::INVALID_VALUES_ERR;
+    case GESTURE_ERROR_OPERATION_FAILED:
+      return ErrorCode::IO_ERR;
+    case GESTURE_ERROR_NOT_SUPPORTED:
+      return ErrorCode::NOT_SUPPORTED_ERR;
+    case GESTURE_ERROR_INVALID_OPERATION:
+    case GESTURE_ERROR_OUT_OF_MEMORY:
+    case GESTURE_ERROR_PERMISSION_DENIED:
+    case GESTURE_ERROR_ALREADY_STARTED:
+    case GESTURE_ERROR_NOT_STARTED:
+    default:
+      return ErrorCode::ABORT_ERR;
+  }
+}
+
+PlatformResult StrToGestureType(const std::string& type, gesture_type_e* type_e) {
+  if ("GESTURE_DOUBLE_TAP" == type) {
+    *type_e = GESTURE_DOUBLE_TAP;
+  } else if ("GESTURE_MOVE_TO_EAR" == type) {
+    *type_e = GESTURE_MOVE_TO_EAR;
+  } else if ("GESTURE_NO_MOVE" == type) {
+    *type_e = GESTURE_NO_MOVE;
+  } else if ("GESTURE_PICK_UP" == type) {
+    *type_e = GESTURE_PICK_UP;
+  } else if ("GESTURE_SHAKE" == type) {
+    *type_e = GESTURE_SHAKE;
+  } else if ("GESTURE_SNAP" == type) {
+    *type_e = GESTURE_SNAP;
+  } else if ("GESTURE_TILT" == type) {
+    *type_e = GESTURE_TILT;
+  } else if ("GESTURE_TURN_FACE_DOWN" == type) {
+    *type_e = GESTURE_TURN_FACE_DOWN;
+  } else if ("GESTURE_WRIST_UP" == type) {
+    *type_e = GESTURE_WRIST_UP;
+  } else {
+    return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Unknown gesture type");
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+std::string GestureTypeToStr(gesture_type_e type) {
+  switch (type) {
+    case GESTURE_DOUBLE_TAP:
+      return "GESTURE_DOUBLE_TAP";
+    case GESTURE_MOVE_TO_EAR:
+      return "GESTURE_MOVE_TO_EAR";
+    case GESTURE_NO_MOVE:
+      return "GESTURE_NO_MOVE";
+    case GESTURE_PICK_UP:
+      return "GESTURE_PICK_UP";
+    case GESTURE_SHAKE:
+      return "GESTURE_SHAKE";
+    case GESTURE_SNAP:
+      return "GESTURE_SNAP";
+    case GESTURE_TILT:
+      return "GESTURE_TILT";
+    case GESTURE_TURN_FACE_DOWN:
+      return "GESTURE_TURN_FACE_DOWN";
+    case GESTURE_WRIST_UP:
+      return "GESTURE_WRIST_UP";
+    default:
+      return "GESTURE_UNKNOWN_TYPE";
+  }
+}
+std::string GestureEventToStr(gesture_event_e event, gesture_type_e gesture) {
+  switch (event) {
+    // GESTURE_EVENT_DETECTED == GESTURE_SHAKE_DETECTED == GESTURE_SNAP_X_NEGATIVE == 1
+    case GESTURE_EVENT_DETECTED:
+      if (GESTURE_SHAKE == gesture) {
+        return "GESTURE_SHAKE_DETECTED";
+      } else if (GESTURE_SNAP == gesture) {
+        return "GESTURE_SNAP_X_NEGATIVE";
+      } else {
+        return "GESTURE_EVENT_DETECTED";
+      }
+    // GESTURE_SHAKE_FINISHED == GESTURE_SNAP_X_POSITIVE == 2
+    case GESTURE_SHAKE_FINISHED:
+      if (GESTURE_SHAKE == gesture) {
+        return "GESTURE_SHAKE_FINISHED";
+      } else {
+        return "GESTURE_SNAP_X_POSITIVE";
+      }
+    case GESTURE_SNAP_Y_NEGATIVE:
+      return "GESTURE_SNAP_Y_NEGATIVE";
+    case GESTURE_SNAP_Y_POSITIVE:
+      return "GESTURE_SNAP_Y_POSITIVE";
+    case GESTURE_SNAP_Z_NEGATIVE:
+      return "GESTURE_SNAP_Z_NEGATIVE";
+    case GESTURE_SNAP_Z_POSITIVE:
+      return "GESTURE_SNAP_Z_POSITIVE";
+    default:
+      return "GESTURE_EVENT_NONE";
+  }
+}
+
+void GestureRecognitionDefaultCb(gesture_type_e gesture, const gesture_data_h data,
+                                 double timestamp, gesture_error_e error, void *user_data) {
+  ScopeLogger();
+
+  GestureManager* manager = static_cast<GestureManager*>(user_data);
+  if (!manager) {
+    LoggerW("User data is null");
+    return;
+  }
+
+  manager->CompleteGestureListenerCb(gesture, data, timestamp, error, false);
+}
+
+void GestureRecognitionAlwaysOnCb(gesture_type_e gesture, const gesture_data_h data,
+                                  double timestamp, gesture_error_e error, void *user_data) {
+  ScopeLogger();
+  GestureManager* manager = static_cast<GestureManager*>(user_data);
+
+  if (!manager) {
+    LoggerW("User data is null");
+    return;
+  }
+
+  manager->CompleteGestureListenerCb(gesture, data, timestamp, error, true);
+}
+
+}  // namespace
+
+GestureManager::GestureManager() :
+    m_callback(nullptr),
+    m_recognition_default_map(),
+    m_recognition_always_on_map() {
+  ScopeLogger();
+}
+
+GestureManager::~GestureManager() {
+  ScopeLogger();
+
+  int ret = GESTURE_ERROR_NONE;
+
+  for (auto& it : m_recognition_default_map) {
+    ret = gesture_stop_recognition(it.second);
+    if (GESTURE_ERROR_NONE != ret) {
+      LoggerE("gesture_stop_recognition() failed");
+    }
+
+    ret = gesture_release(it.second);
+    if (GESTURE_ERROR_NONE != ret) {
+      LoggerE("gesture_release() failed");
+    }
+  }
+
+  for (auto& it : m_recognition_always_on_map) {
+    ret = gesture_stop_recognition(it.second);
+    if (GESTURE_ERROR_NONE != ret) {
+      LoggerE("gesture_stop_recognition() failed");
+    }
+
+    ret = gesture_release(it.second);
+    if (GESTURE_ERROR_NONE != ret) {
+      LoggerE("gesture_release() failed");
+    }
+  }
+
+  m_recognition_default_map.clear();
+  m_recognition_always_on_map.clear();
+}
+
+PlatformResult GestureManager::IsSupported(const std::string& type, bool* is_supported) {
+  ScopeLogger();
+
+  gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+  PlatformResult result = StrToGestureType(type, &type_e);
+  if (!result) {
+    return result;
+  }
+
+  int ret = gesture_is_supported(type_e, is_supported);
+  if (GESTURE_ERROR_NONE != ret) {
+    return LogAndCreateResult(getErrorCode(ret),
+                              "Checking gesture failed",
+                              ("Checking gesture failed, error: %d (%s)", ret, get_error_message(ret)));
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+gesture_event_e GestureManager::GetGestureEvent(const gesture_data_h data) {
+  ScopeLogger();
+
+  gesture_event_e event = GESTURE_EVENT_NONE;
+  int ret = gesture_get_event(data, &event);
+  if (GESTURE_ERROR_NONE != ret) {
+    LoggerE("gesture_get_event() failed, error %d (%s)", ret, get_error_message(ret));
+  }
+
+  return event;
+}
+
+void GestureManager::FillTiltData(const gesture_data_h data, picojson::object* obj) {
+  ScopeLogger();
+
+  int x = 0;
+  int y = 0;
+
+  int ret = gesture_get_tilt(data, &x, &y);
+  if (GESTURE_ERROR_NONE != ret) {
+    LoggerE("gesture_get_tilt() failed, error %d (%s)", ret, get_error_message(ret));
+  }
+
+  obj->insert(std::make_pair("x", picojson::value(static_cast<double>(x))));
+  obj->insert(std::make_pair("y", picojson::value(static_cast<double>(y))));
+}
+
+void GestureManager::CompleteGestureListenerCb(gesture_type_e gesture,
+                                               const gesture_data_h data,
+                                               double timestamp,
+                                               gesture_error_e error,
+                                               bool always_on) {
+  ScopeLogger();
+
+  picojson::value response = picojson::value(picojson::object());
+  auto& obj = response.get<picojson::object>();
+
+  obj.insert(std::make_pair(kAlwayOn, picojson::value(always_on)));
+  obj.insert(std::make_pair(kListenerId, picojson::value(kListener)));
+
+  if (GESTURE_ERROR_NONE != error) {
+    obj.insert(std::make_pair(kAction, picojson::value(kOnError)));
+
+    PlatformResult result = LogAndCreateResult(getErrorCode(error), "Error occurred during recognition");
+    ReportError(result, &obj);
+  } else {
+    gesture_event_e event = GetGestureEvent(data);
+    if (GESTURE_EVENT_NONE == event) {
+      LoggerD("Gesture event none detected.");
+      return;
+    }
+
+    std::string gesture_str = GestureTypeToStr(gesture);
+    if ("GESTURE_UNKNOWN_TYPE" == gesture_str) {
+      LoggerE("Unknown gesture type");
+      return;
+    }
+
+    obj.insert(std::make_pair(kAction, picojson::value(kOnDetect)));
+
+    picojson::value result = picojson::value(picojson::object());
+    auto& result_obj = result.get<picojson::object>();
+
+    result_obj.insert(std::make_pair(kEvent, picojson::value(GestureEventToStr(event, gesture))));
+    result_obj.insert(std::make_pair(kTimestamp, picojson::value(timestamp)));
+    result_obj.insert(std::make_pair(kType, picojson::value(gesture_str)));
+
+    if (GESTURE_TILT == gesture) {
+      FillTiltData(data, &result_obj);
+    }
+
+    ReportSuccess(result, obj);
+  }
+
+  if (!m_callback) {
+    LoggerE("Callback is not defined");
+  } else {
+    m_callback(&response);
+  }
+}
+
+PlatformResult GestureManager::AddListener(gesture_type_e type, gesture_option_e option,
+                                           RecognitionMap& gesture_map,
+                                           gesture_recognition_cb callback) {
+  ScopeLogger();
+
+  gesture_h handle = nullptr;
+
+  int ret = gesture_create(&handle);
+  if (GESTURE_ERROR_NONE != ret) {
+    return LogAndCreateResult(getErrorCode(ret),
+                              "Creating handle failed",
+                              ("Creating handle failed, error: %d (%s)", ret, get_error_message(ret)));
+  }
+
+  ret = gesture_start_recognition(handle, type, option, callback, this);
+  if (GESTURE_ERROR_NONE != ret) {
+    gesture_release(handle);
+    return LogAndCreateResult(getErrorCode(ret),
+                              "Starting recognition failed",
+                              ("Starting recognition failed, error: %d (%s)", ret, get_error_message(ret)));
+  }
+
+  gesture_map[type] = handle;
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+
+PlatformResult GestureManager::AddGestureRecognitionListener(const std::string& type,
+                                                             bool always_on,
+                                                             JsonCallback cb) {
+  ScopeLogger();
+
+  gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+  PlatformResult result = StrToGestureType(type, &type_e);
+  if (!result) {
+    return result;
+  }
+
+  gesture_option_e option = GESTURE_OPTION_DEFAULT;
+  gesture_recognition_cb callback = GestureRecognitionDefaultCb;
+  RecognitionMap* gesture_map = &m_recognition_default_map;
+
+  if (!m_callback) {
+    m_callback = cb;
+  }
+
+  if (always_on) {
+    option = GESTURE_OPTION_ALWAYS_ON;
+    callback = GestureRecognitionAlwaysOnCb;
+    gesture_map = &m_recognition_always_on_map;
+  }
+
+  return AddListener(type_e, option, *gesture_map, callback);
+}
+
+PlatformResult GestureManager::RemoveGestureRecognitionListener(const std::string& type,
+                                                                bool always_on) {
+  ScopeLogger();
+
+  auto& recognition_map = always_on ? m_recognition_always_on_map : m_recognition_default_map;
+  gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+  PlatformResult result = StrToGestureType(type, &type_e);
+  if (!result) {
+    LoggerD("Unknown gesture type.");
+    return PlatformResult(ErrorCode::NO_ERROR);
+  }
+
+  gesture_h handle = nullptr;
+  RecognitionMap::iterator it = recognition_map.find(type_e);
+
+  if (recognition_map.end() != it) {
+    handle = it->second;
+  }
+
+  if (handle) {
+    int ret = gesture_stop_recognition(handle);
+    if (GESTURE_ERROR_NONE != ret) {
+      return LogAndCreateResult(getErrorCode(ret),
+                                "Stoping recognition failed",
+                                ("Stoping recognition failed, error: %d (%s)", ret, get_error_message(ret)));
+    }
+
+    ret = gesture_release(handle);
+    if (GESTURE_ERROR_NONE != ret) {
+      LoggerE("gesture_release() failed");
+    }
+
+    recognition_map.erase(it);
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+}  // namespace humanactivitymonitor
+}  // namespace extension
diff --git a/src/humanactivitymonitor/gesture_manager.h b/src/humanactivitymonitor/gesture_manager.h
new file mode 100644 (file)
index 0000000..081b81d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    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 HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
+#define HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
+
+#include <string>
+#include <functional>
+#include <gesture_recognition.h>
+
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+namespace extension {
+namespace humanactivitymonitor {
+
+using JsonCallback = std::function<void(picojson::value*)>;
+
+typedef std::map<gesture_type_e, gesture_h> RecognitionMap;
+
+class GestureManager {
+ public:
+  GestureManager();
+  virtual ~GestureManager();
+
+  common::PlatformResult IsSupported(const std::string& types, bool* is_supported);
+  common::PlatformResult AddGestureRecognitionListener(const std::string& type, bool always_on,
+                                                       JsonCallback cb);
+  common::PlatformResult RemoveGestureRecognitionListener(const std::string& type, bool always_on);
+  void CompleteGestureListenerCb(gesture_type_e gesture, const gesture_data_h data,
+                                 double timestamp, gesture_error_e error, bool always_on);
+
+ private:
+  gesture_event_e GetGestureEvent(const gesture_data_h data);
+  void FillTiltData(const gesture_data_h data, picojson::object* obj);
+  common::PlatformResult AddListener(gesture_type_e type, gesture_option_e option,
+                                  RecognitionMap& gesture_map, gesture_recognition_cb callback);
+
+  JsonCallback m_callback;
+  RecognitionMap m_recognition_default_map;
+  RecognitionMap m_recognition_always_on_map;
+};
+
+} // namespace humanactivitymonitor
+} // namespace extension
+
+#endif  // HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
index 6c250c1871c3f03aa8c66afe3eb55aded36d336c..c6b54a04c1efdce087a1c64eaaf070e6aae3fa54 100755 (executable)
@@ -17,6 +17,8 @@
         'humanactivitymonitor_instance.h',
         'humanactivitymonitor_manager.cc',
         'humanactivitymonitor_manager.h',
+        'gesture_manager.cc',
+        'gesture_manager.h',
       ],
       'conditions': [
         ['tizen == 1', {
index 736b9a49af70a5e9dd0438836a8fec1884501c07..711f635c5058d5c82482c98148895a5e2c6a61ac 100755 (executable)
@@ -78,6 +78,18 @@ var SleepStatus = {
   AWAKE: 'AWAKE'
 };
 
+var GestureType = {
+  GESTURE_DOUBLE_TAP : 'GESTURE_DOUBLE_TAP',
+  GESTURE_MOVE_TO_EAR : 'GESTURE_MOVE_TO_EAR',
+  GESTURE_NO_MOVE : 'GESTURE_NO_MOVE',
+  GESTURE_PICK_UP : 'GESTURE_PICK_UP',
+  GESTURE_SHAKE : 'GESTURE_SHAKE',
+  GESTURE_SNAP : 'GESTURE_SNAP',
+  GESTURE_TILT : 'GESTURE_TILT',
+  GESTURE_TURN_FACE_DOWN : 'GESTURE_TURN_FACE_DOWN',
+  GESTURE_WRIST_UP : 'GESTURE_WRIST_UP',
+};
+
 function convertActivityData(type, data) {
   switch (type) {
     case HumanActivityType.PEDOMETER:
@@ -512,6 +524,157 @@ HumanActivityMonitorManager.prototype.readRecorderData = function() {
   }
 };
 
+HumanActivityMonitorManager.prototype.isGestureSupported = function() {
+  var args = validator_.validateMethod(arguments, [{
+    name : 'type',
+    type: types_.ENUM,
+    values: Object.keys(GestureType)
+  }
+  ]);
+
+  var callArgs = {};
+  callArgs.type = args.type;
+
+  var result = native_.callSync('GestureManager_isGestureSupported', callArgs);
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+
+  return native_.getResultObject(result);
+};
+
+function GestureListenerManager(native, listenerName) {
+  this.listeners = {};
+  //below maps keep information about number of registered listeners for the specific type
+  //there are two maps as one keeps information about listeners which should be always called
+  //and one keeps information about number of the listeners which should be called only
+  //if power-saving mode is off
+  this.typeCountMapDefault = {};
+  this.typeCountMapAlwaysOn = {};
+  this.nextId = 1;
+  this.nativeSet = false;
+  this.native = native;
+  this.listenerName = listenerName;
+  for (var type in GestureType) {
+    this.typeCountMapDefault[type] = this.typeCountMapAlwaysOn[type] = 0;
+  }
+};
+
+GestureListenerManager.prototype.onListenerCalled = function(msg) {
+  var d = undefined;
+  var result = undefined;
+  var alwaysOn = msg.alwaysOn;
+  switch (msg.action) {
+    case 'ondetect':
+      d = new GestureData(this.native.getResultObject(msg));
+      break;
+    case 'onerror':
+      d = this.native.getErrorObject(msg);
+      break;
+    default:
+      console.log('Unknown mode: ' + msg.action);
+      return;
+  }
+
+  for (var watchId in this.listeners) {
+    if (this.listeners.hasOwnProperty(watchId)) {
+      var listener = this.listeners[watchId];
+      var call = alwaysOn ? listener.alwaysOn : true;
+      if (call && listener[msg.action]) {
+        listener[msg.action](d);
+      }
+    }
+  }
+};
+
+GestureListenerManager.prototype.addListener = function(successCb, errorCb, type, alwaysOn) {
+  var listener = {
+      'type' : type,
+      'alwaysOn' : alwaysOn,
+      'ondetect' : successCb,
+      'onerror' : errorCb
+  };
+
+  var typeCountMap = alwaysOn ? this.typeCountMapAlwaysOn : this.typeCountMapDefault;
+  if (typeCountMap[type] === 0) {
+    var result = this.native.callSync('GestureManager_addGestureRecognitionListener', listener);
+    if (this.native.isFailure(result)) {
+      throw this.native.getErrorObject(result);
+    }
+  }
+
+  typeCountMap[type]++;
+  var id = this.nextId++;
+  this.listeners[id] = listener;
+
+  if (!this.nativeSet) {
+    this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
+    this.nativeSet = true;
+  }
+
+  return id;
+};
+
+GestureListenerManager.prototype.removeListener = function(watchId) {
+  if (this.listeners.hasOwnProperty(watchId)) {
+      var listener = this.listeners[watchId];
+      var typeCountMap = listener.alwaysOn ? this.typeCountMapAlwaysOn : this.typeCountMapDefault;
+
+      if (typeCountMap[listener.type] === 1) {
+        var result = this.native.callSync('GestureManager_removeGestureRecognitionListener', listener);
+        if (this.native.isFailure(result)) {
+          throw this.native.getErrorObject(result);
+        }
+      }
+
+      delete this.listeners[watchId];
+      typeCountMap[listener.type]--;
+  }
+
+  if (this.nativeSet && type_.isEmptyObject(this.listeners)) {
+    this.native.removeListener(this.listenerName);
+    this.nativeSet = false;
+  }
+};
+
+var GESTURE_RECOGNITION_LISTENER = 'GestureRecognitionListener';
+var gestureRecognitionListener = new GestureListenerManager(native_, GESTURE_RECOGNITION_LISTENER);
+
+HumanActivityMonitorManager.prototype.addGestureRecognitionListener = function() {
+  var args = validator_.validateMethod(arguments, [{
+    name : 'type',
+    type: types_.ENUM,
+    values: Object.keys(GestureType)
+  },
+  {
+    name : 'eventCallback',
+    type : types_.FUNCTION
+  },
+  {
+    name : 'errorCallback',
+    type : types_.FUNCTION,
+    optional: true,
+    nullable: true
+  },
+  {
+    name : 'alwaysOn',
+    type : types_.BOOLEAN,
+    optional : true,
+    nullable : true
+  }]);
+
+  return gestureRecognitionListener.addListener(args.eventCallback, args.errorCallback, args.type, args.alwaysOn);
+};
+
+HumanActivityMonitorManager.prototype.removeGestureRecognitionListener = function() {
+  var args = validator_.validateMethod(arguments, [{
+    name : 'watchId',
+    type : types_.LONG,
+  }]);
+
+  gestureRecognitionListener.removeListener(args.watchId);
+};
+
 function StepDifference(data) {
   SetReadOnlyProperty(this, 'stepCountDifference', data.stepCountDifference);
   SetReadOnlyProperty(this, 'timestamp', data.timestamp);
@@ -649,6 +812,22 @@ function HumanActivityRecorderPressureData(data) {
   SetReadOnlyProperty(this, 'average', data.average);
 }
 
+function GestureData(data) {
+  if (data) {
+    SetReadOnlyProperty(this, 'type', data.type);
+    SetReadOnlyProperty(this, 'event', data.event);
+    SetReadOnlyProperty(this, 'timestamp', data.timestamp);
+
+    if (data.type === 'GESTURE_TILT') {
+      SetReadOnlyProperty(this, 'x', data.x);
+      SetReadOnlyProperty(this, 'y', data.y);
+    } else {
+      SetReadOnlyProperty(this, 'x', null);
+      SetReadOnlyProperty(this, 'y', null);
+    }
+  }
+}
+
 HumanActivityRecorderPressureData.prototype = new HumanActivityRecorderData();
 HumanActivityRecorderPressureData.prototype.constructor = HumanActivityRecorderPressureData;
 
index 89eeb676af4d162ef3154a3465c0b5a3e2c510ed..69c1c2acbd73e93dfe64253653bb817dcbedcc23 100755 (executable)
@@ -43,7 +43,8 @@ using common::PlatformResult;
 using common::ErrorCode;
 using common::TaskQueue;
 
-HumanActivityMonitorInstance::HumanActivityMonitorInstance() {
+HumanActivityMonitorInstance::HumanActivityMonitorInstance() :
+  gesture_manager_() {
   LoggerD("Enter");
   using std::placeholders::_1;
   using std::placeholders::_2;
@@ -66,6 +67,12 @@ HumanActivityMonitorInstance::HumanActivityMonitorInstance() {
                 HumanActivityMonitorManagerStopRecorder);
   REGISTER_SYNC("HumanActivityMonitorManager_readRecorderData",
                  HumanActivityMonitorManagerReadRecorderData);
+  REGISTER_SYNC("GestureManager_isGestureSupported",
+                GestureManagerIsGestureSupported);
+  REGISTER_SYNC("GestureManager_addGestureRecognitionListener",
+                GestureManagerAddGestureRecognitionListener);
+  REGISTER_SYNC("GestureManager_removeGestureRecognitionListener",
+                GestureManagerRemoveGestureRecognitionListener);
 #undef REGISTER_SYNC
 }
 
@@ -381,6 +388,65 @@ void HumanActivityMonitorInstance::HumanActivityMonitorManagerReadRecorderData(
   ReportSuccess(out);
 }
 
+void HumanActivityMonitorInstance::GestureManagerIsGestureSupported(
+    const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  CHECK_EXIST(args, "type", out)
+  const auto& type = args.get("type").get<std::string>();
+  bool is_supported = false;
+
+  PlatformResult result = gesture_manager_.IsSupported(type, &is_supported);
+  if (result) {
+    ReportSuccess(picojson::value(is_supported), out);
+  } else {
+    LogAndReportError(result, &out, ("Failed: gesture_manager_->IsSupported()"));
+  }
+}
+
+void HumanActivityMonitorInstance::GestureManagerAddGestureRecognitionListener(
+    const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  CHECK_EXIST(args, "type", out)
+  CHECK_EXIST(args, "alwaysOn", out)
+  const auto& type = args.get("type").get<std::string>();
+  bool always_on = args.get("alwaysOn").get<bool>();
+
+  auto cb = [this](picojson::value* data) -> void {
+    if (!data) {
+      LoggerE("No data passed to json callback");
+      return;
+    }
+
+    Instance::PostMessage(this, data->serialize().c_str());
+  };
+
+  PlatformResult result = gesture_manager_.AddGestureRecognitionListener(type, always_on, cb);
+  if (result) {
+    ReportSuccess(out);
+  } else {
+    LogAndReportError(result, &out, ("Failed: gesture_manager_->AddGestureRecognitionListener()"));
+  }
+}
+
+void HumanActivityMonitorInstance::GestureManagerRemoveGestureRecognitionListener(
+    const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  CHECK_EXIST(args, "type", out)
+  CHECK_EXIST(args, "alwaysOn", out)
+  const auto& type = args.get("type").get<std::string>();
+  bool always_on = args.get("alwaysOn").get<bool>();
+
+  PlatformResult result = gesture_manager_.RemoveGestureRecognitionListener(type, always_on);
+  if (result) {
+    ReportSuccess(out);
+  } else {
+    LogAndReportError(result, &out, ("Failed: gesture_manager_->RemoveGestureRecognitionListener()"));
+  }
+}
+
 #undef CHECK_EXIST
 
 }  // namespace humanactivitymonitor
index 1ab6829e02c2fda08d70abb46964f3cf218b5747..c58e37cf6f91007c9a491ee8a3838a4aa779a02f 100755 (executable)
@@ -22,6 +22,7 @@
 #include "common/extension.h"
 #include "common/platform_result.h"
 #include "humanactivitymonitor/humanactivitymonitor_manager.h"
+#include "humanactivitymonitor/gesture_manager.h"
 
 namespace extension {
 namespace humanactivitymonitor {
@@ -48,8 +49,15 @@ class HumanActivityMonitorInstance : public common::ParsedInstance {
       const picojson::value& args, picojson::object& out);
   void HumanActivityMonitorManagerReadRecorderData(
       const picojson::value& args, picojson::object& out);
+  void GestureManagerIsGestureSupported(
+      const picojson::value& args, picojson::object& out);
+  void GestureManagerAddGestureRecognitionListener(
+      const picojson::value& args, picojson::object& out);
+  void GestureManagerRemoveGestureRecognitionListener(
+      const picojson::value& args, picojson::object& out);
 
   std::shared_ptr<HumanActivityMonitorManager> manager_;
+  GestureManager gesture_manager_;
   common::PlatformResult Init();
 };