Add exclude section for impossible lines to be executed in TCT
[platform/core/uifw/capi-ui-sticker.git] / consumer / sticker_consumer.c
1 /*
2  * Copyright (c) 2019 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 <app_common.h>
21 #include <cynara-client.h>
22 #include <cynara-error.h>
23 #include <cynara-session.h>
24
25 #include "sticker_consumer.h"
26 #include "sticker_consumer_main.h"
27 #include "sticker_dbus.h"
28
29 #ifdef LOG_TAG
30 #undef LOG_TAG
31 #endif
32 #define LOG_TAG "STICKER_CONSUMER"
33
34 static cynara *p_cynara = NULL;
35
36 static void _free_sticker_data(sticker_data_h sticker_data)
37 {
38     if (sticker_data->app_id) {
39         free(sticker_data->app_id);
40         sticker_data->app_id = NULL;
41     }
42
43     if (sticker_data->uri) {
44         free(sticker_data->uri);
45         sticker_data->uri = NULL;
46     }
47
48     if (sticker_data->thumbnail) {
49         free(sticker_data->thumbnail);
50         sticker_data->thumbnail = NULL;
51     }
52
53     if (sticker_data->keyword) {
54         g_list_free_full(sticker_data->keyword, free);
55         sticker_data->keyword = NULL;
56     }
57
58     if (sticker_data->group) {
59         free(sticker_data->group);
60         sticker_data->group = NULL;
61     }
62
63     if (sticker_data->description) {
64         free(sticker_data->description);
65         sticker_data->description = NULL;
66     }
67
68     if (sticker_data->date) {
69         free(sticker_data->date);
70         sticker_data->date = NULL;
71     }
72
73     free(sticker_data);
74     sticker_data = NULL;
75 }
76
77 static int _cynara_initialize()
78 {
79     int ret = cynara_initialize(&p_cynara, NULL);
80     if (ret != CYNARA_API_SUCCESS)
81         LOGE("Failed to cynara initialize"); //LCOV_EXCL_LINE
82
83     return ret;
84 }
85
86 static int _check_privilege(const char *uid, const char *privilege)
87 {
88     int ret;
89     FILE *fp = NULL;
90     char label_path[1024] = "/proc/self/attr/current";
91     char smack_label[1024] = {'\0',};
92
93     if (!p_cynara) {
94         return -1;
95     }
96
97     fp = fopen(label_path, "r");
98     if (fp != NULL) {
99         ret = fread(smack_label, 1, sizeof(smack_label), fp);
100         if (ret <= 0)
101             LOGE("Failed to fread");
102
103         fclose(fp);
104     }
105
106     pid_t pid = getpid();
107     char *session = cynara_session_from_pid(pid);
108     ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
109     if (session)
110         free(session);
111
112     if (ret != CYNARA_API_ACCESS_ALLOWED) {
113         LOGE("Access denied. The result of cynara_check() : %d.", ret); //LCOV_EXCL_LINE
114         return -1;
115     }
116
117     return 0;
118 }
119
120 static void _cynara_deinitialize()
121 {
122     if (p_cynara)
123         cynara_finish(p_cynara);
124
125     p_cynara = NULL;
126 }
127
128 static int _sticker_check_privilege() {
129     char uid[16];
130     int ret = STICKER_ERROR_NONE;
131
132     if (_cynara_initialize() != CYNARA_API_SUCCESS)
133         return STICKER_ERROR_PERMISSION_DENIED;
134
135     snprintf(uid, 16, "%d", getuid());
136     if (_check_privilege(uid, STICKER_PRIVILEGE_MEDIASTORAGE) < 0) {
137         LOGE("Permission is denied"); //LCOV_EXCL_LINE
138         ret = STICKER_ERROR_PERMISSION_DENIED;
139     }
140
141     _cynara_deinitialize();
142
143     return ret;
144 }
145
146 EXPORT_API int sticker_consumer_create(sticker_consumer_h *consumer_handle)
147 {
148     CHECK_STICKER_FEATURE();
149
150     int ret;
151     if (!consumer_handle)
152         return STICKER_ERROR_INVALID_PARAMETER;
153
154     if (_sticker_check_privilege() != STICKER_ERROR_NONE)
155         return STICKER_ERROR_PERMISSION_DENIED;
156
157     struct sticker_consumer_s *consumer_struct = (sticker_consumer_h)calloc(1, sizeof(struct sticker_consumer_s));
158
159     if (!consumer_struct)
160         return STICKER_ERROR_OUT_OF_MEMORY;
161
162     ret = app_get_id(&consumer_struct->app_id);
163     if (ret != APP_ERROR_NONE) {
164         //LCOV_EXCL_START
165         LOGE("Failed to get app_id : %d", ret);
166         free(consumer_struct);
167         return STICKER_ERROR_OPERATION_FAILED;
168         //LCOV_EXCL_STOP
169     }
170
171     ret = sticker_dbus_init(&consumer_struct->gdbus_connection, &consumer_struct->server_watcher_id,
172         &consumer_struct->monitor_id, &consumer_struct->server_monitor_id, STICKER_CLIENT_LIB_CONSUMER, (void *)consumer_struct);
173     if (ret != STICKER_ERROR_NONE) {
174         //LCOV_EXCL_START
175         LOGE("Failed to initialize dbus : %d", ret);
176         free(consumer_struct);
177         return STICKER_ERROR_OPERATION_FAILED;
178         //LCOV_EXCL_STOP
179     }
180
181     *consumer_handle = consumer_struct;
182
183     return STICKER_ERROR_NONE;
184 }
185
186 EXPORT_API int sticker_consumer_destroy(sticker_consumer_h consumer_handle)
187 {
188     CHECK_STICKER_FEATURE();
189
190     int ret;
191     if (!consumer_handle)
192         return STICKER_ERROR_INVALID_PARAMETER;
193
194     LOGD("consumer_handle : %p", consumer_handle);
195     ret = sticker_dbus_shutdown(consumer_handle->gdbus_connection, &consumer_handle->server_watcher_id,
196                                 &consumer_handle->server_monitor_id, &consumer_handle->monitor_id, STICKER_CLIENT_LIB_CONSUMER);
197     if (ret != STICKER_ERROR_NONE) {
198         //LCOV_EXCL_START
199         LOGE("Failed to finalize dbus : %d", ret);
200         free(consumer_handle);
201         return STICKER_ERROR_OPERATION_FAILED;
202         //LCOV_EXCL_STOP
203     }
204
205     if (consumer_handle->gdbus_connection)
206         g_object_unref(consumer_handle->gdbus_connection);
207
208     if (consumer_handle->app_id) {
209         free(consumer_handle->app_id);
210         consumer_handle->app_id = NULL;
211     }
212
213     free(consumer_handle);
214
215     return STICKER_ERROR_NONE;
216 }
217
218 EXPORT_API int sticker_consumer_data_foreach_all(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data)
219 {
220     CHECK_STICKER_FEATURE();
221
222     int ret;
223     int info_id;
224     int sticker_count = 0;
225     GVariantIter *id_iter = NULL;
226
227     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !callback)
228         return STICKER_ERROR_INVALID_PARAMETER;
229
230     ret = sticker_dbus_get_all_sticker_info(consumer_handle->gdbus_connection, consumer_handle->app_id, offset, count, &id_iter);
231     if (ret != STICKER_ERROR_NONE) {
232         LOGE("Failed to get all sticker information : %d", ret);
233         ret = STICKER_ERROR_OPERATION_FAILED;
234         goto cleanup;
235     }
236
237     if (id_iter) {
238         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
239             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
240             if (!sticker_data) {
241                 ret = STICKER_ERROR_OUT_OF_MEMORY;
242                 goto cleanup;
243             }
244
245             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
246             if (ret == STICKER_ERROR_NONE) {
247                 sticker_count++;
248                 callback(sticker_data, user_data);
249                 _free_sticker_data(sticker_data);
250             } else {
251                 _free_sticker_data(sticker_data);
252                 goto cleanup;
253             }
254         }
255     }
256
257     *result = sticker_count;
258
259 cleanup:
260     if (id_iter)
261         g_variant_iter_free(id_iter);
262
263     return ret;
264 }
265
266 EXPORT_API int sticker_consumer_data_foreach_by_keyword(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *keyword, sticker_consumer_data_foreach_cb callback, void *user_data)
267 {
268     CHECK_STICKER_FEATURE();
269
270     int ret;
271     int info_id;
272     int sticker_count = 0;
273     GVariantIter *id_iter = NULL;
274
275     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !keyword || !callback)
276         return STICKER_ERROR_INVALID_PARAMETER;
277
278     ret = sticker_dbus_get_sticker_info_by_keyword(consumer_handle->gdbus_connection, consumer_handle->app_id, keyword, offset, count, &id_iter);
279     if (ret != STICKER_ERROR_NONE) {
280         LOGE("Failed to get sticker information by keyword : %d", ret);
281         ret = STICKER_ERROR_OPERATION_FAILED;
282         goto cleanup;
283     }
284
285     if (id_iter) {
286         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
287             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
288             if (!sticker_data) {
289                 ret = STICKER_ERROR_OUT_OF_MEMORY;
290                 goto cleanup;
291             }
292
293             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
294             if (ret == STICKER_ERROR_NONE) {
295                 sticker_count++;
296                 callback(sticker_data, user_data);
297                 _free_sticker_data(sticker_data);
298             } else {
299                 _free_sticker_data(sticker_data);
300                 goto cleanup;
301             }
302         }
303     }
304
305     *result = sticker_count;
306
307 cleanup:
308     if (id_iter)
309         g_variant_iter_free(id_iter);
310
311     return ret;
312 }
313
314 EXPORT_API int sticker_consumer_data_foreach_by_group(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *group, sticker_consumer_data_foreach_cb callback, void *user_data)
315 {
316     CHECK_STICKER_FEATURE();
317
318         int ret;
319     int info_id;
320     int sticker_count = 0;
321     GVariantIter *id_iter = NULL;
322
323     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !group || !callback)
324         return STICKER_ERROR_INVALID_PARAMETER;
325
326     ret = sticker_dbus_get_sticker_info_by_group(consumer_handle->gdbus_connection, consumer_handle->app_id, group, offset, count, &id_iter);
327     if (ret != STICKER_ERROR_NONE) {
328         LOGE("Failed to get sticker information by group : %d", ret);
329         ret = STICKER_ERROR_OPERATION_FAILED;
330         goto cleanup;
331     }
332
333     if (id_iter) {
334         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
335             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
336             if (!sticker_data) {
337                 ret = STICKER_ERROR_OUT_OF_MEMORY;
338                 goto cleanup;
339             }
340
341             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
342             if (ret == STICKER_ERROR_NONE) {
343                 sticker_count++;
344                 callback(sticker_data, user_data);
345                 _free_sticker_data(sticker_data);
346             } else {
347                 _free_sticker_data(sticker_data);
348                 goto cleanup;
349             }
350         }
351     }
352
353     *result = sticker_count;
354
355 cleanup:
356     if (id_iter)
357         g_variant_iter_free(id_iter);
358
359     return ret;
360 }
361
362 EXPORT_API int sticker_consumer_data_foreach_by_type(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_data_uri_type_e type, sticker_consumer_data_foreach_cb callback, void *user_data)
363 {
364     CHECK_STICKER_FEATURE();
365
366     int ret;
367     int info_id;
368     int sticker_count = 0;
369     GVariantIter *id_iter = NULL;
370
371     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || (type < 1) || !callback)
372         return STICKER_ERROR_INVALID_PARAMETER;
373
374     ret = sticker_dbus_get_sticker_info_by_type(consumer_handle->gdbus_connection, consumer_handle->app_id, type, offset, count, &id_iter);
375     if (ret != STICKER_ERROR_NONE) {
376         LOGE("Failed to get sticker information by uri type : %d", ret);
377         ret = STICKER_ERROR_OPERATION_FAILED;
378         goto cleanup;
379     }
380
381     if (id_iter) {
382         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
383             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
384             if (!sticker_data) {
385                 ret = STICKER_ERROR_OUT_OF_MEMORY;
386                 goto cleanup;
387             }
388
389             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
390             if (ret == STICKER_ERROR_NONE) {
391                 sticker_count++;
392                 callback(sticker_data, user_data);
393                 _free_sticker_data(sticker_data);
394             } else {
395                 _free_sticker_data(sticker_data);
396                 goto cleanup;
397             }
398         }
399     }
400
401     *result = sticker_count;
402
403 cleanup:
404     if (id_iter)
405         g_variant_iter_free(id_iter);
406
407     return ret;
408 }
409
410 EXPORT_API int sticker_consumer_group_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_group_list_foreach_cb callback, void *user_data)
411 {
412     CHECK_STICKER_FEATURE();
413
414     int ret;
415     GList *list = NULL;
416
417     if (!consumer_handle || !callback)
418         return STICKER_ERROR_INVALID_PARAMETER;
419
420     ret = sticker_dbus_get_group_list(consumer_handle->gdbus_connection, consumer_handle->app_id, &list);
421     if (ret != STICKER_ERROR_NONE) {
422         LOGE("Failed to get group list : %d", ret);
423         ret = STICKER_ERROR_OPERATION_FAILED;
424         goto cleanup;
425     }
426
427     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
428         callback((const char *)tmp->data, user_data);
429     }
430
431 cleanup:
432     if (list)
433         g_list_free_full(list, free);
434
435     return ret;
436 }
437
438 EXPORT_API int sticker_consumer_keyword_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_keyword_list_foreach_cb callback, void *user_data)
439 {
440     CHECK_STICKER_FEATURE();
441
442     int ret;
443     GList *list = NULL;
444
445     if (!consumer_handle || !callback)
446         return STICKER_ERROR_INVALID_PARAMETER;
447
448     ret = sticker_dbus_get_keyword_list(consumer_handle->gdbus_connection, consumer_handle->app_id, &list);
449     if (ret != STICKER_ERROR_NONE) {
450         LOGE("Failed to get keyword list : %d", ret);
451         ret = STICKER_ERROR_OPERATION_FAILED;
452         goto cleanup;
453     }
454
455     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
456         callback((const char *)tmp->data, user_data);
457     }
458
459 cleanup:
460     if (list)
461         g_list_free_full(list, free);
462
463     return ret;
464 }
465
466 EXPORT_API int sticker_consumer_data_foreach_by_display_type(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_data_display_type_e type, sticker_consumer_data_foreach_cb callback, void *user_data)
467 {
468     CHECK_STICKER_FEATURE();
469
470     int ret;
471     int info_id;
472     int sticker_count = 0;
473     GVariantIter *id_iter = NULL;
474
475     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || (type < 1) || !callback)
476         return STICKER_ERROR_INVALID_PARAMETER;
477
478     ret = sticker_dbus_get_sticker_info_by_display_type(consumer_handle->gdbus_connection, consumer_handle->app_id, type, offset, count, &id_iter);
479     if (ret != STICKER_ERROR_NONE) {
480         LOGE("Failed to get sticker information by display type : %d", ret);
481         ret = STICKER_ERROR_OPERATION_FAILED;
482         goto cleanup;
483     }
484
485     if (id_iter) {
486         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
487             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
488             if (!sticker_data) {
489                 ret = STICKER_ERROR_OUT_OF_MEMORY;
490                 goto cleanup;
491             }
492
493             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
494             if (ret == STICKER_ERROR_NONE) {
495                 sticker_count++;
496                 callback(sticker_data, user_data);
497                 _free_sticker_data(sticker_data);
498             } else {
499                 _free_sticker_data(sticker_data);
500                 goto cleanup;
501             }
502         }
503     }
504
505     *result = sticker_count;
506
507 cleanup:
508     if (id_iter)
509         g_variant_iter_free(id_iter);
510
511     return ret;
512 }
513
514 EXPORT_API int sticker_consumer_group_list_foreach_by_display_type(sticker_consumer_h consumer_handle, sticker_data_display_type_e type, sticker_consumer_group_list_foreach_cb callback, void *user_data)
515 {
516     CHECK_STICKER_FEATURE();
517
518     int ret;
519     GList *list = NULL;
520
521     if (!consumer_handle || (type < 1) || !callback)
522         return STICKER_ERROR_INVALID_PARAMETER;
523
524     ret = sticker_dbus_get_group_list_by_display_type(consumer_handle->gdbus_connection, consumer_handle->app_id, type, &list);
525     if (ret != STICKER_ERROR_NONE) {
526         LOGE("Failed to get group list : %d", ret);
527         ret = STICKER_ERROR_OPERATION_FAILED;
528         goto cleanup;
529     }
530
531     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
532         callback((const char *)tmp->data, user_data);
533     }
534
535 cleanup:
536     if (list)
537         g_list_free_full(list, free);
538
539     return ret;
540 }
541
542 EXPORT_API int sticker_consumer_add_recent_data(sticker_consumer_h consumer_handle, sticker_data_h data_handle)
543 {
544     CHECK_STICKER_FEATURE();
545
546     int ret;
547
548     if (!consumer_handle || !data_handle || (data_handle->sticker_info_id <= 0) || !data_handle->uri)
549         return STICKER_ERROR_INVALID_PARAMETER;
550
551     ret = sticker_dbus_insert_recent_sticker_info(consumer_handle->gdbus_connection, data_handle->sticker_info_id);
552     if (ret != STICKER_ERROR_NONE) {
553         LOGE("Failed to add recent sticker information : %d", ret);
554         return STICKER_ERROR_OPERATION_FAILED;
555     }
556
557     return STICKER_ERROR_NONE;
558 }
559
560 EXPORT_API int sticker_consumer_get_recent_data_list(sticker_consumer_h consumer_handle, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data)
561 {
562     CHECK_STICKER_FEATURE();
563
564     int ret;
565     int info_id;
566     int sticker_count = 0;
567     GVariantIter *id_iter = NULL;
568
569     if (!consumer_handle || (count <= 0) || !result || !callback)
570         return STICKER_ERROR_INVALID_PARAMETER;
571
572     ret = sticker_dbus_get_recent_sticker_list(consumer_handle->gdbus_connection, count, &id_iter);
573     if (ret != STICKER_ERROR_NONE) {
574         LOGE("Failed to get recent sticker information : %d", ret);
575         ret = STICKER_ERROR_OPERATION_FAILED;
576         goto cleanup;
577     }
578
579     if (id_iter) {
580         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
581             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
582             if (!sticker_data) {
583                 ret = STICKER_ERROR_OUT_OF_MEMORY;
584                 goto cleanup;
585             }
586
587             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
588             if (ret == STICKER_ERROR_NONE) {
589                 sticker_count++;
590                 callback(sticker_data, user_data);
591                 _free_sticker_data(sticker_data);
592             } else {
593                 _free_sticker_data(sticker_data);
594                 goto cleanup;
595             }
596         }
597     }
598
599     *result = sticker_count;
600
601 cleanup:
602     if (id_iter)
603         g_variant_iter_free(id_iter);
604
605     return ret;
606 }
607
608 EXPORT_API int sticker_consumer_set_event_cb(sticker_consumer_h consumer_handle, sticker_consumer_event_cb callback, void *user_data)
609 {
610     CHECK_STICKER_FEATURE();
611
612     if (!consumer_handle || !callback)
613         return STICKER_ERROR_INVALID_PARAMETER;
614
615     consumer_handle->event_cb = callback;
616     consumer_handle->event_cb_user_data = user_data;
617
618     return STICKER_ERROR_NONE;
619 }
620
621 EXPORT_API int sticker_consumer_unset_event_cb(sticker_consumer_h consumer_handle)
622 {
623     CHECK_STICKER_FEATURE();
624
625     if (!consumer_handle)
626         return STICKER_ERROR_INVALID_PARAMETER;
627
628     consumer_handle->event_cb = NULL;
629     consumer_handle->event_cb_user_data = NULL;
630
631     return STICKER_ERROR_NONE;
632 }