Change length of copy when snprintf is called
[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(handle);
205         ASSERT_NOT_NULL(supported);
206
207         int ret;
208         ret = gesture_client_dbus_is_support_gesture_type(handle->gdbus_connection, gesture, supported);
209         if (ret != HAND_GESTURE_ERROR_NONE) {
210                 LOGE("Failed to get is_supported_type dbus : %d", ret);
211                 free(handle);
212                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
213         }
214
215         return HAND_GESTURE_ERROR_NONE;
216 }
217 //LCOV_EXCL_START
218 EXPORT_API int hand_gesture_set_handtype(hand_gesture_h handle, hand_gesture_handtype_e hand_type)
219 {
220         LOGD("hand_gesture_set_handtype");
221
222         CHECK_GESTURE_FEATURE();
223         ASSERT_NOT_NULL(handle);
224
225         int ret = HAND_GESTURE_ERROR_NONE;
226
227         ret = gesture_client_dbus_set_handtype(handle->gdbus_connection, hand_type);
228         if (ret != HAND_GESTURE_ERROR_NONE) {
229                 LOGE("Failed to set handtype : %d", ret);
230                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
231         }
232
233         return ret;
234 }
235
236 EXPORT_API int hand_gesture_set_workmode(hand_gesture_h handle, hand_gesture_workmode_e work_mode)
237 {
238         LOGD("hand_gesture_set_workmode");
239
240         CHECK_GESTURE_FEATURE();
241         ASSERT_NOT_NULL(handle);
242
243         int ret = HAND_GESTURE_ERROR_NONE;
244
245         ret = gesture_client_dbus_set_workmode(handle->gdbus_connection, work_mode);
246         if (ret != HAND_GESTURE_ERROR_NONE) {
247                 LOGE("Failed to set work_mode : %d", ret);
248                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
249         }
250
251         return ret;
252 }
253 //LCOV_EXCL_STOP
254 EXPORT_API int hand_gesture_set_option(hand_gesture_h handle, hand_gesture_option_e option)
255 {
256         LOGD("hand_gesture_set_option");
257
258         CHECK_GESTURE_FEATURE();
259         ASSERT_NOT_NULL(handle);
260
261         int ret = HAND_GESTURE_ERROR_NONE;
262
263         ret = gesture_client_dbus_set_option(handle->gdbus_connection, option);
264         if (ret != HAND_GESTURE_ERROR_NONE) {
265                 LOGE("Failed to set option : %d", ret);
266                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
267         }
268
269         return ret;
270 }
271 //LCOV_EXCL_START
272 EXPORT_API int hand_gesture_set_sensitivity(hand_gesture_h handle, int sensitivity)
273 {
274         LOGD("hand_gesture_set_sensitivity");
275
276         CHECK_GESTURE_FEATURE();
277         ASSERT_NOT_NULL(handle);
278
279         int ret = HAND_GESTURE_ERROR_NONE;
280
281         ret = gesture_client_dbus_set_sensitivity(handle->gdbus_connection, sensitivity);
282         if (ret != HAND_GESTURE_ERROR_NONE) {
283                 LOGE("Failed to set sensitivity : %d", ret);
284                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
285         }
286
287         return ret;
288 }
289 //LCOV_EXCL_STOP
290 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)
291 {
292         LOGD("hand_gesture_start_recognition");
293
294         CHECK_GESTURE_FEATURE();
295         ASSERT_NOT_NULL(handle);
296
297         if (_gesture_check_privilege() != HAND_GESTURE_ERROR_NONE)
298                 return HAND_GESTURE_ERROR_PERMISSION_DENIED;
299
300         ASSERT_NOT_NULL(callback);
301         IF_FAIL_RETURN(IS_VALID_GESTURE(gesture_type), HAND_GESTURE_ERROR_INVALID_PARAMETER);
302
303         int ret = HAND_GESTURE_ERROR_NONE;
304
305         /* Set recognition callback and userdata in the handle */
306         handle->recog_cb = callback;
307         handle->recog_user_data = user_data;
308
309         hand_gesture_data_h gesture_data = (hand_gesture_data_h)calloc(1, sizeof(struct hand_gesture_data_s));
310         if (!gesture_data) {
311                 return HAND_GESTURE_ERROR_OUT_OF_MEMORY;
312         }
313
314         ret = gesture_client_dbus_start_recognition(handle->gdbus_connection, gesture_type, gesture_data, callback);
315         if (ret != HAND_GESTURE_ERROR_NONE) {
316                 LOGE("Failed to start recoginition : %d", ret);
317                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
318         }
319
320         return ret;
321 }
322
323 EXPORT_API int hand_gesture_stop_recognition(hand_gesture_h handle)
324 {
325         CHECK_GESTURE_FEATURE();
326
327         ASSERT_NOT_NULL(handle);
328
329         int ret = HAND_GESTURE_ERROR_NONE;
330         ret = gesture_client_dbus_stop_recognition(handle->gdbus_connection);
331         if (ret != HAND_GESTURE_ERROR_NONE) {
332                 LOGE("Failed to stop recoginition : %d", ret);
333                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
334         }
335
336         /* Unset recognition callback and userdata in the handle */
337         handle->recog_cb = NULL;
338         handle->recog_user_data = NULL;
339
340         return HAND_GESTURE_ERROR_NONE;
341 }
342 //LCOV_EXCL_START
343 EXPORT_API int hand_gesture_get_event(const hand_gesture_data_h data, hand_gesture_event_e *event)
344 {
345         CHECK_GESTURE_FEATURE();
346         ASSERT_NOT_NULL(data);
347         ASSERT_NOT_NULL(event);
348
349         //*event = static_cast<gesture_event_e>(data->event);
350
351         return HAND_GESTURE_ERROR_NONE;
352 }
353 //LCOV_EXCL_STOP
354 EXPORT_API int hand_gesture_get_engine_info(hand_gesture_h handle, char** engine_app_id, char** engine_name)
355 {
356         LOGD("[engineInfo] hand_gesture_get_engine_info");
357
358         CHECK_GESTURE_FEATURE();
359         ASSERT_NOT_NULL(handle);
360
361         int ret = HAND_GESTURE_ERROR_NONE;
362
363         ret = gesture_client_dbus_get_engine_info(handle->gdbus_connection, engine_app_id, engine_name);
364         if (ret != HAND_GESTURE_ERROR_NONE) {
365                 LOGE("Failed to get engine info : %d", ret);
366                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
367         }
368         LOGD("[engineInfo] hand_gesture_get_engine_info : engine_app_id = %s, engine_name = %s", *engine_app_id, *engine_name);
369         return ret;
370 }
371
372 EXPORT_API int hand_gesture_set_error_cb(hand_gesture_h handle, hand_gesture_error_cb callback, void *user_data)
373 {
374         CHECK_GESTURE_FEATURE();
375         ASSERT_NOT_NULL(handle);
376
377         ASSERT_NOT_NULL(callback);
378
379         LOGD("[DEBUG] Set error_cb");
380
381         int ret = HAND_GESTURE_ERROR_NONE;
382
383         handle->error_cb = callback;
384         handle->error_user_data = user_data;
385
386
387         return ret;
388 }
389
390 EXPORT_API int hand_gesture_unset_error_cb(hand_gesture_h handle)
391 {
392         CHECK_GESTURE_FEATURE();
393         ASSERT_NOT_NULL(handle);
394
395         LOGD("[DEBUG] Unset error_cb");
396
397         int ret = HAND_GESTURE_ERROR_NONE;
398
399         handle->error_cb = NULL;
400         handle->error_user_data = NULL;
401
402
403         return ret;
404 }