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> |
| 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 |
OLD | NEW |