Sort sticker data in reverse order by db index
[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 tzplatform_mkpath(TZ_SYS_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     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
484
485     if (fd == -1 || n_fd == -1) {
486         tmp_err = errno;
487         ret = -1;
488         goto cleanup;
489     }
490
491     while((size = read(fd, buf, 4096))) {
492         if (size == -1) {
493             if(errno == EINTR)
494                 continue;
495
496             tmp_err = errno;
497             ret = -1;
498             goto cleanup;
499         }
500
501         while(write(n_fd, buf, size) == -1) {
502             if(errno == EINTR) {
503                 continue;
504             } else {
505                 tmp_err = errno;
506                 goto cleanup;
507             }
508         }
509     }
510
511 cleanup:
512     if (fd != -1)
513         close(fd);
514
515     if (n_fd != -1)
516         close(n_fd);
517
518     errno = tmp_err;
519     return ret;
520 }
521
522 static char* _convert_sticker_uri(const char *uri, const char *appid)
523 {
524     int ret;
525     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
526     char * new_path = (char *)calloc(len, sizeof(char));
527     if (new_path == NULL) {
528         LOGE("Failed to alloc memory");
529         return NULL;
530     }
531
532     if (uri[0] == '/')
533         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
534     else
535         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
536
537     if (access(new_path, F_OK) == 0) {
538         LOGE("sticker file already exists : %s", new_path);
539         ret = -1;
540         goto cleanup;
541     }
542
543     ret = _mkdirs(new_path, 0755);
544     if (ret != 0) {
545         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
546         LOGE("directory create error : %s", error_buffer);
547         goto cleanup;
548     }
549
550     ret = _file_copy(uri, new_path);
551     if (ret != 0) {
552         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
553         LOGE("failed to copy sticker file : %s", error_buffer);
554     }
555
556 cleanup:
557     if (ret == 0) {
558         return new_path;
559     } else {
560         free(new_path);
561         new_path = NULL;
562         return NULL;
563     }
564 }
565
566 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
567 {
568     if (!keyword) {
569         LOGE("keyword doesn't exist");
570         return;
571     }
572
573     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
574 }
575
576 static GVariant* _get_sticker_g_variant(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
577 {
578     GVariantBuilder *info_builder;
579     GVariantBuilder *keyword_builder;
580
581     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
582     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
583     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
584     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
585     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
586     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
587     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
588     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
589     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
590
591     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
592     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
593
594     GVariant *body = g_variant_new("(ia{iv}a(s))", (int)type, info_builder, keyword_builder);
595     g_variant_builder_unref(info_builder);
596     g_variant_builder_unref(keyword_builder);
597
598     if (body)
599         return body;
600     else
601         return NULL;
602 }
603
604 void _get_consumer_busname(gpointer data, gpointer user_data)
605 {
606     if (data == NULL)
607         return;
608
609     int ret;
610     char *cmd = "send_sticker_changed_event";
611     char *sender = (char *)data;
612     GVariant *body = (GVariant *)user_data;
613
614     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_CONSUMER);
615     if (ret != STICKERD_SERVER_ERROR_NONE)
616         LOGE("Failed to send sticker changed event");
617 }
618
619 static void _send_sticker_changed_event(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
620 {
621     GVariant *body = _get_sticker_g_variant(type, sticker_info);
622
623     if (body)
624         g_list_foreach(consumer_list, _get_consumer_busname, body);
625
626     if (body)
627         g_variant_unref(body);
628 }
629
630 static void _free_sticker_data(sticker_info_db *sticker_data)
631 {
632     if (!sticker_data)
633         return;
634
635     if (sticker_data->app_id) {
636         free(sticker_data->app_id);
637         sticker_data->app_id = NULL;
638     }
639
640     if (sticker_data->uri) {
641         free(sticker_data->uri);
642         sticker_data->uri = NULL;
643     }
644
645     if (sticker_data->thumbnail) {
646         free(sticker_data->thumbnail);
647         sticker_data->thumbnail = NULL;
648     }
649
650     if (sticker_data->keyword) {
651         g_list_free_full(sticker_data->keyword, free);
652         sticker_data->keyword = NULL;
653     }
654
655     if (sticker_data->group) {
656         free(sticker_data->group);
657         sticker_data->group = NULL;
658     }
659
660     if (sticker_data->description) {
661         free(sticker_data->description);
662         sticker_data->description = NULL;
663     }
664
665     if (sticker_data->date) {
666         free(sticker_data->date);
667         sticker_data->date = NULL;
668     }
669
670     free(sticker_data);
671 }
672
673 int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
674 {
675     int ret;
676     int record_id = 0;
677     STICKER_DAT_TYPE key;
678     sticker_info_db *sticker_info = NULL;
679     GVariant *value = NULL;
680     GVariantIter *info_iter = NULL;
681     GVariantIter *keyword_iter = NULL;
682     char *keyword;
683
684     g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
685     if (!info_iter || !keyword_iter) {
686         LOGD("failed to get iter");
687         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
688         goto cleanup;
689     }
690
691     sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
692
693     if (!sticker_info) {
694         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
695         goto cleanup;
696     }
697
698     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
699         switch(key) {
700             case STICKER_DATA_TYPE_APP_ID:
701             sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
702             break;
703             case STICKER_DATA_TYPE_URI_TYPE:
704             sticker_info->type = g_variant_get_int32(value);
705             break;
706             case STICKER_DATA_TYPE_URI:
707             sticker_info->uri = (char *) g_variant_get_string(value, NULL);
708             break;
709             case STICKER_DATA_TYPE_THUMBNAIL:
710             sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
711             break;
712             case STICKER_DATA_TYPE_DESCRIPTION:
713             sticker_info->description = (char *) g_variant_get_string(value, NULL);
714             break;
715             case STICKER_DATA_TYPE_GROUP:
716             sticker_info->group = (char *) g_variant_get_string(value, NULL);
717             break;
718             case STICKER_DATA_TYPE_DISP_TYPE:
719             sticker_info->display_type = g_variant_get_int32(value);
720             default:
721             break;
722         }
723     }
724
725     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
726         sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
727     }
728
729     if (sticker_info->type == 1) {
730         if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
731             sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
732             if (!sticker_info->uri) {
733                 LOGE("failed to copy sticker file");
734                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
735                 goto cleanup;
736             }
737         } else {
738             LOGE("sticker file does not exist");
739             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
740             goto cleanup;
741         }
742     }
743
744     if (sticker_info->thumbnail) {
745         if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
746             sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
747             if (!sticker_info->thumbnail) {
748                 LOGE("failed to copy sticker thumbnail");
749                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
750                 goto cleanup;
751             }
752         } else {
753             LOGE("sticker thumbnail does not exist");
754             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
755             goto cleanup;
756         }
757     }
758
759     ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
760     if (ret != STICKERD_SERVER_ERROR_NONE) {
761         LOGE("Failed to insert sticker info");
762         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
763         goto cleanup;
764     }
765
766     *reply_body = g_variant_new("(i)", record_id);
767     if (*reply_body == NULL) {
768         LOGE("Failed to create reply_body");
769         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
770     } else
771         _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
772
773 cleanup:
774     if (value)
775         g_variant_unref(value);
776
777     if (info_iter)
778         g_variant_iter_free(info_iter);
779
780     if (keyword_iter)
781         g_variant_iter_free(keyword_iter);
782
783     if (sticker_info) {
784         free(sticker_info);
785         sticker_info = NULL;
786     }
787
788     return ret;
789 }
790
791 static char* _get_string_from_object(JsonObject *object, const char *key)
792 {
793     if (json_object_has_member(object, key) == false)
794         return NULL;
795
796     const char *str = json_object_get_string_member(object, key);
797     if (str != NULL)
798         return strdup(str);
799     else
800         return NULL;
801 }
802
803 static int _get_int_from_object(JsonObject *object, const char *key)
804 {
805     if (json_object_has_member(object, key) == false)
806         return -1;
807
808     int type = json_object_get_int_member(object, key);
809
810     return type;
811 }
812
813 int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
814 {
815     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
816     int record_id;
817     sticker_info_db *sticker_info = NULL;
818     char *app_id = NULL;
819     char *json_path = NULL;
820     JsonParser* parser = NULL;
821     GError* err_msg = NULL;
822     GVariant *body = NULL;
823     char *cmd = "send_insert_result";
824
825     *reply_body = g_variant_new("()");
826         if (*reply_body == NULL) {
827         LOGE("Failed to create reply_body");
828         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
829     }
830
831     g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
832
833     if (!app_id || !json_path) {
834         LOGE("failed to get parameter");
835         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
836     }
837
838     SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
839
840     parser = json_parser_new();
841     json_parser_load_from_file(parser, json_path, &err_msg);
842     if (err_msg) {
843         LOGE("failed to load json file. error message: %s", err_msg->message);
844         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
845         goto cleanup;
846     }
847
848     JsonNode *root = json_parser_get_root(parser);
849     if (root == NULL) {
850         LOGE("failed to get root");
851         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
852         goto cleanup;
853     }
854
855     JsonObject *root_obj = json_node_get_object(root);
856     if (root_obj == NULL) {
857         LOGE("failed to get object");
858         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
859         goto cleanup;
860     }
861
862     JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
863     if (sticker_arr == NULL) {
864         LOGE("failed to get array member");
865         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
866         goto cleanup;
867     }
868
869     int arr_len = json_array_get_length(sticker_arr);
870     for (int i = 0; i < arr_len; i++) {
871         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
872         if (info_object != NULL) {
873             sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
874             if (!sticker_info) {
875                 LOGE("Failed to alloc memory");
876                 continue;
877             }
878
879             sticker_info->app_id = strdup(app_id);
880             if (!sticker_info->app_id)
881                 goto free_memory;
882
883             sticker_info->type = _get_int_from_object(info_object, "type");
884             if (sticker_info->type < 1)
885                 goto free_memory;
886
887             sticker_info->uri = _get_string_from_object(info_object, "uri");
888             if (!sticker_info->uri || sticker_info->uri[0] == '\0')
889                 goto free_memory;
890
891             if (sticker_info->type == 1) {
892                 if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
893                     sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
894                     if (!sticker_info->uri)
895                         goto free_memory;
896                 } else {
897                     goto free_memory;
898                 }
899             }
900
901             sticker_info->group = _get_string_from_object(info_object, "group");
902             if (!sticker_info->group)
903                 goto free_memory;
904
905             sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
906             if (sticker_info->thumbnail && sticker_info->thumbnail[0] != '\0') {
907                 if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
908                     sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
909                     if (!sticker_info->thumbnail)
910                         goto free_memory;
911                 } else {
912                     goto free_memory;
913                 }
914             }
915
916             sticker_info->description = _get_string_from_object(info_object, "description");
917
918             sticker_info->display_type = _get_int_from_object(info_object, "display_type");
919
920             JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
921             int keyword_arr_len = json_array_get_length(keyword_arr);
922             if (keyword_arr_len < 1)
923                 goto free_memory;
924
925             for (int j = 0; j < keyword_arr_len; j++) {
926                 sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)json_array_get_string_element(keyword_arr, j)));
927             }
928
929             ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
930             if (ret != STICKERD_SERVER_ERROR_NONE) {
931                 LOGE("Failed to insert sticker info");
932                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
933             } else
934                 _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
935
936 free_memory:
937             _free_sticker_data(sticker_info);
938             sticker_info = NULL;
939         }
940     }
941
942 cleanup:
943     if (err_msg)
944         g_error_free(err_msg);
945     if (parser)
946         g_object_unref(parser);
947
948     body = g_variant_new("(i)", ret);
949
950     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
951     if (ret != STICKERD_SERVER_ERROR_NONE)
952         LOGE("Failed to send insert result to client");
953
954     if(body)
955         g_variant_unref(body);
956
957     return ret;
958 }
959
960 int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
961 {
962     int ret;
963     int record_id;
964
965     *reply_body = g_variant_new("()");
966     if (*reply_body == NULL) {
967         LOGE("Failed to create reply_body");
968         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
969     }
970
971     g_variant_get(parameters, "(i)", &record_id);
972
973     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
974     if (sticker_info)
975         stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
976
977     ret = stickerd_db_delete_sticker_info(record_id);
978     if (ret != STICKERD_SERVER_ERROR_NONE) {
979         LOGE("Failed to delete sticker info");
980         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
981     } else {
982         if (sticker_info && sticker_info->uri)
983             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
984     }
985
986     if (sticker_info) {
987         _free_sticker_data(sticker_info);
988         sticker_info = NULL;
989     }
990
991     return ret;
992 }
993
994 int stickerd_del_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
995 {
996     int ret;
997     char *uri = NULL;
998
999     *reply_body = g_variant_new("()");
1000     if (*reply_body == NULL) {
1001         LOGE("Failed to create reply_body");
1002         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1003     }
1004
1005     g_variant_get(parameters, "(&s)", &uri);
1006
1007     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1008     if (sticker_info)
1009         stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1010
1011     ret = stickerd_db_delete_sticker_info_by_uri(uri);
1012     if (ret != STICKERD_SERVER_ERROR_NONE) {
1013         LOGE("Failed to delete sticker info");
1014         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1015     } else {
1016         if (sticker_info && sticker_info->uri)
1017             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
1018     }
1019
1020     if (sticker_info) {
1021         _free_sticker_data(sticker_info);
1022         sticker_info = NULL;
1023     }
1024
1025     return ret;
1026 }
1027
1028 int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
1029 {
1030     int ret;
1031     int record_id;
1032     int type;
1033
1034     *reply_body = g_variant_new("()");
1035     if (*reply_body == NULL) {
1036         LOGE("Failed to create reply_body");
1037         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1038     }
1039
1040     g_variant_get(parameters, "(ii)", &record_id, &type);
1041
1042     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
1043     if (ret != STICKERD_SERVER_ERROR_NONE) {
1044         LOGE("Failed to update sticker type");
1045         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1046     }
1047
1048     return ret;
1049 }
1050
1051 int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
1052 {
1053     int ret;
1054     int record_id;
1055     int type;
1056     char *app_id;
1057     char *uri;
1058
1059     *reply_body = g_variant_new("()");
1060     if (*reply_body == NULL) {
1061         LOGE("Failed to create reply_body");
1062         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1063     }
1064
1065     g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
1066
1067     if (type == 1) {
1068         if (_check_file_exist(app_id, uri) == 0) {
1069             uri = _convert_sticker_uri(uri, app_id);
1070             if (!uri) {
1071                 LOGE("failed to copy sticker file");
1072                 return STICKERD_SERVER_ERROR_FILE_EXISTS;
1073             }
1074         } else {
1075             return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1076         }
1077     }
1078
1079     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
1080     if (ret != STICKERD_SERVER_ERROR_NONE) {
1081         LOGE("Failed to update sticker uri");
1082         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1083     }
1084
1085     return ret;
1086 }
1087
1088 int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
1089 {
1090     int ret;
1091     int record_id;
1092     char *app_id;
1093     char *thumbnail;
1094
1095     *reply_body = g_variant_new("()");
1096     if (*reply_body == NULL) {
1097         LOGE("Failed to create reply_body");
1098         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1099     }
1100
1101     g_variant_get(parameters, "(i&s&s)", &record_id, &app_id, &thumbnail);
1102
1103     if (_check_file_exist(app_id, thumbnail) == 0) {
1104         thumbnail = _convert_sticker_uri(thumbnail, app_id);
1105         if (!thumbnail) {
1106             LOGE("failed to copy sticker thumbnail");
1107             return STICKERD_SERVER_ERROR_FILE_EXISTS;
1108         }
1109     } else {
1110         return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1111     }
1112
1113     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
1114     if (ret != STICKERD_SERVER_ERROR_NONE) {
1115         LOGE("Failed to update sticker thumbnail");
1116         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1117     }
1118
1119     return ret;
1120 }
1121
1122 int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
1123 {
1124     int ret;
1125     int record_id;
1126     char *description;
1127
1128     *reply_body = g_variant_new("()");
1129     if (*reply_body == NULL) {
1130         LOGE("Failed to create reply_body");
1131         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1132     }
1133
1134     g_variant_get(parameters, "(i&s)", &record_id, &description);
1135
1136     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
1137     if (ret != STICKERD_SERVER_ERROR_NONE) {
1138         LOGE("Failed to update sticker description");
1139         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1140     }
1141
1142     return ret;
1143 }
1144
1145 int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
1146 {
1147     int ret;
1148     int record_id;
1149     char *group;
1150
1151     *reply_body = g_variant_new("()");
1152     if (*reply_body == NULL) {
1153         LOGE("Failed to create reply_body");
1154         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1155     }
1156
1157     g_variant_get(parameters, "(i&s)", &record_id, &group);
1158
1159     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
1160     if (ret != STICKERD_SERVER_ERROR_NONE) {
1161         LOGE("Failed to update sticker group");
1162         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1163     }
1164
1165     return ret;
1166 }
1167
1168 int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
1169 {
1170     int ret;
1171     int record_id;
1172     GVariantIter *keyword_iter = NULL;
1173     char *keyword = NULL;
1174     GList *keyword_list = NULL;
1175
1176     *reply_body = g_variant_new("()");
1177     if (*reply_body == NULL) {
1178         LOGE("Failed to create reply_body");
1179         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1180     }
1181
1182     g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
1183
1184     if (!keyword_iter) {
1185         LOGD("failed to get iter");
1186         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1187     }
1188
1189     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
1190         keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
1191     }
1192
1193     g_variant_iter_free(keyword_iter);
1194
1195     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
1196     if (ret != STICKERD_SERVER_ERROR_NONE) {
1197         LOGE("Failed to update sticker keyword");
1198         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1199     }
1200
1201     return ret;
1202 }
1203
1204 int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
1205 {
1206     int ret;
1207     int record_id;
1208     GVariantBuilder *info_builder;
1209     GVariantBuilder *keyword_builder;
1210
1211     g_variant_get(parameters, "(i)", &record_id);
1212     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1213
1214     if (!sticker_info)
1215         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1216
1217     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1218     if (ret != STICKERD_SERVER_ERROR_NONE) {
1219         LOGE("Failed to get sticker info");
1220         _free_sticker_data(sticker_info);
1221         sticker_info = NULL;
1222         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1223     }
1224
1225     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1226     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1227     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1228     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1229     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1230     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1231     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1232     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1233     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1234
1235     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1236     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1237
1238     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1239     g_variant_builder_unref(info_builder);
1240     g_variant_builder_unref(keyword_builder);
1241
1242     if (*reply_body == NULL) {
1243         LOGE("Failed to create reply_body");
1244         _free_sticker_data(sticker_info);
1245         sticker_info = NULL;
1246         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1247     }
1248
1249     _free_sticker_data(sticker_info);
1250     sticker_info = NULL;
1251
1252     return ret;
1253 }
1254
1255 int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
1256 {
1257     int ret;
1258     GVariantBuilder *builder = NULL;
1259     char *app_id = NULL;
1260
1261     g_variant_get(parameters, "(&s)", &app_id);
1262
1263     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1264     ret = stickerd_db_get_group_list(builder, app_id);
1265     if (ret != STICKERD_SERVER_ERROR_NONE) {
1266         LOGE("Failed to get sticker group list");
1267         g_variant_builder_unref(builder);
1268         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1269     }
1270
1271     *reply_body = g_variant_new("(a(s))", builder);
1272     g_variant_builder_unref(builder);
1273
1274     if (*reply_body == NULL) {
1275         LOGE("Failed to create reply_body");
1276         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1277     }
1278
1279     return ret;
1280 }
1281
1282 int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
1283 {
1284     int ret;
1285     GVariantBuilder *builder = NULL;
1286     char *app_id = NULL;
1287
1288     g_variant_get(parameters, "(&s)", &app_id);
1289
1290     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1291     ret = stickerd_db_get_keyword_list(builder, app_id);
1292     if (ret != STICKERD_SERVER_ERROR_NONE) {
1293         LOGE("Failed to get sticker keyword list");
1294         g_variant_builder_unref(builder);
1295         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1296     }
1297
1298     *reply_body = g_variant_new("(a(s))", builder);
1299     g_variant_builder_unref(builder);
1300
1301     if (*reply_body == NULL) {
1302         LOGE("Failed to create reply_body");
1303         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1304     }
1305
1306     return ret;
1307 }
1308
1309 int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
1310 {
1311     int ret;
1312     int count;
1313     char *app_id = NULL;
1314
1315     g_variant_get(parameters, "(&s)", &app_id);
1316
1317     ret = stickerd_db_get_sticker_count(&count, app_id);
1318     if (ret != STICKERD_SERVER_ERROR_NONE) {
1319         LOGE("Failed to get sticker count");
1320         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1321     }
1322
1323     *reply_body = g_variant_new("(i)", count);
1324     if (*reply_body == NULL) {
1325         LOGE("Failed to create reply_body");
1326         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1327     }
1328
1329     return ret;
1330 }
1331
1332 #if 0
1333 // Send the sticker information by asynchronous communication.
1334 static int send_sticker_info_async(int record_id, sticker_info_db_type type, const char *sender)
1335 {
1336     int ret;
1337     char *cmd = NULL;
1338
1339     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1340
1341     if (!sticker_info)
1342         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1343
1344     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1345     if (ret != STICKERD_SERVER_ERROR_NONE) {
1346         LOGE("Failed to get sticker info");
1347         free(sticker_info);
1348         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1349     }
1350
1351     switch (type) {
1352         case STICKER_DB_STICKER_ALL:
1353         cmd = "send_all_sticker_info";
1354         break;
1355         case STICKER_DB_STICKER_APPID:
1356         cmd = "send_sticker_info_by_appid";
1357         break;
1358         case STICKER_DB_STICKER_TYPE:
1359         cmd = "send_sticker_info_by_type";
1360         break;
1361         case STICKER_DB_STICKER_GROUP:
1362         cmd = "send_sticker_info_by_group";
1363         break;
1364         case STICKER_DB_STICKER_KEYWORD:
1365         cmd = "send_sticker_info_by_keyword";
1366         break;
1367         default:
1368         cmd = "";
1369         break;
1370     }
1371
1372     GVariantBuilder *info_builder;
1373     GVariantBuilder *keyword_builder;
1374
1375     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1376     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(record_id));
1377     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1378     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1379     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1380     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1381     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1382     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1383     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1384
1385     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1386     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1387
1388     GVariant *body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1389     g_variant_builder_unref(info_builder);
1390     g_variant_builder_unref(keyword_builder);
1391
1392     ret = stickerd_send_dbus_message(body, sender, cmd);
1393     if (ret != STICKERD_SERVER_ERROR_NONE) {
1394         LOGE("Failed to send sticker info to client");
1395         free(sticker_info);
1396         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1397     }
1398
1399     free(sticker_info);
1400     return ret;
1401 }
1402 #endif
1403
1404 static void _set_id_builder(char *id, GVariantBuilder *id_builder)
1405 {
1406     if (!id) {
1407         LOGE("id doesn't exist");
1408         return;
1409     }
1410
1411     g_variant_builder_add(id_builder, "(i)", atoi(id));
1412 }
1413
1414 int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
1415 {
1416     int ret;
1417     int offset, count;
1418     char *app_id = NULL;
1419     GList *id_list = NULL;
1420     GVariantBuilder *id_builder = NULL;
1421
1422     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1423
1424     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, app_id, offset, count);
1425     if (ret != STICKERD_SERVER_ERROR_NONE) {
1426         LOGE("Failed to get all sticker id");
1427         if(id_list)
1428             g_list_free_full(id_list, free);
1429         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1430     }
1431
1432     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1433     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1434
1435     *reply_body = g_variant_new("(a(i))", id_builder);
1436     if (*reply_body == NULL) {
1437         LOGE("Failed to create reply_body");
1438         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1439     }
1440
1441     if (id_list)
1442         g_list_free_full(id_list, free);
1443
1444     if (id_builder)
1445         g_variant_builder_unref(id_builder);
1446
1447     return ret;
1448 }
1449
1450 int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
1451 {
1452     int ret;
1453     GList *id_list = NULL;
1454     char *app_id = NULL;
1455     int offset, count;
1456     GVariantBuilder *id_builder = NULL;
1457
1458     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1459
1460     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, NULL, app_id, offset, count);
1461     if (ret != STICKERD_SERVER_ERROR_NONE) {
1462         LOGE("Failed to get all sticker id");
1463         if(id_list)
1464             g_list_free_full(id_list, free);
1465         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1466     }
1467
1468     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1469     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1470
1471     *reply_body = g_variant_new("(a(i))", id_builder);
1472     if (*reply_body == NULL) {
1473         LOGE("Failed to create reply_body");
1474         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1475     }
1476
1477     if (id_list)
1478         g_list_free_full(id_list, free);
1479
1480     if (id_builder)
1481         g_variant_builder_unref(id_builder);
1482
1483     return ret;
1484 }
1485
1486 int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
1487 {
1488     int ret;
1489     GList *id_list = NULL;
1490     char *app_id = NULL;
1491     int type, offset, count;
1492     GVariantBuilder *id_builder = NULL;
1493
1494     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1495
1496     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, app_id, offset, count);
1497     if (ret != STICKERD_SERVER_ERROR_NONE) {
1498         LOGE("Failed to get all sticker id");
1499         if(id_list)
1500             g_list_free_full(id_list, free);
1501         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1502     }
1503
1504     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1505     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1506
1507     *reply_body = g_variant_new("(a(i))", id_builder);
1508     if (*reply_body == NULL) {
1509         LOGE("Failed to create reply_body");
1510         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1511     }
1512
1513     if (id_list)
1514         g_list_free_full(id_list, free);
1515
1516     if (id_builder)
1517         g_variant_builder_unref(id_builder);
1518
1519     return ret;
1520 }
1521
1522 int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
1523 {
1524     int ret;
1525     GList *id_list = NULL;
1526     char *app_id = NULL;
1527     char *group = NULL;
1528     int offset, count;
1529     GVariantBuilder *id_builder = NULL;
1530
1531     g_variant_get(parameters, "(&s&sii)", &app_id, &group, &offset, &count);
1532
1533     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, app_id, offset, count);
1534     if (ret != STICKERD_SERVER_ERROR_NONE) {
1535         LOGE("Failed to get all sticker id");
1536         if(id_list)
1537             g_list_free_full(id_list, free);
1538         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1539     }
1540
1541     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1542     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1543
1544     *reply_body = g_variant_new("(a(i))", id_builder);
1545     if (*reply_body == NULL) {
1546         LOGE("Failed to create reply_body");
1547         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1548     }
1549
1550     if (id_list)
1551         g_list_free_full(id_list, free);
1552
1553     if (id_builder)
1554         g_variant_builder_unref(id_builder);
1555
1556     return ret;
1557 }
1558
1559 int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
1560 {
1561     int ret;
1562     GList *id_list = NULL;
1563     char *app_id = NULL;
1564     char *keyword = NULL;
1565     int offset, count;
1566     GVariantBuilder *id_builder = NULL;
1567
1568     g_variant_get(parameters, "(&s&sii)", &app_id, &keyword, &offset, &count);
1569
1570     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, app_id, offset, count);
1571     if (ret != STICKERD_SERVER_ERROR_NONE) {
1572         LOGE("Failed to get all sticker id");
1573         if(id_list)
1574             g_list_free_full(id_list, free);
1575         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1576     }
1577
1578     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1579     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1580
1581     *reply_body = g_variant_new("(a(i))", id_builder);
1582     if (*reply_body == NULL) {
1583         LOGE("Failed to create reply_body");
1584         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1585     }
1586
1587     if (id_list)
1588         g_list_free_full(id_list, free);
1589
1590     if (id_builder)
1591         g_variant_builder_unref(id_builder);
1592
1593     return ret;
1594 }
1595
1596 int stickerd_get_sticker_info_by_display_type(GVariant *parameters, GVariant **reply_body)
1597 {
1598     int ret;
1599     GList *id_list = NULL;
1600     char *app_id = NULL;
1601     int type, offset, count;
1602     GVariantBuilder *id_builder = NULL;
1603
1604     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1605
1606     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_DISP_TYPE, &id_list, &type, app_id, offset, count);
1607     if (ret != STICKERD_SERVER_ERROR_NONE) {
1608         LOGE("Failed to get all sticker id");
1609         if(id_list)
1610             g_list_free_full(id_list, free);
1611         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1612     }
1613
1614     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1615     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1616
1617     *reply_body = g_variant_new("(a(i))", id_builder);
1618     if (*reply_body == NULL) {
1619         LOGE("Failed to create reply_body");
1620         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1621     }
1622
1623     if (id_list)
1624         g_list_free_full(id_list, free);
1625
1626     if (id_builder)
1627         g_variant_builder_unref(id_builder);
1628
1629     return ret;
1630 }
1631
1632 int stickerd_get_group_list_by_disp_type(GVariant *parameters, GVariant **reply_body)
1633 {
1634     int ret;
1635     GVariantBuilder *builder = NULL;
1636     char *app_id = NULL;
1637     int disp_type;
1638
1639     g_variant_get(parameters, "(&si)", &app_id, &disp_type);
1640
1641     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1642     ret = stickerd_db_get_group_list_by_display_type(builder, app_id, disp_type);
1643     if (ret != STICKERD_SERVER_ERROR_NONE) {
1644         LOGE("Failed to get sticker group list");
1645         g_variant_builder_unref(builder);
1646         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1647     }
1648
1649     *reply_body = g_variant_new("(a(s))", builder);
1650     g_variant_builder_unref(builder);
1651
1652     if (*reply_body == NULL) {
1653         LOGE("Failed to create reply_body");
1654         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1655     }
1656
1657     return ret;
1658 }
1659
1660 int stickerd_update_sticker_disp_type(GVariant *parameters, GVariant **reply_body)
1661 {
1662     int ret;
1663     int record_id;
1664     int disp_type;
1665
1666     *reply_body = g_variant_new("()");
1667     if (*reply_body == NULL) {
1668         LOGE("Failed to create reply_body");
1669         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1670     }
1671
1672     g_variant_get(parameters, "(ii)", &record_id, &disp_type);
1673
1674     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DISP_TYPE, &disp_type);
1675     if (ret != STICKERD_SERVER_ERROR_NONE) {
1676         LOGE("Failed to update sticker disp_type");
1677         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1678     }
1679
1680     return ret;
1681 }
1682
1683 int stickerd_check_file_exists(GVariant *parameters, GVariant **reply_body)
1684 {
1685     int ret;
1686     int result;
1687     char *uri = NULL;
1688
1689     g_variant_get(parameters, "(&s)", &uri);
1690
1691     ret = stickerd_db_check_file_exists(&result, uri);
1692     if (ret != STICKERD_SERVER_ERROR_NONE) {
1693         LOGE("Failed to get sticker count");
1694         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1695     }
1696
1697     *reply_body = g_variant_new("(i)", result);
1698     if (*reply_body == NULL) {
1699         LOGE("Failed to create reply_body");
1700         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1701     }
1702
1703     return ret;
1704 }
1705
1706 int stickerd_insert_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1707 {
1708     int ret;
1709     int record_id;
1710
1711     *reply_body = g_variant_new("()");
1712     if (*reply_body == NULL) {
1713         LOGE("Failed to create reply_body");
1714         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1715     }
1716
1717     g_variant_get(parameters, "(i)", &record_id);
1718
1719     ret = stickerd_db_insert_recent_sticker_info(record_id);
1720     if (ret != STICKERD_SERVER_ERROR_NONE) {
1721         LOGE("Failed to insert recent sticker info");
1722         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1723     }
1724
1725     return ret;
1726 }
1727
1728 int stickerd_get_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1729 {
1730     int ret;
1731     int count;
1732     GList *id_list = NULL;
1733     GVariantBuilder *id_builder = NULL;
1734
1735     g_variant_get(parameters, "(i)", &count);
1736
1737     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_RECENT_HISTORY, &id_list, NULL, NULL, 0, count);
1738     if (ret != STICKERD_SERVER_ERROR_NONE) {
1739         LOGE("Failed to get recent sticker id");
1740         if(id_list)
1741             g_list_free_full(id_list, free);
1742         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1743     }
1744
1745     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1746     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1747
1748     *reply_body = g_variant_new("(a(i))", id_builder);
1749     if (*reply_body == NULL) {
1750         LOGE("Failed to create reply_body");
1751         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1752     }
1753
1754     if (id_list)
1755         g_list_free_full(id_list, free);
1756
1757     if (id_builder)
1758         g_variant_builder_unref(id_builder);
1759
1760     return ret;
1761 }
1762
1763 int stickerd_send_update_event(GVariant *parameters, GVariant **reply_body)
1764 {
1765     int ret = STICKERD_SERVER_ERROR_NONE;
1766     int record_id;
1767
1768     *reply_body = g_variant_new("()");
1769     if (*reply_body == NULL) {
1770         LOGE("Failed to create reply_body");
1771         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1772     }
1773
1774     g_variant_get(parameters, "(i)", &record_id);
1775
1776     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1777     if (sticker_info) {
1778         ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1779         if (ret == STICKERD_SERVER_ERROR_NONE)
1780             _send_sticker_changed_event(STICKER_EVENT_TYPE_UPDATE, sticker_info);
1781
1782         _free_sticker_data(sticker_info);
1783         sticker_info = NULL;
1784     }
1785
1786     return ret;
1787 }
1788
1789 int stickerd_get_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
1790 {
1791     int ret;
1792     char *uri = NULL;
1793     GVariantBuilder *info_builder;
1794     GVariantBuilder *keyword_builder;
1795
1796     g_variant_get(parameters, "(&s)", &uri);
1797
1798     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1799
1800     if (!sticker_info)
1801         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1802
1803     ret = stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1804     if (ret != STICKERD_SERVER_ERROR_NONE) {
1805         LOGE("Failed to get sticker info");
1806         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1807         goto cleanup;
1808     }
1809
1810     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1811     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(sticker_info->record_id));
1812     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1813     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1814     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1815     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1816     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1817     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1818     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1819     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1820
1821     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1822     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1823
1824     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1825     g_variant_builder_unref(info_builder);
1826     g_variant_builder_unref(keyword_builder);
1827
1828     if (*reply_body == NULL) {
1829         LOGE("Failed to create reply_body");
1830         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1831     }
1832
1833 cleanup:
1834     if (sticker_info) {
1835         _free_sticker_data(sticker_info);
1836         sticker_info = NULL;
1837     }
1838
1839     return ret;
1840 }