dbus_method_response.h revision fed60b0c640828b320f56293c8bebc43fd2b1da8
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
17namespace brillo {
18
19class Error;
20
21namespace dbus_utils {
22
23using 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.
28class 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.
78template<typename... Types>
79class 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