• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
set_connection_error_handler(const base::Closure & error_handler)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.
encountered_error()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.
has_pending_responders()58   bool has_pending_responders() const {
59     DCHECK(thread_checker_.CalledOnValidThread());
60     return !async_responders_.empty() || !sync_responses_.empty();
61   }
62 
group_controller()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