Fix crash issue
[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='a(s)' name='group_list' direction='out'/>"
229             "        </method>"
230
231             "        <method name='get_keyword_list'>"
232             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
233             "        </method>"
234
235             "        <method name='get_sticker_count'>"
236             "          <arg type='s' name='app_id' direction='in'/>"
237             "          <arg type='i' name='count' direction='out'/>"
238             "        </method>"
239
240             "        <method name='get_all_sticker_info'>"
241             "          <arg type='i' name='offset' direction='in'/>"
242             "          <arg type='i' name='count' direction='in'/>"
243             "          <arg type='a(i)' name='id_list' direction='out'/>"
244             "        </method>"
245
246             "        <method name='get_sticker_info_by_appid'>"
247             "          <arg type='s' name='app_id' direction='in'/>"
248             "          <arg type='i' name='offset' direction='in'/>"
249             "          <arg type='i' name='count' direction='in'/>"
250             "          <arg type='a(i)' name='id_list' direction='out'/>"
251             "        </method>"
252
253             "        <method name='get_sticker_info_by_type'>"
254             "          <arg type='i' name='type' direction='in'/>"
255             "          <arg type='i' name='offset' direction='in'/>"
256             "          <arg type='i' name='count' direction='in'/>"
257             "          <arg type='a(i)' name='id_list' direction='out'/>"
258             "        </method>"
259
260             "        <method name='get_sticker_info_by_group'>"
261             "          <arg type='s' name='group' direction='in'/>"
262             "          <arg type='i' name='offset' direction='in'/>"
263             "          <arg type='i' name='count' direction='in'/>"
264             "          <arg type='a(i)' name='id_list' direction='out'/>"
265             "        </method>"
266
267             "        <method name='get_sticker_info_by_keyword'>"
268             "          <arg type='s' name='keyword' direction='in'/>"
269             "          <arg type='i' name='offset' direction='in'/>"
270             "          <arg type='i' name='count' direction='in'/>"
271             "          <arg type='a(i)' name='id_list' direction='out'/>"
272             "        </method>"
273             "  </interface>"
274             "  </node>";
275
276     return stickerd_server_register_dbus_interface(introspection_xml, _sticker_interface_vtable);
277 }
278
279 int stickerd_dbus_init(void)
280 {
281     int ret;
282
283     ret = stickerd_register_dbus_interface();
284     if (ret != STICKERD_SERVER_ERROR_NONE) {
285         LOGE("Failed to register dbus interface : %d", ret);
286         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
287     }
288
289     return STICKERD_SERVER_ERROR_NONE;
290 }
291
292 static int _check_file_exist(const char *app_id, const char *path)
293 {
294     int ret = 0;
295     package_info_h package_info = NULL;
296     char *app_path = NULL;
297     char *file_path = NULL;
298
299     if (access(path, F_OK) == 0) {
300         ret = 0;
301         goto cleanup;
302     }
303
304     ret = package_info_create(app_id, &package_info);
305     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
306         LOGE("failed to create package_info. ret: %d", ret);
307         ret = -1;
308         goto cleanup;
309     }
310
311     ret = package_info_get_root_path(package_info, &app_path);
312     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
313         LOGE("failed to create package_info. ret: %d", ret);
314         ret = -1;
315         goto cleanup;
316     }
317
318     int path_len = strlen(app_path) + strlen(path) + 2;
319     file_path = (char *)calloc(path_len, sizeof(char));
320     if (!file_path) {
321         LOGE("Failed to alloc memory");
322         ret = -1;
323         goto cleanup;
324     }
325
326     if(path[0] == '/')
327         snprintf(file_path, path_len, "%s%s",app_path, path);
328     else
329         snprintf(file_path, path_len, "%s%s%s",app_path, "/", path);
330
331     if (access(file_path, F_OK) != 0) {
332         LOGE("%s does not exist", file_path);
333         ret = -1;
334     } else
335         ret = 0;
336
337 cleanup:
338     if (package_info)
339         package_info_destroy(package_info);
340
341     if (app_path) {
342         free(app_path);
343         app_path = NULL;
344     }
345
346     if (file_path) {
347         free(file_path);
348         file_path = NULL;
349     }
350
351     return ret;
352 }
353
354 static int _mkdirs(const char *path, mode_t mode)
355 {
356     int len = 0;
357     char prev_path[2048];
358     const char *tmp = path;
359
360     if (!path || strlen(path) > 2048)
361         return -1;
362
363     memset(prev_path, '\0', 2048);
364     while ((tmp = strchr(tmp, '/')) != NULL) {
365         len = tmp - path;
366         tmp++;
367
368         if (len == 0)
369             continue;
370
371         strncpy(prev_path, path, len);
372         prev_path[len] = 0x00;
373
374         if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
375             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
376             LOGE("directory create error : %s", error_buffer);
377             return -1;
378         }
379     }
380
381     if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
382         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
383         LOGE("directory create error : %s", error_buffer);
384         return -1;
385     }
386
387     return 0;
388 }
389
390 static int _file_copy(const char *src, const char *dest)
391 {
392     int ret = 0;
393     int fd = -1, n_fd = -1;
394     char buf[4096];
395     int tmp_err = 0;
396     int size;
397
398     memset(buf, '\0', 4096);
399     fd = open(src, O_RDONLY);
400     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
401
402     if (fd == -1 || n_fd == -1) {
403         tmp_err = errno;
404         ret = -1;
405         goto cleanup;
406     }
407
408     while((size = read(fd, buf, 4096))) {
409         if (size == -1) {
410             if(errno == EINTR)
411                 continue;
412
413             tmp_err = errno;
414             ret = -1;
415             goto cleanup;
416         }
417
418         while(write(n_fd, buf, size) == -1) {
419             if(errno == EINTR) {
420                 continue;
421             } else {
422                 tmp_err = errno;
423                 goto cleanup;
424             }
425         }
426     }
427
428 cleanup:
429     if (fd != -1)
430         close(fd);
431
432     if (n_fd != -1)
433         close(n_fd);
434
435     errno = tmp_err;
436     return ret;
437 }
438
439 static char* _convert_sticker_uri(const char *uri, const char *appid)
440 {
441     int ret;
442     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
443     char * new_path = (char *)calloc(len, sizeof(char));
444     if (new_path == NULL) {
445         LOGE("Failed to alloc memory");
446         return NULL;
447     }
448
449     if (uri[0] == '/')
450         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
451     else
452         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
453
454     if (access(new_path, F_OK) == 0) {
455         LOGE("sticker file already exists");
456         ret = -1;
457         goto cleanup;
458     }
459
460     ret = _mkdirs(new_path, 0755);
461     if (ret != 0) {
462         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
463         LOGE("directory create error : %s", error_buffer);
464         goto cleanup;
465     }
466
467     ret = _file_copy(uri, new_path);
468     if (ret != 0) {
469         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
470         LOGE("failed to copy sticker file : %s", error_buffer);
471     }
472
473 cleanup:
474     if (ret == 0) {
475         return new_path;
476     } else {
477         free(new_path);
478         new_path = NULL;
479         return NULL;
480     }
481 }
482
483 int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
484 {
485     int ret;
486     int record_id = 0;
487     STICKER_DAT_TYPE key;
488     sticker_info_db *sticker_info = NULL;
489     GVariant *value = NULL;
490     GVariantIter *info_iter = NULL;
491     GVariantIter *keyword_iter = NULL;
492     char *keyword;
493
494     g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
495     if (!info_iter || !keyword_iter) {
496         LOGD("failed to get iter");
497         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
498         goto cleanup;
499     }
500
501     sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
502
503     if (!sticker_info) {
504         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
505         goto cleanup;
506     }
507
508     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
509         switch(key) {
510             case STICKER_DATA_TYPE_APP_ID:
511             sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
512             break;
513             case STICKER_DATA_TYPE_URI_TYPE:
514             sticker_info->type = g_variant_get_int32(value);
515             break;
516             case STICKER_DATA_TYPE_URI:
517             sticker_info->uri = (char *) g_variant_get_string(value, NULL);
518             break;
519             case STICKER_DATA_TYPE_THUMBNAIL:
520             sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
521             break;
522             case STICKER_DATA_TYPE_DESCRIPTION:
523             sticker_info->description = (char *) g_variant_get_string(value, NULL);
524             break;
525             case STICKER_DATA_TYPE_GROUP:
526             sticker_info->group = (char *) g_variant_get_string(value, NULL);
527             break;
528             default:
529             break;
530         }
531     }
532
533     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
534         sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
535     }
536
537     if (sticker_info->type == 1) {
538         if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
539             sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
540             if (!sticker_info->uri) {
541                 LOGE("failed to copy sticker file");
542                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
543                 goto cleanup;
544             }
545         } else {
546             LOGE("sticker file does not exist");
547             ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
548             goto cleanup;
549         }
550     }
551
552     ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
553     if (ret != STICKERD_SERVER_ERROR_NONE) {
554         LOGE("Failed to insert sticker info");
555         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
556         goto cleanup;
557     }
558
559     *reply_body = g_variant_new("(i)", record_id);
560     if (*reply_body == NULL) {
561         LOGE("Failed to create reply_body");
562         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
563     }
564
565 cleanup:
566     if (value)
567         g_variant_unref(value);
568
569     if (info_iter)
570         g_variant_iter_free(info_iter);
571
572     if (keyword_iter)
573         g_variant_iter_free(keyword_iter);
574
575     if (sticker_info) {
576         free(sticker_info);
577         sticker_info = NULL;
578     }
579
580     return ret;
581 }
582
583 static char* _get_string_from_object(JsonObject *object, const char *key)
584 {
585     if (json_object_has_member(object, key) == false)
586         return NULL;
587
588     const char *str = json_object_get_string_member(object, key);
589     if (str != NULL)
590         return strdup(str);
591     else
592         return NULL;
593 }
594
595 static int _get_int_from_object(JsonObject *object, const char *key)
596 {
597     if (json_object_has_member(object, key) == false)
598         return -1;
599
600     int type = json_object_get_int_member(object, key);
601
602     return type;
603 }
604
605 int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
606 {
607     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
608     int record_id;
609     sticker_info_db *sticker_info = NULL;
610     char *app_id = NULL;
611     char *json_path = NULL;
612     JsonParser* parser = NULL;
613     GError* err_msg = NULL;
614     GVariant *body = NULL;
615     char *cmd = "send_insert_result";
616
617     *reply_body = g_variant_new("()");
618         if (*reply_body == NULL) {
619         LOGE("Failed to create reply_body");
620         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
621     }
622
623     g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
624
625     if (!app_id || !json_path) {
626         LOGE("failed to get parameter");
627         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
628     }
629
630     SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
631
632     parser = json_parser_new();
633     json_parser_load_from_file(parser, json_path, &err_msg);
634     if (err_msg) {
635         LOGE("failed to load json file. error message: %s", err_msg->message);
636         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
637         goto cleanup;
638     }
639
640     JsonNode *root = json_parser_get_root(parser);
641     if (root == NULL) {
642         LOGE("failed to get root");
643         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
644         goto cleanup;
645     }
646
647     JsonObject *root_obj = json_node_get_object(root);
648     if (root_obj == NULL) {
649         LOGE("failed to get object");
650         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
651         goto cleanup;
652     }
653
654     JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
655     if (sticker_arr == NULL) {
656         LOGE("failed to get array member");
657         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
658         goto cleanup;
659     }
660
661     int arr_len = json_array_get_length(sticker_arr);
662     for (int i = 0; i < arr_len; i++) {
663         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
664         if (info_object != NULL) {
665             sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
666             if (!sticker_info) {
667                 LOGE("Failed to alloc memory");
668                 continue;
669             }
670
671             sticker_info->app_id = app_id;
672             sticker_info->type = _get_int_from_object(info_object, "type");
673             if (sticker_info->type < 1)
674                 goto free_memory;
675
676             sticker_info->uri = _get_string_from_object(info_object, "uri");
677             if (!sticker_info->uri)
678                 goto free_memory;
679
680             if (sticker_info->type == 1) {
681                 if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
682                     sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
683                     if (!sticker_info->uri)
684                         goto free_memory;
685                 }
686             }
687
688             sticker_info->group = _get_string_from_object(info_object, "group");
689             if (!sticker_info->group)
690                 goto free_memory;
691
692             sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
693             if (!sticker_info->thumbnail)
694                 goto free_memory;
695
696             sticker_info->description = _get_string_from_object(info_object, "description");
697
698             JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
699             int keyword_arr_len = json_array_get_length(keyword_arr);
700             if (keyword_arr_len < 1)
701                 goto free_memory;
702
703             for (int j = 0; j < keyword_arr_len; j++) {
704                 sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)json_array_get_string_element(keyword_arr, j)));
705             }
706
707             ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
708             if (ret != STICKERD_SERVER_ERROR_NONE) {
709                 LOGE("Failed to insert sticker info");
710                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
711             }
712
713 free_memory:
714             free(sticker_info);
715             sticker_info = NULL;
716         }
717     }
718
719 cleanup:
720     if (err_msg)
721         g_error_free(err_msg);
722     if (parser)
723         g_object_unref(parser);
724
725     body = g_variant_new("(i)", ret);
726
727     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
728     if (ret != STICKERD_SERVER_ERROR_NONE)
729         LOGE("Failed to send insert result to client");
730
731     if(body)
732         g_variant_unref(body);
733
734     return ret;
735 }
736
737 int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
738 {
739     int ret;
740     int record_id;
741
742     *reply_body = g_variant_new("()");
743     if (*reply_body == NULL) {
744         LOGE("Failed to create reply_body");
745         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
746     }
747
748     g_variant_get(parameters, "(i)", &record_id);
749
750     ret = stickerd_db_delete_sticker_info(record_id);
751     if (ret != STICKERD_SERVER_ERROR_NONE) {
752         LOGE("Failed to delete sticker info");
753         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
754     }
755
756     return ret;
757 }
758
759 int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
760 {
761     int ret;
762     int record_id;
763     int type;
764
765     *reply_body = g_variant_new("()");
766     if (*reply_body == NULL) {
767         LOGE("Failed to create reply_body");
768         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
769     }
770
771     g_variant_get(parameters, "(ii)", &record_id, &type);
772
773     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
774     if (ret != STICKERD_SERVER_ERROR_NONE) {
775         LOGE("Failed to update sticker type");
776         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
777     }
778
779     return ret;
780 }
781
782 int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
783 {
784     int ret;
785     int record_id;
786     int type;
787     char *app_id;
788     char *uri;
789
790     *reply_body = g_variant_new("()");
791     if (*reply_body == NULL) {
792         LOGE("Failed to create reply_body");
793         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
794     }
795
796     g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
797
798     if (type == 1) {
799         if (_check_file_exist(app_id, uri) == 0) {
800             uri = _convert_sticker_uri(uri, app_id);
801             if (!uri) {
802                 LOGE("failed to copy sticker file");
803                 return STICKERD_SERVER_ERROR_OPERATION_FAILED;
804             }
805         }
806     }
807
808     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
809     if (ret != STICKERD_SERVER_ERROR_NONE) {
810         LOGE("Failed to update sticker uri");
811         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
812     }
813
814     return ret;
815 }
816
817 int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
818 {
819     int ret;
820     int record_id;
821     char *thumbnail;
822
823     *reply_body = g_variant_new("()");
824     if (*reply_body == NULL) {
825         LOGE("Failed to create reply_body");
826         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
827     }
828
829     g_variant_get(parameters, "(i&s)", &record_id, &thumbnail);
830
831     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
832     if (ret != STICKERD_SERVER_ERROR_NONE) {
833         LOGE("Failed to update sticker thumbnail");
834         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
835     }
836
837     return ret;
838 }
839
840 int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
841 {
842     int ret;
843     int record_id;
844     char *description;
845
846     *reply_body = g_variant_new("()");
847     if (*reply_body == NULL) {
848         LOGE("Failed to create reply_body");
849         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
850     }
851
852     g_variant_get(parameters, "(i&s)", &record_id, &description);
853
854     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
855     if (ret != STICKERD_SERVER_ERROR_NONE) {
856         LOGE("Failed to update sticker description");
857         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
858     }
859
860     return ret;
861 }
862
863 int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
864 {
865     int ret;
866     int record_id;
867     char *group;
868
869     *reply_body = g_variant_new("()");
870     if (*reply_body == NULL) {
871         LOGE("Failed to create reply_body");
872         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
873     }
874
875     g_variant_get(parameters, "(i&s)", &record_id, &group);
876
877     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
878     if (ret != STICKERD_SERVER_ERROR_NONE) {
879         LOGE("Failed to update sticker group");
880         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
881     }
882
883     return ret;
884 }
885
886 int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
887 {
888     int ret;
889     int record_id;
890     GVariantIter *keyword_iter = NULL;
891     char *keyword = NULL;
892     GList *keyword_list = NULL;
893
894     *reply_body = g_variant_new("()");
895     if (*reply_body == NULL) {
896         LOGE("Failed to create reply_body");
897         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
898     }
899
900     g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
901
902     if (!keyword_iter) {
903         LOGD("failed to get iter");
904         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
905     }
906
907     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
908         keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
909     }
910
911     g_variant_iter_free(keyword_iter);
912
913     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
914     if (ret != STICKERD_SERVER_ERROR_NONE) {
915         LOGE("Failed to update sticker keyword");
916         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
917     }
918
919     return ret;
920 }
921
922 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
923 {
924     if (!keyword) {
925         LOGE("keyword doesn't exist");
926         return;
927     }
928
929     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
930 }
931
932 int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
933 {
934     int ret;
935     int record_id;
936     GVariantBuilder *info_builder;
937     GVariantBuilder *keyword_builder;
938
939     g_variant_get(parameters, "(i)", &record_id);
940     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
941
942     if (!sticker_info)
943         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
944
945     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
946     if (ret != STICKERD_SERVER_ERROR_NONE) {
947         LOGE("Failed to get sticker info");
948
949         if (sticker_info->app_id)
950             free(sticker_info->app_id);
951
952         if (sticker_info->uri)
953             free(sticker_info->uri);
954
955         if (sticker_info->thumbnail)
956             free(sticker_info->thumbnail);
957
958         if (sticker_info->keyword)
959             free(sticker_info->keyword);
960
961         if (sticker_info->group)
962             free(sticker_info->group);
963
964         if (sticker_info->description)
965             free(sticker_info->description);
966
967         if (sticker_info->date)
968             free(sticker_info->date);
969
970         free(sticker_info);
971         sticker_info = NULL;
972         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
973     }
974
975     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
976     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
977     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
978     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
979     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
980     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
981     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
982     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
983
984     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
985     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
986
987     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
988     g_variant_builder_unref(info_builder);
989     g_variant_builder_unref(keyword_builder);
990
991     if (*reply_body == NULL) {
992         LOGE("Failed to create reply_body");
993         free(sticker_info);
994         sticker_info = NULL;
995         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
996     }
997
998     free(sticker_info);
999     sticker_info = NULL;
1000     return ret;
1001 }
1002
1003 int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
1004 {
1005     int ret;
1006     GVariantBuilder *builder = NULL;
1007
1008     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1009     ret = stickerd_db_get_group_list(builder);
1010
1011     if (ret != STICKERD_SERVER_ERROR_NONE) {
1012         LOGE("Failed to get sticker group list");
1013         g_variant_builder_unref(builder);
1014         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1015     }
1016
1017     *reply_body = g_variant_new("(a(s))", builder);
1018     g_variant_builder_unref(builder);
1019
1020     if (*reply_body == NULL) {
1021         LOGE("Failed to create reply_body");
1022         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1023     }
1024
1025     return ret;
1026 }
1027
1028 int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
1029 {
1030     int ret;
1031     GVariantBuilder *builder = NULL;
1032
1033     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1034     ret = stickerd_db_get_keyword_list(builder);
1035     if (ret != STICKERD_SERVER_ERROR_NONE) {
1036         LOGE("Failed to get sticker keyword list");
1037         g_variant_builder_unref(builder);
1038         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1039     }
1040
1041     *reply_body = g_variant_new("(a(s))", builder);
1042     g_variant_builder_unref(builder);
1043
1044     if (*reply_body == NULL) {
1045         LOGE("Failed to create reply_body");
1046         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1047     }
1048
1049     return ret;
1050 }
1051
1052 int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
1053 {
1054     int ret;
1055     int count;
1056     char *app_id = NULL;
1057
1058     g_variant_get(parameters, "(&s)", &app_id);
1059
1060     ret = stickerd_db_get_sticker_count(&count, app_id);
1061     if (ret != STICKERD_SERVER_ERROR_NONE) {
1062         LOGE("Failed to get sticker count");
1063         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1064     }
1065
1066     *reply_body = g_variant_new("(i)", count);
1067     if (*reply_body == NULL) {
1068         LOGE("Failed to create reply_body");
1069         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1070     }
1071
1072     return ret;
1073 }
1074
1075 #if 0
1076 // Send the sticker information by asynchronous communication.
1077 static int send_sticker_info_async(int record_id, sticker_info_db_type type, const char *sender)
1078 {
1079     int ret;
1080     char *cmd = NULL;
1081
1082     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1083
1084     if (!sticker_info)
1085         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1086
1087     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1088     if (ret != STICKERD_SERVER_ERROR_NONE) {
1089         LOGE("Failed to get sticker info");
1090         free(sticker_info);
1091         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1092     }
1093
1094     switch (type) {
1095         case STICKER_DB_STICKER_ALL:
1096         cmd = "send_all_sticker_info";
1097         break;
1098         case STICKER_DB_STICKER_APPID:
1099         cmd = "send_sticker_info_by_appid";
1100         break;
1101         case STICKER_DB_STICKER_TYPE:
1102         cmd = "send_sticker_info_by_type";
1103         break;
1104         case STICKER_DB_STICKER_GROUP:
1105         cmd = "send_sticker_info_by_group";
1106         break;
1107         case STICKER_DB_STICKER_KEYWORD:
1108         cmd = "send_sticker_info_by_keyword";
1109         break;
1110         default:
1111         cmd = "";
1112         break;
1113     }
1114
1115     GVariantBuilder *info_builder;
1116     GVariantBuilder *keyword_builder;
1117
1118     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1119     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(record_id));
1120     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1121     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1122     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1123     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1124     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1125     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1126     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1127
1128     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1129     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1130
1131     GVariant *body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1132     g_variant_builder_unref(info_builder);
1133     g_variant_builder_unref(keyword_builder);
1134
1135     ret = stickerd_send_dbus_message(body, sender, cmd);
1136     if (ret != STICKERD_SERVER_ERROR_NONE) {
1137         LOGE("Failed to send sticker info to client");
1138         free(sticker_info);
1139         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1140     }
1141
1142     free(sticker_info);
1143     return ret;
1144 }
1145 #endif
1146
1147 static void _set_id_builder(char *id, GVariantBuilder *id_builder)
1148 {
1149     if (!id) {
1150         LOGE("id doesn't exist");
1151         return;
1152     }
1153
1154     g_variant_builder_add(id_builder, "(i)", atoi(id));
1155 }
1156
1157 int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
1158 {
1159     int ret;
1160     int offset, count;
1161     GList *id_list = NULL;
1162     GVariantBuilder *id_builder = NULL;
1163
1164     g_variant_get(parameters, "(ii)", &offset, &count);
1165
1166     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, offset, count);
1167     if (ret != STICKERD_SERVER_ERROR_NONE) {
1168         LOGE("Failed to get all sticker id");
1169         if(id_list)
1170             g_list_free_full(id_list, free);
1171         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1172     }
1173
1174     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1175     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1176
1177     *reply_body = g_variant_new("(a(i))", id_builder);
1178     if (*reply_body == NULL) {
1179         LOGE("Failed to create reply_body");
1180         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1181     }
1182
1183     if (id_list)
1184         g_list_free_full(id_list, free);
1185
1186     if (id_builder)
1187         g_variant_builder_unref(id_builder);
1188
1189     return ret;
1190 }
1191
1192 int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
1193 {
1194     int ret;
1195     GList *id_list = NULL;
1196     char *app_id = NULL;
1197     int offset, count;
1198     GVariantBuilder *id_builder = NULL;
1199
1200     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1201
1202     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, (void *)app_id, offset, count);
1203     if (ret != STICKERD_SERVER_ERROR_NONE) {
1204         LOGE("Failed to get all sticker id");
1205         if(id_list)
1206             g_list_free_full(id_list, free);
1207         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1208     }
1209
1210     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1211     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1212
1213     *reply_body = g_variant_new("(a(i))", id_builder);
1214     if (*reply_body == NULL) {
1215         LOGE("Failed to create reply_body");
1216         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1217     }
1218
1219     if (id_list)
1220         g_list_free_full(id_list, free);
1221
1222     if (id_builder)
1223         g_variant_builder_unref(id_builder);
1224
1225     return ret;
1226 }
1227
1228 int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
1229 {
1230     int ret;
1231     GList *id_list = NULL;
1232     int type, offset, count;
1233     GVariantBuilder *id_builder = NULL;
1234
1235     g_variant_get(parameters, "(iii)", &type, &offset, &count);
1236
1237     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, offset, count);
1238     if (ret != STICKERD_SERVER_ERROR_NONE) {
1239         LOGE("Failed to get all sticker id");
1240         if(id_list)
1241             g_list_free_full(id_list, free);
1242         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1243     }
1244
1245     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1246     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1247
1248     *reply_body = g_variant_new("(a(i))", id_builder);
1249     if (*reply_body == NULL) {
1250         LOGE("Failed to create reply_body");
1251         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1252     }
1253
1254     if (id_list)
1255         g_list_free_full(id_list, free);
1256
1257     if (id_builder)
1258         g_variant_builder_unref(id_builder);
1259
1260     return ret;
1261 }
1262
1263 int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
1264 {
1265     int ret;
1266     GList *id_list = NULL;
1267     char *group = NULL;
1268     int offset, count;
1269     GVariantBuilder *id_builder = NULL;
1270
1271     g_variant_get(parameters, "(&sii)", &group, &offset, &count);
1272
1273     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, offset, count);
1274     if (ret != STICKERD_SERVER_ERROR_NONE) {
1275         LOGE("Failed to get all sticker id");
1276         if(id_list)
1277             g_list_free_full(id_list, free);
1278         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1279     }
1280
1281     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1282     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1283
1284     *reply_body = g_variant_new("(a(i))", id_builder);
1285     if (*reply_body == NULL) {
1286         LOGE("Failed to create reply_body");
1287         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1288     }
1289
1290     if (id_list)
1291         g_list_free_full(id_list, free);
1292
1293     if (id_builder)
1294         g_variant_builder_unref(id_builder);
1295
1296     return ret;
1297 }
1298
1299 int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
1300 {
1301     int ret;
1302     GList *id_list = NULL;
1303     char *keyword = NULL;
1304     int offset, count;
1305     GVariantBuilder *id_builder = NULL;
1306
1307     g_variant_get(parameters, "(&sii)", &keyword, &offset, &count);
1308
1309     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, offset, count);
1310     if (ret != STICKERD_SERVER_ERROR_NONE) {
1311         LOGE("Failed to get all sticker id");
1312         if(id_list)
1313             g_list_free_full(id_list, free);
1314         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1315     }
1316
1317     id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1318     g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
1319
1320     *reply_body = g_variant_new("(a(i))", id_builder);
1321     if (*reply_body == NULL) {
1322         LOGE("Failed to create reply_body");
1323         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1324     }
1325
1326     if (id_list)
1327         g_list_free_full(id_list, free);
1328
1329     if (id_builder)
1330         g_variant_builder_unref(id_builder);
1331
1332     return ret;
1333 }