• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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