Modified to prevent frequent restart of Sticker daemon
[platform/core/uifw/capi-ui-sticker.git] / server / stickerd_data_manager.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 <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <tzplatform_config.h>
21 #include <gio/gunixfdlist.h>
22 #include <dlog.h>
23 #include <json-glib/json-glib.h>
24 #include <package_manager.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <dirent.h>
29 #include <fcntl.h>
30 #include <glib.h>
31
32 #include "stickerd_dbus.h"
33 #include "stickerd_data_manager.h"
34 #include "stickerd_db_manager.h"
35 #include "sticker_defs.h"
36 #include "stickerd_error.h"
37
38 #ifdef LOG_TAG
39 #undef LOG_TAG
40 #endif
41 #define LOG_TAG "STICKERD_DATA_MANAGER"
42
43 #define MAX_ERROR_BUFFER  256
44 #define TERMINATE_TIMER_INTERVAL 3000
45
46 enum {
47     STICKER_URI_TYPE_NONE,
48     STICKER_URI_TYPE_LOCAL_PATH,
49     STICKER_URI_TYPE_WEB_RESOURCE,
50 };
51
52 static GHashTable *_monitoring_hash = NULL;
53 static char error_buffer[MAX_ERROR_BUFFER];
54 static GList *consumer_list = NULL;
55 static guint _terminate_timer_id = 0;
56 extern GMainLoop *main_loop;
57
58 static void _terminate_daemon()
59 {
60     LOGD("Terminate sticker daemon");
61     g_hash_table_destroy(_monitoring_hash);
62     _monitoring_hash = NULL;
63     g_list_free_full(consumer_list, free);
64     consumer_list = NULL;
65     g_main_loop_quit(main_loop);
66 }
67
68 static gboolean _terminate_timer_handler(gpointer user_data)
69 {
70     _terminate_daemon();
71     return TRUE;
72 }
73
74 static void _check_watcher_exist()
75 {
76     if (_monitoring_hash != NULL && g_hash_table_size(_monitoring_hash) == 0) {
77         if (_terminate_timer_id != 0) {
78             g_source_remove(_terminate_timer_id);
79             _terminate_timer_id = 0;
80         }
81
82         _terminate_timer_id = g_timeout_add(TERMINATE_TIMER_INTERVAL, _terminate_timer_handler, NULL);
83         if (_terminate_timer_id <= 0)
84             _terminate_daemon();
85     }
86 }
87
88 static void _on_name_appeared(GDBusConnection *connection,
89         const gchar     *name,
90         const gchar     *name_owner,
91         gpointer         user_data)
92 {
93     LOGD("name: %s", name);
94     if (_terminate_timer_id != 0) {
95         g_source_remove(_terminate_timer_id);
96         _terminate_timer_id = 0;
97     }
98 }
99
100 static void _on_name_vanished(GDBusConnection *connection,
101         const gchar     *name,
102         gpointer         user_data)
103 {
104     monitoring_info_s *info = (monitoring_info_s *)user_data;
105
106     if (info) {
107         if (_monitoring_hash != NULL && g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(info->watcher_id)) != NULL) {
108             LOGD("name: %s", name);
109             g_bus_unwatch_name(info->watcher_id);
110             delete_monitoring_list(&_monitoring_hash, info->bus_name, info->watcher_id);
111         }
112
113         if (g_list_find(consumer_list, info->bus_name))
114             consumer_list = g_list_remove(consumer_list, info->bus_name);
115
116         if (info->bus_name)
117             free(info->bus_name);
118         free(info);
119         info = NULL;
120     }
121
122     _check_watcher_exist();
123 }
124
125 static void _stickerd_client_dbus_method_call_handler(GDBusConnection *conn, const gchar *sender, const gchar *object_path,
126         const gchar *iface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation,
127         gpointer user_data)
128 {
129     LOGD("stickerd method_name: %s, sender: %s", method_name, sender);
130
131     if (_monitoring_hash == NULL)
132         _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
133
134     if (consumer_list == NULL)
135         consumer_list = g_list_alloc();
136
137     GVariant *reply_body = NULL;
138     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
139
140     if (g_strcmp0(method_name, "sticker_service_register") == 0) {
141         ret = stickerd_server_register(parameters, &reply_body, sender,
142             _on_name_appeared, _on_name_vanished, &_monitoring_hash, &consumer_list);
143     } else if (g_strcmp0(method_name, "sticker_service_unregister") == 0) {
144         ret = stickerd_server_unregister(parameters, &reply_body, sender, &_monitoring_hash, &consumer_list);
145     } else if (g_strcmp0(method_name, "insert_sticker_info") == 0) {
146         ret = stickerd_insert_sticker_info(parameters, &reply_body);
147     } else if  (g_strcmp0(method_name, "update_sticker_info_by_json") == 0) {
148         ret = stickerd_insert_sticker_info_by_json(parameters, &reply_body, sender);
149     } else if (g_strcmp0(method_name, "delete_sticker_info") == 0) {
150         ret = stickerd_del_sticker_info(parameters, &reply_body);
151     } else if (g_strcmp0(method_name, "delete_sticker_info_by_uri") == 0) {
152         ret = stickerd_del_sticker_info_by_uri(parameters, &reply_body);
153     } else if (g_strcmp0(method_name, "update_sticker_type") == 0) {
154         ret = stickerd_update_sticker_type(parameters, &reply_body);
155     } else if (g_strcmp0(method_name, "update_sticker_uri") == 0) {
156         ret = stickerd_update_sticker_uri(parameters, &reply_body);
157     } else if (g_strcmp0(method_name, "update_sticker_thumbnail") == 0) {
158         ret = stickerd_update_sticker_thumbnail(parameters, &reply_body);
159     } else if (g_strcmp0(method_name, "update_sticker_description") == 0) {
160         ret = stickerd_update_sticker_description(parameters, &reply_body);
161     } else if (g_strcmp0(method_name, "update_sticker_group") == 0) {
162         ret = stickerd_update_sticker_group(parameters, &reply_body);
163     } else if (g_strcmp0(method_name, "update_sticker_keyword") == 0) {
164         ret = stickerd_update_sticker_keyword(parameters, &reply_body);
165     } else if (g_strcmp0(method_name, "get_sticker_info") == 0) {
166         ret = stickerd_get_sticker_info(parameters, &reply_body);
167     } else if (g_strcmp0(method_name, "get_group_list") == 0) {
168         ret = stickerd_get_group_list(parameters, &reply_body);
169     } else if (g_strcmp0(method_name, "get_keyword_list") == 0) {
170         ret = stickerd_get_keyword_list(parameters, &reply_body);
171     } else if (g_strcmp0(method_name, "get_sticker_count") == 0) {
172         ret = stickerd_get_sticker_count(parameters, &reply_body);
173     } else if (g_strcmp0(method_name, "get_all_sticker_info") == 0) {
174         ret = stickerd_get_all_sticker_info(parameters, &reply_body);
175     } else if (g_strcmp0(method_name, "get_sticker_info_by_appid") == 0) {
176         ret = stickerd_get_sticker_info_by_app_id(parameters, &reply_body);
177     } else if (g_strcmp0(method_name, "get_sticker_info_by_type") == 0) {
178         ret = stickerd_get_sticker_info_by_type(parameters, &reply_body);
179     } else if (g_strcmp0(method_name, "get_sticker_info_by_group") == 0) {
180         ret = stickerd_get_sticker_info_by_group(parameters, &reply_body);
181     } else if (g_strcmp0(method_name, "get_sticker_info_by_keyword") == 0) {
182         ret = stickerd_get_sticker_info_by_keyword(parameters, &reply_body);
183     } else if (g_strcmp0(method_name, "get_sticker_info_by_disp_type") == 0) {
184         ret = stickerd_get_sticker_info_by_display_type(parameters, &reply_body);
185     } else if (g_strcmp0(method_name, "get_group_list_by_disp_type") == 0) {
186         ret = stickerd_get_group_list_by_disp_type(parameters, &reply_body);
187     } else if (g_strcmp0(method_name, "update_sticker_disp_type") == 0) {
188         ret = stickerd_update_sticker_disp_type(parameters, &reply_body);
189     } else if (g_strcmp0(method_name, "check_file_exists") == 0) {
190         ret = stickerd_check_file_exists(parameters, &reply_body);
191     } else if (g_strcmp0(method_name, "insert_recent_sticker_info") == 0) {
192         ret = stickerd_insert_recent_sticker_info(parameters, &reply_body);
193     } else if (g_strcmp0(method_name, "get_recent_sticker_info") == 0) {
194         ret = stickerd_get_recent_sticker_info(parameters, &reply_body);
195     } else if (g_strcmp0(method_name, "send_update_event") == 0) {
196         ret = stickerd_send_update_event(parameters, &reply_body);
197     } else if (g_strcmp0(method_name, "get_sticker_info_by_uri") == 0) {
198         ret = stickerd_get_sticker_info_by_uri(parameters, &reply_body);
199     } else if (g_strcmp0(method_name, "check_group_exists") == 0) {
200         ret = stickerd_check_group_exists(parameters, &reply_body);
201     } else if (g_strcmp0(method_name, "set_group_image") == 0) {
202         ret = stickerd_set_group_image(parameters, &reply_body);
203     } else if (g_strcmp0(method_name, "get_group_image_list") == 0) {
204         ret = stickerd_get_group_image_list(parameters, &reply_body);
205     }
206
207     if (ret == STICKERD_SERVER_ERROR_NONE) {
208         LOGD("method_call successful, method_name : %s", method_name);
209         g_dbus_method_invocation_return_value(invocation, reply_body);
210     } else {
211         LOGE("method_call failed, method_name : %s", method_name);
212         g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "sticker error");
213     }
214
215     _check_watcher_exist();
216 }
217
218 static const GDBusInterfaceVTable _sticker_interface_vtable = {
219         _stickerd_client_dbus_method_call_handler,
220         NULL,
221         NULL
222 };
223
224 int stickerd_register_dbus_interface(void)
225 {
226     static gchar introspection_xml[] =
227             "  <node>"
228             "  <interface name='org.tizen.sticker_service'>"
229             "        <method name='sticker_service_register'>"
230             "          <arg type='i' name='lib_type' direction='in'/>"
231             "          <arg type='i' name='watcher_id' direction='out'/>"
232             "        </method>"
233
234             "        <method name='sticker_service_unregister'>"
235             "          <arg type='i' name='lib_type' direction='in'/>"
236             "          <arg type='i' name='watcher_id' direction='in'/>"
237             "        </method>"
238
239             "        <method name='insert_sticker_info'>"
240             "          <arg type='a{iv}' name='sticker_info' direction='in'/>"
241             "          <arg type='a(s)' name='keyword_list' direction='in'/>"
242             "          <arg type='i' name='record_id' direction='out'/>"
243             "        </method>"
244
245             "        <method name='update_sticker_info_by_json'>"
246             "          <arg type='s' name='app_id' direction='in'/>"
247             "          <arg type='s' name='json_path' direction='in'/>"
248             "        </method>"
249
250             "        <method name='delete_sticker_info'>"
251             "          <arg type='i' name='record_id' direction='in'/>"
252             "        </method>"
253
254             "        <method name='delete_sticker_info_by_uri'>"
255             "          <arg type='s' name='uri' direction='in'/>"
256             "        </method>"
257
258             "        <method name='update_sticker_type'>"
259             "          <arg type='i' name='record_id' direction='in'/>"
260             "          <arg type='i' name='type' direction='in'/>"
261             "        </method>"
262
263             "        <method name='update_sticker_uri'>"
264             "          <arg type='i' name='record_id' direction='in'/>"
265             "          <arg type='s' name='app_id' direction='in'/>"
266             "          <arg type='i' name='type' direction='in'/>"
267             "          <arg type='s' name='uri' direction='in'/>"
268             "        </method>"
269
270             "        <method name='update_sticker_thumbnail'>"
271             "          <arg type='i' name='record_id' direction='in'/>"
272             "          <arg type='s' name='app_id' direction='in'/>"
273             "          <arg type='s' name='thumbnail' direction='in'/>"
274             "        </method>"
275
276             "        <method name='update_sticker_description'>"
277             "          <arg type='i' name='record_id' direction='in'/>"
278             "          <arg type='s' name='description' direction='in'/>"
279             "        </method>"
280
281             "        <method name='update_sticker_group'>"
282             "          <arg type='i' name='record_id' direction='in'/>"
283             "          <arg type='s' name='group' direction='in'/>"
284             "        </method>"
285
286             "        <method name='update_sticker_keyword'>"
287             "          <arg type='i' name='record_id' direction='in'/>"
288             "          <arg type='a(s)' name='keyword' direction='in'/>"
289             "        </method>"
290
291             "        <method name='get_sticker_info'>"
292             "          <arg type='i' name='record_id' direction='in'/>"
293             "          <arg type='a{iv}' name='sticker_info' direction='out'/>"
294             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
295             "        </method>"
296
297             "        <method name='get_group_list'>"
298             "          <arg type='s' name='app_id' direction='in'/>"
299             "          <arg type='a(s)' name='group_list' direction='out'/>"
300             "        </method>"
301
302             "        <method name='get_keyword_list'>"
303             "          <arg type='s' name='app_id' direction='in'/>"
304             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
305             "        </method>"
306
307             "        <method name='get_sticker_count'>"
308             "          <arg type='s' name='app_id' direction='in'/>"
309             "          <arg type='i' name='count' direction='out'/>"
310             "        </method>"
311
312             "        <method name='get_all_sticker_info'>"
313             "          <arg type='s' name='app_id' direction='in'/>"
314             "          <arg type='i' name='offset' direction='in'/>"
315             "          <arg type='i' name='count' direction='in'/>"
316             "          <arg type='a(i)' name='id_list' direction='out'/>"
317             "        </method>"
318
319             "        <method name='get_sticker_info_by_appid'>"
320             "          <arg type='s' name='app_id' direction='in'/>"
321             "          <arg type='i' name='offset' direction='in'/>"
322             "          <arg type='i' name='count' direction='in'/>"
323             "          <arg type='a(i)' name='id_list' direction='out'/>"
324             "        </method>"
325
326             "        <method name='get_sticker_info_by_type'>"
327             "          <arg type='s' name='app_id' direction='in'/>"
328             "          <arg type='i' name='type' direction='in'/>"
329             "          <arg type='i' name='offset' direction='in'/>"
330             "          <arg type='i' name='count' direction='in'/>"
331             "          <arg type='a(i)' name='id_list' direction='out'/>"
332             "        </method>"
333
334             "        <method name='get_sticker_info_by_group'>"
335             "          <arg type='s' name='app_id' direction='in'/>"
336             "          <arg type='s' name='group' direction='in'/>"
337             "          <arg type='i' name='offset' direction='in'/>"
338             "          <arg type='i' name='count' direction='in'/>"
339             "          <arg type='a(i)' name='id_list' direction='out'/>"
340             "        </method>"
341
342             "        <method name='get_sticker_info_by_keyword'>"
343             "          <arg type='s' name='app_id' direction='in'/>"
344             "          <arg type='s' name='keyword' direction='in'/>"
345             "          <arg type='i' name='offset' direction='in'/>"
346             "          <arg type='i' name='count' direction='in'/>"
347             "          <arg type='a(i)' name='id_list' direction='out'/>"
348             "        </method>"
349
350             "        <method name='get_sticker_info_by_disp_type'>"
351             "          <arg type='s' name='app_id' direction='in'/>"
352             "          <arg type='i' name='type' direction='in'/>"
353             "          <arg type='i' name='offset' direction='in'/>"
354             "          <arg type='i' name='count' direction='in'/>"
355             "          <arg type='a(i)' name='id_list' direction='out'/>"
356             "        </method>"
357
358             "        <method name='get_group_list_by_disp_type'>"
359             "          <arg type='s' name='app_id' direction='in'/>"
360             "          <arg type='i' name='disp_type' direction='in'/>"
361             "          <arg type='a(s)' name='group_list' direction='out'/>"
362             "        </method>"
363
364             "        <method name='update_sticker_disp_type'>"
365             "          <arg type='i' name='record_id' direction='in'/>"
366             "          <arg type='i' name='disp_type' direction='in'/>"
367             "        </method>"
368
369             "        <method name='check_file_exists'>"
370             "          <arg type='s' name='uri' direction='in'/>"
371             "          <arg type='i' name='result' direction='out'/>"
372             "        </method>"
373
374             "        <method name='insert_recent_sticker_info'>"
375             "          <arg type='i' name='record_id' direction='in'/>"
376             "        </method>"
377
378             "        <method name='get_recent_sticker_info'>"
379             "          <arg type='i' name='count' direction='in'/>"
380             "          <arg type='a(i)' name='id_list' direction='out'/>"
381             "        </method>"
382
383             "        <method name='send_update_event'>"
384             "          <arg type='i' name='record_id' direction='in'/>"
385             "        </method>"
386
387             "        <method name='get_sticker_info_by_uri'>"
388             "          <arg type='s' name='uri' direction='in'/>"
389             "          <arg type='a{iv}' name='sticker_info' direction='out'/>"
390             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
391             "        </method>"
392
393             "        <method name='check_group_exists'>"
394             "          <arg type='s' name='app_id' direction='in'/>"
395             "          <arg type='s' name='group' direction='in'/>"
396             "          <arg type='i' name='result' direction='out'/>"
397             "        </method>"
398
399             "        <method name='set_group_image'>"
400             "          <arg type='s' name='app_id' direction='in'/>"
401             "          <arg type='s' name='group' direction='in'/>"
402             "          <arg type='i' name='type' direction='in'/>"
403             "          <arg type='s' name='uri' direction='in'/>"
404             "        </method>"
405
406             "        <method name='get_group_image_list'>"
407             "          <arg type='s' name='app_id' direction='in'/>"
408             "          <arg type='a(sis)' name='group_image_list' direction='out'/>"
409             "        </method>"
410             "  </interface>"
411             "  </node>";
412
413     return stickerd_server_register_dbus_interface(introspection_xml, _sticker_interface_vtable);
414 }
415
416 int stickerd_dbus_init(void)
417 {
418     int ret;
419
420     ret = stickerd_register_dbus_interface();
421     if (ret != STICKERD_SERVER_ERROR_NONE) {
422         LOGE("Failed to register dbus interface : %d", ret);
423         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
424     }
425
426     return STICKERD_SERVER_ERROR_NONE;
427 }
428
429 static int _check_file_exist(const char *app_id, const char *path)
430 {
431     int ret = 0;
432     int path_len = 0;
433     package_info_h package_info = NULL;
434     char *app_path = NULL;
435     char *file_path = NULL;
436
437     if (access(path, F_OK) == 0) {
438         ret = 0;
439         goto cleanup;
440     }
441
442     ret = package_info_create(app_id, &package_info);
443     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
444         LOGE("failed to create package_info. ret: %d", ret);
445         ret = -1;
446         goto cleanup;
447     }
448
449     ret = package_info_get_root_path(package_info, &app_path);
450     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
451         LOGE("failed to create package_info. ret: %d", ret);
452         ret = -1;
453         goto cleanup;
454     }
455
456     path_len = strlen(app_path) + strlen(path) + 2;
457     file_path = (char *)calloc(path_len, sizeof(char));
458     if (!file_path) {
459         LOGE("Failed to alloc memory");
460         ret = -1;
461         goto cleanup;
462     }
463
464     if (path[0] == '/')
465         snprintf(file_path, path_len, "%s%s",app_path, path);
466     else
467         snprintf(file_path, path_len, "%s%s%s",app_path, "/", path);
468
469     if (access(file_path, F_OK) != 0) {
470         LOGE("%s does not exist", file_path);
471         ret = -1;
472     } else
473         ret = 0;
474
475 cleanup:
476     if (package_info)
477         package_info_destroy(package_info);
478
479     if (app_path) {
480         free(app_path);
481         app_path = NULL;
482     }
483
484     if (file_path) {
485         free(file_path);
486         file_path = NULL;
487     }
488
489     return ret;
490 }
491
492 static int _mkdirs(const char *path, mode_t mode)
493 {
494     int len = 0;
495     char prev_path[2048];
496     const char *tmp = path;
497
498     if (!path || strlen(path) > 2048)
499         return -1;
500
501     memset(prev_path, '\0', 2048);
502     while ((tmp = strchr(tmp, '/')) != NULL) {
503         len = tmp - path;
504         tmp++;
505
506         if (len == 0)
507             continue;
508
509         strncpy(prev_path, path, len);
510         prev_path[len] = 0x00;
511
512         if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
513             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
514             LOGE("directory create error : %s", error_buffer);
515             return -1;
516         }
517     }
518
519     if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
520         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
521         LOGE("directory create error : %s", error_buffer);
522         return -1;
523     }
524
525     return 0;
526 }
527
528 static int _file_copy(const char *src, const char *dest)
529 {
530     int ret = 0;
531     int fd = -1, n_fd = -1;
532     char buf[4096];
533     int tmp_err = 0;
534     int size;
535
536     memset(buf, '\0', 4096);
537     fd = open(src, O_RDONLY);
538     if (fd == -1) {
539         LOGE("Failed to open file (%s) for reading", src);
540     }
541
542     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
543     if (n_fd == -1) {
544         LOGE("Failed to open file (%s) for writing", dest);
545     }
546
547     if (fd == -1 || n_fd == -1) {
548         tmp_err = errno;
549         ret = -1;
550         goto cleanup;
551     }
552
553     while ((size = read(fd, buf, 4096))) {
554         if (size == -1) {
555             if (errno == EINTR)
556                 continue;
557
558             tmp_err = errno;
559             ret = -1;
560             goto cleanup;
561         }
562
563         while (write(n_fd, buf, size) == -1) {
564             if (errno == EINTR) {
565                 continue;
566             } else {
567                 tmp_err = errno;
568                 goto cleanup;
569             }
570         }
571     }
572
573 cleanup:
574     if (fd != -1)
575         close(fd);
576
577     if (n_fd != -1)
578         close(n_fd);
579
580     errno = tmp_err;
581     return ret;
582 }
583
584 static char* _convert_sticker_uri(const char *uri, const char *appid)
585 {
586     int ret;
587     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
588     char * new_path = (char *)calloc(len, sizeof(char));
589     if (new_path == NULL) {
590         LOGE("Failed to alloc memory");
591         return NULL;
592     }
593
594     if (uri[0] == '/')
595         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
596     else
597         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
598
599     if (access(new_path, F_OK) == 0) {
600         LOGE("sticker file already exists : %s", new_path);
601         ret = -1;
602         goto cleanup;
603     }
604
605     ret = _mkdirs(new_path, 0755);
606     if (ret != 0) {
607         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
608         LOGE("directory create error : %s", error_buffer);
609         goto cleanup;
610     }
611
612     ret = _file_copy(uri, new_path);
613     if (ret != 0) {
614         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
615         LOGE("failed to copy sticker file : %s", error_buffer);
616     }
617
618 cleanup:
619     if (ret == 0) {
620         return new_path;
621     } else {
622         free(new_path);
623         new_path = NULL;
624         return NULL;
625     }
626 }
627
628 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
629 {
630     if (!keyword) {
631         LOGE("keyword doesn't exist");
632         return;
633     }
634
635     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
636 }
637
638 static GVariant* _get_sticker_g_variant(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
639 {
640     GVariantBuilder *info_builder;
641     GVariantBuilder *keyword_builder;
642
643     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
644     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
645     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
646     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
647     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
648     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
649     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
650     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
651     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
652
653     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
654     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
655
656     GVariant *body = g_variant_new("(ia{iv}a(s))", (int)type, info_builder, keyword_builder);
657     g_variant_builder_unref(info_builder);
658     g_variant_builder_unref(keyword_builder);
659
660     if (body)
661         return body;
662     else
663         return NULL;
664 }
665
666 void _get_consumer_busname(gpointer data, gpointer user_data)
667 {
668     if (data == NULL)
669         return;
670
671     int ret;
672     char *cmd = "send_sticker_changed_event";
673     char *sender = (char *)data;
674     GVariant *body = (GVariant *)user_data;
675
676     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_CONSUMER);
677     if (ret != STICKERD_SERVER_ERROR_NONE)
678         LOGE("Failed to send sticker changed event");
679 }
680
681 static void _send_sticker_changed_event(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
682 {
683     GVariant *body = _get_sticker_g_variant(type, sticker_info);
684
685     if (body)
686         g_list_foreach(consumer_list, _get_consumer_busname, body);
687
688     if (body)
689         g_variant_unref(body);
690 }
691
692 static void _free_sticker_data(sticker_info_db *sticker_data)
693 {
694     if (!sticker_data)
695         return;
696
697     if (sticker_data->app_id) {
698         free(sticker_data->app_id);
699         sticker_data->app_id = NULL;
700     }
701
702     if (sticker_data->uri) {
703         free(sticker_data->uri);
704         sticker_data->uri = NULL;
705     }
706
707     if (sticker_data->thumbnail) {
708         free(sticker_data->thumbnail);
709         sticker_data->thumbnail = NULL;
710     }
711
712     if (sticker_data->keyword) {
713         g_list_free_full(sticker_data->keyword, free);
714         sticker_data->keyword = NULL;
715     }
716
717     if (sticker_data->group) {
718         free(sticker_data->group);
719         sticker_data->group = NULL;
720     }
721
722     if (sticker_data->description) {
723         free(sticker_data->description);
724         sticker_data->description = NULL;
725     }
726
727     if (sticker_data->date) {
728         free(sticker_data->date);
729         sticker_data->date = NULL;
730     }
731
732     free(sticker_data);
733 }
734
735 int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
736 {
737     int ret;
738     int record_id = 0;
739     STICKER_DAT_TYPE key;
740     sticker_info_db *sticker_info = NULL;
741     GVariant *value = NULL;
742     GVariantIter *info_iter = NULL;
743     GVariantIter *keyword_iter = NULL;
744     char *keyword;
745
746     g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
747     if (!info_iter || !keyword_iter) {
748         LOGD("failed to get iter");
749         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
750         goto cleanup;
751     }
752
753     sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
754
755     if (!sticker_info) {
756         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
757         goto cleanup;
758     }
759
760     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
761         switch(key) {
762             case STICKER_DATA_TYPE_APP_ID:
763             sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
764             break;
765             case STICKER_DATA_TYPE_URI_TYPE:
766             sticker_info->type = g_variant_get_int32(value);
767             break;
768             case STICKER_DATA_TYPE_URI:
769             sticker_info->uri = (char *) g_variant_get_string(value, NULL);
770             break;
771             case STICKER_DATA_TYPE_THUMBNAIL:
772             sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
773             break;
774             case STICKER_DATA_TYPE_DESCRIPTION:
775             sticker_info->description = (char *) g_variant_get_string(value, NULL);
776             break;
777             case STICKER_DATA_TYPE_GROUP:
778             sticker_info->group = (char *) g_variant_get_string(value, NULL);
779             break;
780             case STICKER_DATA_TYPE_DISP_TYPE:
781             sticker_info->display_type = g_variant_get_int32(value);
782             default:
783             break;
784         }
785     }
786
787     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
788         sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
789     }
790
791     if (sticker_info->type == STICKER_URI_TYPE_LOCAL_PATH) {
792         if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
793             sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
794             if (!sticker_info->uri) {
795                 LOGE("failed to copy sticker file");
796                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
797                 goto cleanup;
798             }
799         } else {
800             LOGE("sticker file does not exist");
801             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
802             goto cleanup;
803         }
804     }
805
806     if (sticker_info->thumbnail) {
807         if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
808             sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
809             if (!sticker_info->thumbnail) {
810                 LOGE("failed to copy sticker thumbnail");
811                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
812                 goto cleanup;
813             }
814         } else {
815             LOGE("sticker thumbnail does not exist");
816             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
817             goto cleanup;
818         }
819     }
820
821     ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
822     if (ret != STICKERD_SERVER_ERROR_NONE) {
823         LOGE("Failed to insert sticker info");
824         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
825         goto cleanup;
826     }
827
828     *reply_body = g_variant_new("(i)", record_id);
829     if (*reply_body == NULL) {
830         LOGE("Failed to create reply_body");
831         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
832     } else
833         _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
834
835 cleanup:
836     if (value)
837         g_variant_unref(value);
838
839     if (info_iter)
840         g_variant_iter_free(info_iter);
841
842     if (keyword_iter)
843         g_variant_iter_free(keyword_iter);
844
845     if (sticker_info) {
846         free(sticker_info);
847         sticker_info = NULL;
848     }
849
850     return ret;
851 }
852
853 static char* _get_string_from_object(JsonObject *object, const char *key)
854 {
855     if (json_object_has_member(object, key) == false)
856         return NULL;
857
858     const char *str = json_object_get_string_member(object, key);
859     if (str != NULL)
860         return strdup(str);
861     else
862         return NULL;
863 }
864
865 static int _get_int_from_object(JsonObject *object, const char *key)
866 {
867     if (json_object_has_member(object, key) == false)
868         return -1;
869
870     int type = json_object_get_int_member(object, key);
871
872     return type;
873 }
874
875 int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
876 {
877     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
878     int record_id;
879     sticker_info_db *sticker_info = NULL;
880     char *app_id = NULL;
881     char *json_path = NULL;
882     JsonParser* parser = NULL;
883     GError* err_msg = NULL;
884     GVariant *body = NULL;
885     char *cmd = "send_insert_result";
886     JsonArray *sticker_arr = NULL;
887     JsonArray *keyword_arr = NULL;
888     int arr_len = 0;
889     int keyword_arr_len = 0;
890     const char *keyword = NULL;
891
892     JsonNode *root = NULL;
893     JsonObject *root_obj = NULL;
894
895     *reply_body = g_variant_new("()");
896         if (*reply_body == NULL) {
897         LOGE("Failed to create reply_body");
898         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
899     }
900
901     g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
902
903     if (!app_id || !json_path) {
904         LOGE("failed to get parameter");
905         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
906     }
907
908     SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
909
910     parser = json_parser_new();
911     json_parser_load_from_file(parser, json_path, &err_msg);
912     if (err_msg) {
913         LOGE("failed to load json file. error message: %s", err_msg->message);
914         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
915         goto cleanup;
916     }
917
918     root = json_parser_get_root(parser);
919     if (root == NULL) {
920         LOGE("failed to get root");
921         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
922         goto cleanup;
923     }
924
925     root_obj = json_node_get_object(root);
926     if (root_obj == NULL) {
927         LOGE("failed to get object");
928         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
929         goto cleanup;
930     }
931
932     sticker_arr = json_object_get_array_member(root_obj, "sticker");
933     if (sticker_arr == NULL) {
934         LOGE("failed to get array member");
935         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
936         goto cleanup;
937     }
938
939     arr_len = json_array_get_length(sticker_arr);
940     for (int i = 0; i < arr_len; i++) {
941         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
942         if (info_object != NULL) {
943             sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
944             if (!sticker_info) {
945                 LOGE("Failed to alloc memory");
946                 continue;
947             }
948
949             sticker_info->app_id = strdup(app_id);
950             if (!sticker_info->app_id)
951                 goto free_memory;
952
953             sticker_info->type = _get_int_from_object(info_object, "type");
954             if (sticker_info->type < 1)
955                 goto free_memory;
956
957             sticker_info->uri = _get_string_from_object(info_object, "uri");
958             if (!sticker_info->uri || sticker_info->uri[0] == '\0')
959                 goto free_memory;
960
961             if (sticker_info->type == STICKER_URI_TYPE_LOCAL_PATH) {
962                 if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
963                     sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
964                     if (!sticker_info->uri)
965                         goto free_memory;
966                 } else {
967                     goto free_memory;
968                 }
969             }
970
971             sticker_info->group = _get_string_from_object(info_object, "group");
972             if (!sticker_info->group)
973                 goto free_memory;
974
975             sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
976             if (sticker_info->thumbnail && sticker_info->thumbnail[0] != '\0') {
977                 if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
978                     sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
979                     if (!sticker_info->thumbnail)
980                         goto free_memory;
981                 } else {
982                     goto free_memory;
983                 }
984             }
985
986             sticker_info->description = _get_string_from_object(info_object, "description");
987
988             sticker_info->display_type = _get_int_from_object(info_object, "display_type");
989
990             keyword_arr = json_object_get_array_member(info_object, "keyword");
991             keyword_arr_len = json_array_get_length(keyword_arr);
992             if (keyword_arr_len < 1)
993                 goto free_memory;
994
995             for (int j = 0; j < keyword_arr_len; j++) {
996                 keyword = json_array_get_string_element(keyword_arr, j);
997                 if (keyword)
998                     sticker_info->keyword = g_list_append(sticker_info->keyword, strdup(keyword));
999             }
1000
1001             ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
1002             if (ret != STICKERD_SERVER_ERROR_NONE) {
1003                 LOGE("Failed to insert sticker info");
1004                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1005             } else
1006                 _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
1007
1008 free_memory:
1009             _free_sticker_data(sticker_info);
1010             sticker_info = NULL;
1011         }
1012     }
1013
1014 cleanup:
1015     if (err_msg)
1016         g_error_free(err_msg);
1017     if (parser)
1018         g_object_unref(parser);
1019
1020     body = g_variant_new("(i)", ret);
1021
1022     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
1023     if (ret != STICKERD_SERVER_ERROR_NONE)
1024         LOGE("Failed to send insert result to client");
1025
1026     if (body)
1027         g_variant_unref(body);
1028
1029     return ret;
1030 }
1031
1032 int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
1033 {
1034     int ret;
1035     int record_id;
1036
1037     *reply_body = g_variant_new("()");
1038     if (*reply_body == NULL) {
1039         LOGE("Failed to create reply_body");
1040         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1041     }
1042
1043     g_variant_get(parameters, "(i)", &record_id);
1044
1045     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1046     if (sticker_info)
1047         stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1048
1049     ret = stickerd_db_delete_sticker_info(record_id);
1050     if (ret != STICKERD_SERVER_ERROR_NONE) {
1051         LOGE("Failed to delete sticker info");
1052         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1053     } else {
1054         if (sticker_info && sticker_info->uri)
1055             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
1056     }
1057
1058     if (sticker_info) {
1059         _free_sticker_data(sticker_info);
1060         sticker_info = NULL;
1061     }
1062
1063     return ret;
1064 }
1065
1066 int stickerd_del_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
1067 {
1068     int ret;
1069     char *uri = NULL;
1070
1071     *reply_body = g_variant_new("()");
1072     if (*reply_body == NULL) {
1073         LOGE("Failed to create reply_body");
1074         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1075     }
1076
1077     g_variant_get(parameters, "(&s)", &uri);
1078
1079     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1080     if (sticker_info)
1081         stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1082
1083     ret = stickerd_db_delete_sticker_info_by_uri(uri);
1084     if (ret != STICKERD_SERVER_ERROR_NONE) {
1085         LOGE("Failed to delete sticker info");
1086         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1087     } else {
1088         if (sticker_info && sticker_info->uri)
1089             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
1090     }
1091
1092     if (sticker_info) {
1093         _free_sticker_data(sticker_info);
1094         sticker_info = NULL;
1095     }
1096
1097     return ret;
1098 }
1099
1100 int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
1101 {
1102     int ret;
1103     int record_id;
1104     int type;
1105
1106     *reply_body = g_variant_new("()");
1107     if (*reply_body == NULL) {
1108         LOGE("Failed to create reply_body");
1109         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1110     }
1111
1112     g_variant_get(parameters, "(ii)", &record_id, &type);
1113
1114     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
1115     if (ret != STICKERD_SERVER_ERROR_NONE) {
1116         LOGE("Failed to update sticker type");
1117         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1118     }
1119
1120     return ret;
1121 }
1122
1123 int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
1124 {
1125     int ret;
1126     int record_id;
1127     int type;
1128     char *app_id;
1129     char *uri;
1130
1131     *reply_body = g_variant_new("()");
1132     if (*reply_body == NULL) {
1133         LOGE("Failed to create reply_body");
1134         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1135     }
1136
1137     g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
1138
1139     if (type == STICKER_URI_TYPE_LOCAL_PATH) {
1140         if (_check_file_exist(app_id, uri) == 0) {
1141             uri = _convert_sticker_uri(uri, app_id);
1142             if (!uri) {
1143                 LOGE("failed to copy sticker file");
1144                 return STICKERD_SERVER_ERROR_FILE_EXISTS;
1145             }
1146         } else {
1147             return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1148         }
1149     }
1150
1151     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
1152     if (ret != STICKERD_SERVER_ERROR_NONE) {
1153         LOGE("Failed to update sticker uri");
1154         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1155     }
1156
1157     return ret;
1158 }
1159
1160 int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
1161 {
1162     int ret;
1163     int record_id;
1164     char *app_id;
1165     char *thumbnail;
1166
1167     *reply_body = g_variant_new("()");
1168     if (*reply_body == NULL) {
1169         LOGE("Failed to create reply_body");
1170         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1171     }
1172
1173     g_variant_get(parameters, "(i&s&s)", &record_id, &app_id, &thumbnail);
1174
1175     if (_check_file_exist(app_id, thumbnail) == 0) {
1176         thumbnail = _convert_sticker_uri(thumbnail, app_id);
1177         if (!thumbnail) {
1178             LOGE("failed to copy sticker thumbnail");
1179             return STICKERD_SERVER_ERROR_FILE_EXISTS;
1180         }
1181     } else {
1182         return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1183     }
1184
1185     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
1186     if (ret != STICKERD_SERVER_ERROR_NONE) {
1187         LOGE("Failed to update sticker thumbnail");
1188         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1189     }
1190
1191     return ret;
1192 }
1193
1194 int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
1195 {
1196     int ret;
1197     int record_id;
1198     char *description;
1199
1200     *reply_body = g_variant_new("()");
1201     if (*reply_body == NULL) {
1202         LOGE("Failed to create reply_body");
1203         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1204     }
1205
1206     g_variant_get(parameters, "(i&s)", &record_id, &description);
1207
1208     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
1209     if (ret != STICKERD_SERVER_ERROR_NONE) {
1210         LOGE("Failed to update sticker description");
1211         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1212     }
1213
1214     return ret;
1215 }
1216
1217 int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
1218 {
1219     int ret;
1220     int record_id;
1221     char *group;
1222
1223     *reply_body = g_variant_new("()");
1224     if (*reply_body == NULL) {
1225         LOGE("Failed to create reply_body");
1226         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1227     }
1228
1229     g_variant_get(parameters, "(i&s)", &record_id, &group);
1230
1231     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
1232     if (ret != STICKERD_SERVER_ERROR_NONE) {
1233         LOGE("Failed to update sticker group");
1234         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1235     }
1236
1237     return ret;
1238 }
1239
1240 int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
1241 {
1242     int ret;
1243     int record_id;
1244     GVariantIter *keyword_iter = NULL;
1245     char *keyword = NULL;
1246     GList *keyword_list = NULL;
1247
1248     *reply_body = g_variant_new("()");
1249     if (*reply_body == NULL) {
1250         LOGE("Failed to create reply_body");
1251         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1252     }
1253
1254     g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
1255
1256     if (!keyword_iter) {
1257         LOGD("failed to get iter");
1258         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1259     }
1260
1261     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
1262         keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
1263     }
1264
1265     g_variant_iter_free(keyword_iter);
1266
1267     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
1268     if (ret != STICKERD_SERVER_ERROR_NONE) {
1269         LOGE("Failed to update sticker keyword");
1270         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1271     }
1272
1273     return ret;
1274 }
1275
1276 int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
1277 {
1278     int ret;
1279     int record_id;
1280     GVariantBuilder *info_builder;
1281     GVariantBuilder *keyword_builder;
1282
1283     g_variant_get(parameters, "(i)", &record_id);
1284     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1285
1286     if (!sticker_info)
1287         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1288
1289     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1290     if (ret != STICKERD_SERVER_ERROR_NONE) {
1291         LOGE("Failed to get sticker info");
1292         _free_sticker_data(sticker_info);
1293         sticker_info = NULL;
1294         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1295     }
1296
1297     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1298     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1299     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1300     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1301     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1302     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1303     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1304     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1305     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1306
1307     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1308     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1309
1310     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1311     g_variant_builder_unref(info_builder);
1312     g_variant_builder_unref(keyword_builder);
1313
1314     if (*reply_body == NULL) {
1315         LOGE("Failed to create reply_body");
1316         _free_sticker_data(sticker_info);
1317         sticker_info = NULL;
1318         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1319     }
1320
1321     _free_sticker_data(sticker_info);
1322     sticker_info = NULL;
1323
1324     return ret;
1325 }
1326
1327 int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
1328 {
1329     int ret;
1330     GVariantBuilder *builder = NULL;
1331     char *app_id = NULL;
1332
1333     g_variant_get(parameters, "(&s)", &app_id);
1334
1335     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1336     ret = stickerd_db_get_group_list(builder, app_id);
1337     if (ret != STICKERD_SERVER_ERROR_NONE) {
1338         LOGE("Failed to get sticker group list");
1339         g_variant_builder_unref(builder);
1340         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1341     }
1342
1343     *reply_body = g_variant_new("(a(s))", builder);
1344     g_variant_builder_unref(builder);
1345
1346     if (*reply_body == NULL) {
1347         LOGE("Failed to create reply_body");
1348         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1349     }
1350
1351     return ret;
1352 }
1353
1354 int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
1355 {
1356     int ret;
1357     GVariantBuilder *builder = NULL;
1358     char *app_id = NULL;
1359
1360     g_variant_get(parameters, "(&s)", &app_id);
1361
1362     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1363     ret = stickerd_db_get_keyword_list(builder, app_id);
1364     if (ret != STICKERD_SERVER_ERROR_NONE) {
1365         LOGE("Failed to get sticker keyword list");
1366         g_variant_builder_unref(builder);
1367         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1368     }
1369
1370     *reply_body = g_variant_new("(a(s))", builder);
1371     g_variant_builder_unref(builder);
1372
1373     if (*reply_body == NULL) {
1374         LOGE("Failed to create reply_body");
1375         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1376     }
1377
1378     return ret;
1379 }
1380
1381 int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
1382 {
1383     int ret;
1384     int count;
1385     char *app_id = NULL;
1386
1387     g_variant_get(parameters, "(&s)", &app_id);
1388
1389     ret = stickerd_db_get_sticker_count(&count, app_id);
1390     if (ret != STICKERD_SERVER_ERROR_NONE) {
1391         LOGE("Failed to get sticker count");
1392         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1393     }
1394
1395     *reply_body = g_variant_new("(i)", count);
1396     if (*reply_body == NULL) {
1397         LOGE("Failed to create reply_body");
1398         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1399     }
1400
1401     return ret;
1402 }
1403
1404 static void _set_id_builder(char *id, GVariantBuilder *id_builder)
1405 {
1406     if (!id) {
1407         LOGE("id doesn't exist");
1408         return;
1409     }
1410
1411     g_variant_builder_add(id_builder, "(i)", atoi(id));
1412 }
1413
1414 static int _set_reply_body(GList *list, GVariant **reply_body)
1415 {
1416     int ret  = STICKERD_SERVER_ERROR_NONE;
1417     GVariantBuilder *builder = NULL;
1418
1419     builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1420     g_list_foreach(list, (GFunc) _set_id_builder, builder);
1421
1422     *reply_body = g_variant_new("(a(i))", builder);
1423     if (*reply_body == NULL) {
1424         LOGE("Failed to create reply_body");
1425         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1426     }
1427
1428     if (builder)
1429         g_variant_builder_unref(builder);
1430
1431     return ret;
1432 }
1433
1434 int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
1435 {
1436     int ret;
1437     int offset, count;
1438     char *app_id = NULL;
1439     GList *id_list = NULL;
1440
1441     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1442
1443     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, app_id, offset, count);
1444     if (ret != STICKERD_SERVER_ERROR_NONE) {
1445         LOGE("Failed to get all sticker id");
1446         if (id_list)
1447             g_list_free_full(id_list, free);
1448         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1449     }
1450
1451     ret = _set_reply_body(id_list, reply_body);
1452     if (id_list)
1453         g_list_free_full(id_list, free);
1454
1455     return ret;
1456 }
1457
1458 int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
1459 {
1460     int ret;
1461     GList *id_list = NULL;
1462     char *app_id = NULL;
1463     int offset, count;
1464
1465     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1466
1467     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, NULL, app_id, offset, count);
1468     if (ret != STICKERD_SERVER_ERROR_NONE) {
1469         LOGE("Failed to get all sticker id");
1470         if (id_list)
1471             g_list_free_full(id_list, free);
1472         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1473     }
1474
1475     ret = _set_reply_body(id_list, reply_body);
1476     if (id_list)
1477         g_list_free_full(id_list, free);
1478
1479     return ret;
1480 }
1481
1482 int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
1483 {
1484     int ret;
1485     GList *id_list = NULL;
1486     char *app_id = NULL;
1487     int type, offset, count;
1488
1489     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1490
1491     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, app_id, offset, count);
1492     if (ret != STICKERD_SERVER_ERROR_NONE) {
1493         LOGE("Failed to get all sticker id");
1494         if (id_list)
1495             g_list_free_full(id_list, free);
1496         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1497     }
1498
1499     ret = _set_reply_body(id_list, reply_body);
1500     if (id_list)
1501         g_list_free_full(id_list, free);
1502
1503     return ret;
1504 }
1505
1506 int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
1507 {
1508     int ret;
1509     GList *id_list = NULL;
1510     char *app_id = NULL;
1511     char *group = NULL;
1512     int offset, count;
1513
1514     g_variant_get(parameters, "(&s&sii)", &app_id, &group, &offset, &count);
1515
1516     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, app_id, offset, count);
1517     if (ret != STICKERD_SERVER_ERROR_NONE) {
1518         LOGE("Failed to get all sticker id");
1519         if (id_list)
1520             g_list_free_full(id_list, free);
1521         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1522     }
1523
1524     ret = _set_reply_body(id_list, reply_body);
1525     if (id_list)
1526         g_list_free_full(id_list, free);
1527
1528     return ret;
1529 }
1530
1531 int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
1532 {
1533     int ret;
1534     GList *id_list = NULL;
1535     char *app_id = NULL;
1536     char *keyword = NULL;
1537     int offset, count;
1538
1539     g_variant_get(parameters, "(&s&sii)", &app_id, &keyword, &offset, &count);
1540
1541     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, app_id, offset, count);
1542     if (ret != STICKERD_SERVER_ERROR_NONE) {
1543         LOGE("Failed to get all sticker id");
1544         if (id_list)
1545             g_list_free_full(id_list, free);
1546         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1547     }
1548
1549     ret = _set_reply_body(id_list, reply_body);
1550     if (id_list)
1551         g_list_free_full(id_list, free);
1552
1553     return ret;
1554 }
1555
1556 int stickerd_get_sticker_info_by_display_type(GVariant *parameters, GVariant **reply_body)
1557 {
1558     int ret;
1559     GList *id_list = NULL;
1560     char *app_id = NULL;
1561     int type, offset, count;
1562
1563     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1564
1565     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_DISP_TYPE, &id_list, &type, app_id, offset, count);
1566     if (ret != STICKERD_SERVER_ERROR_NONE) {
1567         LOGE("Failed to get all sticker id");
1568         if (id_list)
1569             g_list_free_full(id_list, free);
1570         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1571     }
1572
1573     ret = _set_reply_body(id_list, reply_body);
1574     if (id_list)
1575         g_list_free_full(id_list, free);
1576
1577     return ret;
1578 }
1579
1580 int stickerd_get_group_list_by_disp_type(GVariant *parameters, GVariant **reply_body)
1581 {
1582     int ret;
1583     GVariantBuilder *builder = NULL;
1584     char *app_id = NULL;
1585     int disp_type;
1586
1587     g_variant_get(parameters, "(&si)", &app_id, &disp_type);
1588
1589     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1590     ret = stickerd_db_get_group_list_by_display_type(builder, app_id, disp_type);
1591     if (ret != STICKERD_SERVER_ERROR_NONE) {
1592         LOGE("Failed to get sticker group list");
1593         g_variant_builder_unref(builder);
1594         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1595     }
1596
1597     *reply_body = g_variant_new("(a(s))", builder);
1598     g_variant_builder_unref(builder);
1599
1600     if (*reply_body == NULL) {
1601         LOGE("Failed to create reply_body");
1602         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1603     }
1604
1605     return ret;
1606 }
1607
1608 int stickerd_update_sticker_disp_type(GVariant *parameters, GVariant **reply_body)
1609 {
1610     int ret;
1611     int record_id;
1612     int disp_type;
1613
1614     *reply_body = g_variant_new("()");
1615     if (*reply_body == NULL) {
1616         LOGE("Failed to create reply_body");
1617         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1618     }
1619
1620     g_variant_get(parameters, "(ii)", &record_id, &disp_type);
1621
1622     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DISP_TYPE, &disp_type);
1623     if (ret != STICKERD_SERVER_ERROR_NONE) {
1624         LOGE("Failed to update sticker disp_type");
1625         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1626     }
1627
1628     return ret;
1629 }
1630
1631 int stickerd_check_file_exists(GVariant *parameters, GVariant **reply_body)
1632 {
1633     int ret;
1634     int result;
1635     char *uri = NULL;
1636
1637     g_variant_get(parameters, "(&s)", &uri);
1638
1639     ret = stickerd_db_check_file_exists(&result, uri);
1640     if (ret != STICKERD_SERVER_ERROR_NONE) {
1641         LOGE("Failed to get sticker count");
1642         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1643     }
1644
1645     *reply_body = g_variant_new("(i)", result);
1646     if (*reply_body == NULL) {
1647         LOGE("Failed to create reply_body");
1648         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1649     }
1650
1651     return ret;
1652 }
1653
1654 int stickerd_insert_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1655 {
1656     int ret;
1657     int record_id;
1658
1659     *reply_body = g_variant_new("()");
1660     if (*reply_body == NULL) {
1661         LOGE("Failed to create reply_body");
1662         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1663     }
1664
1665     g_variant_get(parameters, "(i)", &record_id);
1666
1667     ret = stickerd_db_insert_recent_sticker_info(record_id);
1668     if (ret != STICKERD_SERVER_ERROR_NONE) {
1669         LOGE("Failed to insert recent sticker info");
1670         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1671     }
1672
1673     return ret;
1674 }
1675
1676 int stickerd_get_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1677 {
1678     int ret;
1679     int count;
1680     GList *id_list = NULL;
1681
1682     g_variant_get(parameters, "(i)", &count);
1683
1684     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_RECENT_HISTORY, &id_list, NULL, NULL, 0, count);
1685     if (ret != STICKERD_SERVER_ERROR_NONE) {
1686         LOGE("Failed to get recent sticker id");
1687         if (id_list)
1688             g_list_free_full(id_list, free);
1689         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1690     }
1691
1692     ret = _set_reply_body(id_list, reply_body);
1693     if (id_list)
1694         g_list_free_full(id_list, free);
1695
1696     return ret;
1697 }
1698
1699 int stickerd_send_update_event(GVariant *parameters, GVariant **reply_body)
1700 {
1701     int ret = STICKERD_SERVER_ERROR_NONE;
1702     int record_id;
1703
1704     *reply_body = g_variant_new("()");
1705     if (*reply_body == NULL) {
1706         LOGE("Failed to create reply_body");
1707         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1708     }
1709
1710     g_variant_get(parameters, "(i)", &record_id);
1711
1712     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1713     if (sticker_info) {
1714         ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1715         if (ret == STICKERD_SERVER_ERROR_NONE)
1716             _send_sticker_changed_event(STICKER_EVENT_TYPE_UPDATE, sticker_info);
1717
1718         _free_sticker_data(sticker_info);
1719         sticker_info = NULL;
1720     }
1721
1722     return ret;
1723 }
1724
1725 int stickerd_get_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
1726 {
1727     int ret;
1728     char *uri = NULL;
1729     GVariantBuilder *info_builder;
1730     GVariantBuilder *keyword_builder;
1731
1732     g_variant_get(parameters, "(&s)", &uri);
1733
1734     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1735
1736     if (!sticker_info)
1737         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1738
1739     ret = stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1740     if (ret != STICKERD_SERVER_ERROR_NONE) {
1741         LOGE("Failed to get sticker info");
1742         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1743         goto cleanup;
1744     }
1745
1746     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1747     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(sticker_info->record_id));
1748     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1749     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1750     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1751     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1752     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1753     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1754     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1755     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1756
1757     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1758     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1759
1760     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1761     g_variant_builder_unref(info_builder);
1762     g_variant_builder_unref(keyword_builder);
1763
1764     if (*reply_body == NULL) {
1765         LOGE("Failed to create reply_body");
1766         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1767     }
1768
1769 cleanup:
1770     if (sticker_info) {
1771         _free_sticker_data(sticker_info);
1772         sticker_info = NULL;
1773     }
1774
1775     return ret;
1776 }
1777
1778 int stickerd_check_group_exists(GVariant *parameters, GVariant **reply_body)
1779 {
1780     int ret;
1781     int result;
1782     char *app_id = NULL;
1783     char *group = NULL;
1784
1785     g_variant_get(parameters, "(&s&s)", &app_id, &group);
1786
1787     ret = stickerd_db_check_group_exists(&result, app_id, group);
1788     if (ret != STICKERD_SERVER_ERROR_NONE) {
1789         LOGE("Failed to check group exists");
1790         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1791     }
1792
1793     *reply_body = g_variant_new("(i)", result);
1794     if (*reply_body == NULL) {
1795         LOGE("Failed to create reply_body");
1796         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1797     }
1798
1799     return ret;
1800 }
1801
1802 int stickerd_set_group_image(GVariant *parameters, GVariant **reply_body)
1803 {
1804     int ret;
1805     int type;
1806     char *app_id = NULL;
1807     char *group = NULL;
1808     char *uri = NULL;
1809
1810     *reply_body = g_variant_new("()");
1811     if (*reply_body == NULL) {
1812         LOGE("Failed to create reply_body");
1813         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1814     }
1815
1816     g_variant_get(parameters, "(&s&si&s)", &app_id, &group, &type, &uri);
1817
1818     if (type == STICKER_URI_TYPE_LOCAL_PATH) {
1819         if (_check_file_exist(app_id, uri) == 0) {
1820             uri = _convert_sticker_uri(uri, app_id);
1821             if (!uri) {
1822                 LOGE("failed to copy sticker file");
1823                 return STICKERD_SERVER_ERROR_FILE_EXISTS;
1824             }
1825         } else {
1826             LOGE("sticker file does not exist");
1827             return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1828         }
1829     }
1830
1831     ret = stickerd_db_set_group_image(app_id, group, type, uri);
1832     if (ret != STICKERD_SERVER_ERROR_NONE) {
1833         LOGE("Failed to set group image");
1834         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1835     }
1836
1837     return ret;
1838 }
1839
1840 int stickerd_get_group_image_list(GVariant *parameters, GVariant **reply_body)
1841 {
1842     int ret;
1843     GVariantBuilder *builder = NULL;
1844     char *app_id = NULL;
1845
1846     g_variant_get(parameters, "(&s)", &app_id);
1847
1848     builder = g_variant_builder_new(G_VARIANT_TYPE("a(sis)"));
1849     ret = stickerd_db_get_group_image_list(builder, app_id);
1850     if (ret != STICKERD_SERVER_ERROR_NONE) {
1851         LOGE("Failed to get sticker group image list");
1852         g_variant_builder_unref(builder);
1853         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1854     }
1855
1856     *reply_body = g_variant_new("(a(sis))", builder);
1857     g_variant_builder_unref(builder);
1858
1859     if (*reply_body == NULL) {
1860         LOGE("Failed to create reply_body");
1861         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1862     }
1863
1864     return ret;
1865 }