Support on-demand launch
[platform/core/uifw/capi-ui-sticker.git] / client / sticker_dbus.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 <dlog.h>
18
19 #include "sticker_dbus.h"
20
21 #ifdef LOG_TAG
22 #undef LOG_TAG
23 #endif
24 #define LOG_TAG "STICKER_DBUS"
25
26 static int is_server_started = 0;
27
28 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
29 {
30     LOGD("name : %s, name_owner : %s", name, name_owner);
31 }
32
33 //LCOV_EXCL_START
34 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
35 {
36     LOGD("name : %s", name);
37 }
38 //LCOV_EXCL_STOP
39
40 static int _dbus_init(GDBusConnection **gdbus_connection)
41 {
42     GError *error = NULL;
43     int watch_id = 0;
44
45     if (*gdbus_connection == NULL) {
46         GDBusConnection *conn = NULL;
47         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
48         if (conn == NULL) {
49             if (error != NULL) {
50                 LOGE("g_bus_get_sync error message = %s", error->message);
51                 g_error_free(error);
52             }
53             return STICKER_CLIENT_ERROR_IO_ERROR;
54         }
55         *gdbus_connection = conn;
56     }
57
58     LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection));
59     watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
60                 STICKER_DBUS_NAME,
61                 G_BUS_NAME_WATCHER_FLAGS_NONE,
62                 _server_appeared_cb,
63                 _server_vanished_cb,
64                 NULL, NULL);
65
66     LOGD("watch_id : %d", watch_id);
67     if (watch_id == 0) {
68         LOGE("Failed to get identifier");
69         return STICKER_CLIENT_ERROR_IO_ERROR;
70     }
71
72     return STICKER_CLIENT_ERROR_NONE;
73 }
74
75 static void _get_sticker_info_from_gvariant(GVariant *body, sticker_data_h sticker_data)
76 {
77     STICKER_DAT_TYPE key;
78     GVariant *value = NULL;
79     GVariantIter *info_iter = NULL;
80     GVariantIter *keyword_iter = NULL;
81     char *keyword = NULL;
82
83     g_variant_get(body, "(a{iv}a(s))", &info_iter, &keyword_iter);
84
85     if (!info_iter || !keyword_iter) {
86         LOGD("failed to get iter");
87         return;
88     }
89
90     while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
91         switch(key) {
92             case STICKER_DATA_TYPE_APP_ID:
93             sticker_data->app_id = g_variant_dup_string(value, NULL);
94             break;
95             case STICKER_DATA_TYPE_URI_TYPE:
96             sticker_data->type = g_variant_get_int32(value);
97             break;
98             case STICKER_DATA_TYPE_URI:
99             sticker_data->uri = g_variant_dup_string(value, NULL);
100             break;
101             case STICKER_DATA_TYPE_THUMBNAIL:
102             sticker_data->thumbnail = g_variant_dup_string(value, NULL);
103             break;
104             case STICKER_DATA_TYPE_DESCRIPTION:
105             sticker_data->description = g_variant_dup_string(value, NULL);
106             break;
107             case STICKER_DATA_TYPE_GROUP:
108             sticker_data->group = g_variant_dup_string(value, NULL);
109             break;
110             case STICKER_DATA_TYPE_DATE:
111             sticker_data->date = g_variant_dup_string(value, NULL);
112             break;
113             default:
114             break;
115         }
116     }
117
118     while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
119         sticker_data->keyword = g_list_append(sticker_data->keyword, strdup((const char *)keyword));
120     }
121
122     if (value)
123         g_variant_unref(value);
124
125     g_variant_iter_free(info_iter);
126     g_variant_iter_free(keyword_iter);
127 }
128
129 static void _free_sticker_data(sticker_data_h sticker_data)
130 {
131     if (sticker_data->app_id) {
132         free(sticker_data->app_id);
133         sticker_data->app_id = NULL;
134     }
135
136     if (sticker_data->uri) {
137         free(sticker_data->uri);
138         sticker_data->uri = NULL;
139     }
140
141     if (sticker_data->thumbnail) {
142         free(sticker_data->thumbnail);
143         sticker_data->thumbnail = NULL;
144     }
145
146     if (sticker_data->keyword) {
147         g_list_free_full(sticker_data->keyword, free);
148         sticker_data->keyword = NULL;
149     }
150
151     if (sticker_data->group) {
152         free(sticker_data->group);
153         sticker_data->group = NULL;
154     }
155
156     if (sticker_data->description) {
157         free(sticker_data->description);
158         sticker_data->description = NULL;
159     }
160
161     if (sticker_data->date) {
162         free(sticker_data->date);
163         sticker_data->date = NULL;
164     }
165
166     free(sticker_data);
167     sticker_data = NULL;
168 }
169
170 static void _call_insert_finished_cb(sticker_provider_h provider_handle, GVariant *body)
171 {
172     int ret;
173     g_variant_get(body, "(i)", &ret);
174
175     if (ret == 0) {
176         provider_handle->insert_finished_cb(STICKER_ERROR_NONE, provider_handle->insert_finished_cb_user_data);
177     } else {
178         provider_handle->insert_finished_cb(STICKER_ERROR_OPERATION_FAILED, provider_handle->insert_finished_cb_user_data);
179     }
180 }
181
182 //LCOV_EXCL_START
183 static void _handle_sticker_consumer_cb(GDBusConnection *connection,
184                                const gchar *sender_name,
185                                const gchar *object_path,
186                                const gchar *interface_name,
187                                const gchar *signal_name,
188                                GVariant *parameters,
189                                gpointer user_data)
190 {
191     LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
192     sticker_consumer_h consumer_handle = (sticker_consumer_h)user_data;
193
194     if (consumer_handle == NULL) {
195         LOGE("consumer handle is not available");
196         return;
197     }
198
199     if (parameters == NULL) {
200         LOGE("failed to get sticker info");
201         return;
202     }
203
204     #if 0 // Receive the sticker information by asynchronous communication.
205     if (g_strcmp0(signal_name, "send_group_list") == 0) {
206         if (consumer_handle->group_foreach_cb != NULL)
207             _call_sticker_list_cb(consumer_handle, parameters, signal_name);
208         return;
209     } else if (g_strcmp0(signal_name, "send_keyword_list") == 0) {
210         if (consumer_handle->keyword_foreach_cb != NULL)
211             _call_sticker_list_cb(consumer_handle, parameters, signal_name);
212         return;
213     }
214
215     sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
216
217     if (!sticker_data) {
218         LOGE("failed to allocate memory");
219         return;
220     }
221
222     _get_sticker_info_from_gvariant(parameters, sticker_data);
223
224     if (g_strcmp0(signal_name, "send_all_sticker_info") == 0) {
225         if (consumer_handle->data_foreach_cb != NULL)
226             consumer_handle->data_foreach_cb(sticker_data, consumer_handle->data_foreach_cb_user_data);
227         else
228             LOGW("No registered callback function");
229     } else if (g_strcmp0(signal_name, "send_sticker_info_by_keyword") == 0) {
230         if (consumer_handle->data_foreach_by_keyword_cb != NULL)
231             consumer_handle->data_foreach_by_keyword_cb(sticker_data, consumer_handle->data_foreach_by_keyword_cb_user_data);
232         else
233             LOGW("No registered callback function");
234     } else if (g_strcmp0(signal_name, "send_sticker_info_by_group") == 0) {
235         if (consumer_handle->data_foreach_by_group_cb != NULL)
236             consumer_handle->data_foreach_by_group_cb(sticker_data, consumer_handle->data_foreach_by_group_cb_user_data);
237         else
238             LOGW("No registered callback function");
239     } else if (g_strcmp0(signal_name, "send_sticker_info_by_type") == 0) {
240         if (consumer_handle->data_foreach_by_type_cb != NULL)
241             consumer_handle->data_foreach_by_type_cb(sticker_data, consumer_handle->data_foreach_by_type_cb_user_data);
242         else
243             LOGW("No registered callback function");
244     }
245
246     _free_sticker_data(sticker_data);
247     #endif
248 }
249 //LCOV_EXCL_STOP
250
251 static void _handle_sticker_provider_cb(GDBusConnection *connection,
252                                const gchar *sender_name,
253                                const gchar *object_path,
254                                const gchar *interface_name,
255                                const gchar *signal_name,
256                                GVariant *parameters,
257                                gpointer user_data)
258 {
259     LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
260     sticker_provider_h provider_handle = (sticker_provider_h)user_data;
261
262     if (provider_handle == NULL) {
263         LOGE("provider handle is not available");
264         return;
265     }
266
267     if (parameters == NULL) {
268         LOGE("failed to get sticker info");
269         return;
270     }
271
272     if (g_strcmp0(signal_name, "send_insert_result") == 0) {
273         if (provider_handle->insert_finished_cb != NULL)
274             _call_insert_finished_cb(provider_handle, parameters);
275     }
276
277     #if 0 // Receive the sticker information by asynchronous communication.
278     sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
279
280     if (!sticker_data) {
281         LOGE("failed to allocate memory");
282         return;
283     }
284
285     _get_sticker_info_from_gvariant(parameters, sticker_data);
286
287     if (g_strcmp0(signal_name, "send_sticker_info_by_appid") == 0) {
288         if (provider_handle->data_foreach_cb != NULL)
289             provider_handle->data_foreach_cb(sticker_data, provider_handle->data_foreach_cb_user_data);
290         else
291             LOGW("No registered callback function");
292     }
293
294     _free_sticker_data(sticker_data);
295     #endif
296 }
297
298 static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
299 {
300     int ret = STICKER_CLIENT_ERROR_NONE;
301     if (*monitor_id == 0) {
302         int id = 0;
303         if (lib == STICKER_CLIENT_LIB_CONSUMER)
304             id = g_dbus_connection_signal_subscribe(gdbus_connection,
305                                                     STICKER_DBUS_NAME,
306                                                     STICKER_CONSUMER_INTERFACE_NAME,
307                                                     NULL,
308                                                     STICKER_OBJECT_PATH,
309                                                     NULL,
310                                                     G_DBUS_SIGNAL_FLAGS_NONE,
311                                                     _handle_sticker_consumer_cb,
312                                                     data,
313                                                     NULL);
314         else if (lib == STICKER_CLIENT_LIB_PROVIDER)
315             id = g_dbus_connection_signal_subscribe(gdbus_connection,
316                                                     STICKER_DBUS_NAME,
317                                                     STICKER_PROVIDER_INTERFACE_NAME,
318                                                     NULL,
319                                                     STICKER_OBJECT_PATH,
320                                                     NULL,
321                                                     G_DBUS_SIGNAL_FLAGS_NONE,
322                                                     _handle_sticker_provider_cb,
323                                                     data,
324                                                     NULL);
325         LOGD("id : %d", id);
326         if (id == 0) {
327             ret = STICKER_CLIENT_ERROR_IO_ERROR;
328             LOGE("g_dbus_connection_signal_subscribe() failed");
329         } else {
330             *monitor_id = id;
331         }
332     }
333
334     return ret;
335 }
336
337 static GDBusMessage *_get_gbus_message(GVariant *body, const char *cmd)
338 {
339     GDBusMessage *message = NULL;
340     message = g_dbus_message_new_method_call(
341         STICKER_DBUS_NAME,
342         STICKER_OBJECT_PATH,
343         STICKER_INTERFACE_NAME,
344         cmd);
345
346     if (!message) {
347         LOGE("Failed to create a new gdbus message");
348         if (body)
349             g_variant_unref(body);
350         return NULL;
351     }
352
353     if (body != NULL)
354         g_dbus_message_set_body(message, body);
355
356     return message;
357 }
358
359 static int _send_gdbus_sync_message(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
360 {
361     int ret = STICKER_CLIENT_ERROR_NONE;
362     GError *err = NULL;
363
364     *reply = g_dbus_connection_send_message_with_reply_sync(
365             gdbus_connection,
366             msg,
367             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
368             -1,
369             NULL,
370             NULL,
371             &err);
372
373     if (!*reply) {
374         ret = STICKER_CLIENT_ERROR_SERVICE_NOT_READY;
375         if (err != NULL) {
376             LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
377             if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
378                 ret = STICKER_CLIENT_ERROR_PERMISSION_DENIED;
379             g_error_free(err);
380         }
381         return ret;
382     }
383
384     if (g_dbus_message_to_gerror(*reply, &err)) {
385         LOGE("error message = %s, code = %d", err->message, err->code);
386         if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
387             ret = STICKER_CLIENT_ERROR_PERMISSION_DENIED;
388         else
389             ret = err->code;
390         g_error_free(err);
391         return ret;
392     }
393
394     LOGD("Send a message to server(cmd : %s)", cmd);
395     return STICKER_CLIENT_ERROR_NONE;
396 }
397
398 static int _send_sync_message(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
399 {
400     int ret = STICKER_CLIENT_ERROR_NONE;
401     GDBusMessage *msg = NULL;
402
403     msg = _get_gbus_message(body, cmd);
404     if (msg == NULL)
405         return STICKER_CLIENT_ERROR_IO_ERROR;
406
407     ret = _send_gdbus_sync_message(gdbus_connection, msg, reply, cmd);
408
409     if (msg)
410         g_object_unref(msg);
411
412     return ret;
413 }
414
415 static int _send_async_message(GDBusConnection *gdbus_connection, GVariant *body, char *cmd)
416 {
417     int ret = STICKER_CLIENT_ERROR_NONE;
418     GDBusMessage *msg = NULL;
419     GError *err = NULL;
420
421     msg = _get_gbus_message(body, cmd);
422     if (msg == NULL)
423         return STICKER_CLIENT_ERROR_IO_ERROR;
424
425     g_dbus_connection_send_message(gdbus_connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
426
427     if (msg)
428         g_object_unref(msg);
429
430     if (err != NULL) {
431         ret = STICKER_CLIENT_ERROR_SERVICE_NOT_READY;
432         LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
433
434         if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
435             ret = STICKER_CLIENT_ERROR_PERMISSION_DENIED;
436
437         g_error_free(err);
438         return ret;
439     }
440
441     return ret;
442 }
443
444 static int _monitor_register(GDBusConnection *gdbus_connection, int *server_watcher_id)
445 {
446     int ret;
447     GDBusMessage *reply = NULL;
448     GVariant *reply_body = NULL;
449
450     ret = _send_sync_message(gdbus_connection, g_variant_new("()"), &reply, "sticker_service_register");
451
452     if (ret != STICKER_CLIENT_ERROR_NONE) {
453         LOGE("_send_sync_message() failed : %d", ret);
454         return ret;
455     }
456
457     reply_body = g_dbus_message_get_body(reply);
458     g_variant_get(reply_body, "(i)", server_watcher_id);
459
460     if (reply)
461         g_object_unref(reply);
462
463     is_server_started = 1;
464     return ret;
465 }
466
467 static void _on_name_appeared(GDBusConnection *connection,
468         const gchar     *name,
469         const gchar     *name_owner,
470         gpointer         user_data)
471 {
472     if (is_server_started == 0) {
473         int *watcher_id = (int *)user_data;
474         _monitor_register(connection, watcher_id);
475     }
476 }
477
478 //LCOV_EXCL_START
479 static void _on_name_vanished(GDBusConnection *connection,
480         const gchar     *name,
481         gpointer         user_data)
482 {
483     is_server_started = 0;
484 }
485 //LCOV_EXCL_STOP
486
487 int sticker_dbus_init(GDBusConnection **gdbus_connection, int *server_watcher_id,
488                       int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
489 {
490     int ret;
491
492     ret = _dbus_init(gdbus_connection);
493     if (ret != STICKER_CLIENT_ERROR_NONE) {
494         LOGE("_dbus_init() failed : %d", ret);
495         return ret;
496     }
497
498     ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
499     if (ret != STICKER_CLIENT_ERROR_NONE) {
500         LOGE("_dbus_signal_init() failed : %d", ret);
501         return ret;
502     }
503
504     ret = _monitor_register(*gdbus_connection, server_watcher_id);
505     if (ret != STICKER_CLIENT_ERROR_NONE) {
506         LOGE("_monitor_register() failed : %d", ret);
507         return ret;
508     }
509
510     if (*server_monitor_id == 0) {
511         *server_monitor_id = g_bus_watch_name_on_connection(
512                 *gdbus_connection,
513                 STICKER_DBUS_NAME,
514                 G_BUS_NAME_WATCHER_FLAGS_NONE,
515                 _on_name_appeared,
516                 _on_name_vanished,
517                 server_watcher_id,
518                 NULL);
519         if (*server_monitor_id == 0) {
520             g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
521             *monitor_id = 0;
522             LOGE("Failed to get identifier");
523             return STICKER_CLIENT_ERROR_IO_ERROR;
524         }
525     }
526
527     return STICKER_CLIENT_ERROR_NONE;
528 }
529
530 int sticker_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_watcher_id, int *server_monitor_id, int *monitor_id)
531 {
532     int ret;
533     GVariant *body = NULL;
534
535     if (server_watcher_id) {
536         body = g_variant_new("(i)", *server_watcher_id);
537         ret = _send_async_message(gdbus_connection, body, "sticker_service_unregister");
538         if (ret != STICKER_CLIENT_ERROR_NONE) {
539             LOGE("Failed to unregister sticker service");
540             return ret;
541         }
542
543         *server_watcher_id = 0;
544     }
545
546     if (*server_monitor_id) {
547         g_bus_unwatch_name(*server_monitor_id);
548         *server_monitor_id = 0;
549     }
550
551     if (*monitor_id) {
552         g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
553         *monitor_id = 0;
554     }
555
556     if (body)
557         g_variant_unref(body);
558
559     return STICKER_CLIENT_ERROR_NONE;
560 }
561
562 static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
563 {
564     if (!keyword) {
565         LOGE("keyword doesn't exist");
566         return;
567     }
568
569     g_variant_builder_add(keyword_builder, "(s)", (const char *)keyword);
570 }
571
572 int sticker_dbus_insert_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data)
573 {
574     int ret;
575     int ret_id = -1;
576     GDBusMessage *reply = NULL;
577     GVariant *body = NULL;
578     GVariant *reply_body = NULL;
579     GVariantBuilder *info_builder;
580     GVariantBuilder *keyword_builder;
581
582     if (!sticker_data->app_id || (sticker_data->type < 1) || !sticker_data->uri || !sticker_data->group || !sticker_data->keyword)
583         return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
584
585     info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
586     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_data->app_id));
587     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_data->type));
588     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_data->uri));
589     if (sticker_data->thumbnail)
590         g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_data->thumbnail));
591     if (sticker_data->description)
592         g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_data->description));
593     g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_data->group));
594
595     keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
596     g_list_foreach(sticker_data->keyword, (GFunc) _set_keyword_builder, keyword_builder);
597
598     body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
599
600     g_variant_builder_unref(info_builder);
601     g_variant_builder_unref(keyword_builder);
602
603     ret = _send_sync_message(gdbus_connection, body, &reply, "insert_sticker_info");
604     if (ret != STICKER_CLIENT_ERROR_NONE) {
605         LOGW("Failed to save sticker info");
606         return ret;
607     }
608
609     reply_body = g_dbus_message_get_body(reply);
610     g_variant_get(reply_body, "(i)", &ret_id);
611     sticker_data->sticker_info_id = ret_id;
612
613     LOGD("ret_id : %d", ret_id);
614     if (body)
615         g_variant_unref(body);
616
617     if (reply_body)
618         g_variant_unref(reply_body);
619
620     if (reply)
621         g_object_unref(reply);
622
623     return ret;
624 }
625
626 int sticker_dbus_insert_sticker_info_by_json(GDBusConnection *gdbus_connection, const char *app_id, const char *json_path)
627 {
628     int ret;
629     GVariant *body = NULL;
630
631     body = g_variant_new("(ss)", app_id, json_path);
632     ret = _send_async_message(gdbus_connection, body, "update_sticker_info_by_json");
633     if (ret != STICKER_CLIENT_ERROR_NONE)
634         LOGE("failed to send json path");
635
636     if (body)
637         g_variant_unref(body);
638
639     return ret;
640 }
641
642 int sticker_dbus_delete_sticker_info(GDBusConnection *gdbus_connection, int record_id)
643 {
644     int ret;
645     GDBusMessage *reply = NULL;
646     GVariant *body = NULL;
647
648     body = g_variant_new("(i)", record_id);
649     ret = _send_sync_message(gdbus_connection, body, &reply, "delete_sticker_info");
650     if (ret != STICKER_CLIENT_ERROR_NONE)
651         LOGE("failed to delete sticker info");
652
653     if (body)
654         g_variant_unref(body);
655
656     if (reply)
657         g_object_unref(reply);
658
659     return ret;
660 }
661
662 int sticker_dbus_update_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data)
663 {
664     int ret;
665     GDBusMessage *reply = NULL;
666     GVariant *body = NULL;
667     GVariant *reply_body = NULL;
668     sticker_data_h origin_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
669
670     if (!origin_data) {
671         LOGE("failed to allocate memory");
672         return STICKER_CLIENT_ERROR_OUT_OF_MEMORY;
673     }
674
675     body = g_variant_new("(i)", sticker_data->sticker_info_id);
676     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info");
677
678     if (ret == STICKER_CLIENT_ERROR_NONE) {
679         reply_body = g_dbus_message_get_body(reply);
680         _get_sticker_info_from_gvariant(reply_body, origin_data);
681     } else {
682         LOGW("failed to get sticker info");
683         free(origin_data);
684         if (reply)
685             g_object_unref(reply);
686         if (body)
687             g_variant_unref(body);
688         return ret;
689     }
690
691     if (sticker_data->type != 0 && sticker_data->type != origin_data->type) {
692         LOGD("origin_type : %d, new_type : %d", origin_data->type, sticker_data->type);
693         g_variant_unref(body);
694         body = g_variant_new("(ii)", sticker_data->sticker_info_id, sticker_data->type);
695         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_type");
696         if (ret != STICKER_CLIENT_ERROR_NONE)
697             LOGE("failed to update sticker type");
698     }
699
700     if (sticker_data->uri && strcmp(sticker_data->uri, origin_data->uri) != 0) {
701         LOGD("origin_uri : %s, new_uri : %s", origin_data->uri, sticker_data->uri);
702         g_variant_unref(body);
703         body = g_variant_new("(isis)", sticker_data->sticker_info_id, sticker_data->app_id, sticker_data->type, sticker_data->uri);
704         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_uri");
705         if (ret != STICKER_CLIENT_ERROR_NONE)
706             LOGE("failed to update sticker uri");
707     }
708
709     if (sticker_data->thumbnail && strcmp(sticker_data->thumbnail, origin_data->thumbnail) != 0) {
710         LOGD("origin_thumbnail : %s, new_thumbnail : %s", origin_data->thumbnail, sticker_data->thumbnail);
711         g_variant_unref(body);
712         body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->thumbnail);
713         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_thumbnail");
714         if (ret != STICKER_CLIENT_ERROR_NONE)
715             LOGE("failed to update sticker thumbnail");
716     }
717
718     if (sticker_data->description && strcmp(sticker_data->description, origin_data->description) != 0) {
719         LOGD("origin_description : %s, new_description : %s", origin_data->description, sticker_data->description);
720         g_variant_unref(body);
721         body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->description);
722         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_description");
723         if (ret != STICKER_CLIENT_ERROR_NONE)
724             LOGE("failed to update sticker description");
725     }
726
727     if (sticker_data->group && strcmp(sticker_data->group, origin_data->group) != 0) {
728         LOGD("origin_group : %s, new_group : %s", origin_data->group, sticker_data->group);
729         g_variant_unref(body);
730         body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->group);
731         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_group");
732         if (ret != STICKER_CLIENT_ERROR_NONE)
733             LOGE("failed to update sticker group");
734     }
735
736     if (sticker_data->keyword) {
737         GVariantBuilder *keyword_builder;
738         g_variant_unref(body);
739         keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
740         g_list_foreach(sticker_data->keyword, (GFunc) _set_keyword_builder, keyword_builder);
741         body = g_variant_new("(ia(s))", sticker_data->sticker_info_id, keyword_builder);
742         ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_keyword");
743         if (ret != STICKER_CLIENT_ERROR_NONE)
744             LOGE("failed to update sticker keyword");
745     }
746
747     _free_sticker_data(origin_data);
748
749     if (body)
750         g_variant_unref(body);
751
752     if (reply_body)
753         g_variant_unref(reply_body);
754
755     if (reply)
756         g_object_unref(reply);
757
758     return ret;
759 }
760
761 int sticker_dbus_get_sticker_info_by_record_id(GDBusConnection *gdbus_connection, sticker_data_h sticker_data, int record_id)
762 {
763     int ret;
764     GDBusMessage *reply = NULL;
765     GVariant *body = NULL;
766     GVariant *reply_body = NULL;
767
768     body = g_variant_new("(i)", record_id);
769     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info");
770
771     if (ret == STICKER_CLIENT_ERROR_NONE) {
772         reply_body = g_dbus_message_get_body(reply);
773         sticker_data->sticker_info_id = record_id;
774         _get_sticker_info_from_gvariant(reply_body, sticker_data);
775
776         if (reply_body)
777             g_variant_unref(reply_body);
778     }
779
780     if (body)
781         g_variant_unref(body);
782
783     if (reply)
784         g_object_unref(reply);
785
786     return ret;
787 }
788
789 int sticker_dbus_get_group_list(GDBusConnection *gdbus_connection, GList **group_list)
790 {
791     int ret;
792     GDBusMessage *reply = NULL;
793     GVariantIter *iter = NULL;
794     GVariant *body = NULL;
795     GVariant *reply_body = NULL;
796     char *group = NULL;
797
798     if (group_list == NULL) {
799         LOGE("group_list is invalid");
800         return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
801     }
802
803     body = g_variant_new("()");
804     ret = _send_sync_message(gdbus_connection, body, &reply, "get_group_list");
805
806     if (ret == STICKER_CLIENT_ERROR_NONE) {
807         reply_body = g_dbus_message_get_body(reply);
808         g_variant_get(reply_body, "(a(s))", &iter);
809
810         if (!iter) {
811             LOGD("failed to get iter");
812             return STICKER_CLIENT_ERROR_OPERATION_FAILED;
813         }
814
815         while (g_variant_iter_loop (iter, "(s)", &group)) {
816             *group_list = g_list_append(*group_list, strdup((const char *)group));
817         }
818
819         g_variant_iter_free(iter);
820     }
821
822     if (body)
823         g_variant_unref(body);
824
825     if (reply_body)
826         g_variant_unref(reply_body);
827
828     if (reply)
829         g_object_unref(reply);
830
831     return ret;
832 }
833
834 int sticker_dbus_get_keyword_list(GDBusConnection *gdbus_connection, GList **keyword_list)
835 {
836     int ret;
837     GDBusMessage *reply = NULL;
838     GVariantIter *iter = NULL;
839     GVariant *body = NULL;
840     GVariant *reply_body = NULL;
841     char *keyword = NULL;
842
843     if (keyword_list == NULL) {
844         LOGE("keyword_list is invalid");
845         return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
846     }
847
848     body = g_variant_new("()");
849     ret = _send_sync_message(gdbus_connection, body, &reply, "get_keyword_list");
850
851     if (ret == STICKER_CLIENT_ERROR_NONE) {
852         reply_body = g_dbus_message_get_body(reply);
853         g_variant_get(reply_body, "(a(s))", &iter);
854
855         if (!iter) {
856             LOGD("failed to get iter");
857             return STICKER_CLIENT_ERROR_OPERATION_FAILED;
858         }
859
860         while (g_variant_iter_loop (iter, "(s)", &keyword)) {
861             *keyword_list = g_list_append(*keyword_list, strdup((const char *)keyword));
862         }
863
864         g_variant_iter_free(iter);
865     }
866
867     if (body)
868         g_variant_unref(body);
869
870     if (reply_body)
871         g_variant_unref(reply_body);
872
873     if (reply)
874         g_object_unref(reply);
875
876     return ret;
877 }
878
879 int sticker_dbus_get_sticker_count(GDBusConnection *gdbus_connection, const char *app_id, int *count)
880 {
881     int ret;
882     GDBusMessage *reply = NULL;
883     GVariant *body = NULL;
884     GVariant *reply_body = NULL;
885
886     body = g_variant_new("(s)", app_id);
887     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_count");
888
889     if (ret == STICKER_CLIENT_ERROR_NONE) {
890         reply_body = g_dbus_message_get_body(reply);
891         g_variant_get(reply_body, "(i)", count);
892     }
893
894     if (body)
895         g_variant_unref(body);
896
897     if (reply_body)
898         g_variant_unref(reply_body);
899
900     if (reply)
901         g_object_unref(reply);
902
903     return ret;
904 }
905
906 int sticker_dbus_get_all_sticker_info(GDBusConnection *gdbus_connection, int offset, int count, GVariantIter **id_iter)
907 {
908     int ret;
909     GDBusMessage *reply = NULL;
910     GVariant *body = NULL;
911     GVariant *reply_body = NULL;
912
913     body = g_variant_new("(ii)", offset, count);
914     ret = _send_sync_message(gdbus_connection, body, &reply, "get_all_sticker_info");
915     if (ret == STICKER_CLIENT_ERROR_NONE) {
916         reply_body = g_dbus_message_get_body(reply);
917         g_variant_get(reply_body, "(a(i))", &(*id_iter));
918     }
919
920     if (body)
921         g_variant_unref(body);
922
923     if (reply_body)
924         g_variant_unref(reply_body);
925
926     if (reply)
927         g_object_unref(reply);
928
929     return ret;
930 }
931
932 int sticker_dbus_get_sticker_info_by_appid(GDBusConnection *gdbus_connection, const char *app_id, int offset, int count, GVariantIter **id_iter)
933 {
934     int ret;
935     GDBusMessage *reply = NULL;
936     GVariant *body = NULL;
937     GVariant *reply_body = NULL;
938
939     body = g_variant_new("(sii)", app_id, offset, count);
940     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_appid");
941     if (ret == STICKER_CLIENT_ERROR_NONE) {
942         reply_body = g_dbus_message_get_body(reply);
943         g_variant_get(reply_body, "(a(i))", &(*id_iter));
944     }
945
946     if (body)
947         g_variant_unref(body);
948
949     if (reply_body)
950         g_variant_unref(reply_body);
951
952     if (reply)
953         g_object_unref(reply);
954
955     return ret;
956 }
957
958 int sticker_dbus_get_sticker_info_by_type(GDBusConnection *gdbus_connection, sticker_data_uri_type_e type, int offset, int count, GVariantIter **id_iter)
959 {
960     int ret;
961     GDBusMessage *reply = NULL;
962     GVariant *body = NULL;
963     GVariant *reply_body = NULL;
964
965     body = g_variant_new("(iii)", (int)type, offset, count);
966     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_type");
967     if (ret == STICKER_CLIENT_ERROR_NONE) {
968         reply_body = g_dbus_message_get_body(reply);
969         g_variant_get(reply_body, "(a(i))", &(*id_iter));
970     }
971
972     if (body)
973         g_variant_unref(body);
974
975     if (reply_body)
976         g_variant_unref(reply_body);
977
978     if (reply)
979         g_object_unref(reply);
980
981     return ret;
982 }
983
984 int sticker_dbus_get_sticker_info_by_group(GDBusConnection *gdbus_connection, const char *group, int offset, int count, GVariantIter **id_iter)
985 {
986     int ret;
987     GDBusMessage *reply = NULL;
988     GVariant *body = NULL;
989     GVariant *reply_body = NULL;
990
991     body = g_variant_new("(sii)", group, offset, count);
992     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_group");
993     if (ret == STICKER_CLIENT_ERROR_NONE) {
994         reply_body = g_dbus_message_get_body(reply);
995         g_variant_get(reply_body, "(a(i))", &(*id_iter));
996     }
997
998     if (body)
999         g_variant_unref(body);
1000
1001     if (reply_body)
1002         g_variant_unref(reply_body);
1003
1004     if (reply)
1005         g_object_unref(reply);
1006
1007     return ret;
1008 }
1009
1010 int sticker_dbus_get_sticker_info_by_keyword(GDBusConnection *gdbus_connection, const char *keyword, int offset, int count, GVariantIter **id_iter)
1011 {
1012     int ret;
1013     GDBusMessage *reply = NULL;
1014     GVariant *body = NULL;
1015     GVariant *reply_body = NULL;
1016
1017     body = g_variant_new("(sii)", keyword, offset, count);
1018     ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_keyword");
1019     if (ret == STICKER_CLIENT_ERROR_NONE) {
1020         reply_body = g_dbus_message_get_body(reply);
1021         g_variant_get(reply_body, "(a(i))", &(*id_iter));
1022     }
1023
1024     if (body)
1025         g_variant_unref(body);
1026
1027     if (reply_body)
1028         g_variant_unref(reply_body);
1029
1030     if (reply)
1031         g_object_unref(reply);
1032
1033     return ret;
1034 }