dbus_signal_handler.h revision c7b0177da3ad8299c8c7650d1dc21768591bd362
1927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved. 2927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be 3927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// found in the LICENSE file. 4927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_ 6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_ 7927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 8927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko#include <string> 9927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 109ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/bind_lambda.h> 119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/dbus/dbus_param_reader.h> 12927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko#include <dbus/message.h> 13927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko#include <dbus/object_proxy.h> 14927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 159ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 16927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenkonamespace dbus_utils { 17927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 189ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko// brillo::dbus_utils::ConnectToSignal() is a helper function similar to 19927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// dbus::ObjectProxy::ConnectToSignal() but the |signal_callback| is an actual 20927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// C++ signal handler with expected signal parameters as native method args. 21927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// 229ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko// brillo::dbus_utils::ConnectToSignal() actually registers a stub signal 23927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// handler with D-Bus which has a standard signature that matches 24927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// dbus::ObjectProxy::SignalCallback. 25927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// 26927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// When a D-Bus signal is emitted, the stub handler is invoked, which unpacks 27927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// the expected parameters from dbus::Signal message and then calls 28927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// |signal_callback| with unpacked arguments. 29927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// 30927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// If the signal message doesn't contain correct number or types of arguments, 31927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// an error message is logged to the system log and the signal is ignored 32927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko// (|signal_callback| is not invoked). 33927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenkotemplate<typename... Args> 34927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenkovoid ConnectToSignal( 35927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko dbus::ObjectProxy* object_proxy, 36927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko const std::string& interface_name, 37927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko const std::string& signal_name, 38927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko base::Callback<void(Args...)> signal_callback, 39927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko dbus::ObjectProxy::OnConnectedCallback on_connected_callback) { 40927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko // Raw signal handler stub method. When called, unpacks the signal arguments 41927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko // from |signal| message buffer and redirects the call to 42927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko // |signal_callback_wrapper| which, in turn, would call the user-provided 43927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko // |signal_callback|. 44c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez auto dbus_signal_callback = []( 45c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez const base::Callback<void(Args...)>& signal_callback, 46c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez dbus::Signal* signal) { 47c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez // DBusParamReader::Invoke() needs a functor object, not a base::Callback. 48c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez // Wrap the callback with lambda so we can redirect the call. 49c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez auto signal_callback_wrapper = [signal_callback](const Args&... args) { 50c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez if (!signal_callback.is_null()) { 51c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez signal_callback.Run(args...); 52c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez } 53c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez }; 54c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez 55927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko dbus::MessageReader reader(signal); 5605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko DBusParamReader<false, Args...>::Invoke( 5705d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko signal_callback_wrapper, &reader, nullptr); 58927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko }; 59927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 60927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko // Register our stub handler with D-Bus ObjectProxy. 61927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko object_proxy->ConnectToSignal(interface_name, 62927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko signal_name, 63c7b0177da3ad8299c8c7650d1dc21768591bd362Luis Hector Chavez base::Bind(dbus_signal_callback, signal_callback), 64927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko on_connected_callback); 65927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko} 66927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 67927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko} // namespace dbus_utils 689ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 69927171f88672fda187fac64e1a28bb84ac6877bcAlex Vakulenko 70fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif // LIBBRILLO_BRILLO_DBUS_DBUS_SIGNAL_HANDLER_H_ 71