2 * Copyright (c) 2020 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.
21 #include "theme/dbus/request_broker.h"
22 #include "theme/utils/logging.h"
26 const char kDbusBusName[] = "org.tizen.ThemeManager";
27 const char kDbusInterfaceName[] = "org.tizen.ThemeManager";
28 const char kDbusObjectPath[] = "/org/tizen/ThemeManager";
29 const char kDBusMethodSendData[] = "SendData";
36 void RequestBroker::OnReceiveDbusMethod(GDBusConnection* connection,
37 const gchar* sender, const gchar* object_path, const gchar* interface_name,
38 const gchar* method_name, GVariant* parameters,
39 GDBusMethodInvocation* invocation, gpointer user_data) {
40 RequestBroker* broker = static_cast<RequestBroker*>(user_data);
41 GVariant* reply_body = nullptr;
43 char* serialized = nullptr;
44 g_variant_get(parameters, "(i&s)", &command, &serialized);
46 Command cmd = static_cast<Command>(command);
47 tizen_base::Bundle b(serialized);
49 auto it = broker->filters_.find(cmd);
50 if (it == broker->filters_.end()) {
51 LOG(ERROR) << "UnKnown command";
52 g_dbus_method_invocation_return_value(invocation, nullptr);
56 tizen_base::Bundle result = it->second.GetHandler()->OnRequest(cmd, b);
58 g_variant_new("(is)", Command::RESULT, result.ToRaw().first.get());
59 g_dbus_method_invocation_return_value(invocation, reply_body);
62 bool RequestBroker::Init() {
63 GError* error = nullptr;
64 connection_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
65 if (connection_ == nullptr) {
66 if (error != nullptr) {
67 LOG(ERROR) << "Failed to get dbus [" << error->message << "]";
76 RequestBroker& RequestBroker::GetInst() {
77 static RequestBroker sBroker;
78 if (sBroker.connection_ == nullptr)
83 GDBusConnection* RequestBroker::GetConnection() {
87 int RequestBroker::RegisterRequestFilter(RequestFilter filter) {
88 filters_.emplace(filter.GetCmd(), filter);
92 bool RequestBroker::EmitSignal(std::string signal_name,
93 Command cmd, tizen_base::Bundle data) {
94 GError* err = nullptr;
95 gboolean result = TRUE;
96 GVariant *serialized = nullptr;
98 serialized = g_variant_new("(is)", static_cast<int>(cmd),
99 reinterpret_cast<char*>(data.ToRaw().first.get()));
101 result = g_dbus_connection_emit_signal(connection_,
102 nullptr, kDbusObjectPath, kDbusInterfaceName, signal_name.c_str(),
104 if (result == FALSE) {
105 LOG(ERROR) << "g_dbus_connection_emit_signal() is failed";
106 if (err != nullptr) {
107 LOG(ERROR) << "g_dbus_connection_emit_signal() err : " << err->message;
111 LOG(INFO) << "Successfully emit signal";
116 bool RequestBroker::Listen() {
117 const GDBusInterfaceVTable interface_vtable = {
122 gchar introspection_xml[] =
124 " <interface name='org.tizen.ThemeManager'>"
125 " <method name='SendData'>"
126 " <arg type='i' name='command' direction='in'/>"
127 " <arg type='s' name='serialized' direction='in'/>"
128 " <arg type='i' name='command' direction='out'/>"
129 " <arg type='s' name='serialized' direction='out'/>"
133 GError* error = nullptr;
134 GDBusNodeInfo* introspection_data =
135 g_dbus_node_info_new_for_xml(introspection_xml, &error);
136 if (!introspection_data) {
137 LOG(ERROR) << "g_dbus_node_info_new_for_xml is failed";
138 if (error != nullptr) {
139 LOG(ERROR) << "g_dbus_node_info_new_for_xml err ["
140 << error->message << "]";
146 registration_id_ = g_dbus_connection_register_object(
147 connection_, kDbusObjectPath, introspection_data->interfaces[0],
148 &interface_vtable, this, nullptr, nullptr);
149 g_dbus_node_info_unref(introspection_data);
150 if (registration_id_ == 0) {
151 LOG(ERROR) << "register object fail";
155 int owner_id = g_bus_own_name_on_connection(connection_,
156 kDbusBusName, G_BUS_NAME_OWNER_FLAGS_NONE,
157 nullptr, nullptr, nullptr, nullptr);
159 g_object_unref(connection_);
160 LOG(ERROR) << "g_bus_own_name_on_connection error";
167 void RequestBroker::OnReceiveDbusSignal(GDBusConnection* connection,
168 const gchar* sender_name, const gchar* object_path,
169 const gchar* interface_name, const gchar* signal_name,
170 GVariant* parameters, void* user_data) {
171 RequestBroker* broker = static_cast<RequestBroker*>(user_data);
172 char* serialized = nullptr;
174 g_variant_get(parameters, "(i&s)", &command, &serialized);
176 Command cmd = static_cast<Command>(command);
177 tizen_base::Bundle b(serialized);
179 auto it = broker->filters_.find(cmd);
180 if (it == broker->filters_.end())
183 tizen_base::Bundle result = it->second.GetHandler()->OnRequest(cmd, b);
186 bool RequestBroker::Subscribe() {
187 subscribe_id_ = g_dbus_connection_signal_subscribe(connection_, nullptr,
188 kDbusInterfaceName, nullptr, kDbusObjectPath, nullptr,
189 G_DBUS_SIGNAL_FLAGS_NONE, OnReceiveDbusSignal, this, nullptr);
191 return subscribe_id_ > 0;
194 tizen_base::Bundle RequestBroker::SendData(Command cmd,
195 tizen_base::Bundle& data) {
196 GError* err = nullptr;
197 GDBusMessage* msg = g_dbus_message_new_method_call(kDbusInterfaceName,
198 kDbusObjectPath, kDbusInterfaceName, kDBusMethodSendData);
200 LOG(ERROR) << "Can't allocate new method call";
204 g_dbus_message_set_body(msg,
205 g_variant_new("(is)",
206 static_cast<int>(cmd),
207 reinterpret_cast<char*>(data.ToRaw().first.get())));
209 GDBusMessage* reply = g_dbus_connection_send_message_with_reply_sync(
210 connection_, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE,
211 -1, nullptr, nullptr, &err);
212 GVariant* reply_body = g_dbus_message_get_body(reply);
214 char* serialized = nullptr;
215 g_variant_get(reply_body, "(i&s)", &command, &serialized);
216 tizen_base::Bundle result(serialized);
221 void RequestBroker::OnResultReceivedCb(GObject* source_object,
222 GAsyncResult* res, gpointer user_data) {
223 GDBusConnection* conn = reinterpret_cast<GDBusConnection*>(source_object);
224 GError* err = nullptr;
225 GDBusMessage* reply = g_dbus_connection_send_message_with_reply_finish(conn,
228 LOG(ERROR) << "No reply . err[" << (err ? err->message : "Unknown") << "]";
233 char* serialized = nullptr;
235 GVariant* reply_body = g_dbus_message_get_body(reply);
236 g_variant_get(reply_body, "(i&s)", &command, &serialized);
237 RequestBroker* broker = static_cast<RequestBroker*>(user_data);
238 Command cmd = static_cast<Command>(command);
239 tizen_base::Bundle b(serialized);
240 g_object_unref(reply);
242 auto it = broker->filters_.find(cmd);
243 if (it == broker->filters_.end())
246 it->second.GetHandler()->OnRequest(cmd, b);
249 void RequestBroker::SendDataAsync(Command cmd, tizen_base::Bundle& data) {
250 GDBusMessage* msg = g_dbus_message_new_method_call(
251 kDbusBusName, kDbusObjectPath, kDbusInterfaceName, kDBusMethodSendData);
253 LOG(ERROR) << "Can't allocate new method call";
257 g_dbus_message_set_body(msg, g_variant_new("(is)", static_cast<int>(cmd),
258 reinterpret_cast<char*>(data.ToRaw().first.get())));
260 g_dbus_connection_send_message_with_reply(connection_, msg,
261 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr,
262 nullptr, OnResultReceivedCb, this);