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.
649 lines
28 KiB
649 lines
28 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.
|
|
|
|
// DBusObject is a special helper class that simplifies the implementation of
|
|
// D-Bus objects in C++. It provides an easy way to define interfaces with
|
|
// methods and properties and offloads a lot of work to register the object and
|
|
// all of its interfaces, to marshal method calls (by converting D-Bus method
|
|
// parameters to native C++ types and invoking native method handlers), etc.
|
|
|
|
// The basic usage pattern of this class is as follows:
|
|
/*
|
|
class MyDbusObject {
|
|
public:
|
|
MyDbusObject(ExportedObjectManager* object_manager,
|
|
const scoped_refptr<dbus::Bus>& bus)
|
|
: dbus_object_(object_manager, bus,
|
|
dbus::ObjectPath("/org/chromium/my_obj")) {}
|
|
|
|
void Init(const AsyncEventSequencer::CompletionAction& callback) {
|
|
DBusInterface* my_interface =
|
|
dbus_object_.AddOrGetInterface("org.chromium.MyInterface");
|
|
my_interface->AddSimpleMethodHandler("Method1", this,
|
|
&MyDbusObject::Method1);
|
|
my_interface->AddSimpleMethodHandlerWithError("Method2", this,
|
|
&MyDbusObject::Method2);
|
|
my_interface->AddMethodHandler("Method3", this, &MyDbusObject::Method3);
|
|
my_interface->AddProperty("Property1", &prop1_);
|
|
my_interface->AddProperty("Property2", &prop2_);
|
|
prop1_.SetValue("prop1_value");
|
|
prop2_.SetValue(50);
|
|
// Register the object by exporting its methods and properties and
|
|
// exposing them to D-Bus clients.
|
|
dbus_object_.RegisterAsync(callback);
|
|
}
|
|
|
|
private:
|
|
DBusObject dbus_object_;
|
|
|
|
// Make sure the properties outlive the DBusObject they are registered with.
|
|
brillo::dbus_utils::ExportedProperty<std::string> prop1_;
|
|
brillo::dbus_utils::ExportedProperty<int> prop2_;
|
|
int Method1() { return 5; }
|
|
bool Method2(brillo::ErrorPtr* error, const std::string& message);
|
|
void Method3(std::unique_ptr<DBusMethodResponse<int_32>> response,
|
|
const std::string& message) {
|
|
if (message.empty()) {
|
|
response->ReplyWithError(FROM_HERE,
|
|
brillo::errors::dbus::kDomain,
|
|
DBUS_ERROR_INVALID_ARGS,
|
|
"Message string cannot be empty");
|
|
return;
|
|
}
|
|
int32_t message_len = message.length();
|
|
response->Return(message_len);
|
|
}
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MyDbusObject);
|
|
};
|
|
*/
|
|
|
|
#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
|
|
#define LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include <base/bind.h>
|
|
#include <base/callback_helpers.h>
|
|
#include <base/macros.h>
|
|
#include <base/memory/weak_ptr.h>
|
|
#include <brillo/brillo_export.h>
|
|
#include <brillo/dbus/async_event_sequencer.h>
|
|
#include <brillo/dbus/dbus_object_internal_impl.h>
|
|
#include <brillo/dbus/dbus_signal.h>
|
|
#include <brillo/dbus/exported_property_set.h>
|
|
#include <brillo/errors/error.h>
|
|
#include <dbus/bus.h>
|
|
#include <dbus/exported_object.h>
|
|
#include <dbus/message.h>
|
|
#include <dbus/object_path.h>
|
|
|
|
namespace brillo {
|
|
namespace dbus_utils {
|
|
|
|
class ExportedObjectManager;
|
|
class ExportedPropertyBase;
|
|
class DBusObject;
|
|
|
|
// This is an implementation proxy class for a D-Bus interface of an object.
|
|
// The important functionality for the users is the ability to add D-Bus method
|
|
// handlers and define D-Bus object properties. This is achieved by using one
|
|
// of the overload of AddSimpleMethodHandler()/AddMethodHandler() and
|
|
// AddProperty() respectively.
|
|
// There are three overloads for DBusInterface::AddSimpleMethodHandler() and
|
|
// AddMethodHandler() each:
|
|
// 1. That takes a handler as base::Callback
|
|
// 2. That takes a static function
|
|
// 3. That takes a class instance pointer and a class member function
|
|
// The signature of the handler for AddSimpleMethodHandler must be one of:
|
|
// R(Args... args) [IN only]
|
|
// void(Args... args) [IN/OUT]
|
|
// The signature of the handler for AddSimpleMethodHandlerWithError must be:
|
|
// bool(ErrorPtr* error, Args... args) [IN/OUT]
|
|
// The signature of the handler for AddSimpleMethodHandlerWithErrorAndMessage:
|
|
// bool(ErrorPtr* error, dbus::Message* msg, Args... args) [IN/OUT]
|
|
// The signature of the handler for AddMethodHandler must be:
|
|
// void(std::unique_ptr<DBusMethodResponse<T...>> response,
|
|
// Args... args) [IN]
|
|
// The signature of the handler for AddMethodHandlerWithMessage must be:
|
|
// void(std::unique_ptr<DBusMethodResponse<T...>> response,
|
|
// dbus::Message* msg, Args... args) [IN]
|
|
// There is also an AddRawMethodHandler() call that lets provide a custom
|
|
// handler that can parse its own input parameter and construct a custom
|
|
// response.
|
|
// The signature of the handler for AddRawMethodHandler must be:
|
|
// void(dbus::MethodCall* method_call, ResponseSender sender)
|
|
class BRILLO_EXPORT DBusInterface final {
|
|
public:
|
|
DBusInterface(DBusObject* dbus_object, const std::string& interface_name);
|
|
|
|
// Register sync DBus method handler for |method_name| as base::Callback.
|
|
template<typename R, typename... Args>
|
|
inline void AddSimpleMethodHandler(
|
|
const std::string& method_name,
|
|
const base::Callback<R(Args...)>& handler) {
|
|
Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
|
|
this, method_name, handler);
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a static
|
|
// function.
|
|
template<typename R, typename... Args>
|
|
inline void AddSimpleMethodHandler(const std::string& method_name,
|
|
R(*handler)(Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
|
|
this, method_name, base::Bind(handler));
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a class member
|
|
// function.
|
|
template<typename Instance, typename Class, typename R, typename... Args>
|
|
inline void AddSimpleMethodHandler(const std::string& method_name,
|
|
Instance instance,
|
|
R(Class::*handler)(Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Same as above but for const-method of a class.
|
|
template<typename Instance, typename Class, typename R, typename... Args>
|
|
inline void AddSimpleMethodHandler(const std::string& method_name,
|
|
Instance instance,
|
|
R(Class::*handler)(Args...) const) {
|
|
Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register sync DBus method handler for |method_name| as base::Callback.
|
|
template<typename... Args>
|
|
inline void AddSimpleMethodHandlerWithError(
|
|
const std::string& method_name,
|
|
const base::Callback<bool(ErrorPtr*, Args...)>& handler) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
|
|
this, method_name, handler);
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a static
|
|
// function.
|
|
template<typename... Args>
|
|
inline void AddSimpleMethodHandlerWithError(
|
|
const std::string& method_name,
|
|
bool(*handler)(ErrorPtr*, Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
|
|
this, method_name, base::Bind(handler));
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a class member
|
|
// function.
|
|
template<typename Instance, typename Class, typename... Args>
|
|
inline void AddSimpleMethodHandlerWithError(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
bool(Class::*handler)(ErrorPtr*, Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Same as above but for const-method of a class.
|
|
template<typename Instance, typename Class, typename... Args>
|
|
inline void AddSimpleMethodHandlerWithError(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
bool(Class::*handler)(ErrorPtr*, Args...) const) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register sync DBus method handler for |method_name| as base::Callback.
|
|
// Passing the method sender as a first parameter to the callback.
|
|
template <typename... Args>
|
|
inline void AddSimpleMethodHandlerWithErrorAndMessage(
|
|
const std::string& method_name,
|
|
const base::Callback<bool(ErrorPtr*, ::dbus::Message*, Args...)>&
|
|
handler) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
|
|
this, method_name, handler);
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a static
|
|
// function. Passing the method D-Bus message as the second parameter to the
|
|
// callback.
|
|
template <typename... Args>
|
|
inline void AddSimpleMethodHandlerWithErrorAndMessage(
|
|
const std::string& method_name,
|
|
bool (*handler)(ErrorPtr*, ::dbus::Message*, Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
|
|
this, method_name, base::Bind(handler));
|
|
}
|
|
|
|
// Register sync D-Bus method handler for |method_name| as a class member
|
|
// function. Passing the method D-Bus message as the second parameter to the
|
|
// callback.
|
|
template <typename Instance, typename Class, typename... Args>
|
|
inline void AddSimpleMethodHandlerWithErrorAndMessage(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
bool (Class::*handler)(ErrorPtr*, ::dbus::Message*, Args...)) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Same as above but for const-method of a class.
|
|
template <typename Instance, typename Class, typename... Args>
|
|
inline void AddSimpleMethodHandlerWithErrorAndMessage(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
bool (Class::*handler)(ErrorPtr*, ::dbus::Message*, Args...) const) {
|
|
Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register an async DBus method handler for |method_name| as base::Callback.
|
|
template<typename Response, typename... Args>
|
|
inline void AddMethodHandler(
|
|
const std::string& method_name,
|
|
const base::Callback<void(std::unique_ptr<Response>, Args...)>& handler) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
|
|
this, method_name, handler);
|
|
}
|
|
|
|
// Register an async D-Bus method handler for |method_name| as a static
|
|
// function.
|
|
template<typename Response, typename... Args>
|
|
inline void AddMethodHandler(
|
|
const std::string& method_name,
|
|
void (*handler)(std::unique_ptr<Response>, Args...)) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler));
|
|
}
|
|
|
|
// Register an async D-Bus method handler for |method_name| as a class member
|
|
// function.
|
|
template<typename Response,
|
|
typename Instance,
|
|
typename Class,
|
|
typename... Args>
|
|
inline void AddMethodHandler(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
void(Class::*handler)(std::unique_ptr<Response>, Args...)) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Same as above but for const-method of a class.
|
|
template<typename Response,
|
|
typename Instance,
|
|
typename Class,
|
|
typename... Args>
|
|
inline void AddMethodHandler(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
void(Class::*handler)(std::unique_ptr<Response>, Args...) const) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register an async DBus method handler for |method_name| as base::Callback.
|
|
template <typename Response, typename... Args>
|
|
inline void AddMethodHandlerWithMessage(
|
|
const std::string& method_name,
|
|
const base::Callback<void(
|
|
std::unique_ptr<Response>, ::dbus::Message*, Args...)>& handler) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
|
|
this, method_name, handler);
|
|
}
|
|
|
|
// Register an async D-Bus method handler for |method_name| as a static
|
|
// function.
|
|
template <typename Response, typename... Args>
|
|
inline void AddMethodHandlerWithMessage(
|
|
const std::string& method_name,
|
|
void (*handler)(std::unique_ptr<Response>, ::dbus::Message*, Args...)) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler));
|
|
}
|
|
|
|
// Register an async D-Bus method handler for |method_name| as a class member
|
|
// function.
|
|
template <typename Response,
|
|
typename Instance,
|
|
typename Class,
|
|
typename... Args>
|
|
inline void AddMethodHandlerWithMessage(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
void (Class::*handler)(std::unique_ptr<Response>,
|
|
::dbus::Message*,
|
|
Args...)) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Same as above but for const-method of a class.
|
|
template <typename Response,
|
|
typename Instance,
|
|
typename Class,
|
|
typename... Args>
|
|
inline void AddMethodHandlerWithMessage(
|
|
const std::string& method_name,
|
|
Instance instance,
|
|
void (Class::*handler)(std::unique_ptr<Response>,
|
|
::dbus::Message*,
|
|
Args...) const) {
|
|
static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
|
|
"Response must be DBusMethodResponse<T...>");
|
|
Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register a raw D-Bus method handler for |method_name| as base::Callback.
|
|
inline void AddRawMethodHandler(
|
|
const std::string& method_name,
|
|
const base::Callback<void(::dbus::MethodCall*, ResponseSender)>&
|
|
handler) {
|
|
Handler<RawDBusInterfaceMethodHandler>::Add(this, method_name, handler);
|
|
}
|
|
|
|
// Register a raw D-Bus method handler for |method_name| as a class member
|
|
// function.
|
|
template <typename Instance, typename Class>
|
|
inline void AddRawMethodHandler(const std::string& method_name,
|
|
Instance instance,
|
|
void (Class::*handler)(::dbus::MethodCall*,
|
|
ResponseSender)) {
|
|
Handler<RawDBusInterfaceMethodHandler>::Add(
|
|
this, method_name, base::Bind(handler, instance));
|
|
}
|
|
|
|
// Register a D-Bus property.
|
|
void AddProperty(const std::string& property_name,
|
|
ExportedPropertyBase* prop_base);
|
|
|
|
// Unregisters a D-Bus property.
|
|
void RemoveProperty(const std::string& property_name);
|
|
|
|
// Registers a D-Bus signal that has a specified number and types (|Args|) of
|
|
// arguments. Returns a weak pointer to the DBusSignal object which can be
|
|
// used to send the signal on this interface when needed:
|
|
/*
|
|
DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
|
|
auto signal = itf->RegisterSignal<int, bool>("MySignal");
|
|
...
|
|
// Send the Interface.MySig(12, true) signal.
|
|
if (signal.lock()->Send(12, true)) { ... }
|
|
*/
|
|
// Or if the signal signature is long or complex, you can alias the
|
|
// DBusSignal<Args...> signal type and use RegisterSignalOfType method
|
|
// instead:
|
|
/*
|
|
DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
|
|
using MySignal = DBusSignal<int, bool>;
|
|
auto signal = itf->RegisterSignalOfType<MySignal>("MySignal");
|
|
...
|
|
// Send the Interface.MySig(12, true) signal.
|
|
if (signal.lock()->Send(12, true)) { ... }
|
|
*/
|
|
// If the signal with the given name was already registered, the existing
|
|
// copy of the signal proxy object is returned as long as the method signature
|
|
// of the original signal matches the current call. If it doesn't, the method
|
|
// aborts.
|
|
|
|
// RegisterSignalOfType can be used to create a signal if the type of the
|
|
// complete DBusSignal<Args...> class which is pre-defined/aliased earlier.
|
|
template<typename DBusSignalType>
|
|
inline std::weak_ptr<DBusSignalType> RegisterSignalOfType(
|
|
const std::string& signal_name) {
|
|
auto signal = std::make_shared<DBusSignalType>(
|
|
dbus_object_, interface_name_, signal_name);
|
|
AddSignalImpl(signal_name, signal);
|
|
return signal;
|
|
}
|
|
|
|
// For simple signal arguments, you can specify their types directly in
|
|
// RegisterSignal<t1, t2, ...>():
|
|
// auto signal = itf->RegisterSignal<int>("SignalName");
|
|
// This will create a callback signal object that expects one int argument.
|
|
template<typename... Args>
|
|
inline std::weak_ptr<DBusSignal<Args...>> RegisterSignal(
|
|
const std::string& signal_name) {
|
|
return RegisterSignalOfType<DBusSignal<Args...>>(signal_name);
|
|
}
|
|
|
|
private:
|
|
// Helper to create an instance of DBusInterfaceMethodHandlerInterface-derived
|
|
// handler and add it to the method handler map of the interface.
|
|
// This makes the actual AddXXXMethodHandler() methods very light-weight and
|
|
// easier to provide different overloads for various method handler kinds.
|
|
// Using struct here to allow partial specialization on HandlerType while
|
|
// letting the compiler to deduce the type of the callback without explicitly
|
|
// specifying it.
|
|
template<typename HandlerType>
|
|
struct Handler {
|
|
template<typename CallbackType>
|
|
inline static void Add(DBusInterface* self,
|
|
const std::string& method_name,
|
|
const CallbackType& callback) {
|
|
std::unique_ptr<DBusInterfaceMethodHandlerInterface> sync_method_handler(
|
|
new HandlerType(callback));
|
|
self->AddHandlerImpl(method_name, std::move(sync_method_handler));
|
|
}
|
|
};
|
|
// A generic D-Bus method handler for the interface. It extracts the method
|
|
// name from |method_call|, looks up a registered handler from |handlers_|
|
|
// map and dispatched the call to that handler.
|
|
void HandleMethodCall(::dbus::MethodCall* method_call, ResponseSender sender);
|
|
// Helper to add a handler for method |method_name| to the |handlers_| map.
|
|
// Not marked BRILLO_PRIVATE because it needs to be called by the inline
|
|
// template functions AddMethodHandler(...)
|
|
void AddHandlerImpl(
|
|
const std::string& method_name,
|
|
std::unique_ptr<DBusInterfaceMethodHandlerInterface> handler);
|
|
// Helper to add a signal object to the |signals_| map.
|
|
// Not marked BRILLO_PRIVATE because it needs to be called by the inline
|
|
// template function RegisterSignalOfType(...)
|
|
void AddSignalImpl(const std::string& signal_name,
|
|
const std::shared_ptr<DBusSignalBase>& signal);
|
|
// Exports all the methods and properties of this interface and claims the
|
|
// D-Bus interface.
|
|
// object_manager - ExportedObjectManager instance that notifies D-Bus
|
|
// listeners of a new interface being claimed.
|
|
// exported_object - instance of D-Bus object the interface is being added to.
|
|
// object_path - D-Bus object path for the object instance.
|
|
// interface_name - name of interface being registered.
|
|
// completion_callback - a callback to be called when the asynchronous
|
|
// registration operation is completed.
|
|
BRILLO_PRIVATE void ExportAsync(
|
|
ExportedObjectManager* object_manager,
|
|
::dbus::Bus* bus,
|
|
::dbus::ExportedObject* exported_object,
|
|
const ::dbus::ObjectPath& object_path,
|
|
const AsyncEventSequencer::CompletionAction& completion_callback);
|
|
// Exports all the methods and properties of this interface and claims the
|
|
// D-Bus interface synchronously.
|
|
// object_manager - ExportedObjectManager instance that notifies D-Bus
|
|
// listeners of a new interface being claimed.
|
|
// exported_object - instance of D-Bus object the interface is being added to.
|
|
// object_path - D-Bus object path for the object instance.
|
|
// interface_name - name of interface being registered.
|
|
BRILLO_PRIVATE void ExportAndBlock(ExportedObjectManager* object_manager,
|
|
::dbus::Bus* bus,
|
|
::dbus::ExportedObject* exported_object,
|
|
const ::dbus::ObjectPath& object_path);
|
|
// Releases the D-Bus interface and unexports all the methods asynchronously.
|
|
BRILLO_PRIVATE void UnexportAsync(
|
|
ExportedObjectManager* object_manager,
|
|
::dbus::ExportedObject* exported_object,
|
|
const ::dbus::ObjectPath& object_path,
|
|
const AsyncEventSequencer::CompletionAction& completion_callback);
|
|
// Releases the D-Bus interface and unexports all the methods synchronously.
|
|
BRILLO_PRIVATE void UnexportAndBlock(ExportedObjectManager* object_manager,
|
|
::dbus::ExportedObject* exported_object,
|
|
const ::dbus::ObjectPath& object_path);
|
|
|
|
BRILLO_PRIVATE void ClaimInterface(
|
|
base::WeakPtr<ExportedObjectManager> object_manager,
|
|
const ::dbus::ObjectPath& object_path,
|
|
const ExportedPropertySet::PropertyWriter& writer,
|
|
bool all_succeeded);
|
|
|
|
// Method registration map.
|
|
std::map<std::string, std::unique_ptr<DBusInterfaceMethodHandlerInterface>>
|
|
handlers_;
|
|
// Signal registration map.
|
|
std::map<std::string, std::shared_ptr<DBusSignalBase>> signals_;
|
|
|
|
friend class DBusObject;
|
|
friend class DBusInterfaceTestHelper;
|
|
DBusObject* dbus_object_;
|
|
std::string interface_name_;
|
|
base::ScopedClosureRunner release_interface_cb_;
|
|
|
|
base::WeakPtrFactory<DBusInterface> weak_factory_{this};
|
|
DISALLOW_COPY_AND_ASSIGN(DBusInterface);
|
|
};
|
|
|
|
// A D-Bus object implementation class. Manages the interfaces implemented
|
|
// by this object.
|
|
class BRILLO_EXPORT DBusObject {
|
|
public:
|
|
using PropertyHandlerSetupCallback = base::Callback<void(
|
|
DBusInterface* prop_interface, ExportedPropertySet* property_set)>;
|
|
|
|
// object_manager - ExportedObjectManager instance that notifies D-Bus
|
|
// listeners of a new interface being claimed and property
|
|
// changes on those interfaces.
|
|
// object_path - D-Bus object path for the object instance.
|
|
DBusObject(ExportedObjectManager* object_manager,
|
|
const scoped_refptr<::dbus::Bus>& bus,
|
|
const ::dbus::ObjectPath& object_path);
|
|
|
|
// property_handler_setup_callback - To be called when setting up property
|
|
// method handlers. Clients can register
|
|
// their own custom property method handlers
|
|
// (GetAll/Get/Set) by passing in this
|
|
// callback.
|
|
DBusObject(ExportedObjectManager* object_manager,
|
|
const scoped_refptr<::dbus::Bus>& bus,
|
|
const ::dbus::ObjectPath& object_path,
|
|
PropertyHandlerSetupCallback property_handler_setup_callback);
|
|
|
|
virtual ~DBusObject();
|
|
|
|
// Returns an proxy handler for the interface |interface_name|. If the
|
|
// interface proxy does not exist yet, it will be automatically created.
|
|
DBusInterface* AddOrGetInterface(const std::string& interface_name);
|
|
|
|
// Finds an interface with the given name. Returns nullptr if there is no
|
|
// interface registered by this name.
|
|
DBusInterface* FindInterface(const std::string& interface_name) const;
|
|
|
|
// Removes the previously added proxy handler for the interface
|
|
// |interface_name|.
|
|
void RemoveInterface(const std::string& interface_name);
|
|
|
|
// Exports a proxy handler for the interface |interface_name|. If the
|
|
// interface proxy does not exist yet, it will be automatically created.
|
|
void ExportInterfaceAsync(
|
|
const std::string& interface_name,
|
|
const AsyncEventSequencer::CompletionAction& completion_callback);
|
|
|
|
// Exports a proxy handler for the interface |interface_name|. If the
|
|
// interface proxy does not exist yet, it will be automatically created. This
|
|
// call is synchronous and will block until all methods of the interface are
|
|
// registered and the interface is claimed.
|
|
void ExportInterfaceAndBlock(const std::string& interface_name);
|
|
|
|
// Unexports the interface |interface_name| and unexports all method handlers.
|
|
// In some cases, one may want to export an interface even after it's removed.
|
|
// In that case, they should call this method before removing the interface
|
|
// to make sure it will start with a clean state of method handlers.
|
|
void UnexportInterfaceAsync(
|
|
const std::string& interface_name,
|
|
const AsyncEventSequencer::CompletionAction& completion_callback);
|
|
|
|
// Unexports the interface |interface_name| and unexports all method handlers.
|
|
// In some cases, one may want to export an interface even after it's removed.
|
|
// In that case, they should call this method before removing the interface
|
|
// to make sure it will start with a clean state of method handlers.
|
|
// This call is synchronous and will block until the interface is released and
|
|
// all of its methods of are unregistered.
|
|
void UnexportInterfaceAndBlock(const std::string& interface_name);
|
|
|
|
// Registers the object instance with D-Bus. This is an asynchronous call
|
|
// that will call |completion_callback| when the object and all of its
|
|
// interfaces are registered.
|
|
virtual void RegisterAsync(
|
|
const AsyncEventSequencer::CompletionAction& completion_callback);
|
|
|
|
// Registers the object instance with D-Bus. This is call is synchronous and
|
|
// will block until the object and all of its interfaces are registered.
|
|
virtual void RegisterAndBlock();
|
|
|
|
// Unregister the object instance with D-Bus. This will unregister the
|
|
// |exported_object_| and its path from the bus. The destruction of
|
|
// |exported_object_| will be deferred in an async task posted by the bus.
|
|
// It is guarantee that upon return from this call a new DBusObject with the
|
|
// same object path can be created/registered.
|
|
virtual void UnregisterAsync();
|
|
|
|
// Returns the ExportedObjectManager proxy, if any. If DBusObject has been
|
|
// constructed without an object manager, this method returns an empty
|
|
// smart pointer (containing nullptr).
|
|
const base::WeakPtr<ExportedObjectManager>& GetObjectManager() const {
|
|
return object_manager_;
|
|
}
|
|
|
|
// Sends a signal from the exported D-Bus object.
|
|
bool SendSignal(::dbus::Signal* signal);
|
|
|
|
// Returns the reference to dbus::Bus this object is associated with.
|
|
scoped_refptr<::dbus::Bus> GetBus() { return bus_; }
|
|
|
|
private:
|
|
// Add the org.freedesktop.DBus.Properties interface to the object.
|
|
void RegisterPropertiesInterface();
|
|
|
|
// A map of all the interfaces added to this object.
|
|
std::map<std::string, std::unique_ptr<DBusInterface>> interfaces_;
|
|
// Exported property set for properties registered with the interfaces
|
|
// implemented by this D-Bus object.
|
|
ExportedPropertySet property_set_;
|
|
// Delegate object implementing org.freedesktop.DBus.ObjectManager interface.
|
|
base::WeakPtr<ExportedObjectManager> object_manager_;
|
|
// D-Bus bus object.
|
|
scoped_refptr<::dbus::Bus> bus_;
|
|
// D-Bus object path for this object.
|
|
::dbus::ObjectPath object_path_;
|
|
// D-Bus object instance once this object is successfully exported.
|
|
::dbus::ExportedObject* exported_object_ = nullptr; // weak; owned by |bus_|.
|
|
// Sets up property method handlers.
|
|
PropertyHandlerSetupCallback property_handler_setup_callback_;
|
|
|
|
friend class DBusInterface;
|
|
DISALLOW_COPY_AND_ASSIGN(DBusObject);
|
|
};
|
|
|
|
} // namespace dbus_utils
|
|
} // namespace brillo
|
|
|
|
#endif // LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
|