xref: /aosp_15_r20/external/libchrome/mojo/public/cpp/bindings/message.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
6*635a8641SAndroid Build Coastguard Worker #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include <limits>
12*635a8641SAndroid Build Coastguard Worker #include <memory>
13*635a8641SAndroid Build Coastguard Worker #include <string>
14*635a8641SAndroid Build Coastguard Worker #include <vector>
15*635a8641SAndroid Build Coastguard Worker 
16*635a8641SAndroid Build Coastguard Worker #include "base/callback.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/component_export.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
21*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/buffer.h"
22*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/message_internal.h"
23*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
24*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
25*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message.h"
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker namespace mojo {
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker class AssociatedGroupController;
30*635a8641SAndroid Build Coastguard Worker 
31*635a8641SAndroid Build Coastguard Worker using ReportBadMessageCallback =
32*635a8641SAndroid Build Coastguard Worker     base::OnceCallback<void(const std::string& error)>;
33*635a8641SAndroid Build Coastguard Worker 
34*635a8641SAndroid Build Coastguard Worker // Message is a holder for the data and handles to be sent over a MessagePipe.
35*635a8641SAndroid Build Coastguard Worker // Message owns its data and handles, but a consumer of Message is free to
36*635a8641SAndroid Build Coastguard Worker // mutate the data and handles. The message's data is comprised of a header
37*635a8641SAndroid Build Coastguard Worker // followed by payload.
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)38*635a8641SAndroid Build Coastguard Worker class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) Message {
39*635a8641SAndroid Build Coastguard Worker  public:
40*635a8641SAndroid Build Coastguard Worker   static const uint32_t kFlagExpectsResponse = 1 << 0;
41*635a8641SAndroid Build Coastguard Worker   static const uint32_t kFlagIsResponse = 1 << 1;
42*635a8641SAndroid Build Coastguard Worker   static const uint32_t kFlagIsSync = 1 << 2;
43*635a8641SAndroid Build Coastguard Worker 
44*635a8641SAndroid Build Coastguard Worker   // Constructs an uninitialized Message object.
45*635a8641SAndroid Build Coastguard Worker   Message();
46*635a8641SAndroid Build Coastguard Worker 
47*635a8641SAndroid Build Coastguard Worker   // See the move-assignment operator below.
48*635a8641SAndroid Build Coastguard Worker   Message(Message&& other);
49*635a8641SAndroid Build Coastguard Worker 
50*635a8641SAndroid Build Coastguard Worker   // Constructs a new message with an unserialized context attached. This
51*635a8641SAndroid Build Coastguard Worker   // message may be serialized later if necessary.
52*635a8641SAndroid Build Coastguard Worker   explicit Message(
53*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<internal::UnserializedMessageContext> context);
54*635a8641SAndroid Build Coastguard Worker 
55*635a8641SAndroid Build Coastguard Worker   // Constructs a new serialized Message object with optional handles attached.
56*635a8641SAndroid Build Coastguard Worker   // This message is fully functional and may be exchanged for a
57*635a8641SAndroid Build Coastguard Worker   // ScopedMessageHandle for transit over a message pipe. See TakeMojoMessage().
58*635a8641SAndroid Build Coastguard Worker   //
59*635a8641SAndroid Build Coastguard Worker   // If |handles| is non-null, any handles in |*handles| are attached to the
60*635a8641SAndroid Build Coastguard Worker   // newly constructed message.
61*635a8641SAndroid Build Coastguard Worker   //
62*635a8641SAndroid Build Coastguard Worker   // Note that |payload_size| is only the initially known size of the message
63*635a8641SAndroid Build Coastguard Worker   // payload, if any. The payload can be expanded after construction using the
64*635a8641SAndroid Build Coastguard Worker   // interface returned by |payload_buffer()|.
65*635a8641SAndroid Build Coastguard Worker   Message(uint32_t name,
66*635a8641SAndroid Build Coastguard Worker           uint32_t flags,
67*635a8641SAndroid Build Coastguard Worker           size_t payload_size,
68*635a8641SAndroid Build Coastguard Worker           size_t payload_interface_id_count,
69*635a8641SAndroid Build Coastguard Worker           std::vector<ScopedHandle>* handles);
70*635a8641SAndroid Build Coastguard Worker 
71*635a8641SAndroid Build Coastguard Worker   // Constructs a new serialized Message object from an existing
72*635a8641SAndroid Build Coastguard Worker   // ScopedMessageHandle; e.g., one read from a message pipe.
73*635a8641SAndroid Build Coastguard Worker   //
74*635a8641SAndroid Build Coastguard Worker   // If the message had any handles attached, they will be extracted and
75*635a8641SAndroid Build Coastguard Worker   // retrievable via |handles()|. Such messages may NOT be sent back over
76*635a8641SAndroid Build Coastguard Worker   // another message pipe, but are otherwise safe to inspect and pass around.
77*635a8641SAndroid Build Coastguard Worker   Message(ScopedMessageHandle handle);
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker   ~Message();
80*635a8641SAndroid Build Coastguard Worker 
81*635a8641SAndroid Build Coastguard Worker   // Moves |other| into a new Message object. The moved-from Message becomes
82*635a8641SAndroid Build Coastguard Worker   // invalid and is effectively in a default-constructed state after this call.
83*635a8641SAndroid Build Coastguard Worker   Message& operator=(Message&& other);
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker   // Resets the Message to an uninitialized state. Upon reset, the Message
86*635a8641SAndroid Build Coastguard Worker   // exists as if it were default-constructed: it has no data buffer and owns no
87*635a8641SAndroid Build Coastguard Worker   // handles.
88*635a8641SAndroid Build Coastguard Worker   void Reset();
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker   // Indicates whether this Message is uninitialized.
91*635a8641SAndroid Build Coastguard Worker   bool IsNull() const { return !handle_.is_valid(); }
92*635a8641SAndroid Build Coastguard Worker 
93*635a8641SAndroid Build Coastguard Worker   // Indicates whether this Message is serialized.
94*635a8641SAndroid Build Coastguard Worker   bool is_serialized() const { return serialized_; }
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   // Access the raw bytes of the message.
97*635a8641SAndroid Build Coastguard Worker   const uint8_t* data() const {
98*635a8641SAndroid Build Coastguard Worker     DCHECK(payload_buffer_.is_valid());
99*635a8641SAndroid Build Coastguard Worker     return static_cast<const uint8_t*>(payload_buffer_.data());
100*635a8641SAndroid Build Coastguard Worker   }
101*635a8641SAndroid Build Coastguard Worker   uint8_t* mutable_data() { return const_cast<uint8_t*>(data()); }
102*635a8641SAndroid Build Coastguard Worker 
103*635a8641SAndroid Build Coastguard Worker   size_t data_num_bytes() const {
104*635a8641SAndroid Build Coastguard Worker     DCHECK(payload_buffer_.is_valid());
105*635a8641SAndroid Build Coastguard Worker     return payload_buffer_.cursor();
106*635a8641SAndroid Build Coastguard Worker   }
107*635a8641SAndroid Build Coastguard Worker 
108*635a8641SAndroid Build Coastguard Worker   // Access the header.
109*635a8641SAndroid Build Coastguard Worker   const internal::MessageHeader* header() const {
110*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<const internal::MessageHeader*>(data());
111*635a8641SAndroid Build Coastguard Worker   }
112*635a8641SAndroid Build Coastguard Worker   internal::MessageHeader* header() {
113*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<internal::MessageHeader*>(mutable_data());
114*635a8641SAndroid Build Coastguard Worker   }
115*635a8641SAndroid Build Coastguard Worker 
116*635a8641SAndroid Build Coastguard Worker   const internal::MessageHeaderV1* header_v1() const {
117*635a8641SAndroid Build Coastguard Worker     DCHECK_GE(version(), 1u);
118*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<const internal::MessageHeaderV1*>(data());
119*635a8641SAndroid Build Coastguard Worker   }
120*635a8641SAndroid Build Coastguard Worker   internal::MessageHeaderV1* header_v1() {
121*635a8641SAndroid Build Coastguard Worker     DCHECK_GE(version(), 1u);
122*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<internal::MessageHeaderV1*>(mutable_data());
123*635a8641SAndroid Build Coastguard Worker   }
124*635a8641SAndroid Build Coastguard Worker 
125*635a8641SAndroid Build Coastguard Worker   const internal::MessageHeaderV2* header_v2() const {
126*635a8641SAndroid Build Coastguard Worker     DCHECK_GE(version(), 2u);
127*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<const internal::MessageHeaderV2*>(data());
128*635a8641SAndroid Build Coastguard Worker   }
129*635a8641SAndroid Build Coastguard Worker   internal::MessageHeaderV2* header_v2() {
130*635a8641SAndroid Build Coastguard Worker     DCHECK_GE(version(), 2u);
131*635a8641SAndroid Build Coastguard Worker     return reinterpret_cast<internal::MessageHeaderV2*>(mutable_data());
132*635a8641SAndroid Build Coastguard Worker   }
133*635a8641SAndroid Build Coastguard Worker 
134*635a8641SAndroid Build Coastguard Worker   uint32_t version() const { return header()->version; }
135*635a8641SAndroid Build Coastguard Worker 
136*635a8641SAndroid Build Coastguard Worker   uint32_t interface_id() const { return header()->interface_id; }
137*635a8641SAndroid Build Coastguard Worker   void set_interface_id(uint32_t id) { header()->interface_id = id; }
138*635a8641SAndroid Build Coastguard Worker 
139*635a8641SAndroid Build Coastguard Worker   uint32_t name() const { return header()->name; }
140*635a8641SAndroid Build Coastguard Worker   bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); }
141*635a8641SAndroid Build Coastguard Worker 
142*635a8641SAndroid Build Coastguard Worker   // Access the request_id field (if present).
143*635a8641SAndroid Build Coastguard Worker   uint64_t request_id() const { return header_v1()->request_id; }
144*635a8641SAndroid Build Coastguard Worker   void set_request_id(uint64_t request_id) {
145*635a8641SAndroid Build Coastguard Worker     header_v1()->request_id = request_id;
146*635a8641SAndroid Build Coastguard Worker   }
147*635a8641SAndroid Build Coastguard Worker 
148*635a8641SAndroid Build Coastguard Worker   // Access the payload.
149*635a8641SAndroid Build Coastguard Worker   const uint8_t* payload() const;
150*635a8641SAndroid Build Coastguard Worker   uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); }
151*635a8641SAndroid Build Coastguard Worker   uint32_t payload_num_bytes() const;
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker   uint32_t payload_num_interface_ids() const;
154*635a8641SAndroid Build Coastguard Worker   const uint32_t* payload_interface_ids() const;
155*635a8641SAndroid Build Coastguard Worker 
156*635a8641SAndroid Build Coastguard Worker   internal::Buffer* payload_buffer() { return &payload_buffer_; }
157*635a8641SAndroid Build Coastguard Worker 
158*635a8641SAndroid Build Coastguard Worker   // Access the handles of a received message. Note that these are unused on
159*635a8641SAndroid Build Coastguard Worker   // outgoing messages.
160*635a8641SAndroid Build Coastguard Worker   const std::vector<ScopedHandle>* handles() const { return &handles_; }
161*635a8641SAndroid Build Coastguard Worker   std::vector<ScopedHandle>* mutable_handles() { return &handles_; }
162*635a8641SAndroid Build Coastguard Worker 
163*635a8641SAndroid Build Coastguard Worker   const std::vector<ScopedInterfaceEndpointHandle>*
164*635a8641SAndroid Build Coastguard Worker   associated_endpoint_handles() const {
165*635a8641SAndroid Build Coastguard Worker     return &associated_endpoint_handles_;
166*635a8641SAndroid Build Coastguard Worker   }
167*635a8641SAndroid Build Coastguard Worker   std::vector<ScopedInterfaceEndpointHandle>*
168*635a8641SAndroid Build Coastguard Worker   mutable_associated_endpoint_handles() {
169*635a8641SAndroid Build Coastguard Worker     return &associated_endpoint_handles_;
170*635a8641SAndroid Build Coastguard Worker   }
171*635a8641SAndroid Build Coastguard Worker 
172*635a8641SAndroid Build Coastguard Worker   // Takes ownership of any handles within |*context| and attaches them to this
173*635a8641SAndroid Build Coastguard Worker   // Message.
174*635a8641SAndroid Build Coastguard Worker   void AttachHandlesFromSerializationContext(
175*635a8641SAndroid Build Coastguard Worker       internal::SerializationContext* context);
176*635a8641SAndroid Build Coastguard Worker 
177*635a8641SAndroid Build Coastguard Worker   // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for
178*635a8641SAndroid Build Coastguard Worker   // transmission. Note that this invalidates this Message object, taking
179*635a8641SAndroid Build Coastguard Worker   // ownership of its internal storage and any attached handles.
180*635a8641SAndroid Build Coastguard Worker   ScopedMessageHandle TakeMojoMessage();
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker   // Notifies the system that this message is "bad," in this case meaning it was
183*635a8641SAndroid Build Coastguard Worker   // rejected by bindings validation code.
184*635a8641SAndroid Build Coastguard Worker   void NotifyBadMessage(const std::string& error);
185*635a8641SAndroid Build Coastguard Worker 
186*635a8641SAndroid Build Coastguard Worker   // Serializes |associated_endpoint_handles_| into the payload_interface_ids
187*635a8641SAndroid Build Coastguard Worker   // field.
188*635a8641SAndroid Build Coastguard Worker   void SerializeAssociatedEndpointHandles(
189*635a8641SAndroid Build Coastguard Worker       AssociatedGroupController* group_controller);
190*635a8641SAndroid Build Coastguard Worker 
191*635a8641SAndroid Build Coastguard Worker   // Deserializes |associated_endpoint_handles_| from the payload_interface_ids
192*635a8641SAndroid Build Coastguard Worker   // field.
193*635a8641SAndroid Build Coastguard Worker   bool DeserializeAssociatedEndpointHandles(
194*635a8641SAndroid Build Coastguard Worker       AssociatedGroupController* group_controller);
195*635a8641SAndroid Build Coastguard Worker 
196*635a8641SAndroid Build Coastguard Worker   // If this Message has an unserialized message context attached, force it to
197*635a8641SAndroid Build Coastguard Worker   // be serialized immediately. Otherwise this does nothing.
198*635a8641SAndroid Build Coastguard Worker   void SerializeIfNecessary();
199*635a8641SAndroid Build Coastguard Worker 
200*635a8641SAndroid Build Coastguard Worker   // Takes the unserialized message context from this Message if its tag matches
201*635a8641SAndroid Build Coastguard Worker   // |tag|.
202*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<internal::UnserializedMessageContext> TakeUnserializedContext(
203*635a8641SAndroid Build Coastguard Worker       const internal::UnserializedMessageContext::Tag* tag);
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   template <typename MessageType>
206*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<MessageType> TakeUnserializedContext() {
207*635a8641SAndroid Build Coastguard Worker     auto generic_context = TakeUnserializedContext(&MessageType::kMessageTag);
208*635a8641SAndroid Build Coastguard Worker     if (!generic_context)
209*635a8641SAndroid Build Coastguard Worker       return nullptr;
210*635a8641SAndroid Build Coastguard Worker     return base::WrapUnique(
211*635a8641SAndroid Build Coastguard Worker         generic_context.release()->template SafeCast<MessageType>());
212*635a8641SAndroid Build Coastguard Worker   }
213*635a8641SAndroid Build Coastguard Worker 
214*635a8641SAndroid Build Coastguard Worker #if defined(ENABLE_IPC_FUZZER)
215*635a8641SAndroid Build Coastguard Worker   const char* interface_name() const { return interface_name_; }
216*635a8641SAndroid Build Coastguard Worker   void set_interface_name(const char* interface_name) {
217*635a8641SAndroid Build Coastguard Worker     interface_name_ = interface_name;
218*635a8641SAndroid Build Coastguard Worker   }
219*635a8641SAndroid Build Coastguard Worker 
220*635a8641SAndroid Build Coastguard Worker   const char* method_name() const { return method_name_; }
221*635a8641SAndroid Build Coastguard Worker   void set_method_name(const char* method_name) { method_name_ = method_name; }
222*635a8641SAndroid Build Coastguard Worker #endif
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker  private:
225*635a8641SAndroid Build Coastguard Worker   ScopedMessageHandle handle_;
226*635a8641SAndroid Build Coastguard Worker 
227*635a8641SAndroid Build Coastguard Worker   // A Buffer which may be used to allocate blocks of data within the message
228*635a8641SAndroid Build Coastguard Worker   // payload for reading or writing.
229*635a8641SAndroid Build Coastguard Worker   internal::Buffer payload_buffer_;
230*635a8641SAndroid Build Coastguard Worker 
231*635a8641SAndroid Build Coastguard Worker   std::vector<ScopedHandle> handles_;
232*635a8641SAndroid Build Coastguard Worker   std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_;
233*635a8641SAndroid Build Coastguard Worker 
234*635a8641SAndroid Build Coastguard Worker   // Indicates whether this Message object is transferable, i.e. can be sent
235*635a8641SAndroid Build Coastguard Worker   // elsewhere. In general this is true unless |handle_| is invalid or
236*635a8641SAndroid Build Coastguard Worker   // serialized handles have been extracted from the serialized message object
237*635a8641SAndroid Build Coastguard Worker   // identified by |handle_|.
238*635a8641SAndroid Build Coastguard Worker   bool transferable_ = false;
239*635a8641SAndroid Build Coastguard Worker 
240*635a8641SAndroid Build Coastguard Worker   // Indicates whether this Message object is serialized.
241*635a8641SAndroid Build Coastguard Worker   bool serialized_ = false;
242*635a8641SAndroid Build Coastguard Worker 
243*635a8641SAndroid Build Coastguard Worker #if defined(ENABLE_IPC_FUZZER)
244*635a8641SAndroid Build Coastguard Worker   const char* interface_name_ = nullptr;
245*635a8641SAndroid Build Coastguard Worker   const char* method_name_ = nullptr;
246*635a8641SAndroid Build Coastguard Worker #endif
247*635a8641SAndroid Build Coastguard Worker 
248*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Message);
249*635a8641SAndroid Build Coastguard Worker };
250*635a8641SAndroid Build Coastguard Worker 
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)251*635a8641SAndroid Build Coastguard Worker class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) MessageReceiver {
252*635a8641SAndroid Build Coastguard Worker  public:
253*635a8641SAndroid Build Coastguard Worker   virtual ~MessageReceiver() {}
254*635a8641SAndroid Build Coastguard Worker 
255*635a8641SAndroid Build Coastguard Worker   // Indicates whether the receiver prefers to receive serialized messages.
256*635a8641SAndroid Build Coastguard Worker   virtual bool PrefersSerializedMessages();
257*635a8641SAndroid Build Coastguard Worker 
258*635a8641SAndroid Build Coastguard Worker   // The receiver may mutate the given message.  Returns true if the message
259*635a8641SAndroid Build Coastguard Worker   // was accepted and false otherwise, indicating that the message was invalid
260*635a8641SAndroid Build Coastguard Worker   // or malformed.
261*635a8641SAndroid Build Coastguard Worker   virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0;
262*635a8641SAndroid Build Coastguard Worker };
263*635a8641SAndroid Build Coastguard Worker 
264*635a8641SAndroid Build Coastguard Worker class MessageReceiverWithResponder : public MessageReceiver {
265*635a8641SAndroid Build Coastguard Worker  public:
~MessageReceiverWithResponder()266*635a8641SAndroid Build Coastguard Worker   ~MessageReceiverWithResponder() override {}
267*635a8641SAndroid Build Coastguard Worker 
268*635a8641SAndroid Build Coastguard Worker   // A variant on Accept that registers a MessageReceiver (known as the
269*635a8641SAndroid Build Coastguard Worker   // responder) to handle the response message generated from the given
270*635a8641SAndroid Build Coastguard Worker   // message. The responder's Accept method may be called during
271*635a8641SAndroid Build Coastguard Worker   // AcceptWithResponder or some time after its return.
272*635a8641SAndroid Build Coastguard Worker   virtual bool AcceptWithResponder(Message* message,
273*635a8641SAndroid Build Coastguard Worker                                    std::unique_ptr<MessageReceiver> responder)
274*635a8641SAndroid Build Coastguard Worker       WARN_UNUSED_RESULT = 0;
275*635a8641SAndroid Build Coastguard Worker };
276*635a8641SAndroid Build Coastguard Worker 
277*635a8641SAndroid Build Coastguard Worker // A MessageReceiver that is also able to provide status about the state
278*635a8641SAndroid Build Coastguard Worker // of the underlying MessagePipe to which it will be forwarding messages
279*635a8641SAndroid Build Coastguard Worker // received via the |Accept()| call.
280*635a8641SAndroid Build Coastguard Worker class MessageReceiverWithStatus : public MessageReceiver {
281*635a8641SAndroid Build Coastguard Worker  public:
~MessageReceiverWithStatus()282*635a8641SAndroid Build Coastguard Worker   ~MessageReceiverWithStatus() override {}
283*635a8641SAndroid Build Coastguard Worker 
284*635a8641SAndroid Build Coastguard Worker   // Returns |true| if this MessageReceiver is currently bound to a MessagePipe,
285*635a8641SAndroid Build Coastguard Worker   // the pipe has not been closed, and the pipe has not encountered an error.
286*635a8641SAndroid Build Coastguard Worker   virtual bool IsConnected() = 0;
287*635a8641SAndroid Build Coastguard Worker 
288*635a8641SAndroid Build Coastguard Worker   // Determines if this MessageReceiver is still bound to a message pipe and has
289*635a8641SAndroid Build Coastguard Worker   // not encountered any errors. This is asynchronous but may be called from any
290*635a8641SAndroid Build Coastguard Worker   // sequence. |callback| is eventually invoked from an arbitrary sequence with
291*635a8641SAndroid Build Coastguard Worker   // the result of the query.
292*635a8641SAndroid Build Coastguard Worker   virtual void IsConnectedAsync(base::OnceCallback<void(bool)> callback) = 0;
293*635a8641SAndroid Build Coastguard Worker };
294*635a8641SAndroid Build Coastguard Worker 
295*635a8641SAndroid Build Coastguard Worker // An alternative to MessageReceiverWithResponder for cases in which it
296*635a8641SAndroid Build Coastguard Worker // is necessary for the implementor of this interface to know about the status
297*635a8641SAndroid Build Coastguard Worker // of the MessagePipe which will carry the responses.
298*635a8641SAndroid Build Coastguard Worker class MessageReceiverWithResponderStatus : public MessageReceiver {
299*635a8641SAndroid Build Coastguard Worker  public:
~MessageReceiverWithResponderStatus()300*635a8641SAndroid Build Coastguard Worker   ~MessageReceiverWithResponderStatus() override {}
301*635a8641SAndroid Build Coastguard Worker 
302*635a8641SAndroid Build Coastguard Worker   // A variant on Accept that registers a MessageReceiverWithStatus (known as
303*635a8641SAndroid Build Coastguard Worker   // the responder) to handle the response message generated from the given
304*635a8641SAndroid Build Coastguard Worker   // message. Any of the responder's methods (Accept or IsValid) may be called
305*635a8641SAndroid Build Coastguard Worker   // during  AcceptWithResponder or some time after its return.
306*635a8641SAndroid Build Coastguard Worker   virtual bool AcceptWithResponder(Message* message,
307*635a8641SAndroid Build Coastguard Worker                                    std::unique_ptr<MessageReceiverWithStatus>
308*635a8641SAndroid Build Coastguard Worker                                        responder) WARN_UNUSED_RESULT = 0;
309*635a8641SAndroid Build Coastguard Worker };
310*635a8641SAndroid Build Coastguard Worker 
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)311*635a8641SAndroid Build Coastguard Worker class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) PassThroughFilter
312*635a8641SAndroid Build Coastguard Worker     : public MessageReceiver {
313*635a8641SAndroid Build Coastguard Worker  public:
314*635a8641SAndroid Build Coastguard Worker   PassThroughFilter();
315*635a8641SAndroid Build Coastguard Worker   ~PassThroughFilter() override;
316*635a8641SAndroid Build Coastguard Worker 
317*635a8641SAndroid Build Coastguard Worker   // MessageReceiver:
318*635a8641SAndroid Build Coastguard Worker   bool Accept(Message* message) override;
319*635a8641SAndroid Build Coastguard Worker 
320*635a8641SAndroid Build Coastguard Worker  private:
321*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(PassThroughFilter);
322*635a8641SAndroid Build Coastguard Worker };
323*635a8641SAndroid Build Coastguard Worker 
324*635a8641SAndroid Build Coastguard Worker namespace internal {
325*635a8641SAndroid Build Coastguard Worker class SyncMessageResponseSetup;
326*635a8641SAndroid Build Coastguard Worker }
327*635a8641SAndroid Build Coastguard Worker 
328*635a8641SAndroid Build Coastguard Worker // An object which should be constructed on the stack immediately before making
329*635a8641SAndroid Build Coastguard Worker // a sync request for which the caller wishes to perform custom validation of
330*635a8641SAndroid Build Coastguard Worker // the response value(s). It is illegal to make more than one sync call during
331*635a8641SAndroid Build Coastguard Worker // the lifetime of the topmost SyncMessageResponseContext, but it is legal to
332*635a8641SAndroid Build Coastguard Worker // nest contexts to support reentrancy.
333*635a8641SAndroid Build Coastguard Worker //
334*635a8641SAndroid Build Coastguard Worker // Usage should look something like:
335*635a8641SAndroid Build Coastguard Worker //
336*635a8641SAndroid Build Coastguard Worker //     SyncMessageResponseContext response_context;
337*635a8641SAndroid Build Coastguard Worker //     foo_interface->SomeSyncCall(&response_value);
338*635a8641SAndroid Build Coastguard Worker //     if (response_value.IsBad())
339*635a8641SAndroid Build Coastguard Worker //       response_context.ReportBadMessage("Bad response_value!");
340*635a8641SAndroid Build Coastguard Worker //
COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)341*635a8641SAndroid Build Coastguard Worker class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) SyncMessageResponseContext {
342*635a8641SAndroid Build Coastguard Worker  public:
343*635a8641SAndroid Build Coastguard Worker   SyncMessageResponseContext();
344*635a8641SAndroid Build Coastguard Worker   ~SyncMessageResponseContext();
345*635a8641SAndroid Build Coastguard Worker 
346*635a8641SAndroid Build Coastguard Worker   static SyncMessageResponseContext* current();
347*635a8641SAndroid Build Coastguard Worker 
348*635a8641SAndroid Build Coastguard Worker   void ReportBadMessage(const std::string& error);
349*635a8641SAndroid Build Coastguard Worker 
350*635a8641SAndroid Build Coastguard Worker   ReportBadMessageCallback GetBadMessageCallback();
351*635a8641SAndroid Build Coastguard Worker 
352*635a8641SAndroid Build Coastguard Worker  private:
353*635a8641SAndroid Build Coastguard Worker   friend class internal::SyncMessageResponseSetup;
354*635a8641SAndroid Build Coastguard Worker 
355*635a8641SAndroid Build Coastguard Worker   SyncMessageResponseContext* outer_context_;
356*635a8641SAndroid Build Coastguard Worker   Message response_;
357*635a8641SAndroid Build Coastguard Worker 
358*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(SyncMessageResponseContext);
359*635a8641SAndroid Build Coastguard Worker };
360*635a8641SAndroid Build Coastguard Worker 
361*635a8641SAndroid Build Coastguard Worker // Read a single message from the pipe. The caller should have created the
362*635a8641SAndroid Build Coastguard Worker // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if
363*635a8641SAndroid Build Coastguard Worker // the caller should wait on the handle to become readable. Returns
364*635a8641SAndroid Build Coastguard Worker // MOJO_RESULT_OK if the message was read successfully and should be
365*635a8641SAndroid Build Coastguard Worker // dispatched, otherwise returns an error code if something went wrong.
366*635a8641SAndroid Build Coastguard Worker //
367*635a8641SAndroid Build Coastguard Worker // NOTE: The message hasn't been validated and may be malformed!
368*635a8641SAndroid Build Coastguard Worker COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
369*635a8641SAndroid Build Coastguard Worker MojoResult ReadMessage(MessagePipeHandle handle, Message* message);
370*635a8641SAndroid Build Coastguard Worker 
371*635a8641SAndroid Build Coastguard Worker // Reports the currently dispatching Message as bad. Note that this is only
372*635a8641SAndroid Build Coastguard Worker // legal to call from directly within the stack frame of a message dispatch. If
373*635a8641SAndroid Build Coastguard Worker // you need to do asynchronous work before you can determine the legitimacy of
374*635a8641SAndroid Build Coastguard Worker // a message, use GetBadMessageCallback() and retain its result until you're
375*635a8641SAndroid Build Coastguard Worker // ready to invoke or discard it.
376*635a8641SAndroid Build Coastguard Worker COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
377*635a8641SAndroid Build Coastguard Worker void ReportBadMessage(const std::string& error);
378*635a8641SAndroid Build Coastguard Worker 
379*635a8641SAndroid Build Coastguard Worker // Acquires a callback which may be run to report the currently dispatching
380*635a8641SAndroid Build Coastguard Worker // Message as bad. Note that this is only legal to call from directly within the
381*635a8641SAndroid Build Coastguard Worker // stack frame of a message dispatch, but the returned callback may be called
382*635a8641SAndroid Build Coastguard Worker // exactly once any time thereafter to report the message as bad. This may only
383*635a8641SAndroid Build Coastguard Worker // be called once per message.
384*635a8641SAndroid Build Coastguard Worker COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
385*635a8641SAndroid Build Coastguard Worker ReportBadMessageCallback GetBadMessageCallback();
386*635a8641SAndroid Build Coastguard Worker 
387*635a8641SAndroid Build Coastguard Worker }  // namespace mojo
388*635a8641SAndroid Build Coastguard Worker 
389*635a8641SAndroid Build Coastguard Worker #endif  // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
390