2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <app_manager.h>
21 #include <DBusTypes.h>
23 #include "ClientRequest.h"
24 #include "access_control/PeerCreds.h"
25 #include "DBusServer.h"
29 static const gchar __introspection_xml[] =
31 " <interface name='" DBUS_IFACE "'>"
32 " <method name='" METHOD_REQUEST "'>"
33 " <arg type='i' name='" ARG_REQTYPE "' direction='in'/>"
34 " <arg type='s' name='" ARG_COOKIE "' direction='in'/>"
35 " <arg type='i' name='" ARG_REQID "' direction='in'/>"
36 " <arg type='s' name='" ARG_SUBJECT "' direction='in'/>"
37 " <arg type='s' name='" ARG_INPUT "' direction='in'/>"
38 " <arg type='i' name='" ARG_RESULT_ERR "' direction='out'/>"
39 " <arg type='s' name='" ARG_RESULT_ADD "' direction='out'/>"
40 " <arg type='s' name='" ARG_OUTPUT "' direction='out'/>"
42 " <method name='" METHOD_CHK_PRIV_APPLAUNCH "'>"
43 " <arg type='i' name='" ARG_RESULT_ERR "' direction='out'/>"
45 " <method name='" METHOD_CHK_PRIV_CALL "'>"
46 " <arg type='i' name='" ARG_RESULT_ERR "' direction='out'/>"
48 " <method name='" METHOD_CHK_PRIV_NOTIFICATION "'>"
49 " <arg type='i' name='" ARG_RESULT_ERR "' direction='out'/>"
54 DBusServer *DBusServer::__theInstance = NULL;
56 DBusServer::DBusServer() :
63 DBusServer::~DBusServer()
68 void DBusServer::__processRequest(const char *sender, GVariant *param, GDBusMethodInvocation *invocation)
71 const gchar *cookie = NULL;
73 const gchar *subject = NULL;
74 const gchar *input = NULL;
76 g_variant_get(param, "(i&si&s&s)", &reqType, &cookie, &reqId, &subject, &input);
77 IF_FAIL_VOID_TAG(reqType > 0 && reqId > 0 && cookie && subject && input, _E, "Invalid request");
79 _I("[%d] ReqId: %d, Subject: %s", reqType, reqId, subject);
80 _SI("Input: %s", input);
82 Credentials *creds = NULL;
84 if (!peer_creds::get(__connection, sender, cookie, &creds)) {
85 _E("Peer credentialing failed");
86 g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
90 ClientRequest *request = new(std::nothrow) ClientRequest(reqType, reqId, subject, input, creds, sender, invocation);
92 _E("Memory allocation failed");
93 g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
98 Server::sendRequest(request);
101 void DBusServer::__reply(GDBusMethodInvocation *invocation, int error)
103 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", error));
106 void DBusServer::__onMethodCalled(GDBusConnection *conn, const gchar *sender,
107 const gchar *path, const gchar *iface, const gchar *name,
108 GVariant *param, GDBusMethodInvocation *invocation, gpointer userData)
110 IF_FAIL_VOID_TAG(STR_EQ(path, DBUS_PATH), _W, "Invalid path: %s", path);
111 IF_FAIL_VOID_TAG(STR_EQ(iface, DBUS_IFACE), _W, "Invalid interface: %s", path);
113 if (STR_EQ(name, METHOD_REQUEST)) {
114 __theInstance->__processRequest(sender, param, invocation);
116 __theInstance->__reply(invocation, ERR_NONE);
120 void DBusServer::__onBusAcquired(GDBusConnection *conn, const gchar *name, gpointer userData)
122 GDBusInterfaceVTable vtable;
123 vtable.method_call = __onMethodCalled;
124 vtable.get_property = NULL;
125 vtable.set_property = NULL;
127 guint regId = g_dbus_connection_register_object(conn, DBUS_PATH,
128 __theInstance->__nodeInfo->interfaces[0], &vtable, NULL, NULL, NULL);
131 _E("Failed to acquire dbus");
135 __theInstance->__connection = conn;
136 _I("Dbus connection acquired");
139 void DBusServer::__onNameAcquired(GDBusConnection *conn, const gchar *name, gpointer userData)
141 _SI("Dbus name acquired: %s", name);
145 void DBusServer::__onNameLost(GDBusConnection *conn, const gchar *name, gpointer userData)
147 _E("Dbus name lost");
151 void DBusServer::__onCallDone(GObject *source, GAsyncResult *res, gpointer userData)
153 _I("Call %u done", *static_cast<unsigned int*>(userData));
155 GDBusConnection *conn = G_DBUS_CONNECTION(source);
156 GError *error = NULL;
157 g_dbus_connection_call_finish(conn, res, &error);
158 HANDLE_GERROR(error);
161 bool DBusServer::__init()
163 __nodeInfo = g_dbus_node_info_new_for_xml(__introspection_xml, NULL);
164 IF_FAIL_RETURN_TAG(__nodeInfo != NULL, false, _E, "Initialization failed");
166 __owner = g_bus_own_name(G_BUS_TYPE_SESSION, DBUS_DEST, G_BUS_NAME_OWNER_FLAGS_NONE,
167 __onBusAcquired, __onNameAcquired, __onNameLost, NULL, NULL);
169 __theInstance = this;
173 void DBusServer::__release()
176 g_dbus_connection_flush_sync(__connection, NULL, NULL);
180 g_bus_unown_name(__owner);
185 g_dbus_connection_close_sync(__connection, NULL, NULL);
186 g_object_unref(__connection);
191 g_dbus_node_info_unref(__nodeInfo);
196 void DBusServer::__publish(const char *dest, int reqId, const char *subject, int error, const char *data)
198 _SI("Publish: %s, %d, %s, %#x, %s", dest, reqId, subject, error, data);
200 GVariant *param = g_variant_new("(isis)", reqId, subject, error, data);
201 IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed");
203 g_dbus_connection_call(__connection, dest, DBUS_PATH, DBUS_IFACE,
204 METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, NULL);
207 void DBusServer::__call(const char *dest, const char *obj, const char *iface, const char *method, GVariant *param)
209 static unsigned int callCount = 0;
212 _SI("Call %u: %s, %s, %s.%s", callCount, dest, obj, iface, method);
214 g_dbus_connection_call(__connection, dest, obj, iface, method, param, NULL,
215 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, __onCallDone, &callCount);
218 void DBusServer::publish(std::string dest, int reqId, std::string subject, int error, std::string data)
220 IF_FAIL_VOID_TAG(__theInstance, _E, "Not initialized");
221 __theInstance->__publish(dest.c_str(), reqId, subject.c_str(), error, data.c_str());
224 void DBusServer::call(std::string dest, std::string obj, std::string iface, std::string method, GVariant *param)
226 IF_FAIL_VOID_TAG(__theInstance, _E, "Not initialized");
227 __theInstance->__call(dest.c_str(), obj.c_str(), iface.c_str(), method.c_str(), param);