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