You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.7 KiB
71 lines
2.7 KiB
// Copyright 2014 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_
|
|
#define LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_
|
|
|
|
#include <functional>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include <base/bind.h>
|
|
#include <brillo/dbus/dbus_param_reader.h>
|
|
#include <dbus/message.h>
|
|
#include <dbus/object_proxy.h>
|
|
|
|
namespace brillo {
|
|
namespace dbus_utils {
|
|
|
|
// brillo::dbus_utils::ConnectToSignal() is a helper function similar to
|
|
// dbus::ObjectProxy::ConnectToSignal() but the |signal_callback| is an actual
|
|
// C++ signal handler with expected signal parameters as native method args.
|
|
//
|
|
// brillo::dbus_utils::ConnectToSignal() actually registers a stub signal
|
|
// handler with D-Bus which has a standard signature that matches
|
|
// dbus::ObjectProxy::SignalCallback.
|
|
//
|
|
// When a D-Bus signal is emitted, the stub handler is invoked, which unpacks
|
|
// the expected parameters from dbus::Signal message and then calls
|
|
// |signal_callback| with unpacked arguments.
|
|
//
|
|
// If the signal message doesn't contain correct number or types of arguments,
|
|
// an error message is logged to the system log and the signal is ignored
|
|
// (|signal_callback| is not invoked).
|
|
template <typename... Args>
|
|
void 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) {
|
|
// DBusParamReader::Invoke() needs a functor object, not a base::Callback.
|
|
// Wrap the callback with lambda so we can redirect the call.
|
|
auto signal_callback_wrapper = [signal_callback](const Args&... args) {
|
|
if (!signal_callback.is_null()) {
|
|
signal_callback.Run(args...);
|
|
}
|
|
};
|
|
|
|
// Raw signal handler stub method. When called, unpacks the signal arguments
|
|
// from |signal| message buffer and redirects the call to
|
|
// |signal_callback_wrapper| which, in turn, would call the user-provided
|
|
// |signal_callback|.
|
|
auto dbus_signal_callback = [](std::function<void(const Args&...)> callback,
|
|
::dbus::Signal* signal) {
|
|
::dbus::MessageReader reader(signal);
|
|
DBusParamReader<false, Args...>::Invoke(callback, &reader, nullptr);
|
|
};
|
|
|
|
// Register our stub handler with D-Bus ObjectProxy.
|
|
object_proxy->ConnectToSignal(
|
|
interface_name, signal_name,
|
|
base::Bind(dbus_signal_callback, signal_callback_wrapper),
|
|
std::move(on_connected_callback));
|
|
}
|
|
|
|
} // namespace dbus_utils
|
|
} // namespace brillo
|
|
|
|
#endif // LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_
|