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