• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_STRONG_BINDING_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/memory/weak_ptr.h"
17 #include "mojo/public/cpp/bindings/binding.h"
18 #include "mojo/public/cpp/bindings/connection_error_callback.h"
19 #include "mojo/public/cpp/bindings/filter_chain.h"
20 #include "mojo/public/cpp/bindings/interface_ptr.h"
21 #include "mojo/public/cpp/bindings/interface_request.h"
22 #include "mojo/public/cpp/bindings/message_header_validator.h"
23 #include "mojo/public/cpp/system/core.h"
24 
25 namespace mojo {
26 
27 template <typename Interface>
28 class StrongBinding;
29 
30 template <typename Interface>
31 using StrongBindingPtr = base::WeakPtr<StrongBinding<Interface>>;
32 
33 // This connects an interface implementation strongly to a pipe. When a
34 // connection error is detected the implementation is deleted. If the task
35 // runner that a StrongBinding is bound on is stopped, the connection error
36 // handler will not be invoked and the implementation will not be deleted.
37 //
38 // To use, call StrongBinding<T>::Create() (see below) or the helper
39 // MakeStrongBinding function:
40 //
41 //   mojo::MakeStrongBinding(std::make_unique<FooImpl>(),
42 //                           std::move(foo_request));
43 //
44 template <typename Interface>
45 class StrongBinding {
46  public:
47   // Create a new StrongBinding instance. The instance owns itself, cleaning up
48   // only in the event of a pipe connection error. Returns a WeakPtr to the new
49   // StrongBinding instance.
Create(std::unique_ptr<Interface> impl,InterfaceRequest<Interface> request)50   static StrongBindingPtr<Interface> Create(
51       std::unique_ptr<Interface> impl,
52       InterfaceRequest<Interface> request) {
53     StrongBinding* binding =
54         new StrongBinding(std::move(impl), std::move(request));
55     return binding->weak_factory_.GetWeakPtr();
56   }
57 
58   // Note: The error handler must not delete the interface implementation.
59   //
60   // This method may only be called after this StrongBinding has been bound to a
61   // message pipe.
set_connection_error_handler(base::OnceClosure error_handler)62   void set_connection_error_handler(base::OnceClosure error_handler) {
63     DCHECK(binding_.is_bound());
64     connection_error_handler_ = std::move(error_handler);
65     connection_error_with_reason_handler_.Reset();
66   }
67 
set_connection_error_with_reason_handler(ConnectionErrorWithReasonCallback error_handler)68   void set_connection_error_with_reason_handler(
69       ConnectionErrorWithReasonCallback error_handler) {
70     DCHECK(binding_.is_bound());
71     connection_error_with_reason_handler_ = std::move(error_handler);
72     connection_error_handler_.Reset();
73   }
74 
75   // Stops processing incoming messages until
76   // ResumeIncomingMethodCallProcessing().
77   // Outgoing messages are still sent.
78   //
79   // No errors are detected on the message pipe while paused.
80   //
81   // This method may only be called if the object has been bound to a message
82   // pipe and there are no associated interfaces running.
PauseIncomingMethodCallProcessing()83   void PauseIncomingMethodCallProcessing() {
84     binding_.PauseIncomingMethodCallProcessing();
85   }
ResumeIncomingMethodCallProcessing()86   void ResumeIncomingMethodCallProcessing() {
87     binding_.ResumeIncomingMethodCallProcessing();
88   }
89 
90   // Forces the binding to close. This destroys the StrongBinding instance.
Close()91   void Close() { delete this; }
92 
impl()93   Interface* impl() { return impl_.get(); }
94 
95   // Sends a message on the underlying message pipe and runs the current
96   // message loop until its response is received. This can be used in tests to
97   // verify that no message was sent on a message pipe in response to some
98   // stimulus.
FlushForTesting()99   void FlushForTesting() { binding_.FlushForTesting(); }
100 
101  private:
StrongBinding(std::unique_ptr<Interface> impl,InterfaceRequest<Interface> request)102   StrongBinding(std::unique_ptr<Interface> impl,
103                 InterfaceRequest<Interface> request)
104       : impl_(std::move(impl)),
105         binding_(impl_.get(), std::move(request)),
106         weak_factory_(this) {
107     binding_.set_connection_error_with_reason_handler(
108         base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
109   }
110 
~StrongBinding()111   ~StrongBinding() {}
112 
OnConnectionError(uint32_t custom_reason,const std::string & description)113   void OnConnectionError(uint32_t custom_reason,
114                          const std::string& description) {
115     if (connection_error_handler_) {
116       std::move(connection_error_handler_).Run();
117     } else if (connection_error_with_reason_handler_) {
118       std::move(connection_error_with_reason_handler_)
119           .Run(custom_reason, description);
120     }
121     Close();
122   }
123 
124   std::unique_ptr<Interface> impl_;
125   base::OnceClosure connection_error_handler_;
126   ConnectionErrorWithReasonCallback connection_error_with_reason_handler_;
127   Binding<Interface> binding_;
128   base::WeakPtrFactory<StrongBinding> weak_factory_;
129 
130   DISALLOW_COPY_AND_ASSIGN(StrongBinding);
131 };
132 
133 template <typename Interface, typename Impl>
MakeStrongBinding(std::unique_ptr<Impl> impl,InterfaceRequest<Interface> request)134 StrongBindingPtr<Interface> MakeStrongBinding(
135     std::unique_ptr<Impl> impl,
136     InterfaceRequest<Interface> request) {
137   return StrongBinding<Interface>::Create(std::move(impl), std::move(request));
138 }
139 
140 }  // namespace mojo
141 
142 #endif  // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
143