Move header into proper file
[platform/core/api/gesture.git] / client / gesture.c
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <dlog.h>
18 #include <gio/gio.h>
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>
24
25 #include "gesture.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"
31
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36 #define LOG_TAG "GESTURE_CLIENT"
37
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)
42
43
44 static cynara *p_cynara = NULL;
45
46 static int _cynara_initialize()
47 {
48         int ret = cynara_initialize(&p_cynara, NULL);
49         if (ret != CYNARA_API_SUCCESS)
50                 LOGE("Failed to cynara initialize");
51
52         return ret;
53 }
54
55 static char * _get_smack_label()
56 {
57         FILE *fp = NULL;
58         char label_path[1024] = "/proc/self/attr/current";
59         static char smack_label[1024] = {'\0',};
60
61         fp = fopen(label_path, "r");
62         if (fp != NULL) {
63                 int ret = fread(smack_label, 1, sizeof(smack_label), fp);
64                 if (ret <= 0)
65                         LOGE("Failed to fread");
66
67                 fclose(fp);
68         }
69
70         return smack_label;
71 }
72
73 static int _check_privilege(const char *uid, const char *privilege)
74 {
75         int ret;
76         char smack_label[1024] = {'\0',};
77
78         if (!p_cynara) {
79                 return -1;
80         }
81         char * sl = _get_smack_label();
82         memcpy(smack_label, sl, strlen(sl) + 1);
83
84         pid_t pid = getpid();
85         char *session = cynara_session_from_pid(pid);
86         ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
87         if (session)
88                 free(session);
89
90         if (ret != CYNARA_API_ACCESS_ALLOWED) {
91                 LOGE("Access denied. The result of cynara_check() : %d.", ret);
92                 return -1;
93         }
94
95         return 0;
96 }
97
98 static void _cynara_deinitialize()
99 {
100         if (p_cynara)
101                 cynara_finish(p_cynara);
102
103         p_cynara = NULL;
104 }
105
106 static int _gesture_check_privilege()
107 {
108         char uid[16];
109         int ret = HAND_GESTURE_ERROR_NONE;
110
111         if (_cynara_initialize() != CYNARA_API_SUCCESS)
112                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
113
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;
118         }
119
120         _cynara_deinitialize();
121
122         return ret;
123 }
124
125 EXPORT_API int hand_gesture_create(hand_gesture_h *handle)
126 {
127         LOGD("hand_gesture_create");
128
129         CHECK_GESTURE_FEATURE();
130         ASSERT_NOT_NULL(handle);
131
132         int ret;
133
134         if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
135                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
136
137         struct hand_gesture_s *_struct = (hand_gesture_h)calloc(1, sizeof(struct hand_gesture_s));
138
139         if (!_struct)
140                 return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
141
142         /* get uid and smack label */
143         snprintf(_struct->uid, 16, "%d", getuid());
144
145         char *sl = _get_smack_label();
146         memcpy(_struct->smack_label, sl, strlen(sl) + 1);
147
148         LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label);
149
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);
154                 free(_struct);
155                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
156         }
157
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);
161                 free(_struct);
162                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
163         }
164
165         *handle = _struct;
166
167
168         return HAND_GESTURE_ERROR_NONE;
169 }
170
171 EXPORT_API int hand_gesture_destroy(hand_gesture_h handle)
172 {
173         LOGD("hand_gesture_destroy");
174
175         CHECK_GESTURE_FEATURE();
176         ASSERT_NOT_NULL(handle);
177
178         int ret;
179
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);
184                 free(handle);
185                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
186         }
187
188         if (handle->gdbus_connection)
189                 g_object_unref(handle->gdbus_connection);
190
191         free(handle);
192
193         return HAND_GESTURE_ERROR_NONE;
194 }
195
196 EXPORT_API int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e gesture, bool* supported)
197 {
198         LOGD("hand_gesture_is_supported_type");
199
200         CHECK_GESTURE_FEATURE();
201         ASSERT_NOT_NULL(handle);
202         ASSERT_NOT_NULL(supported);
203
204         int ret;
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);
208                 free(handle);
209                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
210         }
211
212         return HAND_GESTURE_ERROR_NONE;
213 }
214 //LCOV_EXCL_START
215 EXPORT_API int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type)
216 {
217         LOGD("hand_gesture_set_handtype");
218
219         CHECK_GESTURE_FEATURE();
220         ASSERT_NOT_NULL(handle);
221
222         int ret = HAND_GESTURE_ERROR_NONE;
223
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;
228         }
229
230         return ret;
231 }
232
233 EXPORT_API int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode)
234 {
235         LOGD("hand_gesture_set_workmode");
236
237         CHECK_GESTURE_FEATURE();
238         ASSERT_NOT_NULL(handle);
239
240         int ret = HAND_GESTURE_ERROR_NONE;
241
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;
246         }
247
248         return ret;
249 }
250 //LCOV_EXCL_STOP
251 EXPORT_API int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option)
252 {
253         LOGD("hand_gesture_set_option");
254
255         CHECK_GESTURE_FEATURE();
256         ASSERT_NOT_NULL(handle);
257
258         int ret = HAND_GESTURE_ERROR_NONE;
259
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;
264         }
265
266         return ret;
267 }
268 //LCOV_EXCL_START
269 EXPORT_API int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity)
270 {
271         LOGD("hand_gesture_set_sensitivity");
272
273         CHECK_GESTURE_FEATURE();
274         ASSERT_NOT_NULL(handle);
275
276         int ret = HAND_GESTURE_ERROR_NONE;
277
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;
282         }
283
284         return ret;
285 }
286 //LCOV_EXCL_STOP
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)
288 {
289         LOGD("hand_gesture_start_recognition");
290
291         CHECK_GESTURE_FEATURE();
292         ASSERT_NOT_NULL(handle);
293
294         if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
295                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
296
297         ASSERT_NOT_NULL(callback);
298         IF_FAIL_RETURN(IS_VALID_GESTURE(gesture_type), HAND_GESTURE_ERROR_INVALID_PARAMETER);
299
300         int ret = HAND_GESTURE_ERROR_NONE;
301
302         /* Set recognition callback and userdata in the handle */
303         handle->recog_cb = callback;
304         handle->recog_user_data = user_data;
305
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;
310         // }
311
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;
316         }
317
318         return ret;
319 }
320
321 EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle)
322 {
323         CHECK_GESTURE_FEATURE();
324
325         ASSERT_NOT_NULL(handle);
326
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;
332         }
333
334         /* Unset recognition callback and userdata in the handle */
335         handle->recog_cb = NULL;
336         handle->recog_user_data = NULL;
337
338         return HAND_GESTURE_ERROR_NONE;
339 }
340 //LCOV_EXCL_START
341 EXPORT_API int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event)
342 {
343         CHECK_GESTURE_FEATURE();
344         ASSERT_NOT_NULL(data);
345         ASSERT_NOT_NULL(event);
346
347         //*event = static_cast<gesture_event_e>(data->event);
348
349         return HAND_GESTURE_ERROR_NONE;
350 }
351 //LCOV_EXCL_STOP
352 EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name)
353 {
354         LOGD("[engineInfo] hand_gesture_get_engine_info");
355
356         CHECK_GESTURE_FEATURE();
357         ASSERT_NOT_NULL(handle);
358
359         int ret = HAND_GESTURE_ERROR_NONE;
360
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;
365         }
366         LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name);
367         return ret;
368 }
369
370 EXPORT_API int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data)
371 {
372         CHECK_GESTURE_FEATURE();
373         ASSERT_NOT_NULL(handle);
374
375         ASSERT_NOT_NULL(callback);
376
377         LOGD("[DEBUG] Set error_cb");
378
379         int ret = HAND_GESTURE_ERROR_NONE;
380
381         handle->error_cb = callback;
382         handle->error_user_data = user_data;
383
384
385         return ret;
386 }
387
388 EXPORT_API int hand_gesture_unset_error_cb(hand_gesture_h handle)
389 {
390         CHECK_GESTURE_FEATURE();
391         ASSERT_NOT_NULL(handle);
392
393         LOGD("[DEBUG] Unset error_cb");
394
395         int ret = HAND_GESTURE_ERROR_NONE;
396
397         handle->error_cb = NULL;
398         handle->error_user_data = NULL;
399
400
401         return ret;
402 }