OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/common/mojo/mojo_shell_connection_impl.h" | 5 #include "content/common/mojo/mojo_shell_connection_impl.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 // Safe to call any time before Start() is called. | 108 // Safe to call any time before Start() is called. |
109 void SetDefaultBinderForBrowserConnection( | 109 void SetDefaultBinderForBrowserConnection( |
110 const shell::InterfaceRegistry::Binder& binder) { | 110 const shell::InterfaceRegistry::Binder& binder) { |
111 DCHECK(!started_); | 111 DCHECK(!started_); |
112 default_browser_binder_ = base::Bind( | 112 default_browser_binder_ = base::Bind( |
113 &IOThreadContext::CallBinderOnTaskRunner, | 113 &IOThreadContext::CallBinderOnTaskRunner, |
114 base::ThreadTaskRunnerHandle::Get(), binder); | 114 base::ThreadTaskRunnerHandle::Get(), binder); |
115 } | 115 } |
116 | 116 |
117 // Safe to call any time after Start() is called. | |
118 void GetRemoteInterface(const mojo::String& interface_name, | |
119 mojo::ScopedMessagePipeHandle request_handle) { | |
120 DCHECK(started_); | |
121 io_task_runner_->PostTask( | |
122 FROM_HERE, | |
123 base::Bind(&IOThreadContext::GetRemoteInterfaceOnIOThread, this, | |
124 interface_name, base::Passed(&request_handle))); | |
125 } | |
126 | |
127 private: | 117 private: |
128 friend class base::RefCountedThreadSafe<IOThreadContext>; | 118 friend class base::RefCountedThreadSafe<IOThreadContext>; |
129 | 119 |
130 ~IOThreadContext() override {} | 120 ~IOThreadContext() override {} |
131 | 121 |
132 void StartOnIOThread() { | 122 void StartOnIOThread() { |
133 // Should bind |io_thread_checker_| to the context's thread. | 123 // Should bind |io_thread_checker_| to the context's thread. |
134 DCHECK(io_thread_checker_.CalledOnValidThread()); | 124 DCHECK(io_thread_checker_.CalledOnValidThread()); |
135 service_context_.reset(new shell::ServiceContext( | 125 service_context_.reset(new shell::ServiceContext( |
136 this, std::move(pending_service_request_), | 126 this, std::move(pending_service_request_), |
137 std::move(io_thread_connector_), | 127 std::move(io_thread_connector_), |
138 std::move(pending_connector_request_))); | 128 std::move(pending_connector_request_))); |
139 } | 129 } |
140 | 130 |
141 void ShutDownOnIOThread() { | 131 void ShutDownOnIOThread() { |
142 DCHECK(io_thread_checker_.CalledOnValidThread()); | 132 DCHECK(io_thread_checker_.CalledOnValidThread()); |
143 service_context_.reset(); | 133 service_context_.reset(); |
144 factory_bindings_.CloseAllBindings(); | 134 factory_bindings_.CloseAllBindings(); |
145 } | 135 } |
146 | 136 |
147 void GetRemoteInterfaceOnIOThread( | |
148 const mojo::String& interface_name, | |
149 mojo::ScopedMessagePipeHandle request_handle) { | |
150 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
151 if (browser_connection_) { | |
152 browser_connection_->GetRemoteInterfaces()->GetInterface( | |
153 interface_name, std::move(request_handle)); | |
154 } else { | |
155 pending_remote_interface_requests_.emplace(interface_name, | |
156 std::move(request_handle)); | |
157 } | |
158 } | |
159 | |
160 void OnBrowserConnectionLost() { | 137 void OnBrowserConnectionLost() { |
161 DCHECK(io_thread_checker_.CalledOnValidThread()); | 138 DCHECK(io_thread_checker_.CalledOnValidThread()); |
162 browser_connection_ = nullptr; | 139 has_browser_connection_ = false; |
163 } | 140 } |
164 | 141 |
165 ///////////////////////////////////////////////////////////////////////////// | 142 ///////////////////////////////////////////////////////////////////////////// |
166 // shell::Service implementation | 143 // shell::Service implementation |
167 | 144 |
168 void OnStart(const shell::Identity& identity) override { | 145 void OnStart(const shell::Identity& identity) override { |
169 DCHECK(io_thread_checker_.CalledOnValidThread()); | 146 DCHECK(io_thread_checker_.CalledOnValidThread()); |
170 DCHECK(!initialize_handler_.is_null()); | 147 DCHECK(!initialize_handler_.is_null()); |
171 | 148 |
172 InitializeCallback handler = base::ResetAndReturn(&initialize_handler_); | 149 InitializeCallback handler = base::ResetAndReturn(&initialize_handler_); |
173 callback_task_runner_->PostTask(FROM_HERE, base::Bind(handler, identity)); | 150 callback_task_runner_->PostTask(FROM_HERE, base::Bind(handler, identity)); |
174 } | 151 } |
175 | 152 |
176 bool OnConnect(shell::Connection* connection) override { | 153 bool OnConnect(const shell::Identity& remote_identity, |
| 154 shell::InterfaceRegistry* registry) override { |
177 DCHECK(io_thread_checker_.CalledOnValidThread()); | 155 DCHECK(io_thread_checker_.CalledOnValidThread()); |
178 std::string remote_app = connection->GetRemoteIdentity().name(); | 156 std::string remote_app = remote_identity.name(); |
179 if (remote_app == "mojo:shell") { | 157 if (remote_app == "mojo:shell") { |
180 // Only expose the SCF interface to the shell. | 158 // Only expose the SCF interface to the shell. |
181 connection->AddInterface<shell::mojom::ServiceFactory>(this); | 159 registry->AddInterface<shell::mojom::ServiceFactory>(this); |
182 return true; | 160 return true; |
183 } | 161 } |
184 | 162 |
185 bool accept = false; | 163 bool accept = false; |
186 for (auto& filter : connection_filters_) { | 164 for (auto& filter : connection_filters_) { |
187 accept = accept || | 165 accept = accept || |
188 filter->OnConnect(connection, service_context_->connector()); | 166 filter->OnConnect(remote_identity, registry, |
| 167 service_context_->connector()); |
189 } | 168 } |
190 | 169 |
191 // Capture the browser connection if possible. | 170 if (remote_identity.name() == "exe:content_browser" && |
192 if (remote_app == "exe:content_browser" && !browser_connection_) { | 171 !has_browser_connection_) { |
193 browser_connection_ = connection; | 172 has_browser_connection_ = true; |
194 connection->GetInterfaceRegistry()->set_default_binder( | 173 registry->set_default_binder(default_browser_binder_); |
195 default_browser_binder_); | 174 registry->SetConnectionLostClosure( |
196 connection->SetConnectionLostClosure( | |
197 base::Bind(&IOThreadContext::OnBrowserConnectionLost, this)); | 175 base::Bind(&IOThreadContext::OnBrowserConnectionLost, this)); |
198 shell::InterfaceProvider* remote_interfaces = | |
199 connection->GetRemoteInterfaces(); | |
200 | |
201 // Flush any pending outgoing interface requests. | |
202 while (!pending_remote_interface_requests_.empty()) { | |
203 auto& request = pending_remote_interface_requests_.front(); | |
204 remote_interfaces->GetInterface( | |
205 request.first, std::move(request.second)); | |
206 pending_remote_interface_requests_.pop(); | |
207 } | |
208 return true; | 176 return true; |
209 } | 177 } |
210 | 178 |
211 // If no filters were interested, reject the connection. | 179 // If no filters were interested, reject the connection. |
212 return accept; | 180 return accept; |
213 } | 181 } |
214 | 182 |
215 bool OnStop() override { | 183 bool OnStop() override { |
216 callback_task_runner_->PostTask(FROM_HERE, stop_callback_); | 184 callback_task_runner_->PostTask(FROM_HERE, stop_callback_); |
217 return true; | 185 return true; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 | 230 |
263 // Callback to run once Service::OnStart is invoked. | 231 // Callback to run once Service::OnStart is invoked. |
264 InitializeCallback initialize_handler_; | 232 InitializeCallback initialize_handler_; |
265 | 233 |
266 // Callback to run when a new Service request is received. | 234 // Callback to run when a new Service request is received. |
267 ServiceFactoryCallback create_service_callback_; | 235 ServiceFactoryCallback create_service_callback_; |
268 | 236 |
269 // Callback to run if the service is stopped by the service manager. | 237 // Callback to run if the service is stopped by the service manager. |
270 base::Closure stop_callback_; | 238 base::Closure stop_callback_; |
271 | 239 |
272 // The incoming Connection from the browser process. This is captured the | 240 // Called once a connection has been received from the browser process & the |
273 // first time the browser connects to this Service and persists until shutdown | 241 // default binder (below) has been set up. |
274 // or a connection error is detected. This connection is used to fulfill | 242 bool has_browser_connection_ = false; |
275 // remote interface requests from legacy code which does not use | |
276 // shell::Connector. | |
277 // | |
278 // TODO(rockot): Remove this once all child-to-browser interface connections | |
279 // are made via a Connector rather than directly through an InterfaceProvider | |
280 // and all interfaces exposed to the browser are exposed via a | |
281 // ConnectionFilter. | |
282 shell::Connection* browser_connection_ = nullptr; | |
283 | |
284 // A queue of remote interface requests destined for the browser, which will | |
285 // remain pending until an incoming connection is accepted from the browser. | |
286 // | |
287 // TODO(rockot): Remove this once all child-to-browser interface connections | |
288 // are made via a Connector rather than directly through an InterfaceProvider. | |
289 std::queue<std::pair<mojo::String, mojo::ScopedMessagePipeHandle>> | |
290 pending_remote_interface_requests_; | |
291 | 243 |
292 // Default binder callback used for the browser connection's | 244 // Default binder callback used for the browser connection's |
293 // InterfaceRegistry. | 245 // InterfaceRegistry. |
294 // | 246 // |
295 // TODO(rockot): Remove this once all interfaces exposed to the browser are | 247 // TODO(rockot): Remove this once all interfaces exposed to the browser are |
296 // exposed via a ConnectionFilter. | 248 // exposed via a ConnectionFilter. |
297 shell::InterfaceRegistry::Binder default_browser_binder_; | 249 shell::InterfaceRegistry::Binder default_browser_binder_; |
298 | 250 |
299 std::unique_ptr<shell::ServiceContext> service_context_; | 251 std::unique_ptr<shell::ServiceContext> service_context_; |
300 mojo::BindingSet<shell::mojom::ServiceFactory> factory_bindings_; | 252 mojo::BindingSet<shell::mojom::ServiceFactory> factory_bindings_; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 | 350 |
399 void MojoShellConnectionImpl::SetupInterfaceRequestProxies( | 351 void MojoShellConnectionImpl::SetupInterfaceRequestProxies( |
400 shell::InterfaceRegistry* registry, | 352 shell::InterfaceRegistry* registry, |
401 shell::InterfaceProvider* provider) { | 353 shell::InterfaceProvider* provider) { |
402 // It's safe to bind |registry| as a raw pointer because the caller must | 354 // It's safe to bind |registry| as a raw pointer because the caller must |
403 // guarantee that it outlives |this|, and |this| is bound as a weak ptr here. | 355 // guarantee that it outlives |this|, and |this| is bound as a weak ptr here. |
404 context_->SetDefaultBinderForBrowserConnection( | 356 context_->SetDefaultBinderForBrowserConnection( |
405 base::Bind(&MojoShellConnectionImpl::GetInterface, | 357 base::Bind(&MojoShellConnectionImpl::GetInterface, |
406 weak_factory_.GetWeakPtr(), registry)); | 358 weak_factory_.GetWeakPtr(), registry)); |
407 | 359 |
408 if (!provider) | 360 // TODO(beng): remove provider parameter. |
409 return; | |
410 | |
411 // Forward all remote interface requests on |provider| to our IO-thread | |
412 // context. This will ensure they're forwarded to the provider on the | |
413 // incoming browser connection. | |
414 provider->Forward(base::Bind(&IOThreadContext::GetRemoteInterface, | |
415 context_)); | |
416 } | 361 } |
417 | 362 |
418 void MojoShellConnectionImpl::AddConnectionFilter( | 363 void MojoShellConnectionImpl::AddConnectionFilter( |
419 std::unique_ptr<ConnectionFilter> filter) { | 364 std::unique_ptr<ConnectionFilter> filter) { |
420 context_->AddConnectionFilter(std::move(filter)); | 365 context_->AddConnectionFilter(std::move(filter)); |
421 } | 366 } |
422 | 367 |
423 std::unique_ptr<ConnectionFilter> | 368 std::unique_ptr<ConnectionFilter> |
424 MojoShellConnectionImpl::RemoveConnectionFilter(ConnectionFilter* filter) { | 369 MojoShellConnectionImpl::RemoveConnectionFilter(ConnectionFilter* filter) { |
425 return context_->RemoveConnectionFilter(filter); | 370 return context_->RemoveConnectionFilter(filter); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 } | 410 } |
466 | 411 |
467 void MojoShellConnectionImpl::GetInterface( | 412 void MojoShellConnectionImpl::GetInterface( |
468 shell::mojom::InterfaceProvider* provider, | 413 shell::mojom::InterfaceProvider* provider, |
469 const mojo::String& interface_name, | 414 const mojo::String& interface_name, |
470 mojo::ScopedMessagePipeHandle request_handle) { | 415 mojo::ScopedMessagePipeHandle request_handle) { |
471 provider->GetInterface(interface_name, std::move(request_handle)); | 416 provider->GetInterface(interface_name, std::move(request_handle)); |
472 } | 417 } |
473 | 418 |
474 } // namespace content | 419 } // namespace content |
OLD | NEW |