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