Home | History | Annotate | Download | only in dbus
      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 tracked_objects::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.
     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