Fix invalid licenses
[platform/framework/web/crosswalk-tizen.git] / src / common / dbus_server.cc
1 /*
2  * Copyright (c) 2015 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 "common/dbus_server.h"
18
19 #include "common/logger.h"
20
21 namespace wrt {
22
23 namespace {
24
25 static void OnMethodCall(GDBusConnection* connection,
26                          const gchar* /*sender*/,
27                          const gchar* /*object_path*/,
28                          const gchar* interface_name,
29                          const gchar* method_name,
30                          GVariant* parameters,
31                          GDBusMethodInvocation* invocation,
32                          gpointer user_data) {
33   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
34   if (!self) {
35     LOGGER(ERROR) << "DBusServer is NULL.";
36     return;
37   }
38   auto callback = self->GetMethodCallback(interface_name);
39   if (callback) {
40     callback(connection, method_name, parameters, invocation);
41   }
42 }
43
44 static GVariant* OnGetProperty(GDBusConnection* connection,
45                                const gchar* /*sender*/,
46                                const gchar* /*object_path*/,
47                                const gchar* interface_name,
48                                const gchar* property_name,
49                                GError** /*error*/,
50                                gpointer user_data) {
51   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
52   if (!self) {
53     LOGGER(ERROR) << "DBusServer is NULL.";
54     return NULL;
55   }
56
57   auto callback =
58       self->GetPropertyGetter(interface_name);
59
60   GVariant* ret = NULL;
61   if (callback) {
62     ret = callback(connection, property_name);
63   }
64
65   return ret;
66 }
67
68 static gboolean OnSetProperty(GDBusConnection* connection,
69                               const gchar* /*sender*/,
70                               const gchar* /*object_path*/,
71                               const gchar* interface_name,
72                               const gchar* property_name,
73                               GVariant* value,
74                               GError** /*error*/,
75                               gpointer user_data) {
76   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
77   if (!self) {
78     LOGGER(ERROR) << "DBusServer is NULL.";
79     return FALSE;
80   }
81
82   auto callback =
83       self->GetPropertySetter(interface_name);
84
85   gboolean ret = FALSE;
86   if (callback) {
87     if (callback(connection, property_name, value)) {
88       ret = TRUE;
89     }
90   }
91
92   return ret;
93 }
94
95 static const GDBusInterfaceVTable kInterfaceVTable = {
96   OnMethodCall,
97   OnGetProperty,
98   OnSetProperty
99 };
100
101 static void OnClosedConnection(GDBusConnection* connection,
102                                gboolean /*remote_peer_vanished*/,
103                                GError* /*error*/,
104                                gpointer user_data) {
105   g_signal_handlers_disconnect_by_func(connection,
106                                        (gpointer)OnClosedConnection,
107                                        user_data);
108   g_object_unref(connection);
109 }
110
111 static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
112                                 GDBusConnection* connection,
113                                 gpointer user_data) {
114   GError* err = NULL;
115   DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
116
117   g_signal_connect(connection, "closed",
118                    G_CALLBACK(OnClosedConnection), self);
119
120   if (self) {
121     // Check Peer Credentials
122     DBusServer::PeerCredentialsCallback callback =
123         self->GetPeerCredentialsCallback();
124     if (callback && !callback(
125         g_dbus_connection_get_peer_credentials(connection))) {
126       LOGGER(WARN) << "Invalid peer credentials.";
127       g_dbus_connection_close_sync(connection, NULL, NULL);
128     }
129
130     GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
131     if (!node_info) {
132       LOGGER(ERROR) << "Introspection is not set.";
133       return TRUE;
134     }
135
136     // TODO(wy80.choi): register multiple interfaces
137     g_object_ref(connection);
138     guint reg_id = g_dbus_connection_register_object(
139                           connection,
140                           "/",
141                           node_info->interfaces[0],
142                           &kInterfaceVTable,
143                           self,
144                           NULL,
145                           &err);
146     if (reg_id == 0) {
147       LOGGER(ERROR) << "Failed to register object : " << err->message;
148       g_error_free(err);
149     }
150   }
151   return TRUE;
152 }
153
154 }  // namespace
155
156 DBusServer::DBusServer()
157     : server_(NULL),
158       node_info_(NULL) {
159 }
160
161 DBusServer::~DBusServer() {
162   if (node_info_) {
163     g_dbus_node_info_unref(node_info_);
164   }
165
166   if (server_) {
167     g_object_unref(server_);
168   }
169
170   if (!address_path_.empty()) {
171     unlink(address_path_.c_str());
172   }
173 }
174
175 void DBusServer::Start(const std::string& name) {
176   GError* err = NULL;
177
178   address_path_.clear();
179   address_path_.append(g_get_user_runtime_dir());
180   address_path_.append("/.");
181   address_path_.append(name);
182   // unlink existing bus address
183   unlink(address_path_.c_str());
184
185   std::string address("unix:path=");
186   address.append(address_path_);
187
188   // create new bus socket
189   // TODO(wy80.choi): bus socket (Address) should be removed gracefully
190   // when application is terminated.
191   gchar* guid = g_dbus_generate_guid();
192   server_ = g_dbus_server_new_sync(
193                   address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
194                   guid, NULL, NULL, &err);
195   g_free(guid);
196   if (!server_) {
197     LOGGER(ERROR) << "Failed to create dbus server : " << err->message;
198     g_error_free(err);
199     return;
200   }
201
202   // start server
203   g_signal_connect(server_, "new-connection",
204                    G_CALLBACK(OnClientRequest), this);
205
206   g_dbus_server_start(server_);
207 }
208
209 std::string DBusServer::GetClientAddress() const {
210   return std::string(g_dbus_server_get_client_address(server_));
211 }
212
213 void DBusServer::SetIntrospectionXML(const std::string& xml) {
214   GError* err = NULL;
215   node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
216   if (!node_info_) {
217     LOGGER(ERROR) << "Failed to create node info from introspection xml : "
218                   << err->message;
219     g_error_free(err);
220   }
221 }
222
223 void DBusServer::SendSignal(GDBusConnection* connection,
224                             const std::string& iface,
225                             const std::string& signal_name,
226                             GVariant* parameters) {
227   GError* err = NULL;
228   gboolean ret = g_dbus_connection_emit_signal(
229       connection, NULL, "/",
230       iface.c_str(), signal_name.c_str(),
231       parameters, &err);
232   if (!ret) {
233     LOGGER(ERROR) << "Failed to emit signal : '"
234                   << iface << '.' << signal_name << "'";
235     g_error_free(err);
236   }
237 }
238
239 void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
240   peer_credentials_callback_ = func;
241 }
242
243 void DBusServer::SetMethodCallback(
244     const std::string& iface, MethodCallback func) {
245   method_callbacks_[iface] = func;
246 }
247
248 void DBusServer::SetPropertyGetter(
249     const std::string& iface, PropertyGetter func) {
250   property_getters_[iface] = func;
251 }
252
253 void DBusServer::SetPropertySetter(
254     const std::string& iface, PropertySetter func) {
255   property_setters_[iface] = func;
256 }
257
258 DBusServer::PeerCredentialsCallback
259 DBusServer::GetPeerCredentialsCallback() const {
260   return peer_credentials_callback_;
261 }
262
263 DBusServer::MethodCallback
264 DBusServer::GetMethodCallback(const std::string& iface) {
265   return method_callbacks_[iface];
266 }
267
268 DBusServer::PropertySetter
269 DBusServer::GetPropertySetter(const std::string& iface) {
270   return property_setters_[iface];
271 }
272
273 DBusServer::PropertyGetter
274 DBusServer::GetPropertyGetter(const std::string& iface) {
275   return property_getters_[iface];
276 }
277
278 }  // namespace wrt