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