Home | History | Annotate | Download | only in bindings
      1 // Copyright 2014 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <limits>
     12 #include <memory>
     13 #include <string>
     14 #include <vector>
     15 
     16 #include "base/callback.h"
     17 #include "base/compiler_specific.h"
     18 #include "base/logging.h"
     19 #include "mojo/public/cpp/bindings/bindings_export.h"
     20 #include "mojo/public/cpp/bindings/lib/message_buffer.h"
     21 #include "mojo/public/cpp/bindings/lib/message_internal.h"
     22 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
     23 #include "mojo/public/cpp/system/message.h"
     24 
     25 namespace mojo {
     26 
     27 class AssociatedGroupController;
     28 
     29 using ReportBadMessageCallback = base::Callback<void(const std::string& error)>;
     30 
     31 // Message is a holder for the data and handles to be sent over a MessagePipe.
     32 // Message owns its data and handles, but a consumer of Message is free to
     33 // mutate the data and handles. The message's data is comprised of a header
     34 // followed by payload.
     35 class MOJO_CPP_BINDINGS_EXPORT Message {
     36  public:
     37   static const uint32_t kFlagExpectsResponse = 1 << 0;
     38   static const uint32_t kFlagIsResponse = 1 << 1;
     39   static const uint32_t kFlagIsSync = 1 << 2;
     40 
     41   Message();
     42   Message(Message&& other);
     43 
     44   ~Message();
     45 
     46   Message& operator=(Message&& other);
     47 
     48   // Resets the Message to an uninitialized state. Upon reset, the Message
     49   // exists as if it were default-constructed: it has no data buffer and owns no
     50   // handles.
     51   void Reset();
     52 
     53   // Indicates whether this Message is uninitialized.
     54   bool IsNull() const { return !buffer_; }
     55 
     56   // Initializes a Message with enough space for |capacity| bytes.
     57   void Initialize(size_t capacity, bool zero_initialized);
     58 
     59   // Initializes a Message from an existing Mojo MessageHandle.
     60   void InitializeFromMojoMessage(ScopedMessageHandle message,
     61                                  uint32_t num_bytes,
     62                                  std::vector<Handle>* handles);
     63 
     64   uint32_t data_num_bytes() const {
     65     return static_cast<uint32_t>(buffer_->size());
     66   }
     67 
     68   // Access the raw bytes of the message.
     69   const uint8_t* data() const {
     70     return static_cast<const uint8_t*>(buffer_->data());
     71   }
     72 
     73   uint8_t* mutable_data() { return static_cast<uint8_t*>(buffer_->data()); }
     74 
     75   // Access the header.
     76   const internal::MessageHeader* header() const {
     77     return static_cast<const internal::MessageHeader*>(buffer_->data());
     78   }
     79   internal::MessageHeader* header() {
     80     return static_cast<internal::MessageHeader*>(buffer_->data());
     81   }
     82 
     83   const internal::MessageHeaderV1* header_v1() const {
     84     DCHECK_GE(version(), 1u);
     85     return static_cast<const internal::MessageHeaderV1*>(buffer_->data());
     86   }
     87   internal::MessageHeaderV1* header_v1() {
     88     DCHECK_GE(version(), 1u);
     89     return static_cast<internal::MessageHeaderV1*>(buffer_->data());
     90   }
     91 
     92   const internal::MessageHeaderV2* header_v2() const {
     93     DCHECK_GE(version(), 2u);
     94     return static_cast<const internal::MessageHeaderV2*>(buffer_->data());
     95   }
     96   internal::MessageHeaderV2* header_v2() {
     97     DCHECK_GE(version(), 2u);
     98     return static_cast<internal::MessageHeaderV2*>(buffer_->data());
     99   }
    100 
    101   uint32_t version() const { return header()->version; }
    102 
    103   uint32_t interface_id() const { return header()->interface_id; }
    104   void set_interface_id(uint32_t id) { header()->interface_id = id; }
    105 
    106   uint32_t name() const { return header()->name; }
    107   bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); }
    108 
    109   // Access the request_id field (if present).
    110   uint64_t request_id() const { return header_v1()->request_id; }
    111   void set_request_id(uint64_t request_id) {
    112     header_v1()->request_id = request_id;
    113   }
    114 
    115   // Access the payload.
    116   const uint8_t* payload() const;
    117   uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); }
    118   uint32_t payload_num_bytes() const;
    119 
    120   uint32_t payload_num_interface_ids() const;
    121   const uint32_t* payload_interface_ids() const;
    122 
    123   // Access the handles.
    124   const std::vector<Handle>* handles() const { return &handles_; }
    125   std::vector<Handle>* mutable_handles() { return &handles_; }
    126 
    127   const std::vector<ScopedInterfaceEndpointHandle>*
    128   associated_endpoint_handles() const {
    129     return &associated_endpoint_handles_;
    130   }
    131   std::vector<ScopedInterfaceEndpointHandle>*
    132   mutable_associated_endpoint_handles() {
    133     return &associated_endpoint_handles_;
    134   }
    135 
    136   // Access the underlying Buffer interface.
    137   internal::Buffer* buffer() { return buffer_.get(); }
    138 
    139   // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for
    140   // transmission. Note that this invalidates this Message object, taking
    141   // ownership of its internal storage and any attached handles.
    142   ScopedMessageHandle TakeMojoMessage();
    143 
    144   // Notifies the system that this message is "bad," in this case meaning it was
    145   // rejected by bindings validation code.
    146   void NotifyBadMessage(const std::string& error);
    147 
    148   // Serializes |associated_endpoint_handles_| into the payload_interface_ids
    149   // field.
    150   void SerializeAssociatedEndpointHandles(
    151       AssociatedGroupController* group_controller);
    152 
    153   // Deserializes |associated_endpoint_handles_| from the payload_interface_ids
    154   // field.
    155   bool DeserializeAssociatedEndpointHandles(
    156       AssociatedGroupController* group_controller);
    157 
    158  private:
    159   void CloseHandles();
    160 
    161   std::unique_ptr<internal::MessageBuffer> buffer_;
    162   std::vector<Handle> handles_;
    163   std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_;
    164 
    165   DISALLOW_COPY_AND_ASSIGN(Message);
    166 };
    167 
    168 class MessageReceiver {
    169  public:
    170   virtual ~MessageReceiver() {}
    171 
    172   // The receiver may mutate the given message.  Returns true if the message
    173   // was accepted and false otherwise, indicating that the message was invalid
    174   // or malformed.
    175   virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0;
    176 };
    177 
    178 class MessageReceiverWithResponder : public MessageReceiver {
    179  public:
    180   ~MessageReceiverWithResponder() override {}
    181 
    182   // A variant on Accept that registers a MessageReceiver (known as the
    183   // responder) to handle the response message generated from the given
    184   // message. The responder's Accept method may be called during
    185   // AcceptWithResponder or some time after its return.
    186   //
    187   // NOTE: Upon returning true, AcceptWithResponder assumes ownership of
    188   // |responder| and will delete it after calling |responder->Accept| or upon
    189   // its own destruction.
    190   //
    191   // TODO(yzshen): consider changing |responder| to
    192   // std::unique_ptr<MessageReceiver>.
    193   virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
    194       WARN_UNUSED_RESULT = 0;
    195 };
    196 
    197 // A MessageReceiver that is also able to provide status about the state
    198 // of the underlying MessagePipe to which it will be forwarding messages
    199 // received via the |Accept()| call.
    200 class MessageReceiverWithStatus : public MessageReceiver {
    201  public:
    202   ~MessageReceiverWithStatus() override {}
    203 
    204   // Returns |true| if this MessageReceiver is currently bound to a MessagePipe,
    205   // the pipe has not been closed, and the pipe has not encountered an error.
    206   virtual bool IsValid() = 0;
    207 
    208   // DCHECKs if this MessageReceiver is currently bound to a MessagePipe, the
    209   // pipe has not been closed, and the pipe has not encountered an error.
    210   // This function may be called on any thread.
    211   virtual void DCheckInvalid(const std::string& message) = 0;
    212 };
    213 
    214 // An alternative to MessageReceiverWithResponder for cases in which it
    215 // is necessary for the implementor of this interface to know about the status
    216 // of the MessagePipe which will carry the responses.
    217 class MessageReceiverWithResponderStatus : public MessageReceiver {
    218  public:
    219   ~MessageReceiverWithResponderStatus() override {}
    220 
    221   // A variant on Accept that registers a MessageReceiverWithStatus (known as
    222   // the responder) to handle the response message generated from the given
    223   // message. Any of the responder's methods (Accept or IsValid) may be called
    224   // during  AcceptWithResponder or some time after its return.
    225   //
    226   // NOTE: Upon returning true, AcceptWithResponder assumes ownership of
    227   // |responder| and will delete it after calling |responder->Accept| or upon
    228   // its own destruction.
    229   //
    230   // TODO(yzshen): consider changing |responder| to
    231   // std::unique_ptr<MessageReceiver>.
    232   virtual bool AcceptWithResponder(Message* message,
    233                                    MessageReceiverWithStatus* responder)
    234       WARN_UNUSED_RESULT = 0;
    235 };
    236 
    237 class MOJO_CPP_BINDINGS_EXPORT PassThroughFilter
    238     : NON_EXPORTED_BASE(public MessageReceiver) {
    239  public:
    240   PassThroughFilter();
    241   ~PassThroughFilter() override;
    242 
    243   // MessageReceiver:
    244   bool Accept(Message* message) override;
    245 
    246  private:
    247   DISALLOW_COPY_AND_ASSIGN(PassThroughFilter);
    248 };
    249 
    250 namespace internal {
    251 class SyncMessageResponseSetup;
    252 }
    253 
    254 // An object which should be constructed on the stack immediately before making
    255 // a sync request for which the caller wishes to perform custom validation of
    256 // the response value(s). It is illegal to make more than one sync call during
    257 // the lifetime of the topmost SyncMessageResponseContext, but it is legal to
    258 // nest contexts to support reentrancy.
    259 //
    260 // Usage should look something like:
    261 //
    262 //     SyncMessageResponseContext response_context;
    263 //     foo_interface->SomeSyncCall(&response_value);
    264 //     if (response_value.IsBad())
    265 //       response_context.ReportBadMessage("Bad response_value!");
    266 //
    267 class MOJO_CPP_BINDINGS_EXPORT SyncMessageResponseContext {
    268  public:
    269   SyncMessageResponseContext();
    270   ~SyncMessageResponseContext();
    271 
    272   static SyncMessageResponseContext* current();
    273 
    274   void ReportBadMessage(const std::string& error);
    275 
    276   const ReportBadMessageCallback& GetBadMessageCallback();
    277 
    278  private:
    279   friend class internal::SyncMessageResponseSetup;
    280 
    281   SyncMessageResponseContext* outer_context_;
    282   Message response_;
    283   ReportBadMessageCallback bad_message_callback_;
    284 
    285   DISALLOW_COPY_AND_ASSIGN(SyncMessageResponseContext);
    286 };
    287 
    288 // Read a single message from the pipe. The caller should have created the
    289 // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if
    290 // the caller should wait on the handle to become readable. Returns
    291 // MOJO_RESULT_OK if the message was read successfully and should be
    292 // dispatched, otherwise returns an error code if something went wrong.
    293 //
    294 // NOTE: The message hasn't been validated and may be malformed!
    295 MojoResult ReadMessage(MessagePipeHandle handle, Message* message);
    296 
    297 // Reports the currently dispatching Message as bad. Note that this is only
    298 // legal to call from directly within the stack frame of a message dispatch. If
    299 // you need to do asynchronous work before you can determine the legitimacy of
    300 // a message, use TakeBadMessageCallback() and retain its result until you're
    301 // ready to invoke or discard it.
    302 MOJO_CPP_BINDINGS_EXPORT
    303 void ReportBadMessage(const std::string& error);
    304 
    305 // Acquires a callback which may be run to report the currently dispatching
    306 // Message as bad. Note that this is only legal to call from directly within the
    307 // stack frame of a message dispatch, but the returned callback may be called
    308 // exactly once any time thereafter to report the message as bad. This may only
    309 // be called once per message.
    310 MOJO_CPP_BINDINGS_EXPORT
    311 ReportBadMessageCallback GetBadMessageCallback();
    312 
    313 }  // namespace mojo
    314 
    315 #endif  // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_
    316