Fix issue that detected by static analysis tool
[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
31
32 #ifdef LOG_TAG
33 #undef LOG_TAG
34 #endif
35 #define LOG_TAG "GESTURE_CLIENT"
36
37 #define GESTURE_FIRST   HAND_GESTURE_WRIST_UP
38 #define GESTURE_LAST    HAND_GESTURE_WRIST_UP
39 //#define GESTURE_LAST  GESTURE_RIGHT_HAND_MOVE
40 #define IS_VALID_GESTURE(X)     (GESTURE_FIRST <= (X) && (X) <= GESTURE_LAST)
41
42
43 static cynara *p_cynara = NULL;
44
45 static int _cynara_initialize()
46 {
47         int ret = cynara_initialize(&p_cynara, NULL);
48         if (ret != CYNARA_API_SUCCESS)
49                 LOGE("Failed to cynara initialize");
50
51         return ret;
52 }
53
54 static char * _get_smack_label()
55 {
56         FILE *fp = NULL;
57         char label_path[1024] = "/proc/self/attr/current";
58         static char smack_label[1024] = {'\0',};
59
60         fp = fopen(label_path, "r");
61         if (fp != NULL) {
62                 int ret = fread(smack_label, 1, sizeof(smack_label), fp);
63                 if (ret <= 0)
64                         LOGE("Failed to fread");
65
66                 fclose(fp);
67         }
68
69         return smack_label;
70 }
71
72 static int _check_privilege(const char *uid, const char *privilege)
73 {
74         int ret;
75         char smack_label[1024] = {'\0',};
76
77         if (!p_cynara) {
78                 return -1;
79         }
80         char * sl = _get_smack_label();
81         memcpy(smack_label, sl, strlen(sl) + 1);
82
83         pid_t pid = getpid();
84         char *session = cynara_session_from_pid(pid);
85         ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
86         if (session)
87                 free(session);
88
89         if (ret != CYNARA_API_ACCESS_ALLOWED) {
90                 LOGE("Access denied. The result of cynara_check() : %d.", ret);
91                 return -1;
92         }
93
94         return 0;
95 }
96
97 static void _cynara_deinitialize()
98 {
99         if (p_cynara)
100                 cynara_finish(p_cynara);
101
102         p_cynara = NULL;
103 }
104
105 static int _gesture_check_privilege()
106 {
107         char uid[16];
108         int ret = HAND_GESTURE_ERROR_NONE;
109
110         if (_cynara_initialize() != CYNARA_API_SUCCESS)
111                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
112
113         snprintf(uid, 16, "%d", getuid());
114         if (_check_privilege(uid, GESTURE_PRIVILEGE_APPLAUNCH) < 0) {
115                 LOGE("Permission is denied");
116                 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
117         }
118
119         _cynara_deinitialize();
120
121         return ret;
122 }
123
124 EXPORT_API int hand_gesture_create(hand_gesture_h *handle)
125 {
126         LOGD("hand_gesture_create");
127
128         CHECK_GESTURE_FEATURE();
129         ASSERT_NOT_NULL(handle);
130
131         int ret;
132         if (!handle)
133                 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
134
135         if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
136                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
137
138         struct hand_gesture_s *_struct = (hand_gesture_h)calloc(1, sizeof(struct hand_gesture_s));
139
140         if (!_struct)
141                 return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
142
143         /* get uid and smack label */
144         snprintf(_struct->uid, 16, "%d", getuid());
145
146         char *sl = _get_smack_label();
147         memcpy(_struct->smack_label, sl, strlen(sl) + 1);
148
149         LOGI("uid(%s), smack(%s)", _struct->uid, _struct->smack_label);
150
151         ret = gesture_client_dbus_init(&_struct->gdbus_connection, &_struct->server_watcher_id,
152                 &_struct->monitor_id, &_struct->server_monitor_id, GESTURE_CLIENT_LIB_GESTURE, _struct->uid, _struct->smack_label, (void *)_struct);
153         if (ret != HAND_GESTURE_ERROR_NONE) {
154                 LOGE("Failed to initialize dbus : %d", ret);
155                 free(_struct);
156                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
157         }
158
159         ret = gesture_client_dbus_initialize_engine(_struct->gdbus_connection);
160         if (ret != HAND_GESTURE_ERROR_NONE) {
161                 LOGE("Failed to initialize engine dbus : %d", ret);
162                 free(_struct);
163                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
164         }
165
166         *handle = _struct;
167
168
169         return HAND_GESTURE_ERROR_NONE;
170 }
171
172 EXPORT_API int hand_gesture_destroy(hand_gesture_h handle)
173 {
174         LOGD("hand_gesture_destroy");
175
176         CHECK_GESTURE_FEATURE();
177         ASSERT_NOT_NULL(handle);
178
179         int ret;
180         if (!handle)
181                 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
182
183         LOGD("handle : %p", handle);
184         ret = gesture_client_dbus_shutdown(handle->gdbus_connection, &handle->server_monitor_id, &handle->monitor_id);
185         if (ret != HAND_GESTURE_ERROR_NONE) {
186                 LOGE("Failed to finalize dbus : %d", ret);
187                 free(handle);
188                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
189         }
190
191         if (handle->gdbus_connection)
192                 g_object_unref(handle->gdbus_connection);
193
194         free(handle);
195
196         return HAND_GESTURE_ERROR_NONE;
197 }
198
199 EXPORT_API int hand_gesture_is_supported_type(hand_gesture_h handle, hand_gesture_type_e gesture, bool* supported)
200 {
201         LOGD("hand_gesture_is_supported_type");
202
203         CHECK_GESTURE_FEATURE();
204         ASSERT_NOT_NULL(supported);
205
206         int ret;
207         ret = gesture_client_dbus_is_support_gesture_type(handle->gdbus_connection, gesture, supported);
208         if (ret != HAND_GESTURE_ERROR_NONE) {
209                 LOGE("Failed to get is_supported_type dbus : %d", ret);
210                 free(handle);
211                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
212         }
213
214         return HAND_GESTURE_ERROR_NONE;
215 }
216
217 EXPORT_API int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type)
218 {
219         LOGD("hand_gesture_set_handtype");
220
221         CHECK_GESTURE_FEATURE();
222         ASSERT_NOT_NULL(handle);
223
224         int ret = HAND_GESTURE_ERROR_NONE;
225
226         ret = gesture_client_dbus_set_handtype(handle->gdbus_connection, hand_type);
227         if (ret != HAND_GESTURE_ERROR_NONE) {
228                 LOGE("Failed to set handtype : %d", ret);
229                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
230         }
231
232         return ret;
233 }
234
235 EXPORT_API int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode)
236 {
237         LOGD("hand_gesture_set_workmode");
238
239         CHECK_GESTURE_FEATURE();
240         ASSERT_NOT_NULL(handle);
241
242         int ret = HAND_GESTURE_ERROR_NONE;
243
244         ret = gesture_client_dbus_set_workmode(handle->gdbus_connection, work_mode);
245         if (ret != HAND_GESTURE_ERROR_NONE) {
246                 LOGE("Failed to set work_mode : %d", ret);
247                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
248         }
249
250         return ret;
251 }
252
253 EXPORT_API int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option)
254 {
255         LOGD("hand_gesture_set_option");
256
257         CHECK_GESTURE_FEATURE();
258         ASSERT_NOT_NULL(handle);
259
260         int ret = HAND_GESTURE_ERROR_NONE;
261
262         ret = gesture_client_dbus_set_option(handle->gdbus_connection, option);
263         if (ret != HAND_GESTURE_ERROR_NONE) {
264                 LOGE("Failed to set option : %d", ret);
265                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
266         }
267
268         return ret;
269 }
270
271 EXPORT_API int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity)
272 {
273         LOGD("hand_gesture_set_sensitivity");
274
275         CHECK_GESTURE_FEATURE();
276         ASSERT_NOT_NULL(handle);
277
278         int ret = HAND_GESTURE_ERROR_NONE;
279
280         ret = gesture_client_dbus_set_sensitivity(handle->gdbus_connection, sensitivity);
281         if (ret != HAND_GESTURE_ERROR_NONE) {
282                 LOGE("Failed to set sensitivity : %d", ret);
283                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
284         }
285
286         return ret;
287 }
288
289 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)
290 {
291         LOGD("hand_gesture_start_recognition");
292
293         CHECK_GESTURE_FEATURE();
294         ASSERT_NOT_NULL(handle);
295
296         if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
297                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
298
299         ASSERT_NOT_NULL(callback);
300         IF_FAIL_RETURN(IS_VALID_GESTURE(gesture_type), HAND_GESTURE_ERROR_INVALID_PARAMETER);
301
302         int ret = HAND_GESTURE_ERROR_NONE;
303
304         /* Set recognition callback and userdata in the handle */
305         handle->recog_cb = callback;
306         handle->recog_user_data = user_data;
307
308         hand_gesture_data_h gesture_data = (hand_gesture_data_h)calloc(1, sizeof(struct hand_gesture_data_s));
309         if (!gesture_data) {
310                 return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
311         }
312
313         ret = gesture_client_dbus_start_recognition(handle->gdbus_connection, gesture_type, gesture_data, callback);
314         if (ret != HAND_GESTURE_ERROR_NONE) {
315                 LOGE("Failed to start recoginition : %d", ret);
316                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
317         }
318
319         return ret;
320 }
321
322 EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle)
323 {
324         CHECK_GESTURE_FEATURE();
325
326         ASSERT_NOT_NULL(handle);
327
328         int ret = HAND_GESTURE_ERROR_NONE;
329         ret = gesture_client_dbus_stop_recognition(handle->gdbus_connection);
330         if (ret != HAND_GESTURE_ERROR_NONE) {
331                 LOGE("Failed to stop recoginition : %d", ret);
332                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
333         }
334
335         /* Unset recognition callback and userdata in the handle */
336         handle->recog_cb = NULL;
337         handle->recog_user_data = NULL;
338
339         return HAND_GESTURE_ERROR_NONE;
340 }
341
342 EXPORT_API int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event)
343 {
344         CHECK_GESTURE_FEATURE();
345         ASSERT_NOT_NULL(data);
346         ASSERT_NOT_NULL(event);
347
348         //*event = static_cast<gesture_event_e>(data->event);
349
350         return HAND_GESTURE_ERROR_NONE;
351 }
352
353 EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name)
354 {
355         LOGD("[engineInfo] hand_gesture_get_engine_info");
356
357         CHECK_GESTURE_FEATURE();
358         ASSERT_NOT_NULL(handle);
359
360         int ret = HAND_GESTURE_ERROR_NONE;
361
362         ret = gesture_client_dbus_get_engine_info(handle->gdbus_connection, engine_app_id, engine_name);
363         if (ret != HAND_GESTURE_ERROR_NONE) {
364                 LOGE("Failed to get engine info : %d", ret);
365                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
366         }
367         LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name);
368         return ret;
369 }
370
371 EXPORT_API int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data)
372 {
373         CHECK_GESTURE_FEATURE();
374         ASSERT_NOT_NULL(handle);
375
376         ASSERT_NOT_NULL(callback);
377
378         LOGD("[DEBUG] Set error_cb");
379
380         int ret = HAND_GESTURE_ERROR_NONE;
381
382         handle->error_cb = callback;
383         handle->error_user_data = user_data;
384
385
386         return ret;
387 }
388
389 EXPORT_API int hand_gesture_unset_error_cb(hand_gesture_h handle)
390 {
391         CHECK_GESTURE_FEATURE();
392         ASSERT_NOT_NULL(handle);
393
394         LOGD("[DEBUG] Unset error_cb");
395
396         int ret = HAND_GESTURE_ERROR_NONE;
397
398         handle->error_cb = NULL;
399         handle->error_user_data = NULL;
400
401
402         return ret;
403 }