OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "mojo/application_manager/application_manager.h" | 5 #include "mojo/application_manager/application_manager.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 ApplicationManager* const manager_; | 112 ApplicationManager* const manager_; |
113 const GURL url_; | 113 const GURL url_; |
114 | 114 |
115 DISALLOW_COPY_AND_ASSIGN(ShellImpl); | 115 DISALLOW_COPY_AND_ASSIGN(ShellImpl); |
116 }; | 116 }; |
117 | 117 |
118 struct ApplicationManager::ContentHandlerConnection { | 118 struct ApplicationManager::ContentHandlerConnection { |
119 ContentHandlerConnection(ApplicationManager* manager, | 119 ContentHandlerConnection(ApplicationManager* manager, |
120 const GURL& content_handler_url) { | 120 const GURL& content_handler_url) { |
121 ServiceProviderPtr service_provider; | 121 ServiceProviderPtr service_provider; |
122 BindToProxy(&service_provider_impl, &service_provider); | 122 WeakBindToProxy(&service_provider_impl, &service_provider); |
Aaron Boodman
2014/10/31 16:40:46
Alternately, what if we just don't hold onto the S
qsr
2014/10/31 17:22:32
But then you can imagine the service provider surv
Aaron Boodman
2014/10/31 18:43:18
What is the problem with that? If the app somehow
| |
123 manager->ConnectToApplication( | 123 manager->ConnectToApplication( |
124 content_handler_url, GURL(), service_provider.Pass()); | 124 content_handler_url, GURL(), service_provider.Pass()); |
125 mojo::ConnectToService(service_provider_impl.client(), &content_handler); | 125 mojo::ConnectToService(service_provider_impl.client(), &content_handler); |
126 } | 126 } |
127 | 127 |
128 StubServiceProvider service_provider_impl; | 128 StubServiceProvider service_provider_impl; |
129 ContentHandlerPtr content_handler; | 129 ContentHandlerPtr content_handler; |
130 }; | 130 }; |
131 | 131 |
132 // static | 132 // static |
(...skipping 21 matching lines...) Expand all Loading... | |
154 | 154 |
155 ApplicationManager::~ApplicationManager() { | 155 ApplicationManager::~ApplicationManager() { |
156 STLDeleteValues(&url_to_content_handler_); | 156 STLDeleteValues(&url_to_content_handler_); |
157 TerminateShellConnections(); | 157 TerminateShellConnections(); |
158 STLDeleteValues(&url_to_loader_); | 158 STLDeleteValues(&url_to_loader_); |
159 STLDeleteValues(&scheme_to_loader_); | 159 STLDeleteValues(&scheme_to_loader_); |
160 } | 160 } |
161 | 161 |
162 void ApplicationManager::TerminateShellConnections() { | 162 void ApplicationManager::TerminateShellConnections() { |
163 STLDeleteValues(&url_to_shell_impl_); | 163 STLDeleteValues(&url_to_shell_impl_); |
164 STLDeleteElements(&content_shell_impls_); | |
164 } | 165 } |
165 | 166 |
166 // static | 167 // static |
167 ApplicationManager* ApplicationManager::GetInstance() { | 168 ApplicationManager* ApplicationManager::GetInstance() { |
168 static base::LazyInstance<ApplicationManager> instance = | 169 static base::LazyInstance<ApplicationManager> instance = |
169 LAZY_INSTANCE_INITIALIZER; | 170 LAZY_INSTANCE_INITIALIZER; |
170 has_created_instance = true; | 171 has_created_instance = true; |
171 return &instance.Get(); | 172 return &instance.Get(); |
172 } | 173 } |
173 | 174 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 ScopedMessagePipeHandle* shell_handle) { | 218 ScopedMessagePipeHandle* shell_handle) { |
218 ShellImpl* shell_impl = NULL; | 219 ShellImpl* shell_impl = NULL; |
219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); | 220 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); |
220 if (iter != url_to_shell_impl_.end()) { | 221 if (iter != url_to_shell_impl_.end()) { |
221 // This can happen because services are loaded asynchronously. So if we get | 222 // This can happen because services are loaded asynchronously. So if we get |
222 // two requests for the same service close to each other, we might get here | 223 // two requests for the same service close to each other, we might get here |
223 // and find that we already have it. | 224 // and find that we already have it. |
224 shell_impl = iter->second; | 225 shell_impl = iter->second; |
225 } else { | 226 } else { |
226 MessagePipe pipe; | 227 MessagePipe pipe; |
227 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | |
228 Array<String> args; | |
229 if (args_it != url_to_args_.end()) | |
230 args = Array<String>::From(args_it->second); | |
231 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); | 228 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); |
232 url_to_shell_impl_[url] = shell_impl; | 229 url_to_shell_impl_[url] = shell_impl; |
233 *shell_handle = pipe.handle0.Pass(); | 230 *shell_handle = pipe.handle0.Pass(); |
234 shell_impl->client()->Initialize(args.Pass()); | 231 shell_impl->client()->Initialize(GetArgsForURL(url)); |
235 } | 232 } |
236 | 233 |
237 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); | 234 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); |
238 } | 235 } |
239 | 236 |
240 void ApplicationManager::LoadWithContentHandler( | 237 void ApplicationManager::LoadWithContentHandler( |
241 const GURL& content_url, | 238 const GURL& content_url, |
242 const GURL& requestor_url, | 239 const GURL& requestor_url, |
243 const GURL& content_handler_url, | 240 const GURL& content_handler_url, |
244 URLResponsePtr url_response, | 241 URLResponsePtr url_response, |
245 ServiceProviderPtr service_provider) { | 242 ServiceProviderPtr service_provider) { |
246 ContentHandlerConnection* connection = NULL; | 243 ContentHandlerConnection* connection = NULL; |
247 URLToContentHandlerMap::iterator iter = | 244 URLToContentHandlerMap::iterator iter = |
248 url_to_content_handler_.find(content_handler_url); | 245 url_to_content_handler_.find(content_handler_url); |
249 if (iter != url_to_content_handler_.end()) { | 246 if (iter != url_to_content_handler_.end()) { |
250 connection = iter->second; | 247 connection = iter->second; |
251 } else { | 248 } else { |
252 connection = new ContentHandlerConnection(this, content_handler_url); | 249 connection = new ContentHandlerConnection(this, content_handler_url); |
253 url_to_content_handler_[content_handler_url] = connection; | 250 url_to_content_handler_[content_handler_url] = connection; |
254 } | 251 } |
255 | 252 |
256 InterfaceRequest<ServiceProvider> spir; | 253 ShellPtr shell_proxy; |
257 spir.Bind(service_provider.PassMessagePipe()); | 254 ShellImpl* shell_impl = |
258 connection->content_handler->OnConnect( | 255 WeakBindToProxy(new ShellImpl(this, content_url), &shell_proxy); |
259 requestor_url.spec(), url_response.Pass(), spir.Pass()); | 256 content_shell_impls_.insert(shell_impl); |
257 shell_impl->client()->Initialize(GetArgsForURL(content_url)); | |
258 | |
259 connection->content_handler->StartApplication(shell_proxy.Pass(), | |
260 url_response.Pass()); | |
261 ConnectToClient( | |
262 shell_impl, content_url, requestor_url, service_provider.Pass()); | |
260 } | 263 } |
261 | 264 |
262 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 265 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
263 const GURL& url) { | 266 const GURL& url) { |
264 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 267 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
265 if (it != url_to_loader_.end()) | 268 if (it != url_to_loader_.end()) |
266 delete it->second; | 269 delete it->second; |
267 url_to_loader_[url] = loader.release(); | 270 url_to_loader_[url] = loader.release(); |
268 } | 271 } |
269 | 272 |
(...skipping 21 matching lines...) Expand all Loading... | |
291 return url_it->second; | 294 return url_it->second; |
292 SchemeToLoaderMap::const_iterator scheme_it = | 295 SchemeToLoaderMap::const_iterator scheme_it = |
293 scheme_to_loader_.find(url.scheme()); | 296 scheme_to_loader_.find(url.scheme()); |
294 if (scheme_it != scheme_to_loader_.end()) | 297 if (scheme_it != scheme_to_loader_.end()) |
295 return scheme_it->second; | 298 return scheme_it->second; |
296 return default_loader_.get(); | 299 return default_loader_.get(); |
297 } | 300 } |
298 | 301 |
299 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { | 302 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { |
300 // Called from ~ShellImpl, so we do not need to call Destroy here. | 303 // Called from ~ShellImpl, so we do not need to call Destroy here. |
304 auto content_shell_it = content_shell_impls_.find(shell_impl); | |
305 if (content_shell_it != content_shell_impls_.end()) { | |
306 delete (*content_shell_it); | |
307 content_shell_impls_.erase(content_shell_it); | |
308 return; | |
309 } | |
301 const GURL url = shell_impl->url(); | 310 const GURL url = shell_impl->url(); |
311 // If the shell is a connection to a content handler, remove the mapping/ | |
312 URLToContentHandlerMap::iterator content_handler_it = | |
Aaron Boodman
2014/10/31 16:40:46
auto
qsr
2014/10/31 17:22:32
Done.
| |
313 url_to_content_handler_.find(url); | |
Aaron Boodman
2014/10/31 16:40:46
Is it possible for both the above and this to be t
qsr
2014/10/31 17:22:32
What about instead cleaning up the content handler
| |
314 if (content_handler_it != url_to_content_handler_.end()) { | |
315 delete content_handler_it->second; | |
316 url_to_content_handler_.erase(content_handler_it); | |
317 } | |
318 // Remove the shell. | |
302 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); | 319 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); |
303 DCHECK(it != url_to_shell_impl_.end()); | 320 DCHECK(it != url_to_shell_impl_.end()); |
304 delete it->second; | 321 delete it->second; |
305 url_to_shell_impl_.erase(it); | 322 url_to_shell_impl_.erase(it); |
306 ApplicationLoader* loader = GetLoaderForURL(url); | 323 ApplicationLoader* loader = GetLoaderForURL(url); |
307 if (loader) | 324 if (loader) |
308 loader->OnApplicationError(this, url); | 325 loader->OnApplicationError(this, url); |
309 if (delegate_) | 326 if (delegate_) |
310 delegate_->OnApplicationError(url); | 327 delegate_->OnApplicationError(url); |
311 } | 328 } |
312 | 329 |
313 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 330 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
314 const GURL& application_url, | 331 const GURL& application_url, |
315 const std::string& interface_name) { | 332 const std::string& interface_name) { |
316 StubServiceProvider* stub_sp = new StubServiceProvider; | 333 StubServiceProvider* stub_sp = new StubServiceProvider; |
317 ServiceProviderPtr spp; | 334 ServiceProviderPtr spp; |
318 BindToProxy(stub_sp, &spp); | 335 BindToProxy(stub_sp, &spp); |
319 ConnectToApplication(application_url, GURL(), spp.Pass()); | 336 ConnectToApplication(application_url, GURL(), spp.Pass()); |
320 MessagePipe pipe; | 337 MessagePipe pipe; |
321 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, | 338 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, |
322 pipe.handle1.Pass()); | 339 pipe.handle1.Pass()); |
323 return pipe.handle0.Pass(); | 340 return pipe.handle0.Pass(); |
324 } | 341 } |
342 | |
343 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { | |
344 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | |
345 if (args_it != url_to_args_.end()) | |
346 return Array<String>::From(args_it->second); | |
347 return Array<String>(); | |
348 } | |
325 } // namespace mojo | 349 } // namespace mojo |
OLD | NEW |