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