1*1a96fba6SXin Li // Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li
5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_GLIB_DBUS_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_GLIB_DBUS_H_
7*1a96fba6SXin Li
8*1a96fba6SXin Li // IMPORTANT: Do not use this in new code. Instead, use libchrome's D-Bus
9*1a96fba6SXin Li // bindings. See https://goo.gl/EH3MmR for more details.
10*1a96fba6SXin Li
11*1a96fba6SXin Li #include <dbus/dbus-glib.h>
12*1a96fba6SXin Li #include <glib-object.h>
13*1a96fba6SXin Li
14*1a96fba6SXin Li #include <algorithm>
15*1a96fba6SXin Li #include <string>
16*1a96fba6SXin Li #include <utility>
17*1a96fba6SXin Li
18*1a96fba6SXin Li #include "base/logging.h"
19*1a96fba6SXin Li #include <brillo/brillo_export.h>
20*1a96fba6SXin Li #include <brillo/glib/object.h>
21*1a96fba6SXin Li
22*1a96fba6SXin Li struct DBusMessage;
23*1a96fba6SXin Li struct DBusConnection;
24*1a96fba6SXin Li
25*1a96fba6SXin Li namespace brillo {
26*1a96fba6SXin Li
27*1a96fba6SXin Li namespace dbus {
28*1a96fba6SXin Li
29*1a96fba6SXin Li // \brief BusConnection manages the ref-count for a ::DBusGConnection*.
30*1a96fba6SXin Li //
31*1a96fba6SXin Li // A BusConnection has reference semantics bound to a particular communication
32*1a96fba6SXin Li // bus.
33*1a96fba6SXin Li //
34*1a96fba6SXin Li // \models Copyable, Assignable
35*1a96fba6SXin Li // \related GetSystemBusConnection()
36*1a96fba6SXin Li
37*1a96fba6SXin Li class BRILLO_EXPORT BusConnection {
38*1a96fba6SXin Li public:
39*1a96fba6SXin Li typedef ::DBusGConnection* value_type;
40*1a96fba6SXin Li
BusConnection(const BusConnection & x)41*1a96fba6SXin Li BusConnection(const BusConnection& x) : object_(x.object_) {
42*1a96fba6SXin Li if (object_)
43*1a96fba6SXin Li ::dbus_g_connection_ref(object_);
44*1a96fba6SXin Li }
45*1a96fba6SXin Li
~BusConnection()46*1a96fba6SXin Li ~BusConnection() {
47*1a96fba6SXin Li if (object_)
48*1a96fba6SXin Li ::dbus_g_connection_unref(object_);
49*1a96fba6SXin Li }
50*1a96fba6SXin Li
51*1a96fba6SXin Li BusConnection& operator=(BusConnection x) {
52*1a96fba6SXin Li swap(*this, x);
53*1a96fba6SXin Li return *this;
54*1a96fba6SXin Li }
55*1a96fba6SXin Li
g_connection()56*1a96fba6SXin Li const value_type& g_connection() const {
57*1a96fba6SXin Li DCHECK(object_) << "referencing an empty connection";
58*1a96fba6SXin Li return object_;
59*1a96fba6SXin Li }
60*1a96fba6SXin Li
61*1a96fba6SXin Li operator bool() const { return object_; }
62*1a96fba6SXin Li
HasConnection()63*1a96fba6SXin Li bool HasConnection() const { return object_; }
64*1a96fba6SXin Li
65*1a96fba6SXin Li private:
66*1a96fba6SXin Li friend void swap(BusConnection& x, BusConnection& y);
67*1a96fba6SXin Li
68*1a96fba6SXin Li friend class Proxy;
69*1a96fba6SXin Li friend BusConnection GetSystemBusConnection();
70*1a96fba6SXin Li friend BusConnection GetPrivateBusConnection(const char* address);
71*1a96fba6SXin Li
72*1a96fba6SXin Li // Constructor takes ownership
BusConnection(::DBusGConnection * x)73*1a96fba6SXin Li BRILLO_PRIVATE explicit BusConnection(::DBusGConnection* x) : object_(x) {}
74*1a96fba6SXin Li
75*1a96fba6SXin Li value_type object_;
76*1a96fba6SXin Li };
77*1a96fba6SXin Li
swap(BusConnection & x,BusConnection & y)78*1a96fba6SXin Li inline void swap(BusConnection& x, BusConnection& y) {
79*1a96fba6SXin Li std::swap(x.object_, y.object_);
80*1a96fba6SXin Li }
81*1a96fba6SXin Li
82*1a96fba6SXin Li // \brief Proxy manages the ref-count for a ::DBusGProxy*.
83*1a96fba6SXin Li //
84*1a96fba6SXin Li // Proxy has reference semantics and represents a connection to on object on
85*1a96fba6SXin Li // the bus. A proxy object is constructed with a connection to a bus, a name
86*1a96fba6SXin Li // to an entity on the bus, a path to an object owned by the entity, and an
87*1a96fba6SXin Li // interface protocol name used to communicate with the object.
88*1a96fba6SXin Li
89*1a96fba6SXin Li class BRILLO_EXPORT Proxy {
90*1a96fba6SXin Li public:
91*1a96fba6SXin Li typedef ::DBusGProxy* value_type;
92*1a96fba6SXin Li
93*1a96fba6SXin Li Proxy();
94*1a96fba6SXin Li
95*1a96fba6SXin Li // Set |connect_to_name_owner| true if you'd like to use
96*1a96fba6SXin Li // dbus_g_proxy_new_for_name_owner() rather than dbus_g_proxy_new_for_name().
97*1a96fba6SXin Li Proxy(const BusConnection& connection,
98*1a96fba6SXin Li const char* name,
99*1a96fba6SXin Li const char* path,
100*1a96fba6SXin Li const char* interface,
101*1a96fba6SXin Li bool connect_to_name_owner);
102*1a96fba6SXin Li
103*1a96fba6SXin Li // Equivalent to Proxy(connection, name, path, interface, false).
104*1a96fba6SXin Li Proxy(const BusConnection& connection,
105*1a96fba6SXin Li const char* name,
106*1a96fba6SXin Li const char* path,
107*1a96fba6SXin Li const char* interface);
108*1a96fba6SXin Li
109*1a96fba6SXin Li // Creates a peer proxy using dbus_g_proxy_new_for_peer.
110*1a96fba6SXin Li Proxy(const BusConnection& connection,
111*1a96fba6SXin Li const char* path,
112*1a96fba6SXin Li const char* interface);
113*1a96fba6SXin Li
114*1a96fba6SXin Li Proxy(const Proxy& x);
115*1a96fba6SXin Li
116*1a96fba6SXin Li ~Proxy();
117*1a96fba6SXin Li
118*1a96fba6SXin Li Proxy& operator=(Proxy x) {
119*1a96fba6SXin Li swap(*this, x);
120*1a96fba6SXin Li return *this;
121*1a96fba6SXin Li }
122*1a96fba6SXin Li
path()123*1a96fba6SXin Li const char* path() const {
124*1a96fba6SXin Li DCHECK(object_) << "referencing an empty proxy";
125*1a96fba6SXin Li return ::dbus_g_proxy_get_path(object_);
126*1a96fba6SXin Li }
127*1a96fba6SXin Li
128*1a96fba6SXin Li // gproxy() returns a reference to the underlying ::DBusGProxy*. As this
129*1a96fba6SXin Li // library evolves, the gproxy() will be moved to be private.
130*1a96fba6SXin Li
gproxy()131*1a96fba6SXin Li const value_type& gproxy() const {
132*1a96fba6SXin Li DCHECK(object_) << "referencing an empty proxy";
133*1a96fba6SXin Li return object_;
134*1a96fba6SXin Li }
135*1a96fba6SXin Li
136*1a96fba6SXin Li operator bool() const { return object_; }
137*1a96fba6SXin Li
138*1a96fba6SXin Li private:
139*1a96fba6SXin Li BRILLO_PRIVATE static value_type GetGProxy(const BusConnection& connection,
140*1a96fba6SXin Li const char* name,
141*1a96fba6SXin Li const char* path,
142*1a96fba6SXin Li const char* interface,
143*1a96fba6SXin Li bool connect_to_name_owner);
144*1a96fba6SXin Li
145*1a96fba6SXin Li BRILLO_PRIVATE static value_type GetGPeerProxy(
146*1a96fba6SXin Li const BusConnection& connection,
147*1a96fba6SXin Li const char* path,
148*1a96fba6SXin Li const char* interface);
149*1a96fba6SXin Li
150*1a96fba6SXin Li BRILLO_PRIVATE operator int() const; // for safe bool cast
151*1a96fba6SXin Li friend void swap(Proxy& x, Proxy& y);
152*1a96fba6SXin Li
153*1a96fba6SXin Li value_type object_;
154*1a96fba6SXin Li };
155*1a96fba6SXin Li
swap(Proxy & x,Proxy & y)156*1a96fba6SXin Li inline void swap(Proxy& x, Proxy& y) {
157*1a96fba6SXin Li std::swap(x.object_, y.object_);
158*1a96fba6SXin Li }
159*1a96fba6SXin Li
160*1a96fba6SXin Li // \brief RegisterExclusiveService configures a GObject to run as a service on
161*1a96fba6SXin Li // a supplied ::BusConnection.
162*1a96fba6SXin Li //
163*1a96fba6SXin Li // RegisterExclusiveService encapsulates the process of configuring the
164*1a96fba6SXin Li // supplied \param object at \param service_path on the \param connection.
165*1a96fba6SXin Li // Exclusivity is ensured by replacing any existing services at that named
166*1a96fba6SXin Li // location and confirming that the connection is the primary owner.
167*1a96fba6SXin Li //
168*1a96fba6SXin Li // Type information for the \param object must be installed with
169*1a96fba6SXin Li // dbus_g_object_type_install_info prior to use.
170*1a96fba6SXin Li
171*1a96fba6SXin Li BRILLO_EXPORT bool RegisterExclusiveService(const BusConnection& connection,
172*1a96fba6SXin Li const char* interface_name,
173*1a96fba6SXin Li const char* service_name,
174*1a96fba6SXin Li const char* service_path,
175*1a96fba6SXin Li GObject* object);
176*1a96fba6SXin Li
177*1a96fba6SXin Li template<typename F> // F is a function signature
178*1a96fba6SXin Li class MonitorConnection;
179*1a96fba6SXin Li
180*1a96fba6SXin Li template<typename A1>
181*1a96fba6SXin Li class MonitorConnection<void(A1)> {
182*1a96fba6SXin Li public:
MonitorConnection(const Proxy & proxy,const char * name,void (* monitor)(void *,A1),void * object)183*1a96fba6SXin Li MonitorConnection(const Proxy& proxy,
184*1a96fba6SXin Li const char* name,
185*1a96fba6SXin Li void (*monitor)(void*, A1),
186*1a96fba6SXin Li void* object)
187*1a96fba6SXin Li : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
188*1a96fba6SXin Li
Run(::DBusGProxy *,A1 x,MonitorConnection * self)189*1a96fba6SXin Li static void Run(::DBusGProxy*, A1 x, MonitorConnection* self) {
190*1a96fba6SXin Li self->monitor_(self->object_, x);
191*1a96fba6SXin Li }
proxy()192*1a96fba6SXin Li const Proxy& proxy() const { return proxy_; }
name()193*1a96fba6SXin Li const std::string& name() const { return name_; }
194*1a96fba6SXin Li
195*1a96fba6SXin Li private:
196*1a96fba6SXin Li Proxy proxy_;
197*1a96fba6SXin Li std::string name_;
198*1a96fba6SXin Li void (*monitor_)(void*, A1);
199*1a96fba6SXin Li void* object_;
200*1a96fba6SXin Li };
201*1a96fba6SXin Li
202*1a96fba6SXin Li template<typename A1, typename A2>
203*1a96fba6SXin Li class MonitorConnection<void(A1, A2)> {
204*1a96fba6SXin Li public:
MonitorConnection(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2),void * object)205*1a96fba6SXin Li MonitorConnection(const Proxy& proxy,
206*1a96fba6SXin Li const char* name,
207*1a96fba6SXin Li void (*monitor)(void*, A1, A2),
208*1a96fba6SXin Li void* object)
209*1a96fba6SXin Li : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
210*1a96fba6SXin Li
Run(::DBusGProxy *,A1 x,A2 y,MonitorConnection * self)211*1a96fba6SXin Li static void Run(::DBusGProxy*, A1 x, A2 y, MonitorConnection* self) {
212*1a96fba6SXin Li self->monitor_(self->object_, x, y);
213*1a96fba6SXin Li }
proxy()214*1a96fba6SXin Li const Proxy& proxy() const { return proxy_; }
name()215*1a96fba6SXin Li const std::string& name() const { return name_; }
216*1a96fba6SXin Li
217*1a96fba6SXin Li private:
218*1a96fba6SXin Li Proxy proxy_;
219*1a96fba6SXin Li std::string name_;
220*1a96fba6SXin Li void (*monitor_)(void*, A1, A2);
221*1a96fba6SXin Li void* object_;
222*1a96fba6SXin Li };
223*1a96fba6SXin Li
224*1a96fba6SXin Li template<typename A1, typename A2, typename A3>
225*1a96fba6SXin Li class MonitorConnection<void(A1, A2, A3)> {
226*1a96fba6SXin Li public:
MonitorConnection(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2,A3),void * object)227*1a96fba6SXin Li MonitorConnection(const Proxy& proxy,
228*1a96fba6SXin Li const char* name,
229*1a96fba6SXin Li void (*monitor)(void*, A1, A2, A3),
230*1a96fba6SXin Li void* object)
231*1a96fba6SXin Li : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
232*1a96fba6SXin Li
Run(::DBusGProxy *,A1 x,A2 y,A3 z,MonitorConnection * self)233*1a96fba6SXin Li static void Run(::DBusGProxy*, A1 x, A2 y, A3 z, MonitorConnection* self) {
234*1a96fba6SXin Li self->monitor_(self->object_, x, y, z);
235*1a96fba6SXin Li }
proxy()236*1a96fba6SXin Li const Proxy& proxy() const { return proxy_; }
name()237*1a96fba6SXin Li const std::string& name() const { return name_; }
238*1a96fba6SXin Li
239*1a96fba6SXin Li private:
240*1a96fba6SXin Li Proxy proxy_;
241*1a96fba6SXin Li std::string name_;
242*1a96fba6SXin Li void (*monitor_)(void*, A1, A2, A3);
243*1a96fba6SXin Li void* object_;
244*1a96fba6SXin Li };
245*1a96fba6SXin Li
246*1a96fba6SXin Li template<typename A1, typename A2, typename A3, typename A4>
247*1a96fba6SXin Li class MonitorConnection<void(A1, A2, A3, A4)> {
248*1a96fba6SXin Li public:
MonitorConnection(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2,A3,A4),void * object)249*1a96fba6SXin Li MonitorConnection(const Proxy& proxy,
250*1a96fba6SXin Li const char* name,
251*1a96fba6SXin Li void (*monitor)(void*, A1, A2, A3, A4),
252*1a96fba6SXin Li void* object)
253*1a96fba6SXin Li : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
254*1a96fba6SXin Li
Run(::DBusGProxy *,A1 x,A2 y,A3 z,A4 w,MonitorConnection * self)255*1a96fba6SXin Li static void Run(::DBusGProxy*,
256*1a96fba6SXin Li A1 x,
257*1a96fba6SXin Li A2 y,
258*1a96fba6SXin Li A3 z,
259*1a96fba6SXin Li A4 w,
260*1a96fba6SXin Li MonitorConnection* self) {
261*1a96fba6SXin Li self->monitor_(self->object_, x, y, z, w);
262*1a96fba6SXin Li }
proxy()263*1a96fba6SXin Li const Proxy& proxy() const { return proxy_; }
name()264*1a96fba6SXin Li const std::string& name() const { return name_; }
265*1a96fba6SXin Li
266*1a96fba6SXin Li private:
267*1a96fba6SXin Li Proxy proxy_;
268*1a96fba6SXin Li std::string name_;
269*1a96fba6SXin Li void (*monitor_)(void*, A1, A2, A3, A4);
270*1a96fba6SXin Li void* object_;
271*1a96fba6SXin Li };
272*1a96fba6SXin Li
273*1a96fba6SXin Li template<typename A1>
Monitor(const Proxy & proxy,const char * name,void (* monitor)(void *,A1),void * object)274*1a96fba6SXin Li MonitorConnection<void(A1)>* Monitor(const Proxy& proxy,
275*1a96fba6SXin Li const char* name,
276*1a96fba6SXin Li void (*monitor)(void*, A1),
277*1a96fba6SXin Li void* object) {
278*1a96fba6SXin Li typedef MonitorConnection<void(A1)> ConnectionType;
279*1a96fba6SXin Li
280*1a96fba6SXin Li ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
281*1a96fba6SXin Li
282*1a96fba6SXin Li ::dbus_g_proxy_add_signal(
283*1a96fba6SXin Li proxy.gproxy(), name, glib::type_to_gtypeid<A1>(), G_TYPE_INVALID);
284*1a96fba6SXin Li ::dbus_g_proxy_connect_signal(
285*1a96fba6SXin Li proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
286*1a96fba6SXin Li return result;
287*1a96fba6SXin Li }
288*1a96fba6SXin Li
289*1a96fba6SXin Li template<typename A1, typename A2>
Monitor(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2),void * object)290*1a96fba6SXin Li MonitorConnection<void(A1, A2)>* Monitor(const Proxy& proxy,
291*1a96fba6SXin Li const char* name,
292*1a96fba6SXin Li void (*monitor)(void*, A1, A2),
293*1a96fba6SXin Li void* object) {
294*1a96fba6SXin Li typedef MonitorConnection<void(A1, A2)> ConnectionType;
295*1a96fba6SXin Li
296*1a96fba6SXin Li ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
297*1a96fba6SXin Li
298*1a96fba6SXin Li ::dbus_g_proxy_add_signal(proxy.gproxy(),
299*1a96fba6SXin Li name,
300*1a96fba6SXin Li glib::type_to_gtypeid<A1>(),
301*1a96fba6SXin Li glib::type_to_gtypeid<A2>(),
302*1a96fba6SXin Li G_TYPE_INVALID);
303*1a96fba6SXin Li ::dbus_g_proxy_connect_signal(
304*1a96fba6SXin Li proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
305*1a96fba6SXin Li return result;
306*1a96fba6SXin Li }
307*1a96fba6SXin Li
308*1a96fba6SXin Li template<typename A1, typename A2, typename A3>
Monitor(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2,A3),void * object)309*1a96fba6SXin Li MonitorConnection<void(A1, A2, A3)>* Monitor(const Proxy& proxy,
310*1a96fba6SXin Li const char* name,
311*1a96fba6SXin Li void (*monitor)(void*, A1, A2, A3),
312*1a96fba6SXin Li void* object) {
313*1a96fba6SXin Li typedef MonitorConnection<void(A1, A2, A3)> ConnectionType;
314*1a96fba6SXin Li
315*1a96fba6SXin Li ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
316*1a96fba6SXin Li
317*1a96fba6SXin Li ::dbus_g_proxy_add_signal(proxy.gproxy(),
318*1a96fba6SXin Li name,
319*1a96fba6SXin Li glib::type_to_gtypeid<A1>(),
320*1a96fba6SXin Li glib::type_to_gtypeid<A2>(),
321*1a96fba6SXin Li glib::type_to_gtypeid<A3>(),
322*1a96fba6SXin Li G_TYPE_INVALID);
323*1a96fba6SXin Li ::dbus_g_proxy_connect_signal(
324*1a96fba6SXin Li proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
325*1a96fba6SXin Li return result;
326*1a96fba6SXin Li }
327*1a96fba6SXin Li
328*1a96fba6SXin Li template<typename A1, typename A2, typename A3, typename A4>
Monitor(const Proxy & proxy,const char * name,void (* monitor)(void *,A1,A2,A3,A4),void * object)329*1a96fba6SXin Li MonitorConnection<void(A1, A2, A3, A4)>* Monitor(
330*1a96fba6SXin Li const Proxy& proxy,
331*1a96fba6SXin Li const char* name,
332*1a96fba6SXin Li void (*monitor)(void*, A1, A2, A3, A4),
333*1a96fba6SXin Li void* object) {
334*1a96fba6SXin Li typedef MonitorConnection<void(A1, A2, A3, A4)> ConnectionType;
335*1a96fba6SXin Li
336*1a96fba6SXin Li ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
337*1a96fba6SXin Li
338*1a96fba6SXin Li ::dbus_g_proxy_add_signal(proxy.gproxy(),
339*1a96fba6SXin Li name,
340*1a96fba6SXin Li glib::type_to_gtypeid<A1>(),
341*1a96fba6SXin Li glib::type_to_gtypeid<A2>(),
342*1a96fba6SXin Li glib::type_to_gtypeid<A3>(),
343*1a96fba6SXin Li glib::type_to_gtypeid<A4>(),
344*1a96fba6SXin Li G_TYPE_INVALID);
345*1a96fba6SXin Li ::dbus_g_proxy_connect_signal(
346*1a96fba6SXin Li proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
347*1a96fba6SXin Li return result;
348*1a96fba6SXin Li }
349*1a96fba6SXin Li
350*1a96fba6SXin Li template<typename F>
Disconnect(MonitorConnection<F> * connection)351*1a96fba6SXin Li void Disconnect(MonitorConnection<F>* connection) {
352*1a96fba6SXin Li typedef MonitorConnection<F> ConnectionType;
353*1a96fba6SXin Li
354*1a96fba6SXin Li ::dbus_g_proxy_disconnect_signal(connection->proxy().gproxy(),
355*1a96fba6SXin Li connection->name().c_str(),
356*1a96fba6SXin Li G_CALLBACK(&ConnectionType::Run),
357*1a96fba6SXin Li connection);
358*1a96fba6SXin Li delete connection;
359*1a96fba6SXin Li }
360*1a96fba6SXin Li
361*1a96fba6SXin Li // \brief call_PtrArray() invokes a method on a proxy returning a
362*1a96fba6SXin Li // glib::PtrArray.
363*1a96fba6SXin Li //
364*1a96fba6SXin Li // CallPtrArray is the first instance of what is likely to be a general
365*1a96fba6SXin Li // way to make method calls to a proxy. It will likely be replaced with
366*1a96fba6SXin Li // something like Call(proxy, method, arg1, arg2, ..., ResultType*) in the
367*1a96fba6SXin Li // future. However, I don't yet have enough cases to generalize from.
368*1a96fba6SXin Li
369*1a96fba6SXin Li BRILLO_EXPORT bool CallPtrArray(const Proxy& proxy,
370*1a96fba6SXin Li const char* method,
371*1a96fba6SXin Li glib::ScopedPtrArray<const char*>* result);
372*1a96fba6SXin Li
373*1a96fba6SXin Li // \brief RetrieveProperty() retrieves a property of an object associated with a
374*1a96fba6SXin Li // proxy.
375*1a96fba6SXin Li //
376*1a96fba6SXin Li // Given a proxy to an object supporting the org.freedesktop.DBus.Properties
377*1a96fba6SXin Li // interface, the RetrieveProperty() call will retrieve a property of the
378*1a96fba6SXin Li // specified interface on the object storing it in \param result and returning
379*1a96fba6SXin Li // \true. If the dbus call fails or the object returned is not of type \param T,
380*1a96fba6SXin Li // then \false is returned and \param result is unchanged.
381*1a96fba6SXin Li //
382*1a96fba6SXin Li // \example
383*1a96fba6SXin Li // Proxy proxy(GetSystemBusConnection(),
384*1a96fba6SXin Li // "org.freedesktop.DeviceKit.Power", // A named entity on the bus
385*1a96fba6SXin Li // battery_name, // Path to a battery on the bus
386*1a96fba6SXin Li // "org.freedesktop.DBus.Properties") // Properties interface
387*1a96fba6SXin Li //
388*1a96fba6SXin Li // double x;
389*1a96fba6SXin Li // if (RetrieveProperty(proxy,
390*1a96fba6SXin Li // "org.freedesktop.DeviceKit.Power.Device",
391*1a96fba6SXin Li // "percentage")
392*1a96fba6SXin Li // std::cout << "Battery charge is " << x << "% of capacity.";
393*1a96fba6SXin Li // \end_example
394*1a96fba6SXin Li
395*1a96fba6SXin Li template<typename T>
RetrieveProperty(const Proxy & proxy,const char * interface,const char * property,T * result)396*1a96fba6SXin Li inline bool RetrieveProperty(const Proxy& proxy,
397*1a96fba6SXin Li const char* interface,
398*1a96fba6SXin Li const char* property,
399*1a96fba6SXin Li T* result) {
400*1a96fba6SXin Li glib::ScopedError error;
401*1a96fba6SXin Li glib::Value value;
402*1a96fba6SXin Li
403*1a96fba6SXin Li if (!::dbus_g_proxy_call(proxy.gproxy(), "Get", &Resetter(&error).lvalue(),
404*1a96fba6SXin Li G_TYPE_STRING, interface,
405*1a96fba6SXin Li G_TYPE_STRING, property,
406*1a96fba6SXin Li G_TYPE_INVALID,
407*1a96fba6SXin Li G_TYPE_VALUE, &value,
408*1a96fba6SXin Li G_TYPE_INVALID)) {
409*1a96fba6SXin Li LOG(ERROR) << "Getting property failed: "
410*1a96fba6SXin Li << (error->message ? error->message : "Unknown Error.");
411*1a96fba6SXin Li return false;
412*1a96fba6SXin Li }
413*1a96fba6SXin Li return glib::Retrieve(value, result);
414*1a96fba6SXin Li }
415*1a96fba6SXin Li
416*1a96fba6SXin Li // \brief RetrieveProperties returns a HashTable of all properties for the
417*1a96fba6SXin Li // specified interface.
418*1a96fba6SXin Li
419*1a96fba6SXin Li BRILLO_EXPORT bool RetrieveProperties(const Proxy& proxy,
420*1a96fba6SXin Li const char* interface,
421*1a96fba6SXin Li glib::ScopedHashTable* result);
422*1a96fba6SXin Li
423*1a96fba6SXin Li // \brief Returns a connection to the system bus.
424*1a96fba6SXin Li
425*1a96fba6SXin Li BRILLO_EXPORT BusConnection GetSystemBusConnection();
426*1a96fba6SXin Li
427*1a96fba6SXin Li // \brief Returns a private connection to a bus at |address|.
428*1a96fba6SXin Li
429*1a96fba6SXin Li BRILLO_EXPORT BusConnection GetPrivateBusConnection(const char* address);
430*1a96fba6SXin Li
431*1a96fba6SXin Li // \brief Calls a method |method_name| with no arguments per the given |path|
432*1a96fba6SXin Li // and |interface_name|. Ignores return value.
433*1a96fba6SXin Li
434*1a96fba6SXin Li BRILLO_EXPORT void CallMethodWithNoArguments(const char* service_name,
435*1a96fba6SXin Li const char* path,
436*1a96fba6SXin Li const char* interface_name,
437*1a96fba6SXin Li const char* method_name);
438*1a96fba6SXin Li
439*1a96fba6SXin Li // \brief Low-level signal monitor base class.
440*1a96fba6SXin Li //
441*1a96fba6SXin Li // Used when there is no definite named signal sender (that Proxy
442*1a96fba6SXin Li // could be used for).
443*1a96fba6SXin Li
444*1a96fba6SXin Li class BRILLO_EXPORT SignalWatcher {
445*1a96fba6SXin Li public:
SignalWatcher()446*1a96fba6SXin Li SignalWatcher() {}
447*1a96fba6SXin Li ~SignalWatcher();
448*1a96fba6SXin Li void StartMonitoring(const std::string& interface, const std::string& signal);
449*1a96fba6SXin Li
450*1a96fba6SXin Li private:
451*1a96fba6SXin Li // Callback invoked on the given signal arrival.
452*1a96fba6SXin Li virtual void OnSignal(DBusMessage* message) = 0;
453*1a96fba6SXin Li
454*1a96fba6SXin Li // Returns a string matching the D-Bus messages that we want to listen for.
455*1a96fba6SXin Li BRILLO_PRIVATE std::string GetDBusMatchString() const;
456*1a96fba6SXin Li
457*1a96fba6SXin Li // A D-Bus message filter to receive signals.
458*1a96fba6SXin Li BRILLO_PRIVATE static DBusHandlerResult FilterDBusMessage(
459*1a96fba6SXin Li DBusConnection* dbus_conn,
460*1a96fba6SXin Li DBusMessage* message,
461*1a96fba6SXin Li void* data);
462*1a96fba6SXin Li std::string interface_;
463*1a96fba6SXin Li std::string signal_;
464*1a96fba6SXin Li };
465*1a96fba6SXin Li
466*1a96fba6SXin Li } // namespace dbus
467*1a96fba6SXin Li } // namespace brillo
468*1a96fba6SXin Li
469*1a96fba6SXin Li #endif // LIBBRILLO_BRILLO_GLIB_DBUS_H_
470