Fix build error in sticker-receiver
[platform/core/uifw/capi-ui-sticker.git] / server / stickerd_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 <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <gio/gio.h>
21 #include <dlog.h>
22
23 #include "stickerd_dbus.h"
24 #include "stickerd_error.h"
25
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29 #define LOG_TAG "STICKERD_DBUS"
30
31 static GDBusConnection *_gdbus_connection;
32 extern GMainLoop *main_loop;
33
34 int stickerd_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler,
35         GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash, GList **consumer_list)
36 {
37     int ret = STICKERD_SERVER_ERROR_NONE;
38     char *m_info_bus_name = NULL;
39     char *list_bus_name = NULL;
40     monitoring_info_s *m_info = NULL;
41     GList *monitoring_list = NULL;
42     int c_lib;
43
44     g_variant_get(parameters, "(i)", &c_lib);
45
46     if (reply_body == NULL)
47         return STICKERD_SERVER_ERROR_INVALID_PARAMETER;
48
49     m_info_bus_name = strdup(sender);
50     list_bus_name = strdup(sender);
51     if (m_info_bus_name == NULL || list_bus_name == NULL) {
52         ret = STICKERD_SERVER_ERROR_IO_ERROR;
53         goto cleanup;
54     }
55
56     LOGD("Add a new sender");
57     m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
58     if (m_info == NULL) {
59         LOGE("Failed to alloc memory");
60         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
61         goto cleanup;
62     }
63
64     m_info->bus_name = m_info_bus_name;
65     m_info->watcher_id = g_bus_watch_name_on_connection(
66             _gdbus_connection,
67             m_info_bus_name,
68             G_BUS_NAME_WATCHER_FLAGS_NONE,
69             name_appeared_handler,
70             name_vanished_handler,
71             m_info,
72             NULL);
73     if (m_info->watcher_id == 0) {
74         LOGE("Failed to get identifier");
75         ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
76         goto cleanup;
77     }
78
79     *reply_body = g_variant_new("(i)", m_info->watcher_id);
80     if (*reply_body == NULL) {
81         LOGE("Failed to make reply");
82         ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
83         goto cleanup;
84     }
85
86     if ((CLIENT_LIB)c_lib == STICKER_CLIENT_LIB_CONSUMER)
87         *consumer_list = g_list_append(*consumer_list, strdup((const char *)sender));
88
89     LOGD("sender: %s, watcher: %d", sender, m_info->watcher_id);
90     monitoring_list = g_list_append(monitoring_list, list_bus_name);
91     if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(m_info->watcher_id)) == NULL)
92         g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(m_info->watcher_id), monitoring_list);
93     else
94         LOGW("Sender(%s) already exist", sender);
95
96     return STICKERD_SERVER_ERROR_NONE;
97
98 cleanup:
99     if (m_info_bus_name)
100         free(m_info_bus_name);
101
102     if (list_bus_name)
103         free(list_bus_name);
104
105     if (m_info) {
106         free(m_info);
107         m_info = NULL;
108     }
109
110     return ret;
111 }
112
113 int stickerd_server_unregister(GVariant *parameters, GVariant **reply_body, const gchar *sender, GHashTable **monitoring_hash, GList **consumer_list)
114 {
115     int watcher_id = 0;
116     int c_lib;
117
118     g_variant_get(parameters, "(ii)", &c_lib, &watcher_id);
119
120     if ((CLIENT_LIB)c_lib == STICKER_CLIENT_LIB_CONSUMER)
121         *consumer_list = g_list_remove(*consumer_list, sender);
122
123     if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id)) != NULL) {
124         g_bus_unwatch_name(watcher_id);
125         delete_monitoring_list(monitoring_hash, sender, watcher_id);
126     }
127
128     return STICKERD_SERVER_ERROR_NONE;
129 }
130
131 int stickerd_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
132 {
133     int result;
134     int own_id, registration_id;
135     GError *error = NULL;
136     GDBusNodeInfo *introspection_data = NULL;
137
138     if (_gdbus_connection == NULL) {
139         _gdbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
140         if (_gdbus_connection == NULL) {
141             if (error != NULL) {
142                 LOGE("g_bus_get_sync error message = %s", error->message);
143                 g_error_free(error);
144             }
145             result = STICKERD_SERVER_ERROR_IO_ERROR;
146             goto cleanup;
147         }
148     }
149
150     own_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
151             STICKER_DBUS_NAME,
152             G_BUS_NAME_OWNER_FLAGS_NONE,
153             NULL,
154             NULL,
155             NULL,
156             NULL, NULL);
157     if (own_id == 0) {
158         LOGE("Failed to register bus name");
159         result = STICKERD_SERVER_ERROR_IO_ERROR;
160         goto cleanup;
161     }
162
163     LOGD("own_id = %d", own_id);
164
165     introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
166     if (introspection_data == NULL) {
167         LOGE("Failed to get GDBusNodeInfo");
168         result = STICKERD_SERVER_ERROR_IO_ERROR;
169         if (error != NULL) {
170             LOGE("g_dbus_node_info_new_for_xml error message = %s", error->message);
171             g_error_free(error);
172         }
173         goto cleanup;
174     }
175
176     registration_id = g_dbus_connection_register_object(_gdbus_connection, STICKER_OBJECT_PATH,
177         introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL);
178     LOGD("registration_id = %d", registration_id);
179     if (registration_id == 0) {
180         LOGE("Failed to register object");
181         result = STICKERD_SERVER_ERROR_IO_ERROR;
182         goto cleanup;
183     }
184
185     return STICKERD_SERVER_ERROR_NONE;
186
187 cleanup:
188     if (introspection_data)
189         g_dbus_node_info_unref(introspection_data);
190
191     return result;
192 }
193
194 int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, int watcher_id)
195 {
196     GList *monitoring_list = NULL;
197     GList *del_list = NULL;
198     char *bus_name;
199
200     monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
201     if (monitoring_list == NULL) {
202         LOGE("The key(%d) is not found", watcher_id);
203         return STICKERD_SERVER_ERROR_IO_ERROR;
204     }
205
206     monitoring_list = g_list_first(monitoring_list);
207     del_list = g_list_find_custom(monitoring_list, sender, (GCompareFunc) strcmp);
208
209     if (del_list) {
210         LOGD("Delete sender(%s)", sender);
211         bus_name = g_list_nth_data(del_list, 0);
212         if (bus_name)
213             free(bus_name);
214         monitoring_list = g_list_delete_link(monitoring_list, del_list);
215
216         if (monitoring_list == NULL) {
217             g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(watcher_id));
218         } else {
219             monitoring_list = g_list_first(monitoring_list);
220             g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(watcher_id), monitoring_list);
221         }
222     }
223     return STICKERD_SERVER_ERROR_NONE;
224 }
225
226 int stickerd_send_dbus_message(GVariant *body, const char *dest, char *cmd, CLIENT_LIB lib)
227 {
228     GError *err = NULL;
229     char *interface = NULL;
230
231     if (lib == STICKER_CLIENT_LIB_PROVIDER)
232         interface = STICKER_PROVIDER_INTERFACE_NAME;
233     else if (lib == STICKER_CLIENT_LIB_CONSUMER)
234         interface = STICKER_CONSUMER_INTERFACE_NAME;
235
236     if (g_variant_is_floating(body))
237         g_variant_ref(body);
238
239     if (!g_dbus_connection_emit_signal(_gdbus_connection,
240                                       dest,
241                                       STICKER_OBJECT_PATH,
242                                       interface,
243                                       cmd,
244                                       body,
245                                       &err)) {
246         if (err != NULL) {
247             LOGE("Failed to send dbus message : %s", err->message);
248             g_error_free(err);
249         }
250
251         return STICKERD_SERVER_ERROR_IO_ERROR;
252     }
253
254     LOGD("Send message to client : %s", cmd);
255     return STICKERD_SERVER_ERROR_NONE;
256 }