80
80
bool IsConnected() const;
82
82
void OnProxyNameOwnerChanged(GDBusProxy*, GParamSpec*);
83
void OnProxySignal(GDBusProxy* proxy, char* sender_name, char* signal_name,
84
GVariant* parameters);
83
void OnProxySignal(GDBusProxy* proxy, const char*, const char*, GVariant*);
84
void OnPropertyChanged(GDBusProxy*, GVariant*, GStrv*);
86
86
static void OnProxyConnectCallback(GObject* source, GAsyncResult* res, gpointer impl);
87
87
static void OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data);
105
105
unsigned reconnection_attempts_;
107
glib::Signal<void, GDBusProxy*, char*, char*, GVariant*> g_signal_connection_;
107
glib::Signal<void, GDBusProxy*, const char*, const char*, GVariant*> g_signal_connection_;
108
glib::Signal<void, GDBusProxy*, GVariant*, GStrv*> g_property_signal_;
108
109
glib::Signal<void, GDBusProxy*, GParamSpec*> name_owner_signal_;
109
110
glib::Source::UniquePtr reconnect_timeout_;
110
111
sigc::signal<void> proxy_acquired;
112
SignalHandlers handlers_;
113
SignalHandlers signal_handlers_;
114
SignalHandlers property_handlers_;
115
117
DBusProxy::Impl::Impl(DBusProxy* owner,
202
204
self->name_owner_signal_.Connect(self->proxy_, "notify::g-name-owner",
203
205
sigc::mem_fun(self, &Impl::OnProxyNameOwnerChanged));
205
if (!self->handlers_.empty())
207
if (!self->signal_handlers_.empty())
207
209
// Connecting to the signals only if we have handlers
208
210
if (glib::object_cast<GObject>(self->proxy_) != self->g_signal_connection_.object())
209
211
self->g_signal_connection_.Connect(self->proxy_, "g-signal", sigc::mem_fun(self, &Impl::OnProxySignal));
214
if (!self->property_handlers_.empty())
216
// Connecting to the property-changed only if we have handlers
217
if (glib::object_cast<GObject>(self->proxy_) != self->g_property_signal_.object())
218
self->g_property_signal_.Connect(self->proxy_, "g-properties-changed", sigc::mem_fun(self, &Impl::OnPropertyChanged));
212
221
// If a proxy cannot autostart a service, it doesn't throw an error, but
213
222
// sets name_owner to NULL
214
223
if (glib::String(g_dbus_proxy_get_name_owner(proxy)))
246
void DBusProxy::Impl::OnProxySignal(GDBusProxy* proxy,
249
GVariant* parameters)
255
void DBusProxy::Impl::OnProxySignal(GDBusProxy* proxy, const char* sender_name, const char* signal_name, GVariant* parameters)
251
257
LOG_DEBUG(logger) << "Signal Received for proxy (" << object_path_ << ") "
252
258
<< "SenderName: " << sender_name << " "
253
259
<< "SignalName: " << signal_name << " "
254
260
<< "ParameterType: " << g_variant_get_type_string(parameters);
256
auto handler_it = handlers_.find(signal_name);
262
auto handler_it = signal_handlers_.find(signal_name);
258
if (handler_it != handlers_.end())
264
if (handler_it != signal_handlers_.end())
260
266
for (ReplyCallback const& callback : handler_it->second)
261
267
callback(parameters);
271
void DBusProxy::Impl::OnPropertyChanged(GDBusProxy* proxy, GVariant* changed_props, GStrv* invalidated)
273
LOG_DEBUG(logger) << "Properties changed for proxy (" << object_path_ << ")";
275
if (g_variant_n_children(changed_props) > 0)
278
const gchar *property_name;
281
g_variant_get(changed_props, "a{sv}", &iter);
282
while (g_variant_iter_loop (iter, "{&sv}", &property_name, &value))
284
LOG_DEBUG(logger) << "Property: '" << property_name << "': "
285
<< glib::String(g_variant_print(value, TRUE));
287
auto handler_it = property_handlers_.find(property_name);
289
if (handler_it != property_handlers_.end())
291
for (ReplyCallback const& callback : handler_it->second)
296
g_variant_iter_free (iter);
265
300
void DBusProxy::Impl::WaitForProxy(GCancellable* cancellable,
266
301
int timeout_msec,
267
302
std::function<void(glib::Error const&)> const& callback)
402
437
g_signal_connection_.Connect(proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignal));
405
handlers_[signal_name].push_back(callback);
440
signal_handlers_[signal_name].push_back(callback);
408
443
void DBusProxy::Impl::DisconnectSignal(std::string const& signal_name)
410
445
if (signal_name.empty())
447
signal_handlers_.clear();
416
handlers_.erase(signal_name);
451
signal_handlers_.erase(signal_name);
419
if (handlers_.empty())
454
if (signal_handlers_.empty())
420
455
g_signal_connection_.Disconnect();
568
void DBusProxy::ConnectProperty(std::string const& name, ReplyCallback const& callback)
570
if (!callback || name.empty())
572
LOG_WARN(logger) << "Impossible to connect to empty property or with invalid callback";
576
if (pimpl->proxy_ && glib::object_cast<GObject>(pimpl->proxy_) != pimpl->g_property_signal_.object())
578
// It's the first time we connect to a property so we need to setup the call handler
579
pimpl->g_property_signal_.Connect(pimpl->proxy_, "g-properties-changed", sigc::mem_fun(pimpl.get(), &Impl::OnPropertyChanged));
582
pimpl->property_handlers_[name].push_back(callback);
585
void DBusProxy::DisconnectProperty(std::string const& name)
589
pimpl->property_handlers_.clear();
593
pimpl->property_handlers_.erase(name);
596
if (pimpl->property_handlers_.empty())
597
pimpl->g_property_signal_.Disconnect();
533
600
void DBusProxy::Connect(std::string const& signal_name, ReplyCallback const& callback)
535
602
pimpl->Connect(signal_name, callback);