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 "shell/application_manager/application_manager.h" | 5 #include "shell/application_manager/application_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
12 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
13 #include "mojo/public/cpp/bindings/binding.h" | 14 #include "mojo/public/cpp/bindings/binding.h" |
14 #include "mojo/services/authenticating_url_loader_interceptor/interfaces/authent
icating_url_loader_interceptor_meta_factory.mojom.h" | 15 #include "mojo/services/authenticating_url_loader_interceptor/interfaces/authent
icating_url_loader_interceptor_meta_factory.mojom.h" |
15 #include "mojo/services/authentication/interfaces/authentication.mojom.h" | 16 #include "mojo/services/authentication/interfaces/authentication.mojom.h" |
16 #include "mojo/services/content_handler/interfaces/content_handler.mojom.h" | 17 #include "mojo/services/content_handler/interfaces/content_handler.mojom.h" |
17 #include "shell/application_manager/fetcher.h" | 18 #include "shell/application_manager/fetcher.h" |
18 #include "shell/application_manager/local_fetcher.h" | 19 #include "shell/application_manager/local_fetcher.h" |
19 #include "shell/application_manager/network_fetcher.h" | 20 #include "shell/application_manager/network_fetcher.h" |
20 #include "shell/application_manager/query_util.h" | 21 #include "shell/application_manager/query_util.h" |
(...skipping 20 matching lines...) Expand all Loading... |
41 return v1; | 42 return v1; |
42 std::vector<std::string> result(v1); | 43 std::vector<std::string> result(v1); |
43 result.insert(result.end(), v1.begin(), v1.end()); | 44 result.insert(result.end(), v1.begin(), v1.end()); |
44 return result; | 45 return result; |
45 } | 46 } |
46 | 47 |
47 } // namespace | 48 } // namespace |
48 | 49 |
49 class ApplicationManager::ContentHandlerConnection { | 50 class ApplicationManager::ContentHandlerConnection { |
50 public: | 51 public: |
51 ContentHandlerConnection(ApplicationManager* manager, | 52 ContentHandlerConnection(ApplicationManager* manager, Identity identity) |
52 const GURL& content_handler_url) | 53 : manager_(manager), identity_(identity) { |
53 : manager_(manager), content_handler_url_(content_handler_url) { | |
54 ServiceProviderPtr services; | 54 ServiceProviderPtr services; |
55 manager->ConnectToApplication(content_handler_url, GURL(), | 55 manager->ConnectToApplication(identity_.url, GURL(), |
56 mojo::GetProxy(&services), nullptr, | 56 mojo::GetProxy(&services), nullptr, |
57 base::Closure()); | 57 base::Closure()); |
58 mojo::MessagePipe pipe; | 58 mojo::MessagePipe pipe; |
59 content_handler_.Bind( | 59 content_handler_.Bind( |
60 mojo::InterfacePtrInfo<mojo::ContentHandler>(pipe.handle0.Pass(), 0u)); | 60 mojo::InterfacePtrInfo<mojo::ContentHandler>(pipe.handle0.Pass(), 0u)); |
61 services->ConnectToService(mojo::ContentHandler::Name_, | 61 services->ConnectToService(mojo::ContentHandler::Name_, |
62 pipe.handle1.Pass()); | 62 pipe.handle1.Pass()); |
63 content_handler_.set_connection_error_handler( | 63 content_handler_.set_connection_error_handler( |
64 [this]() { manager_->OnContentHandlerError(this); }); | 64 [this]() { manager_->OnContentHandlerError(this); }); |
65 } | 65 } |
66 ~ContentHandlerConnection() {} | 66 ~ContentHandlerConnection() {} |
67 | 67 |
68 mojo::ContentHandler* content_handler() { return content_handler_.get(); } | 68 mojo::ContentHandler* content_handler() { return content_handler_.get(); } |
69 | 69 |
70 GURL content_handler_url() { return content_handler_url_; } | 70 const GURL& content_handler_url() const { return identity_.url; } |
| 71 |
| 72 const Identity& identity() const { return identity_; } |
71 | 73 |
72 private: | 74 private: |
73 ApplicationManager* manager_; | 75 ApplicationManager* manager_; |
74 GURL content_handler_url_; | 76 const Identity identity_; |
75 mojo::ContentHandlerPtr content_handler_; | 77 mojo::ContentHandlerPtr content_handler_; |
76 | 78 |
77 DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection); | 79 DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection); |
78 }; | 80 }; |
79 | 81 |
80 // static | 82 // static |
81 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 83 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) |
82 : manager_(manager) { | 84 : manager_(manager) { |
83 } | 85 } |
84 | 86 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 bool ApplicationManager::ConnectToRunningApplication( | 225 bool ApplicationManager::ConnectToRunningApplication( |
224 const GURL& resolved_url, | 226 const GURL& resolved_url, |
225 const GURL& requestor_url, | 227 const GURL& requestor_url, |
226 InterfaceRequest<ServiceProvider>* services, | 228 InterfaceRequest<ServiceProvider>* services, |
227 ServiceProviderPtr* exposed_services) { | 229 ServiceProviderPtr* exposed_services) { |
228 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); | 230 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); |
229 ShellImpl* shell_impl = GetShellImpl(application_url); | 231 ShellImpl* shell_impl = GetShellImpl(application_url); |
230 if (!shell_impl) | 232 if (!shell_impl) |
231 return false; | 233 return false; |
232 | 234 |
| 235 DCHECK(!GetNativeApplicationOptionsForURL(application_url) |
| 236 ->new_process_per_connection); |
| 237 |
233 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(), | 238 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(), |
234 exposed_services->Pass()); | 239 exposed_services->Pass()); |
235 return true; | 240 return true; |
236 } | 241 } |
237 | 242 |
238 bool ApplicationManager::ConnectToApplicationWithLoader( | 243 bool ApplicationManager::ConnectToApplicationWithLoader( |
239 const GURL& resolved_url, | 244 const GURL& resolved_url, |
240 const GURL& requestor_url, | 245 const GURL& requestor_url, |
241 InterfaceRequest<ServiceProvider>* services, | 246 InterfaceRequest<ServiceProvider>* services, |
242 ServiceProviderPtr* exposed_services, | 247 ServiceProviderPtr* exposed_services, |
243 const base::Closure& on_application_end, | 248 const base::Closure& on_application_end, |
244 const std::vector<std::string>& parameters, | 249 const std::vector<std::string>& parameters, |
245 ApplicationLoader* loader) { | 250 ApplicationLoader* loader) { |
246 if (!loader) | 251 if (!loader) |
247 return false; | 252 return false; |
248 | 253 |
249 loader->Load( | 254 loader->Load( |
250 resolved_url, | 255 resolved_url, |
251 RegisterShell(resolved_url, requestor_url, services->Pass(), | 256 RegisterShell(resolved_url, requestor_url, services->Pass(), |
252 exposed_services->Pass(), on_application_end, parameters)); | 257 exposed_services->Pass(), on_application_end, parameters)); |
253 return true; | 258 return true; |
254 } | 259 } |
255 | 260 |
| 261 Identity ApplicationManager::MakeApplicationIdentity(const GURL& resolved_url) { |
| 262 static uint64_t unique_id_number = 1; |
| 263 bool new_process_per_connection = |
| 264 GetNativeApplicationOptionsForURL( |
| 265 GetBaseURLAndQuery(resolved_url, nullptr)) |
| 266 ->new_process_per_connection; |
| 267 return new_process_per_connection |
| 268 ? Identity(resolved_url, base::Uint64ToString(unique_id_number++)) |
| 269 : Identity(resolved_url); |
| 270 } |
| 271 |
256 InterfaceRequest<Application> ApplicationManager::RegisterShell( | 272 InterfaceRequest<Application> ApplicationManager::RegisterShell( |
257 const GURL& resolved_url, | 273 const GURL& resolved_url, |
258 const GURL& requestor_url, | 274 const GURL& requestor_url, |
259 InterfaceRequest<ServiceProvider> services, | 275 InterfaceRequest<ServiceProvider> services, |
260 ServiceProviderPtr exposed_services, | 276 ServiceProviderPtr exposed_services, |
261 const base::Closure& on_application_end, | 277 const base::Closure& on_application_end, |
262 const std::vector<std::string>& parameters) { | 278 const std::vector<std::string>& parameters) { |
263 Identity app_identity(resolved_url); | 279 Identity app_identity = MakeApplicationIdentity(resolved_url); |
264 | 280 |
265 mojo::ApplicationPtr application; | 281 mojo::ApplicationPtr application; |
266 InterfaceRequest<Application> application_request = | 282 InterfaceRequest<Application> application_request = |
267 mojo::GetProxy(&application); | 283 mojo::GetProxy(&application); |
268 ShellImpl* shell = | 284 ShellImpl* shell = |
269 new ShellImpl(application.Pass(), this, app_identity, on_application_end); | 285 new ShellImpl(application.Pass(), this, app_identity, on_application_end); |
270 identity_to_shell_impl_[app_identity] = make_scoped_ptr(shell); | 286 identity_to_shell_impl_[app_identity] = make_scoped_ptr(shell); |
271 shell->InitializeApplication(mojo::Array<mojo::String>::From(parameters)); | 287 shell->InitializeApplication(mojo::Array<mojo::String>::From(parameters)); |
272 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), | 288 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), |
273 exposed_services.Pass()); | 289 exposed_services.Pass()); |
274 return application_request; | 290 return application_request; |
275 } | 291 } |
276 | 292 |
| 293 // Note: If a service was created with a unique ID, intending to be unique |
| 294 // (such that multiple requests for a service result in unique processes), then |
| 295 // 'GetShellImpl' should return nullptr. |
277 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { | 296 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { |
278 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); | 297 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); |
279 if (shell_it != identity_to_shell_impl_.end()) | 298 if (shell_it != identity_to_shell_impl_.end()) |
280 return shell_it->second.get(); | 299 return shell_it->second.get(); |
281 return nullptr; | 300 return nullptr; |
282 } | 301 } |
283 | 302 |
284 void ApplicationManager::ConnectToClient( | 303 void ApplicationManager::ConnectToClient( |
285 ShellImpl* shell_impl, | 304 ShellImpl* shell_impl, |
286 const GURL& resolved_url, | 305 const GURL& resolved_url, |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 DCHECK(content_handler_url.is_valid()) | 422 DCHECK(content_handler_url.is_valid()) |
404 << "Content handler URL is invalid for mime type " << mime_type; | 423 << "Content handler URL is invalid for mime type " << mime_type; |
405 mime_type_to_url_[mime_type] = content_handler_url; | 424 mime_type_to_url_[mime_type] = content_handler_url; |
406 } | 425 } |
407 | 426 |
408 void ApplicationManager::LoadWithContentHandler( | 427 void ApplicationManager::LoadWithContentHandler( |
409 const GURL& content_handler_url, | 428 const GURL& content_handler_url, |
410 InterfaceRequest<Application> application_request, | 429 InterfaceRequest<Application> application_request, |
411 mojo::URLResponsePtr url_response) { | 430 mojo::URLResponsePtr url_response) { |
412 ContentHandlerConnection* connection = nullptr; | 431 ContentHandlerConnection* connection = nullptr; |
413 auto it = url_to_content_handler_.find(content_handler_url); | 432 Identity content_handler_id = MakeApplicationIdentity(content_handler_url); |
414 if (it != url_to_content_handler_.end()) { | 433 auto it = identity_to_content_handler_.find(content_handler_id); |
| 434 if (it != identity_to_content_handler_.end()) { |
415 connection = it->second.get(); | 435 connection = it->second.get(); |
416 } else { | 436 } else { |
417 connection = new ContentHandlerConnection(this, content_handler_url); | 437 connection = new ContentHandlerConnection(this, content_handler_id); |
418 url_to_content_handler_[content_handler_url] = make_scoped_ptr(connection); | 438 identity_to_content_handler_[content_handler_id] = |
| 439 make_scoped_ptr(connection); |
419 } | 440 } |
420 | 441 |
421 connection->content_handler()->StartApplication(application_request.Pass(), | 442 connection->content_handler()->StartApplication(application_request.Pass(), |
422 url_response.Pass()); | 443 url_response.Pass()); |
423 } | 444 } |
424 | 445 |
425 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 446 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
426 const GURL& url) { | 447 const GURL& url) { |
427 url_to_loader_[url] = loader.Pass(); | 448 url_to_loader_[url] = loader.Pass(); |
428 } | 449 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 auto it = identity_to_shell_impl_.find(identity); | 499 auto it = identity_to_shell_impl_.find(identity); |
479 DCHECK(it != identity_to_shell_impl_.end()); | 500 DCHECK(it != identity_to_shell_impl_.end()); |
480 identity_to_shell_impl_.erase(it); | 501 identity_to_shell_impl_.erase(it); |
481 if (!on_application_end.is_null()) | 502 if (!on_application_end.is_null()) |
482 on_application_end.Run(); | 503 on_application_end.Run(); |
483 } | 504 } |
484 | 505 |
485 void ApplicationManager::OnContentHandlerError( | 506 void ApplicationManager::OnContentHandlerError( |
486 ContentHandlerConnection* content_handler) { | 507 ContentHandlerConnection* content_handler) { |
487 // Remove the mapping to the content handler. | 508 // Remove the mapping to the content handler. |
488 auto it = | 509 auto it = identity_to_content_handler_.find(content_handler->identity()); |
489 url_to_content_handler_.find(content_handler->content_handler_url()); | 510 DCHECK(it != identity_to_content_handler_.end()); |
490 DCHECK(it != url_to_content_handler_.end()); | 511 identity_to_content_handler_.erase(it); |
491 url_to_content_handler_.erase(it); | |
492 } | 512 } |
493 | 513 |
494 mojo::ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 514 mojo::ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
495 const GURL& application_url, | 515 const GURL& application_url, |
496 const std::string& interface_name) { | 516 const std::string& interface_name) { |
497 ServiceProviderPtr services; | 517 ServiceProviderPtr services; |
498 ConnectToApplication(application_url, GURL(), mojo::GetProxy(&services), | 518 ConnectToApplication(application_url, GURL(), mojo::GetProxy(&services), |
499 nullptr, base::Closure()); | 519 nullptr, base::Closure()); |
500 mojo::MessagePipe pipe; | 520 mojo::MessagePipe pipe; |
501 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 521 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
502 return pipe.handle0.Pass(); | 522 return pipe.handle0.Pass(); |
503 } | 523 } |
504 | 524 |
505 std::vector<std::string> ApplicationManager::GetArgsForURL(const GURL& url) { | 525 std::vector<std::string> ApplicationManager::GetArgsForURL(const GURL& url) { |
506 const auto& args_it = url_to_args_.find(url); | 526 const auto& args_it = url_to_args_.find(url); |
507 if (args_it != url_to_args_.end()) | 527 if (args_it != url_to_args_.end()) |
508 return args_it->second; | 528 return args_it->second; |
509 return std::vector<std::string>(); | 529 return std::vector<std::string>(); |
510 } | 530 } |
511 | 531 |
512 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 532 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
513 native_runners_.erase( | 533 native_runners_.erase( |
514 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 534 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
515 } | 535 } |
516 | 536 |
517 } // namespace shell | 537 } // namespace shell |
OLD | NEW |