Initial commit
[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     int ret;
148
149     if (!consumer_handle)
150         return STICKER_ERROR_INVALID_PARAMETER;
151
152     if (_sticker_check_privilege() != STICKER_ERROR_NONE)
153         return STICKER_ERROR_PERMISSION_DENIED;
154
155     struct sticker_consumer_s *consumer_struct = (sticker_consumer_h)calloc(1, sizeof(struct sticker_consumer_s));
156
157     if (!consumer_struct)
158         return STICKER_ERROR_OUT_OF_MEMORY;
159
160     ret = sticker_dbus_init(&consumer_struct->gdbus_connection, &consumer_struct->server_watcher_id,
161         &consumer_struct->monitor_id, &consumer_struct->server_monitor_id, STICKER_CLIENT_LIB_CONSUMER, (void *)consumer_struct);
162     if (ret != STICKER_ERROR_NONE) {
163         LOGE("Failed to initialize dbus : %d", ret);
164         free(consumer_struct);
165         return STICKER_ERROR_OPERATION_FAILED;
166     }
167
168     *consumer_handle = consumer_struct;
169
170     return STICKER_ERROR_NONE;
171 }
172
173 EXPORT_API int sticker_consumer_destroy(sticker_consumer_h consumer_handle)
174 {
175     LOGD("consumer_handle : %p", consumer_handle);
176     int ret;
177
178     if (!consumer_handle)
179         return STICKER_ERROR_INVALID_PARAMETER;
180
181     ret = sticker_dbus_shutdown(consumer_handle->gdbus_connection, &consumer_handle->server_monitor_id, &consumer_handle->monitor_id);
182     if (ret != STICKER_ERROR_NONE) {
183         LOGE("Failed to finalize dbus : %d", ret);
184         free(consumer_handle);
185         return STICKER_ERROR_OPERATION_FAILED;
186     }
187
188     if (consumer_handle->gdbus_connection)
189         g_object_unref(consumer_handle->gdbus_connection);
190
191     free(consumer_handle);
192
193     return STICKER_ERROR_NONE;
194 }
195
196 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)
197 {
198     int ret;
199     int info_id;
200     int sticker_count = 0;
201     GVariantIter *id_iter = NULL;
202
203     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !callback)
204         return STICKER_ERROR_INVALID_PARAMETER;
205
206     ret = sticker_dbus_get_all_sticker_info(consumer_handle->gdbus_connection, offset, count, &id_iter);
207     if (ret != STICKER_ERROR_NONE) {
208         LOGE("Failed to get all sticker information : %d", ret);
209         ret = STICKER_ERROR_OPERATION_FAILED;
210         goto cleanup;
211     }
212
213     if (id_iter) {
214         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
215             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
216             if (!sticker_data) {
217                 ret = STICKER_ERROR_OUT_OF_MEMORY;
218                 goto cleanup;
219             }
220
221             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
222             if (ret == STICKER_ERROR_NONE) {
223                 sticker_count++;
224                 callback(sticker_data, user_data);
225                 _free_sticker_data(sticker_data);
226             } else {
227                 _free_sticker_data(sticker_data);
228                 goto cleanup;
229             }
230         }
231     }
232
233     *result = sticker_count;
234
235 cleanup:
236     if (id_iter)
237         g_variant_iter_free(id_iter);
238
239     return ret;
240 }
241
242 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)
243 {
244     int ret;
245     int info_id;
246     int sticker_count = 0;
247     GVariantIter *id_iter = NULL;
248
249     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !keyword || !callback)
250         return STICKER_ERROR_INVALID_PARAMETER;
251
252     ret = sticker_dbus_get_sticker_info_by_keyword(consumer_handle->gdbus_connection, keyword, offset, count, &id_iter);
253     if (ret != STICKER_ERROR_NONE) {
254         LOGE("Failed to get sticker information by keyword : %d", ret);
255         ret = STICKER_ERROR_OPERATION_FAILED;
256         goto cleanup;
257     }
258
259     if (id_iter) {
260         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
261             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
262             if (!sticker_data) {
263                 ret = STICKER_ERROR_OUT_OF_MEMORY;
264                 goto cleanup;
265             }
266
267             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
268             if (ret == STICKER_ERROR_NONE) {
269                 sticker_count++;
270                 callback(sticker_data, user_data);
271                 _free_sticker_data(sticker_data);
272             } else {
273                 _free_sticker_data(sticker_data);
274                 goto cleanup;
275             }
276         }
277     }
278
279     *result = sticker_count;
280
281 cleanup:
282     if (id_iter)
283         g_variant_iter_free(id_iter);
284
285     return ret;
286 }
287
288 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)
289 {
290         int ret;
291     int info_id;
292     int sticker_count = 0;
293     GVariantIter *id_iter = NULL;
294
295     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !group || !callback)
296         return STICKER_ERROR_INVALID_PARAMETER;
297
298     ret = sticker_dbus_get_sticker_info_by_group(consumer_handle->gdbus_connection, group, offset, count, &id_iter);
299     if (ret != STICKER_ERROR_NONE) {
300         LOGE("Failed to get sticker information by group : %d", ret);
301         ret = STICKER_ERROR_OPERATION_FAILED;
302         goto cleanup;
303     }
304
305     if (id_iter) {
306         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
307             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
308             if (!sticker_data) {
309                 ret = STICKER_ERROR_OUT_OF_MEMORY;
310                 goto cleanup;
311             }
312
313             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
314             if (ret == STICKER_ERROR_NONE) {
315                 sticker_count++;
316                 callback(sticker_data, user_data);
317                 _free_sticker_data(sticker_data);
318             } else {
319                 _free_sticker_data(sticker_data);
320                 goto cleanup;
321             }
322         }
323     }
324
325     *result = sticker_count;
326
327 cleanup:
328     if (id_iter)
329         g_variant_iter_free(id_iter);
330
331     return ret;
332 }
333
334 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)
335 {
336     int ret;
337     int info_id;
338     int sticker_count = 0;
339     GVariantIter *id_iter = NULL;
340
341     if (!consumer_handle || (offset < 0) || (count <= 0) || !result || (type < 1) || !callback)
342         return STICKER_ERROR_INVALID_PARAMETER;
343
344     ret = sticker_dbus_get_sticker_info_by_type(consumer_handle->gdbus_connection, type, offset, count, &id_iter);
345     if (ret != STICKER_ERROR_NONE) {
346         LOGE("Failed to get sticker information by group : %d", ret);
347         ret = STICKER_ERROR_OPERATION_FAILED;
348         goto cleanup;
349     }
350
351     if (id_iter) {
352         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
353             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
354             if (!sticker_data) {
355                 ret = STICKER_ERROR_OUT_OF_MEMORY;
356                 goto cleanup;
357             }
358
359             ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
360             if (ret == STICKER_ERROR_NONE) {
361                 sticker_count++;
362                 callback(sticker_data, user_data);
363                 _free_sticker_data(sticker_data);
364             } else {
365                 _free_sticker_data(sticker_data);
366                 goto cleanup;
367             }
368         }
369     }
370
371     *result = sticker_count;
372
373 cleanup:
374     if (id_iter)
375         g_variant_iter_free(id_iter);
376
377     return ret;
378 }
379
380 EXPORT_API int sticker_consumer_group_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_group_list_foreach_cb callback, void *user_data)
381 {
382     int ret;
383     GList *list = NULL;
384
385     if (!consumer_handle || !callback)
386         return STICKER_ERROR_INVALID_PARAMETER;
387
388     ret = sticker_dbus_get_group_list(consumer_handle->gdbus_connection, &list);
389     if (ret != STICKER_ERROR_NONE) {
390         LOGE("Failed to get group list : %d", ret);
391         ret = STICKER_ERROR_OPERATION_FAILED;
392         goto cleanup;
393     }
394
395     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
396         callback((const char *)tmp->data, user_data);
397     }
398
399 cleanup:
400     if (list)
401         g_list_free_full(list, free);
402
403     return ret;
404 }
405
406 EXPORT_API int sticker_consumer_keyword_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_keyword_list_foreach_cb callback, void *user_data)
407 {
408     int ret;
409     GList *list = NULL;
410
411     if (!consumer_handle || !callback)
412         return STICKER_ERROR_INVALID_PARAMETER;
413
414     ret = sticker_dbus_get_keyword_list(consumer_handle->gdbus_connection, &list);
415     if (ret != STICKER_ERROR_NONE) {
416         LOGE("Failed to get keyword list : %d", ret);
417         ret = STICKER_ERROR_OPERATION_FAILED;
418         goto cleanup;
419     }
420
421     for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
422         callback((const char *)tmp->data, user_data);
423     }
424
425 cleanup:
426     if (list)
427         g_list_free_full(list, free);
428
429     return ret;
430 }