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