From: Tomasz Marciniak Date: Tue, 28 Feb 2017 11:11:48 +0000 (+0100) Subject: [HAM] Added gesture recognition functionality X-Git-Tag: submit/tizen/20170405.081251~2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=147b9b9955da33c984af6498376168afb7750478;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [HAM] Added gesture recognition functionality [Verification] Code compiles. Change-Id: Iae7b4d5bdd80c3573196abaedc229c4f22706a7c Signed-off-by: Tomasz Marciniak --- diff --git a/src/humanactivitymonitor/gesture_manager.cc b/src/humanactivitymonitor/gesture_manager.cc new file mode 100644 index 00000000..050d79e5 --- /dev/null +++ b/src/humanactivitymonitor/gesture_manager.cc @@ -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 + +#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(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(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(x)))); + obj->insert(std::make_pair("y", picojson::value(static_cast(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(); + + 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(); + + 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 index 00000000..081b81dc --- /dev/null +++ b/src/humanactivitymonitor/gesture_manager.h @@ -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 +#include +#include + +#include "common/picojson.h" +#include "common/platform_result.h" + +namespace extension { +namespace humanactivitymonitor { + +using JsonCallback = std::function; + +typedef std::map 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 diff --git a/src/humanactivitymonitor/humanactivitymonitor.gyp b/src/humanactivitymonitor/humanactivitymonitor.gyp index 6c250c18..c6b54a04 100755 --- a/src/humanactivitymonitor/humanactivitymonitor.gyp +++ b/src/humanactivitymonitor/humanactivitymonitor.gyp @@ -17,6 +17,8 @@ 'humanactivitymonitor_instance.h', 'humanactivitymonitor_manager.cc', 'humanactivitymonitor_manager.h', + 'gesture_manager.cc', + 'gesture_manager.h', ], 'conditions': [ ['tizen == 1', { diff --git a/src/humanactivitymonitor/humanactivitymonitor_api.js b/src/humanactivitymonitor/humanactivitymonitor_api.js index 736b9a49..711f635c 100755 --- a/src/humanactivitymonitor/humanactivitymonitor_api.js +++ b/src/humanactivitymonitor/humanactivitymonitor_api.js @@ -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; diff --git a/src/humanactivitymonitor/humanactivitymonitor_instance.cc b/src/humanactivitymonitor/humanactivitymonitor_instance.cc index 89eeb676..69c1c2ac 100755 --- a/src/humanactivitymonitor/humanactivitymonitor_instance.cc +++ b/src/humanactivitymonitor/humanactivitymonitor_instance.cc @@ -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(); + 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(); + bool always_on = args.get("alwaysOn").get(); + + 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(); + bool always_on = args.get("alwaysOn").get(); + + 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 diff --git a/src/humanactivitymonitor/humanactivitymonitor_instance.h b/src/humanactivitymonitor/humanactivitymonitor_instance.h index 1ab6829e..c58e37cf 100755 --- a/src/humanactivitymonitor/humanactivitymonitor_instance.h +++ b/src/humanactivitymonitor/humanactivitymonitor_instance.h @@ -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 manager_; + GestureManager gesture_manager_; common::PlatformResult Init(); };