// 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 <string> #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); 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". 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. 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_; DISALLOW_COPY_AND_ASSIGN(DBusMethodResponseBase); }; // 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. inline 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_