Terminate sticker-receiver after sending result
[platform/core/uifw/capi-ui-sticker.git] / server / stickerd_data_manager.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <tzplatform_config.h>
21 #include <gio/gunixfdlist.h>
22 #include <dlog.h>
23 #include <json-glib/json-glib.h>
24 #include <package_manager.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <dirent.h>
29 #include <fcntl.h>
30
31 #include "stickerd_dbus.h"
32 #include "stickerd_data_manager.h"
33 #include "stickerd_db_manager.h"
34 #include "sticker_defs.h"
35 #include "stickerd_error.h"
36
37 #ifdef LOG_TAG
38 #undef LOG_TAG
39 #endif
40 #define LOG_TAG "STICKERD_DATA_MANAGER"
41
42 #define STICKER_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "sticker-data")
43 #define MAX_ERROR_BUFFER  256
44
45 static GHashTable *_monitoring_hash = NULL;
46 static char error_buffer[MAX_ERROR_BUFFER];
47 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_main_loop_quit(main_loop);
56     }
57 }
58
59 static void _on_name_appeared(GDBusConnection *connection,
60         const gchar     *name,
61         const gchar     *name_owner,
62         gpointer         user_data)
63 {
64     LOGD("name: %s", name);
65 }
66
67 static void _on_name_vanished(GDBusConnection *connection,
68         const gchar     *name,
69         gpointer         user_data)
70 {
71     monitoring_info_s *info = (monitoring_info_s *)user_data;
72
73     if (info) {
74         if (_monitoring_hash != NULL && g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(info->watcher_id)) != NULL) {
75             LOGD("name: %s", name);
76             g_bus_unwatch_name(info->watcher_id);
77             delete_monitoring_list(&_monitoring_hash, info->bus_name, info->watcher_id);
78         }
79
80         if (info->bus_name)
81             free(info->bus_name);
82         free(info);
83         info = NULL;
84     }
85
86     _check_watcher_exist();
87 }
88
89 static void _stickerd_client_dbus_method_call_handler(GDBusConnection *conn, const gchar *sender, const gchar *object_path,
90         const gchar *iface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation,
91         gpointer user_data)
92 {
93     LOGD("stickerd method_name: %s, sender: %s", method_name, sender);
94
95     if (_monitoring_hash == NULL)
96         _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
97
98     GVariant *reply_body = NULL;
99     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
100
101     if (g_strcmp0(method_name, "sticker_service_register") == 0) {
102         ret = stickerd_server_register(parameters, &reply_body, sender,
103             _on_name_appeared, _on_name_vanished, &_monitoring_hash);
104     } else if (g_strcmp0(method_name, "sticker_service_unregister") == 0) {
105         ret = stickerd_server_unregister(parameters, &reply_body, sender, &_monitoring_hash);
106     } else if (g_strcmp0(method_name, "insert_sticker_info") == 0) {
107         ret = stickerd_insert_sticker_info(parameters, &reply_body);
108     } else if  (g_strcmp0(method_name, "update_sticker_info_by_json") == 0) {
109         ret = stickerd_insert_sticker_info_by_json(parameters, &reply_body, sender);
110     } else if (g_strcmp0(method_name, "delete_sticker_info") == 0) {
111         ret = stickerd_del_sticker_info(parameters, &reply_body);
112     } else if (g_strcmp0(method_name, "update_sticker_type") == 0) {
113         ret = stickerd_update_sticker_type(parameters, &reply_body);
114     } else if (g_strcmp0(method_name, "update_sticker_uri") == 0) {
115         ret = stickerd_update_sticker_uri(parameters, &reply_body);
116     } else if (g_strcmp0(method_name, "update_sticker_thumbnail") == 0) {
117         ret = stickerd_update_sticker_thumbnail(parameters, &reply_body);
118     } else if (g_strcmp0(method_name, "update_sticker_description") == 0) {
119         ret = stickerd_update_sticker_description(parameters, &reply_body);
120     } else if (g_strcmp0(method_name, "update_sticker_group") == 0) {
121         ret = stickerd_update_sticker_group(parameters, &reply_body);
122     } else if (g_strcmp0(method_name, "update_sticker_keyword") == 0) {
123         ret = stickerd_update_sticker_keyword(parameters, &reply_body);
124     } else if (g_strcmp0(method_name, "get_sticker_info") == 0) {
125         ret = stickerd_get_sticker_info(parameters, &reply_body);
126     } else if (g_strcmp0(method_name, "get_group_list") == 0) {
127         ret = stickerd_get_group_list(parameters, &reply_body);
128     } else if (g_strcmp0(method_name, "get_keyword_list") == 0) {
129         ret = stickerd_get_keyword_list(parameters, &reply_body);
130     } else if (g_strcmp0(method_name, "get_sticker_count") == 0) {
131         ret = stickerd_get_sticker_count(parameters, &reply_body);
132     } else if (g_strcmp0(method_name, "get_all_sticker_info") == 0) {
133         ret = stickerd_get_all_sticker_info(parameters, &reply_body);
134     } else if (g_strcmp0(method_name, "get_sticker_info_by_appid") == 0) {
135         ret = stickerd_get_sticker_info_by_app_id(parameters, &reply_body);
136     } else if (g_strcmp0(method_name, "get_sticker_info_by_type") == 0) {
137         ret = stickerd_get_sticker_info_by_type(parameters, &reply_body);
138     } else if (g_strcmp0(method_name, "get_sticker_info_by_group") == 0) {
139         ret = stickerd_get_sticker_info_by_group(parameters, &reply_body);
140     } else if (g_strcmp0(method_name, "get_sticker_info_by_keyword") == 0) {
141         ret = stickerd_get_sticker_info_by_keyword(parameters, &reply_body);
142     }
143
144     if (ret == STICKERD_SERVER_ERROR_NONE) {
145         LOGD("method_call successful, method_name : %s", method_name);
146         g_dbus_method_invocation_return_value(invocation, reply_body);
147     } else {
148         LOGE("method_call failed, method_name : %s", method_name);
149         g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "sticker error");
150     }
151
152     _check_watcher_exist();
153 }
154
155 static const GDBusInterfaceVTable _sticker_interface_vtable = {
156         _stickerd_client_dbus_method_call_handler,
157         NULL,
158         NULL
159 };
160
161 int stickerd_register_dbus_interface(void)
162 {
163     static gchar introspection_xml[] =
164             "  <node>"
165             "  <interface name='org.tizen.sticker_service'>"
166             "        <method name='sticker_service_register'>"
167             "          <arg type='i' name='watcher_id' direction='out'/>"
168             "        </method>"
169
170             "        <method name='sticker_service_unregister'>"
171             "          <arg type='i' name='watcher_id' direction='in'/>"
172             "        </method>"
173
174             "        <method name='insert_sticker_info'>"
175             "          <arg type='a{iv}' name='sticker_info' direction='in'/>"
176             "          <arg type='a(s)' name='keyword_list' direction='in'/>"
177             "          <arg type='i' name='record_id' direction='out'/>"
178             "        </method>"
179
180             "        <method name='update_sticker_info_by_json'>"
181             "          <arg type='s' name='app_id' direction='in'/>"
182             "          <arg type='s' name='json_path' direction='in'/>"
183             "        </method>"
184
185             "        <method name='delete_sticker_info'>"
186             "          <arg type='i' name='record_id' direction='in'/>"
187             "        </method>"
188
189             "        <method name='update_sticker_type'>"
190             "          <arg type='i' name='record_id' direction='in'/>"
191             "          <arg type='i' name='type' direction='in'/>"
192             "        </method>"
193
194             "        <method name='update_sticker_uri'>"
195             "          <arg type='i' name='record_id' direction='in'/>"
196             "          <arg type='s' name='app_id' direction='in'/>"
197             "          <arg type='i' name='type' direction='in'/>"
198             "          <arg type='s' name='uri' direction='in'/>"
199             "        </method>"
200
201             "        <method name='update_sticker_thumbnail'>"
202             "          <arg type='i' name='record_id' direction='in'/>"
203             "          <arg type='s' name='thumbnail' direction='in'/>"
204             "        </method>"
205
206             "        <method name='update_sticker_description'>"
207             "          <arg type='i' name='record_id' direction='in'/>"
208             "          <arg type='s' name='description' direction='in'/>"
209             "        </method>"
210
211             "        <method name='update_sticker_group'>"
212             "          <arg type='i' name='record_id' direction='in'/>"
213             "          <arg type='s' name='group' direction='in'/>"
214             "        </method>"
215
216             "        <method name='update_sticker_keyword'>"
217             "          <arg type='i' name='record_id' direction='in'/>"
218             "          <arg type='a(s)' name='keyword' direction='in'/>"
219             "        </method>"
220
221             "        <method name='get_sticker_info'>"
222             "          <arg type='i' name='record_id' direction='in'/>"
223             "          <arg type='a{iv}' name='sticker_info' direction='out'/>"
224             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
225             "        </method>"
226
227             "        <method name='get_group_list'>"
228             "          <arg type='s' name='app_id' direction='in'/>"
229             "          <arg type='a(s)' name='group_list' direction='out'/>"
230             "        </method>"
231
232             "        <method name='get_keyword_list'>"
233             "          <arg type='s' name='app_id' direction='in'/>"
234             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
235             "        </method>"
236
237             "        <method name='get_sticker_count'>"
238             "          <arg type='s' name='app_id' direction='in'/>"
239             "          <arg type='i' name='count' direction='out'/>"
240             "        </method>"
241
242             "        <method name='get_all_sticker_info'>"
243             "          <arg type='s' name='app_id' direction='in'/>"
244             "          <arg type='i' name='offset' direction='in'/>"
245             "          <arg type='i' name='count' direction='in'/>"
246             "          <arg type='a(i)' name='id_list' direction='out'/>"
247             "        </method>"
248
249             "        <method name='get_sticker_info_by_appid'>"
250             "          <arg type='s' name='app_id' direction='in'/>"
251             "          <arg type='i' name='offset' direction='in'/>"
252             "          <arg type='i' name='count' direction='in'/>"
253             "          <arg type='a(i)' name='id_list' direction='out'/>"
254             "        </method>"
255
256             "        <method name='get_sticker_info_by_type'>"
257             "          <arg type='s' name='app_id' direction='in'/>"
258             "          <arg type='i' name='type' direction='in'/>"
259             "          <arg type='i' name='offset' direction='in'/>"
260             "          <arg type='i' name='count' direction='in'/>"
261             "          <arg type='a(i)' name='id_list' direction='out'/>"
262             "        </method>"
263
264             "        <method name='get_sticker_info_by_group'>"
265             "          <arg type='s' name='app_id' direction='in'/>"
266             "          <arg type='s' name='group' direction='in'/>"
267             "          <arg type='i' name='offset' direction='in'/>"
268             "          <arg type='i' name='count' direction='in'/>"
269             "          <arg type='a(i)' name='id_list' direction='out'/>"
270             "        </method>"
271
272             "        <method name='get_sticker_info_by_keyword'>"
273             "          <arg type='s' name='app_id' direction='in'/>"
274             "          <arg type='s' name='keyword' direction='in'/>"
275             "          <arg type='i' name='offset' direction='in'/>"
276             "          <arg type='i' name='count' direction='in'/>"
277             "          <arg type='a(i)' name='id_list' direction='out'/>"
278             "        </method>"
279             "  </interface>"
280             "  </node>";
281
282     return stickerd_server_register_dbus_interface(introspection_xml, _sticker_interface_vtable);
283 }
284
285 int stickerd_dbus_init(void)
286 {
287     int ret;
288
289     ret = stickerd_register_dbus_interface();
290     if (ret != STICKERD_SERVER_ERROR_NONE) {
291         LOGE("Failed to register dbus interface : %d", ret);
292         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
293     }
294
295     return STICKERD_SERVER_ERROR_NONE;
296 }
297
298 static int _check_file_exist(const char *app_id, const char *path)
299 {
300     int ret = 0;
301     package_info_h package_info = NULL;
302     char *app_path = NULL;
303     char *file_path = NULL;
304
305     if (access(path, F_OK) == 0) {
306         ret = 0;
307         goto cleanup;
308     }
309
310     ret = package_info_create(app_id, &package_info);
311     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
312         LOGE("failed to create package_info. ret: %d", ret);
313         ret = -1;
314         goto cleanup;
315     }
316
317     ret = package_info_get_root_path(package_info, &app_path);
318     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
319         LOGE("failed to create package_info. ret: %d", ret);
320         ret = -1;
321         goto cleanup;
322     }
323
324     int path_len = strlen(app_path) + strlen(path) + 2;
325     file_path = (char *)calloc(path_len, sizeof(char));
326     if (!file_path) {
327         LOGE("Failed to alloc memory");
328         ret = -1;
329         goto cleanup;
330     }
331
332     if(path[0] == '/')
333         snprintf(file_path, path_len, "%s%s",app_path, path);
334     else
335         snprintf(file_path, path_len, "%s%s%s",app_path, "/", path);
336
337     if (access(file_path, F_OK) != 0) {
338         LOGE("%s does not exist", file_path);
339         ret = -1;
340     } else
341         ret = 0;
342
343 cleanup:
344     if (package_info)
345         package_info_destroy(package_info);
346
347     if (app_path) {
348         free(app_path);
349         app_path = NULL;
350     }
351
352     if (file_path) {
353         free(file_path);
354         file_path = NULL;
355     }
356
357     return ret;
358 }
359
360 static int _mkdirs(const char *path, mode_t mode)
361 {
362     int len = 0;
363     char prev_path[2048];
364     const char *tmp = path;
365
366     if (!path || strlen(path) > 2048)
367         return -1;
368
369     memset(prev_path, '\0', 2048);
370     while ((tmp = strchr(tmp, '/')) != NULL) {
371         len = tmp - path;
372         tmp++;
373
374         if (len == 0)
375             continue;
376
377         strncpy(prev_path, path, len);
378         prev_path[len] = 0x00;
379
380         if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
381             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
382             LOGE("directory create error : %s", error_buffer);
383             return -1;
384         }
385     }
386
387     if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
388         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
389         LOGE("directory create error : %s", error_buffer);
390         return -1;
391     }
392
393     return 0;
394 }
395
396 static int _file_copy(const char *src, const char *dest)
397 {
398     int ret = 0;
399     int fd = -1, n_fd = -1;
400     char buf[4096];
401     int tmp_err = 0;
402     int size;
403
404     memset(buf, '\0', 4096);
405     fd = open(src, O_RDONLY);
406     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
407
408     if (fd == -1 || n_fd == -1) {
409         tmp_err = errno;
410         ret = -1;
411         goto cleanup;
412     }
413
414     while((size = read(fd, buf, 4096))) {
415         if (size == -1) {
416             if(errno == EINTR)
417                 continue;
418
419             tmp_err = errno;
420             ret = -1;
421             goto cleanup;
422         }
423
424         while(write(n_fd, buf, size) == -1) {
425             if(errno == EINTR) {
426                 continue;
427             } else {
428                 tmp_err = errno;
429                 goto cleanup;
430             }
431         }
432     }
433
434 cleanup:
435     if (fd != -1)
436         close(fd);
437
438     if (n_fd != -1)
439         close(n_fd);
440
441     errno = tmp_err;
442     return ret;
443 }
444
445 static char* _convert_sticker_uri(const char *uri, const char *appid)
446 {
447     int ret;
448     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
449     char * new_path = (char *)calloc(len, sizeof(char));
450     if (new_path == NULL) {
451         LOGE("Failed to alloc memory");
452         return NULL;
453     }
454
455     if (uri[0] == '/')
456         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
457     else
458         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
459
460     if (access(new_path, F_OK) == 0) {
461         LOGE("sticker file already exists");
462         ret = -1;
463         goto cleanup;
464     }
465
466     ret = _mkdirs(new_path, 0755);
467     if (ret != 0) {
468         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
469         LOGE("directory create error : %s", error_buffer);
470         goto cleanup;
471     }
472
473     ret = _file_copy(uri, new_path);
474     if (ret != 0) {
475         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
476         LOGE("failed to copy sticker file : %s", error_buffer);
477     }
478
479 cleanup:
480     if (ret == 0) {
481         return new_path;
482     } else {
483         free(new_path);
484         new_path = NULL;
485         return NULL;
486     }
487 }
488
489 int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
490 {
491     int ret;
492     int record_id = 0;
493     STICKER_DAT_TYPE key;
494     sticker_info_db *sticker_info = NULL;
495     GVariant *value = NULL;
496     GVariantIter *info_iter = NULL;
497     GVariantIter *keyword_iter = NULL;
498     char *keyword;
499
500     g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
501     if (!info_iter || !keyword_iter) {
502         LOGD("failed to get iter");
503         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
504         goto cleanup;
505     }
506
507     sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
508
509     if (!sticker_info) {
510         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
511         goto cleanup;
512     }
513
514     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
515         switch(key) {
516             case STICKER_DATA_TYPE_APP_ID:
517             sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
518             break;
519             case STICKER_DATA_TYPE_URI_TYPE:
520             sticker_info->type = g_variant_get_int32(value);
521             break;
522             case STICKER_DATA_TYPE_URI:
523             sticker_info->uri = (char *) g_variant_get_string(value, NULL);
524             break;
525             case STICKER_DATA_TYPE_THUMBNAIL:
526             sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
527             break;
528             case STICKER_DATA_TYPE_DESCRIPTION:
529             sticker_info->description = (char *) g_variant_get_string(value, NULL);
530             break;
531             case STICKER_DATA_TYPE_GROUP:
532             sticker_info->group = (char *) g_variant_get_string(value, NULL);
533             break;
534             default:
535             break;
536         }
537     }
538
539     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
540         sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
541     }
542
543     if (sticker_info->type == 1) {
544         if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
545             sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
546             if (!sticker_info->uri) {
547                 LOGE("failed to copy sticker file");
548                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
549                 goto cleanup;
550             }
551         } else {
552             LOGE("sticker file does not exist");
553             ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
554             goto cleanup;
555         }
556     }
557
558     ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
559     if (ret != STICKERD_SERVER_ERROR_NONE) {
560         LOGE("Failed to insert sticker info");
561         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
562         goto cleanup;
563     }
564
565     *reply_body = g_variant_new("(i)", record_id);
566     if (*reply_body == NULL) {
567         LOGE("Failed to create reply_body");
568         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
569     }
570
571 cleanup:
572     if (value)
573         g_variant_unref(value);
574
575     if (info_iter)
576         g_variant_iter_free(info_iter);
577
578     if (keyword_iter)
579         g_variant_iter_free(keyword_iter);
580
581     if (sticker_info) {
582         free(sticker_info);
583         sticker_info = NULL;
584     }
585
586     return ret;
587 }
588
589 static char* _get_string_from_object(JsonObject *object, const char *key)
590 {
591     if (json_object_has_member(object, key) == false)
592         return NULL;
593
594     const char *str = json_object_get_string_member(object, key);
595     if (str != NULL)
596         return strdup(str);
597     else
598         return NULL;
599 }
600
601 static int _get_int_from_object(JsonObject *object, const char *key)
602 {
603     if (json_object_has_member(object, key) == false)
604         return -1;
605
606     int type = json_object_get_int_member(object, key);
607
608     return type;
609 }
610
611 int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
612 {
613     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
614     int record_id;
615     sticker_info_db *sticker_info = NULL;
616     char *app_id = NULL;
617     char *json_path = NULL;
618     JsonParser* parser = NULL;
619     GError* err_msg = NULL;
620     GVariant *body = NULL;
621     char *cmd = "send_insert_result";
622
623     *reply_body = g_variant_new("()");
624         if (*reply_body == NULL) {
625         LOGE("Failed to create reply_body");
626         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
627     }
628
629     g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
630
631     if (!app_id || !json_path) {
632         LOGE("failed to get parameter");
633         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
634     }
635
636     SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
637
638     parser = json_parser_new();
639     json_parser_load_from_file(parser, json_path, &err_msg);
640     if (err_msg) {
641         LOGE("failed to load json file. error message: %s", err_msg->message);
642         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
643         goto cleanup;
644     }
645
646     JsonNode *root = json_parser_get_root(parser);
647     if (root == NULL) {
648         LOGE("failed to get root");
649         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
650         goto cleanup;
651     }
652
653     JsonObject *root_obj = json_node_get_object(root);
654     if (root_obj == NULL) {
655         LOGE("failed to get object");
656         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
657         goto cleanup;
658     }
659
660     JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
661     if (sticker_arr == NULL) {
662         LOGE("failed to get array member");
663         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
664         goto cleanup;
665     }
666
667     int arr_len = json_array_get_length(sticker_arr);
668     for (int i = 0; i < arr_len; i++) {
669         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
670         if (info_object != NULL) {
671             sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
672             if (!sticker_info) {
673                 LOGE("Failed to alloc memory");
674                 continue;
675             }
676
677             sticker_info->app_id = app_id;
678             sticker_info->type = _get_int_from_object(info_object, "type");
679             if (sticker_info->type < 1)
680                 goto free_memory;
681
682             sticker_info->uri = _get_string_from_object(info_object, "uri");
683             if (!sticker_info->uri)
684                 goto free_memory;
685
686             if (sticker_info->type == 1) {
687                 if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
688                     sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
689                     if (!sticker_info->uri)
690                         goto free_memory;
691                 }
692             }
693
694             sticker_info->group = _get_string_from_object(info_object, "group");
695             if (!sticker_info->group)
696                 goto free_memory;
697
698             sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
699             if (!sticker_info->thumbnail)
700                 goto free_memory;
701
702             sticker_info->description = _get_string_from_object(info_object, "description");
703
704             JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
705             int keyword_arr_len = json_array_get_length(keyword_arr);
706             if (keyword_arr_len < 1)
707                 goto free_memory;
708
709             for (int j = 0; j < keyword_arr_len; j++) {
710                 sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)json_array_get_string_element(keyword_arr, j)));
711             }
712
713             ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
714             if (ret != STICKERD_SERVER_ERROR_NONE) {
715                 LOGE("Failed to insert sticker info");
716                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
717             }
718
719 free_memory:
720             free(sticker_info);
721             sticker_info = NULL;
722         }
723     }
724
725 cleanup:
726     if (err_msg)
727         g_error_free(err_msg);
728     if (parser)
729         g_object_unref(parser);
730
731     body = g_variant_new("(i)", ret);
732
733     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
734     if (ret != STICKERD_SERVER_ERROR_NONE)
735         LOGE("Failed to send insert result to client");
736
737     if(body)
738         g_variant_unref(body);
739
740     return ret;
741 }
742
743 int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
744 {
745     int ret;
746     int record_id;
747
748     *reply_body = g_variant_new("()");
749     if (*reply_body == NULL) {
750         LOGE("Failed to create reply_body");
751         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
752     }
753
754     g_variant_get(parameters, "(i)", &record_id);
755
756     ret = stickerd_db_delete_sticker_info(record_id);
757     if (ret != STICKERD_SERVER_ERROR_NONE) {
758         LOGE("Failed to delete sticker info");
759         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
760     }
761
762     return ret;
763 }
764
765 int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
766 {
767     int ret;
768     int record_id;
769     int type;
770
771     *reply_body = g_variant_new("()");
772     if (*reply_body == NULL) {
773         LOGE("Failed to create reply_body");
774         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
775     }
776
777     g_variant_get(parameters, "(ii)", &record_id, &type);
778
779     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
780     if (ret != STICKERD_SERVER_ERROR_NONE) {
781         LOGE("Failed to update sticker type");
782         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
783     }
784
785     return ret;
786 }
787
788 int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
789 {
790     int ret;
791     int record_id;
792     int type;
793     char *app_id;
794     char *uri;
795
796     *reply_body = g_variant_new("()");
797     if (*reply_body == NULL) {
798         LOGE("Failed to create reply_body");
799         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
800     }
801
802     g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
803
804     if (type == 1) {
805         if (_check_file_exist(app_id, uri) == 0) {
806             uri = _convert_sticker_uri(uri, app_id);
807             if (!uri) {
808                 LOGE("failed to copy sticker file");
809                 return STICKERD_SERVER_ERROR_OPERATION_FAILED;
810             }
811         }
812     }
813
814     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
815     if (ret != STICKERD_SERVER_ERROR_NONE) {
816         LOGE("Failed to update sticker uri");
817         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
818     }
819
820     return ret;
821 }
822
823 int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
824 {
825     int ret;
826     int record_id;
827     char *thumbnail;
828
829     *reply_body = g_variant_new("()");
830     if (*reply_body == NULL) {
831         LOGE("Failed to create reply_body");
832         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
833     }
834
835     g_variant_get(parameters, "(i&s)", &record_id, &thumbnail);
836
837     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
838     if (ret != STICKERD_SERVER_ERROR_NONE) {
839         LOGE("Failed to update sticker thumbnail");
840         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
841     }
842
843     return ret;
844 }
845
846 int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
847 {
848     int ret;
849     int record_id;
850     char *description;
851
852     *reply_body = g_variant_new("()");
853     if (*reply_body == NULL) {
854         LOGE("Failed to create reply_body");
855         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
856     }
857
858     g_variant_get(parameters, "(i&s)", &record_id, &description);
859
860     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
861     if (ret != STICKERD_SERVER_ERROR_NONE) {
862         LOGE("Failed to update sticker description");
863         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
864     }
865
866     return ret;
867 }
868
869 int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
870 {
871     int ret;
872     int record_id;
873     char *group;
874
875     *reply_body = g_variant_new("()");
876     if (*reply_body == NULL) {
877         LOGE("Failed to create reply_body");
878         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
879     }
880
881     g_variant_get(parameters, "(i&s)", &record_id, &group);
882
883     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
884     if (ret != STICKERD_SERVER_ERROR_NONE) {
885         LOGE("Failed to update sticker group");
886         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
887     }
888
889     return ret;
890 }
891
892 int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
893 {
894     int ret;
895     int record_id;
896     GVariantIter *keyword_iter = NULL;
897     char *keyword = NULL;
898     GList *keyword_list = NULL;
899
900     *reply_body = g_variant_new("()");
901     if (*reply_body == NULL) {
902         LOGE("Failed to create reply_body");
903         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
904     }
905
906     g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
907
908     if (!keyword_iter) {
909         LOGD("failed to get iter");
910         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
911     }
912
913     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
914         keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
915     }
916
917     g_variant_iter_free(keyword_iter);
918
919     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
920     if (ret != STICKERD_SERVER_ERROR_NONE) {
921         LOGE("Failed to update sticker keyword");
922         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
923     }
924
925     return ret;
926 }
927
928 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
929 {
930     if (!keyword) {
931         LOGE("keyword doesn't exist");
932         return;
933     }
934
935     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
936 }
937
938 int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
939 {
940     int ret;
941     int record_id;
942     GVariantBuilder *info_builder;
943     GVariantBuilder *keyword_builder;
944
945     g_variant_get(parameters, "(i)", &record_id);
946     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
947
948     if (!sticker_info)
949         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
950
951     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
952     if (ret != STICKERD_SERVER_ERROR_NONE) {
953         LOGE("Failed to get sticker info");
954
955         if (sticker_info->app_id)
956             free(sticker_info->app_id);
957
958         if (sticker_info->uri)
959             free(sticker_info->uri);
960
961         if (sticker_info->thumbnail)
962             free(sticker_info->thumbnail);
963
964         if (sticker_info->keyword)
965             free(sticker_info->keyword);
966
967         if (sticker_info->group)
968             free(sticker_info->group);
969
970         if (sticker_info->description)
971             free(sticker_info->description);
972
973         if (sticker_info->date)
974             free(sticker_info->date);
975
976         free(sticker_info);
977         sticker_info = NULL;
978         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
979     }
980
981     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
982     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
983     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
984     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
985     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
986     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
987     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
988     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
989
990     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
991     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
992
993     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
994     g_variant_builder_unref(info_builder);
995     g_variant_builder_unref(keyword_builder);
996
997     if (*reply_body == NULL) {
998         LOGE("Failed to create reply_body");
999         free(sticker_info);
1000         sticker_info = NULL;
1001         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1002     }
1003
1004     free(sticker_info);
1005     sticker_info = NULL;
1006     return ret;
1007 }
1008
1009 int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
1010 {
1011     int ret;
1012     GVariantBuilder *builder = NULL;
1013     char *app_id = NULL;
1014
1015     g_variant_get(parameters, "(&s)", &app_id);
1016
1017     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1018     ret = stickerd_db_get_group_list(builder, app_id);
1019     if (ret != STICKERD_SERVER_ERROR_NONE) {
1020         LOGE("Failed to get sticker group list");
1021         g_variant_builder_unref(builder);
1022         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1023     }
1024
1025     *reply_body = g_variant_new("(a(s))", builder);
1026     g_variant_builder_unref(builder);
1027
1028     if (*reply_body == NULL) {
1029         LOGE("Failed to create reply_body");
1030         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1031     }
1032
1033     return ret;
1034 }
1035
1036 int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
1037 {
1038     int ret;
1039     GVariantBuilder *builder = NULL;
1040     char *app_id = NULL;
1041
1042     g_variant_get(parameters, "(&s)", &app_id);
1043
1044     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1045     ret = stickerd_db_get_keyword_list(builder, app_id);
1046     if (ret != STICKERD_SERVER_ERROR_NONE) {
1047         LOGE("Failed to get sticker keyword list");
1048         g_variant_builder_unref(builder);
1049         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1050     }
1051
1052     *reply_body = g_variant_new("(a(s))", builder);
1053     g_variant_builder_unref(builder);
1054
1055     if (*reply_body == NULL) {
1056         LOGE("Failed to create reply_body");
1057         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1058     }
1059
1060     return ret;
1061 }
1062
1063 int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
1064 {
1065     int ret;
1066     int count;
1067     char *app_id = NULL;
1068
1069     g_variant_get(parameters, "(&s)", &app_id);
1070
1071     ret = stickerd_db_get_sticker_count(&count, app_id);
1072     if (ret != STICKERD_SERVER_ERROR_NONE) {
1073         LOGE("Failed to get sticker count");
1074         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1075     }
1076
1077     *reply_body = g_variant_new("(i)", count);
1078     if (*reply_body == NULL) {
1079         LOGE("Failed to create reply_body");
1080         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1081     }
1082
1083     return ret;
1084 }
1085
1086 #if 0
1087 // Send the sticker information by asynchronous communication.
1088 static int send_sticker_info_async(int record_id, sticker_info_db_type type, const char *sender)
1089 {
1090     int ret;
1091     char *cmd = NULL;
1092
1093     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1094
1095     if (!sticker_info)
1096         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1097
1098     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1099     if (ret != STICKERD_SERVER_ERROR_NONE) {
1100         LOGE("Failed to get sticker info");
1101         free(sticker_info);
1102         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1103     }
1104
1105     switch (type) {
1106         case STICKER_DB_STICKER_ALL:
1107         cmd = "send_all_sticker_info";
1108         break;
1109         case STICKER_DB_STICKER_APPID:
1110         cmd = "send_sticker_info_by_appid";
1111         break;
1112         case STICKER_DB_STICKER_TYPE:
1113         cmd = "send_sticker_info_by_type";
1114         break;
1115         case STICKER_DB_STICKER_GROUP:
1116         cmd = "send_sticker_info_by_group";
1117         break;
1118         case STICKER_DB_STICKER_KEYWORD:
1119         cmd = "send_sticker_info_by_keyword";
1120         break;
1121         default:
1122         cmd = "";
1123         break;
1124     }
1125
1126     GVariantBuilder *info_builder;
1127     GVariantBuilder *keyword_builder;
1128
1129     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1130     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(record_id));
1131     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1132     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1133     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1134     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1135     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1136     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1137     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1138
1139     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1140     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1141
1142     GVariant *body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1143     g_variant_builder_unref(info_builder);
1144     g_variant_builder_unref(keyword_builder);
1145
1146     ret = stickerd_send_dbus_message(body, sender, cmd);
1147     if (ret != STICKERD_SERVER_ERROR_NONE) {
1148         LOGE("Failed to send sticker info to client");
1149         free(sticker_info);
1150         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1151     }
1152
1153     free(sticker_info);
1154     return ret;
1155 }
1156 #endif
1157
1158 static void _set_id_builder(char *id, GVariantBuilder *id_builder)
1159 {
1160     if (!id) {
1161         LOGE("id doesn't exist");
1162         return;
1163     }
1164
1165     g_variant_builder_add(id_builder, "(i)", atoi(id));
1166 }
1167
1168 int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
1169 {
1170     int ret;
1171     int offset, count;
1172     char *app_id = NULL;
1173     GList *id_list = NULL;
1174     GVariantBuilder *id_builder = NULL;
1175
1176     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1177
1178     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, app_id, offset, count);
1179     if (ret != STICKERD_SERVER_ERROR_NONE) {
1180         LOGE("Failed to get all sticker id");
1181         if(id_list)
1182             g_list_free_full(id_list, free);
1183         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1184     }
1185
1186     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1187     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1188
1189     *reply_body = g_variant_new("(a(i))", id_builder);
1190     if (*reply_body == NULL) {
1191         LOGE("Failed to create reply_body");
1192         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1193     }
1194
1195     if (id_list)
1196         g_list_free_full(id_list, free);
1197
1198     if (id_builder)
1199         g_variant_builder_unref(id_builder);
1200
1201     return ret;
1202 }
1203
1204 int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
1205 {
1206     int ret;
1207     GList *id_list = NULL;
1208     char *app_id = NULL;
1209     int offset, count;
1210     GVariantBuilder *id_builder = NULL;
1211
1212     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1213
1214     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, NULL, app_id, offset, count);
1215     if (ret != STICKERD_SERVER_ERROR_NONE) {
1216         LOGE("Failed to get all sticker id");
1217         if(id_list)
1218             g_list_free_full(id_list, free);
1219         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1220     }
1221
1222     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1223     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1224
1225     *reply_body = g_variant_new("(a(i))", id_builder);
1226     if (*reply_body == NULL) {
1227         LOGE("Failed to create reply_body");
1228         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1229     }
1230
1231     if (id_list)
1232         g_list_free_full(id_list, free);
1233
1234     if (id_builder)
1235         g_variant_builder_unref(id_builder);
1236
1237     return ret;
1238 }
1239
1240 int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
1241 {
1242     int ret;
1243     GList *id_list = NULL;
1244     char *app_id = NULL;
1245     int type, offset, count;
1246     GVariantBuilder *id_builder = NULL;
1247
1248     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1249
1250     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, app_id, offset, count);
1251     if (ret != STICKERD_SERVER_ERROR_NONE) {
1252         LOGE("Failed to get all sticker id");
1253         if(id_list)
1254             g_list_free_full(id_list, free);
1255         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1256     }
1257
1258     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1259     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1260
1261     *reply_body = g_variant_new("(a(i))", id_builder);
1262     if (*reply_body == NULL) {
1263         LOGE("Failed to create reply_body");
1264         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1265     }
1266
1267     if (id_list)
1268         g_list_free_full(id_list, free);
1269
1270     if (id_builder)
1271         g_variant_builder_unref(id_builder);
1272
1273     return ret;
1274 }
1275
1276 int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
1277 {
1278     int ret;
1279     GList *id_list = NULL;
1280     char *app_id = NULL;
1281     char *group = NULL;
1282     int offset, count;
1283     GVariantBuilder *id_builder = NULL;
1284
1285     g_variant_get(parameters, "(&s&sii)", &app_id, &group, &offset, &count);
1286
1287     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, app_id, offset, count);
1288     if (ret != STICKERD_SERVER_ERROR_NONE) {
1289         LOGE("Failed to get all sticker id");
1290         if(id_list)
1291             g_list_free_full(id_list, free);
1292         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1293     }
1294
1295     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1296     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1297
1298     *reply_body = g_variant_new("(a(i))", id_builder);
1299     if (*reply_body == NULL) {
1300         LOGE("Failed to create reply_body");
1301         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1302     }
1303
1304     if (id_list)
1305         g_list_free_full(id_list, free);
1306
1307     if (id_builder)
1308         g_variant_builder_unref(id_builder);
1309
1310     return ret;
1311 }
1312
1313 int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
1314 {
1315     int ret;
1316     GList *id_list = NULL;
1317     char *app_id = NULL;
1318     char *keyword = NULL;
1319     int offset, count;
1320     GVariantBuilder *id_builder = NULL;
1321
1322     g_variant_get(parameters, "(&s&sii)", &app_id, &keyword, &offset, &count);
1323
1324     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, app_id, offset, count);
1325     if (ret != STICKERD_SERVER_ERROR_NONE) {
1326         LOGE("Failed to get all sticker id");
1327         if(id_list)
1328             g_list_free_full(id_list, free);
1329         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1330     }
1331
1332     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1333     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1334
1335     *reply_body = g_variant_new("(a(i))", id_builder);
1336     if (*reply_body == NULL) {
1337         LOGE("Failed to create reply_body");
1338         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1339     }
1340
1341     if (id_list)
1342         g_list_free_full(id_list, free);
1343
1344     if (id_builder)
1345         g_variant_builder_unref(id_builder);
1346
1347     return ret;
1348 }