From 47178f4934128e4a4f22d7a050c72d987c280555 Mon Sep 17 00:00:00 2001 From: chakradhar Date: Tue, 17 Dec 2019 10:58:26 +0530 Subject: [PATCH 02/14] Gesture repository Change-Id: I79f46496ffcd6dee4a9bdd6966b73034d433c148 --- CMakeLists.txt | 59 +++++++ LICENSE | 203 ++++++++++++++++++++++++ capi-context-gesture.pc.in | 13 ++ doc/gesture_recognition_doc.h | 149 ++++++++++++++++++ include/gesture_recognition.h | 269 ++++++++++++++++++++++++++++++++ packaging/capi-context-gesture.manifest | 5 + packaging/capi-context-gesture.spec | 70 +++++++++ src/Gesture.cpp | 157 +++++++++++++++++++ src/GestureSensor.cpp | 101 ++++++++++++ src/GestureSensor.h | 61 ++++++++ src/ISensorListener.h | 31 ++++ src/SensorAdapter.cpp | 135 ++++++++++++++++ src/SensorAdapter.h | 55 +++++++ src/TypesInternal.cpp | 35 +++++ src/TypesInternal.h | 88 +++++++++++ 15 files changed, 1431 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 capi-context-gesture.pc.in create mode 100644 doc/gesture_recognition_doc.h create mode 100644 include/gesture_recognition.h create mode 100644 packaging/capi-context-gesture.manifest create mode 100644 packaging/capi-context-gesture.spec create mode 100644 src/Gesture.cpp create mode 100644 src/GestureSensor.cpp create mode 100644 src/GestureSensor.h create mode 100644 src/ISensorListener.h create mode 100644 src/SensorAdapter.cpp create mode 100644 src/SensorAdapter.h create mode 100644 src/TypesInternal.cpp create mode 100644 src/TypesInternal.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..214b460 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,59 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(capi-context-gesture) +INCLUDE(GNUInstallDirs) + +SET(target ${PROJECT_NAME}) + +# Source Lists +FILE(GLOB SRCS src/*.cpp) + +SET(inc_subdir "context-service") +SET(dependency "glib-2.0 dlog capi-base-common capi-system-info sensor") + +# Options +INCLUDE(FindPkgConfig) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +ADD_DEFINITIONS(-O2 -Wall -fPIC -flto -fdata-sections -ffunction-sections -fvisibility=hidden) +ADD_DEFINITIONS(-fdiagnostics-color) +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections") +SET(CMAKE_VERBOSE_MAKEFILE OFF) + +# Build +pkg_check_modules(pkgs REQUIRED ${dependency}) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +ADD_LIBRARY(${target} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${target} ${pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS}) +SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CAPI-GESTURE\"") +SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER}) +SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER}) + +# Install +INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${inc_subdir} + FILES_MATCHING PATTERN "*.h" +) + +SET(VERSION ${FULLVER}) +SET(PC_PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(PC_NAME ${PROJECT_NAME}) +SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") +SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${inc_subdir}") +SET(PC_DESCRIPTION "Tizen C Native Gesture Recognition API") +SET(PC_REQUIRED ${dependency}) +SET(PC_LDFLAGS -l${target}) + +CONFIGURE_FILE( + ${PROJECT_NAME}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6ce6ec7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) [yyyy] [name of copyright owner] + + 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. diff --git a/capi-context-gesture.pc.in b/capi-context-gesture.pc.in new file mode 100644 index 0000000..71c14c4 --- /dev/null +++ b/capi-context-gesture.pc.in @@ -0,0 +1,13 @@ +#Package Information for pkg-config + +prefix=@PC_PREFIX@ +exec_prefix=@PC_PREFIX@ +libdir=@PC_LIBDIR@ +includedir=@PC_INCLUDE@ + +Name: @PC_NAME@ +Description: @PC_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} diff --git a/doc/gesture_recognition_doc.h b/doc/gesture_recognition_doc.h new file mode 100644 index 0000000..48c913f --- /dev/null +++ b/doc/gesture_recognition_doc.h @@ -0,0 +1,149 @@ +/* + * gesture + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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. + * + */ + +/** + * @ingroup CAPI_CONTEXT_FRAMEWORK + * @defgroup CAPI_CONTEXT_GESTURE_MODULE Gesture Recognition + * + * @brief The gesture recognition API allows applications to be notified and + * react when the user performs a gesture. + * + * @section CAPI_CONTEXT_GESTURE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_CONTEXT_GESTURE_MODULE_OVERVIEW Overview + * + * + * The gesture recognition API allows to register callback functions to be called + * when the user performs meaningful gestures listed in #gesture_type_e, for example, + * shaking the device. + * + * Regardless of the gesture types, + * the overall process of using the gesture recognition API is as follows. + * + * If necessary, applications can check whether a gesture type is supported in the current device in advance. + * Note that, some gestures may not be supported in some devices, if the devices do not have necessary sensors. + + \code + bool supported = false; + gesture_is_supported(GESTURE_SHAKE, &supported); + + if (!supported) { + // Not supported in the current device. + } + \endcode + + * If the gesture type is supported, to use the recognition engine, + * an @c handle for the gesture recognition needs to be initialized first. + + \code + gesture_h handle; + + result = gesture_create(&handle); + + if (result != GESTURE_ERROR_NONE) { + // An error occurred. + } + \endcode + + * With the @c handle initialized, a callback function, + * which will be called when a specified gesture is detected, + * is registered by using gesture_start_recognition(). + + \code + result = gesture_start_recognition(handle, GESTURE_SHAKE, GESTURE_OPTION_DEFAULT, gesture_cb, NULL); + + if (result != GESTURE_ERROR_NONE) { + // An error occurred. Do necessary error handling here. + } + \endcode + + * Then the callback function @c gesture_cb will be called whenever the shake gesture is detected. + * + * Note that, calling gesture_start_recognition() twice on the same handle returns #GESTURE_ERROR_ALREADY_STARTED. + * If it needs to recognize another gesture using the same handle, + * the started recognition session should be stopped and restarted with the new gesture type. + * Otherwise, the application needs to created multiple handles, one handle for each gesture needed. + * + * An example callback function is as follows. + + \code + void gesture_cb(gesture_type_e type, const gesture_data_h data, double timestamp, gesture_error_e error, void *user_data) + { + int result; + gesture_event_e event; + + if (error != GESTURE_ERROR_NONE) { + // An error occurred. Do necessary error handling here. + return; + } + + if (type == GESTURE_SHAKE) { + // More than one gestures can be started using the same callback function. + + result = gesture_get_event(data, &event); + + if (result != GESTURE_ERROR_NONE) { + // An error occurred. Do necessary error handling here. + return; + } + + if (event == GESTURE_SHAKE_DETECTED) { + // Shake gesture is started + + } else if (event == GESTURE_SHAKE_FINISHED) { + // Shake gesture is stopped + } + } + } + \endcode + + * As we started gesture recognition with #GESTURE_SHAKE, + * gesture_get_event() returns either #GESTURE_SHAKE_DETECTED or #GESTURE_SHAKE_FINISHED + * as it has two different states, the gesture is started, or finished. + * Most of the gesture types, however, simply provide #GESTURE_EVENT_DETECTED. + * In such cases, #GESTURE_EVENT_NONE may not be delivered at all. + * + * If #GESTURE_TILT is started, within the callback function, + * gesture_get_tilt() can be used to extract the tilting degrees. + * + * Finally, if the application does not need to be notified the gesture event, + * it can be stopped as follows. + + \code + gesture_stop_recognition(handle); + + // If the handle will not be used anymore, its resources needs be released explicitly. + gesture_release(handle); + \endcode + + * @section CAPI_CONTEXT_GESTURE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/sensor.gesture_recognition\n + * - http://tizen.org/feature/sensor.wrist_up + * + * It is recommended to design feature related code in your application for reliability.\n + * + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ diff --git a/include/gesture_recognition.h b/include/gesture_recognition.h new file mode 100644 index 0000000..4b9ae4b --- /dev/null +++ b/include/gesture_recognition.h @@ -0,0 +1,269 @@ +/* + * gesture + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 __TIZEN_GESTURE_H__ +#define __TIZEN_GESTURE_H__ + +/** + * @addtogroup CAPI_CONTEXT_GESTURE_MODULE + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief The gesture recognizer controlling handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _gesture_handle_s* gesture_h; + +/** + * @brief Delivery through gesture_recognition_cb() of gesture data handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _gesture_data_s* gesture_data_h; + +/** + * @brief Enumeration for error codes. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum { + GESTURE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + GESTURE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ + GESTURE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */ + GESTURE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + GESTURE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + GESTURE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + GESTURE_ERROR_ALREADY_STARTED = TIZEN_ERROR_CONTEXT | 0x01, /**< Recognition is already started */ + GESTURE_ERROR_NOT_STARTED = TIZEN_ERROR_CONTEXT | 0x02, /**< Recognition is not started */ + GESTURE_ERROR_OPERATION_FAILED = TIZEN_ERROR_CONTEXT | 0x04, /**< Operation failed because of a system error */ +} gesture_error_e; + +/** + * @brief Enumeration for gesture types. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum { + GESTURE_DOUBLE_TAP = 1, /**< The mobile device is tapped twice */ + GESTURE_MOVE_TO_EAR, /**< The mobile device is moved near to an ear */ + GESTURE_NO_MOVE, /**< The mobile device is being stopped for a while */ + GESTURE_PICK_UP, /**< The mobile device is picked up */ + GESTURE_SHAKE, /**< The mobile device is quickly moved back and forth */ + GESTURE_SNAP, /**< The mobile device is moved along an axis and back */ + GESTURE_TILT, /**< The mobile device is tilted */ + GESTURE_TURN_FACE_DOWN, /**< The mobile device is flipped from face to back */ + GESTURE_WRIST_UP, /**< The wearable device is moved and faced up */ +} gesture_type_e; + +/** + * @brief Enumeration for gesture recognition option. + * @details If the default option is used, the system tries to reduce power consumption. + * For example, the recognition engine may stop detecting gestures if the display is turned off. + * Using #GESTURE_OPTION_ALWAYS_ON disables such power-saving functionalities. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum { + GESTURE_OPTION_DEFAULT = 0, /**< Running in the default setting */ + GESTURE_OPTION_ALWAYS_ON = 1, /**< Trying to detect gestures always */ +} gesture_option_e; + +/** + * @brief Enumeration for gesture event types. + * @details With regards to type of the gesture, gesture_get_event() returns one of the followings. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum { + GESTURE_EVENT_NONE = 0, /**< Detected nothing */ + GESTURE_EVENT_DETECTED = 1, /**< Detected the gesture */ + + GESTURE_SHAKE_DETECTED = 1, /**< Shake gesture started */ + GESTURE_SHAKE_FINISHED = 2, /**< Shake gesture stopped */ + + GESTURE_SNAP_X_NEGATIVE = 1, /**< Detected -X snap */ + GESTURE_SNAP_X_POSITIVE = 2, /**< Detected +X snap */ + GESTURE_SNAP_Y_NEGATIVE = 3, /**< Detected -Y snap */ + GESTURE_SNAP_Y_POSITIVE = 4, /**< Detected +Y snap */ + GESTURE_SNAP_Z_NEGATIVE = 5, /**< Detected -Z snap */ + GESTURE_SNAP_Z_POSITIVE = 6, /**< Detected +Z snap */ +} gesture_event_e; + +/** + * @brief Called when a gesture is detected. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] gesture Gesture type detected + * @param[in] data Detailed information of the detected gesture.@n + * gesture_get_event() or gesture_get_tilt() + * can be used to extract the information from @c data. + * @param[in] timestamp The time when the gesture is detected. Epoch time in seconds. + * @param[in] error An error value. It can be one of the following error values:@n + * #GESTURE_ERROR_NONE, if the operation succeeded.@n + * #GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported in the current profile.@n + * #GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error.@n + * #GESTURE_ERROR_PERMISSION_DENIED, if the application has no permission to use this. + * @param[in] user_data The user data had passed to gesture_start_recognition() + * + * @pre gesture_start_recognition() + */ +typedef void(* gesture_recognition_cb)(gesture_type_e gesture, const gesture_data_h data, double timestamp, gesture_error_e error, void *user_data); + +/** + * @brief Check whether the gesture is supported or not. + * @details Check if the given gesture type is supported in the current device. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] gesture Gesture type to be checked + * @param[out] supported @c true if the gesture is recognizable in the current device,@n + * @c false otherwise + * + * @return @c 0 if the @c gesture is supported, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Supported + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED The @c gesture is not supported + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * @retval #GESTURE_ERROR_PERMISSION_DENIED Does not have permission to use this + */ +int gesture_is_supported(gesture_type_e gesture, bool* supported); + +/** + * @brief Initializes a gesture handle. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[out] handle Gesture handle to be initialized + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error, e.g., out of memory + * + * @see gesture_release() + */ +int gesture_create(gesture_h *handle); + +/** + * @brief Releases the resources occupied by the gesture handle. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] handle Gesture handle to be released + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @pre gesture_create() + */ +int gesture_release(gesture_h handle); + +/** + * @brief Starts to recognize a gesture. + * @details Sets a callback function to be invoked when the gesture is detected, + * and starts to monitor occurrences of the gesture. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] gesture Gesture type to be monitored + * @param[in] option Detection option + * @param[in] callback Callback function to receive gesture events + * @param[in] user_data User data to be passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * @retval #GESTURE_ERROR_PERMISSION_DENIED Does not have permission to use this + * + * @pre gesture_create() + * @post gesture_recognition_cb() + * @see gesture_stop_recognition() + */ +int gesture_start_recognition(gesture_h handle, gesture_type_e gesture, gesture_option_e option, gesture_recognition_cb callback, void *user_data); + +/** + * @brief Stops recognizing the gesture registered to the gesture handle. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] handle Gesture handle to release its callback function registered + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_NOT_STARTED Nothing is started using the @c handle + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int gesture_stop_recognition(gesture_h handle); + +/** + * @brief Gets the gesture event from the gesture data received. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] data Gesture data received through a callback function + * @param[out] event Gesture event data + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int gesture_get_event(const gesture_data_h data, gesture_event_e *event); + +/** + * @brief Gets the tilting degrees from #GESTURE_TILT data received. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] data Tilt gesture data received through a callback function + * @param[out] x Tilting degree on X-axis + * @param[out] y Tilting degree on Y-axis + * + * @return @c 0 on success, otherwise a negative error value + * @retval #GESTURE_ERROR_NONE Successful + * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int gesture_get_tilt(const gesture_data_h data, int *x, int *y); + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** +* @} +*/ + +#endif // __TIZEN_GESTURE_H__ diff --git a/packaging/capi-context-gesture.manifest b/packaging/capi-context-gesture.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/packaging/capi-context-gesture.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/capi-context-gesture.spec b/packaging/capi-context-gesture.spec new file mode 100644 index 0000000..22a8b9c --- /dev/null +++ b/packaging/capi-context-gesture.spec @@ -0,0 +1,70 @@ +Name: capi-context-gesture +Summary: Tizen Native Gesture Recognition API +Version: 2.0.2 +Release: 1 +Group: Service/Context +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz + +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(sensor) + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +# Backward compatibility +Provides: gesture +Provides: libcore-context-manager.so.1 + +%description +Tizen Native Gesture Recognition API + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +export CXXFLAGS+=" -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter" +export CXXFLAGS+=" -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls" +export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow" +export CXXFLAGS+=" -Wnon-virtual-dtor" + +%cmake . -DMAJORVER=${MAJORVER} -DFULLVER=%{version} +make %{?_smp_mflags} + +%install +%make_install + +# For backward compatibility +ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/gesture.pc +ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/libcore-context-manager.pc +ln -s lib%{name}.so.%{version} %{buildroot}/%{_libdir}/libcore-context-manager.so.1 + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%manifest packaging/%{name}.manifest +%{_libdir}/*.so.* +%license LICENSE + +%package devel +Summary: Tizen Native Gesture Recognition API (Development) +Group: Framework/context +Requires: %{name} = %{version}-%{release} + +%description devel +Tizen Native Gesture Recognition API (Development) + +%files devel +%{_includedir}/*/*.h +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc diff --git a/src/Gesture.cpp b/src/Gesture.cpp new file mode 100644 index 0000000..1b74537 --- /dev/null +++ b/src/Gesture.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 +#include "GestureSensor.h" + +#define FEATURE_GESTURE "tizen.org/feature/sensor.gesture_recognition" + +#define GESTURE_FIRST GESTURE_DOUBLE_TAP +#define GESTURE_LAST GESTURE_WRIST_UP +#define IS_VALID_GESTURE(X) (GESTURE_FIRST <= (X) && (X) <= GESTURE_LAST) + +using namespace gesture; + +struct _gesture_handle_s { + GestureSensor *sensor; +}; + +EXPORT_API int gesture_is_supported(gesture_type_e gesture, bool* supported) +{ + if (supported) + *supported = false; + + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(supported); + IF_FAIL_RETURN(IS_VALID_GESTURE(gesture), ERR_INVALID_PARAMETER); + + *supported = GestureSensor::isSupported(gesture); + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_create(gesture_h *handle) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(handle); + + _gesture_handle_s *hdl = static_cast(malloc(sizeof(_gesture_handle_s))); + IF_FAIL_RETURN_TAG(hdl, ERR_OPERATION_FAILED, _E, "Memory allocation failed"); + + hdl->sensor = new(std::nothrow) GestureSensor(); + if (hdl->sensor == NULL) { + _E("Memory allocation failed"); + free(hdl); + return ERR_OPERATION_FAILED; + } + + *handle = hdl; + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_release(gesture_h handle) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(handle); + + delete handle->sensor; + free(handle); + + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_start_recognition(gesture_h handle, gesture_type_e gesture, gesture_option_e option, gesture_recognition_cb callback, void *user_data) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(handle); + ASSERT_NOT_NULL(callback); + IF_FAIL_RETURN(IS_VALID_GESTURE(gesture), ERR_INVALID_PARAMETER); + + if (option == GESTURE_OPTION_DEFAULT) { + handle->sensor->setPowerSave(true); + } else if (option == GESTURE_OPTION_ALWAYS_ON) { + handle->sensor->setPowerSave(false); + } else { + return ERR_INVALID_PARAMETER; + } + + if (!handle->sensor->setGesture(gesture)) { + return GESTURE_ERROR_NOT_SUPPORTED; + } + + handle->sensor->setCallback(callback); + handle->sensor->setUserData(user_data); + + if (!handle->sensor->start()) { + return ERR_OPERATION_FAILED; + } + + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_stop_recognition(gesture_h handle) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(handle); + + IF_FAIL_RETURN(handle->sensor->stop(), GESTURE_ERROR_NOT_STARTED); + + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_get_event(const gesture_data_h data, gesture_event_e *event) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(data); + ASSERT_NOT_NULL(event); + + if (data->gesture == GESTURE_TILT) + return GESTURE_ERROR_NOT_SUPPORTED; + + *event = static_cast(data->event); + + return ERR_NONE; + //LCOV_EXCL_STOP +} + +EXPORT_API int gesture_get_tilt(const gesture_data_h data, int *x, int *y) +{ + ASSERT_SUPPORTED(FEATURE_GESTURE); + //LCOV_EXCL_START + ASSERT_NOT_NULL(data); + ASSERT_NOT_NULL(x); + ASSERT_NOT_NULL(y); + + if (data->gesture != GESTURE_TILT) + return ERR_NOT_SUPPORTED; + + *x = data->tilt_x; + *y = data->tilt_y; + + return ERR_NONE; + //LCOV_EXCL_STOP +} diff --git a/src/GestureSensor.cpp b/src/GestureSensor.cpp new file mode 100644 index 0000000..b4f6617 --- /dev/null +++ b/src/GestureSensor.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 "GestureSensor.h" + +using namespace gesture; + +//LCOV_EXCL_START +GestureSensor::GestureSensor() : + __gestureType(static_cast(UNDEFINED)), + __callback(NULL), + __userData(NULL), + __sensorAdapter(this) +{ +} + +GestureSensor::~GestureSensor() +{ +} + +bool GestureSensor::setGesture(gesture_type_e type) +{ + sensor_type_t sensor = __toSensor(type); + IF_FAIL_RETURN(sensor != UNKNOWN_SENSOR, false); + + __gestureType = type; + __sensorAdapter.setSensor(sensor); + return true; +} + +void GestureSensor::setPowerSave(bool ps) +{ + __sensorAdapter.setPowerSave(ps); +} + +void GestureSensor::setCallback(gesture_recognition_cb cb) +{ + __callback = cb; +} + +void GestureSensor::setUserData(void* data) +{ + __userData = data; +} + +bool GestureSensor::start() +{ + return __sensorAdapter.start(); +} + +bool GestureSensor::stop() +{ + return __sensorAdapter.stop(); +} + +bool GestureSensor::isSupported(gesture_type_e type) +{ + sensor_type_t sensor = __toSensor(type); + IF_FAIL_RETURN(sensor != UNKNOWN_SENSOR, false); + + return SensorAdapter::isSupported(sensor); +} + +void GestureSensor::onEvent(double timestamp, float* values, int accuracy) +{ + _gesture_data_s data; + data.gesture = __gestureType; + + /* TODO: This is the default form. + For each sensor, this part needs to adapt accordingly */ + data.event = static_cast(values[0]); + + __callback(__gestureType, &data, timestamp, static_cast(ERR_NONE), __userData); +} + +sensor_type_t GestureSensor::__toSensor(gesture_type_e type) +{ + switch (type) { + case GESTURE_PICK_UP: + return GESTURE_MOVEMENT_SENSOR; + case GESTURE_WRIST_UP: + return GESTURE_WRIST_UP_SENSOR; + default: + return UNKNOWN_SENSOR; + } +} +//LCOV_EXCL_STOP diff --git a/src/GestureSensor.h b/src/GestureSensor.h new file mode 100644 index 0000000..0599538 --- /dev/null +++ b/src/GestureSensor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 __GESTURE_SENSOR_H__ +#define __GESTURE_SENSOR_H__ + +#include +#include "SensorAdapter.h" + +struct _gesture_data_s { + int gesture; + int event; + int tilt_x; + int tilt_y; +}; + +namespace gesture { + + class GestureSensor : public ISensorListener { + public: + GestureSensor(); + ~GestureSensor(); + + bool setGesture(gesture_type_e type); + void setPowerSave(bool ps); + void setCallback(gesture_recognition_cb cb); + void setUserData(void* data); + + bool start(); + bool stop(); + + static bool isSupported(gesture_type_e type); + + private: + void onEvent(double timestamp, float* values, int accuracy); + + static sensor_type_t __toSensor(gesture_type_e type); + + gesture_type_e __gestureType; + gesture_recognition_cb __callback; + void *__userData; + SensorAdapter __sensorAdapter; + }; + +} + +#endif /* __GESTURE_SENSOR_H__ */ diff --git a/src/ISensorListener.h b/src/ISensorListener.h new file mode 100644 index 0000000..eeee8a5 --- /dev/null +++ b/src/ISensorListener.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 __I_SENSOR_LISTENER_H__ +#define __I_SENSOR_LISTENER_H__ + +namespace gesture { + + class ISensorListener { + public: + virtual ~ISensorListener() {} + virtual void onEvent(double timestamp, float* values, int accuracy) = 0; + }; + +} + +#endif /* __I_SENSOR_LISTENER_H__ */ diff --git a/src/SensorAdapter.cpp b/src/SensorAdapter.cpp new file mode 100644 index 0000000..07aee57 --- /dev/null +++ b/src/SensorAdapter.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include "SensorAdapter.h" + +#define SENSOR_EVENT(X) (((int)(X) << 16) | 0x01) + +using namespace gesture; + +SensorAdapter::SensorAdapter(ISensorListener* listener) : + __sensorHandle(-1), + __sensorType(UNKNOWN_SENSOR), + __powerSave(true), + __listener(listener) +{ +} + +SensorAdapter::~SensorAdapter() +{ + stop(); +} + +//LCOV_EXCL_START +void SensorAdapter::setSensor(sensor_type_t type) +{ + __sensorType = type; +} + +void SensorAdapter::setPowerSave(bool ps) +{ + __powerSave = ps; + + if (__sensorHandle < 0) + return; + + sensord_set_attribute_int(__sensorHandle, SENSORD_ATTRIBUTE_PAUSE_POLICY, + __powerSave ? SENSORD_PAUSE_ALL : SENSORD_PAUSE_NONE); +} + +void SensorAdapter::setAttribute(int key, int value) +{ + IF_FAIL_VOID_TAG(__sensorHandle >= 0, _W, "Sensor not started"); + sensord_set_attribute_int(__sensorHandle, key, value); +} + +bool SensorAdapter::start() +{ + int err; + sensor_t sensor; + + err = sensord_get_default_sensor(__sensorType, &sensor); + IF_FAIL_RETURN_TAG(err == 0, false, _E, "Getting sensor failed (%d)", err); + + __sensorHandle = sensord_connect(sensor); + IF_FAIL_RETURN_TAG(__sensorHandle >= 0, false, _E, "Connection failed"); + + if (!sensord_register_event(__sensorHandle, SENSOR_EVENT(__sensorType), 0, 0, __eventCb, this)) { + _E("Event registration failed"); + sensord_disconnect(__sensorHandle); + __sensorHandle = -1; + return false; + } + + if (!sensord_start(__sensorHandle, __powerSave ? SENSOR_OPTION_DEFAULT : SENSOR_OPTION_ALWAYS_ON)) { + _E("Starting failed"); + sensord_unregister_event(__sensorHandle, SENSOR_EVENT(__sensorType)); + sensord_disconnect(__sensorHandle); + __sensorHandle = -1; + return false; + } + + return true; +} + +bool SensorAdapter::stop() +{ + IF_FAIL_RETURN(__sensorHandle >= 0, false); + + sensord_stop(__sensorHandle); + sensord_unregister_event(__sensorHandle, SENSOR_EVENT(__sensorType)); + sensord_disconnect(__sensorHandle); + __sensorHandle = -1; + + return true; +} + +bool SensorAdapter::isSupported(sensor_type_t type) +{ + sensor_t sensor = sensord_get_sensor(type); + return (sensor != NULL); +} + +double SensorAdapter::__getEpoch(unsigned long long monotonic) +{ + struct timespec ts; + struct timeval tv; + double timeDiff; + double timestamp; + + clock_gettime(CLOCK_MONOTONIC, &ts); + timeDiff = (ts.tv_sec * 1000000000.0 + ts.tv_nsec) / 1000000.0 - monotonic / 1000.0; + + gettimeofday(&tv, NULL); + timestamp = tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0 - timeDiff; + return timestamp; +} + +void SensorAdapter::__onEvent(sensor_data_t *eventData) +{ + double timestamp = __getEpoch(eventData->timestamp); + __listener->onEvent(timestamp / 1000.0, eventData->values, eventData->accuracy); +} + +void SensorAdapter::__eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData) +{ + SensorAdapter *instance = static_cast(cbData); + instance->__onEvent(eventData); +} +//LCOV_EXCL_STOP diff --git a/src/SensorAdapter.h b/src/SensorAdapter.h new file mode 100644 index 0000000..7ce9fc4 --- /dev/null +++ b/src/SensorAdapter.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 __GESTURE_SENSOR_ADAPTER_H__ +#define __GESTURE_SENSOR_ADAPTER_H__ + +#include +#include "TypesInternal.h" +#include "ISensorListener.h" + +namespace gesture { + + class SensorAdapter { + public: + SensorAdapter(ISensorListener* listener); + ~SensorAdapter(); + + void setSensor(sensor_type_t type); + void setPowerSave(bool ps); + void setAttribute(int key, int value); + + bool start(); + bool stop(); + + static bool isSupported(sensor_type_t type); + + private: + double __getEpoch(unsigned long long monotonic); + void __onEvent(sensor_data_t* eventData); + + static void __eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData); + + int __sensorHandle; + sensor_type_t __sensorType; + bool __powerSave; + ISensorListener *__listener; + }; + +} + +#endif /* __GESTURE_SENSOR_ADAPTER_H__ */ diff --git a/src/TypesInternal.cpp b/src/TypesInternal.cpp new file mode 100644 index 0000000..d4d9175 --- /dev/null +++ b/src/TypesInternal.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 +#include "TypesInternal.h" + +int gesture::isSupported(const char *feature) +{ + bool supported = false; + int ret = system_info_get_platform_bool(feature, &supported); + + if (ret == ERR_NONE && !supported) { + _W("Not Supported: %s", feature); + return ERR_NOT_SUPPORTED; + } else if (ret != ERR_NONE) { + _E("Getting system info failed: %#x", ret); + return ERR_OPERATION_FAILED; + } + + return ERR_NONE; +} diff --git a/src/TypesInternal.h b/src/TypesInternal.h new file mode 100644 index 0000000..04cf1fb --- /dev/null +++ b/src/TypesInternal.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 _GESTURE_TYPES_INTERNAL_H_ +#define _GESTURE_TYPES_INTERNAL_H_ + +#include +#include +#include + +#define UNDEFINED -1 + +#define ERR_NONE TIZEN_ERROR_NONE +#define ERR_INVALID_PARAMETER TIZEN_ERROR_INVALID_PARAMETER +#define ERR_INVALID_OPERATION TIZEN_ERROR_INVALID_OPERATION +#define ERR_OUT_OF_MEMORY TIZEN_ERROR_OUT_OF_MEMORY +#define ERR_PERMISSION_DENIED TIZEN_ERROR_PERMISSION_DENIED +#define ERR_NOT_SUPPORTED TIZEN_ERROR_NOT_SUPPORTED +#define ERR_NO_DATA TIZEN_ERROR_NO_DATA +#define ERR_ALREADY_STARTED (TIZEN_ERROR_CONTEXT | 0x01) +#define ERR_NOT_STARTED (TIZEN_ERROR_CONTEXT | 0x02) +#define ERR_OUT_OF_RANGE (TIZEN_ERROR_CONTEXT | 0x03) +#define ERR_OPERATION_FAILED (TIZEN_ERROR_CONTEXT | 0x04) +#define ERR_RULE_ENABLED (TIZEN_ERROR_CONTEXT | 0x05) +#define ERR_RULE_NOT_ENABLED (TIZEN_ERROR_CONTEXT | 0x06) +#define ERR_INVALID_RULE (TIZEN_ERROR_CONTEXT | 0x07) +#define ERR_RULE_NOT_EXIST (TIZEN_ERROR_CONTEXT | 0x08) +#define ERR_INVALID_DATA ERR_INVALID_RULE +#define ERR_DATA_EXIST (TIZEN_ERROR_CONTEXT | 0X09) + +/* Logging and Error Handling */ +#define _I SLOGI +#define _D SLOGD +#define _W SLOGW +#define _E SLOGE +#define _SI SECURE_SLOGI +#define _SD SECURE_SLOGD +#define _SW SECURE_LOGW +#define _SE SECURE_SLOGE + +#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0) + +#define IF_FAIL_RETURN(cond, ret) \ + do { if (!(cond)) { return ret; } } while (0) + +#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0) + +#define IF_FAIL_VOID(cond) \ + do { if (!(cond)) { return; } } while (0) + +#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0) + +#define IF_FAIL_CATCH(cond) \ + do { if (!(cond)) { goto CATCH; } } while (0) + +#define IS_FAILED(X) ((X) != ERR_NONE) + +#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed") +#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, ERR_INVALID_PARAMETER, _E, "Parameter null") + +#define ASSERT_SUPPORTED(feature) \ + do { \ + int __result = gesture::isSupported(feature); \ + if (__result != ERR_NONE) return __result; \ + } while (0) + +namespace gesture { + int isSupported(const char *feature); +} + +#endif /* _GESTURE_TYPES_INTERNAL_H_ */ -- 2.7.4 From e00d8bd4e6373421231e0f70b7b46369bc30a863 Mon Sep 17 00:00:00 2001 From: chakradhar Date: Wed, 12 Feb 2020 12:11:25 +0530 Subject: [PATCH 03/14] removing context name and replacing it with gesture Change-Id: Ie3912bf42491ca4e861ba39d78ab39cadac1427a Signed-off-by: chakradhar --- CMakeLists.txt | 4 ++-- capi-context-gesture.pc.in => capi-gesture.pc.in | 0 doc/gesture_recognition_doc.h | 10 +++++----- include/gesture_recognition.h | 2 +- .../{capi-context-gesture.manifest => capi-gesture.manifest} | 0 packaging/{capi-context-gesture.spec => capi-gesture.spec} | 12 ++++++------ 6 files changed, 14 insertions(+), 14 deletions(-) rename capi-context-gesture.pc.in => capi-gesture.pc.in (100%) rename packaging/{capi-context-gesture.manifest => capi-gesture.manifest} (100%) rename packaging/{capi-context-gesture.spec => capi-gesture.spec} (83%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 214b460..b41fcda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(capi-context-gesture) +PROJECT(capi-gesture) INCLUDE(GNUInstallDirs) SET(target ${PROJECT_NAME}) @@ -7,7 +7,7 @@ SET(target ${PROJECT_NAME}) # Source Lists FILE(GLOB SRCS src/*.cpp) -SET(inc_subdir "context-service") +SET(inc_subdir "gesture") SET(dependency "glib-2.0 dlog capi-base-common capi-system-info sensor") # Options diff --git a/capi-context-gesture.pc.in b/capi-gesture.pc.in similarity index 100% rename from capi-context-gesture.pc.in rename to capi-gesture.pc.in diff --git a/doc/gesture_recognition_doc.h b/doc/gesture_recognition_doc.h index 48c913f..5a3191d 100644 --- a/doc/gesture_recognition_doc.h +++ b/doc/gesture_recognition_doc.h @@ -18,16 +18,16 @@ */ /** - * @ingroup CAPI_CONTEXT_FRAMEWORK - * @defgroup CAPI_CONTEXT_GESTURE_MODULE Gesture Recognition + * @ingroup CAPI_GESTURE_FRAMEWORK + * @defgroup CAPI_GESTURE_MODULE Gesture Recognition * * @brief The gesture recognition API allows applications to be notified and * react when the user performs a gesture. * - * @section CAPI_CONTEXT_GESTURE_MODULE_HEADER Required Header + * @section CAPI_GESTURE_MODULE_HEADER Required Header * \#include * - * @section CAPI_CONTEXT_GESTURE_MODULE_OVERVIEW Overview + * @section CAPI_GESTURE_MODULE_OVERVIEW Overview * * * The gesture recognition API allows to register callback functions to be called @@ -133,7 +133,7 @@ gesture_release(handle); \endcode - * @section CAPI_CONTEXT_GESTURE_MODULE_FEATURE Related Features + * @section CAPI_GESTURE_MODULE_FEATURE Related Features * This API is related with the following features:\n * - http://tizen.org/feature/sensor.gesture_recognition\n * - http://tizen.org/feature/sensor.wrist_up diff --git a/include/gesture_recognition.h b/include/gesture_recognition.h index 4b9ae4b..b5c90ce 100644 --- a/include/gesture_recognition.h +++ b/include/gesture_recognition.h @@ -21,7 +21,7 @@ #define __TIZEN_GESTURE_H__ /** - * @addtogroup CAPI_CONTEXT_GESTURE_MODULE + * @addtogroup CAPI_GESTURE_MODULE * @{ */ diff --git a/packaging/capi-context-gesture.manifest b/packaging/capi-gesture.manifest similarity index 100% rename from packaging/capi-context-gesture.manifest rename to packaging/capi-gesture.manifest diff --git a/packaging/capi-context-gesture.spec b/packaging/capi-gesture.spec similarity index 83% rename from packaging/capi-context-gesture.spec rename to packaging/capi-gesture.spec index 22a8b9c..b456052 100644 --- a/packaging/capi-context-gesture.spec +++ b/packaging/capi-gesture.spec @@ -1,8 +1,8 @@ -Name: capi-context-gesture +Name: capi-gesture Summary: Tizen Native Gesture Recognition API Version: 2.0.2 Release: 1 -Group: Service/Context +Group: Service/Gesture License: Apache-2.0 Source0: %{name}-%{version}.tar.gz @@ -18,7 +18,7 @@ Requires(postun): /sbin/ldconfig # Backward compatibility Provides: gesture -Provides: libcore-context-manager.so.1 +Provides: libcore-gesture-manager.so.1 %description Tizen Native Gesture Recognition API @@ -42,8 +42,8 @@ make %{?_smp_mflags} # For backward compatibility ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/gesture.pc -ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/libcore-context-manager.pc -ln -s lib%{name}.so.%{version} %{buildroot}/%{_libdir}/libcore-context-manager.so.1 +ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/libcore-gesture-manager.pc +ln -s lib%{name}.so.%{version} %{buildroot}/%{_libdir}/libcore-gesture-manager.so.1 %post /sbin/ldconfig @@ -58,7 +58,7 @@ ln -s lib%{name}.so.%{version} %{buildroot}/%{_libdir}/libcore-context-manager.s %package devel Summary: Tizen Native Gesture Recognition API (Development) -Group: Framework/context +Group: Framework/activity Requires: %{name} = %{version}-%{release} %description devel -- 2.7.4 From 72b30216288607f7d3d7f6d3c4c9b074e4f95214 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 29 Jul 2020 21:36:11 +0900 Subject: [PATCH 04/14] [ACR-1585][gesture][Initial version of codes] Change-Id: I75b70fbc7ebf4d0c7f731f89b58fd5e9e26ac6ab Signed-off-by: sooyeon.kim --- AUTHORS | 1 + CMakeLists.txt | 89 ++- LICENSE | 5 +- capi-gesture.pc.in | 13 - capi-ui-gesture-devel.manifest | 5 + capi-ui-gesture.manifest | 5 + client/CMakeLists.txt | 23 + src/ISensorListener.h => client/GestureSensor.c | 45 +- src/TypesInternal.cpp => client/GestureSensor.h | 45 +- client/gesture.c | 342 ++++++++++ client/gesture_client_dbus.c | 663 +++++++++++++++++++ client/gesture_client_dbus.h | 54 ++ client/gesture_main.h | 42 ++ doc/gesture_recognition_doc.h | 149 ----- doc/uix_gesture_doc.h | 53 ++ engine/CMakeLists.txt | 22 + engine/gesture_engine.c | 206 ++++++ engine/gesture_engine_dbus.c | 643 ++++++++++++++++++ engine/gesture_engine_dbus.h | 49 ++ engine/gesture_engine_main.h | 40 ++ include/CMakeLists.txt | 13 + include/capi-ui-gesture-client.pc.in | 11 + include/capi-ui-gesture-engine.pc.in | 11 + include/gesture.h | 208 ++++++ include/gesture_common.h | 86 +++ include/gesture_common_internal.h | 78 +++ include/gesture_data_info.h | 44 ++ include/gesture_defs.h | 117 ++++ include/gesture_engine.h | 573 ++++++++++++++++ include/gesture_internal.h | 117 ++++ include/gesture_recognition.h | 269 -------- manager/gestured_client_manager.cpp | 286 ++++++++ manager/gestured_client_manager.h | 57 ++ manager/gestured_engine_manager.cpp | 284 ++++++++ manager/gestured_engine_manager.h | 54 ++ packaging/capi-gesture.manifest | 5 - packaging/capi-gesture.spec | 70 -- packaging/capi-ui-gesture.conf | 17 + packaging/capi-ui-gesture.service | 15 + packaging/capi-ui-gesture.spec | 131 ++++ packaging/org.tizen.gesture.server.service | 4 + server/CMakeLists.txt | 25 + server/gestured_dbus.c | 840 ++++++++++++++++++++++++ server/gestured_dbus.h | 69 ++ server/gestured_error.h | 50 ++ server/gestured_main.c | 136 ++++ src/Gesture.cpp | 157 ----- src/GestureSensor.cpp | 101 --- src/GestureSensor.h | 61 -- src/SensorAdapter.cpp | 135 ---- src/SensorAdapter.h | 55 -- src/TypesInternal.h | 88 --- 52 files changed, 5480 insertions(+), 1181 deletions(-) create mode 100644 AUTHORS delete mode 100644 capi-gesture.pc.in create mode 100644 capi-ui-gesture-devel.manifest create mode 100644 capi-ui-gesture.manifest create mode 100644 client/CMakeLists.txt rename src/ISensorListener.h => client/GestureSensor.c (59%) rename src/TypesInternal.cpp => client/GestureSensor.h (50%) create mode 100644 client/gesture.c create mode 100644 client/gesture_client_dbus.c create mode 100644 client/gesture_client_dbus.h create mode 100644 client/gesture_main.h delete mode 100644 doc/gesture_recognition_doc.h create mode 100644 doc/uix_gesture_doc.h create mode 100644 engine/CMakeLists.txt create mode 100644 engine/gesture_engine.c create mode 100644 engine/gesture_engine_dbus.c create mode 100644 engine/gesture_engine_dbus.h create mode 100644 engine/gesture_engine_main.h create mode 100644 include/CMakeLists.txt create mode 100644 include/capi-ui-gesture-client.pc.in create mode 100644 include/capi-ui-gesture-engine.pc.in create mode 100644 include/gesture.h create mode 100644 include/gesture_common.h create mode 100644 include/gesture_common_internal.h create mode 100644 include/gesture_data_info.h create mode 100644 include/gesture_defs.h create mode 100644 include/gesture_engine.h create mode 100644 include/gesture_internal.h delete mode 100644 include/gesture_recognition.h create mode 100644 manager/gestured_client_manager.cpp create mode 100644 manager/gestured_client_manager.h create mode 100644 manager/gestured_engine_manager.cpp create mode 100644 manager/gestured_engine_manager.h delete mode 100644 packaging/capi-gesture.manifest delete mode 100644 packaging/capi-gesture.spec create mode 100644 packaging/capi-ui-gesture.conf create mode 100644 packaging/capi-ui-gesture.service create mode 100644 packaging/capi-ui-gesture.spec create mode 100644 packaging/org.tizen.gesture.server.service create mode 100644 server/CMakeLists.txt create mode 100644 server/gestured_dbus.c create mode 100644 server/gestured_dbus.h create mode 100644 server/gestured_error.h create mode 100644 server/gestured_main.c delete mode 100644 src/Gesture.cpp delete mode 100644 src/GestureSensor.cpp delete mode 100644 src/GestureSensor.h delete mode 100644 src/SensorAdapter.cpp delete mode 100644 src/SensorAdapter.h delete mode 100644 src/TypesInternal.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ae57d3f --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Sungwook Park diff --git a/CMakeLists.txt b/CMakeLists.txt index b41fcda..0872c9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,59 +1,48 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(capi-gesture) -INCLUDE(GNUInstallDirs) +PROJECT(capi-ui-gesture) -SET(target ${PROJECT_NAME}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "${PREFIX}") +SET(VERSION 0.2.56) -# Source Lists -FILE(GLOB SRCS src/*.cpp) +ADD_DEFINITIONS("-Werror") -SET(inc_subdir "gesture") -SET(dependency "glib-2.0 dlog capi-base-common capi-system-info sensor") +## Include common directory ## +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/engine") +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/client") +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/server") +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/manager") -# Options +## Dependent packages ## INCLUDE(FindPkgConfig) -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/include +pkg_check_modules(pkgs REQUIRED + dlog + glib-2.0 + json-glib-1.0 + libtzplatform-config + cynara-client + cynara-session + capi-appfw-app-common + capi-appfw-app-control + capi-appfw-app-manager + capi-appfw-package-manager + dbus-1 + capi-system-info + aul ) -ADD_DEFINITIONS(-O2 -Wall -fPIC -flto -fdata-sections -ffunction-sections -fvisibility=hidden) -ADD_DEFINITIONS(-fdiagnostics-color) -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections") -SET(CMAKE_VERBOSE_MAKEFILE OFF) - -# Build -pkg_check_modules(pkgs REQUIRED ${dependency}) - -FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -ADD_LIBRARY(${target} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${target} ${pkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS}) -SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CAPI-GESTURE\"") -SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER}) -SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER}) - -# Install -INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) -INSTALL( - DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${inc_subdir} - FILES_MATCHING PATTERN "*.h" -) +## API ## +ADD_SUBDIRECTORY(include) -SET(VERSION ${FULLVER}) -SET(PC_PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(PC_NAME ${PROJECT_NAME}) -SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") -SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${inc_subdir}") -SET(PC_DESCRIPTION "Tizen C Native Gesture Recognition API") -SET(PC_REQUIRED ${dependency}) -SET(PC_LDFLAGS -l${target}) - -CONFIGURE_FILE( - ${PROJECT_NAME}.pc.in - ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc - @ONLY -) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +## Gesture server ## +ADD_SUBDIRECTORY(server) + +## Gesture engine library ## +ADD_SUBDIRECTORY(engine) + +## Gesture API library ## +ADD_SUBDIRECTORY(client) + +## Gesture manager ## +#ADD_SUBDIRECTORY(manager) diff --git a/LICENSE b/LICENSE index 6ce6ec7..9bbfde4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. Apache License Version 2.0, January 2004 @@ -188,7 +188,7 @@ Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved. same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) [yyyy] [name of copyright owner] + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -201,3 +201,4 @@ Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd. All rights reserved. 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. + diff --git a/capi-gesture.pc.in b/capi-gesture.pc.in deleted file mode 100644 index 71c14c4..0000000 --- a/capi-gesture.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -#Package Information for pkg-config - -prefix=@PC_PREFIX@ -exec_prefix=@PC_PREFIX@ -libdir=@PC_LIBDIR@ -includedir=@PC_INCLUDE@ - -Name: @PC_NAME@ -Description: @PC_DESCRIPTION@ -Version: @VERSION@ -Requires: @PC_REQUIRED@ -Libs: -L${libdir} @PC_LDFLAGS@ -Cflags: -I${includedir} diff --git a/capi-ui-gesture-devel.manifest b/capi-ui-gesture-devel.manifest new file mode 100644 index 0000000..dfdc35c --- /dev/null +++ b/capi-ui-gesture-devel.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/capi-ui-gesture.manifest b/capi-ui-gesture.manifest new file mode 100644 index 0000000..dfdc35c --- /dev/null +++ b/capi-ui-gesture.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..ebc91f2 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,23 @@ +SET(SRCS + gesture.c + GestureSensor.c + gesture_client_dbus.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +## Add definitions ## +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") + +## gesture library ## +ADD_LIBRARY(${PROJECT_NAME}-client SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME}-client ${pkgs_LDFLAGS}) + +## Install library files ## +INSTALL(TARGETS ${PROJECT_NAME}-client DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries) diff --git a/src/ISensorListener.h b/client/GestureSensor.c similarity index 59% rename from src/ISensorListener.h rename to client/GestureSensor.c index eeee8a5..9f4818b 100644 --- a/src/ISensorListener.h +++ b/client/GestureSensor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,42 @@ * */ -#ifndef __I_SENSOR_LISTENER_H__ -#define __I_SENSOR_LISTENER_H__ +#include "GestureSensor.h" -namespace gesture { - class ISensorListener { - public: - virtual ~ISensorListener() {} - virtual void onEvent(double timestamp, float* values, int accuracy) = 0; - }; +bool setGesture(hand_gesture_type_e type) +{ + return true; +} + +void setPowerSave(bool ps) +{ + +} + +void setCallback(hand_gesture_recognition_cb cb) +{ + +} + +void setUserData(void* data) +{ + +} + +bool start() +{ + return true; +} + +bool stop() +{ + return true; +} + +bool isSensorSupported(hand_gesture_type_e type) +{ + return true; } -#endif /* __I_SENSOR_LISTENER_H__ */ diff --git a/src/TypesInternal.cpp b/client/GestureSensor.h similarity index 50% rename from src/TypesInternal.cpp rename to client/GestureSensor.h index d4d9175..c092532 100644 --- a/src/TypesInternal.cpp +++ b/client/GestureSensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,21 +15,34 @@ * */ -#include -#include "TypesInternal.h" +#ifndef __GESTURE_SENSOR_H__ +#define __GESTURE_SENSOR_H__ -int gesture::isSupported(const char *feature) +#include "gesture_main.h" + +#ifdef __cplusplus +extern "C" { - bool supported = false; - int ret = system_info_get_platform_bool(feature, &supported); - - if (ret == ERR_NONE && !supported) { - _W("Not Supported: %s", feature); - return ERR_NOT_SUPPORTED; - } else if (ret != ERR_NONE) { - _E("Getting system info failed: %#x", ret); - return ERR_OPERATION_FAILED; - } - - return ERR_NONE; +#endif + +bool setGesture(hand_gesture_type_e type); +void setPowerSave(bool ps); +void setCallback(hand_gesture_recognition_cb cb); +void setUserData(void* data); + +bool start(); +bool stop(); + +bool isSensorSupported(hand_gesture_type_e type); + +hand_gesture_type_e __gestureType; +hand_gesture_recognition_cb __callback; +void *__userData; + + +#ifdef __cplusplus } +#endif + +#endif /* __GESTURE_SENSOR_H__ */ + diff --git a/client/gesture.c b/client/gesture.c new file mode 100644 index 0000000..d6f8d47 --- /dev/null +++ b/client/gesture.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include +#include +#include +#include + +#include "gesture.h" +#include "gesture_internal.h" +#include "gesture_common_internal.h" +#include "gesture_main.h" +#include "gesture_client_dbus.h" + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURE_CLIENT" + +#define GESTURE_FIRST HAND_GESTURE_WRIST_UP +#define GESTURE_LAST HAND_GESTURE_WRIST_UP +//#define GESTURE_LAST GESTURE_RIGHT_HAND_MOVE +#define IS_VALID_GESTURE(X) (GESTURE_FIRST <= (X) && (X) <= GESTURE_LAST) + + +static cynara *p_cynara = NULL; + +static int _cynara_initialize() +{ + int ret = cynara_initialize(&p_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) + LOGE("Failed to cynara initialize"); + + return ret; +} + +static int _check_privilege(const char *uid, const char *privilege) +{ + int ret; + FILE *fp = NULL; + char label_path[1024] = "/proc/self/attr/current"; + char smack_label[1024] = {'\0',}; + + if (!p_cynara) { + return -1; + } + + fp = fopen(label_path, "r"); + if (fp != NULL) { + ret = fread(smack_label, 1, sizeof(smack_label), fp); + if (ret <= 0) + LOGE("Failed to fread"); + + fclose(fp); + } + + pid_t pid = getpid(); + char *session = cynara_session_from_pid(pid); + ret = cynara_check(p_cynara, smack_label, session, uid, privilege); + if (session) + free(session); + + if (ret != CYNARA_API_ACCESS_ALLOWED) { + LOGE("Access denied. The result of cynara_check() : %d.", ret); + return -1; + } + + return 0; +} + +static void _cynara_deinitialize() +{ + if (p_cynara) + cynara_finish(p_cynara); + + p_cynara = NULL; +} + +static int _gesture_check_privilege() { + char uid[16]; + int ret = HAND_GESTURE_ERROR_NONE; + + if (_cynara_initialize() != CYNARA_API_SUCCESS) + return HAND_GESTURE_ERROR_PERMISSION_DENIED; + + snprintf(uid, 16, "%d", getuid()); + if (_check_privilege(uid, GESTURE_PRIVILEGE_APPLAUNCH) < 0) { + LOGE("Permission is denied"); + ret = HAND_GESTURE_ERROR_PERMISSION_DENIED; + } + + _cynara_deinitialize(); + + return ret; +} + +EXPORT_API int hand_gesture_create(hand_gesture_h *handle) +{ + LOGD("hand_gesture_create"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret; + if (!handle) + return HAND_GESTURE_ERROR_INVALID_PARAMETER; + + if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE) + return HAND_GESTURE_ERROR_PERMISSION_DENIED; + + struct hand_gesture_s *_struct = (hand_gesture_h)calloc(1, sizeof(struct hand_gesture_s)); + + if (!_struct) + return HAND_GESTURE_ERROR_OUT_OF_MEMORY; + + ret = gesture_client_dbus_init(&_struct->gdbus_connection, &_struct->server_watcher_id, + &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, (void *)_struct); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to initialize dbus : %d", ret); + free(_struct); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + *handle = _struct; + + ret = gesture_client_dbus_initialize_engine(_struct->gdbus_connection); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to initialize engine dbus : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return HAND_GESTURE_ERROR_NONE; +} + +EXPORT_API int hand_gesture_destroy(hand_gesture_h handle) +{ + LOGD("hand_gesture_destroy"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret; + if (!handle) + return HAND_GESTURE_ERROR_INVALID_PARAMETER; + + LOGD("handle : %p", handle); + ret = gesture_client_dbus_shutdown(handle->gdbus_connection, &handle->server_monitor_id, &handle->monitor_id); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to finalize dbus : %d", ret); + free(handle); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + if (handle->gdbus_connection) + g_object_unref(handle->gdbus_connection); + + free(handle); + + return HAND_GESTURE_ERROR_NONE; +} + +EXPORT_API int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e gesture, bool* supported) +{ + LOGD("hand_gesture_is_supported_type"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(supported); + + int ret; + ret = gesture_client_dbus_is_support_gesture_type(handle->gdbus_connection, gesture, supported); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to get is_supported_type dbus : %d", ret); + free(handle); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return HAND_GESTURE_ERROR_NONE; +} + +EXPORT_API int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type) +{ + LOGD("hand_gesture_set_handtype"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret = HAND_GESTURE_ERROR_NONE; + + ret = gesture_client_dbus_set_handtype(handle->gdbus_connection, hand_type); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to set handtype : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode) +{ + LOGD("hand_gesture_set_workmode"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret = HAND_GESTURE_ERROR_NONE; + + ret = gesture_client_dbus_set_workmode(handle->gdbus_connection, work_mode); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to set work_mode : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option) +{ + LOGD("hand_gesture_set_option"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret = HAND_GESTURE_ERROR_NONE; + + ret = gesture_client_dbus_set_option(handle->gdbus_connection, option); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to set option : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity) +{ + LOGD("hand_gesture_set_sensitivity"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret = HAND_GESTURE_ERROR_NONE; + + ret = gesture_client_dbus_set_sensitivity(handle->gdbus_connection, sensitivity); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to set sensitivity : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int hand_gesture_start_recognition(hand_gesture_h handle, hand_gesture_type_e gesture_type, hand_gesture_recognition_cb callback, void *user_data) +{ + LOGD("hand_gesture_start_recognition"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE) + return HAND_GESTURE_ERROR_PERMISSION_DENIED; + + ASSERT_NOT_NULL(callback); + IF_FAIL_RETURN(IS_VALID_GESTURE(gesture_type), HAND_GESTURE_ERROR_INVALID_PARAMETER); + + int ret = HAND_GESTURE_ERROR_NONE; + + hand_gesture_data_h gesture_data = (hand_gesture_data_h)calloc(1, sizeof(struct hand_gesture_data_s)); + if (!gesture_data) { + return HAND_GESTURE_ERROR_OUT_OF_MEMORY; + } + + ret = gesture_client_dbus_start_recognition(handle->gdbus_connection, gesture_type, gesture_data, callback); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to start recoginition : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle) +{ + CHECK_GESTURE_FEATURE(); + + ASSERT_NOT_NULL(handle); + IF_FAIL_RETURN(stop(), HAND_GESTURE_ERROR_NOT_STARTED); + + int ret = HAND_GESTURE_ERROR_NONE; + ret = gesture_client_dbus_stop_recognition(handle->gdbus_connection); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to stop recoginition : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return HAND_GESTURE_ERROR_NONE; +} + +EXPORT_API int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event) +{ + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(data); + ASSERT_NOT_NULL(event); + + //*event = static_cast(data->event); + + return HAND_GESTURE_ERROR_NONE; +} + +EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name) +{ + LOGD("[engineInfo] hand_gesture_get_engine_info"); + + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + int ret = HAND_GESTURE_ERROR_NONE; + + ret = gesture_client_dbus_engine_get_info(handle->gdbus_connection, engine_app_id, engine_name); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to get engine info : %d", ret); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name); + return ret; +} diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c new file mode 100644 index 0000000..0683bf0 --- /dev/null +++ b/client/gesture_client_dbus.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2020 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 +#include + +#include "gesture_client_dbus.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURE_CLIENT_DBUS" + +static int is_server_started = 0; +static hand_gesture_recognition_cb g_callback; +static hand_gesture_data_h g_gesture_data; + +static hand_gesture_handtype_e g_hand_type = HAND_GESTURE_LEFT_HAND; +static hand_gesture_workmode_e g_work_mode = HAND_GESTURE_WORK_MODE_ONE_WAY; +static hand_gesture_option_e g_option = HAND_GESTURE_OPTION_DEFAULT; +static int g_sensitivity = 1; + +static char *g_engine_app_id; +static char *g_engine_name; + +static void _free_gesture_data(hand_gesture_data_h gesture_data) +{ + free(gesture_data); + gesture_data = NULL; +} + +static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) +{ + LOGD("name : %s, name_owner : %s", name, name_owner); +} + +static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + LOGD("name : %s", name); +} + +static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id) +{ + GError *error = NULL; + + if (*gdbus_connection == NULL) { + GDBusConnection *conn = NULL; + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (conn == NULL) { + if (error != NULL) { + LOGE("g_bus_get_sync error message = %s", error->message); + g_error_free(error); + } + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + *gdbus_connection = conn; + } + + LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection)); + if (*server_watcher_id == 0) { + *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + GESTURE_DBUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + _server_appeared_cb, + _server_vanished_cb, + NULL, NULL); + } + + LOGD("server_watcher_id : %d", *server_watcher_id); + if (*server_watcher_id == 0) { + LOGE("Failed to get identifier"); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + + return HAND_GESTURE_ERROR_NONE; +} + + +static void _handle_gesture_cb(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name); + hand_gesture_h _handle = (hand_gesture_h)user_data; + + if (_handle == NULL) { + LOGE("handle is not available"); + return; + } + + if (parameters == NULL) { + LOGE("failed to get gesture info"); + return; + } + + if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_RESULT) == 0) { + LOGD("[GESTURE_CLIENT_SIGNAL_GET_RESULT] called"); + int event; + int gesture_type; + int ltype; + int levent; + int lcount; + g_variant_get(parameters, "(iiiii)", &event, &gesture_type, <ype, &levent, &lcount); +#if 0 + char *printmsg = g_variant_print(parameters, true); + LOGD("start parameter print : %s", printmsg); + g_free(printmsg); + LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount); +#endif + if (g_gesture_data == NULL){ + LOGD("Can't send the result to Client because g_gesture_data is NULL"); + return; + } + LOGD("address = %p", g_gesture_data); + g_gesture_data->gesture_type = ltype; + g_gesture_data->event = levent; + g_gesture_data->detected_Count = lcount; + + g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data); + } + else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ERROR) == 0) { + + } + else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS) == 0) { + + } + else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO) == 0) { + g_variant_get(parameters, "(ss)", &g_engine_app_id, &g_engine_name); +#if 1 + char *printmsg = g_variant_print(parameters, true); + LOGD("[engineInfo]start parameter print : %s", printmsg); + g_free(printmsg); + LOGE("[engineInfo][g_engine_app_id = %s] [g_engine_name = %s]", g_engine_app_id, g_engine_name); +#endif + + } +} + +static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data) +{ + int ret = HAND_GESTURE_ERROR_NONE; + if (*monitor_id == 0) { + int id = 0; + if (lib == GESTURE_CLIENT_LIB_GESTURE) { + id = g_dbus_connection_signal_subscribe(gdbus_connection, + GESTURE_DBUS_NAME, + GESTURE_CLIENT_INTERFACE_NAME, + NULL, + GESTURE_OBJECT_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _handle_gesture_cb, + data, + NULL); + } else if (lib == GESTURE_CLIENT_LIB_ENGINE) { + LOGD("Fail to come for ENGINE lib"); + } else { + LOGD("Fail to Not CLIENT lib"); + } + + LOGD("id : %d", id); + if (id == 0) { + ret = HAND_GESTURE_ERROR_OPERATION_FAILED; + LOGE("g_dbus_connection_signal_subscribe() failed"); + } else { + *monitor_id = id; + } + } + + return ret; +} + +static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd) +{ + LOGD("gdbus_make_message : cmd = %s", cmd); + GDBusMessage *message = NULL; + message = g_dbus_message_new_method_call( + GESTURE_DBUS_NAME, + GESTURE_OBJECT_PATH, + GESTURE_INTERFACE_NAME, + cmd); + + if (!message) { + LOGE("Failed to create a new gdbus message"); + if (body) + g_variant_unref(body); + return NULL; + } + + if (body != NULL) + g_dbus_message_set_body(message, body); + + return message; +} + +static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd) +{ + LOGD("_send_message_with_sync : cmd = %s", cmd); + int ret = HAND_GESTURE_ERROR_NONE; + GError *err = NULL; + + gchar *printmsg = g_dbus_message_print (msg, 1); + LOGD("[sync] before send to server, print : %s", printmsg); + g_free(printmsg); + + *reply = g_dbus_connection_send_message_with_reply_sync( + gdbus_connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + &err); + + if (!*reply) { + ret = HAND_GESTURE_ERROR_OPERATION_FAILED; + if (err != NULL) { + LOGE("Error occurred when sending message(%s) : %s", cmd, err->message); + if (err->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = HAND_GESTURE_ERROR_PERMISSION_DENIED; + g_error_free(err); + } + return ret; + } + + if (g_dbus_message_to_gerror(*reply, &err)) { + LOGE("error message = %s, code = %d", err->message, err->code); + if (err->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = HAND_GESTURE_ERROR_PERMISSION_DENIED; + else + ret = err->code; + g_error_free(err); + return ret; + } +#if 0 + printmsg = g_dbus_message_print (*reply, 1); + LOGD("[sync] reply from server, print : %s", printmsg); + g_free(printmsg); + + GVariant *result = NULL; + result = g_dbus_message_get_body(*reply); + if (result != NULL) { + printmsg = g_variant_print(result, true); + LOGD("Result msg print : %s", printmsg); + g_free(printmsg); + } +#endif + return HAND_GESTURE_ERROR_NONE; +} + +static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd) +{ + LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd); + + int ret = HAND_GESTURE_ERROR_NONE; + GDBusMessage *msg = NULL; + + msg = gdbus_make_message(body, cmd); + if (msg == NULL) + return HAND_GESTURE_ERROR_OPERATION_FAILED; + + ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd); + + if (msg) + g_object_unref(msg); + + return ret; +} + +static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data) +{ + LOGD("_async_cb start"); + GDBusMessage *reply = NULL; + GError *err = NULL; +// hand_gesture_data_h gesturedata = (hand_gesture_data_h)user_data; + + reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err); + if (reply) { + if (g_dbus_message_to_gerror(reply, &err)) { + LOGE("error message = %s, code = %d", err->message, err->code); + g_error_free(err); + return; + } +#if 0 + GVariant *result = g_dbus_message_get_body(reply); + gchar *printmsg = g_variant_print (result, true); + LOGD("[async] _async_cb, print : %s", printmsg); + g_free(printmsg); +#endif + + } else { + LOGE("There is no reply"); + return; + } + + if (reply) + g_object_unref(reply); + + return; +} + +static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd, hand_gesture_data_h gesture_data) +{ + LOGD("gdbus_send_message_with_async start : cmd = %s", cmd); + int ret = HAND_GESTURE_ERROR_NONE; + GDBusMessage *msg = NULL; + + msg = gdbus_make_message(body, cmd); + if (msg == NULL) + return HAND_GESTURE_ERROR_OPERATION_FAILED; + + g_dbus_connection_send_message_with_reply( + gdbus_connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + (GAsyncReadyCallback)_async_cb, + gesture_data); + + if (msg) + g_object_unref(msg); + + return ret; +} + +static int _monitor_register(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *client_body = NULL; + + char appid[1024] = {0, }; + ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)); + if (ret != 0) { + LOGE("aul_app_get_appid_bypid() failed : %d", ret); + } + + client_body = g_variant_new("(iis)", 11, GESTURE_CLIENT_LIB_GESTURE, appid); + + ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER); + if (reply) + g_object_unref(reply); + + if (client_body) + g_variant_unref(client_body); + + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("gdbus_send_message_with_sync() failed : %d", ret); + return ret; + } + + is_server_started = 1; + return ret; +} + +static void _on_name_appeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + if (is_server_started == 0) + _monitor_register(connection); +} + +static void _on_name_vanished(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + is_server_started = 0; +} + +int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, + int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data) +{ + LOGD("gesture_client_dbus_init start"); + + int ret; + + ret = _dbus_init(gdbus_connection, server_watcher_id); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("_dbus_init() failed : %d", ret); + return ret; + } + + ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("_dbus_signal_init() failed : %d", ret); + return ret; + } + + ret = _monitor_register(*gdbus_connection); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("_monitor_register() failed : %d", ret); + return ret; + } + + if (*server_monitor_id == 0) { + *server_monitor_id = g_bus_watch_name_on_connection( + *gdbus_connection, + GESTURE_DBUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + _on_name_appeared, + _on_name_vanished, + NULL, + NULL); + if (*server_monitor_id == 0) { + g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id); + *monitor_id = 0; + LOGE("Failed to get identifier"); + return HAND_GESTURE_ERROR_OPERATION_FAILED; + } + } + + return HAND_GESTURE_ERROR_NONE; +} + +int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id) +{ + if (*server_monitor_id) { + g_bus_unwatch_name(*server_monitor_id); + *server_monitor_id = 0; + } + + if (*monitor_id) { + g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id); + *monitor_id = 0; + } + + return HAND_GESTURE_ERROR_NONE; +} + +int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_INITIALIZE_ENGINE); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to initialize"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to deinitialize"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_set_handtype(GDBusConnection *gdbus_connection, hand_gesture_handtype_e hand_type) +{ + int ret = HAND_GESTURE_ERROR_NONE; + if (hand_type > HAND_GESTURE_RIGHT_HAND || hand_type < HAND_GESTURE_NO_SELECTED_HAND) { + LOGE("Invalid Parmeter"); + return HAND_GESTURE_ERROR_INVALID_PARAMETER; + } + g_hand_type = hand_type; + + return ret; +} + +int gesture_client_dbus_set_workmode(GDBusConnection *gdbus_connection, hand_gesture_workmode_e work_mode) +{ + int ret = HAND_GESTURE_ERROR_NONE; + if (work_mode > HAND_GESTURE_WORK_MODE_UNDEFINED || work_mode < HAND_GESTURE_WORK_MODE_ONE_WAY) { + LOGE("Invalid Parmeter"); + return HAND_GESTURE_ERROR_INVALID_PARAMETER; + } + g_work_mode = work_mode; + + return ret; +} + +int gesture_client_dbus_set_option(GDBusConnection *gdbus_connection, hand_gesture_option_e option) +{ + int ret = HAND_GESTURE_ERROR_NONE; + if (option > HAND_GESTURE_OPTION_ALWAYS_ON || option < HAND_GESTURE_OPTION_DEFAULT) { + LOGE("Invalid Parmeter"); + return HAND_GESTURE_ERROR_INVALID_PARAMETER; + } + g_option = option; + + return ret; +} + +int gesture_client_dbus_set_sensitivity(GDBusConnection *gdbus_connection, int sensitivity) +{ + int ret = HAND_GESTURE_ERROR_NONE; + g_sensitivity = sensitivity; + + return ret; +} + +int gesture_client_dbus_start_recognition(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture_type, hand_gesture_data_h gesture_data, hand_gesture_recognition_cb callback) +{ + LOGD("gesture_client_dbus_start_recognition start"); + LOGD("client busname: %s", g_dbus_connection_get_unique_name(gdbus_connection)); + g_callback = callback; + g_gesture_data = gesture_data; + + GVariant *body = NULL; + body = g_variant_new("(iiiii)", gesture_type, g_hand_type, g_work_mode, g_option, g_sensitivity); + + gdbus_send_message_with_async(gdbus_connection, body, GESTURE_CLIENT_MSG_START_RECOGNITION, gesture_data); + + if (body) + g_variant_unref(body); + + return HAND_GESTURE_ERROR_NONE; +} + +int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + /* free for gesture data struct */ + _free_gesture_data(g_gesture_data); + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_STOP_RECOGNITION); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to stop gesture"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to foreach_result_time"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to foreach_supported_type"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to is_supported_gesture_type"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; + +} + +int gesture_client_dbus_engine_get_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name) +{ + int ret; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + g_engine_app_id = *engine_app_id; + g_engine_name = *engine_name; + + body = g_variant_new("()"); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_ENGINE_GET_INFO); + if (ret != HAND_GESTURE_ERROR_NONE) + LOGE("failed to engine_get_info"); + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; +} + diff --git a/client/gesture_client_dbus.h b/client/gesture_client_dbus.h new file mode 100644 index 0000000..fde91b3 --- /dev/null +++ b/client/gesture_client_dbus.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_DBUS_H__ +#define __TIZEN_UIX_GESTURE_DBUS_H__ + +#include +#include +#include +#include +#include +#include "gesture_defs.h" +#include "gesture_data_info.h" +#include "gesture_main.h" +#include "gesture_common_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data); +int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id); +int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection); +int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection); + +int gesture_client_dbus_set_handtype(GDBusConnection *gdbus_connection, hand_gesture_handtype_e hand_type); +int gesture_client_dbus_set_workmode(GDBusConnection *gdbus_connection, hand_gesture_workmode_e work_mode); +int gesture_client_dbus_set_option(GDBusConnection *gdbus_connection, hand_gesture_option_e option); +int gesture_client_dbus_set_sensitivity(GDBusConnection *gdbus_connection, int sensitivity); +int gesture_client_dbus_start_recognition(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture_type, hand_gesture_data_h gesture_data, hand_gesture_recognition_cb callback); +int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection); +int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection); +int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection); +int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported); +int gesture_client_dbus_engine_get_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_DBUS_H__ */ diff --git a/client/gesture_main.h b/client/gesture_main.h new file mode 100644 index 0000000..3cbe67e --- /dev/null +++ b/client/gesture_main.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_MAIN_H__ +#define __TIZEN_UIX_GESTURE_MAIN_H__ + +#include +#include +#include "gesture.h" +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct hand_gesture_s { + GDBusConnection *gdbus_connection; + guint server_watcher_id; + int monitor_id; + int server_monitor_id; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_MAIN_H__ */ diff --git a/doc/gesture_recognition_doc.h b/doc/gesture_recognition_doc.h deleted file mode 100644 index 5a3191d..0000000 --- a/doc/gesture_recognition_doc.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * gesture - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * 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. - * - */ - -/** - * @ingroup CAPI_GESTURE_FRAMEWORK - * @defgroup CAPI_GESTURE_MODULE Gesture Recognition - * - * @brief The gesture recognition API allows applications to be notified and - * react when the user performs a gesture. - * - * @section CAPI_GESTURE_MODULE_HEADER Required Header - * \#include - * - * @section CAPI_GESTURE_MODULE_OVERVIEW Overview - * - * - * The gesture recognition API allows to register callback functions to be called - * when the user performs meaningful gestures listed in #gesture_type_e, for example, - * shaking the device. - * - * Regardless of the gesture types, - * the overall process of using the gesture recognition API is as follows. - * - * If necessary, applications can check whether a gesture type is supported in the current device in advance. - * Note that, some gestures may not be supported in some devices, if the devices do not have necessary sensors. - - \code - bool supported = false; - gesture_is_supported(GESTURE_SHAKE, &supported); - - if (!supported) { - // Not supported in the current device. - } - \endcode - - * If the gesture type is supported, to use the recognition engine, - * an @c handle for the gesture recognition needs to be initialized first. - - \code - gesture_h handle; - - result = gesture_create(&handle); - - if (result != GESTURE_ERROR_NONE) { - // An error occurred. - } - \endcode - - * With the @c handle initialized, a callback function, - * which will be called when a specified gesture is detected, - * is registered by using gesture_start_recognition(). - - \code - result = gesture_start_recognition(handle, GESTURE_SHAKE, GESTURE_OPTION_DEFAULT, gesture_cb, NULL); - - if (result != GESTURE_ERROR_NONE) { - // An error occurred. Do necessary error handling here. - } - \endcode - - * Then the callback function @c gesture_cb will be called whenever the shake gesture is detected. - * - * Note that, calling gesture_start_recognition() twice on the same handle returns #GESTURE_ERROR_ALREADY_STARTED. - * If it needs to recognize another gesture using the same handle, - * the started recognition session should be stopped and restarted with the new gesture type. - * Otherwise, the application needs to created multiple handles, one handle for each gesture needed. - * - * An example callback function is as follows. - - \code - void gesture_cb(gesture_type_e type, const gesture_data_h data, double timestamp, gesture_error_e error, void *user_data) - { - int result; - gesture_event_e event; - - if (error != GESTURE_ERROR_NONE) { - // An error occurred. Do necessary error handling here. - return; - } - - if (type == GESTURE_SHAKE) { - // More than one gestures can be started using the same callback function. - - result = gesture_get_event(data, &event); - - if (result != GESTURE_ERROR_NONE) { - // An error occurred. Do necessary error handling here. - return; - } - - if (event == GESTURE_SHAKE_DETECTED) { - // Shake gesture is started - - } else if (event == GESTURE_SHAKE_FINISHED) { - // Shake gesture is stopped - } - } - } - \endcode - - * As we started gesture recognition with #GESTURE_SHAKE, - * gesture_get_event() returns either #GESTURE_SHAKE_DETECTED or #GESTURE_SHAKE_FINISHED - * as it has two different states, the gesture is started, or finished. - * Most of the gesture types, however, simply provide #GESTURE_EVENT_DETECTED. - * In such cases, #GESTURE_EVENT_NONE may not be delivered at all. - * - * If #GESTURE_TILT is started, within the callback function, - * gesture_get_tilt() can be used to extract the tilting degrees. - * - * Finally, if the application does not need to be notified the gesture event, - * it can be stopped as follows. - - \code - gesture_stop_recognition(handle); - - // If the handle will not be used anymore, its resources needs be released explicitly. - gesture_release(handle); - \endcode - - * @section CAPI_GESTURE_MODULE_FEATURE Related Features - * This API is related with the following features:\n - * - http://tizen.org/feature/sensor.gesture_recognition\n - * - http://tizen.org/feature/sensor.wrist_up - * - * It is recommended to design feature related code in your application for reliability.\n - * - * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n - * - * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n - * - * More details on featuring your application can be found from Feature Element. - * - */ diff --git a/doc/uix_gesture_doc.h b/doc/uix_gesture_doc.h new file mode 100644 index 0000000..7def9e3 --- /dev/null +++ b/doc/uix_gesture_doc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_DOC_H__ +#define __TIZEN_UIX_GESTURE_DOC_H__ + + +/** + * @ingroup CAPI_UIX_FRAMEWORK + * @defgroup CAPI_UIX_GESTURE_MODULE Gesture + * @brief The @ref CAPI_UIX_GESTURE_MODULE API provides functions for recognizing hand gestures from input sensor data. + * @section CAPI_UIX_GESTURE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_UIX_GESTURE_MODULE_OVERVIEW Overview + * You can use Gesture API to recognize a user's hand movement. + * Applications can start and stop recognizing hand gestures and receive the corresponding results with the registered callback function. + * To use Gesture, follow these steps:
+ * 1. Create a handle
+ * 2. Set options such as a hand type, a work mode, and other options necessary to recognize hand gestures
+ * 3. Start recognizing hand gestures
+ * 4. Stop recognizing
+ * 5. Destroy a handle
+ * The Gesture API also notifies you (by callback mechanism) when the input gesture is recognized. + * An application should register a callback function to receive the recognized results with gesture_client_start_recognition(). + * + * @section CAPI_UIX_GESTURE_MODULE_FEATURE Related Features + * This API is related with the following features:
+ * - http://tizen.org/feature/sensor.accelerometer
+ * - http://tizen.org/feature/sensor.gesture_recognition
+ * - http://tizen.org/feature/sensor.gyroscope
+ * It is recommended to design feature related codes in your application for reliability.
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
+ * More details on featuring your application can be found from Feature Element. + */ + + +#endif /* __TIZEN_UIX_GESTURE_DOC_H__ */ diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt new file mode 100644 index 0000000..5101b3e --- /dev/null +++ b/engine/CMakeLists.txt @@ -0,0 +1,22 @@ +SET(SRCS + gesture_engine.c + gesture_engine_dbus.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +## Add definitions ## +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") + +## gesture engine library ## +ADD_LIBRARY(${PROJECT_NAME}-engine SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME}-engine ${pkgs_LDFLAGS}) + +## Install library files ## +INSTALL(TARGETS ${PROJECT_NAME}-engine DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries) diff --git a/engine/gesture_engine.c b/engine/gesture_engine.c new file mode 100644 index 0000000..29f230d --- /dev/null +++ b/engine/gesture_engine.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include +#include +#include + +#include "gesture_engine.h" +#include "gesture_engine_main.h" +#include "gesture_engine_dbus.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURE_ENGINE" + +EXPORT_API int gesture_engine_connect(gesture_engine_h *engine_handle) +{ + LOGD("gesture_engine_connect start"); + CHECK_GESTURE_FEATURE(); + + int ret; + if (!engine_handle) + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + + struct gesture_engine_s *engine_struct = (gesture_engine_h)calloc(1, sizeof(struct gesture_engine_s)); + + if (!engine_struct) + return GESTURE_ENGINE_ERROR_OUT_OF_MEMORY; + + ret = gesture_engine_dbus_init(&engine_struct->gdbus_connection, &engine_struct->server_watcher_id, + &engine_struct->monitor_id, &engine_struct->server_monitor_id, GESTURE_CLIENT_LIB_ENGINE, (void *)engine_struct); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to initialize dbus : %d", ret); + free(engine_struct); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + *engine_handle = engine_struct; + + return GESTURE_ENGINE_ERROR_NONE; +} + +EXPORT_API int gesture_engine_disconnect(gesture_engine_h engine_handle) +{ + CHECK_GESTURE_FEATURE(); + + int ret; + if (!engine_handle) + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + + ret = gesture_engine_dbus_shutdown(engine_handle->gdbus_connection, &engine_handle->server_monitor_id, &engine_handle->monitor_id); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to finalize dbus : %d", ret); + free(engine_handle); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + if (engine_handle->gdbus_connection) + g_object_unref(engine_handle->gdbus_connection); + + free(engine_handle); + + return GESTURE_ENGINE_ERROR_NONE; +} + +EXPORT_API int gesture_engine_main(int argc, char** argv, gesture_engine_h engine_handle, gesture_engine_request_callback_s *callback) +{ + LOGD("gesture_engine_main start"); + + CHECK_GESTURE_FEATURE(); + + if (!callback) { + LOGE("basic engine callbacks pointer is null."); + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + } + + int ret = GESTURE_ENGINE_ERROR_NONE; + + ret = gesture_engine_dbus_main_start(engine_handle->gdbus_connection, callback); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to start engine main : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + return 0; +} + +EXPORT_API int gesture_engine_send_result(gesture_engine_h engine_handle, gesture_engine_result_event_e event, hand_gesture_type_e gesture_type, hand_gesture_data_h result, void* time_info, void* user_data) +{ + LOGD("gesture_engine_send_result start"); + LOGD("gesture type = %d", gesture_type); + + CHECK_GESTURE_FEATURE(); + + if (!engine_handle) { + LOGE("invalid parameter : engine_handle"); + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + } + + int ret = GESTURE_ENGINE_ERROR_NONE; + + ret = gesture_engine_dbus_send_result(engine_handle->gdbus_connection, event, gesture_type, result, time_info, user_data); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to send result : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + return ret; +} + +EXPORT_API int gesture_engine_send_error(gesture_engine_h engine_handle, gesture_engine_error_e error, const char* msg) +{ + LOGD("gesture_engine_send_error start"); + LOGD("error type = %d", error); + LOGD("msg = %s", msg); + + CHECK_GESTURE_FEATURE(); + + if (!engine_handle) { + LOGE("invalid parameter : engine_handle"); + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + } + + int ret = GESTURE_ENGINE_ERROR_NONE; + + ret = gesture_engine_dbus_send_error(engine_handle->gdbus_connection, error, msg); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to send result : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + return 0; +} + +EXPORT_API int gesture_engine_send_motion_status(gesture_engine_h engine_handle, gesture_engine_motion_status_e status, void* user_data) +{ + LOGD("gesture_engine_send_motion_status start"); + LOGD("motion status = %d", status); + + CHECK_GESTURE_FEATURE(); + + if (!engine_handle) { + LOGE("invalid parameter : engine_handle"); + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + } + + int ret = GESTURE_ENGINE_ERROR_NONE; + + ret = gesture_engine_dbus_send_motion_status(engine_handle->gdbus_connection, status, user_data); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to send motion status : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + return 0; +} + +EXPORT_API int gesture_engine_set_private_data_set_cb(gesture_engine_h engine_handle, gesture_engine_private_data_set_cb callback_func) +{ + return 0; +} + +EXPORT_API int gesture_engine_set_private_data_requested_cb(gesture_engine_h engine_handle, gesture_engine_private_data_requested_cb callback_func) +{ + return 0; +} + +EXPORT_API int gesture_engine_send_engine_get_info(gesture_engine_h engine_handle, char* engine_app_id, char* engine_name) +{ + LOGD("gesture engine_app_id = %s", engine_app_id); + + CHECK_GESTURE_FEATURE(); + + if (!engine_handle) { + LOGE("invalid parameter : engine_handle"); + return GESTURE_ENGINE_ERROR_INVALID_PARAMETER; + } + + int ret = GESTURE_ENGINE_ERROR_NONE; + + ret = gesture_engine_dbus_send_engine_get_info(engine_handle->gdbus_connection, engine_app_id, engine_name); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Failed to send result : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + return ret; +} + diff --git a/engine/gesture_engine_dbus.c b/engine/gesture_engine_dbus.c new file mode 100644 index 0000000..f9d6199 --- /dev/null +++ b/engine/gesture_engine_dbus.c @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2020 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 +#include + +#include "gesture_engine_dbus.h" +#include "gesture_engine_main.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURE_ENGINE_DBUS" + +static int is_server_started = 0; +static gesture_engine_request_callback_s g_basic_engine_callback; +static GDBusConnection *mgdbus_connection; + +static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) +{ + LOGD("name : %s, name_owner : %s", name, name_owner); +} + +static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + LOGD("name : %s", name); +} + +static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id) +{ + GError *error = NULL; + + if (*gdbus_connection == NULL) { + GDBusConnection *conn = NULL; + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (conn == NULL) { + if (error != NULL) { + LOGE("g_bus_get_sync error message = %s", error->message); + g_error_free(error); + } + return GESTURE_ENGINE_ERROR_IO_ERROR; + } + *gdbus_connection = conn; + } + + LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection)); + if (*server_watcher_id == 0) { + *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + GESTURE_DBUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + _server_appeared_cb, + _server_vanished_cb, + NULL, NULL); + } + + LOGD("server_watcher_id : %d", *server_watcher_id); + if (*server_watcher_id == 0) { + LOGE("Failed to get identifier"); + return GESTURE_ENGINE_ERROR_IO_ERROR; + } + + return GESTURE_ENGINE_ERROR_NONE; +} + +// callback the result data that received from engine service app. +// will pass this data to daemon +static void gesture_cb(hand_gesture_type_e gesture, const hand_gesture_data_h data, double timestamp, gesture_engine_error_e error, void *user_data) +{ + if(!data) { + LOGE("gesture cb data is NULL"); + return; + } + LOGD("gesture cb >> hand_gesture_type_e : %d", gesture); + LOGD("own_name : %s", g_dbus_connection_get_unique_name(mgdbus_connection)); + gesture_engine_dbus_send_result(mgdbus_connection, GESTURE_ENGINE_RESULT_EVENT_FINAL_RESULT, gesture, data, NULL, user_data); +} + +// called when daemon calls engine with g_dbus_connection_emit_signal. +// must send signal to the engine service app. +static void _handle_gesture_engine_cb(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ +#if 0 + LOGD("own_name : %s, sender_name : %s", g_dbus_connection_get_unique_name(connection), sender_name); + LOGD("object_path : %s, interface_name : %s", object_path, interface_name); + LOGD("signal_name : %s", signal_name); + char *printmsg = g_variant_print(parameters, true); + LOGD("_handle_gesture_engine_cb parameter print : %s", printmsg); + g_free(printmsg); +#endif + gesture_engine_h engine_handle = (gesture_engine_h)user_data; + + if (engine_handle == NULL) { + LOGE("engine handle is not available"); + return; + } + + if (parameters == NULL) { + LOGE("failed to get gesture info"); + return; + } + + if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_INITIALIZE) == 0) { + LOGD("[engine_initialize] called"); + g_basic_engine_callback.initialize(); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_DEINITIALIZE) == 0) { + LOGD("[engine_deinitialize] called"); + g_basic_engine_callback.deinitialize(); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_START) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_START] called"); + int gesture_type = 1; + int hand_type = 2; + int work_mode = 2; + int option = 1; + int sensitivity = 1; + g_variant_get(parameters, "(iiiii)", &gesture_type, &hand_type, &work_mode, &option, &sensitivity); + g_basic_engine_callback.start(gesture_type, hand_type, work_mode, option, sensitivity, gesture_cb, NULL); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_STOP) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_STOP] called"); + g_basic_engine_callback.stop(); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME] called"); + g_basic_engine_callback.foreach_result_time(NULL, NULL, NULL); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE] called"); + g_basic_engine_callback.foreach_types(NULL, NULL); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE] called"); + int gesture_type = 1; + bool isSupported = false; + g_variant_get(parameters, "(i)", &gesture_type); + g_basic_engine_callback.is_support_gesture_type(gesture_type, &isSupported); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO] called"); + char *engine_app_id; + char *engine_name; + g_basic_engine_callback.get_info(&engine_app_id, &engine_name); + } +} + +static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data) +{ + int ret = GESTURE_ENGINE_ERROR_NONE; + if (*monitor_id == 0) { + int id = 0; + if (lib == GESTURE_CLIENT_LIB_GESTURE) + LOGD("Fail to come for CLIENT lib"); + else if (lib == GESTURE_CLIENT_LIB_ENGINE) + id = g_dbus_connection_signal_subscribe(gdbus_connection, + GESTURE_DBUS_NAME, + GESTURE_ENGINE_INTERFACE_NAME, + NULL, + GESTURE_OBJECT_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _handle_gesture_engine_cb, + data, + NULL); + else + LOGD("Fail to Not come for Engine Lib"); + + LOGD("id : %d", id); + if (id == 0) { + ret = GESTURE_ENGINE_ERROR_IO_ERROR; + LOGE("g_dbus_connection_signal_subscribe() failed"); + } else { + *monitor_id = id; + } + } + + return ret; +} + +static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd) +{ + LOGD("gdbus_make_message : cmd = %s", cmd); + GDBusMessage *message = NULL; + message = g_dbus_message_new_method_call( + GESTURE_DBUS_NAME, + GESTURE_OBJECT_PATH, + GESTURE_INTERFACE_NAME, + cmd); + + if (!message) { + LOGE("Failed to create a new gdbus message"); + if (body) + g_variant_unref(body); + return NULL; + } + + if (body != NULL) + g_dbus_message_set_body(message, body); + + return message; +} + +static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd) +{ + LOGD("_send_message_with_sync : cmd = %s", cmd); + int ret = GESTURE_ENGINE_ERROR_NONE; + GError *err = NULL; + + gchar *printmsg = g_dbus_message_print (msg, 1); + LOGD("[sync] before send to server, print : %s", printmsg); + g_free(printmsg); + + *reply = g_dbus_connection_send_message_with_reply_sync( + gdbus_connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + &err); + + if (!*reply) { + ret = GESTURE_ENGINE_ERROR_SERVICE_NOT_READY; + if (err != NULL) { + LOGE("Error occurred when sending message(%s) : %s", cmd, err->message); + if (err->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = GESTURE_ENGINE_ERROR_PERMISSION_DENIED; + g_error_free(err); + } + return ret; + } + + if (g_dbus_message_to_gerror(*reply, &err)) { + LOGE("error message = %s, code = %d", err->message, err->code); + if (err->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = GESTURE_ENGINE_ERROR_PERMISSION_DENIED; + else + ret = err->code; + g_error_free(err); + return ret; + } +#if 0 + printmsg = g_dbus_message_print (*reply, 1); + LOGD("[sync] reply from server, print : %s", printmsg); + g_free(printmsg); + + GVariant *result = NULL; + result = g_dbus_message_get_body(*reply); + if (result != NULL) { + printmsg = g_variant_print(result, true); + LOGD("Result msg print : %s", printmsg); + g_free(printmsg); + } +#endif + return GESTURE_ENGINE_ERROR_NONE; +} + +static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd) +{ + LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd); + + int ret = GESTURE_ENGINE_ERROR_NONE; + GDBusMessage *msg = NULL; + + msg = gdbus_make_message(body, cmd); + if (msg == NULL) + return GESTURE_ENGINE_ERROR_IO_ERROR; + + ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd); + + if (msg) + g_object_unref(msg); + + return ret; +} + +static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data) +{ + LOGD("_async_cb start"); + GDBusMessage *reply = NULL; + GError *err = NULL; + + reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err); + if (reply) { + if (g_dbus_message_to_gerror(reply, &err)) { + LOGE("error message = %s, code = %d", err->message, err->code); + g_error_free(err); + return; + } +#if 1 + GVariant *result = g_dbus_message_get_body(reply); + if (result) { + gchar *printmsg = g_variant_print (result, true); + LOGD("[async] _async_cb, print : %s", printmsg); + g_free(printmsg); + } else { + LOGD("[async] result is null"); + } +#endif + + } else { + LOGE("There is no reply"); + return; + } + + if (reply) + g_object_unref(reply); + + return; +} + +static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd) +{ + LOGD("gdbus_send_message_with_async start : cmd = %s", cmd); + int ret = GESTURE_ENGINE_ERROR_NONE; + GDBusMessage *msg = NULL; + + msg = gdbus_make_message(body, cmd); + if (msg == NULL) + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + + g_dbus_connection_send_message_with_reply( + gdbus_connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, + NULL, + (GAsyncReadyCallback)_async_cb, + NULL); + + if (msg) + g_object_unref(msg); + + return ret; +} + +static int _monitor_register(GDBusConnection *gdbus_connection) +{ + int ret = GESTURE_ENGINE_ERROR_NONE; + GDBusMessage *reply = NULL; + GVariant *engine_body = NULL; + + char appid[1024] = {0, }; + ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)); + if (ret != 0) { + LOGE("aul_app_get_appid_bypid() failed : %d", ret); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + engine_body = g_variant_new("(iis)", 22, GESTURE_CLIENT_LIB_ENGINE, appid); + + ret = gdbus_send_message_with_sync(gdbus_connection, engine_body, &reply, GESTURE_MSG_SERVICE_REGISTER); + if (reply) + g_object_unref(reply); + + if (engine_body) + g_variant_unref(engine_body); + + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("gdbus_send_message_with_sync() failed : %d", ret); + return ret; + } + + is_server_started = 1; + return ret; +} + +static void _on_name_appeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + if (is_server_started == 0) + _monitor_register(connection); +} + +static void _on_name_vanished(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + is_server_started = 0; +} + +int gesture_engine_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, + int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data) +{ + LOGD("gesture_dbus_init start"); + + int ret; + + ret = _dbus_init(gdbus_connection, server_watcher_id); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("_dbus_init() failed : %d", ret); + return ret; + } + + ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("_dbus_signal_init() failed : %d", ret); + return ret; + } + + ret = _monitor_register(*gdbus_connection); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("_monitor_register() failed : %d", ret); + return ret; + } + + if (*server_monitor_id == 0) { + *server_monitor_id = g_bus_watch_name_on_connection( + *gdbus_connection, + GESTURE_DBUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + _on_name_appeared, + _on_name_vanished, + NULL, + NULL); + if (*server_monitor_id == 0) { + g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id); + *monitor_id = 0; + LOGE("Failed to get identifier"); + return GESTURE_ENGINE_ERROR_IO_ERROR; + } + } + + return GESTURE_ENGINE_ERROR_NONE; +} + +int gesture_engine_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id) +{ + if (*server_monitor_id) { + g_bus_unwatch_name(*server_monitor_id); + *server_monitor_id = 0; + } + + if (*monitor_id) { + g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id); + *monitor_id = 0; + } + + return GESTURE_ENGINE_ERROR_NONE; +} +#if 0 +static void proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + LOGD("proxy_new_cb clled"); + + GDBusProxy **ret = user_data; + GError *error = NULL; + *ret = g_dbus_proxy_new_finish (res, &error); +} +#endif + +int gesture_engine_dbus_main_start(GDBusConnection *gdbus_connection, gesture_engine_request_callback_s *callback) +{ + LOGD("gesture_engine_dbus_main_start start"); + LOGD("engine busname: %s", g_dbus_connection_get_unique_name(gdbus_connection)); + mgdbus_connection = gdbus_connection; + + int ret = GESTURE_ENGINE_ERROR_NONE; + + // store engine callback sturct; + g_basic_engine_callback = *callback; + + GVariant *body = NULL; + body = g_variant_new("(i)", 100); + + ret = gdbus_send_message_with_async(gdbus_connection, body, GESTURE_ENGINE_MSG_MAIN_START); +#if 0 + GError *err = NULL; + if (!g_dbus_connection_emit_signal(gdbus_connection, + GESTURE_DBUS_NAME, + GESTURE_OBJECT_PATH, + GESTURE_INTERFACE_NAME, + "psw_test", + body, + &err)) { + if (err != NULL) { + LOGE("Failed to send dbus message : %s", err->message); + g_error_free(err); + } + + return GESTURE_ENGINE_ERROR_NONE; + } + + GDBusProxy *ap; + g_dbus_proxy_new (gdbus_connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + GESTURE_DBUS_NAME, /* name */ + GESTURE_OBJECT_PATH, /* object path */ + GESTURE_INTERFACE_NAME, /* interface name */ + NULL, /* GCancellable */ + (GAsyncReadyCallback) proxy_new_cb, + &ap); +#endif + if (body) + g_variant_unref(body); + + return ret; +} + +int gesture_engine_dbus_send_result(GDBusConnection *gdbus_connection, gesture_engine_result_event_e event, hand_gesture_type_e gesture_type, hand_gesture_data_h result, void* time_info, void* user_data) +{ + LOGD("gesture_engine_dbus_send_result start"); + if (gesture_type) LOGD("gesture_type = %d", gesture_type); + + int ret = GESTURE_ENGINE_ERROR_NONE; + + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + if(!result) { + LOGD("The returned hand_gesture_data_h is NULL"); + return GESTURE_ENGINE_ERROR_OPERATION_FAILED; + } + + body = g_variant_new("(iiiii)", event, gesture_type, result->gesture_type, result->event, result->detected_Count); + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_RESULT); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGD("Fail to send result data to daemon"); + } +#if 0 + gchar *msg = g_dbus_message_print (reply, 1); + LOGD("Reply msg print : %s", msg); + g_free(msg); +#endif + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; +} + +int gesture_engine_dbus_send_error(GDBusConnection *gdbus_connection, gesture_engine_error_e error, const char* msg) +{ + LOGE("gesture_engine_dbus_send_error start"); + + int ret = GESTURE_ENGINE_ERROR_NONE; + + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("(is)", error, msg); + + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_ERROR); + + if (ret == GESTURE_ENGINE_ERROR_NONE) { + gchar *msg = g_dbus_message_print (reply, 1); + LOGD("Reply msg print : %s", msg); + g_free(msg); + } + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; +} + +int gesture_engine_dbus_send_motion_status(GDBusConnection *gdbus_connection, gesture_engine_motion_status_e status, void* user_data) +{ + LOGE("gesture_engine_dbus_send_motion_status start"); + + int ret = GESTURE_ENGINE_ERROR_NONE; + + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("(i)", status); + + ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_MOTION_STATUS); + + if (ret == GESTURE_ENGINE_ERROR_NONE) { + gchar *msg = g_dbus_message_print (reply, 1); + LOGD("Reply msg print : %s", msg); + g_free(msg); + } + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; +} + +int gesture_engine_dbus_send_engine_get_info(GDBusConnection *gdbus_connection, char* engine_app_id, char* engine_name) +{ + LOGD("gesture_engine_send_engine_get_info start"); + if (engine_app_id) LOGD("engine_app_id = %s", engine_app_id); + + int ret = GESTURE_ENGINE_ERROR_NONE; + + GDBusMessage *reply = NULL; + GVariant *body = NULL; + + body = g_variant_new("(ss)", engine_app_id, engine_name); + ret = gdbus_send_message_with_sync(mgdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO); + if (ret != GESTURE_ENGINE_ERROR_NONE) { + LOGE("Fail to send result data to daemon"); + } +#if 0 + gchar *msg = g_dbus_message_print (reply, 1); + LOGD("Reply msg print : %s", msg); + g_free(msg); +#endif + + if (body) + g_variant_unref(body); + + if (reply) + g_object_unref(reply); + + return ret; +} + diff --git a/engine/gesture_engine_dbus.h b/engine/gesture_engine_dbus.h new file mode 100644 index 0000000..066112c --- /dev/null +++ b/engine/gesture_engine_dbus.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_DBUS_H__ +#define __TIZEN_UIX_GESTURE_DBUS_H__ + +#include +#include +#include +#include +#include +#include "gesture_defs.h" +#include "gesture_data_info.h" +#include "gesture_engine.h" +#include "gesture_engine_main.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +int gesture_engine_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data); +int gesture_engine_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id); + +/* send to daemon */ +int gesture_engine_dbus_main_start(GDBusConnection *gdbus_connection, gesture_engine_request_callback_s *callback); +int gesture_engine_dbus_send_result(GDBusConnection *gdbus_connection, gesture_engine_result_event_e event, hand_gesture_type_e gesture_type, hand_gesture_data_h result, void* time_info, void* user_data); +int gesture_engine_dbus_send_error(GDBusConnection *gdbus_connection, gesture_engine_error_e error, const char* msg); +int gesture_engine_dbus_send_motion_status(GDBusConnection *gdbus_connection, gesture_engine_motion_status_e status, void* user_data); +int gesture_engine_dbus_send_engine_get_info(GDBusConnection *gdbus_connection, char* engine_app_id, char* engine_name); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_DBUS_H__ */ diff --git a/engine/gesture_engine_main.h b/engine/gesture_engine_main.h new file mode 100644 index 0000000..57f1d89 --- /dev/null +++ b/engine/gesture_engine_main.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_ENGINE_MAIN_H__ +#define __TIZEN_UIX_GESTURE_ENGINE_MAIN_H__ + +#include +#include +//#include "gesture_engine.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct gesture_engine_s { + GDBusConnection *gdbus_connection; + guint server_watcher_id; + int monitor_id; + int server_monitor_id; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_ENGINE_MAIN_H__ */ diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..5969d28 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,13 @@ +## configure pkgconfig files ## +CONFIGURE_FILE(capi-ui-gesture-client.pc.in "${PROJECT_NAME}-client.pc" @ONLY) +CONFIGURE_FILE(capi-ui-gesture-engine.pc.in "${PROJECT_NAME}-engine.pc" @ONLY) + +## Install header, pc files ## +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-client.pc" DESTINATION ${LIBDIR}/pkgconfig) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-engine.pc" DESTINATION ${LIBDIR}/pkgconfig) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture_common.h" DESTINATION ${INCLUDEDIR}) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture_common_internal.h" DESTINATION ${INCLUDEDIR}) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture_data_info.h" DESTINATION ${INCLUDEDIR}) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture.h" DESTINATION ${INCLUDEDIR}) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture_internal.h" DESTINATION ${INCLUDEDIR}) +INSTALL(FILES "${CMAKE_BINARY_DIR}/include/gesture_engine.h" DESTINATION ${INCLUDEDIR}) diff --git a/include/capi-ui-gesture-client.pc.in b/include/capi-ui-gesture-client.pc.in new file mode 100644 index 0000000..0d0bf9c --- /dev/null +++ b/include/capi-ui-gesture-client.pc.in @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: lib@PROJECT_NAME@-client +Description: Gesture Application APIs +Requires: glib-2.0 dbus-1 +Version: @VERSION@ +Libs: -L${libdir} -lcapi-ui-gesture-client +Cflags: -I${includedir} \ No newline at end of file diff --git a/include/capi-ui-gesture-engine.pc.in b/include/capi-ui-gesture-engine.pc.in new file mode 100644 index 0000000..bbb0c99 --- /dev/null +++ b/include/capi-ui-gesture-engine.pc.in @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: lib@PROJECT_NAME@-engine +Description: Gesture engine APIs +Requires: glib-2.0 dbus-1 +Version: @VERSION@ +Libs: -L${libdir} -lcapi-ui-gesture-engine +Cflags: -I${includedir} \ No newline at end of file diff --git a/include/gesture.h b/include/gesture.h new file mode 100644 index 0000000..65ce9a8 --- /dev/null +++ b/include/gesture.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_H__ +#define __TIZEN_UIX_GESTURE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file gesture.h + * @brief This file contains hand gesture's APIs. + */ + +/** + * @addtogroup CAPI_UIX_GESTURE_MODULE + * @{ + */ + +/** + * @brief The hand gesture handle. + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef struct hand_gesture_s *hand_gesture_h; + +/** + * @brief Called when a gesture is detected. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] gesture Gesture type detected + * @param[in] data Detailed information of the detected gesture.@n + * hand_gesture_get_event() or gesture_get_tilt() can be used to extract the information from @c data. + * @param[in] timestamp The time when the gesture is detected. Epoch time in seconds. + * @param[in] error An error value. It can be one of the following error values:@n + * #HAND_GESTURE_ERROR_NONE, if the operation succeeded.@n + * #HAND_GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported in the current profile.@n + * #HAND_GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error.@n + * #HAND_GESTURE_ERROR_PERMISSION_DENIED, if the application has no permission to use this. + * @param[in] user_data The user data had passed to hand_gesture_start_recognition() + * + * @pre hand_gesture_start_recognition() + */ +typedef void(* hand_gesture_recognition_cb)(hand_gesture_type_e gesture, const hand_gesture_data_h data, double timestamp, hand_gesture_error_e error, void *user_data); + +/** + * @brief Checks whether the gesture is supported or not. + * @details Check if the given gesture type is supported in the current device. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle The gesture handle + * @param[in] gesture Gesture type to be checked + * @param[out] supported @c true if the gesture is recognizable in the current device,@n + * @c false otherwise + * + * @return @c 0 if the @c gesture is supported, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Supported + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED The @c gesture is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e gesture, bool* supported); + +/** + * @brief Creates a gesture handle. + * + * @since_tizen @if WEARABLE 6.0 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/appmanager.launch + * @remarks If the function succeeds, @a handle must be released with hand_gesture_destroy(). + * + * @param[out] handle The gesture handle + * + * @return 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Not supported + * @retval #HAND_GESTURE_ERROR_PERMISSION_DENIED Permission denied + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #HAND_GESTURE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed + * @see hand_gesture_destroy() + */ +int hand_gesture_create(hand_gesture_h *handle); + +/** + * @brief Destroys a gesture handle. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle The gesture handle + * + * @return 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed + * @see hand_gesture_create() + */ +int hand_gesture_destroy(hand_gesture_h handle); + +/** + * @brief Sets the option for gesture recognition. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] option Detection option + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_start_recognition() + */ +int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option); + +/** + * @brief Starts to recognize a gesture. + * @details Sets a callback function to be invoked when the gesture is detected, and starts to monitor occurrences of the gesture. + * + * @since_tizen @if WEARABLE 6.0 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/appmanager.launch + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] gesture Gesture type to be monitored + * @param[in] callback Callback function to receive gesture events + * @param[in] user_data User data to be passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_PERMISSION_DENIED Permission denied + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @pre hand_gesture_create() + * @pre hand_gesture_set_option() + * @post hand_gesture_recognition_cb() + * @see hand_gesture_stop_recognition() + */ +int hand_gesture_start_recognition(hand_gesture_h handle, hand_gesture_type_e gesture, hand_gesture_recognition_cb callback, void *user_data); + +/** + * @brief Stops recognizing the gesture registered to the gesture handle. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle Gesture handle to release its callback function registered + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_NOT_STARTED Nothing is started using the @c handle + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int hand_gesture_stop_recognition(hand_gesture_h handle); + +/** + * @brief Gets the gesture engine information. + * + * @since_tizen @if WEARABLE 6.0 @endif + * @remarks The @a engine_app_id and the @a engine_name should be released using free(). + * + * @param[in] handle Gesture handle to release its callback function registered + * @param[out] engine_app_id The gesture engine app ID + * @param[out] engine_name The gesture engine name + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_NOT_STARTED Nothing is started using the @c handle + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_H__ */ diff --git a/include/gesture_common.h b/include/gesture_common.h new file mode 100644 index 0000000..491e5d7 --- /dev/null +++ b/include/gesture_common.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_COMMON_H__ +#define __TIZEN_UIX_GESTURE_COMMON_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TIZEN_ERROR_GESTURE +#define TIZEN_ERROR_GESTURE -0x03090000 +#endif + +/** + * @file gesture_common.h + * @brief This file contains gesture's common struct info. + */ + +/** + * @brief Delivery through hand_gesture_recognition_cb() of gesture data handle. + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef struct hand_gesture_data_s* hand_gesture_data_h; + +/** + * @brief Enumerations for hand gesture function error. + * + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum { + HAND_GESTURE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + HAND_GESTURE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ + HAND_GESTURE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */ + HAND_GESTURE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + HAND_GESTURE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + HAND_GESTURE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + HAND_GESTURE_ERROR_ALREADY_STARTED = TIZEN_ERROR_GESTURE | 0x01, /**< Recognition is already started */ + HAND_GESTURE_ERROR_NOT_STARTED = TIZEN_ERROR_GESTURE | 0x02, /**< Recognition is not started */ + HAND_GESTURE_ERROR_OPERATION_FAILED = TIZEN_ERROR_GESTURE | 0x04, /**< Operation failed because of a system error */ +} hand_gesture_error_e; + +/** + * @brief Enumerations for hand gesture types. + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum { + HAND_GESTURE_NONE = 1, /**< Nothing type */ + HAND_GESTURE_WRIST_UP = 2, /**< The wearable device is moved and faced up */ +} hand_gesture_type_e; + +/** + * @brief Enumerations for gesture recognition option. + * @details If the default option is used, the system tries to reduce power consumption. + * For example, the recognition engine may stop detecting gestures if the display is turned off. + * Using #HAND_GESTURE_OPTION_ALWAYS_ON disables such power-saving functionalities. + * + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum { + HAND_GESTURE_OPTION_DEFAULT = 1, /**< Running in the default setting */ + HAND_GESTURE_OPTION_ALWAYS_ON = 2, /**< Trying to detect gestures always */ +} hand_gesture_option_e; + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_COMMON_H__ */ diff --git a/include/gesture_common_internal.h b/include/gesture_common_internal.h new file mode 100644 index 0000000..6b42c07 --- /dev/null +++ b/include/gesture_common_internal.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_COMMON_INTERNAL_H__ +#define __TIZEN_UIX_GESTURE_COMMON_INTERNAL_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file gesture_common_internal.h + * @brief This file contains gesture's internal common struct info. + */ + +/** + * @brief Enumeration for gesture hand type. + * @details If the HAND_GESTURE_NO_SELECTED_HAND is used, the system will consider with right hand + * + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum { + HAND_GESTURE_NO_SELECTED_HAND = 1, /**< Gesture with hand, no selected hand */ + HAND_GESTURE_LEFT_HAND = 2, /**< Gesture with left hand */ + HAND_GESTURE_RIGHT_HAND = 3, /**< Gesture with right hand */ +} hand_gesture_handtype_e; + +/** + * @brief Enumeration for gesture movement. + * @details Determining whether to move the hand in one direction or back + * + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum +{ + HAND_GESTURE_WORK_MODE_ONE_WAY = 1, /**< move the hand in one direction */ + HAND_GESTURE_WORK_MODE_ROUND_TRIP = 2, /**< move the hand in round trip */ + HAND_GESTURE_WORK_MODE_MIXED = 3, /**< move the hand in mixed */ + HAND_GESTURE_WORK_MODE_UNDEFINED = 4, /**< move the hand in undefined */ +} hand_gesture_workmode_e; + +/** + * @brief Enumeration for gesture event types. + * @details With regards to type of the gesture, gesture_get_event() returns one of the followings. + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef enum { + HAND_GESTURE_EVENT_NONE = 1, /**< Detected nothing */ + HAND_GESTURE_EVENT_DETECTED = 2, /**< Detected the gesture */ + HAND_GESTURE_HAND_MOVE_RIGHT = 3, /**< move right detected (only for HAND_GESTURE_LEFT_HAND_MOVE or HAND_GESTURE_RIGHT_HAND_MOVE) */ + HAND_GESTURE_HAND_MOVE_LEFT = 4, /**< move left detected (only for HAND_GESTURE_LEFT_HAND_MOVE or HAND_GESTURE_RIGHT_HAND_MOVE) */ + HAND_GESTURE_HAND_MOVE_UP = 5, /**< move up detected (only for HAND_GESTURE_LEFT_HAND_MOVE or HAND_GESTURE_RIGHT_HAND_MOVE) */ + HAND_GESTURE_HAND_MOVE_DOWN = 6, /**< move down detected (only for HAND_GESTURE_LEFT_HAND_MOVE or HAND_GESTURE_RIGHT_HAND_MOVE) */ + HAND_GESTURE_HAND_MOVE_PUSH = 7, /**< move push detected (only for HAND_GESTURE_LEFT_HAND_MOVE or HAND_GESTURE_RIGHT_HAND_MOVE) */ +} hand_gesture_event_e; + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_COMMON_INTERNAL_H__ */ diff --git a/include/gesture_data_info.h b/include/gesture_data_info.h new file mode 100644 index 0000000..c91775b --- /dev/null +++ b/include/gesture_data_info.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_DATA_INFO_H__ +#define __TIZEN_UIX_GESTURE_DATA_INFO_H__ + + +/** + * @file gesture_data_info.h + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct hand_gesture_data_s{ + int gesture_type; + int event; + int detected_Count; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __TIZEN_UIX_GESTURE_DATA_INFO_H__ */ diff --git a/include/gesture_defs.h b/include/gesture_defs.h new file mode 100644 index 0000000..d08beca --- /dev/null +++ b/include/gesture_defs.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_DEFS_H__ +#define __TIZEN_UIX_GESTURE_DEFS_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAPI __attribute__((visibility("hidden"))) + +#define DBUS_NAME "org.freedesktop.DBus" +#define DBUS_OBJECT_PATH "/org/freedesktop/DBus" +#define DBUS_INTERFACE_NAME "org.freedesktop.DBus" + +#define GESTURE_DBUS_NAME "org.tizen.gesture.server" +#define GESTURE_OBJECT_PATH "/org/tizen/gesture/server" +#define GESTURE_INTERFACE_NAME "org.tizen.gesture_service" +#define GESTURE_ENGINE_INTERFACE_NAME "org.tizen.gesture_engine" +#define GESTURE_CLIENT_INTERFACE_NAME "org.tizen.gesture_client" + +#define GESTURE_MSG_SERVICE_REGISTER "gesture_service_register" +#define GESTURE_CLIENT_MSG_INITIALIZE_ENGINE "gesture_client_initialize_engine" +#define GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE "gesture_client_deinitialize_engine" +#define GESTURE_CLIENT_MSG_START_RECOGNITION "gesture_client_start_recognition" +#define GESTURE_CLIENT_MSG_STOP_RECOGNITION "gesture_client_stop_recognition" +#define GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME "gesture_client_foreach_result_time" +#define GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE "gesture_client_foreach_supported_type" +#define GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE "gesture_client_is_support_gesture_type" +#define GESTURE_CLIENT_MSG_ENGINE_GET_INFO "gesture_client_engine_get_info" + +#define GESTURE_CLIENT_SIGNAL_GET_RESULT "get_result" +#define GESTURE_CLIENT_SIGNAL_GET_ERROR "get_error" +#define GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS "get_motion_status" +#define GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO "get_engine_info" + +#define GESTURE_ENGINE_MSG_MAIN_START "gesture_engine_main_start" +#define GESTURE_ENGINE_MSG_SEND_RESULT "gesture_engine_send_result" +#define GESTURE_ENGINE_MSG_SEND_ERROR "gesture_engine_send_error" +#define GESTURE_ENGINE_MSG_SEND_MOTION_STATUS "gesture_engine_send_motion_status" +#define GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO "gesture_engine_send_engine_get_info" + +#define GESTURE_ENGINE_SIGNAL_ENGINE_INITIALIZE "engine_initialize" +#define GESTURE_ENGINE_SIGNAL_ENGINE_DEINITIALIZE "engine_deinitialize" +#define GESTURE_ENGINE_SIGNAL_ENGINE_START "engine_start" +#define GESTURE_ENGINE_SIGNAL_ENGINE_STOP "engine_stop" +#define GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME "engine_foreach_result_time" +#define GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE "engine_foreach_supported_type" +#define GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE "engine_is_support_gesture_type" +#define GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO "engine_get_info" + +#define GESTURE_PRIVILEGE_APPLAUNCH "http://tizen.org/privilege/appmanager.launch" +#define GESTURE_FEATURE_GESTURE "tizen.org/feature/sensor.gesture_recognition" +#define CHECK_GESTURE_FEATURE() \ + do { \ + bool is_supported = false; \ + if (!system_info_get_platform_bool(GESTURE_FEATURE_GESTURE, &is_supported)) { \ + if (is_supported == false) { \ + LOGE("sensor.gesture_recognition feature not supported"); \ + return HAND_GESTURE_ERROR_NOT_SUPPORTED; \ + } \ + } \ + } while (0) + +typedef enum { + GESTURE_CLIENT_LIB_NONE, + GESTURE_CLIENT_LIB_GESTURE, + GESTURE_CLIENT_LIB_ENGINE, +} CLIENT_LIB; + + +#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0) + +#define IF_FAIL_RETURN(cond, ret) \ + do { if (!(cond)) { return ret; } } while (0) + +#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0) + +#define IF_FAIL_VOID(cond) \ + do { if (!(cond)) { return; } } while (0) + +#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \ + do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0) + +#define IF_FAIL_CATCH(cond) \ + do { if (!(cond)) { goto CATCH; } } while (0) + +#define IS_FAILED(X) ((X) != ERR_NONE) + +#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, HAND_GESTURE_ERROR_OUT_OF_MEMORY, LOGE, "Memory allocation failed") +#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, HAND_GESTURE_ERROR_INVALID_PARAMETER, LOGE, "Parameter null") + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_DEFS_H__ */ diff --git a/include/gesture_engine.h b/include/gesture_engine.h new file mode 100644 index 0000000..868c1ff --- /dev/null +++ b/include/gesture_engine.h @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_ENGINE_H__ +#define __TIZEN_UIX_GESTURE_ENGINE_H__ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerations for gesture server error. + */ +typedef enum { + GESTURE_ENGINE_ERROR_NONE = 0, + GESTURE_ENGINE_ERROR_INVALID_PARAMETER, + GESTURE_ENGINE_ERROR_INVALID_OPERATION, + GESTURE_ENGINE_ERROR_OUT_OF_MEMORY, + GESTURE_ENGINE_ERROR_PERMISSION_DENIED, + GESTURE_ENGINE_ERROR_NOT_SUPPORTED, + GESTURE_ENGINE_ERROR_IO_ERROR, + GESTURE_ENGINE_ERROR_SERVICE_NOT_READY, + GESTURE_ENGINE_ERROR_OPERATION_FAILED, +} gesture_engine_error_e; + +/** + * @file gesture_engine.h + * @brief This file contains gesture engine's APIs. + */ + +/** + * @brief The gesture engine handle. + * @since_tizen @if WEARABLE 6.0 @endif + */ +typedef struct gesture_engine_s *gesture_engine_h; + + +/** +* @brief Enumeration for callback event. +* @since_tizen 6.0 +*/ +typedef enum { + GESTURE_ENGINE_RESULT_EVENT_FINAL_RESULT = 0, /**< Event when either the full matched or the final result is delivered */ + GESTURE_ENGINE_RESULT_EVENT_PARTIAL_RESULT, /**< Event when the partial matched result is delivered */ + GESTURE_ENGINE_RESULT_EVENT_ERROR /**< Event when the recognition has failed */ +} gesture_engine_result_event_e; + + +/** +* @brief Enumeration for result time callback event. +* @since_tizen 6.0 +*/ +typedef enum { + GESTURE_ENGINE_RESULT_TIME_EVENT_BEGINNING = 0, /**< Event when the token is beginning type */ + GESTURE_ENGINE_RESULT_TIME_EVENT_MIDDLE, /**< Event when the token is middle type */ + GESTURE_ENGINE_RESULT_TIME_EVENT_END /**< Event when the token is end type */ +} gesture_engine_result_time_event_e; + + +/** +* @brief Enumeration for motion status. +* @since_tizen 6.0 +*/ +typedef enum { + GESTURE_ENGINE_MOTION_STATUS_START_POINT_DETECTED = 0, /**< Beginning point of motion is detected */ + GESTURE_ENGINE_MOTION_STATUS_END_POINT_DETECTED /**< End point of motion is detected */ +} gesture_engine_motion_status_e; + + +typedef void(* gesture_engine_recognition_cb)(hand_gesture_type_e gesture, const hand_gesture_data_h data, double timestamp, gesture_engine_error_e error, void *user_data); + + +/** +* @brief Called when GESTURE engine provides the time stamp of result to the engine service user. +* @details This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. +* @since_tizen 6.0 +* @remarks This callback function is called in gesture_engine_foreach_result_time_cb() for adding time information. +* @a user_data must be transferred from gesture_engine_foreach_result_time_cb(). +* @param[in] index The result index +* @param[in] event The token event +* @param[in] start_time The time started detecting the hand motion +* @param[in] end_time The time finished detecting the hand motion +* @param[in] user_data The user data passed from gesture_engine_foreach_result_time_cb() +* @return @c true to continue with the next iteration of the loop +* @c false to break out of the loop +* @pre gesture_engine_send_result() should be called. +* @see gesture_engine_send_result() +* @see gesture_engine_foreach_result_time_cb() +*/ +typedef bool (*gesture_engine_result_time_cb)(int index, gesture_engine_result_time_event_e event, + long start_time, long end_time, void* user_data); + + +/** +* @brief Called when GESTURE engine informs the engine service user about whole supported gesture types. +* @details This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. +* @since_tizen 6.0 +* @remarks This callback function is called in gesture_engine_foreach_supported_type_cb() to inform the whole supported gesture types. +* @a user_data must be transferred from gesture_engine_foreach_supported_type_cb(). +* @param[in] gesture_type The type is specified as hand_gesture_type_e +* For example, "GESTURE_WRIST_UP", "GESTURE_LEFT_HAND_MOVE" +* @param[in] user_data The user data passed from gesture_engine_foreach_supported_type_cb() +* @return @c true to continue with the next iteration of the loop +* @c false to break out of the loop +* @pre gesture_engine_foreach_supported_type_cb() will invoke this callback function. +* @see gesture_engine_foreach_supported_type_cb() +*/ +typedef bool (*gesture_engine_supported_type_cb)(const char* gesture_type, void* user_data); + + +/** +* @brief Called when the engine service user initializes GESTURE engine. +* @details This callback function is called by the engine service user to request for GESTURE engine to be started. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @see gesture_engine_deinitialize_cb() +*/ +typedef int (*gesture_engine_initialize_cb)(void); + + +/** +* @brief Called when the engine service user deinitializes GESTURE engine +* @details This callback function is called by the engine service user to request for GESTURE engine to be deinitialized. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* NOTE that the engine may be terminated automatically. +* When this callback function is invoked, the release of resources is necessary. +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @see gesture_engine_initialize_cb() +*/ +typedef int (*gesture_engine_deinitialize_cb)(void); + + +/** +* @brief Called when the engine service user gets the whole supported gesture types. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* In this function, the engine service user's callback function 'gesture_engine_supported_type_cb()' is invoked repeatedly for getting all supported gesture types, and @a user_data must be transferred to 'gesture_engine_supported_type_cb()'. +* If 'gesture_engine_supported_type_cb()' returns @c false, it should be stopped to call 'gesture_engine_supported_type_cb()'. +* @param[in] callback The callback function +* @param[in] user_data The user data which must be passed to the callback function 'gesture_engine_supported_type_cb()' +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @post This callback function invokes gesture_engine_supported_type_cb() repeatedly for getting supported gesture types. +* @see gesture_engine_supported_type_cb() +*/ +typedef int (*gesture_engine_foreach_supported_type_cb)(gesture_engine_supported_type_cb callback, void* user_data); + +/** +* @brief Called when the engine service user checks whether GESTURE engine supports the corresponding recognition type. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* @param[in] type The type for recognition (e.g. #GESTURE_WRIST_UP) +* @param[out] is_supported A variable for checking whether GESTURE engine supports the corresponding recognition type. +* @c true to support recognition type, +* @c false not to support recognition type +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* +*/ +typedef int (*gesture_engine_is_support_gesture_type_cb)(const hand_gesture_type_e type, bool* is_supported); + + +/** +* @brief Called when the engine service user gets the result time information(stamp). +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* In this function, the engine service user's callback function 'gesture_engine_result_time_cb()' is invoked repeatedly for sending the time information to the engine service user, and @a user_data must be transferred to 'gesture_engine_result_time_cb()'. +* If 'gesture_engine_result_time_cb()' returns @c false, it should be stopped to call 'gesture_engine_result_time_cb()'. +* @a time_info is transferred from gesture_engine_send_result(). The type of @a time_info is up to the GESTURE engine developer. +* @param[in] time_info The time information +* @param[in] callback The callback function +* @param[in] user_data The user data which must be passed to the callback function 'gesture_engine_result_time_cb()' +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @pre gesture_engine_send_result() will invoke this function. +* @post This function invokes gesture_engine_result_time_cb() repeatedly for getting result time information. +* @see gesture_engine_result_time_cb() +*/ +typedef int (*gesture_engine_foreach_result_time_cb)(void* time_info, gesture_engine_result_time_cb callback, void* user_data); + + +/** +* @brief Called when the engine service user starts to detecting gesture motion +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* In this callback function, GESTURE engine must transfer the recognition result and @a user_data to the engine service user using gesture_engine_send_result(). +* @param[in] gesture_type The gesture type. (e.g. #GESTURE_WRIST_UP) +* @param[in] hand_type Hand type using for gesture (right or left) +* @param[in] work_mode Determining whether to move the hand in one direction or back +* @param[in] option Detection option +* @param[in] sensitivity Set sensitivity for recognizing gesture +* @param[in] callback The result data to be passed to the callback function +* @param[in] user_data The user data to be passed to the callback function +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The engine is not in recognition processing. +* @see gesture_engine_stop_cb() +*/ +typedef int (*gesture_engine_start_cb)(const hand_gesture_type_e gesture_type, hand_gesture_handtype_e hand_type, hand_gesture_workmode_e work_mode, hand_gesture_option_e option, int sensitivity, gesture_engine_recognition_cb callback, void *user_data); + + +/** +* @brief Called when the engine service user stops to detecting gesture motion. +* @details This callback function is called by the engine service user to stop detecting and to get the recognition result. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre gesture_engine_start_cb() should succeed. +* @post After processing of the engine, gesture_engine_send_result() must be called. +* @see gesture_engine_start_cb() +* @see gesture_engine_send_result() +*/ +typedef int (*gesture_engine_stop_cb)(void); + + +/** +* @brief Called when the engine service user requests the basic information of GESTURE engine. +* @since_tizen 6.0 +* @remarks This callback function is mandatory and must be registered using gesture_engine_main(). +* The allocated @a engine_app_id, @a engine_name, and @a engine_setting will be released internally. +* @param[out] engine_app_id The app id of engine +* @param[out] engine_name The name of engine +* @return @c 0 on success, +* otherwise a negative error code on failure +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +*/ +typedef int (*gesture_engine_get_info_cb)(char** engine_app_id, char** engine_name); + + +/** +* @brief Called when GESTURE engine receives the private data from the engine service user. +* @details This callback function is called when the engine service user sends the private data to GESTURE engine. +* @since_tizen 6.0 +* @remarks This callback function is optional and is registered using gesture_engine_set_private_data_set_cb(). +* @param[in] key The key field of private data +* @param[in] data The data field of private data +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @see gesture_engine_private_data_requested_cb() +* @see gesture_engine_set_private_data_set_cb() +*/ +typedef int (*gesture_engine_private_data_set_cb)(const char* key, const char* data); + + +/** +* @brief Called when GESTURE engine provides the engine service user with the private data. +* @details This callback function is called when the engine service user gets the private data from GESTURE engine. +* @since_tizen 6.0 +* @remarks This callback function is optional and is registered using gesture_engine_set_private_data_requested_cb(). +* @param[out] key The key field of private data +* @param[out] data The data field of private data +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @see gesture_engine_private_data_set_cb() +* @see gesture_engine_set_private_data_requested_cb() +*/ +typedef int (*gesture_engine_private_data_requested_cb)(const char* key, char** data); + +/** +* @brief A structure for the GESTURE engine functions. +* @details This structure contains essential callback functions for operating GESTURE engine. +* @since_tizen 6.0 +* @remarks These functions are mandatory for operating GESTURE engine. Therefore, all functions MUST be implemented. +*/ +typedef struct { + int version; /**< The version of the structure 'gesture_engine_request_callback_s' */ + gesture_engine_get_info_cb get_info; /**< Called when the engine service user requests the basic information of GESTURE engine */ + + gesture_engine_initialize_cb initialize; /**< Called when the engine service user initializes GESTURE engine */ + gesture_engine_deinitialize_cb deinitialize; /**< Called when the engine service user deinitializes GESTURE engine */ + + gesture_engine_foreach_supported_type_cb foreach_types; /**< Called when the engine service user gets the whole supported gesture types */ + gesture_engine_is_support_gesture_type_cb is_support_gesture_type; /**< Called when the engine service user checks whether GESTURE engine supports the corresponding recognition type */ + gesture_engine_foreach_result_time_cb foreach_result_time; /**< Called when the engine service user gets the result time information(stamp) */ + + gesture_engine_start_cb start; /**< Called when the engine service user starts to detect gesture motion */ + gesture_engine_stop_cb stop; /**< Called when the engine service user stops to detect gesture motion */ + +} gesture_engine_request_callback_s; + + +/** +* @brief Main function for GESTURE engine. +* @details This function is the main function for operating GESTURE engine. +* @since_tizen 6.0 +* @privlevel public +* @remarks The service_app_main() should be used for working the engine after this function. +* @param[in] argc The argument count(original) +* @param[in] argv The argument(original) +* @param[in] callback The structure of engine request callback function +* @return This function returns @c zero on success, +* or negative with error code on failure +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @see gesture_engine_request_callback_s +* @code +#include + +// Required callback functions - MUST BE IMPLEMENTED +static int gesture_engine_get_info_cb(char** engine_app_id, char** engine_name); +static int gesture_engine_initialize_cb(void); +static int gesture_engine_deinitialize_cb(void); +static int gesture_engine_foreach_supported_type_cb(gesture_engine_supported_type_cb callback, void* user_data); +static int gesture_engine_is_support_gesture_type_cb(const hand_gesture_type_e type, bool* is_supported); +static int gesture_engine_foreach_result_time_cb(void* time_info, gesture_engine_result_time_cb callback, void* user_data); +static int gesture_engine_start_cb(const hand_gesture_type_e gesture_type, hand_gesture_handtype_e hand_type, hand_gesture_workmode_e work_mode, hand_gesture_option_e option, int sensitivity, void *user_data); +static int gesture_engine_stop_cb(void); + +// Optional callback function +static int gesture_engine_private_data_set_cb(const char* key, const char* data); + +// Engine handle +static gesture_engine_h engineHandle = NULL; + +int main(int argc, char* argv[]) +{ + // 0. Connect with server and get engine handle + gesture_engine_connect(&engineHandle); + + // 1. Create a structure 'gesture_engine_request_callback_s' + gesture_engine_request_callback_s engine_callback = { 0, }; + + engine_callback.size = sizeof(gesture_engine_request_callback_s); + engine_callback.version = 1; + engine_callback.get_info = gesture_engine_get_info_cb; + + engine_callback.initialize = gesture_engine_initialize_cb; + engine_callback.deinitialize = gesture_engine_deinitialize_cb; + + engine_callback.foreach_types = gesture_engine_foreach_supported_type_cb; + engine_callback.is_support_gesture_type = gesture_engine_is_support_gesture_type_cb; + + engine_callback.foreach_result_time = gesture_engine_foreach_result_time_cb; + + engine_callback.start = gesture_engine_start_cb; + engine_callback.stop = gesture_engine_stop_cb; + + // 2. Run 'gesture_engine_main()' + if (0 != gesture_engine_main(argc, argv, engine_handle, &engine_callback)) { + return -1; + } + + // Optional + gesture_engine_set_private_data_set_cb(gesture_engine_private_data_set_cb); + + // 3. Set event callbacks for service app and Run 'service_app_main()' + char ad[50] = { 0, }; + + service_app_lifecycle_callback_s event_callback; + app_event_handler_h handlers[5] = { NULL, }; + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + + service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad); + + return service_app_main(argc, argv, &event_callback, ad); +} + +* @endcode +*/ +int gesture_engine_main(int argc, char** argv, gesture_engine_h engine_handle, gesture_engine_request_callback_s *callback); + + +/** + * @brief Connect gesture engine with Server and get handle. + * @since_tizen @if WEARABLE 6.0 @endif + * @remarks If the function succeeds, @a engine_handle must be released with gesture_engine_disconnect(). + * @param[out] engine_handle The gesture handle + * @return 0 on success, otherwise a negative error value + * @retval #GESTURE_ENGINE_ERROR_NONE Successful + * @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported + * @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied + * @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #GESTURE_ENGINE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failed + * @see gesture_engine_disconnect() + */ +int gesture_engine_connect(gesture_engine_h *engine_handle); + + +/** + * @brief Disconnect with server and destroy gesture handle. + * @since_tizen @if WEARABLE 6.0 @endif + * @param[in] engine_handle The gesture handle + * @return 0 on success, otherwise a negative error value + * @retval #GESTURE_ENGINE_ERROR_NONE Successful + * @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported + * @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failed + * @see gesture_engine_connect() + */ +int gesture_engine_disconnect(gesture_engine_h engine_handle); + + +/** +* @brief Sends the recognition result to the engine service user. +* @since_tizen 6.0 +* @remarks This API is used in gesture_engine_stop_cb(), when GESTURE engine sends the recognition result to the engine service user. +* This function is called in the following situations; 1) after gesture_engine_stop_cb() is called, 2) the end point of motion is detected from gesture, or 3) partial result is occurred. +* The recognition result and @a user_data must be transferred to the engine service user through this function. +* Also, @a time_info must be transferred to gesture_engine_foreach_result_time_cb(). The type of @a time_info is up to the GESTURE engine developer. +* @param[in] engine_handle The gesture handle +* @param[in] event The result event +* @param[in] gesture_type The gesture type (e.g. #GESTURE_WRIST_UP, #GESTURE_LEFT_HAND_MOVE) +* @param[in] result The gesture_data_s (gesture_type, event, detected_Count) +* @param[in] time_info The time information +* @param[in] user_data The user data passed from gesture_engine_start_cb() +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The gesture_engine_main() function should be invoked before this function is called. +* gesture_engine_stop_cb() will invoke this function. +* @post This function invokes gesture_engine_foreach_result_time_cb(). +* @see gesture_engine_start_cb() +* @see gesture_engine_stop_cb() +* @see gesture_engine_foreach_result_time_cb() +*/ +int gesture_engine_send_result(gesture_engine_h engine_handle, gesture_engine_result_event_e event, hand_gesture_type_e gesture_type, hand_gesture_data_h result, + void* time_info, void* user_data); + + +/** +* @brief Sends the error to the engine service user. +* @details The following error codes can be delivered. +* #GESTURE_ENGINE_ERROR_NONE, +* #GESTURE_ENGINE_ERROR_IO_ERROR, +* #GESTURE_ENGINE_ERROR_INVALID_PARAMETER, +* #GESTURE_ENGINE_ERROR_PERMISSION_DENIED, +* #GESTURE_ENGINE_ERROR_OUT_OF_MEMORY, +* #GESTURE_ENGINE_ERROR_SERVICE_NOT_READY, +* #GESTURE_ENGINE_ERROR_OPERATION_FAILED, +* #GESTURE_ENGINE_ERROR_NOT_SUPPORTED. +* @since_tizen 6.0 +* @param[in] engine_handle The gesture handle +* @param[in] error The error reason +* @param[in] msg The error message +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The gesture_engine_main() function should be invoked before this function is called. +*/ +int gesture_engine_send_error(gesture_engine_h engine_handle, gesture_engine_error_e error, const char* msg); + + +/** +* @brief Sends the gesture status to the engine service user when GESTURE engine notifies the change of the motion status. +* @since_tizen 6.0 +* @remarks This API is invoked when GESTURE engine wants to notify the change of the motion status anytime. +* NOTE that this API can be invoked for recognizing the motion. +* @param[in] engine_handle The gesture handle +* @param[in] status The status of motion (e.g. GESTURE_ENGINE_MOTION_STATUS_START_POINT_DETECTED or GESTURE_ENGINE_MOTION_STATUS_END_POINT_DETECTED) +* @param[in] user_data The user data passed from the start function. +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The gesture_engine_main() function should be invoked before this function is called. +* gesture_engine_start_cb() will invoke this function. +* @see gesture_engine_start_cb() +*/ +int gesture_engine_send_motion_status(gesture_engine_h engine_handle, gesture_engine_motion_status_e status, void* user_data); + + +/** +* @brief Sets a callback function for setting the private data. +* @since_tizen 6.0 +* @privlevel public +* @remarks The gesture_engine_private_data_set_cb() function is called when the engine service user sends the private data. +* @param[in] engine_handle The gesture handle +* @param[in] callback_func The gesture_engine_private_data_set event callback function +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The gesture_engine_main() function should be invoked before this function is called. +* @see gesture_engine_private_data_set_cb() +*/ +int gesture_engine_set_private_data_set_cb(gesture_engine_h engine_handle, gesture_engine_private_data_set_cb callback_func); + + +/** +* @brief Sets a callback function for requesting the private data. +* @since_tizen 6.0 +* @privlevel public +* @remarks The gesture_engine_private_data_requested_cb() function is called when the engine service user gets the private data from GESTURE engine. +* @param[in] engine_handle The gesture handle +* @param[in] callback_func The gesture_engine_private_data_requested event callback function +* @return @c 0 on success, +* otherwise a negative error value +* @retval #GESTURE_ENGINE_ERROR_NONE Successful +* @retval #GESTURE_ENGINE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #GESTURE_ENGINE_ERROR_PERMISSION_DENIED Permission denied +* @retval #GESTURE_ENGINE_ERROR_NOT_SUPPORTED Not supported +* @retval #GESTURE_ENGINE_ERROR_OPERATION_FAILED Operation failure +* @pre The gesture_engine_main() function should be invoked before this function is called. +* @see gesture_engine_private_data_requested_cb() +*/ +int gesture_engine_set_private_data_requested_cb(gesture_engine_h engine_handle, gesture_engine_private_data_requested_cb callback_func); + +int gesture_engine_send_engine_get_info(gesture_engine_h engine_handle, char* engine_app_id, char* engine_name); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_ENGINE_H__ */ diff --git a/include/gesture_internal.h b/include/gesture_internal.h new file mode 100644 index 0000000..356e123 --- /dev/null +++ b/include/gesture_internal.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURE_INTERNAL_H__ +#define __TIZEN_UIX_GESTURE_INTERNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file gesture_internal.h + * @brief This file contains gesture's internal APIs. + */ + +/** + * @addtogroup CAPI_UIX_GESTURE_MODULE + * @{ + */ + +/** + * @brief Sets the hand type whether right hand or left hand. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] hand_type Hand type using for gesture (right or left) + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_start_recognition() + */ +int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type); + +/** + * @brief Sets the work mode for gesture recognition. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] work_mode Determining whether to move the hand in one direction or back + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_start_recognition() + */ +int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode); + +/** + * @brief Sets the sensitivity for gesture recognition. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle Gesture handle to be used to control the gesture event + * @param[in] sensitivity Set sensitivity for recognizing gesture + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_start_recognition() + */ +int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity); + +/** + * @brief Gets the gesture event from the gesture data received. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[out] data Gesture data received through a callback function + * @param[out] event Gesture event data + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + */ +int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURE_INTERNAL_H__ */ diff --git a/include/gesture_recognition.h b/include/gesture_recognition.h deleted file mode 100644 index b5c90ce..0000000 --- a/include/gesture_recognition.h +++ /dev/null @@ -1,269 +0,0 @@ -/* - * gesture - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * 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 __TIZEN_GESTURE_H__ -#define __TIZEN_GESTURE_H__ - -/** - * @addtogroup CAPI_GESTURE_MODULE - * @{ - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * @brief The gesture recognizer controlling handle. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef struct _gesture_handle_s* gesture_h; - -/** - * @brief Delivery through gesture_recognition_cb() of gesture data handle. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef struct _gesture_data_s* gesture_data_h; - -/** - * @brief Enumeration for error codes. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef enum { - GESTURE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - GESTURE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ - GESTURE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */ - GESTURE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - GESTURE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ - GESTURE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ - GESTURE_ERROR_ALREADY_STARTED = TIZEN_ERROR_CONTEXT | 0x01, /**< Recognition is already started */ - GESTURE_ERROR_NOT_STARTED = TIZEN_ERROR_CONTEXT | 0x02, /**< Recognition is not started */ - GESTURE_ERROR_OPERATION_FAILED = TIZEN_ERROR_CONTEXT | 0x04, /**< Operation failed because of a system error */ -} gesture_error_e; - -/** - * @brief Enumeration for gesture types. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef enum { - GESTURE_DOUBLE_TAP = 1, /**< The mobile device is tapped twice */ - GESTURE_MOVE_TO_EAR, /**< The mobile device is moved near to an ear */ - GESTURE_NO_MOVE, /**< The mobile device is being stopped for a while */ - GESTURE_PICK_UP, /**< The mobile device is picked up */ - GESTURE_SHAKE, /**< The mobile device is quickly moved back and forth */ - GESTURE_SNAP, /**< The mobile device is moved along an axis and back */ - GESTURE_TILT, /**< The mobile device is tilted */ - GESTURE_TURN_FACE_DOWN, /**< The mobile device is flipped from face to back */ - GESTURE_WRIST_UP, /**< The wearable device is moved and faced up */ -} gesture_type_e; - -/** - * @brief Enumeration for gesture recognition option. - * @details If the default option is used, the system tries to reduce power consumption. - * For example, the recognition engine may stop detecting gestures if the display is turned off. - * Using #GESTURE_OPTION_ALWAYS_ON disables such power-saving functionalities. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef enum { - GESTURE_OPTION_DEFAULT = 0, /**< Running in the default setting */ - GESTURE_OPTION_ALWAYS_ON = 1, /**< Trying to detect gestures always */ -} gesture_option_e; - -/** - * @brief Enumeration for gesture event types. - * @details With regards to type of the gesture, gesture_get_event() returns one of the followings. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - */ -typedef enum { - GESTURE_EVENT_NONE = 0, /**< Detected nothing */ - GESTURE_EVENT_DETECTED = 1, /**< Detected the gesture */ - - GESTURE_SHAKE_DETECTED = 1, /**< Shake gesture started */ - GESTURE_SHAKE_FINISHED = 2, /**< Shake gesture stopped */ - - GESTURE_SNAP_X_NEGATIVE = 1, /**< Detected -X snap */ - GESTURE_SNAP_X_POSITIVE = 2, /**< Detected +X snap */ - GESTURE_SNAP_Y_NEGATIVE = 3, /**< Detected -Y snap */ - GESTURE_SNAP_Y_POSITIVE = 4, /**< Detected +Y snap */ - GESTURE_SNAP_Z_NEGATIVE = 5, /**< Detected -Z snap */ - GESTURE_SNAP_Z_POSITIVE = 6, /**< Detected +Z snap */ -} gesture_event_e; - -/** - * @brief Called when a gesture is detected. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] gesture Gesture type detected - * @param[in] data Detailed information of the detected gesture.@n - * gesture_get_event() or gesture_get_tilt() - * can be used to extract the information from @c data. - * @param[in] timestamp The time when the gesture is detected. Epoch time in seconds. - * @param[in] error An error value. It can be one of the following error values:@n - * #GESTURE_ERROR_NONE, if the operation succeeded.@n - * #GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported in the current profile.@n - * #GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error.@n - * #GESTURE_ERROR_PERMISSION_DENIED, if the application has no permission to use this. - * @param[in] user_data The user data had passed to gesture_start_recognition() - * - * @pre gesture_start_recognition() - */ -typedef void(* gesture_recognition_cb)(gesture_type_e gesture, const gesture_data_h data, double timestamp, gesture_error_e error, void *user_data); - -/** - * @brief Check whether the gesture is supported or not. - * @details Check if the given gesture type is supported in the current device. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] gesture Gesture type to be checked - * @param[out] supported @c true if the gesture is recognizable in the current device,@n - * @c false otherwise - * - * @return @c 0 if the @c gesture is supported, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Supported - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED The @c gesture is not supported - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - * @retval #GESTURE_ERROR_PERMISSION_DENIED Does not have permission to use this - */ -int gesture_is_supported(gesture_type_e gesture, bool* supported); - -/** - * @brief Initializes a gesture handle. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[out] handle Gesture handle to be initialized - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error, e.g., out of memory - * - * @see gesture_release() - */ -int gesture_create(gesture_h *handle); - -/** - * @brief Releases the resources occupied by the gesture handle. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] handle Gesture handle to be released - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - * - * @pre gesture_create() - */ -int gesture_release(gesture_h handle); - -/** - * @brief Starts to recognize a gesture. - * @details Sets a callback function to be invoked when the gesture is detected, - * and starts to monitor occurrences of the gesture. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] handle Gesture handle to be used to control the gesture event - * @param[in] gesture Gesture type to be monitored - * @param[in] option Detection option - * @param[in] callback Callback function to receive gesture events - * @param[in] user_data User data to be passed to the callback function - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - * @retval #GESTURE_ERROR_PERMISSION_DENIED Does not have permission to use this - * - * @pre gesture_create() - * @post gesture_recognition_cb() - * @see gesture_stop_recognition() - */ -int gesture_start_recognition(gesture_h handle, gesture_type_e gesture, gesture_option_e option, gesture_recognition_cb callback, void *user_data); - -/** - * @brief Stops recognizing the gesture registered to the gesture handle. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] handle Gesture handle to release its callback function registered - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_NOT_STARTED Nothing is started using the @c handle - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - */ -int gesture_stop_recognition(gesture_h handle); - -/** - * @brief Gets the gesture event from the gesture data received. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] data Gesture data received through a callback function - * @param[out] event Gesture event data - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - */ -int gesture_get_event(const gesture_data_h data, gesture_event_e *event); - -/** - * @brief Gets the tilting degrees from #GESTURE_TILT data received. - * - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif - * - * @param[in] data Tilt gesture data received through a callback function - * @param[out] x Tilting degree on X-axis - * @param[out] y Tilting degree on Y-axis - * - * @return @c 0 on success, otherwise a negative error value - * @retval #GESTURE_ERROR_NONE Successful - * @retval #GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported - * @retval #GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error - */ -int gesture_get_tilt(const gesture_data_h data, int *x, int *y); - -#ifdef __cplusplus -} -#endif // __cplusplus - -/** -* @} -*/ - -#endif // __TIZEN_GESTURE_H__ diff --git a/manager/gestured_client_manager.cpp b/manager/gestured_client_manager.cpp new file mode 100644 index 0000000..970f080 --- /dev/null +++ b/manager/gestured_client_manager.cpp @@ -0,0 +1,286 @@ +#include +#include "gestured_client_manager.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURED_CLIENT_MANAGER" + +static GList* g_client_list = NULL; + +gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name) +{ + LOGD("Create client"); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return NULL; + } + + gesture_manager_client_s* client; + client = (gesture_manager_client_s*)calloc(1, sizeof(gesture_manager_client_s)); + if (NULL == client) { + LOGE("Fail to allocate memory"); + return NULL; + } + + client->pkg_name = strdup(pkg_name); + if (NULL == client->pkg_name) { + LOGE("Fail to strdup"); + free(client); + client = NULL; + return NULL; + } + + client->gestureType = -1; + client->requestTypeCount = -1; + client->clientLib = GESTURE_CLIENT_LIB_NONE; + client->request_uid = -1; + client->gdbus_bus_name = NULL; + client->gdbus_watch_id = -1; + client->gdbus_connection = NULL; + client->state = CLIENT_STATE_NONE; + client->response_cb = NULL; + + return client; +} + +void GestureManagerClientDestroy(gpointer data) +{ + LOGD("Destroy client"); + + if (NULL == data) + return; + + gesture_manager_client_s* client_h = (gesture_manager_client_s*)data; + + if (NULL != client_h->pkg_name) { + free(client_h->pkg_name); + client_h->pkg_name = NULL; + } + + if (NULL != client_h->gdbus_bus_name) { + free(client_h->gdbus_bus_name); + client_h->gdbus_bus_name = NULL; + } + + if (NULL != client_h->gdbus_connection) { + free(client_h->gdbus_connection); + client_h->gdbus_connection = NULL; + } + + if (NULL != client_h->response_cb) { + free(client_h->response_cb); + client_h->response_cb = NULL; + } + + free(client_h); + client_h = NULL; + + return; +} + +int GestureManagerClientAdd(gesture_manager_client_s* client_h) +{ + LOGD("Add a client to client list"); + + if (NULL == client_h) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + g_client_list = g_list_append(g_client_list, client_h); + + return GESTURED_ERROR_NONE; +} + +int GestureManagerClientRemove(gesture_manager_client_s* client_h) +{ + LOGD("Remove a client from client list"); + + if (NULL == client_h) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + g_client_list = g_list_remove(g_client_list, client_h); + GestureManagerClientDestroy(client_h); + + return GESTURED_ERROR_NONE; +} + +int GestureManagerClientNums() +{ + LOGD("Length of client list"); + + int count = 0; + count = g_list_length(g_client_list); + + return count; +} + +gesture_manager_client_s* GestureManagerClientGet(const char* pkg_name) +{ + LOGD("Get client. pkg_name(%s)", pkg_name); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return NULL; + } + + GList* iter = NULL; + gesture_manager_client_s* data = NULL; + + if (g_list_length(g_client_list) > 0) { + iter = g_list_first(g_client_list); + + while (NULL != iter) { + data = (gesture_manager_client_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(pkg_name, data->pkg_name, strlen(pkg_name))) { + LOGD("pkg_name(%s)", data->pkg_name); + return data; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("client doesn't exist"); + + return NULL; +} + +gesture_manager_client_s* GestureManagerClientGetWithBusName(const char* bus_name) +{ + LOGD("Get client. bus_name(%s)", bus_name); + + if (NULL == bus_name) { + LOGE("Invalid parameter"); + return NULL; + } + + GList* iter = NULL; + gesture_manager_client_s* data = NULL; + + if (g_list_length(g_client_list) > 0) { + iter = g_list_first(g_client_list); + + while (NULL != iter) { + data = (gesture_manager_client_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(bus_name, data->gdbus_bus_name, strlen(bus_name))) { + LOGD("gdbus_bus_name(%s)", data->gdbus_bus_name); + return data; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("client doesn't exist"); + + return NULL; +} + +char* GestureManagerClientGetBusName(int num) +{ + LOGD("Get client bus name. num(%d)", num); + + gpointer element_data = g_list_nth_data(g_client_list, num); + gesture_manager_client_s* client = (gesture_manager_client_s*)element_data; + if (client == NULL) { + LOGE("Error : Can not found %d th bus info", num); + return NULL; + } + return client->gdbus_bus_name; +} + +int GestureManagerClientClear() +{ + LOGD("Clear all clients from client list"); + + if (g_client_list) { + g_list_free_full(g_client_list, GestureManagerClientDestroy); + g_client_list = NULL; + } + + return GESTURED_ERROR_NONE; +} + +bool GestureManagerClientAlreadyRegisterd(const char *bus_name) +{ + LOGD("Check already registered client. bus_name(%s)", bus_name); + + if (NULL == bus_name) { + LOGE("Invalid parameter"); + return false; + } + + GList* iter = NULL; + gesture_manager_client_s* data = NULL; + + if (g_list_length(g_client_list) > 0) { + iter = g_list_first(g_client_list); + + while (NULL != iter) { + data = (gesture_manager_client_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(bus_name, data->gdbus_bus_name, strlen(bus_name))) { + LOGD("gdbus_bus_name(%s)", data->gdbus_bus_name); + return true; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("client is not yet registered. Need to register to server"); + + return false; +} + +int GestureManagerClientGetStatus(const char* pkg_name, gesture_manager_client_state_e* state) +{ + LOGD("get state. pkg_name(%s)", pkg_name); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + gesture_manager_client_s* client; + client = GestureManagerClientGet(pkg_name); + if (NULL == client) { + LOGE("Invalid uid"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + *state = client->state; + + return 0; +} + +int GestureManagerClientSetStatus(const char* pkg_name, gesture_manager_client_state_e state) +{ + LOGD("set state. pkg_name(%s), state(%d)", pkg_name, state); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + gesture_manager_client_s* client; + client = GestureManagerClientGet(pkg_name); + if (NULL == client) { + LOGE("Invalid pkg_name"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + client->state = state; + + return 0; +} diff --git a/manager/gestured_client_manager.h b/manager/gestured_client_manager.h new file mode 100644 index 0000000..35238b6 --- /dev/null +++ b/manager/gestured_client_manager.h @@ -0,0 +1,57 @@ +#ifndef __GESTURED_CLIENT_MANAGER_H__ +#define __GESTURED_CLIENT_MANAGER_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "gesture.h" +#include "gesture_defs.h" +#include "gestured_error.h" + +typedef enum { + CLIENT_STATE_NONE, + CLIENT_STATE_CONNECT, + CLIENT_STATE_DISCONNECT +} gesture_manager_client_state_e; + +typedef struct { + char *pkg_name; + int gestureType; + int requestTypeCount; + CLIENT_LIB clientLib; + uid_t request_uid; + char *gdbus_bus_name; + int gdbus_watch_id; + GDBusConnection *gdbus_connection; + gesture_manager_client_state_e state; + hand_gesture_recognition_cb *response_cb; +} gesture_manager_client_s; + +gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name); +void GestureManagerClientDestroy(gpointer data); + +int GestureManagerClientAdd(gesture_manager_client_s* client_h); +int GestureManagerClientRemove(gesture_manager_client_s* client_h); +int GestureManagerClientNums(); +gesture_manager_client_s* GestureManagerClientGet(const char* pkg_name); +gesture_manager_client_s* GestureManagerClientGetWithBusName(const char* bus_name); +char* GestureManagerClientGetBusName(int num); +int GestureManagerClientClear(void); +bool GestureManagerClientAlreadyRegisterd(const char *bus_name); + +int GestureManagerClientGetStatus(const char* pkg_name, gesture_manager_client_state_e* state); +int GestureManagerClientSetStatus(const char* pkg_name, gesture_manager_client_state_e state); + + +#ifdef __cplusplus +} +#endif + +#endif /* __GESTURED_CLIENT_MANAGER_H__ */ + diff --git a/manager/gestured_engine_manager.cpp b/manager/gestured_engine_manager.cpp new file mode 100644 index 0000000..65b805f --- /dev/null +++ b/manager/gestured_engine_manager.cpp @@ -0,0 +1,284 @@ +#include +#include "gestured_engine_manager.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURED_ENGINE_MANAGER" + +static GList* g_engine_list = NULL; + +gesture_manager_engine_s* GestureManagerEngineCreate(const char* pkg_name) +{ + LOGD("Create engine"); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return NULL; + } + + gesture_manager_engine_s* engine; + engine = (gesture_manager_engine_s*)calloc(1, sizeof(gesture_manager_engine_s)); + if (NULL == engine) { + LOGE("Fail to allocate memory"); + return NULL; + } + + engine->pkg_name = strdup(pkg_name); + if (NULL == engine->pkg_name) { + LOGE("Fail to strdup"); + free(engine); + engine = NULL; + return NULL; + } + + engine->engine_name = NULL; + engine->clientLib = GESTURE_CLIENT_LIB_NONE; + engine->request_uid = -1; + engine->gdbus_bus_name = NULL; + engine->gdbus_watch_id = -1; + engine->state = ENGINE_STATE_NONE; + engine->engine_callback = NULL; + + return engine; +} + +void GestureManagerEngineDestroy(gpointer data) +{ + LOGD("Destroy engine"); + + if (NULL == data) + return; + + gesture_manager_engine_s* engine_h = (gesture_manager_engine_s*)data; + + if (NULL != engine_h->pkg_name) { + free(engine_h->pkg_name); + engine_h->pkg_name = NULL; + } + + if (NULL != engine_h->engine_name) { + free(engine_h->engine_name); + engine_h->engine_name = NULL; + } + + if (NULL != engine_h->gdbus_bus_name) { + free(engine_h->gdbus_bus_name); + engine_h->gdbus_bus_name = NULL; + } + + if (NULL != engine_h->engine_callback) { + free(engine_h->engine_callback); + engine_h->engine_callback = NULL; + } + + free(engine_h); + engine_h = NULL; + + return; +} + +int GestureManagerEngineAdd(gesture_manager_engine_s* engine_h) +{ + LOGD("Add a engine to engine list"); + + if (NULL == engine_h) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + g_engine_list = g_list_append(g_engine_list, engine_h); + + return GESTURED_ERROR_NONE; +} + +int GestureManagerEngineRemove(gesture_manager_engine_s* engine_h) +{ + LOGD("Remove a engine from engine list"); + + if (NULL == engine_h) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + g_engine_list = g_list_remove(g_engine_list, engine_h); + GestureManagerEngineDestroy(engine_h); + + return GESTURED_ERROR_NONE; +} + +int GestureManagerEngineNums() +{ + LOGD("Length of engine list"); + + int count = 0; + count = g_list_length(g_engine_list); + + return count; +} + +gesture_manager_engine_s* GestureManagerEngineGet(const char* pkg_name) +{ + LOGD("Get engine. pkg_name(%s)", pkg_name); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return NULL; + } + + GList* iter = NULL; + gesture_manager_engine_s* data = NULL; + + if (g_list_length(g_engine_list) > 0) { + iter = g_list_first(g_engine_list); + + while (NULL != iter) { + data = (gesture_manager_engine_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(pkg_name, data->pkg_name, strlen(pkg_name))) { + LOGD("pkg_name(%s)", data->pkg_name); + return data; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("engine doesn't exist"); + + return NULL; +} + +gesture_manager_engine_s* GestureManagerEngineGetWithBusName(const char* bus_name) +{ + LOGD("Get engine. bus_name(%s)", bus_name); + + if (NULL == bus_name) { + LOGE("Invalid parameter"); + return NULL; + } + + GList* iter = NULL; + gesture_manager_engine_s* data = NULL; + + if (g_list_length(g_engine_list) > 0) { + iter = g_list_first(g_engine_list); + + while (NULL != iter) { + data = (gesture_manager_engine_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(bus_name, data->gdbus_bus_name, strlen(bus_name))) { + LOGD("gdbus_bus_name(%s)", data->gdbus_bus_name); + return data; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("engine doesn't exist"); + + return NULL; +} + +char* GestureManagerEngineGetBusName(int num) +{ + LOGD("Get engine bus name. num(%d)", num); + + gpointer element_data = g_list_nth_data(g_engine_list, num); + gesture_manager_engine_s* engine = (gesture_manager_engine_s*)element_data; + if (engine == NULL) { + LOGE("Error : Can not found %d th bus info", num); + return NULL; + } + return engine->gdbus_bus_name; +} + +int GestureManagerEngineClear() +{ + LOGD("Clear all engines from engine list"); + + if (g_engine_list) { + g_list_free_full(g_engine_list, GestureManagerEngineDestroy); + g_engine_list = NULL; + } + + return GESTURED_ERROR_NONE; +} + +bool GestureManagerEngineAlreadyRegisterd(const char *bus_name) +{ + LOGD("Check already registered engine. bus_name(%s)", bus_name); + + if (NULL == bus_name) { + LOGE("Invalid parameter"); + return false; + } + + GList* iter = NULL; + gesture_manager_engine_s* data = NULL; + + if (g_list_length(g_engine_list) > 0) { + iter = g_list_first(g_engine_list); + + while (NULL != iter) { + data = (gesture_manager_engine_s *)iter->data; + if (NULL != data) { + if (0 == strncmp(bus_name, data->gdbus_bus_name, strlen(bus_name))) { + LOGD("gdbus_bus_name(%s)", data->gdbus_bus_name); + return true; + } + } + + /* next item */ + iter = g_list_next(iter); + } + } + LOGD("engine is not yet registered. Need to register to server"); + + return false; +} + +int GestureManagerEngineGetStatus(const char* pkg_name, gesture_manager_engine_state_e* state) +{ + LOGD("get state. pkg_name(%s)", pkg_name); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + gesture_manager_engine_s* engine; + engine = GestureManagerEngineGet(pkg_name); + if (NULL == engine) { + LOGE("Invalid uid"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + *state = engine->state; + + return 0; +} + +int GestureManagerEngineSetStatus(const char* pkg_name, gesture_manager_engine_state_e state) +{ + LOGD("set state. pkg_name(%s), state(%d)", pkg_name, state); + + if (NULL == pkg_name) { + LOGE("Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + gesture_manager_engine_s* engine; + engine = GestureManagerEngineGet(pkg_name); + if (NULL == engine) { + LOGE("Invalid pkg_name"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + engine->state = state; + + return 0; +} diff --git a/manager/gestured_engine_manager.h b/manager/gestured_engine_manager.h new file mode 100644 index 0000000..e6cc51b --- /dev/null +++ b/manager/gestured_engine_manager.h @@ -0,0 +1,54 @@ +#ifndef __GESTURED_ENGINE_MANAGER_H__ +#define __GESTURED_ENGINE_MANAGER_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "gesture_engine.h" +#include "gesture_defs.h" +#include "gestured_error.h" + +typedef enum { + ENGINE_STATE_NONE, + ENGINE_STATE_CONNECT, + ENGINE_STATE_DISCONNECT +} gesture_manager_engine_state_e; + +typedef struct { + char *pkg_name; + char *engine_name; + CLIENT_LIB clientLib; + uid_t request_uid; + char *gdbus_bus_name; + int gdbus_watch_id; + gesture_manager_engine_state_e state; + gesture_engine_request_callback_s *engine_callback; +} gesture_manager_engine_s; + +gesture_manager_engine_s* GestureManagerEngineCreate(const char* pkg_name); +void GestureManagerEngineDestroy(gpointer data); + +int GestureManagerEngineAdd(gesture_manager_engine_s* engine_h); +int GestureManagerEngineRemove(gesture_manager_engine_s* engine_h); +int GestureManagerEngineNums(); +gesture_manager_engine_s* GestureManagerEngineGet(const char* pkg_name); +gesture_manager_engine_s* GestureManagerEngineGetWithBusName(const char* bus_name); +char* GestureManagerEngineGetBusName(int num); +int GestureManagerEngineClear(void); +bool GestureManagerEngineAlreadyRegisterd(const char *bus_name); + +int GestureManagerEngineGetStatus(const char* pkg_name, gesture_manager_engine_state_e* state); +int GestureManagerEngineSetStatus(const char* pkg_name, gesture_manager_engine_state_e state); + + +#ifdef __cplusplus +} +#endif + +#endif /* __GESTURED_ENGINE_MANAGER_H__ */ + diff --git a/packaging/capi-gesture.manifest b/packaging/capi-gesture.manifest deleted file mode 100644 index 97e8c31..0000000 --- a/packaging/capi-gesture.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packaging/capi-gesture.spec b/packaging/capi-gesture.spec deleted file mode 100644 index b456052..0000000 --- a/packaging/capi-gesture.spec +++ /dev/null @@ -1,70 +0,0 @@ -Name: capi-gesture -Summary: Tizen Native Gesture Recognition API -Version: 2.0.2 -Release: 1 -Group: Service/Gesture -License: Apache-2.0 -Source0: %{name}-%{version}.tar.gz - -BuildRequires: cmake -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(capi-base-common) -BuildRequires: pkgconfig(capi-system-info) -BuildRequires: pkgconfig(sensor) - -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig - -# Backward compatibility -Provides: gesture -Provides: libcore-gesture-manager.so.1 - -%description -Tizen Native Gesture Recognition API - -%prep -%setup -q - -%build -MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` - -export CXXFLAGS+=" -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter" -export CXXFLAGS+=" -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls" -export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow" -export CXXFLAGS+=" -Wnon-virtual-dtor" - -%cmake . -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -make %{?_smp_mflags} - -%install -%make_install - -# For backward compatibility -ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/gesture.pc -ln -s %{name}.pc %{buildroot}/%{_libdir}/pkgconfig/libcore-gesture-manager.pc -ln -s lib%{name}.so.%{version} %{buildroot}/%{_libdir}/libcore-gesture-manager.so.1 - -%post -/sbin/ldconfig - -%postun -/sbin/ldconfig - -%files -%manifest packaging/%{name}.manifest -%{_libdir}/*.so.* -%license LICENSE - -%package devel -Summary: Tizen Native Gesture Recognition API (Development) -Group: Framework/activity -Requires: %{name} = %{version}-%{release} - -%description devel -Tizen Native Gesture Recognition API (Development) - -%files devel -%{_includedir}/*/*.h -%{_libdir}/*.so -%{_libdir}/pkgconfig/*.pc diff --git a/packaging/capi-ui-gesture.conf b/packaging/capi-ui-gesture.conf new file mode 100644 index 0000000..d48278d --- /dev/null +++ b/packaging/capi-ui-gesture.conf @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packaging/capi-ui-gesture.service b/packaging/capi-ui-gesture.service new file mode 100644 index 0000000..b992bc2 --- /dev/null +++ b/packaging/capi-ui-gesture.service @@ -0,0 +1,15 @@ +[Unit] +Description=Start the gesture server + +[Service] +User=ui_fw +Group=ui_fw +BusName=org.tizen.gesture.server +Type=dbus +SmackProcessLabel=System +ExecStart=/usr/bin/gesture-server +Restart=on-failure +RestartSec=2 + +[Install] +WantedBy=multi-user.target diff --git a/packaging/capi-ui-gesture.spec b/packaging/capi-ui-gesture.spec new file mode 100644 index 0000000..2be8bf7 --- /dev/null +++ b/packaging/capi-ui-gesture.spec @@ -0,0 +1,131 @@ +Name: capi-ui-gesture +Summary: Gesture client library and daemon +Version: 0.0.1 +Release: 1 +Group: Graphics & UI Framework/Input +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: capi-ui-gesture.service +Source2: org.tizen.gesture.server.service +Source3: capi-ui-gesture.conf +BuildRequires: cmake, coreutils +BuildRequires: pkgconfig(capi-appfw-app-common) +BuildRequires: pkgconfig(capi-appfw-app-control) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-appfw-package-manager) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(cynara-client) +BuildRequires: pkgconfig(cynara-session) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(aul) +Requires: security-config +Requires(post): /sbin/ldconfig +Requires(post): dbus +Requires(postun): /sbin/ldconfig + +%description +Gesture client library and daemon + +%package devel +Summary: Gesture client library and daemon (Development) +Group: Graphics & UI Framework/Input +Requires: %{name} = %{version}-%{release} + +%description devel +Gesture client library and daemon (Development) + +%if 0%{?gcov:1} +%package gcov +Summary: Gesture client library and daemon (gcov) +Group: Graphics & UI Framework/Input +%description gcov +Gesture client library and daemon (gcov) +%endif + +%prep +%setup -q -n %{name}-%{version} +cp %{SOURCE2} . + +%build +%if 0%{?gcov:1} +export CFLAGS+=" -fprofile-arcs -ftest-coverage" +export CXXFLAGS+=" -fprofile-arcs -ftest-coverage" +export FFLAGS+=" -fprofile-arcs -ftest-coverage" +export LDFLAGS+=" -lgcov" +%endif + +export CFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror" +export CXXFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror" +export FFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden" + +%cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \ + -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_SHARE=%TZ_SYS_SHARE +make %{?jobs:-j%jobs} + +%if 0%{?gcov:1} +mkdir -p gcov-obj +find . -name '*_dbus.c.gcno' -exec rm {} \; +find . -name '*.gcno' -exec cp '{}' gcov-obj ';' +%endif + +%install +rm -rf %{buildroot} +%make_install + +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/capi-ui-gesture.service +%install_service multi-user.target.wants capi-ui-gesture.service + +mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services +install -m 0644 %SOURCE2 %{buildroot}%{_datadir}/dbus-1/system-services/org.tizen.gesture.server.service + +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d +install -m 0644 %SOURCE3 %{buildroot}%{_sysconfdir}/dbus-1/system.d/capi-ui-gesture.conf + +%if 0%{?gcov:1} +mkdir -p %{buildroot}%{_datadir}/gcov/obj +install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj +%endif + +mkdir -p %{buildroot}/etc/dbus-1/system.d/ +cp %{SOURCE3} %{buildroot}/etc/dbus-1/system.d/capi-ui-gesture.conf + +%post +/sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%license LICENSE +%{_libdir}/lib*.so +%attr(0755,ui_fw,ui_fw) %{_bindir}/gesture-server +%attr(0644,root,root) %{_unitdir}/capi-ui-gesture.service +%attr(0644,root,root) %{_unitdir}/multi-user.target.wants/capi-ui-gesture.service +%attr(0644,root,root) %{_datadir}/dbus-1/system-services/org.tizen.gesture.server.service +%config %{_sysconfdir}/dbus-1/system.d/capi-ui-gesture.conf + +%files devel +%manifest %{name}-devel.manifest +%defattr(-,root,root,-) +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/capi-ui-gesture-client.pc +%{_libdir}/pkgconfig/capi-ui-gesture-engine.pc +%{_includedir}/gesture.h +%{_includedir}/gesture_internal.h +%{_includedir}/gesture_engine.h +%{_includedir}/gesture_common.h +%{_includedir}/gesture_common_internal.h +%{_includedir}/gesture_data_info.h + +%config(noreplace) /etc/dbus-1/system.d/capi-ui-gesture.conf + +%if 0%{?gcov:1} +%files gcov +%{_datadir}/gcov/obj/* +%endif diff --git a/packaging/org.tizen.gesture.server.service b/packaging/org.tizen.gesture.server.service new file mode 100644 index 0000000..541552c --- /dev/null +++ b/packaging/org.tizen.gesture.server.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.tizen.gesture.server +Exec=/bin/false +SystemdService=capi-ui-gesture.service \ No newline at end of file diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..c41307a --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,25 @@ +SET(SRCS + gestured_main.c +# gestured_data_manager.c + gestured_dbus.c + ../manager/gestured_client_manager.cpp + ../manager/gestured_engine_manager.cpp +) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=gnu++0x -Wall -fPIE -fpermissive") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fPIE") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fPIE") +SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIE") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +## Executable ## +ADD_EXECUTABLE(gesture-server ${SRCS}) +TARGET_LINK_LIBRARIES(gesture-server ${pkgs_LDFLAGS}) + +## Install daemon file ## +INSTALL(TARGETS gesture-server DESTINATION /usr/bin) diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c new file mode 100644 index 0000000..9a9169c --- /dev/null +++ b/server/gestured_dbus.c @@ -0,0 +1,840 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include +#include +#include +#include + +#include "gestured_dbus.h" +#include "gestured_error.h" +#include "gesture_defs.h" +#include "gestured_client_manager.h" +#include "gestured_engine_manager.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURED_SERVER_DBUS" + +#define GESTURE_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "gesture-data") +#define MAX_ERROR_BUFFER 256 + +static GHashTable *_monitoring_hash; + + +static GDBusConnection *_gdbus_connection; +static const char *_client_bus_name; +static const char *_engine_bus_name; + +static bool __is_engine_installed(const char* appid); +static bool __is_engine_launched(const char* appid); + + +int gestured_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash) +{ + LOGD("server_dbus : gestured_server_register start"); + + const char *bus_name = sender; + monitoring_info_s *m_info = NULL; + uid_t request_uid = 0; + CLIENT_LIB clientLib; + char *pkgName = NULL; + + if (bus_name == NULL) + return GESTURED_ERROR_IO_ERROR; + + g_variant_get(parameters, "(iis)", &request_uid, &clientLib, &pkgName); + LOGD("gestured_server_register > request_uid: %d", request_uid); + LOGD("gestured_server_register > clientLib: %d", clientLib); + LOGD("gestured_server_register > pkgName: %s", pkgName); + + if (clientLib == GESTURE_CLIENT_LIB_ENGINE) { + _engine_bus_name = g_strdup(bus_name); + } else if (clientLib == GESTURE_CLIENT_LIB_GESTURE) { + _client_bus_name = g_strdup(bus_name); + } + + if (clientLib == GESTURE_CLIENT_LIB_GESTURE) { + /* Check this client is already registerd to server or not */ + bool already_registered = GestureManagerClientAlreadyRegisterd(bus_name); + if (already_registered) { + LOGD("This client is skipped to register because already registerd to server"); + return GESTURED_ERROR_NONE; + } + + /* create a new client data */ + gesture_manager_client_s* client = NULL; + client = GestureManagerClientCreate(pkgName); + if (NULL == client) { + LOGE("Fail to create a new client"); + return GESTURED_ERROR_OPERATION_FAILED; + } + client->clientLib = clientLib; + client->request_uid = request_uid; + client->gdbus_bus_name = strdup(bus_name); + client->gdbus_watch_id = g_bus_watch_name_on_connection( + _gdbus_connection, + bus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + name_appeared_handler, + name_vanished_handler, + m_info, + NULL); + if (client->gdbus_watch_id == 0) { + LOGE("Failed to get identifier"); + GestureManagerClientDestroy(client); + return GESTURED_ERROR_OPERATION_FAILED; + } + + int ret = GestureManagerClientAdd(client); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to add client to GestureManager"); + return GESTURED_ERROR_OPERATION_FAILED; + } + LOGD("GestureManager Client count = %d", GestureManagerClientNums()); + } else if (clientLib == GESTURE_CLIENT_LIB_ENGINE) { + /* Check this engine is already registerd to server or not */ + bool already_registered = GestureManagerEngineAlreadyRegisterd(bus_name); + if (already_registered) { + LOGD("This engine is skipped to register because already registerd to server"); + return GESTURED_ERROR_NONE; + } + + /* create a new engine data */ + gesture_manager_engine_s* engine = NULL; + engine = GestureManagerEngineCreate(pkgName); + if (NULL == engine) { + LOGE("Fail to create a new engine"); + return GESTURED_ERROR_OPERATION_FAILED; + } + engine->clientLib = clientLib; + engine->request_uid = request_uid; + engine->gdbus_bus_name = strdup(bus_name); + engine->gdbus_watch_id = g_bus_watch_name_on_connection( + _gdbus_connection, + bus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + name_appeared_handler, + name_vanished_handler, + m_info, + NULL); + if (engine->gdbus_watch_id == 0) { + LOGE("Failed to get identifier"); + GestureManagerEngineDestroy(engine); + return GESTURED_ERROR_OPERATION_FAILED; + } + + int ret = GestureManagerEngineAdd(engine); + if (ret != HAND_GESTURE_ERROR_NONE) { + LOGE("Failed to add engine to GestureManager"); + return GESTURED_ERROR_OPERATION_FAILED; + } + LOGD("GestureManager Engine count = %d", GestureManagerEngineNums()); + } + else { + LOGE("Error type : CLIENT_LIB must be GESTURE_CLIENT_LIB_GESTURE or GESTURE_CLIENT_LIB_ENGINE"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + return GESTURED_ERROR_NONE; +} + +int gestured_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable) +{ + LOGD("server_dbus : gestured_server_register_dbus_interface start"); + + int result; + int own_id, registration_id; + GError *error = NULL; + GDBusNodeInfo *introspection_data = NULL; + + if (_gdbus_connection == NULL) { + _gdbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (_gdbus_connection == NULL) { + if (error != NULL) { + LOGE("g_bus_get_sync error message = %s", error->message); + g_error_free(error); + } + result = GESTURED_ERROR_IO_ERROR; + goto cleanup; + } + } + + own_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + GESTURE_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, + NULL, + NULL, + NULL, NULL); + if (own_id == 0) { + LOGE("Failed to register bus name"); + result = GESTURED_ERROR_IO_ERROR; + goto cleanup; + } + + LOGD("own_id = %d", own_id); + + introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error); + if (introspection_data == NULL) { + LOGE("Failed to get GDBusNodeInfo"); + result = GESTURED_ERROR_IO_ERROR; + if (error != NULL) { + LOGE("g_dbus_node_info_new_for_xml error message = %s", error->message); + g_error_free(error); + } + goto cleanup; + } + + registration_id = g_dbus_connection_register_object(_gdbus_connection, GESTURE_OBJECT_PATH, + introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL); + LOGD("registration_id = %d", registration_id); + if (registration_id == 0) { + LOGE("Failed to register object"); + result = GESTURED_ERROR_IO_ERROR; + goto cleanup; + } + + return GESTURED_ERROR_NONE; + +cleanup: + if (introspection_data) + g_dbus_node_info_unref(introspection_data); + + return result; +} + +int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid) +{ + LOGD("server_dbus : delete_monitoring_list start"); + int ret = GESTURED_ERROR_NONE; + + gesture_manager_client_s *client = NULL; + client = GestureManagerClientGet(sender); + if (!client) { + LOGD("failed to GestureManagerClientGet"); + return GESTURED_ERROR_OPERATION_FAILED; + } + ret = GestureManagerClientRemove(client); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Fail to remove client"); + return ret; + } + + return GESTURED_ERROR_NONE; +} + +int gestured_send_dbus_message(GVariant *body, const char *sender, char *cmd, CLIENT_LIB lib) +{ + LOGD("server_dbus : gestured_send_dbus_message [sender = %s] [cmd = %s]", sender, cmd); + + GError *err = NULL; + char *interface = NULL; + const char *bus_name = NULL; + + if (lib == GESTURE_CLIENT_LIB_ENGINE) { + interface = GESTURE_ENGINE_INTERFACE_NAME; + bus_name = _engine_bus_name; + } else if (lib == GESTURE_CLIENT_LIB_GESTURE) { + interface = GESTURE_CLIENT_INTERFACE_NAME; + bus_name = _client_bus_name; + } +#if 1 + char *printmsg = g_variant_print(body, true); + LOGD("send_dbus_msg body print : %s", printmsg); + g_free(printmsg); + LOGD("[_client_bus_name = %s] [_engine_bus_name = %s]", _client_bus_name, _engine_bus_name); + LOGD("send message server to clinet/engine : bus_name = %s", bus_name); +#endif + if (g_variant_is_floating(body)) + g_variant_ref(body); + + int num = GestureManagerClientNums(); + if (lib == GESTURE_CLIENT_LIB_GESTURE && !strncmp(cmd, GESTURE_CLIENT_SIGNAL_GET_RESULT, strlen(cmd)) && num > 1) { + for (int i = 0; i < num; i++) { + bus_name = GestureManagerClientGetBusName(i); +#if 1 + gesture_manager_client_s *client = GestureManagerClientGetWithBusName(bus_name); + LOGD("=========================="); + LOGD("client num = %d", num); + LOGD("client pkg = %s", client->pkg_name); + LOGD("current i = %d", i); + LOGD("bus name = %s", bus_name); + LOGD("interface = %s", interface); + LOGD("cmd = %s", cmd); + LOGD("=========================="); +#endif + if (!g_dbus_connection_emit_signal(_gdbus_connection, + bus_name, + GESTURE_OBJECT_PATH, + interface, + cmd, + body, + &err)) { + if (err != NULL) { + LOGE("Failed to send dbus message : %s", err->message); + g_error_free(err); + } + + return GESTURED_ERROR_IO_ERROR; + } + } + } else { + if (!g_dbus_connection_emit_signal(_gdbus_connection, + bus_name, + GESTURE_OBJECT_PATH, + interface, + cmd, + body, + &err)) { + if (err != NULL) { + LOGE("Failed to send dbus message : %s", err->message); + g_error_free(err); + } + + return GESTURED_ERROR_IO_ERROR; + } + } + return GESTURED_ERROR_NONE; +} + +static void _on_name_appeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + LOGD("[name: %s] [name_owner: %s]", name, name_owner); +} + +static void _on_name_vanished(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + gesture_manager_client_s *client = NULL; + client = GestureManagerClientGetWithBusName(name); + if (!client) { + LOGD("failed to GestureManagerClientGetWithBusName"); + } + int ret = GestureManagerClientRemove(client); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Fail to remove client"); + } + LOGD("GestureManager Client count = %d", GestureManagerClientNums()); + + gesture_manager_engine_s *engine = NULL; + engine = GestureManagerEngineGetWithBusName(name); + if (!engine) { + LOGD("failed to GestureManagerEngineGetWithBusName"); + } + ret = GestureManagerEngineRemove(engine); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Fail to remove engine"); + } + LOGD("GestureManager Engine count = %d", GestureManagerEngineNums()); +} + +static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, const gchar *sender, const gchar *object_path, + const gchar *iface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data) +{ + LOGD("gestured [sender: %s], [object_path: %s]", sender, object_path); + LOGD("gestured [iface_name: %s], [method_name: %s]", iface_name, method_name); + LOGD("gestured _monitoring_hash len: %d", g_hash_table_size(_monitoring_hash)); + + GVariant *reply_body = NULL; + int ret = GESTURED_ERROR_NONE; + + if (g_strcmp0(method_name, GESTURE_MSG_SERVICE_REGISTER) == 0) { + LOGD("[GESTURE_MSG_SERVICE_REGISTER] called"); + ret = gestured_server_register(parameters, &reply_body, sender, + _on_name_appeared, _on_name_vanished, &_monitoring_hash); + } + /* from client */ + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_INITIALIZE_ENGINE) == 0) { + LOGD("[GESTURE_CLIENT_MSG_INITIALIZE_ENGINE] called"); + ret = gestured_client_initialize_engine(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE) == 0) { + LOGD("[GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE] called"); + ret = gestured_client_deinitialize_engine(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_START_RECOGNITION) == 0) { + LOGD("[GESTURE_CLIENT_MSG_START_RECOGNITION] called"); + ret = gestured_client_start_recognition(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_STOP_RECOGNITION) == 0) { + LOGD("[GESTURE_CLIENT_MSG_STOP_RECOGNITION] called"); + ret = gestured_client_stop_recognition(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME) == 0) { + LOGD("[GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME] called"); + ret = gestured_client_foreach_result_time(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE) == 0) { + LOGD("[GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE] called"); + ret = gestured_client_foreach_supported_type(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE) == 0) { + LOGD("[GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE] called"); + ret = gestured_client_is_support_gesture_type(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_ENGINE_GET_INFO) == 0) { + LOGD("[GESTURE_CLIENT_MSG_ENGINE_GET_INFO] called"); + ret = gestured_client_engine_get_info(parameters, &reply_body, sender); + } + + /* from engine */ + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_SEND_RESULT) == 0) { + LOGD("[GESTURE_ENGINE_MSG_SEND_RESULT] called"); + ret = gestured_engine_send_result(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_SEND_ERROR) == 0) { + LOGD("[GESTURE_ENGINE_MSG_SEND_ERROR] called"); + ret = gestured_engine_send_error(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_SEND_MOTION_STATUS) == 0) { + LOGD("[GESTURE_ENGINE_MSG_SEND_MOTION_STATUS] called"); + ret = gestured_engine_send_motion_status(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_MAIN_START) == 0) { + LOGD("[GESTURE_ENGINE_MSG_MAIN_START] called"); + } + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO) == 0) { + LOGD("[GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO] called"); + ret = gestured_engine_send_engine_get_info(parameters, &reply_body, sender); + } + else if (g_strcmp0(method_name, "psw_test") == 0) { + LOGD("[psw_test] called"); + } + + if (ret == GESTURED_ERROR_NONE) { + LOGD("method_call successful, method_name : %s", method_name); +#if 0 + if (reply_body != NULL) { + gchar *printmsg = g_variant_print(reply_body, true); + LOGD("<<>> : %s", printmsg); + g_free(printmsg); + } +#endif + g_dbus_method_invocation_return_value(invocation, reply_body); + } else if (ret == GESTURED_ERROR_SERVICE_NOT_READY) { + // for no return because will send the result with async + LOGD("method call pass because async function"); + } else { + LOGE("method_call failed, method_name : %s", method_name); + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "gesture error"); + } + + if (reply_body) + g_variant_unref(reply_body); +} + +static const GDBusInterfaceVTable _gesture_interface_vtable = { + _gestured_client_dbus_method_call_handler, + NULL, + NULL +}; + +int gestured_register_dbus_interface(void) +{ + LOGD("gestured_register_dbus_interface"); + static gchar introspection_xml[] = + " " + " " + " " + " " + " " + " " + " " + + " " + " " + + " " + " " + + " " + " " + " " + " " + " " + " " +// " " + " " + + " " + " " + + " " + " " + + " " + " " + + " " + " " + + " " + " " + + " " + " " + " " + " " + " " + " " + " " + + " " + " " + " " + " " + + " " + " " + " " + + " " + " " + " " + + " " + " " + " " + " " + + " " + " " + " " + " " + " "; + + return gestured_server_register_dbus_interface(introspection_xml, _gesture_interface_vtable); +} + +int gestured_dbus_init(void) +{ + LOGD("gestured_dbus_init"); + int ret; + + ret = gestured_register_dbus_interface(); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Failed to register dbus interface : %d", ret); + return GESTURED_ERROR_OPERATION_FAILED; + } + + __launch_engine_service_app("org.tizen.gesture-engine-default"); + + return GESTURED_ERROR_NONE; +} + +/*******************************************/ +/* client side function : client -> daemon */ +/* must add logic to send dameon -> engine */ +/*******************************************/ + +int gestured_client_initialize_engine(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_INITIALIZE; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + /* check whether engine is launched or not */ + bool is_launched = __is_engine_launched("org.tizen.gesture-engine-default"); + if (false == is_launched) { + LOGI("Request to launch engine"); + __launch_engine_service_app("org.tizen.gesture-engine-default"); + } else { + LOGI("engine is launched"); + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +int gestured_client_deinitialize_engine(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_DEINITIALIZE; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +int gestured_client_start_recognition(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGD("gestured_client_start_recognition : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_START; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Failed to start to engine"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + return ret; +} + +int gestured_client_stop_recognition(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGE("gestured_client_stop_recognition : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_STOP; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) { + LOGE("Failed to start to engine"); + } + + return ret; +} + +int gestured_client_foreach_result_time(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +int gestured_client_foreach_supported_type(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +int gestured_client_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGD("[engineInfo] gestured_client_engine_get_info : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO; + + if (parameters == NULL) { + LOGE("failed to get parameters"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + if (ret != GESTURED_ERROR_NONE) + LOGE("Failed to start to engine"); + + return ret; +} + +/*******************************************/ +/* engine side function : engine -> daemon */ +/* must add logic to send dameon -> client */ +/*******************************************/ + +int gestured_engine_send_result(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGD("gestured_engine_send_result : sendor [%s]", sender); +#if 0 + int event, gesture_type, ltype, levent, lcount; + g_variant_get(parameters, "(iiiii)", &event, &gesture_type, <ype, &levent, &lcount); + LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount); +#endif + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_CLIENT_SIGNAL_GET_RESULT; + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_GESTURE); + return ret; +} + +int gestured_engine_send_error(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGE("gestured_engine_send_error : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_CLIENT_SIGNAL_GET_ERROR; + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_GESTURE); + return ret; +} + +int gestured_engine_send_motion_status(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGE("gestured_engine_send_motion_status : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS; + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_GESTURE); + return ret; +} + +int gestured_engine_send_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender) +{ + LOGD("[engineInfo] gestured_engine_send_engine_get_info : sendor [%s]", sender); + + int ret = GESTURED_ERROR_NONE; + char *cmd = GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO; + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_GESTURE); + return ret; +} + +static void __response_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) +{ + LOGD("app_control launch result : %d", result); +} + +static bool __is_engine_installed(const char* appid) +{ + app_info_h app_info = NULL; + int ret = app_manager_get_app_info(appid, &app_info); + if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) { + LOGE("[ERROR] There is no tts engine (%s). ret(%d)", appid, ret); + return false; + } else { + LOGI("[INFO] There is tts engine (%s)", appid); + } + + ret = app_info_destroy(app_info); + if (APP_MANAGER_ERROR_NONE != ret) + LOGE("[ERROR] Fail to destroy app_info. ret(%d)", ret); + + return true; +} + +static bool __is_engine_launched(const char* appid) +{ + int ret = -1; + bool is_installed = false; + bool is_running = false; + is_installed = __is_engine_installed(appid); + + if (false == is_installed) { + LOGW("[WARNING] tts engine(%s) is not installed", appid); + return false; + } else { + ret = app_manager_is_running(appid, &is_running); + if (APP_MANAGER_ERROR_NONE != ret) { + LOGW("[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret); + LOGI("[INFO] tts engine is installed(%d)", is_installed); + return false; + } else { + LOGI("[INFO] tts engine is%s running. is_installed(%d)", (is_running) ? "" : " not", is_installed); + } + + return is_running; + } +} + +int __launch_engine_service_app(char *appid) +{ + int ret = GESTURED_ERROR_NONE; + app_control_h app_control = NULL; + + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + LOGD("[ERROR] Fail to create, ret(%d)", ret); + return GESTURED_ERROR_OPERATION_FAILED; + } + + // Set an app ID. + ret = app_control_set_app_id(app_control, appid); + if (APP_CONTROL_ERROR_NONE != ret) { + LOGD("[ERROR] Fail to set app id, ret(%d)", ret); + app_control_destroy(app_control); + return GESTURED_ERROR_OPERATION_FAILED; + } + + // Sent launch request + ret = app_control_send_launch_request(app_control, __response_cb, NULL); + if (APP_CONTROL_ERROR_NONE != ret) { + LOGD("[ERROR] Fail to send launch request, ret(%d)", ret); + app_control_destroy(app_control); + return GESTURED_ERROR_OPERATION_FAILED; + } + + // Destroy app control + ret = app_control_destroy(app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + LOGD("[ERROR] Fail to destroy, ret(%d)", ret); + return GESTURED_ERROR_OPERATION_FAILED; + } + + return ret; +} + diff --git a/server/gestured_dbus.h b/server/gestured_dbus.h new file mode 100644 index 0000000..03d5452 --- /dev/null +++ b/server/gestured_dbus.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURED_DBUS_H__ +#define __TIZEN_UIX_GESTURED_DBUS_H__ + +#include +#include +#include "gesture_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct monitoring_info { + int watcher_id; + char *bus_name; + uid_t uid; + char *pkg_name; +} monitoring_info_s; + +int gestured_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash); +int gestured_server_unregister(GVariant *parameters, GVariant **reply_body, const gchar *sender, GHashTable **monitoring_hash); +int gestured_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable); +int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid); +int gestured_send_dbus_message(GVariant *body, const char *sender, char *cmd, CLIENT_LIB lib); + +/* common function */ +int gestured_dbus_init(void); +int gestured_register_dbus_interface(void); + +/* client side function : client -> daemon */ +int gestured_client_initialize_engine(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_deinitialize_engine(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_start_recognition(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_stop_recognition(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_foreach_result_time(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_foreach_supported_type(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender); + +/* engine side function : engine -> daemon */ +int gestured_engine_send_result(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_engine_send_error(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_engine_send_motion_status(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_engine_send_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender); + +int __launch_engine_service_app(char *appid); + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURED_DBUS_H__ */ diff --git a/server/gestured_error.h b/server/gestured_error.h new file mode 100644 index 0000000..63a81e5 --- /dev/null +++ b/server/gestured_error.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 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 __TIZEN_UIX_GESTURED_ERROR_H__ +#define __TIZEN_UIX_GESTURED_ERROR_H__ + +/** + * @file gestured_error.h + * @brief This file contains gesture error enumeration. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TIZEN_ERROR_GESTURE +#define TIZEN_ERROR_GESTURE -0x03090000 +#endif + +/** + * @brief Enumeration for gesture server error. + */ +enum gestured_server_error { + GESTURED_ERROR_NONE = TIZEN_ERROR_NONE, + GESTURED_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, + GESTURED_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, + GESTURED_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, + GESTURED_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, + GESTURED_ERROR_SERVICE_NOT_READY = TIZEN_ERROR_GESTURE | 0x02, + GESTURED_ERROR_OPERATION_FAILED = TIZEN_ERROR_GESTURE | 0x04, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_UIX_GESTURED_ERROR_H__ */ diff --git a/server/gestured_main.c b/server/gestured_main.c new file mode 100644 index 0000000..d2ad4c7 --- /dev/null +++ b/server/gestured_main.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include +#include +#include +#include + +//#include "gestured_data_manager.h" +#include "gestured_dbus.h" +#include "gestured_error.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURED_SERVER_MAIN" + +#define MAX_ERROR_BUFFER 256 + +static GMainLoop *main_loop; +static GIOChannel *channel = NULL; +static guint source = 0; + +static gboolean signal_handler(GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + LOGD("signal_handler funaction start"); + + struct signalfd_siginfo fd_signal; + ssize_t size; + int sfd; + + sfd = g_io_channel_unix_get_fd(channel); + size = read(sfd, &fd_signal, sizeof(struct signalfd_siginfo)); + if (size != sizeof(struct signalfd_siginfo)) { + LOGE("Failed to read signal"); + return TRUE; + } + + LOGE("sender : %d, signal : %d", fd_signal.ssi_pid, fd_signal.ssi_signo); + g_main_loop_quit(main_loop); + + return TRUE; +} + +static void register_signal_handler() +{ + LOGD("register_signal_handler funaction start"); + + sigset_t mask; + int sfd; + int ret; + char error_buffer[MAX_ERROR_BUFFER]; + + ret = sigemptyset(&mask); + if (ret < 0) { + strerror_r(errno, error_buffer, MAX_ERROR_BUFFER); + LOGE("sigemptyset(): %s", error_buffer); + } + + ret = sigaddset(&mask, SIGTERM); + if (ret < 0) { + strerror_r(errno, error_buffer, MAX_ERROR_BUFFER); + LOGE("sigaddset(): %s", error_buffer); + } + + ret = sigprocmask(SIG_BLOCK, &mask, NULL); + if (ret < 0) { + strerror_r(errno, error_buffer, MAX_ERROR_BUFFER); + LOGE("sigprocmask(): %s", error_buffer); + } + + sfd = signalfd(-1, &mask, SFD_NONBLOCK); + if (sfd < 0) { + strerror_r(errno, error_buffer, MAX_ERROR_BUFFER); + LOGE("signalfd(): %s", error_buffer); + } + + channel = g_io_channel_unix_new(sfd); + g_io_channel_set_close_on_unref(channel, TRUE); + g_io_channel_set_encoding(channel, NULL, NULL); + g_io_channel_set_buffered(channel, FALSE); + source = g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_OUT, signal_handler, NULL); + LOGD("source : %u", source); +} + +static void unregister_signal_handler() +{ + LOGD("unregister_signal_handler funaction start"); + + if (source > 0) + g_source_remove(source); + if (channel) + g_io_channel_unref(channel); +} + +int main(int argc, char** argv) +{ + LOGD("main funaction start"); + + int ret; + main_loop = g_main_loop_new(NULL, FALSE); + if (main_loop == NULL) { + LOGE("Failed to create GMainLoop structure"); + return -1; + } + + ret = gestured_dbus_init(); + if (ret != GESTURED_ERROR_NONE) + LOGW("Failed to init dbus"); + + register_signal_handler(); + + g_main_loop_run(main_loop); + + unregister_signal_handler(); + + g_main_loop_unref(main_loop); + + return 0; +} diff --git a/src/Gesture.cpp b/src/Gesture.cpp deleted file mode 100644 index 1b74537..0000000 --- a/src/Gesture.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 -#include "GestureSensor.h" - -#define FEATURE_GESTURE "tizen.org/feature/sensor.gesture_recognition" - -#define GESTURE_FIRST GESTURE_DOUBLE_TAP -#define GESTURE_LAST GESTURE_WRIST_UP -#define IS_VALID_GESTURE(X) (GESTURE_FIRST <= (X) && (X) <= GESTURE_LAST) - -using namespace gesture; - -struct _gesture_handle_s { - GestureSensor *sensor; -}; - -EXPORT_API int gesture_is_supported(gesture_type_e gesture, bool* supported) -{ - if (supported) - *supported = false; - - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(supported); - IF_FAIL_RETURN(IS_VALID_GESTURE(gesture), ERR_INVALID_PARAMETER); - - *supported = GestureSensor::isSupported(gesture); - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_create(gesture_h *handle) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(handle); - - _gesture_handle_s *hdl = static_cast(malloc(sizeof(_gesture_handle_s))); - IF_FAIL_RETURN_TAG(hdl, ERR_OPERATION_FAILED, _E, "Memory allocation failed"); - - hdl->sensor = new(std::nothrow) GestureSensor(); - if (hdl->sensor == NULL) { - _E("Memory allocation failed"); - free(hdl); - return ERR_OPERATION_FAILED; - } - - *handle = hdl; - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_release(gesture_h handle) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(handle); - - delete handle->sensor; - free(handle); - - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_start_recognition(gesture_h handle, gesture_type_e gesture, gesture_option_e option, gesture_recognition_cb callback, void *user_data) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(handle); - ASSERT_NOT_NULL(callback); - IF_FAIL_RETURN(IS_VALID_GESTURE(gesture), ERR_INVALID_PARAMETER); - - if (option == GESTURE_OPTION_DEFAULT) { - handle->sensor->setPowerSave(true); - } else if (option == GESTURE_OPTION_ALWAYS_ON) { - handle->sensor->setPowerSave(false); - } else { - return ERR_INVALID_PARAMETER; - } - - if (!handle->sensor->setGesture(gesture)) { - return GESTURE_ERROR_NOT_SUPPORTED; - } - - handle->sensor->setCallback(callback); - handle->sensor->setUserData(user_data); - - if (!handle->sensor->start()) { - return ERR_OPERATION_FAILED; - } - - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_stop_recognition(gesture_h handle) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(handle); - - IF_FAIL_RETURN(handle->sensor->stop(), GESTURE_ERROR_NOT_STARTED); - - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_get_event(const gesture_data_h data, gesture_event_e *event) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(data); - ASSERT_NOT_NULL(event); - - if (data->gesture == GESTURE_TILT) - return GESTURE_ERROR_NOT_SUPPORTED; - - *event = static_cast(data->event); - - return ERR_NONE; - //LCOV_EXCL_STOP -} - -EXPORT_API int gesture_get_tilt(const gesture_data_h data, int *x, int *y) -{ - ASSERT_SUPPORTED(FEATURE_GESTURE); - //LCOV_EXCL_START - ASSERT_NOT_NULL(data); - ASSERT_NOT_NULL(x); - ASSERT_NOT_NULL(y); - - if (data->gesture != GESTURE_TILT) - return ERR_NOT_SUPPORTED; - - *x = data->tilt_x; - *y = data->tilt_y; - - return ERR_NONE; - //LCOV_EXCL_STOP -} diff --git a/src/GestureSensor.cpp b/src/GestureSensor.cpp deleted file mode 100644 index b4f6617..0000000 --- a/src/GestureSensor.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 "GestureSensor.h" - -using namespace gesture; - -//LCOV_EXCL_START -GestureSensor::GestureSensor() : - __gestureType(static_cast(UNDEFINED)), - __callback(NULL), - __userData(NULL), - __sensorAdapter(this) -{ -} - -GestureSensor::~GestureSensor() -{ -} - -bool GestureSensor::setGesture(gesture_type_e type) -{ - sensor_type_t sensor = __toSensor(type); - IF_FAIL_RETURN(sensor != UNKNOWN_SENSOR, false); - - __gestureType = type; - __sensorAdapter.setSensor(sensor); - return true; -} - -void GestureSensor::setPowerSave(bool ps) -{ - __sensorAdapter.setPowerSave(ps); -} - -void GestureSensor::setCallback(gesture_recognition_cb cb) -{ - __callback = cb; -} - -void GestureSensor::setUserData(void* data) -{ - __userData = data; -} - -bool GestureSensor::start() -{ - return __sensorAdapter.start(); -} - -bool GestureSensor::stop() -{ - return __sensorAdapter.stop(); -} - -bool GestureSensor::isSupported(gesture_type_e type) -{ - sensor_type_t sensor = __toSensor(type); - IF_FAIL_RETURN(sensor != UNKNOWN_SENSOR, false); - - return SensorAdapter::isSupported(sensor); -} - -void GestureSensor::onEvent(double timestamp, float* values, int accuracy) -{ - _gesture_data_s data; - data.gesture = __gestureType; - - /* TODO: This is the default form. - For each sensor, this part needs to adapt accordingly */ - data.event = static_cast(values[0]); - - __callback(__gestureType, &data, timestamp, static_cast(ERR_NONE), __userData); -} - -sensor_type_t GestureSensor::__toSensor(gesture_type_e type) -{ - switch (type) { - case GESTURE_PICK_UP: - return GESTURE_MOVEMENT_SENSOR; - case GESTURE_WRIST_UP: - return GESTURE_WRIST_UP_SENSOR; - default: - return UNKNOWN_SENSOR; - } -} -//LCOV_EXCL_STOP diff --git a/src/GestureSensor.h b/src/GestureSensor.h deleted file mode 100644 index 0599538..0000000 --- a/src/GestureSensor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 __GESTURE_SENSOR_H__ -#define __GESTURE_SENSOR_H__ - -#include -#include "SensorAdapter.h" - -struct _gesture_data_s { - int gesture; - int event; - int tilt_x; - int tilt_y; -}; - -namespace gesture { - - class GestureSensor : public ISensorListener { - public: - GestureSensor(); - ~GestureSensor(); - - bool setGesture(gesture_type_e type); - void setPowerSave(bool ps); - void setCallback(gesture_recognition_cb cb); - void setUserData(void* data); - - bool start(); - bool stop(); - - static bool isSupported(gesture_type_e type); - - private: - void onEvent(double timestamp, float* values, int accuracy); - - static sensor_type_t __toSensor(gesture_type_e type); - - gesture_type_e __gestureType; - gesture_recognition_cb __callback; - void *__userData; - SensorAdapter __sensorAdapter; - }; - -} - -#endif /* __GESTURE_SENSOR_H__ */ diff --git a/src/SensorAdapter.cpp b/src/SensorAdapter.cpp deleted file mode 100644 index 07aee57..0000000 --- a/src/SensorAdapter.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 -#include -#include "SensorAdapter.h" - -#define SENSOR_EVENT(X) (((int)(X) << 16) | 0x01) - -using namespace gesture; - -SensorAdapter::SensorAdapter(ISensorListener* listener) : - __sensorHandle(-1), - __sensorType(UNKNOWN_SENSOR), - __powerSave(true), - __listener(listener) -{ -} - -SensorAdapter::~SensorAdapter() -{ - stop(); -} - -//LCOV_EXCL_START -void SensorAdapter::setSensor(sensor_type_t type) -{ - __sensorType = type; -} - -void SensorAdapter::setPowerSave(bool ps) -{ - __powerSave = ps; - - if (__sensorHandle < 0) - return; - - sensord_set_attribute_int(__sensorHandle, SENSORD_ATTRIBUTE_PAUSE_POLICY, - __powerSave ? SENSORD_PAUSE_ALL : SENSORD_PAUSE_NONE); -} - -void SensorAdapter::setAttribute(int key, int value) -{ - IF_FAIL_VOID_TAG(__sensorHandle >= 0, _W, "Sensor not started"); - sensord_set_attribute_int(__sensorHandle, key, value); -} - -bool SensorAdapter::start() -{ - int err; - sensor_t sensor; - - err = sensord_get_default_sensor(__sensorType, &sensor); - IF_FAIL_RETURN_TAG(err == 0, false, _E, "Getting sensor failed (%d)", err); - - __sensorHandle = sensord_connect(sensor); - IF_FAIL_RETURN_TAG(__sensorHandle >= 0, false, _E, "Connection failed"); - - if (!sensord_register_event(__sensorHandle, SENSOR_EVENT(__sensorType), 0, 0, __eventCb, this)) { - _E("Event registration failed"); - sensord_disconnect(__sensorHandle); - __sensorHandle = -1; - return false; - } - - if (!sensord_start(__sensorHandle, __powerSave ? SENSOR_OPTION_DEFAULT : SENSOR_OPTION_ALWAYS_ON)) { - _E("Starting failed"); - sensord_unregister_event(__sensorHandle, SENSOR_EVENT(__sensorType)); - sensord_disconnect(__sensorHandle); - __sensorHandle = -1; - return false; - } - - return true; -} - -bool SensorAdapter::stop() -{ - IF_FAIL_RETURN(__sensorHandle >= 0, false); - - sensord_stop(__sensorHandle); - sensord_unregister_event(__sensorHandle, SENSOR_EVENT(__sensorType)); - sensord_disconnect(__sensorHandle); - __sensorHandle = -1; - - return true; -} - -bool SensorAdapter::isSupported(sensor_type_t type) -{ - sensor_t sensor = sensord_get_sensor(type); - return (sensor != NULL); -} - -double SensorAdapter::__getEpoch(unsigned long long monotonic) -{ - struct timespec ts; - struct timeval tv; - double timeDiff; - double timestamp; - - clock_gettime(CLOCK_MONOTONIC, &ts); - timeDiff = (ts.tv_sec * 1000000000.0 + ts.tv_nsec) / 1000000.0 - monotonic / 1000.0; - - gettimeofday(&tv, NULL); - timestamp = tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0 - timeDiff; - return timestamp; -} - -void SensorAdapter::__onEvent(sensor_data_t *eventData) -{ - double timestamp = __getEpoch(eventData->timestamp); - __listener->onEvent(timestamp / 1000.0, eventData->values, eventData->accuracy); -} - -void SensorAdapter::__eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData) -{ - SensorAdapter *instance = static_cast(cbData); - instance->__onEvent(eventData); -} -//LCOV_EXCL_STOP diff --git a/src/SensorAdapter.h b/src/SensorAdapter.h deleted file mode 100644 index 7ce9fc4..0000000 --- a/src/SensorAdapter.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 __GESTURE_SENSOR_ADAPTER_H__ -#define __GESTURE_SENSOR_ADAPTER_H__ - -#include -#include "TypesInternal.h" -#include "ISensorListener.h" - -namespace gesture { - - class SensorAdapter { - public: - SensorAdapter(ISensorListener* listener); - ~SensorAdapter(); - - void setSensor(sensor_type_t type); - void setPowerSave(bool ps); - void setAttribute(int key, int value); - - bool start(); - bool stop(); - - static bool isSupported(sensor_type_t type); - - private: - double __getEpoch(unsigned long long monotonic); - void __onEvent(sensor_data_t* eventData); - - static void __eventCb(sensor_t sensor, unsigned int eventType, sensor_data_t *eventData, void *cbData); - - int __sensorHandle; - sensor_type_t __sensorType; - bool __powerSave; - ISensorListener *__listener; - }; - -} - -#endif /* __GESTURE_SENSOR_ADAPTER_H__ */ diff --git a/src/TypesInternal.h b/src/TypesInternal.h deleted file mode 100644 index 04cf1fb..0000000 --- a/src/TypesInternal.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * 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 _GESTURE_TYPES_INTERNAL_H_ -#define _GESTURE_TYPES_INTERNAL_H_ - -#include -#include -#include - -#define UNDEFINED -1 - -#define ERR_NONE TIZEN_ERROR_NONE -#define ERR_INVALID_PARAMETER TIZEN_ERROR_INVALID_PARAMETER -#define ERR_INVALID_OPERATION TIZEN_ERROR_INVALID_OPERATION -#define ERR_OUT_OF_MEMORY TIZEN_ERROR_OUT_OF_MEMORY -#define ERR_PERMISSION_DENIED TIZEN_ERROR_PERMISSION_DENIED -#define ERR_NOT_SUPPORTED TIZEN_ERROR_NOT_SUPPORTED -#define ERR_NO_DATA TIZEN_ERROR_NO_DATA -#define ERR_ALREADY_STARTED (TIZEN_ERROR_CONTEXT | 0x01) -#define ERR_NOT_STARTED (TIZEN_ERROR_CONTEXT | 0x02) -#define ERR_OUT_OF_RANGE (TIZEN_ERROR_CONTEXT | 0x03) -#define ERR_OPERATION_FAILED (TIZEN_ERROR_CONTEXT | 0x04) -#define ERR_RULE_ENABLED (TIZEN_ERROR_CONTEXT | 0x05) -#define ERR_RULE_NOT_ENABLED (TIZEN_ERROR_CONTEXT | 0x06) -#define ERR_INVALID_RULE (TIZEN_ERROR_CONTEXT | 0x07) -#define ERR_RULE_NOT_EXIST (TIZEN_ERROR_CONTEXT | 0x08) -#define ERR_INVALID_DATA ERR_INVALID_RULE -#define ERR_DATA_EXIST (TIZEN_ERROR_CONTEXT | 0X09) - -/* Logging and Error Handling */ -#define _I SLOGI -#define _D SLOGD -#define _W SLOGW -#define _E SLOGE -#define _SI SECURE_SLOGI -#define _SD SECURE_SLOGD -#define _SW SECURE_LOGW -#define _SE SECURE_SLOGE - -#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \ - do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0) - -#define IF_FAIL_RETURN(cond, ret) \ - do { if (!(cond)) { return ret; } } while (0) - -#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \ - do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0) - -#define IF_FAIL_VOID(cond) \ - do { if (!(cond)) { return; } } while (0) - -#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \ - do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0) - -#define IF_FAIL_CATCH(cond) \ - do { if (!(cond)) { goto CATCH; } } while (0) - -#define IS_FAILED(X) ((X) != ERR_NONE) - -#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed") -#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, ERR_INVALID_PARAMETER, _E, "Parameter null") - -#define ASSERT_SUPPORTED(feature) \ - do { \ - int __result = gesture::isSupported(feature); \ - if (__result != ERR_NONE) return __result; \ - } while (0) - -namespace gesture { - int isSupported(const char *feature); -} - -#endif /* _GESTURE_TYPES_INTERNAL_H_ */ -- 2.7.4 From f730eed310831186d128c9b7d5331bcf143a6730 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 14 Aug 2020 15:59:05 +0900 Subject: [PATCH 05/14] [ACR-1585][gesture][Add changes in gesture.h] - Add APIs to set and unset error callback Change-Id: Idb5a113ee6f69788386c0119e1baf451d762fb17 Signed-off-by: sooyeon.kim --- client/gesture.c | 44 ++++++++++++++++- client/gesture_client_dbus.c | 20 ++++++-- client/gesture_client_dbus.h | 2 +- client/gesture_main.h | 13 +++-- doc/uix_gesture_doc.h | 4 +- include/gesture.h | 115 +++++++++++++++++++++++++++++++++---------- include/gesture_common.h | 11 ++++- server/gestured_dbus.c | 29 ++++++----- 8 files changed, 184 insertions(+), 54 deletions(-) diff --git a/client/gesture.c b/client/gesture.c index d6f8d47..96fe1be 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -281,6 +281,10 @@ EXPORT_API int hand_gesture_start_recognition(hand_gesture_h handle, hand_gestur int ret = HAND_GESTURE_ERROR_NONE; + /* Set recognition callback and userdata in the handle */ + handle->recog_cb = callback; + handle->recog_user_data = user_data; + hand_gesture_data_h gesture_data = (hand_gesture_data_h)calloc(1, sizeof(struct hand_gesture_data_s)); if (!gesture_data) { return HAND_GESTURE_ERROR_OUT_OF_MEMORY; @@ -309,6 +313,10 @@ EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle) return HAND_GESTURE_ERROR_OPERATION_FAILED; } + /* Unset recognition callback and userdata in the handle */ + handle->recog_cb = NULL; + handle->recog_user_data = NULL; + return HAND_GESTURE_ERROR_NONE; } @@ -332,7 +340,7 @@ EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine int ret = HAND_GESTURE_ERROR_NONE; - ret = gesture_client_dbus_engine_get_info(handle->gdbus_connection, engine_app_id, engine_name); + ret = gesture_client_dbus_get_engine_info(handle->gdbus_connection, engine_app_id, engine_name); if (ret != HAND_GESTURE_ERROR_NONE) { LOGE("Failed to get engine info : %d", ret); return HAND_GESTURE_ERROR_OPERATION_FAILED; @@ -340,3 +348,37 @@ EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name); return ret; } + +EXPORT_API int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data) +{ + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + ASSERT_NOT_NULL(callback); + + LOGD("[DEBUG] Set error_cb"); + + int ret = HAND_GESTURE_ERROR_NONE; + + handle->error_cb = callback; + handle->error_user_data = user_data; + + + return ret; +} + +EXPORT_API int hand_gesture_unset_error_cb(hand_gesture_h handle) +{ + CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); + + LOGD("[DEBUG] Unset error_cb"); + + int ret = HAND_GESTURE_ERROR_NONE; + + handle->error_cb = NULL; + handle->error_user_data = NULL; + + + return ret; +} diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c index 0683bf0..91b139d 100644 --- a/client/gesture_client_dbus.c +++ b/client/gesture_client_dbus.c @@ -133,10 +133,24 @@ static void _handle_gesture_cb(GDBusConnection *connection, g_gesture_data->event = levent; g_gesture_data->detected_Count = lcount; - g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data); +// g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data); + if (_handle->recog_cb) { + LOGD("[CLIENT DBUS] Send recognition result. gesture_type(%d)", gesture_type); + _handle->recog_cb(_handle, gesture_type, 0, HAND_GESTURE_ERROR_NONE, _handle->recog_user_data); + } } else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ERROR) == 0) { - + int error; + char* err_msg = NULL; + g_variant_get(parameters, "(is)", &error, err_msg); + LOGD("[CLIENT DBUS] error(%d)", error); + + if (_handle->error_cb) { + LOGD("[CLIENT DBUS] Send error"); + _handle->error_cb(_handle, (hand_gesture_error_e)error, err_msg, _handle->error_user_data); + } else { + LOGW("[CLIENT DBUS] There is no error callback"); + } } else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS) == 0) { @@ -639,7 +653,7 @@ int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connectio } -int gesture_client_dbus_engine_get_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name) +int gesture_client_dbus_get_engine_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name) { int ret; GDBusMessage *reply = NULL; diff --git a/client/gesture_client_dbus.h b/client/gesture_client_dbus.h index fde91b3..b3666be 100644 --- a/client/gesture_client_dbus.h +++ b/client/gesture_client_dbus.h @@ -45,7 +45,7 @@ int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection); int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection); int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection); int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported); -int gesture_client_dbus_engine_get_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name); +int gesture_client_dbus_get_engine_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name); #ifdef __cplusplus } diff --git a/client/gesture_main.h b/client/gesture_main.h index 3cbe67e..c35f331 100644 --- a/client/gesture_main.h +++ b/client/gesture_main.h @@ -29,10 +29,15 @@ extern "C" #endif struct hand_gesture_s { - GDBusConnection *gdbus_connection; - guint server_watcher_id; - int monitor_id; - int server_monitor_id; + GDBusConnection *gdbus_connection; + guint server_watcher_id; + int monitor_id; + int server_monitor_id; + + hand_gesture_recognition_cb recog_cb; + void* recog_user_data; + hand_gesture_error_cb error_cb; + void* error_user_data; }; #ifdef __cplusplus diff --git a/doc/uix_gesture_doc.h b/doc/uix_gesture_doc.h index 7def9e3..042d0dd 100644 --- a/doc/uix_gesture_doc.h +++ b/doc/uix_gesture_doc.h @@ -36,13 +36,11 @@ * 4. Stop recognizing
* 5. Destroy a handle
* The Gesture API also notifies you (by callback mechanism) when the input gesture is recognized. - * An application should register a callback function to receive the recognized results with gesture_client_start_recognition(). + * An application should register a callback function to receive the recognized results with hand_gesture_start_recognition(). * * @section CAPI_UIX_GESTURE_MODULE_FEATURE Related Features * This API is related with the following features:
- * - http://tizen.org/feature/sensor.accelerometer
* - http://tizen.org/feature/sensor.gesture_recognition
- * - http://tizen.org/feature/sensor.gyroscope
* It is recommended to design feature related codes in your application for reliability.
* You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
* To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
diff --git a/include/gesture.h b/include/gesture.h index 65ce9a8..6b4f13e 100644 --- a/include/gesture.h +++ b/include/gesture.h @@ -23,7 +23,7 @@ extern "C" { #endif -/** +/* * @file gesture.h * @brief This file contains hand gesture's APIs. */ @@ -43,30 +43,52 @@ typedef struct hand_gesture_s *hand_gesture_h; * @brief Called when a gesture is detected. * * @since_tizen @if WEARABLE 6.0 @endif + * @remarks The @a handle is managed by the platform and will be released when hand_gesture_destroy() is called. * - * @param[in] gesture Gesture type detected - * @param[in] data Detailed information of the detected gesture.@n - * hand_gesture_get_event() or gesture_get_tilt() can be used to extract the information from @c data. + * @param[in] handle A gesture handle + * @param[in] gesture A gesture type detected * @param[in] timestamp The time when the gesture is detected. Epoch time in seconds. * @param[in] error An error value. It can be one of the following error values:@n * #HAND_GESTURE_ERROR_NONE, if the operation succeeded.@n * #HAND_GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported in the current profile.@n * #HAND_GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error.@n * #HAND_GESTURE_ERROR_PERMISSION_DENIED, if the application has no permission to use this. - * @param[in] user_data The user data had passed to hand_gesture_start_recognition() + * @param[in] user_data The user data is passed to hand_gesture_start_recognition() * - * @pre hand_gesture_start_recognition() + * @see hand_gesture_start_recognition() */ -typedef void(* hand_gesture_recognition_cb)(hand_gesture_type_e gesture, const hand_gesture_data_h data, double timestamp, hand_gesture_error_e error, void *user_data); +typedef void(* hand_gesture_recognition_cb)(hand_gesture_h handle, hand_gesture_type_e gesture, double timestamp, hand_gesture_error_e error, void *user_data); /** - * @brief Checks whether the gesture is supported or not. + * @brief Called when an error is occurred. + * + * @since_tizen @if WEARABLE 6.0 @endif + * @remarks The @a handle is the same object for which the callback was set. + * The @a handle is available until hand_gesture_destroy() is called. + * The @a msg is managed by the platform and will be released when invoking this callback function is finished. + * + * @param[in] handle A gesture handle + * @param[in] error An error value. It can be one of the following error values: @n + * #HAND_GESTURE_ERROR_INVALID_PARAMETER, + * #HAND_GESTURE_ERROR_INVALID_OPERATION, + * #HAND_GESTURE_ERROR_OUT_OF_MEMORY, + * #HAND_GESTURE_ERROR_OPERATION_FAILED + * @param[in] msg An error message from gesture engine service + * @param[in] user_data The user data is passed to hand_gesture_set_error_cb() + * + * @see hand_gesture_set_error_cb() + * @see hand_gesture_unset_error_cb() + */ +typedef void(* hand_gesture_error_cb)(hand_gesture_h handle, hand_gesture_error_e error, const char* msg, void *user_data); + +/** + * @brief Checks whether a gesture is supported or not. * @details Check if the given gesture type is supported in the current device. * * @since_tizen @if WEARABLE 6.0 @endif * - * @param[in] handle The gesture handle - * @param[in] gesture Gesture type to be checked + * @param[in] handle A gesture handle + * @param[in] gesture A gesture type to be checked * @param[out] supported @c true if the gesture is recognizable in the current device,@n * @c false otherwise * @@ -86,7 +108,7 @@ int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e ge * @privilege %http://tizen.org/privilege/appmanager.launch * @remarks If the function succeeds, @a handle must be released with hand_gesture_destroy(). * - * @param[out] handle The gesture handle + * @param[out] handle A gesture handle * * @return 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful @@ -95,6 +117,7 @@ int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e ge * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #HAND_GESTURE_ERROR_OUT_OF_MEMORY Out of memory * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed + * * @see hand_gesture_destroy() */ int hand_gesture_create(hand_gesture_h *handle); @@ -104,30 +127,32 @@ int hand_gesture_create(hand_gesture_h *handle); * * @since_tizen @if WEARABLE 6.0 @endif * - * @param[in] handle The gesture handle + * @param[in] handle A gesture handle * * @return 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Not supported * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed + * * @see hand_gesture_create() */ int hand_gesture_destroy(hand_gesture_h handle); /** - * @brief Sets the option for gesture recognition. + * @brief Sets an option for gesture recognition. * * @since_tizen @if WEARABLE 6.0 @endif + * @remarks If you would like to set a gesture option, you should call this function before hand_gesture_start_recognition() is invoked. \n + * If you do not call this function, #HAND_GESTURE_OPTION_DEFAULT will be set as the default option. * - * @param[in] handle Gesture handle to be used to control the gesture event - * @param[in] option Detection option + * @param[in] handle A gesture handle used to control the gesture event + * @param[in] option An option for detecting gestures * * @return @c 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error * * @see hand_gesture_start_recognition() @@ -142,10 +167,10 @@ int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option) * @privlevel public * @privilege %http://tizen.org/privilege/appmanager.launch * - * @param[in] handle Gesture handle to be used to control the gesture event - * @param[in] gesture Gesture type to be monitored - * @param[in] callback Callback function to receive gesture events - * @param[in] user_data User data to be passed to the callback function + * @param[in] handle A gesture handle used to control the gesture event + * @param[in] gesture A gesture type to be monitored + * @param[in] callback A callback function to receive gesture events + * @param[in] user_data A user data to be passed to the callback function * * @return @c 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful @@ -153,6 +178,7 @@ int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option) * @retval #HAND_GESTURE_ERROR_PERMISSION_DENIED Permission denied * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used * @retval #HAND_GESTURE_ERROR_ALREADY_STARTED The @c handle is being used already + * @retval #HAND_GESTURE_ERROR_OUT_OF_MEMORY Out of memory * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error * * @pre hand_gesture_create() @@ -167,7 +193,7 @@ int hand_gesture_start_recognition(hand_gesture_h handle, hand_gesture_type_e ge * * @since_tizen @if WEARABLE 6.0 @endif * - * @param[in] handle Gesture handle to release its callback function registered + * @param[in] handle A gesture handle * * @return @c 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful @@ -179,25 +205,62 @@ int hand_gesture_start_recognition(hand_gesture_h handle, hand_gesture_type_e ge int hand_gesture_stop_recognition(hand_gesture_h handle); /** - * @brief Gets the gesture engine information. + * @brief Gets a gesture engine information. * * @since_tizen @if WEARABLE 6.0 @endif * @remarks The @a engine_app_id and the @a engine_name should be released using free(). * - * @param[in] handle Gesture handle to release its callback function registered - * @param[out] engine_app_id The gesture engine app ID - * @param[out] engine_name The gesture engine name + * @param[in] handle A gesture handle + * @param[out] engine_app_id A gesture engine app ID + * @param[out] engine_name A gesture engine name * * @return @c 0 on success, otherwise a negative error value * @retval #HAND_GESTURE_ERROR_NONE Successful * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used - * @retval #HAND_GESTURE_ERROR_NOT_STARTED Nothing is started using the @c handle * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error */ int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name); /** + * @brief Sets a callback function to be invoked when an error is occurred. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle A gesture handle + * @param[in] callback A callback function invoked when an error is occurred + * @param[in] user_data A user data to be passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_error_cb() + * @see hand_gesture_unset_error_cb() + */ +int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data); + +/** + * @brief Unsets a callback function to be invoked when an error is occurred. + * + * @since_tizen @if WEARABLE 6.0 @endif + * + * @param[in] handle A gesture handle + * + * @return @c 0 on success, otherwise a negative error value + * @retval #HAND_GESTURE_ERROR_NONE Successful + * @retval #HAND_GESTURE_ERROR_NOT_SUPPORTED Gesture recognition is not supported + * @retval #HAND_GESTURE_ERROR_INVALID_PARAMETER Invalid parameter used + * @retval #HAND_GESTURE_ERROR_OPERATION_FAILED Operation failed because of a system error + * + * @see hand_gesture_set_error_cb() + */ +int hand_gesture_unset_error_cb(hand_gesture_h handle); + + +/** * @} */ diff --git a/include/gesture_common.h b/include/gesture_common.h index 491e5d7..0aaf39a 100644 --- a/include/gesture_common.h +++ b/include/gesture_common.h @@ -28,12 +28,17 @@ extern "C" { #define TIZEN_ERROR_GESTURE -0x03090000 #endif -/** +/* * @file gesture_common.h * @brief This file contains gesture's common struct info. */ /** + * @addtogroup CAPI_UIX_GESTURE_MODULE + * @{ + */ + +/** * @brief Delivery through hand_gesture_recognition_cb() of gesture data handle. * @since_tizen @if WEARABLE 6.0 @endif */ @@ -79,6 +84,10 @@ typedef enum { } hand_gesture_option_e; +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 9a9169c..539a202 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -282,32 +282,32 @@ int gestured_send_dbus_message(GVariant *body, const char *sender, char *cmd, CL LOGD("cmd = %s", cmd); LOGD("=========================="); #endif - if (!g_dbus_connection_emit_signal(_gdbus_connection, + if (!g_dbus_connection_emit_signal(_gdbus_connection, bus_name, GESTURE_OBJECT_PATH, interface, cmd, body, &err)) { - if (err != NULL) { - LOGE("Failed to send dbus message : %s", err->message); - g_error_free(err); - } + if (err != NULL) { + LOGE("Failed to send dbus message : %s", err->message); + g_error_free(err); + } - return GESTURED_ERROR_IO_ERROR; - } + return GESTURED_ERROR_IO_ERROR; + } } } else { if (!g_dbus_connection_emit_signal(_gdbus_connection, - bus_name, - GESTURE_OBJECT_PATH, - interface, - cmd, - body, - &err)) { + bus_name, + GESTURE_OBJECT_PATH, + interface, + cmd, + body, + &err)) { if (err != NULL) { LOGE("Failed to send dbus message : %s", err->message); - g_error_free(err); + g_error_free(err); } return GESTURED_ERROR_IO_ERROR; @@ -477,7 +477,6 @@ int gestured_register_dbus_interface(void) " " " " " " -// " " " " " " -- 2.7.4 From 391d9573cc9d9f17183451137383f43942d0e1ae Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Tue, 18 Aug 2020 21:14:15 +0900 Subject: [PATCH 06/14] Move engine launching sequence to dbus init Change-Id: I8c6b53fe1f95a1e69c2a738b5fbbd983ac57bda8 Signed-off-by: Sungwook Park --- server/gestured_dbus.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 539a202..5a1991b 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -73,6 +73,15 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const } if (clientLib == GESTURE_CLIENT_LIB_GESTURE) { + /* launch engine process if engine is not running */ + bool is_launched = __is_engine_launched("org.tizen.gesture-engine-default"); + if (false == is_launched) { + LOGI("Request to launch engine"); + __launch_engine_service_app("org.tizen.gesture-engine-default"); + } else { + LOGI("engine is launched"); + } + /* Check this client is already registerd to server or not */ bool already_registered = GestureManagerClientAlreadyRegisterd(bus_name); if (already_registered) { @@ -540,8 +549,6 @@ int gestured_dbus_init(void) return GESTURED_ERROR_OPERATION_FAILED; } - __launch_engine_service_app("org.tizen.gesture-engine-default"); - return GESTURED_ERROR_NONE; } @@ -560,15 +567,6 @@ int gestured_client_initialize_engine(GVariant *parameters, GVariant **reply_bod return GESTURED_ERROR_INVALID_PARAMETER; } - /* check whether engine is launched or not */ - bool is_launched = __is_engine_launched("org.tizen.gesture-engine-default"); - if (false == is_launched) { - LOGI("Request to launch engine"); - __launch_engine_service_app("org.tizen.gesture-engine-default"); - } else { - LOGI("engine is launched"); - } - ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); if (ret != GESTURED_ERROR_NONE) LOGE("Failed to start to engine"); -- 2.7.4 From e241af89bcb2bc48ace0e19e5d767964306d459b Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Wed, 19 Aug 2020 11:27:06 +0900 Subject: [PATCH 07/14] Fix issue that detected by static analysis tool Change-Id: I68e7dc381de3b2815f3cc4754bbfeb9a2f7d8bd7 Signed-off-by: Sungwook Park --- server/gestured_dbus.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 539a202..7c49b3c 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -435,9 +435,6 @@ static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, con } #endif g_dbus_method_invocation_return_value(invocation, reply_body); - } else if (ret == GESTURED_ERROR_SERVICE_NOT_READY) { - // for no return because will send the result with async - LOGD("method call pass because async function"); } else { LOGE("method_call failed, method_name : %s", method_name); g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "gesture error"); -- 2.7.4 From 27f50529716444a5a67197aa84905a2fc321a471 Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Wed, 19 Aug 2020 20:14:16 +0900 Subject: [PATCH 08/14] Remove unused code Change-Id: I794bd8c96e37c752fe30ca2130d10387726a6434 Signed-off-by: Sungwook Park --- client/gesture_client_dbus.c | 23 ----------------------- engine/gesture_engine_dbus.c | 27 --------------------------- server/gestured_dbus.c | 6 ------ 3 files changed, 56 deletions(-) diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c index 91b139d..ce5eec6 100644 --- a/client/gesture_client_dbus.c +++ b/client/gesture_client_dbus.c @@ -25,8 +25,6 @@ #define LOG_TAG "GESTURE_CLIENT_DBUS" static int is_server_started = 0; -static hand_gesture_recognition_cb g_callback; -static hand_gesture_data_h g_gesture_data; static hand_gesture_handtype_e g_hand_type = HAND_GESTURE_LEFT_HAND; static hand_gesture_workmode_e g_work_mode = HAND_GESTURE_WORK_MODE_ONE_WAY; @@ -36,12 +34,6 @@ static int g_sensitivity = 1; static char *g_engine_app_id; static char *g_engine_name; -static void _free_gesture_data(hand_gesture_data_h gesture_data) -{ - free(gesture_data); - gesture_data = NULL; -} - static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { LOGD("name : %s, name_owner : %s", name, name_owner); @@ -124,16 +116,6 @@ static void _handle_gesture_cb(GDBusConnection *connection, g_free(printmsg); LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount); #endif - if (g_gesture_data == NULL){ - LOGD("Can't send the result to Client because g_gesture_data is NULL"); - return; - } - LOGD("address = %p", g_gesture_data); - g_gesture_data->gesture_type = ltype; - g_gesture_data->event = levent; - g_gesture_data->detected_Count = lcount; - -// g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data); if (_handle->recog_cb) { LOGD("[CLIENT DBUS] Send recognition result. gesture_type(%d)", gesture_type); _handle->recog_cb(_handle, gesture_type, 0, HAND_GESTURE_ERROR_NONE, _handle->recog_user_data); @@ -552,8 +534,6 @@ int gesture_client_dbus_start_recognition(GDBusConnection *gdbus_connection, han { LOGD("gesture_client_dbus_start_recognition start"); LOGD("client busname: %s", g_dbus_connection_get_unique_name(gdbus_connection)); - g_callback = callback; - g_gesture_data = gesture_data; GVariant *body = NULL; body = g_variant_new("(iiiii)", gesture_type, g_hand_type, g_work_mode, g_option, g_sensitivity); @@ -572,9 +552,6 @@ int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection) GDBusMessage *reply = NULL; GVariant *body = NULL; - /* free for gesture data struct */ - _free_gesture_data(g_gesture_data); - body = g_variant_new("()"); ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_STOP_RECOGNITION); if (ret != HAND_GESTURE_ERROR_NONE) diff --git a/engine/gesture_engine_dbus.c b/engine/gesture_engine_dbus.c index f9d6199..c0aa267 100644 --- a/engine/gesture_engine_dbus.c +++ b/engine/gesture_engine_dbus.c @@ -486,34 +486,7 @@ int gesture_engine_dbus_main_start(GDBusConnection *gdbus_connection, gesture_en body = g_variant_new("(i)", 100); ret = gdbus_send_message_with_async(gdbus_connection, body, GESTURE_ENGINE_MSG_MAIN_START); -#if 0 - GError *err = NULL; - if (!g_dbus_connection_emit_signal(gdbus_connection, - GESTURE_DBUS_NAME, - GESTURE_OBJECT_PATH, - GESTURE_INTERFACE_NAME, - "psw_test", - body, - &err)) { - if (err != NULL) { - LOGE("Failed to send dbus message : %s", err->message); - g_error_free(err); - } - return GESTURE_ENGINE_ERROR_NONE; - } - - GDBusProxy *ap; - g_dbus_proxy_new (gdbus_connection, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - GESTURE_DBUS_NAME, /* name */ - GESTURE_OBJECT_PATH, /* object path */ - GESTURE_INTERFACE_NAME, /* interface name */ - NULL, /* GCancellable */ - (GAsyncReadyCallback) proxy_new_cb, - &ap); -#endif if (body) g_variant_unref(body); diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index b696ca3..88f7c5b 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -430,9 +430,6 @@ static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, con LOGD("[GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO] called"); ret = gestured_engine_send_engine_get_info(parameters, &reply_body, sender); } - else if (g_strcmp0(method_name, "psw_test") == 0) { - LOGD("[psw_test] called"); - } if (ret == GESTURED_ERROR_NONE) { LOGD("method_call successful, method_name : %s", method_name); @@ -526,9 +523,6 @@ int gestured_register_dbus_interface(void) " " " " - " " - " " - " " " " " "; -- 2.7.4 From 13881d6b9843cdd6feb9ac2459fd47de57ce5336 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 19 Aug 2020 15:19:34 +0900 Subject: [PATCH 09/14] [ACR-1585][gesture][Fix descriptions in header files] - Fix dbus policy issue Change-Id: Iff9779e0a3e03e6aeda036b640c713f6eb24d113 Signed-off-by: sooyeon.kim --- doc/uix_gesture_doc.h | 2 +- include/gesture.h | 32 +++++++++++++++++++++----------- include/gesture_common.h | 2 +- packaging/capi-ui-gesture.conf | 14 ++++++-------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/doc/uix_gesture_doc.h b/doc/uix_gesture_doc.h index 042d0dd..54a528e 100644 --- a/doc/uix_gesture_doc.h +++ b/doc/uix_gesture_doc.h @@ -40,7 +40,7 @@ * * @section CAPI_UIX_GESTURE_MODULE_FEATURE Related Features * This API is related with the following features:
- * - http://tizen.org/feature/sensor.gesture_recognition
+ * - %http://tizen.org/feature/sensor.gesture_recognition
* It is recommended to design feature related codes in your application for reliability.
* You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
* To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
diff --git a/include/gesture.h b/include/gesture.h index 6b4f13e..1171bd0 100644 --- a/include/gesture.h +++ b/include/gesture.h @@ -41,6 +41,11 @@ typedef struct hand_gesture_s *hand_gesture_h; /** * @brief Called when a gesture is detected. + * @details Following error codes can be delivered: \n + * #HAND_GESTURE_ERROR_NONE, \n + * #HAND_GESTURE_ERROR_NOT_SUPPORTED, \n + * #HAND_GESTURE_ERROR_INVALID_PARAMETER, \n + * #HAND_GESTURE_ERROR_OPERATION_FAILED * * @since_tizen @if WEARABLE 6.0 @endif * @remarks The @a handle is managed by the platform and will be released when hand_gesture_destroy() is called. @@ -48,11 +53,11 @@ typedef struct hand_gesture_s *hand_gesture_h; * @param[in] handle A gesture handle * @param[in] gesture A gesture type detected * @param[in] timestamp The time when the gesture is detected. Epoch time in seconds. - * @param[in] error An error value. It can be one of the following error values:@n - * #HAND_GESTURE_ERROR_NONE, if the operation succeeded.@n - * #HAND_GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported in the current profile.@n - * #HAND_GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error.@n - * #HAND_GESTURE_ERROR_PERMISSION_DENIED, if the application has no permission to use this. + * @param[in] error An error value. It can be one of the following error values: \n + * #HAND_GESTURE_ERROR_NONE, if the operation succeeded.\n + * #HAND_GESTURE_ERROR_NOT_SUPPORTED, if the gesture is not supported on the device.\n + * #HAND_GESTURE_ERROR_INVALID_PARAMETER, if the parameter is invalid. \n + * #HAND_GESTURE_ERROR_OPERATION_FAILED, if the operation failed because of a system error. * @param[in] user_data The user data is passed to hand_gesture_start_recognition() * * @see hand_gesture_start_recognition() @@ -61,6 +66,11 @@ typedef void(* hand_gesture_recognition_cb)(hand_gesture_h handle, hand_gesture_ /** * @brief Called when an error is occurred. + * @details Following error codes can be delivered: \n + * #HAND_GESTURE_ERROR_INVALID_PARAMETER, \n + * #HAND_GESTURE_ERROR_INVALID_OPERATION, \n + * #HAND_GESTURE_ERROR_OUT_OF_MEMORY, \n + * #HAND_GESTURE_ERROR_OPERATION_FAILED * * @since_tizen @if WEARABLE 6.0 @endif * @remarks The @a handle is the same object for which the callback was set. @@ -68,10 +78,10 @@ typedef void(* hand_gesture_recognition_cb)(hand_gesture_h handle, hand_gesture_ * The @a msg is managed by the platform and will be released when invoking this callback function is finished. * * @param[in] handle A gesture handle - * @param[in] error An error value. It can be one of the following error values: @n - * #HAND_GESTURE_ERROR_INVALID_PARAMETER, - * #HAND_GESTURE_ERROR_INVALID_OPERATION, - * #HAND_GESTURE_ERROR_OUT_OF_MEMORY, + * @param[in] error An error value. It can be one of the following error values: \n + * #HAND_GESTURE_ERROR_INVALID_PARAMETER, \n + * #HAND_GESTURE_ERROR_INVALID_OPERATION, \n + * #HAND_GESTURE_ERROR_OUT_OF_MEMORY, \n * #HAND_GESTURE_ERROR_OPERATION_FAILED * @param[in] msg An error message from gesture engine service * @param[in] user_data The user data is passed to hand_gesture_set_error_cb() @@ -83,13 +93,13 @@ typedef void(* hand_gesture_error_cb)(hand_gesture_h handle, hand_gesture_error_ /** * @brief Checks whether a gesture is supported or not. - * @details Check if the given gesture type is supported in the current device. + * @details Check if the given gesture type is supported on the device. * * @since_tizen @if WEARABLE 6.0 @endif * * @param[in] handle A gesture handle * @param[in] gesture A gesture type to be checked - * @param[out] supported @c true if the gesture is recognizable in the current device,@n + * @param[out] supported @c true if the gesture is recognizable on the device,\n * @c false otherwise * * @return @c 0 if the @c gesture is supported, otherwise a negative error value diff --git a/include/gesture_common.h b/include/gesture_common.h index 0aaf39a..a8954c6 100644 --- a/include/gesture_common.h +++ b/include/gesture_common.h @@ -51,11 +51,11 @@ typedef struct hand_gesture_data_s* hand_gesture_data_h; */ typedef enum { HAND_GESTURE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + HAND_GESTURE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ HAND_GESTURE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ HAND_GESTURE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */ HAND_GESTURE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ HAND_GESTURE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ - HAND_GESTURE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ HAND_GESTURE_ERROR_ALREADY_STARTED = TIZEN_ERROR_GESTURE | 0x01, /**< Recognition is already started */ HAND_GESTURE_ERROR_NOT_STARTED = TIZEN_ERROR_GESTURE | 0x02, /**< Recognition is not started */ HAND_GESTURE_ERROR_OPERATION_FAILED = TIZEN_ERROR_GESTURE | 0x04, /**< Operation failed because of a system error */ diff --git a/packaging/capi-ui-gesture.conf b/packaging/capi-ui-gesture.conf index d48278d..2514f02 100644 --- a/packaging/capi-ui-gesture.conf +++ b/packaging/capi-ui-gesture.conf @@ -1,17 +1,15 @@ - - - - - + + + - - + + - \ No newline at end of file + -- 2.7.4 From 56a365855b2963be83b84c553597e2d05be3fe68 Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Thu, 20 Aug 2020 21:49:59 +0900 Subject: [PATCH 10/14] change install directory of service file Change-Id: Id30e0c1eedf1505c8cbe338bae912cb080ac23a6 Signed-off-by: Sungwook Park --- packaging/capi-ui-gesture.spec | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packaging/capi-ui-gesture.spec b/packaging/capi-ui-gesture.spec index 2be8bf7..7fb84c2 100644 --- a/packaging/capi-ui-gesture.spec +++ b/packaging/capi-ui-gesture.spec @@ -77,9 +77,8 @@ find . -name '*.gcno' -exec cp '{}' gcov-obj ';' rm -rf %{buildroot} %make_install -mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +mkdir -p %{buildroot}%{_prefix}/lib/systemd/system install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/capi-ui-gesture.service -%install_service multi-user.target.wants capi-ui-gesture.service mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services install -m 0644 %SOURCE2 %{buildroot}%{_datadir}/dbus-1/system-services/org.tizen.gesture.server.service @@ -106,7 +105,6 @@ cp %{SOURCE3} %{buildroot}/etc/dbus-1/system.d/capi-ui-gesture.conf %{_libdir}/lib*.so %attr(0755,ui_fw,ui_fw) %{_bindir}/gesture-server %attr(0644,root,root) %{_unitdir}/capi-ui-gesture.service -%attr(0644,root,root) %{_unitdir}/multi-user.target.wants/capi-ui-gesture.service %attr(0644,root,root) %{_datadir}/dbus-1/system-services/org.tizen.gesture.server.service %config %{_sysconfdir}/dbus-1/system.d/capi-ui-gesture.conf -- 2.7.4 From 7f8c9108299772eb510e8f2470bdf81b48fd3e66 Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Tue, 25 Aug 2020 13:57:57 +0900 Subject: [PATCH 11/14] Remove unused file Change-Id: I13d5f61a0326bb325aeba0473f61de4c88a1deb5 Signed-off-by: Sungwook Park --- CMakeLists.txt | 4 ++-- client/CMakeLists.txt | 1 - client/GestureSensor.c | 56 -------------------------------------------------- client/GestureSensor.h | 48 ------------------------------------------- client/gesture.c | 1 - client/gesture_main.h | 1 - 6 files changed, 2 insertions(+), 109 deletions(-) delete mode 100644 client/GestureSensor.c delete mode 100644 client/GestureSensor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0872c9c..5ccea7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ pkg_check_modules(pkgs REQUIRED cynara-session capi-appfw-app-common capi-appfw-app-control - capi-appfw-app-manager - capi-appfw-package-manager + capi-appfw-app-manager + capi-appfw-package-manager dbus-1 capi-system-info aul diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ebc91f2..c2a5176 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,6 +1,5 @@ SET(SRCS gesture.c - GestureSensor.c gesture_client_dbus.c ) diff --git a/client/GestureSensor.c b/client/GestureSensor.c deleted file mode 100644 index 9f4818b..0000000 --- a/client/GestureSensor.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. - * - * 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 "GestureSensor.h" - - - -bool setGesture(hand_gesture_type_e type) -{ - return true; -} - -void setPowerSave(bool ps) -{ - -} - -void setCallback(hand_gesture_recognition_cb cb) -{ - -} - -void setUserData(void* data) -{ - -} - -bool start() -{ - return true; -} - -bool stop() -{ - return true; -} - -bool isSensorSupported(hand_gesture_type_e type) -{ - return true; -} - diff --git a/client/GestureSensor.h b/client/GestureSensor.h deleted file mode 100644 index c092532..0000000 --- a/client/GestureSensor.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. - * - * 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 __GESTURE_SENSOR_H__ -#define __GESTURE_SENSOR_H__ - -#include "gesture_main.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -bool setGesture(hand_gesture_type_e type); -void setPowerSave(bool ps); -void setCallback(hand_gesture_recognition_cb cb); -void setUserData(void* data); - -bool start(); -bool stop(); - -bool isSensorSupported(hand_gesture_type_e type); - -hand_gesture_type_e __gestureType; -hand_gesture_recognition_cb __callback; -void *__userData; - - -#ifdef __cplusplus -} -#endif - -#endif /* __GESTURE_SENSOR_H__ */ - diff --git a/client/gesture.c b/client/gesture.c index 96fe1be..df6ae46 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -304,7 +304,6 @@ EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle) CHECK_GESTURE_FEATURE(); ASSERT_NOT_NULL(handle); - IF_FAIL_RETURN(stop(), HAND_GESTURE_ERROR_NOT_STARTED); int ret = HAND_GESTURE_ERROR_NONE; ret = gesture_client_dbus_stop_recognition(handle->gdbus_connection); diff --git a/client/gesture_main.h b/client/gesture_main.h index c35f331..4688228 100644 --- a/client/gesture_main.h +++ b/client/gesture_main.h @@ -20,7 +20,6 @@ #include #include #include "gesture.h" -#include #ifdef __cplusplus -- 2.7.4 From decd5d812343bd03855955b33bcd287995b77e63 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 24 Aug 2020 15:43:22 +0900 Subject: [PATCH 12/14] Move privilege checker to gesture-server Change-Id: I013b3509f39f47ca776262a3eeb0e178f406ee6f Signed-off-by: sooyeon.kim --- client/gesture.c | 43 ++++++++++++----- client/gesture_client_dbus.c | 24 ++++++---- client/gesture_client_dbus.h | 2 +- client/gesture_main.h | 3 ++ engine/gesture_engine_dbus.c | 2 +- manager/gestured_client_manager.cpp | 3 +- manager/gestured_client_manager.h | 1 + server/gestured_dbus.c | 95 ++++++++++++++++++++++++++++++++++++- 8 files changed, 149 insertions(+), 24 deletions(-) diff --git a/client/gesture.c b/client/gesture.c index df6ae46..17065d1 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -51,26 +51,35 @@ static int _cynara_initialize() return ret; } -static int _check_privilege(const char *uid, const char *privilege) +static char * _get_smack_label() { - int ret; FILE *fp = NULL; char label_path[1024] = "/proc/self/attr/current"; - char smack_label[1024] = {'\0',}; - - if (!p_cynara) { - return -1; - } + static char smack_label[1024] = {'\0',}; fp = fopen(label_path, "r"); if (fp != NULL) { - ret = fread(smack_label, 1, sizeof(smack_label), fp); + int ret = fread(smack_label, 1, sizeof(smack_label), fp); if (ret <= 0) LOGE("Failed to fread"); fclose(fp); } + return smack_label; +} + +static int _check_privilege(const char *uid, const char *privilege) +{ + int ret; + char smack_label[1024] = {'\0',}; + + if (!p_cynara) { + return -1; + } + + strcpy(smack_label, _get_smack_label()); + pid_t pid = getpid(); char *session = cynara_session_from_pid(pid); ret = cynara_check(p_cynara, smack_label, session, uid, privilege); @@ -93,7 +102,8 @@ static void _cynara_deinitialize() p_cynara = NULL; } -static int _gesture_check_privilege() { +static int _gesture_check_privilege() +{ char uid[16]; int ret = HAND_GESTURE_ERROR_NONE; @@ -130,22 +140,31 @@ EXPORT_API int hand_gesture_create(hand_gesture_h *handle) if (!_struct) return HAND_GESTURE_ERROR_OUT_OF_MEMORY; + /* get uid and smack label */ + snprintf(_struct->uid, 16, "%d", getuid()); + + strcpy(_struct->smack_label, _get_smack_label()); + + LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label); + ret = gesture_client_dbus_init(&_struct->gdbus_connection, &_struct->server_watcher_id, - &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, (void *)_struct); + &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, _struct->uid, _struct->smack_label, (void *)_struct); if (ret != HAND_GESTURE_ERROR_NONE) { LOGE("Failed to initialize dbus : %d", ret); free(_struct); return HAND_GESTURE_ERROR_OPERATION_FAILED; } - *handle = _struct; - ret = gesture_client_dbus_initialize_engine(_struct->gdbus_connection); if (ret != HAND_GESTURE_ERROR_NONE) { LOGE("Failed to initialize engine dbus : %d", ret); + free(_struct); return HAND_GESTURE_ERROR_OPERATION_FAILED; } + *handle = _struct; + + return HAND_GESTURE_ERROR_NONE; } diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c index ce5eec6..532ac88 100644 --- a/client/gesture_client_dbus.c +++ b/client/gesture_client_dbus.c @@ -34,6 +34,7 @@ static int g_sensitivity = 1; static char *g_engine_app_id; static char *g_engine_name; + static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { LOGD("name : %s, name_owner : %s", name, name_owner); @@ -338,19 +339,22 @@ static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVar return ret; } -static int _monitor_register(GDBusConnection *gdbus_connection) +static int _monitor_register(GDBusConnection *gdbus_connection, const char *uid, const char *smack_label) { int ret; GDBusMessage *reply = NULL; GVariant *client_body = NULL; char appid[1024] = {0, }; - ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)); + int pid = getpid(); + ret = aul_app_get_appid_bypid(pid, appid, sizeof(appid)); if (ret != 0) { LOGE("aul_app_get_appid_bypid() failed : %d", ret); } - client_body = g_variant_new("(iis)", 11, GESTURE_CLIENT_LIB_GESTURE, appid); + LOGI("[INFO] appid(%s), pid(%d), uid(%s), smack_label(%s)", appid, pid, uid, smack_label); + + client_body = g_variant_new("(iisiss)", 11, GESTURE_CLIENT_LIB_GESTURE, appid, pid, uid, smack_label); ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER); if (reply) @@ -373,8 +377,12 @@ static void _on_name_appeared(GDBusConnection *connection, const gchar *name_owner, gpointer user_data) { - if (is_server_started == 0) - _monitor_register(connection); + struct hand_gesture_s *_struct = user_data; + + if (is_server_started == 0) { + LOGI("uid(%s), smack_label(%s)", _struct->uid, _struct->smack_label); + _monitor_register(connection, _struct->uid, _struct->smack_label); + } } static void _on_name_vanished(GDBusConnection *connection, @@ -385,7 +393,7 @@ static void _on_name_vanished(GDBusConnection *connection, } int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, - int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data) + int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, const char *uid, const char *smack_label, void *data) { LOGD("gesture_client_dbus_init start"); @@ -403,7 +411,7 @@ int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_w return ret; } - ret = _monitor_register(*gdbus_connection); + ret = _monitor_register(*gdbus_connection, uid, smack_label); if (ret != HAND_GESTURE_ERROR_NONE) { LOGE("_monitor_register() failed : %d", ret); return ret; @@ -416,7 +424,7 @@ int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_w G_BUS_NAME_WATCHER_FLAGS_NONE, _on_name_appeared, _on_name_vanished, - NULL, + data, NULL); if (*server_monitor_id == 0) { g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id); diff --git a/client/gesture_client_dbus.h b/client/gesture_client_dbus.h index b3666be..0ae8bdc 100644 --- a/client/gesture_client_dbus.h +++ b/client/gesture_client_dbus.h @@ -31,7 +31,7 @@ extern "C" { #endif -int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data); +int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id, int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, const char *uid, const char *smack_label, void *data); int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id); int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection); int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection); diff --git a/client/gesture_main.h b/client/gesture_main.h index 4688228..04f0480 100644 --- a/client/gesture_main.h +++ b/client/gesture_main.h @@ -33,6 +33,9 @@ struct hand_gesture_s { int monitor_id; int server_monitor_id; + char uid[16]; + char smack_label[1024]; + hand_gesture_recognition_cb recog_cb; void* recog_user_data; hand_gesture_error_cb error_cb; diff --git a/engine/gesture_engine_dbus.c b/engine/gesture_engine_dbus.c index c0aa267..3eeb674 100644 --- a/engine/gesture_engine_dbus.c +++ b/engine/gesture_engine_dbus.c @@ -367,7 +367,7 @@ static int _monitor_register(GDBusConnection *gdbus_connection) return GESTURE_ENGINE_ERROR_OPERATION_FAILED; } - engine_body = g_variant_new("(iis)", 22, GESTURE_CLIENT_LIB_ENGINE, appid); + engine_body = g_variant_new("(iisiss)", 22, GESTURE_CLIENT_LIB_ENGINE, appid, getpid(), "NULL", "NULL"); ret = gdbus_send_message_with_sync(gdbus_connection, engine_body, &reply, GESTURE_MSG_SERVICE_REGISTER); if (reply) diff --git a/manager/gestured_client_manager.cpp b/manager/gestured_client_manager.cpp index 970f080..04930a4 100644 --- a/manager/gestured_client_manager.cpp +++ b/manager/gestured_client_manager.cpp @@ -31,7 +31,7 @@ gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name) client = NULL; return NULL; } - + client->gestureType = -1; client->requestTypeCount = -1; client->clientLib = GESTURE_CLIENT_LIB_NONE; @@ -41,6 +41,7 @@ gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name) client->gdbus_connection = NULL; client->state = CLIENT_STATE_NONE; client->response_cb = NULL; + client->is_permitted = false; return client; } diff --git a/manager/gestured_client_manager.h b/manager/gestured_client_manager.h index 35238b6..66b6b14 100644 --- a/manager/gestured_client_manager.h +++ b/manager/gestured_client_manager.h @@ -31,6 +31,7 @@ typedef struct { GDBusConnection *gdbus_connection; gesture_manager_client_state_e state; hand_gesture_recognition_cb *response_cb; + bool is_permitted; } gesture_manager_client_s; gesture_manager_client_s* GestureManagerClientCreate(const char* pkg_name); diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 88f7c5b..20a956e 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include "gestured_dbus.h" #include "gestured_error.h" @@ -43,10 +46,68 @@ static GDBusConnection *_gdbus_connection; static const char *_client_bus_name; static const char *_engine_bus_name; + static bool __is_engine_installed(const char* appid); static bool __is_engine_launched(const char* appid); +static cynara *p_cynara = NULL; +static int _cynara_initialize() +{ + int ret = cynara_initialize(&p_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) + LOGE("Failed to cynara initialize"); + + return ret; +} + +static int _check_privilege(const char *uid, const int pid, const char *label, const char *privilege) +{ + int ret; + + if (!p_cynara) { + return -1; + } + + char *session = cynara_session_from_pid(pid); + ret = cynara_check(p_cynara, label, session, uid, privilege); + if (session) + free(session); + if (ret != CYNARA_API_ACCESS_ALLOWED) { + LOGE("Access denied. The result of cynara_check() : %d.", ret); + return -1; + } + + return 0; +} + +static void _cynara_deinitialize() +{ + if (p_cynara) + cynara_finish(p_cynara); + + p_cynara = NULL; +} + +static int _gesture_check_privilege(const char *uid, const int pid, const char *label) +{ + int ret = GESTURED_ERROR_NONE; + + if (_cynara_initialize() != CYNARA_API_SUCCESS) + return GESTURED_ERROR_PERMISSION_DENIED; + + if (_check_privilege(uid, pid, label, GESTURE_PRIVILEGE_APPLAUNCH) < 0) { + LOGE("Permission is denied"); + ret = GESTURED_ERROR_PERMISSION_DENIED; + } + + _cynara_deinitialize(); + + return ret; +} + + + int gestured_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler, GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash) { @@ -57,14 +118,20 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const uid_t request_uid = 0; CLIENT_LIB clientLib; char *pkgName = NULL; + int client_pid = 0; + char *client_uid = NULL; + char *client_smack_label = NULL; if (bus_name == NULL) return GESTURED_ERROR_IO_ERROR; - g_variant_get(parameters, "(iis)", &request_uid, &clientLib, &pkgName); + g_variant_get(parameters, "(iisiss)", &request_uid, &clientLib, &pkgName, &client_pid, &client_uid, &client_smack_label); LOGD("gestured_server_register > request_uid: %d", request_uid); LOGD("gestured_server_register > clientLib: %d", clientLib); LOGD("gestured_server_register > pkgName: %s", pkgName); + LOGD("gestured_server_register > client_pid: %d", client_pid); + LOGD("gestured_server_register > client_uid: %s", (NULL == client_uid) ? "NULL" : client_uid); + LOGD("gestured_server_register > client_smack_label: %s", (NULL == client_smack_label) ? "NULL" : client_smack_label); if (clientLib == GESTURE_CLIENT_LIB_ENGINE) { _engine_bus_name = g_strdup(bus_name); @@ -73,6 +140,15 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const } if (clientLib == GESTURE_CLIENT_LIB_GESTURE) { + /* check privilege */ + if (GESTURED_ERROR_NONE != _gesture_check_privilege(client_uid, client_pid, client_smack_label)) { + LOGE("[ERROR] Permission denied"); + + return GESTURED_ERROR_PERMISSION_DENIED; + } else { + LOGI("[INFO] Permission allowed"); + } + /* launch engine process if engine is not running */ bool is_launched = __is_engine_launched("org.tizen.gesture-engine-default"); if (false == is_launched) { @@ -96,6 +172,7 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const LOGE("Fail to create a new client"); return GESTURED_ERROR_OPERATION_FAILED; } + client->is_permitted = true; client->clientLib = clientLib; client->request_uid = request_uid; client->gdbus_bus_name = strdup(bus_name); @@ -118,6 +195,7 @@ int gestured_server_register(GVariant *parameters, GVariant **reply_body, const LOGE("Failed to add client to GestureManager"); return GESTURED_ERROR_OPERATION_FAILED; } + LOGD("GestureManager Client count = %d", GestureManagerClientNums()); } else if (clientLib == GESTURE_CLIENT_LIB_ENGINE) { /* Check this engine is already registerd to server or not */ @@ -466,6 +544,9 @@ int gestured_register_dbus_interface(void) " " " " " " + " " + " " + " " " " " " @@ -558,6 +639,18 @@ int gestured_client_initialize_engine(GVariant *parameters, GVariant **reply_bod return GESTURED_ERROR_INVALID_PARAMETER; } + /* check privilege */ + gesture_manager_client_s *client = GestureManagerClientGetWithBusName(sender); + if (!client) { + LOGE("failed to GestureManagerClientGet"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + if (false == client->is_permitted) { + LOGE("[ERROR] Permission denied"); + return GESTURED_ERROR_PERMISSION_DENIED; + } + ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); if (ret != GESTURED_ERROR_NONE) LOGE("Failed to start to engine"); -- 2.7.4 From b1eee2124d3e634449c79ae26e8e2ba728c49622 Mon Sep 17 00:00:00 2001 From: Sungwook Park Date: Fri, 28 Aug 2020 14:46:33 +0900 Subject: [PATCH 13/14] Fix issue that detected by static analysis tool Change-Id: I5144129783cfb8acf6f654ea8e2730c4ce6ccc93 Signed-off-by: Sungwook Park --- client/gesture.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/gesture.c b/client/gesture.c index 17065d1..f333dea 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -77,8 +77,8 @@ static int _check_privilege(const char *uid, const char *privilege) if (!p_cynara) { return -1; } - - strcpy(smack_label, _get_smack_label()); + char * sl = _get_smack_label(); + memcpy(smack_label, sl, strlen(sl) + 1); pid_t pid = getpid(); char *session = cynara_session_from_pid(pid); @@ -143,7 +143,8 @@ EXPORT_API int hand_gesture_create(hand_gesture_h *handle) /* get uid and smack label */ snprintf(_struct->uid, 16, "%d", getuid()); - strcpy(_struct->smack_label, _get_smack_label()); + char *sl = _get_smack_label(); + memcpy(_struct->smack_label, sl, strlen(sl) + 1); LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label); -- 2.7.4 From 8a30d4e2d0910de34f6a756c5390992a1bfa18a2 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 25 Aug 2020 19:40:39 +0900 Subject: [PATCH 14/14] Refactor gdbus interface of gesture FW This patch includes these changes. - Extract gdbus interface definition xml from source code to .xml file. - Create invocation manager class to manager gdbus method call session. - Synchronize API behavior(hand_gesture_is_supported_type, hand_gesture_get_engine_info). Change-Id: Ied0b8a766d4b07634b31f6dc9f5325d057471936 Signed-off-by: Suyeon Hwang --- CMakeLists.txt | 2 + capi-ui-gesture-gdbus.xml | 65 ++++++++ client/gesture.c | 1 + client/gesture_client_dbus.c | 43 +++++- engine/gesture_engine_dbus.c | 52 +++++-- include/gesture_defs.h | 7 +- manager/gestured_invocation_manager.cpp | 71 +++++++++ manager/gestured_invocation_manager.h | 20 +++ packaging/capi-ui-gesture.spec | 1 + server/CMakeLists.txt | 1 + server/gestured_dbus.c | 260 ++++++++++++++++++++------------ server/gestured_dbus.h | 8 +- 12 files changed, 418 insertions(+), 113 deletions(-) create mode 100644 capi-ui-gesture-gdbus.xml create mode 100644 manager/gestured_invocation_manager.cpp create mode 100644 manager/gestured_invocation_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ccea7d..c3e0afd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,3 +46,5 @@ ADD_SUBDIRECTORY(client) ## Gesture manager ## #ADD_SUBDIRECTORY(manager) + +INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-ui-gesture-gdbus.xml DESTINATION ${TZ_SYS_RO_SHARE}/gesture) diff --git a/capi-ui-gesture-gdbus.xml b/capi-ui-gesture-gdbus.xml new file mode 100644 index 0000000..4adff75 --- /dev/null +++ b/capi-ui-gesture-gdbus.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/gesture.c b/client/gesture.c index f333dea..3872631 100644 --- a/client/gesture.c +++ b/client/gesture.c @@ -201,6 +201,7 @@ EXPORT_API int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gestur LOGD("hand_gesture_is_supported_type"); CHECK_GESTURE_FEATURE(); + ASSERT_NOT_NULL(handle); ASSERT_NOT_NULL(supported); int ret; diff --git a/client/gesture_client_dbus.c b/client/gesture_client_dbus.c index 532ac88..0c58dad 100644 --- a/client/gesture_client_dbus.c +++ b/client/gesture_client_dbus.c @@ -623,10 +623,21 @@ int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connectio GDBusMessage *reply = NULL; GVariant *body = NULL; - body = g_variant_new("()"); + body = g_variant_new("(i)", gesture); ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE); - if (ret != HAND_GESTURE_ERROR_NONE) + if (ret != HAND_GESTURE_ERROR_NONE || NULL == reply) { LOGE("failed to is_supported_gesture_type"); + } else { + LOGD("Check reply from server"); + GVariant *reply_body = g_dbus_message_get_body(reply); + if (NULL == reply_body) { + LOGE("There is no return value"); + ret = HAND_GESTURE_ERROR_OPERATION_FAILED; + } else { + g_variant_get(reply_body, "(b)", supported); + LOGD("supported(%d)", *supported); + } + } if (body) g_variant_unref(body); @@ -643,13 +654,35 @@ int gesture_client_dbus_get_engine_info(GDBusConnection *gdbus_connection, char* int ret; GDBusMessage *reply = NULL; GVariant *body = NULL; - g_engine_app_id = *engine_app_id; - g_engine_name = *engine_name; body = g_variant_new("()"); ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_ENGINE_GET_INFO); if (ret != HAND_GESTURE_ERROR_NONE) - LOGE("failed to engine_get_info"); + LOGE("Fail to send message"); + + GVariant *reply_body = g_dbus_message_get_body(reply); + if (NULL == reply_body) { + LOGE("There is no return value"); + ret = HAND_GESTURE_ERROR_OPERATION_FAILED; + } else { + g_variant_get(reply_body, "(ss)", engine_app_id, engine_name); + if (NULL == engine_app_id || NULL == engine_name) { + LOGE("Fail to get engine info"); + ret = HAND_GESTURE_ERROR_OPERATION_FAILED; + } else { + if (NULL != g_engine_app_id) { + free(g_engine_app_id); + } + + if (NULL != g_engine_name) { + free(g_engine_name); + } + + g_engine_app_id = *engine_app_id; + g_engine_name = *engine_name; + LOGD("APP ID(%s), Name(%s)", *engine_app_id, *engine_name); + } + } if (body) g_variant_unref(body); diff --git a/engine/gesture_engine_dbus.c b/engine/gesture_engine_dbus.c index 3eeb674..a0ec977 100644 --- a/engine/gesture_engine_dbus.c +++ b/engine/gesture_engine_dbus.c @@ -29,6 +29,8 @@ static int is_server_started = 0; static gesture_engine_request_callback_s g_basic_engine_callback; static GDBusConnection *mgdbus_connection; +static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd); + static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { LOGD("name : %s, name_owner : %s", name, name_owner); @@ -150,16 +152,46 @@ static void _handle_gesture_engine_cb(GDBusConnection *connection, } else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE) == 0) { LOGD("[GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE] called"); - int gesture_type = 1; - bool isSupported = false; - g_variant_get(parameters, "(i)", &gesture_type); - g_basic_engine_callback.is_support_gesture_type(gesture_type, &isSupported); - } - else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO) == 0) { - LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO] called"); - char *engine_app_id; - char *engine_name; + int id = 0; + int gesture_type = 0; + g_variant_get(parameters, "(ii)", &id, &gesture_type); + LOGD("Invocation ID(%d), Gesture Type(%d)", id, gesture_type); + + bool is_supported = false; + g_basic_engine_callback.is_support_gesture_type(gesture_type, &is_supported); + GVariant* body = g_variant_new("(ib)", id, is_supported); + if (NULL == body) { + LOGE("Fail to create body"); + return; + } + + LOGD("send message variant. ID(%d), Is supported(%d)", id, is_supported); + gdbus_send_message_with_async(connection, body, GESTURE_ENGINE_MSG_IS_SUPPORT_GESTURE_TYPE); + g_variant_unref(body); + } + else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO) == 0) { + LOGD("[GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO] called"); + int id = 0; + g_variant_get(parameters, "(i)", &id); + LOGD("Invocation ID(%d)", id); + + char *engine_app_id = NULL; + char *engine_name = NULL; g_basic_engine_callback.get_info(&engine_app_id, &engine_name); + if (NULL == engine_app_id || NULL == engine_name) { + LOGE("Fail to get engine information"); + return; + } + + GVariant* body = g_variant_new("(iss)", id, engine_app_id, engine_name); + if (NULL == body) { + LOGE("Fail to create body"); + return; + } + + LOGD("send message variant. APP ID(%s), Name(%s)", engine_app_id, engine_name); + gdbus_send_message_with_async(connection, body, GESTURE_ENGINE_MSG_GET_ENGINE_INFO); + g_variant_unref(body); } } @@ -595,7 +627,7 @@ int gesture_engine_dbus_send_engine_get_info(GDBusConnection *gdbus_connection, GVariant *body = NULL; body = g_variant_new("(ss)", engine_app_id, engine_name); - ret = gdbus_send_message_with_sync(mgdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO); + ret = gdbus_send_message_with_sync(mgdbus_connection, body, &reply, GESTURE_ENGINE_MSG_GET_ENGINE_INFO); if (ret != GESTURE_ENGINE_ERROR_NONE) { LOGE("Fail to send result data to daemon"); } diff --git a/include/gesture_defs.h b/include/gesture_defs.h index d08beca..613e697 100644 --- a/include/gesture_defs.h +++ b/include/gesture_defs.h @@ -27,6 +27,8 @@ extern "C" { #define HAPI __attribute__((visibility("hidden"))) +#define GESTURE_SHARED_RESOURCE_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "gesture") + #define DBUS_NAME "org.freedesktop.DBus" #define DBUS_OBJECT_PATH "/org/freedesktop/DBus" #define DBUS_INTERFACE_NAME "org.freedesktop.DBus" @@ -56,7 +58,8 @@ extern "C" { #define GESTURE_ENGINE_MSG_SEND_RESULT "gesture_engine_send_result" #define GESTURE_ENGINE_MSG_SEND_ERROR "gesture_engine_send_error" #define GESTURE_ENGINE_MSG_SEND_MOTION_STATUS "gesture_engine_send_motion_status" -#define GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO "gesture_engine_send_engine_get_info" +#define GESTURE_ENGINE_MSG_IS_SUPPORT_GESTURE_TYPE "gesture_engine_is_support_gesture_type" +#define GESTURE_ENGINE_MSG_GET_ENGINE_INFO "gesture_engine_get_engine_info" #define GESTURE_ENGINE_SIGNAL_ENGINE_INITIALIZE "engine_initialize" #define GESTURE_ENGINE_SIGNAL_ENGINE_DEINITIALIZE "engine_deinitialize" @@ -65,7 +68,7 @@ extern "C" { #define GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME "engine_foreach_result_time" #define GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE "engine_foreach_supported_type" #define GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE "engine_is_support_gesture_type" -#define GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO "engine_get_info" +#define GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO "engine_get_engine_info" #define GESTURE_PRIVILEGE_APPLAUNCH "http://tizen.org/privilege/appmanager.launch" #define GESTURE_FEATURE_GESTURE "tizen.org/feature/sensor.gesture_recognition" diff --git a/manager/gestured_invocation_manager.cpp b/manager/gestured_invocation_manager.cpp new file mode 100644 index 0000000..7f1cd14 --- /dev/null +++ b/manager/gestured_invocation_manager.cpp @@ -0,0 +1,71 @@ +#include +#include + +#include + +#include "gestured_invocation_manager.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "GESTURE_INVOCATION" + +static const int MAX_INVOCATION_ID = 1000000; + +static std::map g_invocation_map; +static int g_last_id = -1; + +int gestureInvocationManagerInit() +{ + LOGD("Initialize invocation manager"); + g_last_id = -1; + g_invocation_map.clear(); + + return 0; +} + +int gestureInvocationManagerAdd(GDBusMethodInvocation* invocation) +{ + if (NULL == invocation) { + LOGE("Invalid parameter"); + return -1; + } + + LOGD("Add new invocation handle"); + bool findId = false; + for (int i = g_last_id + 1; i != g_last_id; i = (i + 1) % MAX_INVOCATION_ID) { + if (g_invocation_map.find(i) == g_invocation_map.end()) { + g_last_id = i; + findId = true; + break; + } + } + + if (!findId) { + LOGE("Invocation map is full"); + return -1; + } + + g_invocation_map.insert({g_last_id, invocation}); + + return g_last_id; +} + +GDBusMethodInvocation* gestureInvocationManagerGet(int invocation_id) +{ + LOGD("Find invocation handle. ID(%d)", invocation_id); + auto iter = g_invocation_map.find(invocation_id); + if (iter == g_invocation_map.end()) { + LOGE("There is no handle"); + return nullptr; + } + + return iter->second; +} + +bool gestureInvocationManagerRemove(int invocation_id) +{ + LOGD("Remove invocation handle. ID(%d)", invocation_id); + g_invocation_map.erase(invocation_id); + return true; +} \ No newline at end of file diff --git a/manager/gestured_invocation_manager.h b/manager/gestured_invocation_manager.h new file mode 100644 index 0000000..32c3458 --- /dev/null +++ b/manager/gestured_invocation_manager.h @@ -0,0 +1,20 @@ +#ifndef __GESTURED_INVOCATION_MANAGER_H__ +#define __GESTURED_INVOCATION_MANAGER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int gestureInvocationManagerInit(); +int gestureInvocationManagerAdd(GDBusMethodInvocation* invocation); +GDBusMethodInvocation* gestureInvocationManagerGet(int invocation_id); +bool gestureInvocationManagerRemove(int invocation_id); + +#ifdef __cplusplus +} +#endif + +#endif /* __GESTURED_INVOCATION_MANAGER_H__ */ + diff --git a/packaging/capi-ui-gesture.spec b/packaging/capi-ui-gesture.spec index 7fb84c2..2bae1f2 100644 --- a/packaging/capi-ui-gesture.spec +++ b/packaging/capi-ui-gesture.spec @@ -104,6 +104,7 @@ cp %{SOURCE3} %{buildroot}/etc/dbus-1/system.d/capi-ui-gesture.conf %license LICENSE %{_libdir}/lib*.so %attr(0755,ui_fw,ui_fw) %{_bindir}/gesture-server +%attr(0644,root,root) %{_datadir}/gesture/capi-ui-gesture-gdbus.xml %attr(0644,root,root) %{_unitdir}/capi-ui-gesture.service %attr(0644,root,root) %{_datadir}/dbus-1/system-services/org.tizen.gesture.server.service %config %{_sysconfdir}/dbus-1/system.d/capi-ui-gesture.conf diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index c41307a..d79d081 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -4,6 +4,7 @@ SET(SRCS gestured_dbus.c ../manager/gestured_client_manager.cpp ../manager/gestured_engine_manager.cpp + ../manager/gestured_invocation_manager.cpp ) FOREACH(flag ${pkgs_CFLAGS}) diff --git a/server/gestured_dbus.c b/server/gestured_dbus.c index 20a956e..0673c4d 100644 --- a/server/gestured_dbus.c +++ b/server/gestured_dbus.c @@ -30,6 +30,7 @@ #include "gesture_defs.h" #include "gestured_client_manager.h" #include "gestured_engine_manager.h" +#include "gestured_invocation_manager.h" #ifdef LOG_TAG #undef LOG_TAG @@ -300,6 +301,8 @@ int gestured_server_register_dbus_interface(char *introspection_xml, GDBusInterf goto cleanup; } + gestureInvocationManagerInit(); + return GESTURED_ERROR_NONE; cleanup: @@ -448,6 +451,7 @@ static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, con GVariant *reply_body = NULL; int ret = GESTURED_ERROR_NONE; + bool delay_response = false; if (g_strcmp0(method_name, GESTURE_MSG_SERVICE_REGISTER) == 0) { LOGD("[GESTURE_MSG_SERVICE_REGISTER] called"); @@ -481,11 +485,13 @@ static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, con } else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE) == 0) { LOGD("[GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE] called"); - ret = gestured_client_is_support_gesture_type(parameters, &reply_body, sender); + ret = gestured_client_is_support_gesture_type(parameters, &reply_body, sender, invocation); + delay_response = true; } else if (g_strcmp0(method_name, GESTURE_CLIENT_MSG_ENGINE_GET_INFO) == 0) { LOGD("[GESTURE_CLIENT_MSG_ENGINE_GET_INFO] called"); - ret = gestured_client_engine_get_info(parameters, &reply_body, sender); + ret = gestured_client_get_engine_info(parameters, &reply_body, sender, invocation); + delay_response = true; } /* from engine */ @@ -504,24 +510,32 @@ static void _gestured_client_dbus_method_call_handler(GDBusConnection *conn, con else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_MAIN_START) == 0) { LOGD("[GESTURE_ENGINE_MSG_MAIN_START] called"); } - else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO) == 0) { - LOGD("[GESTURE_ENGINE_MSG_SEND_ENGINE_GET_INFO] called"); - ret = gestured_engine_send_engine_get_info(parameters, &reply_body, sender); + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_GET_ENGINE_INFO) == 0) { + LOGD("[GESTURE_ENGINE_MSG_GET_ENGINE_INFO] called"); + int id = -1; + char* app_id = NULL; + char* name = NULL; + + g_variant_get(parameters, "(iss)", &id, &app_id, &name); + ret = gestured_reply_get_engine_info(id, app_id, name); } + else if (g_strcmp0(method_name, GESTURE_ENGINE_MSG_IS_SUPPORT_GESTURE_TYPE) == 0) { + LOGD("[GESTURE_ENGINE_MSG_IS_SUPPORT_GESTURE_TYPE] called"); + int id = -1; + bool is_supported = false; - if (ret == GESTURED_ERROR_NONE) { - LOGD("method_call successful, method_name : %s", method_name); -#if 0 - if (reply_body != NULL) { - gchar *printmsg = g_variant_print(reply_body, true); - LOGD("<<>> : %s", printmsg); - g_free(printmsg); + g_variant_get(parameters, "(ib)", &id, &is_supported); + ret = gestured_reply_is_support_gesture_type(id, is_supported); + } + + if (false == delay_response) { + if (ret == GESTURED_ERROR_NONE) { + LOGD("method_call successful, method_name : %s", method_name); + g_dbus_method_invocation_return_value(invocation, reply_body); + } else { + LOGE("method_call failed, method_name : %s", method_name); + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "gesture error"); } -#endif - g_dbus_method_invocation_return_value(invocation, reply_body); - } else { - LOGE("method_call failed, method_name : %s", method_name); - g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "gesture error"); } if (reply_body) @@ -537,77 +551,48 @@ static const GDBusInterfaceVTable _gesture_interface_vtable = { int gestured_register_dbus_interface(void) { LOGD("gestured_register_dbus_interface"); - static gchar introspection_xml[] = - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - - " " - " " - - " " - " " - - " " - " " - " " - " " - " " - " " - " " - - " " - " " - - " " - " " - - " " - " " - - " " - " " - - " " - " " - - " " - " " - " " - " " - " " - " " - " " - - " " - " " - " " - " " - - " " - " " - " " - - " " - " " - " " - - " " - " " - " " - " " - - " " - " "; - - return gestured_server_register_dbus_interface(introspection_xml, _gesture_interface_vtable); + + FILE* xml_file = NULL; + char xml_file_path[256] = {'\0', }; + char* introspection_xml = NULL; + int size = 0; + int ret = 0; + + snprintf(xml_file_path, strlen(GESTURE_SHARED_RESOURCE_PATH) + 27, "%s/capi-ui-gesture-gdbus.xml", GESTURE_SHARED_RESOURCE_PATH); + ret = access(xml_file_path, R_OK); + if (0 != ret) { + LOGE("Introspection file is not exist. path(%s)", xml_file_path); + return GESTURED_ERROR_OPERATION_FAILED; + } + + xml_file = fopen(xml_file_path, "r"); + if (NULL == xml_file) { + LOGE("Fail to open introspection file"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + fseek(xml_file, 0, SEEK_END); + size = ftell(xml_file); + rewind(xml_file); + + introspection_xml = (char*)calloc(sizeof(char), size); + if (NULL == introspection_xml) { + LOGE("Fail to allocate memory"); + return GESTURED_ERROR_OUT_OF_MEMORY; + } + + ret = fread(introspection_xml, 1, size, xml_file); + if (ret != size) { + LOGE("Error is occured reading file"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + ret = gestured_server_register_dbus_interface(introspection_xml, _gesture_interface_vtable); + + fclose(xml_file); + free(introspection_xml); + + return ret; } int gestured_dbus_init(void) @@ -750,7 +735,7 @@ int gestured_client_foreach_supported_type(GVariant *parameters, GVariant **repl return ret; } -int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender) +int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender, GDBusMethodInvocation* invocation) { int ret = GESTURED_ERROR_NONE; char *cmd = GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE; @@ -760,26 +745,55 @@ int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **rep return GESTURED_ERROR_INVALID_PARAMETER; } - ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + int id = gestureInvocationManagerAdd(invocation); + if (0 > id) { + LOGE("Fail to store invocation"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + int gesture_type = 0; + g_variant_get(parameters, "(i)", &gesture_type); + + LOGD("invocation id (%d), gesture type(%d)", id, gesture_type); + GVariant* body = g_variant_new("(ii)", id, gesture_type); + if (NULL == body) { + LOGE("Fail to create body"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + ret = gestured_send_dbus_message(body, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); if (ret != GESTURED_ERROR_NONE) LOGE("Failed to start to engine"); return ret; } -int gestured_client_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender) +int gestured_client_get_engine_info(GVariant *parameters, GVariant **reply_body, const char *sender, GDBusMethodInvocation* invocation) { - LOGD("[engineInfo] gestured_client_engine_get_info : sendor [%s]", sender); + LOGD("[engineInfo] gestured_client_get_engine_info : sendor [%s]", sender); int ret = GESTURED_ERROR_NONE; - char *cmd = GESTURE_ENGINE_SIGNAL_ENGINE_GET_INFO; + char *cmd = GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO; if (parameters == NULL) { LOGE("failed to get parameters"); return GESTURED_ERROR_INVALID_PARAMETER; } - ret = gestured_send_dbus_message(parameters, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); + int id = gestureInvocationManagerAdd(invocation); + if (0 > id) { + LOGE("Fail to store invocation"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + LOGD("invocation ID (%d)", id); + GVariant* body = g_variant_new("(i)", id); + if (NULL == body) { + LOGE("Fail to create body"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + ret = gestured_send_dbus_message(body, sender, cmd, GESTURE_CLIENT_LIB_ENGINE); if (ret != GESTURED_ERROR_NONE) LOGE("Failed to start to engine"); @@ -835,6 +849,64 @@ int gestured_engine_send_engine_get_info(GVariant *parameters, GVariant **reply_ return ret; } +int gestured_reply_is_support_gesture_type(int invocation_id, bool is_supported) +{ + GDBusMethodInvocation *invocation = gestureInvocationManagerGet(invocation_id); + if (NULL == invocation) { + LOGE("Invalid invocation ID"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + gestureInvocationManagerRemove(invocation_id); + + GVariant *reply_body = g_variant_new("(b)", is_supported); + if (NULL == reply_body) { + LOGE("Fail to create reply_body"); + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, GESTURED_ERROR_OPERATION_FAILED, "Fail to create return value"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + LOGD("Invocation ID(%d), IsSupport(%d)", invocation_id, is_supported); + + g_dbus_method_invocation_return_value(invocation, reply_body); + g_variant_unref(reply_body); + reply_body = NULL; + + return GESTURED_ERROR_NONE; +} + + +int gestured_reply_get_engine_info(int invocation_id, char* engine_app_id, char* engine_name) +{ + GDBusMethodInvocation *invocation = gestureInvocationManagerGet(invocation_id); + if (NULL == invocation) { + LOGE("Invalid invocation ID"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + gestureInvocationManagerRemove(invocation_id); + + if (NULL == engine_app_id || NULL == engine_name) { + LOGE("Invalid parameter"); + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, GESTURED_ERROR_INVALID_PARAMETER, "Invalid parameter"); + return GESTURED_ERROR_INVALID_PARAMETER; + } + + GVariant *reply_body = g_variant_new("(ss)", engine_app_id, engine_name); + if (NULL == reply_body) { + LOGE("Fail to create reply_body"); + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, GESTURED_ERROR_OPERATION_FAILED, "Fail to create return value"); + return GESTURED_ERROR_OPERATION_FAILED; + } + + LOGD("Invocation ID(%d), APP ID(%s), Name(%s)", invocation_id, engine_app_id, engine_name); + + g_dbus_method_invocation_return_value(invocation, reply_body); + g_variant_unref(reply_body); + reply_body = NULL; + + return GESTURED_ERROR_NONE; +} + + static void __response_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) { LOGD("app_control launch result : %d", result); diff --git a/server/gestured_dbus.h b/server/gestured_dbus.h index 03d5452..5ccda23 100644 --- a/server/gestured_dbus.h +++ b/server/gestured_dbus.h @@ -50,8 +50,8 @@ int gestured_client_start_recognition(GVariant *parameters, GVariant **reply_bod int gestured_client_stop_recognition(GVariant *parameters, GVariant **reply_body, const char *sender); int gestured_client_foreach_result_time(GVariant *parameters, GVariant **reply_body, const char *sender); int gestured_client_foreach_supported_type(GVariant *parameters, GVariant **reply_body, const char *sender); -int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender); -int gestured_client_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender); +int gestured_client_is_support_gesture_type(GVariant *parameters, GVariant **reply_body, const char *sender, GDBusMethodInvocation* invocation); +int gestured_client_get_engine_info(GVariant *parameters, GVariant **reply_body, const char *sender, GDBusMethodInvocation* invocation); /* engine side function : engine -> daemon */ int gestured_engine_send_result(GVariant *parameters, GVariant **reply_body, const char *sender); @@ -59,6 +59,10 @@ int gestured_engine_send_error(GVariant *parameters, GVariant **reply_body, cons int gestured_engine_send_motion_status(GVariant *parameters, GVariant **reply_body, const char *sender); int gestured_engine_send_engine_get_info(GVariant *parameters, GVariant **reply_body, const char *sender); +/* daemon side function : daemon -> client */ +int gestured_reply_is_support_gesture_type(int invocation_id, bool is_supported); +int gestured_reply_get_engine_info(int invocation_id, char* engine_app_id, char* engine_name); + int __launch_engine_service_app(char *appid); -- 2.7.4