Reduce duplicate code in data_manager
[platform/core/uifw/capi-ui-sticker.git] / server / stickerd_data_manager.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <tzplatform_config.h>
21 #include <gio/gunixfdlist.h>
22 #include <dlog.h>
23 #include <json-glib/json-glib.h>
24 #include <package_manager.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <dirent.h>
29 #include <fcntl.h>
30
31 #include "stickerd_dbus.h"
32 #include "stickerd_data_manager.h"
33 #include "stickerd_db_manager.h"
34 #include "sticker_defs.h"
35 #include "stickerd_error.h"
36
37 #ifdef LOG_TAG
38 #undef LOG_TAG
39 #endif
40 #define LOG_TAG "STICKERD_DATA_MANAGER"
41
42 #define MAX_ERROR_BUFFER  256
43
44 enum {
45     STICKER_URI_TYPE_NONE,
46     STICKER_URI_TYPE_LOCAL_PATH,
47     STICKER_URI_TYPE_WEB_RESOURCE,
48 };
49
50 static GHashTable *_monitoring_hash = NULL;
51 static char error_buffer[MAX_ERROR_BUFFER];
52 static GList *consumer_list = NULL;
53 extern GMainLoop *main_loop;
54
55 static void _check_watcher_exist()
56 {
57     if (_monitoring_hash != NULL && g_hash_table_size(_monitoring_hash) == 0) {
58         LOGD("Terminate sticker daemon");
59         g_hash_table_destroy(_monitoring_hash);
60         _monitoring_hash = NULL;
61         g_list_free_full(consumer_list, free);
62         consumer_list = NULL;
63         g_main_loop_quit(main_loop);
64     }
65 }
66
67 static void _on_name_appeared(GDBusConnection *connection,
68         const gchar     *name,
69         const gchar     *name_owner,
70         gpointer         user_data)
71 {
72     LOGD("name: %s", name);
73 }
74
75 static void _on_name_vanished(GDBusConnection *connection,
76         const gchar     *name,
77         gpointer         user_data)
78 {
79     monitoring_info_s *info = (monitoring_info_s *)user_data;
80
81     if (info) {
82         if (_monitoring_hash != NULL && g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(info->watcher_id)) != NULL) {
83             LOGD("name: %s", name);
84             g_bus_unwatch_name(info->watcher_id);
85             delete_monitoring_list(&_monitoring_hash, info->bus_name, info->watcher_id);
86         }
87
88         if (g_list_find(consumer_list, info->bus_name))
89             consumer_list = g_list_remove(consumer_list, info->bus_name);
90
91         if (info->bus_name)
92             free(info->bus_name);
93         free(info);
94         info = NULL;
95     }
96
97     _check_watcher_exist();
98 }
99
100 static void _stickerd_client_dbus_method_call_handler(GDBusConnection *conn, const gchar *sender, const gchar *object_path,
101         const gchar *iface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation,
102         gpointer user_data)
103 {
104     LOGD("stickerd method_name: %s, sender: %s", method_name, sender);
105
106     if (_monitoring_hash == NULL)
107         _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
108
109     if (consumer_list == NULL)
110         consumer_list = g_list_alloc();
111
112     GVariant *reply_body = NULL;
113     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
114
115     if (g_strcmp0(method_name, "sticker_service_register") == 0) {
116         ret = stickerd_server_register(parameters, &reply_body, sender,
117             _on_name_appeared, _on_name_vanished, &_monitoring_hash, &consumer_list);
118     } else if (g_strcmp0(method_name, "sticker_service_unregister") == 0) {
119         ret = stickerd_server_unregister(parameters, &reply_body, sender, &_monitoring_hash, &consumer_list);
120     } else if (g_strcmp0(method_name, "insert_sticker_info") == 0) {
121         ret = stickerd_insert_sticker_info(parameters, &reply_body);
122     } else if  (g_strcmp0(method_name, "update_sticker_info_by_json") == 0) {
123         ret = stickerd_insert_sticker_info_by_json(parameters, &reply_body, sender);
124     } else if (g_strcmp0(method_name, "delete_sticker_info") == 0) {
125         ret = stickerd_del_sticker_info(parameters, &reply_body);
126     } else if (g_strcmp0(method_name, "delete_sticker_info_by_uri") == 0) {
127         ret = stickerd_del_sticker_info_by_uri(parameters, &reply_body);
128     } else if (g_strcmp0(method_name, "update_sticker_type") == 0) {
129         ret = stickerd_update_sticker_type(parameters, &reply_body);
130     } else if (g_strcmp0(method_name, "update_sticker_uri") == 0) {
131         ret = stickerd_update_sticker_uri(parameters, &reply_body);
132     } else if (g_strcmp0(method_name, "update_sticker_thumbnail") == 0) {
133         ret = stickerd_update_sticker_thumbnail(parameters, &reply_body);
134     } else if (g_strcmp0(method_name, "update_sticker_description") == 0) {
135         ret = stickerd_update_sticker_description(parameters, &reply_body);
136     } else if (g_strcmp0(method_name, "update_sticker_group") == 0) {
137         ret = stickerd_update_sticker_group(parameters, &reply_body);
138     } else if (g_strcmp0(method_name, "update_sticker_keyword") == 0) {
139         ret = stickerd_update_sticker_keyword(parameters, &reply_body);
140     } else if (g_strcmp0(method_name, "get_sticker_info") == 0) {
141         ret = stickerd_get_sticker_info(parameters, &reply_body);
142     } else if (g_strcmp0(method_name, "get_group_list") == 0) {
143         ret = stickerd_get_group_list(parameters, &reply_body);
144     } else if (g_strcmp0(method_name, "get_keyword_list") == 0) {
145         ret = stickerd_get_keyword_list(parameters, &reply_body);
146     } else if (g_strcmp0(method_name, "get_sticker_count") == 0) {
147         ret = stickerd_get_sticker_count(parameters, &reply_body);
148     } else if (g_strcmp0(method_name, "get_all_sticker_info") == 0) {
149         ret = stickerd_get_all_sticker_info(parameters, &reply_body);
150     } else if (g_strcmp0(method_name, "get_sticker_info_by_appid") == 0) {
151         ret = stickerd_get_sticker_info_by_app_id(parameters, &reply_body);
152     } else if (g_strcmp0(method_name, "get_sticker_info_by_type") == 0) {
153         ret = stickerd_get_sticker_info_by_type(parameters, &reply_body);
154     } else if (g_strcmp0(method_name, "get_sticker_info_by_group") == 0) {
155         ret = stickerd_get_sticker_info_by_group(parameters, &reply_body);
156     } else if (g_strcmp0(method_name, "get_sticker_info_by_keyword") == 0) {
157         ret = stickerd_get_sticker_info_by_keyword(parameters, &reply_body);
158     } else if (g_strcmp0(method_name, "get_sticker_info_by_disp_type") == 0) {
159         ret = stickerd_get_sticker_info_by_display_type(parameters, &reply_body);
160     } else if (g_strcmp0(method_name, "get_group_list_by_disp_type") == 0) {
161         ret = stickerd_get_group_list_by_disp_type(parameters, &reply_body);
162     } else if (g_strcmp0(method_name, "update_sticker_disp_type") == 0) {
163         ret = stickerd_update_sticker_disp_type(parameters, &reply_body);
164     } else if (g_strcmp0(method_name, "check_file_exists") == 0) {
165         ret = stickerd_check_file_exists(parameters, &reply_body);
166     } else if (g_strcmp0(method_name, "insert_recent_sticker_info") == 0) {
167         ret = stickerd_insert_recent_sticker_info(parameters, &reply_body);
168     } else if (g_strcmp0(method_name, "get_recent_sticker_info") == 0) {
169         ret = stickerd_get_recent_sticker_info(parameters, &reply_body);
170     } else if (g_strcmp0(method_name, "send_update_event") == 0) {
171         ret = stickerd_send_update_event(parameters, &reply_body);
172     } else if (g_strcmp0(method_name, "get_sticker_info_by_uri") == 0) {
173         ret = stickerd_get_sticker_info_by_uri(parameters, &reply_body);
174     } else if (g_strcmp0(method_name, "check_group_exists") == 0) {
175         ret = stickerd_check_group_exists(parameters, &reply_body);
176     } else if (g_strcmp0(method_name, "set_group_image") == 0) {
177         ret = stickerd_set_group_image(parameters, &reply_body);
178     } else if (g_strcmp0(method_name, "get_group_image_list") == 0) {
179         ret = stickerd_get_group_image_list(parameters, &reply_body);
180     }
181
182     if (ret == STICKERD_SERVER_ERROR_NONE) {
183         LOGD("method_call successful, method_name : %s", method_name);
184         g_dbus_method_invocation_return_value(invocation, reply_body);
185     } else {
186         LOGE("method_call failed, method_name : %s", method_name);
187         g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "sticker error");
188     }
189
190     _check_watcher_exist();
191 }
192
193 static const GDBusInterfaceVTable _sticker_interface_vtable = {
194         _stickerd_client_dbus_method_call_handler,
195         NULL,
196         NULL
197 };
198
199 int stickerd_register_dbus_interface(void)
200 {
201     static gchar introspection_xml[] =
202             "  <node>"
203             "  <interface name='org.tizen.sticker_service'>"
204             "        <method name='sticker_service_register'>"
205             "          <arg type='i' name='lib_type' direction='in'/>"
206             "          <arg type='i' name='watcher_id' direction='out'/>"
207             "        </method>"
208
209             "        <method name='sticker_service_unregister'>"
210             "          <arg type='i' name='lib_type' direction='in'/>"
211             "          <arg type='i' name='watcher_id' direction='in'/>"
212             "        </method>"
213
214             "        <method name='insert_sticker_info'>"
215             "          <arg type='a{iv}' name='sticker_info' direction='in'/>"
216             "          <arg type='a(s)' name='keyword_list' direction='in'/>"
217             "          <arg type='i' name='record_id' direction='out'/>"
218             "        </method>"
219
220             "        <method name='update_sticker_info_by_json'>"
221             "          <arg type='s' name='app_id' direction='in'/>"
222             "          <arg type='s' name='json_path' direction='in'/>"
223             "        </method>"
224
225             "        <method name='delete_sticker_info'>"
226             "          <arg type='i' name='record_id' direction='in'/>"
227             "        </method>"
228
229             "        <method name='delete_sticker_info_by_uri'>"
230             "          <arg type='s' name='uri' direction='in'/>"
231             "        </method>"
232
233             "        <method name='update_sticker_type'>"
234             "          <arg type='i' name='record_id' direction='in'/>"
235             "          <arg type='i' name='type' direction='in'/>"
236             "        </method>"
237
238             "        <method name='update_sticker_uri'>"
239             "          <arg type='i' name='record_id' direction='in'/>"
240             "          <arg type='s' name='app_id' direction='in'/>"
241             "          <arg type='i' name='type' direction='in'/>"
242             "          <arg type='s' name='uri' direction='in'/>"
243             "        </method>"
244
245             "        <method name='update_sticker_thumbnail'>"
246             "          <arg type='i' name='record_id' direction='in'/>"
247             "          <arg type='s' name='app_id' direction='in'/>"
248             "          <arg type='s' name='thumbnail' direction='in'/>"
249             "        </method>"
250
251             "        <method name='update_sticker_description'>"
252             "          <arg type='i' name='record_id' direction='in'/>"
253             "          <arg type='s' name='description' direction='in'/>"
254             "        </method>"
255
256             "        <method name='update_sticker_group'>"
257             "          <arg type='i' name='record_id' direction='in'/>"
258             "          <arg type='s' name='group' direction='in'/>"
259             "        </method>"
260
261             "        <method name='update_sticker_keyword'>"
262             "          <arg type='i' name='record_id' direction='in'/>"
263             "          <arg type='a(s)' name='keyword' direction='in'/>"
264             "        </method>"
265
266             "        <method name='get_sticker_info'>"
267             "          <arg type='i' name='record_id' direction='in'/>"
268             "          <arg type='a{iv}' name='sticker_info' direction='out'/>"
269             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
270             "        </method>"
271
272             "        <method name='get_group_list'>"
273             "          <arg type='s' name='app_id' direction='in'/>"
274             "          <arg type='a(s)' name='group_list' direction='out'/>"
275             "        </method>"
276
277             "        <method name='get_keyword_list'>"
278             "          <arg type='s' name='app_id' direction='in'/>"
279             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
280             "        </method>"
281
282             "        <method name='get_sticker_count'>"
283             "          <arg type='s' name='app_id' direction='in'/>"
284             "          <arg type='i' name='count' direction='out'/>"
285             "        </method>"
286
287             "        <method name='get_all_sticker_info'>"
288             "          <arg type='s' name='app_id' direction='in'/>"
289             "          <arg type='i' name='offset' direction='in'/>"
290             "          <arg type='i' name='count' direction='in'/>"
291             "          <arg type='a(i)' name='id_list' direction='out'/>"
292             "        </method>"
293
294             "        <method name='get_sticker_info_by_appid'>"
295             "          <arg type='s' name='app_id' direction='in'/>"
296             "          <arg type='i' name='offset' direction='in'/>"
297             "          <arg type='i' name='count' direction='in'/>"
298             "          <arg type='a(i)' name='id_list' direction='out'/>"
299             "        </method>"
300
301             "        <method name='get_sticker_info_by_type'>"
302             "          <arg type='s' name='app_id' direction='in'/>"
303             "          <arg type='i' name='type' direction='in'/>"
304             "          <arg type='i' name='offset' direction='in'/>"
305             "          <arg type='i' name='count' direction='in'/>"
306             "          <arg type='a(i)' name='id_list' direction='out'/>"
307             "        </method>"
308
309             "        <method name='get_sticker_info_by_group'>"
310             "          <arg type='s' name='app_id' direction='in'/>"
311             "          <arg type='s' name='group' direction='in'/>"
312             "          <arg type='i' name='offset' direction='in'/>"
313             "          <arg type='i' name='count' direction='in'/>"
314             "          <arg type='a(i)' name='id_list' direction='out'/>"
315             "        </method>"
316
317             "        <method name='get_sticker_info_by_keyword'>"
318             "          <arg type='s' name='app_id' direction='in'/>"
319             "          <arg type='s' name='keyword' direction='in'/>"
320             "          <arg type='i' name='offset' direction='in'/>"
321             "          <arg type='i' name='count' direction='in'/>"
322             "          <arg type='a(i)' name='id_list' direction='out'/>"
323             "        </method>"
324
325             "        <method name='get_sticker_info_by_disp_type'>"
326             "          <arg type='s' name='app_id' direction='in'/>"
327             "          <arg type='i' name='type' direction='in'/>"
328             "          <arg type='i' name='offset' direction='in'/>"
329             "          <arg type='i' name='count' direction='in'/>"
330             "          <arg type='a(i)' name='id_list' direction='out'/>"
331             "        </method>"
332
333             "        <method name='get_group_list_by_disp_type'>"
334             "          <arg type='s' name='app_id' direction='in'/>"
335             "          <arg type='i' name='disp_type' direction='in'/>"
336             "          <arg type='a(s)' name='group_list' direction='out'/>"
337             "        </method>"
338
339             "        <method name='update_sticker_disp_type'>"
340             "          <arg type='i' name='record_id' direction='in'/>"
341             "          <arg type='i' name='disp_type' direction='in'/>"
342             "        </method>"
343
344             "        <method name='check_file_exists'>"
345             "          <arg type='s' name='uri' direction='in'/>"
346             "          <arg type='i' name='result' direction='out'/>"
347             "        </method>"
348
349             "        <method name='insert_recent_sticker_info'>"
350             "          <arg type='i' name='record_id' direction='in'/>"
351             "        </method>"
352
353             "        <method name='get_recent_sticker_info'>"
354             "          <arg type='i' name='count' direction='in'/>"
355             "          <arg type='a(i)' name='id_list' direction='out'/>"
356             "        </method>"
357
358             "        <method name='send_update_event'>"
359             "          <arg type='i' name='record_id' direction='in'/>"
360             "        </method>"
361
362             "        <method name='get_sticker_info_by_uri'>"
363             "          <arg type='s' name='uri' direction='in'/>"
364             "          <arg type='a{iv}' name='sticker_info' direction='out'/>"
365             "          <arg type='a(s)' name='keyword_list' direction='out'/>"
366             "        </method>"
367
368             "        <method name='check_group_exists'>"
369             "          <arg type='s' name='app_id' direction='in'/>"
370             "          <arg type='s' name='group' direction='in'/>"
371             "          <arg type='i' name='result' direction='out'/>"
372             "        </method>"
373
374             "        <method name='set_group_image'>"
375             "          <arg type='s' name='app_id' direction='in'/>"
376             "          <arg type='s' name='group' direction='in'/>"
377             "          <arg type='i' name='type' direction='in'/>"
378             "          <arg type='s' name='uri' direction='in'/>"
379             "        </method>"
380
381             "        <method name='get_group_image_list'>"
382             "          <arg type='s' name='app_id' direction='in'/>"
383             "          <arg type='a(sis)' name='group_image_list' direction='out'/>"
384             "        </method>"
385             "  </interface>"
386             "  </node>";
387
388     return stickerd_server_register_dbus_interface(introspection_xml, _sticker_interface_vtable);
389 }
390
391 int stickerd_dbus_init(void)
392 {
393     int ret;
394
395     ret = stickerd_register_dbus_interface();
396     if (ret != STICKERD_SERVER_ERROR_NONE) {
397         LOGE("Failed to register dbus interface : %d", ret);
398         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
399     }
400
401     return STICKERD_SERVER_ERROR_NONE;
402 }
403
404 static int _check_file_exist(const char *app_id, const char *path)
405 {
406     int ret = 0;
407     int path_len = 0;
408     package_info_h package_info = NULL;
409     char *app_path = NULL;
410     char *file_path = NULL;
411
412     if (access(path, F_OK) == 0) {
413         ret = 0;
414         goto cleanup;
415     }
416
417     ret = package_info_create(app_id, &package_info);
418     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
419         LOGE("failed to create package_info. ret: %d", ret);
420         ret = -1;
421         goto cleanup;
422     }
423
424     ret = package_info_get_root_path(package_info, &app_path);
425     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
426         LOGE("failed to create package_info. ret: %d", ret);
427         ret = -1;
428         goto cleanup;
429     }
430
431     path_len = strlen(app_path) + strlen(path) + 2;
432     file_path = (char *)calloc(path_len, sizeof(char));
433     if (!file_path) {
434         LOGE("Failed to alloc memory");
435         ret = -1;
436         goto cleanup;
437     }
438
439     if (path[0] == '/')
440         snprintf(file_path, path_len, "%s%s",app_path, path);
441     else
442         snprintf(file_path, path_len, "%s%s%s",app_path, "/", path);
443
444     if (access(file_path, F_OK) != 0) {
445         LOGE("%s does not exist", file_path);
446         ret = -1;
447     } else
448         ret = 0;
449
450 cleanup:
451     if (package_info)
452         package_info_destroy(package_info);
453
454     if (app_path) {
455         free(app_path);
456         app_path = NULL;
457     }
458
459     if (file_path) {
460         free(file_path);
461         file_path = NULL;
462     }
463
464     return ret;
465 }
466
467 static int _mkdirs(const char *path, mode_t mode)
468 {
469     int len = 0;
470     char prev_path[2048];
471     const char *tmp = path;
472
473     if (!path || strlen(path) > 2048)
474         return -1;
475
476     memset(prev_path, '\0', 2048);
477     while ((tmp = strchr(tmp, '/')) != NULL) {
478         len = tmp - path;
479         tmp++;
480
481         if (len == 0)
482             continue;
483
484         strncpy(prev_path, path, len);
485         prev_path[len] = 0x00;
486
487         if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
488             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
489             LOGE("directory create error : %s", error_buffer);
490             return -1;
491         }
492     }
493
494     if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
495         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
496         LOGE("directory create error : %s", error_buffer);
497         return -1;
498     }
499
500     return 0;
501 }
502
503 static int _file_copy(const char *src, const char *dest)
504 {
505     int ret = 0;
506     int fd = -1, n_fd = -1;
507     char buf[4096];
508     int tmp_err = 0;
509     int size;
510
511     memset(buf, '\0', 4096);
512     fd = open(src, O_RDONLY);
513     if (fd == -1) {
514         LOGE("Failed to open file (%s) for reading", src);
515     }
516
517     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
518     if (n_fd == -1) {
519         LOGE("Failed to open file (%s) for writing", dest);
520     }
521
522     if (fd == -1 || n_fd == -1) {
523         tmp_err = errno;
524         ret = -1;
525         goto cleanup;
526     }
527
528     while ((size = read(fd, buf, 4096))) {
529         if (size == -1) {
530             if (errno == EINTR)
531                 continue;
532
533             tmp_err = errno;
534             ret = -1;
535             goto cleanup;
536         }
537
538         while (write(n_fd, buf, size) == -1) {
539             if (errno == EINTR) {
540                 continue;
541             } else {
542                 tmp_err = errno;
543                 goto cleanup;
544             }
545         }
546     }
547
548 cleanup:
549     if (fd != -1)
550         close(fd);
551
552     if (n_fd != -1)
553         close(n_fd);
554
555     errno = tmp_err;
556     return ret;
557 }
558
559 static char* _convert_sticker_uri(const char *uri, const char *appid)
560 {
561     int ret;
562     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
563     char * new_path = (char *)calloc(len, sizeof(char));
564     if (new_path == NULL) {
565         LOGE("Failed to alloc memory");
566         return NULL;
567     }
568
569     if (uri[0] == '/')
570         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
571     else
572         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
573
574     if (access(new_path, F_OK) == 0) {
575         LOGE("sticker file already exists : %s", new_path);
576         ret = -1;
577         goto cleanup;
578     }
579
580     ret = _mkdirs(new_path, 0755);
581     if (ret != 0) {
582         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
583         LOGE("directory create error : %s", error_buffer);
584         goto cleanup;
585     }
586
587     ret = _file_copy(uri, new_path);
588     if (ret != 0) {
589         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
590         LOGE("failed to copy sticker file : %s", error_buffer);
591     }
592
593 cleanup:
594     if (ret == 0) {
595         return new_path;
596     } else {
597         free(new_path);
598         new_path = NULL;
599         return NULL;
600     }
601 }
602
603 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
604 {
605     if (!keyword) {
606         LOGE("keyword doesn't exist");
607         return;
608     }
609
610     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
611 }
612
613 static GVariant* _get_sticker_g_variant(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
614 {
615     GVariantBuilder *info_builder;
616     GVariantBuilder *keyword_builder;
617
618     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
619     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
620     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
621     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
622     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
623     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
624     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
625     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
626     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
627
628     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
629     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
630
631     GVariant *body = g_variant_new("(ia{iv}a(s))", (int)type, info_builder, keyword_builder);
632     g_variant_builder_unref(info_builder);
633     g_variant_builder_unref(keyword_builder);
634
635     if (body)
636         return body;
637     else
638         return NULL;
639 }
640
641 void _get_consumer_busname(gpointer data, gpointer user_data)
642 {
643     if (data == NULL)
644         return;
645
646     int ret;
647     char *cmd = "send_sticker_changed_event";
648     char *sender = (char *)data;
649     GVariant *body = (GVariant *)user_data;
650
651     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_CONSUMER);
652     if (ret != STICKERD_SERVER_ERROR_NONE)
653         LOGE("Failed to send sticker changed event");
654 }
655
656 static void _send_sticker_changed_event(STICKER_EVENT_TYPE type, sticker_info_db *sticker_info)
657 {
658     GVariant *body = _get_sticker_g_variant(type, sticker_info);
659
660     if (body)
661         g_list_foreach(consumer_list, _get_consumer_busname, body);
662
663     if (body)
664         g_variant_unref(body);
665 }
666
667 static void _free_sticker_data(sticker_info_db *sticker_data)
668 {
669     if (!sticker_data)
670         return;
671
672     if (sticker_data->app_id) {
673         free(sticker_data->app_id);
674         sticker_data->app_id = NULL;
675     }
676
677     if (sticker_data->uri) {
678         free(sticker_data->uri);
679         sticker_data->uri = NULL;
680     }
681
682     if (sticker_data->thumbnail) {
683         free(sticker_data->thumbnail);
684         sticker_data->thumbnail = NULL;
685     }
686
687     if (sticker_data->keyword) {
688         g_list_free_full(sticker_data->keyword, free);
689         sticker_data->keyword = NULL;
690     }
691
692     if (sticker_data->group) {
693         free(sticker_data->group);
694         sticker_data->group = NULL;
695     }
696
697     if (sticker_data->description) {
698         free(sticker_data->description);
699         sticker_data->description = NULL;
700     }
701
702     if (sticker_data->date) {
703         free(sticker_data->date);
704         sticker_data->date = NULL;
705     }
706
707     free(sticker_data);
708 }
709
710 int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
711 {
712     int ret;
713     int record_id = 0;
714     STICKER_DAT_TYPE key;
715     sticker_info_db *sticker_info = NULL;
716     GVariant *value = NULL;
717     GVariantIter *info_iter = NULL;
718     GVariantIter *keyword_iter = NULL;
719     char *keyword;
720
721     g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
722     if (!info_iter || !keyword_iter) {
723         LOGD("failed to get iter");
724         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
725         goto cleanup;
726     }
727
728     sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
729
730     if (!sticker_info) {
731         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
732         goto cleanup;
733     }
734
735     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
736         switch(key) {
737             case STICKER_DATA_TYPE_APP_ID:
738             sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
739             break;
740             case STICKER_DATA_TYPE_URI_TYPE:
741             sticker_info->type = g_variant_get_int32(value);
742             break;
743             case STICKER_DATA_TYPE_URI:
744             sticker_info->uri = (char *) g_variant_get_string(value, NULL);
745             break;
746             case STICKER_DATA_TYPE_THUMBNAIL:
747             sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
748             break;
749             case STICKER_DATA_TYPE_DESCRIPTION:
750             sticker_info->description = (char *) g_variant_get_string(value, NULL);
751             break;
752             case STICKER_DATA_TYPE_GROUP:
753             sticker_info->group = (char *) g_variant_get_string(value, NULL);
754             break;
755             case STICKER_DATA_TYPE_DISP_TYPE:
756             sticker_info->display_type = g_variant_get_int32(value);
757             default:
758             break;
759         }
760     }
761
762     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
763         sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
764     }
765
766     if (sticker_info->type == STICKER_URI_TYPE_LOCAL_PATH) {
767         if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
768             sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
769             if (!sticker_info->uri) {
770                 LOGE("failed to copy sticker file");
771                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
772                 goto cleanup;
773             }
774         } else {
775             LOGE("sticker file does not exist");
776             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
777             goto cleanup;
778         }
779     }
780
781     if (sticker_info->thumbnail) {
782         if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
783             sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
784             if (!sticker_info->thumbnail) {
785                 LOGE("failed to copy sticker thumbnail");
786                 ret = STICKERD_SERVER_ERROR_FILE_EXISTS;
787                 goto cleanup;
788             }
789         } else {
790             LOGE("sticker thumbnail does not exist");
791             ret = STICKERD_SERVER_ERROR_NO_SUCH_FILE;
792             goto cleanup;
793         }
794     }
795
796     ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
797     if (ret != STICKERD_SERVER_ERROR_NONE) {
798         LOGE("Failed to insert sticker info");
799         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
800         goto cleanup;
801     }
802
803     *reply_body = g_variant_new("(i)", record_id);
804     if (*reply_body == NULL) {
805         LOGE("Failed to create reply_body");
806         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
807     } else
808         _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
809
810 cleanup:
811     if (value)
812         g_variant_unref(value);
813
814     if (info_iter)
815         g_variant_iter_free(info_iter);
816
817     if (keyword_iter)
818         g_variant_iter_free(keyword_iter);
819
820     if (sticker_info) {
821         free(sticker_info);
822         sticker_info = NULL;
823     }
824
825     return ret;
826 }
827
828 static char* _get_string_from_object(JsonObject *object, const char *key)
829 {
830     if (json_object_has_member(object, key) == false)
831         return NULL;
832
833     const char *str = json_object_get_string_member(object, key);
834     if (str != NULL)
835         return strdup(str);
836     else
837         return NULL;
838 }
839
840 static int _get_int_from_object(JsonObject *object, const char *key)
841 {
842     if (json_object_has_member(object, key) == false)
843         return -1;
844
845     int type = json_object_get_int_member(object, key);
846
847     return type;
848 }
849
850 int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
851 {
852     int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
853     int record_id;
854     sticker_info_db *sticker_info = NULL;
855     char *app_id = NULL;
856     char *json_path = NULL;
857     JsonParser* parser = NULL;
858     GError* err_msg = NULL;
859     GVariant *body = NULL;
860     char *cmd = "send_insert_result";
861     JsonArray *sticker_arr = NULL;
862     JsonArray *keyword_arr = NULL;
863     int arr_len = 0;
864     int keyword_arr_len = 0;
865     const char *keyword = NULL;
866
867     JsonNode *root = NULL;
868     JsonObject *root_obj = NULL;
869
870     *reply_body = g_variant_new("()");
871         if (*reply_body == NULL) {
872         LOGE("Failed to create reply_body");
873         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
874     }
875
876     g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
877
878     if (!app_id || !json_path) {
879         LOGE("failed to get parameter");
880         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
881     }
882
883     SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
884
885     parser = json_parser_new();
886     json_parser_load_from_file(parser, json_path, &err_msg);
887     if (err_msg) {
888         LOGE("failed to load json file. error message: %s", err_msg->message);
889         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
890         goto cleanup;
891     }
892
893     root = json_parser_get_root(parser);
894     if (root == NULL) {
895         LOGE("failed to get root");
896         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
897         goto cleanup;
898     }
899
900     root_obj = json_node_get_object(root);
901     if (root_obj == NULL) {
902         LOGE("failed to get object");
903         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
904         goto cleanup;
905     }
906
907     sticker_arr = json_object_get_array_member(root_obj, "sticker");
908     if (sticker_arr == NULL) {
909         LOGE("failed to get array member");
910         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
911         goto cleanup;
912     }
913
914     arr_len = json_array_get_length(sticker_arr);
915     for (int i = 0; i < arr_len; i++) {
916         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
917         if (info_object != NULL) {
918             sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
919             if (!sticker_info) {
920                 LOGE("Failed to alloc memory");
921                 continue;
922             }
923
924             sticker_info->app_id = strdup(app_id);
925             if (!sticker_info->app_id)
926                 goto free_memory;
927
928             sticker_info->type = _get_int_from_object(info_object, "type");
929             if (sticker_info->type < 1)
930                 goto free_memory;
931
932             sticker_info->uri = _get_string_from_object(info_object, "uri");
933             if (!sticker_info->uri || sticker_info->uri[0] == '\0')
934                 goto free_memory;
935
936             if (sticker_info->type == STICKER_URI_TYPE_LOCAL_PATH) {
937                 if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
938                     sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
939                     if (!sticker_info->uri)
940                         goto free_memory;
941                 } else {
942                     goto free_memory;
943                 }
944             }
945
946             sticker_info->group = _get_string_from_object(info_object, "group");
947             if (!sticker_info->group)
948                 goto free_memory;
949
950             sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
951             if (sticker_info->thumbnail && sticker_info->thumbnail[0] != '\0') {
952                 if (_check_file_exist(sticker_info->app_id, sticker_info->thumbnail) == 0) {
953                     sticker_info->thumbnail = _convert_sticker_uri(sticker_info->thumbnail, sticker_info->app_id);
954                     if (!sticker_info->thumbnail)
955                         goto free_memory;
956                 } else {
957                     goto free_memory;
958                 }
959             }
960
961             sticker_info->description = _get_string_from_object(info_object, "description");
962
963             sticker_info->display_type = _get_int_from_object(info_object, "display_type");
964
965             keyword_arr = json_object_get_array_member(info_object, "keyword");
966             keyword_arr_len = json_array_get_length(keyword_arr);
967             if (keyword_arr_len < 1)
968                 goto free_memory;
969
970             for (int j = 0; j < keyword_arr_len; j++) {
971                 keyword = json_array_get_string_element(keyword_arr, j);
972                 if (keyword)
973                     sticker_info->keyword = g_list_append(sticker_info->keyword, strdup(keyword));
974             }
975
976             ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
977             if (ret != STICKERD_SERVER_ERROR_NONE) {
978                 LOGE("Failed to insert sticker info");
979                 ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
980             } else
981                 _send_sticker_changed_event(STICKER_EVENT_TYPE_INSERT, sticker_info);
982
983 free_memory:
984             _free_sticker_data(sticker_info);
985             sticker_info = NULL;
986         }
987     }
988
989 cleanup:
990     if (err_msg)
991         g_error_free(err_msg);
992     if (parser)
993         g_object_unref(parser);
994
995     body = g_variant_new("(i)", ret);
996
997     ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
998     if (ret != STICKERD_SERVER_ERROR_NONE)
999         LOGE("Failed to send insert result to client");
1000
1001     if (body)
1002         g_variant_unref(body);
1003
1004     return ret;
1005 }
1006
1007 int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
1008 {
1009     int ret;
1010     int record_id;
1011
1012     *reply_body = g_variant_new("()");
1013     if (*reply_body == NULL) {
1014         LOGE("Failed to create reply_body");
1015         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1016     }
1017
1018     g_variant_get(parameters, "(i)", &record_id);
1019
1020     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1021     if (sticker_info)
1022         stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1023
1024     ret = stickerd_db_delete_sticker_info(record_id);
1025     if (ret != STICKERD_SERVER_ERROR_NONE) {
1026         LOGE("Failed to delete sticker info");
1027         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1028     } else {
1029         if (sticker_info && sticker_info->uri)
1030             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
1031     }
1032
1033     if (sticker_info) {
1034         _free_sticker_data(sticker_info);
1035         sticker_info = NULL;
1036     }
1037
1038     return ret;
1039 }
1040
1041 int stickerd_del_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
1042 {
1043     int ret;
1044     char *uri = NULL;
1045
1046     *reply_body = g_variant_new("()");
1047     if (*reply_body == NULL) {
1048         LOGE("Failed to create reply_body");
1049         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1050     }
1051
1052     g_variant_get(parameters, "(&s)", &uri);
1053
1054     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1055     if (sticker_info)
1056         stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1057
1058     ret = stickerd_db_delete_sticker_info_by_uri(uri);
1059     if (ret != STICKERD_SERVER_ERROR_NONE) {
1060         LOGE("Failed to delete sticker info");
1061         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1062     } else {
1063         if (sticker_info && sticker_info->uri)
1064             _send_sticker_changed_event(STICKER_EVENT_TYPE_DELETE, sticker_info);
1065     }
1066
1067     if (sticker_info) {
1068         _free_sticker_data(sticker_info);
1069         sticker_info = NULL;
1070     }
1071
1072     return ret;
1073 }
1074
1075 int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
1076 {
1077     int ret;
1078     int record_id;
1079     int type;
1080
1081     *reply_body = g_variant_new("()");
1082     if (*reply_body == NULL) {
1083         LOGE("Failed to create reply_body");
1084         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1085     }
1086
1087     g_variant_get(parameters, "(ii)", &record_id, &type);
1088
1089     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
1090     if (ret != STICKERD_SERVER_ERROR_NONE) {
1091         LOGE("Failed to update sticker type");
1092         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1093     }
1094
1095     return ret;
1096 }
1097
1098 int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
1099 {
1100     int ret;
1101     int record_id;
1102     int type;
1103     char *app_id;
1104     char *uri;
1105
1106     *reply_body = g_variant_new("()");
1107     if (*reply_body == NULL) {
1108         LOGE("Failed to create reply_body");
1109         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1110     }
1111
1112     g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
1113
1114     if (type == STICKER_URI_TYPE_LOCAL_PATH) {
1115         if (_check_file_exist(app_id, uri) == 0) {
1116             uri = _convert_sticker_uri(uri, app_id);
1117             if (!uri) {
1118                 LOGE("failed to copy sticker file");
1119                 return STICKERD_SERVER_ERROR_FILE_EXISTS;
1120             }
1121         } else {
1122             return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1123         }
1124     }
1125
1126     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
1127     if (ret != STICKERD_SERVER_ERROR_NONE) {
1128         LOGE("Failed to update sticker uri");
1129         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1130     }
1131
1132     return ret;
1133 }
1134
1135 int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
1136 {
1137     int ret;
1138     int record_id;
1139     char *app_id;
1140     char *thumbnail;
1141
1142     *reply_body = g_variant_new("()");
1143     if (*reply_body == NULL) {
1144         LOGE("Failed to create reply_body");
1145         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1146     }
1147
1148     g_variant_get(parameters, "(i&s&s)", &record_id, &app_id, &thumbnail);
1149
1150     if (_check_file_exist(app_id, thumbnail) == 0) {
1151         thumbnail = _convert_sticker_uri(thumbnail, app_id);
1152         if (!thumbnail) {
1153             LOGE("failed to copy sticker thumbnail");
1154             return STICKERD_SERVER_ERROR_FILE_EXISTS;
1155         }
1156     } else {
1157         return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1158     }
1159
1160     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
1161     if (ret != STICKERD_SERVER_ERROR_NONE) {
1162         LOGE("Failed to update sticker thumbnail");
1163         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1164     }
1165
1166     return ret;
1167 }
1168
1169 int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
1170 {
1171     int ret;
1172     int record_id;
1173     char *description;
1174
1175     *reply_body = g_variant_new("()");
1176     if (*reply_body == NULL) {
1177         LOGE("Failed to create reply_body");
1178         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1179     }
1180
1181     g_variant_get(parameters, "(i&s)", &record_id, &description);
1182
1183     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
1184     if (ret != STICKERD_SERVER_ERROR_NONE) {
1185         LOGE("Failed to update sticker description");
1186         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1187     }
1188
1189     return ret;
1190 }
1191
1192 int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
1193 {
1194     int ret;
1195     int record_id;
1196     char *group;
1197
1198     *reply_body = g_variant_new("()");
1199     if (*reply_body == NULL) {
1200         LOGE("Failed to create reply_body");
1201         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1202     }
1203
1204     g_variant_get(parameters, "(i&s)", &record_id, &group);
1205
1206     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
1207     if (ret != STICKERD_SERVER_ERROR_NONE) {
1208         LOGE("Failed to update sticker group");
1209         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1210     }
1211
1212     return ret;
1213 }
1214
1215 int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
1216 {
1217     int ret;
1218     int record_id;
1219     GVariantIter *keyword_iter = NULL;
1220     char *keyword = NULL;
1221     GList *keyword_list = NULL;
1222
1223     *reply_body = g_variant_new("()");
1224     if (*reply_body == NULL) {
1225         LOGE("Failed to create reply_body");
1226         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1227     }
1228
1229     g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
1230
1231     if (!keyword_iter) {
1232         LOGD("failed to get iter");
1233         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1234     }
1235
1236     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
1237         keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
1238     }
1239
1240     g_variant_iter_free(keyword_iter);
1241
1242     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
1243     if (ret != STICKERD_SERVER_ERROR_NONE) {
1244         LOGE("Failed to update sticker keyword");
1245         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1246     }
1247
1248     return ret;
1249 }
1250
1251 int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
1252 {
1253     int ret;
1254     int record_id;
1255     GVariantBuilder *info_builder;
1256     GVariantBuilder *keyword_builder;
1257
1258     g_variant_get(parameters, "(i)", &record_id);
1259     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1260
1261     if (!sticker_info)
1262         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1263
1264     ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1265     if (ret != STICKERD_SERVER_ERROR_NONE) {
1266         LOGE("Failed to get sticker info");
1267         _free_sticker_data(sticker_info);
1268         sticker_info = NULL;
1269         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1270     }
1271
1272     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1273     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1274     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1275     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1276     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1277     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1278     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1279     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1280     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1281
1282     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1283     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1284
1285     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1286     g_variant_builder_unref(info_builder);
1287     g_variant_builder_unref(keyword_builder);
1288
1289     if (*reply_body == NULL) {
1290         LOGE("Failed to create reply_body");
1291         _free_sticker_data(sticker_info);
1292         sticker_info = NULL;
1293         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1294     }
1295
1296     _free_sticker_data(sticker_info);
1297     sticker_info = NULL;
1298
1299     return ret;
1300 }
1301
1302 int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
1303 {
1304     int ret;
1305     GVariantBuilder *builder = NULL;
1306     char *app_id = NULL;
1307
1308     g_variant_get(parameters, "(&s)", &app_id);
1309
1310     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1311     ret = stickerd_db_get_group_list(builder, app_id);
1312     if (ret != STICKERD_SERVER_ERROR_NONE) {
1313         LOGE("Failed to get sticker group list");
1314         g_variant_builder_unref(builder);
1315         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1316     }
1317
1318     *reply_body = g_variant_new("(a(s))", builder);
1319     g_variant_builder_unref(builder);
1320
1321     if (*reply_body == NULL) {
1322         LOGE("Failed to create reply_body");
1323         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1324     }
1325
1326     return ret;
1327 }
1328
1329 int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
1330 {
1331     int ret;
1332     GVariantBuilder *builder = NULL;
1333     char *app_id = NULL;
1334
1335     g_variant_get(parameters, "(&s)", &app_id);
1336
1337     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1338     ret = stickerd_db_get_keyword_list(builder, app_id);
1339     if (ret != STICKERD_SERVER_ERROR_NONE) {
1340         LOGE("Failed to get sticker keyword list");
1341         g_variant_builder_unref(builder);
1342         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1343     }
1344
1345     *reply_body = g_variant_new("(a(s))", builder);
1346     g_variant_builder_unref(builder);
1347
1348     if (*reply_body == NULL) {
1349         LOGE("Failed to create reply_body");
1350         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1351     }
1352
1353     return ret;
1354 }
1355
1356 int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
1357 {
1358     int ret;
1359     int count;
1360     char *app_id = NULL;
1361
1362     g_variant_get(parameters, "(&s)", &app_id);
1363
1364     ret = stickerd_db_get_sticker_count(&count, app_id);
1365     if (ret != STICKERD_SERVER_ERROR_NONE) {
1366         LOGE("Failed to get sticker count");
1367         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1368     }
1369
1370     *reply_body = g_variant_new("(i)", count);
1371     if (*reply_body == NULL) {
1372         LOGE("Failed to create reply_body");
1373         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1374     }
1375
1376     return ret;
1377 }
1378
1379 static void _set_id_builder(char *id, GVariantBuilder *id_builder)
1380 {
1381     if (!id) {
1382         LOGE("id doesn't exist");
1383         return;
1384     }
1385
1386     g_variant_builder_add(id_builder, "(i)", atoi(id));
1387 }
1388
1389 static int _set_reply_body(GList *list, GVariant **reply_body)
1390 {
1391     int ret  = STICKERD_SERVER_ERROR_NONE;
1392     GVariantBuilder *builder = NULL;
1393
1394     builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
1395     g_list_foreach(list, (GFunc) _set_id_builder, builder);
1396
1397     *reply_body = g_variant_new("(a(i))", builder);
1398     if (*reply_body == NULL) {
1399         LOGE("Failed to create reply_body");
1400         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1401     }
1402
1403     if (builder)
1404         g_variant_builder_unref(builder);
1405
1406     return ret;
1407 }
1408
1409 int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
1410 {
1411     int ret;
1412     int offset, count;
1413     char *app_id = NULL;
1414     GList *id_list = NULL;
1415
1416     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1417
1418     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, app_id, offset, count);
1419     if (ret != STICKERD_SERVER_ERROR_NONE) {
1420         LOGE("Failed to get all sticker id");
1421         if (id_list)
1422             g_list_free_full(id_list, free);
1423         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1424     }
1425
1426     ret = _set_reply_body(id_list, reply_body);
1427     if (id_list)
1428         g_list_free_full(id_list, free);
1429
1430     return ret;
1431 }
1432
1433 int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
1434 {
1435     int ret;
1436     GList *id_list = NULL;
1437     char *app_id = NULL;
1438     int offset, count;
1439
1440     g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
1441
1442     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, NULL, app_id, offset, count);
1443     if (ret != STICKERD_SERVER_ERROR_NONE) {
1444         LOGE("Failed to get all sticker id");
1445         if (id_list)
1446             g_list_free_full(id_list, free);
1447         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1448     }
1449
1450     ret = _set_reply_body(id_list, reply_body);
1451     if (id_list)
1452         g_list_free_full(id_list, free);
1453
1454     return ret;
1455 }
1456
1457 int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
1458 {
1459     int ret;
1460     GList *id_list = NULL;
1461     char *app_id = NULL;
1462     int type, offset, count;
1463
1464     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1465
1466     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, app_id, offset, count);
1467     if (ret != STICKERD_SERVER_ERROR_NONE) {
1468         LOGE("Failed to get all sticker id");
1469         if (id_list)
1470             g_list_free_full(id_list, free);
1471         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1472     }
1473
1474     ret = _set_reply_body(id_list, reply_body);
1475     if (id_list)
1476         g_list_free_full(id_list, free);
1477
1478     return ret;
1479 }
1480
1481 int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
1482 {
1483     int ret;
1484     GList *id_list = NULL;
1485     char *app_id = NULL;
1486     char *group = NULL;
1487     int offset, count;
1488
1489     g_variant_get(parameters, "(&s&sii)", &app_id, &group, &offset, &count);
1490
1491     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, app_id, offset, count);
1492     if (ret != STICKERD_SERVER_ERROR_NONE) {
1493         LOGE("Failed to get all sticker id");
1494         if (id_list)
1495             g_list_free_full(id_list, free);
1496         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1497     }
1498
1499     ret = _set_reply_body(id_list, reply_body);
1500     if (id_list)
1501         g_list_free_full(id_list, free);
1502
1503     return ret;
1504 }
1505
1506 int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
1507 {
1508     int ret;
1509     GList *id_list = NULL;
1510     char *app_id = NULL;
1511     char *keyword = NULL;
1512     int offset, count;
1513
1514     g_variant_get(parameters, "(&s&sii)", &app_id, &keyword, &offset, &count);
1515
1516     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, app_id, offset, count);
1517     if (ret != STICKERD_SERVER_ERROR_NONE) {
1518         LOGE("Failed to get all sticker id");
1519         if (id_list)
1520             g_list_free_full(id_list, free);
1521         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1522     }
1523
1524     ret = _set_reply_body(id_list, reply_body);
1525     if (id_list)
1526         g_list_free_full(id_list, free);
1527
1528     return ret;
1529 }
1530
1531 int stickerd_get_sticker_info_by_display_type(GVariant *parameters, GVariant **reply_body)
1532 {
1533     int ret;
1534     GList *id_list = NULL;
1535     char *app_id = NULL;
1536     int type, offset, count;
1537
1538     g_variant_get(parameters, "(&siii)", &app_id, &type, &offset, &count);
1539
1540     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_DISP_TYPE, &id_list, &type, app_id, offset, count);
1541     if (ret != STICKERD_SERVER_ERROR_NONE) {
1542         LOGE("Failed to get all sticker id");
1543         if (id_list)
1544             g_list_free_full(id_list, free);
1545         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1546     }
1547
1548     ret = _set_reply_body(id_list, reply_body);
1549     if (id_list)
1550         g_list_free_full(id_list, free);
1551
1552     return ret;
1553 }
1554
1555 int stickerd_get_group_list_by_disp_type(GVariant *parameters, GVariant **reply_body)
1556 {
1557     int ret;
1558     GVariantBuilder *builder = NULL;
1559     char *app_id = NULL;
1560     int disp_type;
1561
1562     g_variant_get(parameters, "(&si)", &app_id, &disp_type);
1563
1564     builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1565     ret = stickerd_db_get_group_list_by_display_type(builder, app_id, disp_type);
1566     if (ret != STICKERD_SERVER_ERROR_NONE) {
1567         LOGE("Failed to get sticker group list");
1568         g_variant_builder_unref(builder);
1569         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1570     }
1571
1572     *reply_body = g_variant_new("(a(s))", builder);
1573     g_variant_builder_unref(builder);
1574
1575     if (*reply_body == NULL) {
1576         LOGE("Failed to create reply_body");
1577         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1578     }
1579
1580     return ret;
1581 }
1582
1583 int stickerd_update_sticker_disp_type(GVariant *parameters, GVariant **reply_body)
1584 {
1585     int ret;
1586     int record_id;
1587     int disp_type;
1588
1589     *reply_body = g_variant_new("()");
1590     if (*reply_body == NULL) {
1591         LOGE("Failed to create reply_body");
1592         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1593     }
1594
1595     g_variant_get(parameters, "(ii)", &record_id, &disp_type);
1596
1597     ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DISP_TYPE, &disp_type);
1598     if (ret != STICKERD_SERVER_ERROR_NONE) {
1599         LOGE("Failed to update sticker disp_type");
1600         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1601     }
1602
1603     return ret;
1604 }
1605
1606 int stickerd_check_file_exists(GVariant *parameters, GVariant **reply_body)
1607 {
1608     int ret;
1609     int result;
1610     char *uri = NULL;
1611
1612     g_variant_get(parameters, "(&s)", &uri);
1613
1614     ret = stickerd_db_check_file_exists(&result, uri);
1615     if (ret != STICKERD_SERVER_ERROR_NONE) {
1616         LOGE("Failed to get sticker count");
1617         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1618     }
1619
1620     *reply_body = g_variant_new("(i)", result);
1621     if (*reply_body == NULL) {
1622         LOGE("Failed to create reply_body");
1623         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1624     }
1625
1626     return ret;
1627 }
1628
1629 int stickerd_insert_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1630 {
1631     int ret;
1632     int record_id;
1633
1634     *reply_body = g_variant_new("()");
1635     if (*reply_body == NULL) {
1636         LOGE("Failed to create reply_body");
1637         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1638     }
1639
1640     g_variant_get(parameters, "(i)", &record_id);
1641
1642     ret = stickerd_db_insert_recent_sticker_info(record_id);
1643     if (ret != STICKERD_SERVER_ERROR_NONE) {
1644         LOGE("Failed to insert recent sticker info");
1645         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1646     }
1647
1648     return ret;
1649 }
1650
1651 int stickerd_get_recent_sticker_info(GVariant *parameters, GVariant **reply_body)
1652 {
1653     int ret;
1654     int count;
1655     GList *id_list = NULL;
1656
1657     g_variant_get(parameters, "(i)", &count);
1658
1659     ret = stickerd_db_get_record_id(STICKER_DB_STICKER_RECENT_HISTORY, &id_list, NULL, NULL, 0, count);
1660     if (ret != STICKERD_SERVER_ERROR_NONE) {
1661         LOGE("Failed to get recent sticker id");
1662         if (id_list)
1663             g_list_free_full(id_list, free);
1664         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1665     }
1666
1667     ret = _set_reply_body(id_list, reply_body);
1668     if (id_list)
1669         g_list_free_full(id_list, free);
1670
1671     return ret;
1672 }
1673
1674 int stickerd_send_update_event(GVariant *parameters, GVariant **reply_body)
1675 {
1676     int ret = STICKERD_SERVER_ERROR_NONE;
1677     int record_id;
1678
1679     *reply_body = g_variant_new("()");
1680     if (*reply_body == NULL) {
1681         LOGE("Failed to create reply_body");
1682         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1683     }
1684
1685     g_variant_get(parameters, "(i)", &record_id);
1686
1687     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1688     if (sticker_info) {
1689         ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
1690         if (ret == STICKERD_SERVER_ERROR_NONE)
1691             _send_sticker_changed_event(STICKER_EVENT_TYPE_UPDATE, sticker_info);
1692
1693         _free_sticker_data(sticker_info);
1694         sticker_info = NULL;
1695     }
1696
1697     return ret;
1698 }
1699
1700 int stickerd_get_sticker_info_by_uri(GVariant *parameters, GVariant **reply_body)
1701 {
1702     int ret;
1703     char *uri = NULL;
1704     GVariantBuilder *info_builder;
1705     GVariantBuilder *keyword_builder;
1706
1707     g_variant_get(parameters, "(&s)", &uri);
1708
1709     sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
1710
1711     if (!sticker_info)
1712         return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
1713
1714     ret = stickerd_db_get_sticker_info_by_uri(uri, sticker_info);
1715     if (ret != STICKERD_SERVER_ERROR_NONE) {
1716         LOGE("Failed to get sticker info");
1717         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1718         goto cleanup;
1719     }
1720
1721     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
1722     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(sticker_info->record_id));
1723     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
1724     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
1725     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
1726     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
1727     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
1728     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
1729     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
1730     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DISP_TYPE, g_variant_new_int32(sticker_info->display_type));
1731
1732     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
1733     g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
1734
1735     *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
1736     g_variant_builder_unref(info_builder);
1737     g_variant_builder_unref(keyword_builder);
1738
1739     if (*reply_body == NULL) {
1740         LOGE("Failed to create reply_body");
1741         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
1742     }
1743
1744 cleanup:
1745     if (sticker_info) {
1746         _free_sticker_data(sticker_info);
1747         sticker_info = NULL;
1748     }
1749
1750     return ret;
1751 }
1752
1753 int stickerd_check_group_exists(GVariant *parameters, GVariant **reply_body)
1754 {
1755     int ret;
1756     int result;
1757     char *app_id = NULL;
1758     char *group = NULL;
1759
1760     g_variant_get(parameters, "(&s&s)", &app_id, &group);
1761
1762     ret = stickerd_db_check_group_exists(&result, app_id, group);
1763     if (ret != STICKERD_SERVER_ERROR_NONE) {
1764         LOGE("Failed to check group exists");
1765         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1766     }
1767
1768     *reply_body = g_variant_new("(i)", result);
1769     if (*reply_body == NULL) {
1770         LOGE("Failed to create reply_body");
1771         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1772     }
1773
1774     return ret;
1775 }
1776
1777 int stickerd_set_group_image(GVariant *parameters, GVariant **reply_body)
1778 {
1779     int ret;
1780     int type;
1781     char *app_id = NULL;
1782     char *group = NULL;
1783     char *uri = NULL;
1784
1785     *reply_body = g_variant_new("()");
1786     if (*reply_body == NULL) {
1787         LOGE("Failed to create reply_body");
1788         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1789     }
1790
1791     g_variant_get(parameters, "(&s&si&s)", &app_id, &group, &type, &uri);
1792
1793     if (type == STICKER_URI_TYPE_LOCAL_PATH) {
1794         if (_check_file_exist(app_id, uri) == 0) {
1795             uri = _convert_sticker_uri(uri, app_id);
1796             if (!uri) {
1797                 LOGE("failed to copy sticker file");
1798                 return STICKERD_SERVER_ERROR_FILE_EXISTS;
1799             }
1800         } else {
1801             LOGE("sticker file does not exist");
1802             return STICKERD_SERVER_ERROR_NO_SUCH_FILE;
1803         }
1804     }
1805
1806     ret = stickerd_db_set_group_image(app_id, group, type, uri);
1807     if (ret != STICKERD_SERVER_ERROR_NONE) {
1808         LOGE("Failed to set group image");
1809         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1810     }
1811
1812     return ret;
1813 }
1814
1815 int stickerd_get_group_image_list(GVariant *parameters, GVariant **reply_body)
1816 {
1817     int ret;
1818     GVariantBuilder *builder = NULL;
1819     char *app_id = NULL;
1820
1821     g_variant_get(parameters, "(&s)", &app_id);
1822
1823     builder = g_variant_builder_new(G_VARIANT_TYPE("a(sis)"));
1824     ret = stickerd_db_get_group_image_list(builder, app_id);
1825     if (ret != STICKERD_SERVER_ERROR_NONE) {
1826         LOGE("Failed to get sticker group image list");
1827         g_variant_builder_unref(builder);
1828         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1829     }
1830
1831     *reply_body = g_variant_new("(a(sis))", builder);
1832     g_variant_builder_unref(builder);
1833
1834     if (*reply_body == NULL) {
1835         LOGE("Failed to create reply_body");
1836         return STICKERD_SERVER_ERROR_OPERATION_FAILED;
1837     }
1838
1839     return ret;
1840 }