Home | History | Annotate | Download | only in bindings
      1 // Copyright 2015 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_INTERFACE_ENDPOINT_CLIENT_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_ENDPOINT_CLIENT_H_
      7 
      8 #include <stdint.h>
      9 
     10 #include <map>
     11 #include <memory>
     12 
     13 #include "base/callback.h"
     14 #include "base/logging.h"
     15 #include "base/macros.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "base/single_thread_task_runner.h"
     19 #include "base/threading/thread_checker.h"
     20 #include "mojo/public/cpp/bindings/message.h"
     21 #include "mojo/public/cpp/bindings/message_filter.h"
     22 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
     23 
     24 namespace mojo {
     25 
     26 class AssociatedGroup;
     27 class AssociatedGroupController;
     28 class InterfaceEndpointController;
     29 
     30 // InterfaceEndpointClient handles message sending and receiving of an interface
     31 // endpoint, either the implementation side or the client side.
     32 // It should only be accessed and destructed on the creating thread.
     33 class InterfaceEndpointClient : public MessageReceiverWithResponder {
     34  public:
     35   // |receiver| is okay to be null. If it is not null, it must outlive this
     36   // object.
     37   InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle,
     38                           MessageReceiverWithResponderStatus* receiver,
     39                           std::unique_ptr<MessageFilter> payload_validator,
     40                           bool expect_sync_requests,
     41                           scoped_refptr<base::SingleThreadTaskRunner> runner);
     42   ~InterfaceEndpointClient() override;
     43 
     44   // Sets the error handler to receive notifications when an error is
     45   // encountered.
     46   void set_connection_error_handler(const base::Closure& error_handler) {
     47     DCHECK(thread_checker_.CalledOnValidThread());
     48     error_handler_ = error_handler;
     49   }
     50 
     51   // Returns true if an error was encountered.
     52   bool encountered_error() const {
     53     DCHECK(thread_checker_.CalledOnValidThread());
     54     return encountered_error_;
     55   }
     56 
     57   // Returns true if this endpoint has any pending callbacks.
     58   bool has_pending_responders() const {
     59     DCHECK(thread_checker_.CalledOnValidThread());
     60     return !async_responders_.empty() || !sync_responses_.empty();
     61   }
     62 
     63   AssociatedGroupController* group_controller() const {
     64     return handle_.group_controller();
     65   }
     66   AssociatedGroup* associated_group();
     67   uint32_t interface_id() const;
     68 
     69   // After this call the object is in an invalid state and shouldn't be reused.
     70   ScopedInterfaceEndpointHandle PassHandle();
     71 
     72   // Raises an error on the underlying message pipe. It disconnects the pipe
     73   // and notifies all interfaces running on this pipe.
     74   void RaiseError();
     75 
     76   // MessageReceiverWithResponder implementation:
     77   bool Accept(Message* message) override;
     78   bool AcceptWithResponder(Message* message,
     79                            MessageReceiver* responder) override;
     80 
     81   // The following methods are called by the router. They must be called
     82   // outside of the router's lock.
     83 
     84   // NOTE: |message| must have passed message header validation.
     85   bool HandleIncomingMessage(Message* message);
     86   void NotifyError();
     87 
     88  private:
     89   // Maps from the id of a response to the MessageReceiver that handles the
     90   // response.
     91   using AsyncResponderMap =
     92       std::map<uint64_t, std::unique_ptr<MessageReceiver>>;
     93 
     94   struct SyncResponseInfo {
     95    public:
     96     explicit SyncResponseInfo(bool* in_response_received);
     97     ~SyncResponseInfo();
     98 
     99     std::unique_ptr<Message> response;
    100 
    101     // Points to a stack-allocated variable.
    102     bool* response_received;
    103 
    104    private:
    105     DISALLOW_COPY_AND_ASSIGN(SyncResponseInfo);
    106   };
    107 
    108   using SyncResponseMap = std::map<uint64_t, std::unique_ptr<SyncResponseInfo>>;
    109 
    110   // Used as the sink for |payload_validator_| and forwards messages to
    111   // HandleValidatedMessage().
    112   class HandleIncomingMessageThunk : public MessageReceiver {
    113    public:
    114     explicit HandleIncomingMessageThunk(InterfaceEndpointClient* owner);
    115     ~HandleIncomingMessageThunk() override;
    116 
    117     // MessageReceiver implementation:
    118     bool Accept(Message* message) override;
    119 
    120    private:
    121     InterfaceEndpointClient* const owner_;
    122 
    123     DISALLOW_COPY_AND_ASSIGN(HandleIncomingMessageThunk);
    124   };
    125 
    126   bool HandleValidatedMessage(Message* message);
    127 
    128   ScopedInterfaceEndpointHandle handle_;
    129   std::unique_ptr<AssociatedGroup> associated_group_;
    130   InterfaceEndpointController* controller_;
    131 
    132   MessageReceiverWithResponderStatus* const incoming_receiver_;
    133   std::unique_ptr<MessageFilter> payload_validator_;
    134   HandleIncomingMessageThunk thunk_;
    135 
    136   AsyncResponderMap async_responders_;
    137   SyncResponseMap sync_responses_;
    138 
    139   uint64_t next_request_id_;
    140 
    141   base::Closure error_handler_;
    142   bool encountered_error_;
    143 
    144   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
    145 
    146   base::ThreadChecker thread_checker_;
    147 
    148   base::WeakPtrFactory<InterfaceEndpointClient> weak_ptr_factory_;
    149 
    150   DISALLOW_COPY_AND_ASSIGN(InterfaceEndpointClient);
    151 };
    152 
    153 }  // namespace mojo
    154 
    155 #endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_ENDPOINT_CLIENT_H_
    156