Support on-demand launch
[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 <cynara-client.h>
21 #include <cynara-error.h>
22 #include <cynara-session.h>
23
24 #include "sticker_consumer.h"
25 #include "sticker_consumer_main.h"
26 #include "sticker_dbus.h"
27
28 #ifdef LOG_TAG
29 #undef LOG_TAG
30 #endif
31 #define LOG_TAG "STICKER_CONSUMER"
32
33 static cynara *p_cynara = NULL;
34
35 static void _free_sticker_data(sticker_data_h sticker_data)
36 {
37     if (sticker_data->app_id) {
38         free(sticker_data->app_id);
39         sticker_data->app_id = NULL;
40     }
41
42     if (sticker_data->uri) {
43         free(sticker_data->uri);
44         sticker_data->uri = NULL;
45     }
46
47     if (sticker_data->thumbnail) {
48         free(sticker_data->thumbnail);
49         sticker_data->thumbnail = NULL;
50     }
51
52     if (sticker_data->keyword) {
53         g_list_free_full(sticker_data->keyword, free);
54         sticker_data->keyword = NULL;
55     }
56
57     if (sticker_data->group) {
58         free(sticker_data->group);
59         sticker_data->group = NULL;
60     }
61
62     if (sticker_data->description) {
63         free(sticker_data->description);
64         sticker_data->description = NULL;
65     }
66
67     if (sticker_data->date) {
68         free(sticker_data->date);
69         sticker_data->date = NULL;
70     }
71
72     free(sticker_data);
73     sticker_data = NULL;
74 }
75
76 static int _cynara_initialize()
77 {
78     int ret = cynara_initialize(&p_cynara, NULL);
79     if (ret != CYNARA_API_SUCCESS)
80         LOGE("Failed to cynara initialize");
81
82     return ret;
83 }
84
85 static int _check_privilege(const char *uid, const char *privilege)
86 {
87     int ret;
88     FILE *fp = NULL;
89     char label_path[1024] = "/proc/self/attr/current";
90     char smack_label[1024] = {'\0',};
91
92     if (!p_cynara) {
93         return -1;
94     }
95
96     fp = fopen(label_path, "r");
97     if (fp != NULL) {
98         ret = fread(smack_label, 1, sizeof(smack_label), fp);
99         if (ret <= 0)
100             LOGE("Failed to fread");
101
102         fclose(fp);
103     }
104
105     pid_t pid = getpid();
106     char *session = cynara_session_from_pid(pid);
107     ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
108     if (session)
109         free(session);
110
111     if (ret != CYNARA_API_ACCESS_ALLOWED) {
112         LOGE("Access denied. The result of cynara_check() : %d.", ret);
113         return -1;
114     }
115
116     return 0;
117 }
118
119 static void _cynara_deinitialize()
120 {
121     if (p_cynara)
122         cynara_finish(p_cynara);
123
124     p_cynara = NULL;
125 }
126
127 static int _sticker_check_privilege() {
128     char uid[16];
129     int ret = STICKER_ERROR_NONE;
130
131     if (_cynara_initialize() != CYNARA_API_SUCCESS)
132         return STICKER_ERROR_PERMISSION_DENIED;
133
134     snprintf(uid, 16, "%d", getuid());
135     if (_check_privilege(uid, STICKER_PRIVILEGE_MEDIASTORAGE) < 0) {
136         LOGE("Permission is denied");
137         ret = STICKER_ERROR_PERMISSION_DENIED;
138     }
139
140     _cynara_deinitialize();
141
142     return ret;
143 }
144
145 EXPORT_API int sticker_consumer_create(sticker_consumer_h *consumer_handle)
146 {
147     CHECK_STICKER_FEATURE();
148
149     int ret;
150     if (!consumer_handle)
151         return STICKER_ERROR_INVALID_PARAMETER;
152
153     if (_sticker_check_privilege() != STICKER_ERROR_NONE)
154         return STICKER_ERROR_PERMISSION_DENIED;
155
156     struct sticker_consumer_s *consumer_struct = (sticker_consumer_h)calloc(1, sizeof(struct sticker_consumer_s));
157
158     if (!consumer_struct)
159         return STICKER_ERROR_OUT_OF_MEMORY;
160
161     ret = sticker_dbus_init(&consumer_struct->gdbus_connection, &consumer_struct->server_watcher_id,
162         &consumer_struct->monitor_id, &consumer_struct->server_monitor_id, STICKER_CLIENT_LIB_CONSUMER, (void *)consumer_struct);
163     if (ret != STICKER_ERROR_NONE) {
164         LOGE("Failed to initialize dbus : %d", ret);
165         free(consumer_struct);
166         return STICKER_ERROR_OPERATION_FAILED;
167     }
168
169     *consumer_handle = consumer_struct;
170
171     return STICKER_ERROR_NONE;
172 }
173
174 EXPORT_API int sticker_consumer_destroy(sticker_consumer_h consumer_handle)
175 {
176     CHECK_STICKER_FEATURE();
177
178     int ret;
179     if (!consumer_handle)
180         return STICKER_ERROR_INVALID_PARAMETER;
181
182     LOGD("consumer_handle : %p", consumer_handle);
183     ret = sticker_dbus_shutdown(consumer_handle->gdbus_connection, &consumer_handle->server_watcher_id,
184                                 &consumer_handle->server_monitor_id, &consumer_handle->monitor_id);
185     if (ret != STICKER_ERROR_NONE) {
186         LOGE("Failed to finalize dbus : %d", ret);
187         free(consumer_handle);
188         return STICKER_ERROR_OPERATION_FAILED;
189     }
190
191     if (consumer_handle->gdbus_connection)
192         g_object_unref(consumer_handle->gdbus_connection);
193
194     free(consumer_handle);
195
196     return STICKER_ERROR_NONE;
197 }
198
199 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)
200 {
201     CHECK_STICKER_FEATURE();
202
203     int ret;
204     int info_id;
205     int sticker_count = 0;
206     GVariantIter *id_iter = NULL;
207
208     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !callback)
209         return STICKER_ERROR_INVALID_PARAMETER;
210
211     ret = sticker_dbus_get_all_sticker_info(consumer_handle->gdbus_connection, offset, count, &id_iter);
212     if (ret != STICKER_ERROR_NONE) {
213         LOGE("Failed to get all sticker information : %d", ret);
214         ret = STICKER_ERROR_OPERATION_FAILED;
215         goto cleanup;
216     }
217
218     if (id_iter) {
219         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
220             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
221             if (!sticker_data) {
222                 ret = STICKER_ERROR_OUT_OF_MEMORY;
223                 goto cleanup;
224             }
225
226             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
227             if (ret == STICKER_ERROR_NONE) {
228                 sticker_count++;
229                 callback(sticker_data, user_data);
230                 _free_sticker_data(sticker_data);
231             } else {
232                 _free_sticker_data(sticker_data);
233                 goto cleanup;
234             }
235         }
236     }
237
238     *result = sticker_count;
239
240 cleanup:
241     if (id_iter)
242         g_variant_iter_free(id_iter);
243
244     return ret;
245 }
246
247 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)
248 {
249     CHECK_STICKER_FEATURE();
250
251     int ret;
252     int info_id;
253     int sticker_count = 0;
254     GVariantIter *id_iter = NULL;
255
256     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !keyword || !callback)
257         return STICKER_ERROR_INVALID_PARAMETER;
258
259     ret = sticker_dbus_get_sticker_info_by_keyword(consumer_handle->gdbus_connection, keyword, offset, count, &id_iter);
260     if (ret != STICKER_ERROR_NONE) {
261         LOGE("Failed to get sticker information by keyword : %d", ret);
262         ret = STICKER_ERROR_OPERATION_FAILED;
263         goto cleanup;
264     }
265
266     if (id_iter) {
267         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
268             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
269             if (!sticker_data) {
270                 ret = STICKER_ERROR_OUT_OF_MEMORY;
271                 goto cleanup;
272             }
273
274             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
275             if (ret == STICKER_ERROR_NONE) {
276                 sticker_count++;
277                 callback(sticker_data, user_data);
278                 _free_sticker_data(sticker_data);
279             } else {
280                 _free_sticker_data(sticker_data);
281                 goto cleanup;
282             }
283         }
284     }
285
286     *result = sticker_count;
287
288 cleanup:
289     if (id_iter)
290         g_variant_iter_free(id_iter);
291
292     return ret;
293 }
294
295 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)
296 {
297     CHECK_STICKER_FEATURE();
298
299         int ret;
300     int info_id;
301     int sticker_count = 0;
302     GVariantIter *id_iter = NULL;
303
304     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !group || !callback)
305         return STICKER_ERROR_INVALID_PARAMETER;
306
307     ret = sticker_dbus_get_sticker_info_by_group(consumer_handle->gdbus_connection, group, offset, count, &id_iter);
308     if (ret != STICKER_ERROR_NONE) {
309         LOGE("Failed to get sticker information by group : %d", ret);
310         ret = STICKER_ERROR_OPERATION_FAILED;
311         goto cleanup;
312     }
313
314     if (id_iter) {
315         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
316             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
317             if (!sticker_data) {
318                 ret = STICKER_ERROR_OUT_OF_MEMORY;
319                 goto cleanup;
320             }
321
322             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
323             if (ret == STICKER_ERROR_NONE) {
324                 sticker_count++;
325                 callback(sticker_data, user_data);
326                 _free_sticker_data(sticker_data);
327             } else {
328                 _free_sticker_data(sticker_data);
329                 goto cleanup;
330             }
331         }
332     }
333
334     *result = sticker_count;
335
336 cleanup:
337     if (id_iter)
338         g_variant_iter_free(id_iter);
339
340     return ret;
341 }
342
343 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)
344 {
345     CHECK_STICKER_FEATURE();
346
347     int ret;
348     int info_id;
349     int sticker_count = 0;
350     GVariantIter *id_iter = NULL;
351
352     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || (type < 1) || !callback)
353         return STICKER_ERROR_INVALID_PARAMETER;
354
355     ret = sticker_dbus_get_sticker_info_by_type(consumer_handle->gdbus_connection, type, offset, count, &id_iter);
356     if (ret != STICKER_ERROR_NONE) {
357         LOGE("Failed to get sticker information by group : %d", ret);
358         ret = STICKER_ERROR_OPERATION_FAILED;
359         goto cleanup;
360     }
361
362     if (id_iter) {
363         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
364             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
365             if (!sticker_data) {
366                 ret = STICKER_ERROR_OUT_OF_MEMORY;
367                 goto cleanup;
368             }
369
370             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
371             if (ret == STICKER_ERROR_NONE) {
372                 sticker_count++;
373                 callback(sticker_data, user_data);
374                 _free_sticker_data(sticker_data);
375             } else {
376                 _free_sticker_data(sticker_data);
377                 goto cleanup;
378             }
379         }
380     }
381
382     *result = sticker_count;
383
384 cleanup:
385     if (id_iter)
386         g_variant_iter_free(id_iter);
387
388     return ret;
389 }
390
391 EXPORT_API int sticker_consumer_group_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_group_list_foreach_cb callback, void *user_data)
392 {
393     CHECK_STICKER_FEATURE();
394
395     int ret;
396     GList *list = NULL;
397
398     if (!consumer_handle || !callback)
399         return STICKER_ERROR_INVALID_PARAMETER;
400
401     ret = sticker_dbus_get_group_list(consumer_handle->gdbus_connection, &list);
402     if (ret != STICKER_ERROR_NONE) {
403         LOGE("Failed to get group list : %d", ret);
404         ret = STICKER_ERROR_OPERATION_FAILED;
405         goto cleanup;
406     }
407
408     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
409         callback((const char *)tmp->data, user_data);
410     }
411
412 cleanup:
413     if (list)
414         g_list_free_full(list, free);
415
416     return ret;
417 }
418
419 EXPORT_API int sticker_consumer_keyword_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_keyword_list_foreach_cb callback, void *user_data)
420 {
421     CHECK_STICKER_FEATURE();
422
423     int ret;
424     GList *list = NULL;
425
426     if (!consumer_handle || !callback)
427         return STICKER_ERROR_INVALID_PARAMETER;
428
429     ret = sticker_dbus_get_keyword_list(consumer_handle->gdbus_connection, &list);
430     if (ret != STICKER_ERROR_NONE) {
431         LOGE("Failed to get keyword list : %d", ret);
432         ret = STICKER_ERROR_OPERATION_FAILED;
433         goto cleanup;
434     }
435
436     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
437         callback((const char *)tmp->data, user_data);
438     }
439
440 cleanup:
441     if (list)
442         g_list_free_full(list, free);
443
444     return ret;
445 }