1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIBBRILLO_BRILLO_DBUS_DBUS_METHOD_RESPONSE_H_ 6 #define LIBBRILLO_BRILLO_DBUS_DBUS_METHOD_RESPONSE_H_ 7 8 #include <string> 9 10 #include <base/macros.h> 11 #include <brillo/brillo_export.h> 12 #include <brillo/dbus/dbus_param_writer.h> 13 #include <brillo/errors/error.h> 14 #include <dbus/exported_object.h> 15 #include <dbus/message.h> 16 17 namespace brillo { 18 19 class Error; 20 21 namespace dbus_utils { 22 23 using ResponseSender = dbus::ExportedObject::ResponseSender; 24 25 // DBusMethodResponseBase is a helper class used with asynchronous D-Bus method 26 // handlers to encapsulate the information needed to send the method call 27 // response when it is available. 28 class BRILLO_EXPORT DBusMethodResponseBase { 29 public: 30 DBusMethodResponseBase(dbus::MethodCall* method_call, ResponseSender sender); 31 virtual ~DBusMethodResponseBase(); 32 33 // Sends an error response. Marshals the |error| object over D-Bus. 34 // If |error| is from the "dbus" error domain, takes the |error_code| from 35 // |error| and uses it as the DBus error name. 36 // For error is from other domains, the full error information (domain, error 37 // code, error message) is encoded into the D-Bus error message and returned 38 // to the caller as "org.freedesktop.DBus.Failed". 39 void ReplyWithError(const brillo::Error* error); 40 41 // Constructs brillo::Error object from the parameters specified and send 42 // the error information over D-Bus using the method above. 43 void ReplyWithError(const base::Location& location, 44 const std::string& error_domain, 45 const std::string& error_code, 46 const std::string& error_message); 47 48 // Sends a raw D-Bus response message. 49 void SendRawResponse(std::unique_ptr<dbus::Response> response); 50 51 // Creates a custom response object for the current method call. 52 std::unique_ptr<dbus::Response> CreateCustomResponse() const; 53 54 // Checks if the response has been sent already. 55 bool IsResponseSent() const; 56 57 protected: 58 void CheckCanSendResponse() const; 59 60 // Aborts the method execution. Does not send any response message. 61 void Abort(); 62 63 private: 64 // A callback to be called to send the method call response message. 65 ResponseSender sender_; 66 // |method_call_| is actually owned by |sender_| (it is embedded as unique_ptr 67 // in the bound parameter list in the Callback). We set it to nullptr after 68 // the method call response has been sent to ensure we can't possibly try 69 // to send a response again somehow. 70 dbus::MethodCall* method_call_; 71 72 DISALLOW_COPY_AND_ASSIGN(DBusMethodResponseBase); 73 }; 74 75 // DBusMethodResponse is an explicitly-typed version of DBusMethodResponse. 76 // Using DBusMethodResponse<Types...> indicates the types a D-Bus method 77 // is expected to return. 78 template<typename... Types> 79 class DBusMethodResponse : public DBusMethodResponseBase { 80 public: 81 // Make the base class's custom constructor available to DBusMethodResponse. 82 using DBusMethodResponseBase::DBusMethodResponseBase; 83 84 // Sends the a successful response. |return_values| can contain a list 85 // of return values to be sent to the caller. Return(const Types &...return_values)86 inline void Return(const Types&... return_values) { 87 CheckCanSendResponse(); 88 auto response = CreateCustomResponse(); 89 dbus::MessageWriter writer(response.get()); 90 DBusParamWriter::Append(&writer, return_values...); 91 SendRawResponse(std::move(response)); 92 } 93 }; 94 95 } // namespace dbus_utils 96 } // namespace brillo 97 98 #endif // LIBBRILLO_BRILLO_DBUS_DBUS_METHOD_RESPONSE_H_ 99