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