Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: content/common/mojo/mojo_shell_connection_impl.cc

Issue 2111353002: Move content's shell connections to the IO thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
8 #include <utility>
9 #include <vector>
10
7 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
8 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/macros.h"
9 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
10 #include "base/threading/thread_local.h" 16 #include "base/threading/thread_checker.h"
11 #include "content/common/mojo/embedded_application_runner.h" 17 #include "content/common/mojo/embedded_application_runner.h"
18 #include "content/public/common/connection_filter.h"
19 #include "mojo/public/cpp/bindings/binding_set.h"
20 #include "mojo/public/cpp/system/message_pipe.h"
12 #include "services/shell/public/cpp/service.h" 21 #include "services/shell/public/cpp/service.h"
13 #include "services/shell/public/cpp/shell_connection.h" 22 #include "services/shell/public/cpp/shell_connection.h"
23 #include "services/shell/public/interfaces/service_factory.mojom.h"
14 #include "services/shell/runner/common/client_util.h" 24 #include "services/shell/runner/common/client_util.h"
15 25
16 namespace content { 26 namespace content {
17 namespace { 27 namespace {
18 28
19 using MojoShellConnectionPtr = 29 base::LazyInstance<std::unique_ptr<MojoShellConnection>>::Leaky
20 base::ThreadLocalPointer<MojoShellConnection>; 30 g_connection_for_process = LAZY_INSTANCE_INITIALIZER;
21
22 // Env is thread local so that aura may be used on multiple threads.
23 base::LazyInstance<MojoShellConnectionPtr>::Leaky lazy_tls_ptr =
24 LAZY_INSTANCE_INITIALIZER;
25 31
26 MojoShellConnection::Factory* mojo_shell_connection_factory = nullptr; 32 MojoShellConnection::Factory* mojo_shell_connection_factory = nullptr;
27 33
28 } // namespace 34 } // namespace
29 35
36 // A ref-counted object which owns the IO thread state of a
37 // MojoShellConnectionImpl. This includes Service and ServiceFactory
38 // bindings.
39 class MojoShellConnectionImpl::IOThreadContext
40 : public base::RefCountedThreadSafe<IOThreadContext>,
41 public shell::Service,
42 public shell::InterfaceFactory<shell::mojom::ServiceFactory>,
43 public shell::mojom::ServiceFactory {
44 public:
45 using InitializeCallback = base::Callback<void(const shell::Identity&)>;
46 using ServiceFactoryCallback =
47 base::Callback<void(shell::mojom::ServiceRequest, const mojo::String&)>;
48
49 IOThreadContext(shell::mojom::ServiceRequest service_request,
50 scoped_refptr<base::SequencedTaskRunner> io_task_runner,
51 std::unique_ptr<shell::Connector> io_thread_connector,
52 shell::mojom::ConnectorRequest connector_request)
53 : pending_service_request_(std::move(service_request)),
54 io_task_runner_(io_task_runner),
55 io_thread_connector_(std::move(io_thread_connector)),
56 pending_connector_request_(std::move(connector_request)) {
57 // This will be reattached by any of the IO thread functions on first call.
58 io_thread_checker_.DetachFromThread();
59 }
60
61 // Safe to call from any thread.
62 void Start(const InitializeCallback& initialize_callback,
63 const ServiceFactoryCallback& create_service) {
64 DCHECK(!started_);
65
66 started_ = true;
67 initialize_handler_ = base::Bind(
68 &IOThreadContext::CallInitializeOnTaskRunner,
69 base::ThreadTaskRunnerHandle::Get(), initialize_callback);
70
71 create_service_callback_ = base::Bind(
72 &IOThreadContext::CallServiceFactoryOnTaskRunner,
73 base::ThreadTaskRunnerHandle::Get(), create_service);
74
75 io_task_runner_->PostTask(
76 FROM_HERE, base::Bind(&IOThreadContext::StartOnIOThread, this));
77 }
78
79 // Safe to call from whichever thread called Start() (or may have called
80 // Start()). Must be called before IO thread shutdown.
81 void ShutDown() {
82 if (!started_)
83 return;
84
85 bool posted = io_task_runner_->PostTask(
86 FROM_HERE, base::Bind(&IOThreadContext::ShutDownOnIOThread, this));
87 DCHECK(posted);
88 }
89
90 // Safe to call any time before Start() is called.
91 void AddConnectionFilter(std::unique_ptr<ConnectionFilter> filter) {
92 DCHECK(!started_);
93 connection_filters_.emplace_back(std::move(filter));
94 }
95
96 // Safe to call any time before Start() is called.
97 void SetDefaultBinderForBrowserConnection(
98 const shell::InterfaceRegistry::Binder& binder) {
99 DCHECK(!started_);
100 default_browser_binder_ = base::Bind(
101 &IOThreadContext::CallBinderOnTaskRunner,
102 base::ThreadTaskRunnerHandle::Get(), binder);
103 }
104
105 // Safe to call any time after Start() is called.
106 void GetRemoteInterface(const mojo::String& interface_name,
107 mojo::ScopedMessagePipeHandle request_handle) {
108 DCHECK(started_);
109 io_task_runner_->PostTask(
110 FROM_HERE,
111 base::Bind(&IOThreadContext::GetRemoteInterfaceOnIOThread, this,
112 interface_name, base::Passed(&request_handle)));
113 }
114
115 private:
116 friend class base::RefCountedThreadSafe<IOThreadContext>;
117
118 ~IOThreadContext() override {}
119
120 void StartOnIOThread() {
121 // Should bind |io_thread_checker_| to the context's thread.
122 DCHECK(io_thread_checker_.CalledOnValidThread());
123 shell_connection_.reset(new shell::ShellConnection(
124 this, std::move(pending_service_request_),
125 std::move(io_thread_connector_),
126 std::move(pending_connector_request_)));
127 }
128
129 void ShutDownOnIOThread() {
130 DCHECK(io_thread_checker_.CalledOnValidThread());
131 shell_connection_.reset();
132 factory_bindings_.CloseAllBindings();
133 }
134
135 void GetRemoteInterfaceOnIOThread(
136 const mojo::String& interface_name,
137 mojo::ScopedMessagePipeHandle request_handle) {
138 DCHECK(io_thread_checker_.CalledOnValidThread());
139 if (browser_connection_) {
140 browser_connection_->GetRemoteInterfaces()->GetInterface(
141 interface_name, std::move(request_handle));
142 } else {
143 pending_remote_interface_requests_.emplace(interface_name,
144 std::move(request_handle));
145 }
146 }
147
148 void OnBrowserConnectionLost() {
149 DCHECK(io_thread_checker_.CalledOnValidThread());
150 browser_connection_ = nullptr;
151 }
152
153 /////////////////////////////////////////////////////////////////////////////
154 // shell::Service implementation
155
156 void OnStart(shell::Connector* connector,
157 const shell::Identity& identity,
158 uint32_t id) override {
159 DCHECK(io_thread_checker_.CalledOnValidThread());
160 DCHECK(!initialize_handler_.is_null());
161 base::ResetAndReturn(&initialize_handler_).Run(identity);
162 }
163
164 bool OnConnect(shell::Connection* connection) override {
165 DCHECK(io_thread_checker_.CalledOnValidThread());
166 std::string remote_app = connection->GetRemoteIdentity().name();
167 if (remote_app == "mojo:shell") {
168 // Only expose the SCF interface to the shell.
169 connection->AddInterface<shell::mojom::ServiceFactory>(this);
170 return true;
171 }
172
173 bool accept = false;
174 for (auto& filter : connection_filters_) {
175 accept = accept ||
176 filter->AcceptConnection(connection, shell_connection_->connector());
177 }
178
179 // Capture the browser connection if possible.
180 if (remote_app == "exe:content_browser" && !browser_connection_) {
181 browser_connection_ = connection;
182 connection->GetInterfaceRegistry()->set_default_binder(
183 default_browser_binder_);
184 connection->SetConnectionLostClosure(
185 base::Bind(&IOThreadContext::OnBrowserConnectionLost, this));
186 shell::InterfaceProvider* remote_interfaces =
187 connection->GetRemoteInterfaces();
188
189 // Flush any pending outgoing interface requests.
190 while (!pending_remote_interface_requests_.empty()) {
191 auto& request = pending_remote_interface_requests_.front();
192 remote_interfaces->GetInterface(
193 request.first, std::move(request.second));
194 pending_remote_interface_requests_.pop();
195 }
196 return true;
197 }
198
199 // If no filters were interested, reject the connection.
200 return accept;
201 }
202
203 /////////////////////////////////////////////////////////////////////////////
204 // shell::InterfaceFactory<shell::mojom::ServiceFactory> implementation
205
206 void Create(shell::Connection* connection,
207 shell::mojom::ServiceFactoryRequest request) override {
208 DCHECK(io_thread_checker_.CalledOnValidThread());
209 factory_bindings_.AddBinding(this, std::move(request));
210 }
211
212 /////////////////////////////////////////////////////////////////////////////
213 // shell::mojom::ServiceFactory implementation
214
215 void CreateService(shell::mojom::ServiceRequest request,
216 const mojo::String& name) override {
217 DCHECK(io_thread_checker_.CalledOnValidThread());
218 create_service_callback_.Run(std::move(request), name);
219 }
220
221 static void CallInitializeOnTaskRunner(
222 scoped_refptr<base::SequencedTaskRunner> task_runner,
223 const InitializeCallback& callback,
224 const shell::Identity& identity) {
225 task_runner->PostTask(FROM_HERE, base::Bind(callback, identity));
226 }
227
228 static void CallServiceFactoryOnTaskRunner(
229 scoped_refptr<base::SequencedTaskRunner> task_runner,
230 const ServiceFactoryCallback& callback,
231 shell::mojom::ServiceRequest request,
232 const mojo::String& name) {
233 task_runner->PostTask(
234 FROM_HERE, base::Bind(callback, base::Passed(&request), name));
235 }
236
237 static void CallBinderOnTaskRunner(
238 scoped_refptr<base::SequencedTaskRunner> task_runner,
239 const shell::InterfaceRegistry::Binder& binder,
240 const mojo::String& interface_name,
241 mojo::ScopedMessagePipeHandle request_handle) {
242 task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name,
243 base::Passed(&request_handle)));
244 }
245
246 base::ThreadChecker io_thread_checker_;
247 bool started_ = false;
248
249 // Temporary state established on construction and consumed on the IO thread
250 // once the connection is started.
251 shell::mojom::ServiceRequest pending_service_request_;
252 scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
253 std::unique_ptr<shell::Connector> io_thread_connector_;
254 shell::mojom::ConnectorRequest pending_connector_request_;
255
256 // Callback to run once Service::OnStart is invoked.
257 InitializeCallback initialize_handler_;
258
259 // Callback to run when a new Service request is received.
260 ServiceFactoryCallback create_service_callback_;
261
262 // The incoming Connection from the browser process. This is captured the
263 // first time the browser connects to this Service and persists until shutdown
264 // or a connection error is detected. This connection is used to fulfill
265 // remote interface requests from legacy code which does not use
266 // shell::Connector.
267 //
268 // TODO(rockot): Remove this once all child-to-browser interface connections
269 // are made via a Connector rather than directly through an InterfaceProvider
270 // and all interfaces exposed to the browser are exposed via a
271 // ConnectionFilter.
272 shell::Connection* browser_connection_ = nullptr;
273
274 // A queue of remote interface requests destined for the browser, which will
275 // remain pending until an incoming connection is accepted from the browser.
276 //
277 // TODO(rockot): Remove this once all child-to-browser interface connections
278 // are made via a Connector rather than directly through an InterfaceProvider.
279 std::queue<std::pair<mojo::String, mojo::ScopedMessagePipeHandle>>
280 pending_remote_interface_requests_;
281
282 // Default binder callback used for the browser connection's
283 // InterfaceRegistry.
284 //
285 // TODO(rockot): Remove this once all interfaces exposed to the browser are
286 // exposed via a ConnectionFilter.
287 shell::InterfaceRegistry::Binder default_browser_binder_;
288
289 std::unique_ptr<shell::ShellConnection> shell_connection_;
290 mojo::BindingSet<shell::mojom::ServiceFactory> factory_bindings_;
291 std::vector<std::unique_ptr<ConnectionFilter>> connection_filters_;
292
293 DISALLOW_COPY_AND_ASSIGN(IOThreadContext);
294 };
295
30 //////////////////////////////////////////////////////////////////////////////// 296 ////////////////////////////////////////////////////////////////////////////////
31 // MojoShellConnection, public: 297 // MojoShellConnection, public:
32 298
33 // static 299 // static
34 void MojoShellConnection::SetForProcess( 300 void MojoShellConnection::SetForProcess(
35 std::unique_ptr<MojoShellConnection> connection) { 301 std::unique_ptr<MojoShellConnection> connection) {
36 DCHECK(!lazy_tls_ptr.Pointer()->Get()); 302 DCHECK(!g_connection_for_process.Get());
37 lazy_tls_ptr.Pointer()->Set(connection.release()); 303 g_connection_for_process.Get() = std::move(connection);
38 } 304 }
39 305
40 // static 306 // static
41 MojoShellConnection* MojoShellConnection::GetForProcess() { 307 MojoShellConnection* MojoShellConnection::GetForProcess() {
42 return lazy_tls_ptr.Pointer()->Get(); 308 return g_connection_for_process.Get().get();
43 } 309 }
44 310
45 // static 311 // static
46 void MojoShellConnection::DestroyForProcess() { 312 void MojoShellConnection::DestroyForProcess() {
47 // This joins the shell controller thread. 313 // This joins the shell controller thread.
48 delete GetForProcess(); 314 g_connection_for_process.Get().reset();
49 lazy_tls_ptr.Pointer()->Set(nullptr);
50 } 315 }
51 316
52 // static 317 // static
53 void MojoShellConnection::SetFactoryForTest(Factory* factory) { 318 void MojoShellConnection::SetFactoryForTest(Factory* factory) {
54 DCHECK(!lazy_tls_ptr.Pointer()->Get()); 319 DCHECK(!g_connection_for_process.Get());
55 mojo_shell_connection_factory = factory; 320 mojo_shell_connection_factory = factory;
56 } 321 }
57 322
58 // static 323 // static
59 std::unique_ptr<MojoShellConnection> MojoShellConnection::Create( 324 std::unique_ptr<MojoShellConnection> MojoShellConnection::Create(
60 shell::mojom::ServiceRequest request) { 325 shell::mojom::ServiceRequest request,
326 scoped_refptr<base::SequencedTaskRunner> io_task_runner) {
61 if (mojo_shell_connection_factory) 327 if (mojo_shell_connection_factory)
62 return mojo_shell_connection_factory->Run(); 328 return mojo_shell_connection_factory->Run();
63 return base::WrapUnique(new MojoShellConnectionImpl(std::move(request))); 329 return base::MakeUnique<MojoShellConnectionImpl>(
330 std::move(request), io_task_runner);
64 } 331 }
65 332
66 MojoShellConnection::~MojoShellConnection() {} 333 MojoShellConnection::~MojoShellConnection() {}
67 334
68 //////////////////////////////////////////////////////////////////////////////// 335 ////////////////////////////////////////////////////////////////////////////////
69 // MojoShellConnectionImpl, public: 336 // MojoShellConnectionImpl, public:
70 337
71 MojoShellConnectionImpl::MojoShellConnectionImpl( 338 MojoShellConnectionImpl::MojoShellConnectionImpl(
72 shell::mojom::ServiceRequest request) 339 shell::mojom::ServiceRequest request,
73 : shell_connection_(new shell::ShellConnection(this, std::move(request))) {} 340 scoped_refptr<base::SequencedTaskRunner> io_task_runner)
341 : weak_factory_(this) {
342 shell::mojom::ConnectorRequest connector_request;
343 connector_ = shell::Connector::Create(&connector_request);
74 344
75 MojoShellConnectionImpl::~MojoShellConnectionImpl() {} 345 std::unique_ptr<shell::Connector> io_thread_connector = connector_->Clone();
76 346 context_ = new IOThreadContext(
77 //////////////////////////////////////////////////////////////////////////////// 347 std::move(request), io_task_runner, std::move(io_thread_connector),
78 // MojoShellConnectionImpl, shell::Service implementation: 348 std::move(connector_request));
79
80 void MojoShellConnectionImpl::OnStart(shell::Connector* connector,
81 const shell::Identity& identity,
82 uint32_t id) {
83 for (auto& client : embedded_services_)
84 client->OnStart(connector, identity, id);
85 } 349 }
86 350
87 bool MojoShellConnectionImpl::OnConnect(shell::Connection* connection) { 351 MojoShellConnectionImpl::~MojoShellConnectionImpl() {
88 std::string remote_app = connection->GetRemoteIdentity().name(); 352 context_->ShutDown();
89 if (remote_app == "mojo:shell") {
90 // Only expose the SCF interface to the shell.
91 connection->AddInterface<shell::mojom::ServiceFactory>(this);
92 return true;
93 }
94
95 bool accept = false;
96 for (auto& client : embedded_services_)
97 accept |= client->OnConnect(connection);
98
99 // Reject all other connections to this application.
100 return accept;
101 }
102
103 shell::InterfaceRegistry*
104 MojoShellConnectionImpl::GetInterfaceRegistryForConnection() {
105 // TODO(beng): This is really horrible since obviously subject to issues
106 // of ordering, but is no more horrible than this API is in general.
107 shell::InterfaceRegistry* registry = nullptr;
108 for (auto& client : embedded_services_) {
109 registry = client->GetInterfaceRegistryForConnection();
110 if (registry)
111 return registry;
112 }
113 return nullptr;
114 }
115
116 shell::InterfaceProvider*
117 MojoShellConnectionImpl::GetInterfaceProviderForConnection() {
118 // TODO(beng): This is really horrible since obviously subject to issues
119 // of ordering, but is no more horrible than this API is in general.
120 shell::InterfaceProvider* provider = nullptr;
121 for (auto& client : embedded_services_) {
122 provider = client->GetInterfaceProviderForConnection();
123 if (provider)
124 return provider;
125 }
126 return nullptr;
127 }
128
129 ////////////////////////////////////////////////////////////////////////////////
130 // MojoShellConnectionImpl,
131 // shell::InterfaceFactory<shell::mojom::ServiceFactory> implementation:
132
133 void MojoShellConnectionImpl::Create(
134 shell::Connection* connection,
135 shell::mojom::ServiceFactoryRequest request) {
136 factory_bindings_.AddBinding(this, std::move(request));
137 }
138
139 ////////////////////////////////////////////////////////////////////////////////
140 // MojoShellConnectionImpl, shell::mojom::ServiceFactory implementation:
141
142 void MojoShellConnectionImpl::CreateService(
143 shell::mojom::ServiceRequest request,
144 const mojo::String& name) {
145 auto it = request_handlers_.find(name);
146 if (it != request_handlers_.end())
147 it->second.Run(std::move(request));
148 } 353 }
149 354
150 //////////////////////////////////////////////////////////////////////////////// 355 ////////////////////////////////////////////////////////////////////////////////
151 // MojoShellConnectionImpl, MojoShellConnection implementation: 356 // MojoShellConnectionImpl, MojoShellConnection implementation:
152 357
153 shell::ShellConnection* MojoShellConnectionImpl::GetShellConnection() { 358 void MojoShellConnectionImpl::Start() {
154 return shell_connection_.get(); 359 context_->Start(
360 base::Bind(&MojoShellConnectionImpl::OnContextInitialized,
361 weak_factory_.GetWeakPtr()),
362 base::Bind(&MojoShellConnectionImpl::CreateService,
363 weak_factory_.GetWeakPtr()));
364 }
365
366 void MojoShellConnectionImpl::SetInitializeHandler(
367 const base::Closure& handler) {
368 DCHECK(initialize_handler_.is_null());
369 initialize_handler_ = handler;
155 } 370 }
156 371
157 shell::Connector* MojoShellConnectionImpl::GetConnector() { 372 shell::Connector* MojoShellConnectionImpl::GetConnector() {
158 DCHECK(shell_connection_); 373 return connector_.get();
159 return shell_connection_->connector();
160 } 374 }
161 375
162 const shell::Identity& MojoShellConnectionImpl::GetIdentity() const { 376 const shell::Identity& MojoShellConnectionImpl::GetIdentity() const {
163 DCHECK(shell_connection_); 377 return identity_;
164 return shell_connection_->identity();
165 } 378 }
166 379
167 void MojoShellConnectionImpl::SetConnectionLostClosure( 380 void MojoShellConnectionImpl::SetConnectionLostClosure(
168 const base::Closure& closure) { 381 const base::Closure& closure) {
169 shell_connection_->SetConnectionLostClosure(closure); 382 connection_lost_handler_ = closure;
170 } 383 }
171 384
172 void MojoShellConnectionImpl::MergeService( 385 void MojoShellConnectionImpl::SetupInterfaceRequestProxies(
173 std::unique_ptr<shell::Service> service) { 386 shell::InterfaceRegistry* registry,
174 embedded_services_.push_back(service.get()); 387 shell::InterfaceProvider* provider) {
175 owned_services_.push_back(std::move(service)); 388 // It's safe to bind |registry| as a raw pointer because the caller must
389 // guarantee that it outlives |this|, and |this| is bound as a weak ptr here.
390 context_->SetDefaultBinderForBrowserConnection(
391 base::Bind(&MojoShellConnectionImpl::GetInterface,
392 weak_factory_.GetWeakPtr(), registry));
393
394 // Forward all remote interface requests on |provider| to our IO-thread
395 // context. This will ensure they're forwarded to the provider on the
396 // incoming browser connection.
397 provider->Forward(base::Bind(&IOThreadContext::GetRemoteInterface, context_));
176 } 398 }
177 399
178 void MojoShellConnectionImpl::MergeService( 400 void MojoShellConnectionImpl::AddConnectionFilter(
179 shell::Service* service) { 401 std::unique_ptr<ConnectionFilter> filter) {
180 embedded_services_.push_back(service); 402 context_->AddConnectionFilter(std::move(filter));
181 } 403 }
182 404
183 void MojoShellConnectionImpl::AddEmbeddedService( 405 void MojoShellConnectionImpl::AddEmbeddedService(
184 const std::string& name, 406 const std::string& name,
185 const MojoApplicationInfo& info) { 407 const MojoApplicationInfo& info) {
186 std::unique_ptr<EmbeddedApplicationRunner> app( 408 std::unique_ptr<EmbeddedApplicationRunner> app(
187 new EmbeddedApplicationRunner(name, info)); 409 new EmbeddedApplicationRunner(name, info));
188 AddServiceRequestHandler( 410 AddServiceRequestHandler(
189 name, base::Bind(&EmbeddedApplicationRunner::BindServiceRequest, 411 name, base::Bind(&EmbeddedApplicationRunner::BindServiceRequest,
190 base::Unretained(app.get()))); 412 base::Unretained(app.get())));
191 auto result = embedded_apps_.insert(std::make_pair(name, std::move(app))); 413 auto result = embedded_apps_.insert(std::make_pair(name, std::move(app)));
192 DCHECK(result.second); 414 DCHECK(result.second);
193 } 415 }
194 416
195 void MojoShellConnectionImpl::AddServiceRequestHandler( 417 void MojoShellConnectionImpl::AddServiceRequestHandler(
196 const std::string& name, 418 const std::string& name,
197 const ServiceRequestHandler& handler) { 419 const ServiceRequestHandler& handler) {
198 auto result = request_handlers_.insert(std::make_pair(name, handler)); 420 auto result = request_handlers_.insert(std::make_pair(name, handler));
199 DCHECK(result.second); 421 DCHECK(result.second);
200 } 422 }
201 423
424 void MojoShellConnectionImpl::CreateService(
425 shell::mojom::ServiceRequest request,
426 const mojo::String& name) {
427 auto it = request_handlers_.find(name);
428 if (it != request_handlers_.end())
429 it->second.Run(std::move(request));
430 }
431
432 void MojoShellConnectionImpl::OnContextInitialized(
433 const shell::Identity& identity) {
434 identity_ = identity;
435 if (!initialize_handler_.is_null())
436 base::ResetAndReturn(&initialize_handler_).Run();
437 }
438
439 void MojoShellConnectionImpl::OnConnectionLost() {
440 if (!connection_lost_handler_.is_null())
441 connection_lost_handler_.Run();
442 }
443
444 void MojoShellConnectionImpl::GetInterface(
445 shell::mojom::InterfaceProvider* provider,
446 const mojo::String& interface_name,
447 mojo::ScopedMessagePipeHandle request_handle) {
448 provider->GetInterface(interface_name, std::move(request_handle));
449 }
450
202 } // namespace content 451 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698