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.
112 lines
4.1 KiB
112 lines
4.1 KiB
4 months ago
|
// 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_METHOD_RESPONSE_H_
|
||
|
#define LIBBRILLO_BRILLO_DBUS_DBUS_METHOD_RESPONSE_H_
|
||
|
|
||
|
#include <memory>
|
||
|
#include <string>
|
||
|
#include <utility>
|
||
|
|
||
|
#include <base/bind.h>
|
||
|
#include <base/location.h>
|
||
|
#include <base/macros.h>
|
||
|
#include <brillo/brillo_export.h>
|
||
|
#include <brillo/dbus/dbus_param_writer.h>
|
||
|
#include <brillo/errors/error.h>
|
||
|
#include <dbus/exported_object.h>
|
||
|
#include <dbus/message.h>
|
||
|
|
||
|
namespace brillo {
|
||
|
|
||
|
class Error;
|
||
|
|
||
|
namespace dbus_utils {
|
||
|
|
||
|
using ResponseSender = ::dbus::ExportedObject::ResponseSender;
|
||
|
|
||
|
// DBusMethodResponseBase is a helper class used with asynchronous D-Bus method
|
||
|
// handlers to encapsulate the information needed to send the method call
|
||
|
// response when it is available.
|
||
|
class BRILLO_EXPORT DBusMethodResponseBase {
|
||
|
public:
|
||
|
DBusMethodResponseBase(::dbus::MethodCall* method_call,
|
||
|
ResponseSender sender);
|
||
|
DBusMethodResponseBase(DBusMethodResponseBase&& other)
|
||
|
: sender_(std::exchange(
|
||
|
other.sender_,
|
||
|
base::Bind([](std::unique_ptr<dbus::Response> response) {
|
||
|
LOG(DFATAL)
|
||
|
<< "Empty DBusMethodResponseBase attempts to send a response";
|
||
|
}))),
|
||
|
method_call_(std::exchange(other.method_call_, nullptr)) {}
|
||
|
DBusMethodResponseBase& operator=(DBusMethodResponseBase&& other) = delete;
|
||
|
|
||
|
virtual ~DBusMethodResponseBase();
|
||
|
|
||
|
// Sends an error response. Marshals the |error| object over D-Bus.
|
||
|
// If |error| is from the "dbus" error domain, takes the |error_code| from
|
||
|
// |error| and uses it as the DBus error name.
|
||
|
// For error is from other domains, the full error information (domain, error
|
||
|
// code, error message) is encoded into the D-Bus error message and returned
|
||
|
// to the caller as "org.freedesktop.DBus.Failed".
|
||
|
virtual void ReplyWithError(const brillo::Error* error);
|
||
|
|
||
|
// Constructs brillo::Error object from the parameters specified and send
|
||
|
// the error information over D-Bus using the method above.
|
||
|
virtual void ReplyWithError(const base::Location& location,
|
||
|
const std::string& error_domain,
|
||
|
const std::string& error_code,
|
||
|
const std::string& error_message);
|
||
|
|
||
|
// Sends a raw D-Bus response message.
|
||
|
void SendRawResponse(std::unique_ptr<::dbus::Response> response);
|
||
|
|
||
|
// Creates a custom response object for the current method call.
|
||
|
std::unique_ptr<::dbus::Response> CreateCustomResponse() const;
|
||
|
|
||
|
// Checks if the response has been sent already.
|
||
|
bool IsResponseSent() const;
|
||
|
|
||
|
protected:
|
||
|
void CheckCanSendResponse() const;
|
||
|
|
||
|
// Aborts the method execution. Does not send any response message.
|
||
|
void Abort();
|
||
|
|
||
|
private:
|
||
|
// A callback to be called to send the method call response message.
|
||
|
ResponseSender sender_;
|
||
|
// |method_call_| is actually owned by |sender_| (it is embedded as unique_ptr
|
||
|
// in the bound parameter list in the Callback). We set it to nullptr after
|
||
|
// the method call response has been sent to ensure we can't possibly try
|
||
|
// to send a response again somehow.
|
||
|
::dbus::MethodCall* method_call_;
|
||
|
};
|
||
|
|
||
|
// DBusMethodResponse is an explicitly-typed version of DBusMethodResponse.
|
||
|
// Using DBusMethodResponse<Types...> indicates the types a D-Bus method
|
||
|
// is expected to return.
|
||
|
template<typename... Types>
|
||
|
class DBusMethodResponse : public DBusMethodResponseBase {
|
||
|
public:
|
||
|
// Make the base class's custom constructor available to DBusMethodResponse.
|
||
|
using DBusMethodResponseBase::DBusMethodResponseBase;
|
||
|
|
||
|
// Sends the a successful response. |return_values| can contain a list
|
||
|
// of return values to be sent to the caller.
|
||
|
virtual void Return(const Types&... return_values) {
|
||
|
CheckCanSendResponse();
|
||
|
auto response = CreateCustomResponse();
|
||
|
::dbus::MessageWriter writer(response.get());
|
||
|
DBusParamWriter::Append(&writer, return_values...);
|
||
|
SendRawResponse(std::move(response));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace dbus_utils
|
||
|
} // namespace brillo
|
||
|
|
||
|
#endif // LIBBRILLO_BRILLO_DBUS_DBUS_METHOD_RESPONSE_H_
|