2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
20 #include <cynara-client.h>
21 #include <cynara-error.h>
22 #include <cynara-session.h>
23 #include <system_info.h>
26 #include "gesture_internal.h"
27 #include "gesture_common_internal.h"
28 #include "gesture_main.h"
29 #include "gesture_client_dbus.h"
30 #include "gesture_data_info.h"
36 #define LOG_TAG "GESTURE_CLIENT"
38 #define GESTURE_FIRST HAND_GESTURE_WRIST_UP
39 #define GESTURE_LAST HAND_GESTURE_WRIST_UP
40 //#define GESTURE_LAST GESTURE_RIGHT_HAND_MOVE
41 #define IS_VALID_GESTURE(X) (GESTURE_FIRST <= (X) && (X) <= GESTURE_LAST)
44 static cynara *p_cynara = NULL;
46 static int _cynara_initialize()
48 int ret = cynara_initialize(&p_cynara, NULL);
49 if (ret != CYNARA_API_SUCCESS)
50 LOGE("Failed to cynara initialize");
55 static char * _get_smack_label()
58 char label_path[1024] = "/proc/self/attr/current";
59 static char smack_label[1024] = {'\0',};
61 fp = fopen(label_path, "r");
63 int ret = fread(smack_label, 1, sizeof(smack_label), fp);
65 LOGE("Failed to fread");
73 static int _check_privilege(const char *uid, const char *privilege)
76 char smack_label[1024] = {'\0',};
81 char * sl = _get_smack_label();
82 memcpy(smack_label, sl, strlen(sl) + 1);
85 char *session = cynara_session_from_pid(pid);
86 ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
90 if (ret != CYNARA_API_ACCESS_ALLOWED) {
91 LOGE("Access denied. The result of cynara_check() : %d.", ret);
98 static void _cynara_deinitialize()
101 cynara_finish(p_cynara);
106 static int _gesture_check_privilege()
109 int ret = HAND_GESTURE_ERROR_NONE;
111 if (_cynara_initialize() != CYNARA_API_SUCCESS)
112 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
114 snprintf(uid, 16, "%d", getuid());
115 if (_check_privilege(uid, GESTURE_PRIVILEGE_APPLAUNCH) < 0) {
116 LOGE("Permission is denied");
117 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
120 _cynara_deinitialize();
125 EXPORT_API int hand_gesture_create(hand_gesture_h *handle)
127 LOGD("hand_gesture_create");
129 CHECK_GESTURE_FEATURE();
130 ASSERT_NOT_NULL(handle);
134 if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
135 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
137 struct hand_gesture_s *_struct = (hand_gesture_h)calloc(1, sizeof(struct hand_gesture_s));
140 return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
142 /* get uid and smack label */
143 snprintf(_struct->uid, 16, "%d", getuid());
145 char *sl = _get_smack_label();
146 memcpy(_struct->smack_label, sl, strlen(sl) + 1);
148 LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label);
150 ret = gesture_client_dbus_init(&_struct->gdbus_connection, &_struct->server_watcher_id,
151 &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, _struct->uid, _struct->smack_label, (void *)_struct);
152 if (ret != HAND_GESTURE_ERROR_NONE) {
153 LOGE("Failed to initialize dbus : %d", ret);
155 return HAND_GESTURE_ERROR_OPERATION_FAILED;
158 ret = gesture_client_dbus_initialize_engine(_struct->gdbus_connection);
159 if (ret != HAND_GESTURE_ERROR_NONE) {
160 LOGE("Failed to initialize engine dbus : %d", ret);
162 return HAND_GESTURE_ERROR_OPERATION_FAILED;
168 return HAND_GESTURE_ERROR_NONE;
171 EXPORT_API int hand_gesture_destroy(hand_gesture_h handle)
173 LOGD("hand_gesture_destroy");
175 CHECK_GESTURE_FEATURE();
176 ASSERT_NOT_NULL(handle);
180 LOGD("handle : %p", handle);
181 ret = gesture_client_dbus_shutdown(handle->gdbus_connection, &handle->server_monitor_id, &handle->monitor_id);
182 if (ret != HAND_GESTURE_ERROR_NONE) {
183 LOGE("Failed to finalize dbus : %d", ret);
185 return HAND_GESTURE_ERROR_OPERATION_FAILED;
188 if (handle->gdbus_connection)
189 g_object_unref(handle->gdbus_connection);
193 return HAND_GESTURE_ERROR_NONE;
196 EXPORT_API int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e gesture, bool* supported)
198 LOGD("hand_gesture_is_supported_type");
200 CHECK_GESTURE_FEATURE();
201 ASSERT_NOT_NULL(handle);
202 ASSERT_NOT_NULL(supported);
205 ret = gesture_client_dbus_is_support_gesture_type(handle->gdbus_connection, gesture, supported);
206 if (ret != HAND_GESTURE_ERROR_NONE) {
207 LOGE("Failed to get is_supported_type dbus : %d", ret);
209 return HAND_GESTURE_ERROR_OPERATION_FAILED;
212 return HAND_GESTURE_ERROR_NONE;
215 EXPORT_API int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type)
217 LOGD("hand_gesture_set_handtype");
219 CHECK_GESTURE_FEATURE();
220 ASSERT_NOT_NULL(handle);
222 int ret = HAND_GESTURE_ERROR_NONE;
224 ret = gesture_client_dbus_set_handtype(handle->gdbus_connection, hand_type);
225 if (ret != HAND_GESTURE_ERROR_NONE) {
226 LOGE("Failed to set handtype : %d", ret);
227 return HAND_GESTURE_ERROR_OPERATION_FAILED;
233 EXPORT_API int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode)
235 LOGD("hand_gesture_set_workmode");
237 CHECK_GESTURE_FEATURE();
238 ASSERT_NOT_NULL(handle);
240 int ret = HAND_GESTURE_ERROR_NONE;
242 ret = gesture_client_dbus_set_workmode(handle->gdbus_connection, work_mode);
243 if (ret != HAND_GESTURE_ERROR_NONE) {
244 LOGE("Failed to set work_mode : %d", ret);
245 return HAND_GESTURE_ERROR_OPERATION_FAILED;
251 EXPORT_API int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option)
253 LOGD("hand_gesture_set_option");
255 CHECK_GESTURE_FEATURE();
256 ASSERT_NOT_NULL(handle);
258 int ret = HAND_GESTURE_ERROR_NONE;
260 ret = gesture_client_dbus_set_option(handle->gdbus_connection, option);
261 if (ret != HAND_GESTURE_ERROR_NONE) {
262 LOGE("Failed to set option : %d", ret);
263 return HAND_GESTURE_ERROR_OPERATION_FAILED;
269 EXPORT_API int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity)
271 LOGD("hand_gesture_set_sensitivity");
273 CHECK_GESTURE_FEATURE();
274 ASSERT_NOT_NULL(handle);
276 int ret = HAND_GESTURE_ERROR_NONE;
278 ret = gesture_client_dbus_set_sensitivity(handle->gdbus_connection, sensitivity);
279 if (ret != HAND_GESTURE_ERROR_NONE) {
280 LOGE("Failed to set sensitivity : %d", ret);
281 return HAND_GESTURE_ERROR_OPERATION_FAILED;
287 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)
289 LOGD("hand_gesture_start_recognition");
291 CHECK_GESTURE_FEATURE();
292 ASSERT_NOT_NULL(handle);
294 if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
295 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
297 ASSERT_NOT_NULL(callback);
298 IF_FAIL_RETURN(IS_VALID_GESTURE(gesture_type), HAND_GESTURE_ERROR_INVALID_PARAMETER);
300 int ret = HAND_GESTURE_ERROR_NONE;
302 /* Set recognition callback and userdata in the handle */
303 handle->recog_cb = callback;
304 handle->recog_user_data = user_data;
306 // TODO: analysis the purpose of this data.
307 // hand_gesture_data_h gesture_data = (hand_gesture_data_h)calloc(1, sizeof(struct hand_gesture_data_s));
308 // if (!gesture_data) {
309 // return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
312 ret = gesture_client_dbus_start_recognition(handle->gdbus_connection, gesture_type, NULL, callback);
313 if (ret != HAND_GESTURE_ERROR_NONE) {
314 LOGE("Failed to start recoginition : %d", ret);
315 return HAND_GESTURE_ERROR_OPERATION_FAILED;
321 EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle)
323 CHECK_GESTURE_FEATURE();
325 ASSERT_NOT_NULL(handle);
327 int ret = HAND_GESTURE_ERROR_NONE;
328 ret = gesture_client_dbus_stop_recognition(handle->gdbus_connection);
329 if (ret != HAND_GESTURE_ERROR_NONE) {
330 LOGE("Failed to stop recoginition : %d", ret);
331 return HAND_GESTURE_ERROR_OPERATION_FAILED;
334 /* Unset recognition callback and userdata in the handle */
335 handle->recog_cb = NULL;
336 handle->recog_user_data = NULL;
338 return HAND_GESTURE_ERROR_NONE;
341 EXPORT_API int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event)
343 CHECK_GESTURE_FEATURE();
344 ASSERT_NOT_NULL(data);
345 ASSERT_NOT_NULL(event);
347 //*event = static_cast<gesture_event_e>(data->event);
349 return HAND_GESTURE_ERROR_NONE;
352 EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name)
354 LOGD("[engineInfo] hand_gesture_get_engine_info");
356 CHECK_GESTURE_FEATURE();
357 ASSERT_NOT_NULL(handle);
359 int ret = HAND_GESTURE_ERROR_NONE;
361 ret = gesture_client_dbus_get_engine_info(handle->gdbus_connection, engine_app_id, engine_name);
362 if (ret != HAND_GESTURE_ERROR_NONE) {
363 LOGE("Failed to get engine info : %d", ret);
364 return HAND_GESTURE_ERROR_OPERATION_FAILED;
366 LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name);
370 EXPORT_API int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data)
372 CHECK_GESTURE_FEATURE();
373 ASSERT_NOT_NULL(handle);
375 ASSERT_NOT_NULL(callback);
377 LOGD("[DEBUG] Set error_cb");
379 int ret = HAND_GESTURE_ERROR_NONE;
381 handle->error_cb = callback;
382 handle->error_user_data = user_data;
388 EXPORT_API int hand_gesture_unset_error_cb(hand_gesture_h handle)
390 CHECK_GESTURE_FEATURE();
391 ASSERT_NOT_NULL(handle);
393 LOGD("[DEBUG] Unset error_cb");
395 int ret = HAND_GESTURE_ERROR_NONE;
397 handle->error_cb = NULL;
398 handle->error_user_data = NULL;