xref: /aosp_15_r20/external/libbrillo/brillo/dbus/dbus_signal_handler.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2014 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_DBUS_DBUS_SIGNAL_HANDLER_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_
7*1a96fba6SXin Li 
8*1a96fba6SXin Li #include <functional>
9*1a96fba6SXin Li #include <string>
10*1a96fba6SXin Li #include <utility>
11*1a96fba6SXin Li 
12*1a96fba6SXin Li #include <base/bind.h>
13*1a96fba6SXin Li #include <brillo/dbus/dbus_param_reader.h>
14*1a96fba6SXin Li #include <dbus/message.h>
15*1a96fba6SXin Li #include <dbus/object_proxy.h>
16*1a96fba6SXin Li 
17*1a96fba6SXin Li namespace brillo {
18*1a96fba6SXin Li namespace dbus_utils {
19*1a96fba6SXin Li 
20*1a96fba6SXin Li // brillo::dbus_utils::ConnectToSignal() is a helper function similar to
21*1a96fba6SXin Li // dbus::ObjectProxy::ConnectToSignal() but the |signal_callback| is an actual
22*1a96fba6SXin Li // C++ signal handler with expected signal parameters as native method args.
23*1a96fba6SXin Li //
24*1a96fba6SXin Li // brillo::dbus_utils::ConnectToSignal() actually registers a stub signal
25*1a96fba6SXin Li // handler with D-Bus which has a standard signature that matches
26*1a96fba6SXin Li // dbus::ObjectProxy::SignalCallback.
27*1a96fba6SXin Li //
28*1a96fba6SXin Li // When a D-Bus signal is emitted, the stub handler is invoked, which unpacks
29*1a96fba6SXin Li // the expected parameters from dbus::Signal message and then calls
30*1a96fba6SXin Li // |signal_callback| with unpacked arguments.
31*1a96fba6SXin Li //
32*1a96fba6SXin Li // If the signal message doesn't contain correct number or types of arguments,
33*1a96fba6SXin Li // an error message is logged to the system log and the signal is ignored
34*1a96fba6SXin Li // (|signal_callback| is not invoked).
35*1a96fba6SXin Li template <typename... Args>
ConnectToSignal(::dbus::ObjectProxy * object_proxy,const std::string & interface_name,const std::string & signal_name,base::Callback<void (Args...)> signal_callback,::dbus::ObjectProxy::OnConnectedCallback on_connected_callback)36*1a96fba6SXin Li void ConnectToSignal(
37*1a96fba6SXin Li     ::dbus::ObjectProxy* object_proxy,
38*1a96fba6SXin Li     const std::string& interface_name,
39*1a96fba6SXin Li     const std::string& signal_name,
40*1a96fba6SXin Li     base::Callback<void(Args...)> signal_callback,
41*1a96fba6SXin Li     ::dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
42*1a96fba6SXin Li   // DBusParamReader::Invoke() needs a functor object, not a base::Callback.
43*1a96fba6SXin Li   // Wrap the callback with lambda so we can redirect the call.
44*1a96fba6SXin Li   auto signal_callback_wrapper = [signal_callback](const Args&... args) {
45*1a96fba6SXin Li     if (!signal_callback.is_null()) {
46*1a96fba6SXin Li       signal_callback.Run(args...);
47*1a96fba6SXin Li     }
48*1a96fba6SXin Li   };
49*1a96fba6SXin Li 
50*1a96fba6SXin Li   // Raw signal handler stub method. When called, unpacks the signal arguments
51*1a96fba6SXin Li   // from |signal| message buffer and redirects the call to
52*1a96fba6SXin Li   // |signal_callback_wrapper| which, in turn, would call the user-provided
53*1a96fba6SXin Li   // |signal_callback|.
54*1a96fba6SXin Li   auto dbus_signal_callback = [](std::function<void(const Args&...)> callback,
55*1a96fba6SXin Li                                  ::dbus::Signal* signal) {
56*1a96fba6SXin Li     ::dbus::MessageReader reader(signal);
57*1a96fba6SXin Li     DBusParamReader<false, Args...>::Invoke(callback, &reader, nullptr);
58*1a96fba6SXin Li   };
59*1a96fba6SXin Li 
60*1a96fba6SXin Li   // Register our stub handler with D-Bus ObjectProxy.
61*1a96fba6SXin Li   object_proxy->ConnectToSignal(
62*1a96fba6SXin Li       interface_name, signal_name,
63*1a96fba6SXin Li       base::Bind(dbus_signal_callback, signal_callback_wrapper),
64*1a96fba6SXin Li       std::move(on_connected_callback));
65*1a96fba6SXin Li }
66*1a96fba6SXin Li 
67*1a96fba6SXin Li }  // namespace dbus_utils
68*1a96fba6SXin Li }  // namespace brillo
69*1a96fba6SXin Li 
70*1a96fba6SXin Li #endif  // LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_
71