| 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/shell/application_manager.h" | 5 #include "mojo/shell/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" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { | 34 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { |
| 35 public: | 35 public: |
| 36 ContentHandlerConnection(ApplicationManager* manager, | 36 ContentHandlerConnection(ApplicationManager* manager, |
| 37 const GURL& content_handler_url, | 37 const GURL& content_handler_url, |
| 38 const GURL& requestor_url, | 38 const GURL& requestor_url, |
| 39 const std::string& qualifier) | 39 const std::string& qualifier) |
| 40 : manager_(manager), | 40 : manager_(manager), |
| 41 content_handler_url_(content_handler_url), | 41 content_handler_url_(content_handler_url), |
| 42 content_handler_qualifier_(qualifier) { | 42 content_handler_qualifier_(qualifier) { |
| 43 ServiceProviderPtr services; | 43 ServiceProviderPtr services; |
| 44 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 45 request->url = mojo::String::From(content_handler_url.spec()); |
| 44 manager->ConnectToApplicationInternal( | 46 manager->ConnectToApplicationInternal( |
| 45 content_handler_url, qualifier, requestor_url, GetProxy(&services), | 47 request.Pass(), qualifier, requestor_url, GetProxy(&services), |
| 46 nullptr, base::Closure()); | 48 nullptr, base::Closure()); |
| 47 MessagePipe pipe; | 49 MessagePipe pipe; |
| 48 content_handler_.Bind( | 50 content_handler_.Bind( |
| 49 InterfacePtrInfo<ContentHandler>(pipe.handle0.Pass(), 0u)); | 51 InterfacePtrInfo<ContentHandler>(pipe.handle0.Pass(), 0u)); |
| 50 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); | 52 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); |
| 51 content_handler_.set_error_handler(this); | 53 content_handler_.set_error_handler(this); |
| 52 } | 54 } |
| 53 | 55 |
| 54 ContentHandler* content_handler() { return content_handler_.get(); } | 56 ContentHandler* content_handler() { return content_handler_.get(); } |
| 55 | 57 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 TerminateShellConnections(); | 96 TerminateShellConnections(); |
| 95 STLDeleteValues(&url_to_loader_); | 97 STLDeleteValues(&url_to_loader_); |
| 96 STLDeleteValues(&scheme_to_loader_); | 98 STLDeleteValues(&scheme_to_loader_); |
| 97 } | 99 } |
| 98 | 100 |
| 99 void ApplicationManager::TerminateShellConnections() { | 101 void ApplicationManager::TerminateShellConnections() { |
| 100 STLDeleteValues(&identity_to_shell_impl_); | 102 STLDeleteValues(&identity_to_shell_impl_); |
| 101 } | 103 } |
| 102 | 104 |
| 103 void ApplicationManager::ConnectToApplication( | 105 void ApplicationManager::ConnectToApplication( |
| 104 const GURL& requested_url, | 106 mojo::URLRequestPtr requested_url, |
| 105 const GURL& requestor_url, | 107 const GURL& requestor_url, |
| 106 InterfaceRequest<ServiceProvider> services, | 108 InterfaceRequest<ServiceProvider> services, |
| 107 ServiceProviderPtr exposed_services, | 109 ServiceProviderPtr exposed_services, |
| 108 const base::Closure& on_application_end) { | 110 const base::Closure& on_application_end) { |
| 109 ConnectToApplicationInternal( | 111 ConnectToApplicationInternal( |
| 110 requested_url, std::string(), requestor_url, services.Pass(), | 112 requested_url.Pass(), std::string(), requestor_url, services.Pass(), |
| 111 exposed_services.Pass(), on_application_end); | 113 exposed_services.Pass(), on_application_end); |
| 112 } | 114 } |
| 113 | 115 |
| 114 void ApplicationManager::ConnectToApplicationInternal( | 116 void ApplicationManager::ConnectToApplicationInternal( |
| 115 const GURL& requested_url, | 117 mojo::URLRequestPtr requested_url, |
| 116 const std::string& qualifier, | 118 const std::string& qualifier, |
| 117 const GURL& requestor_url, | 119 const GURL& requestor_url, |
| 118 InterfaceRequest<ServiceProvider> services, | 120 InterfaceRequest<ServiceProvider> services, |
| 119 ServiceProviderPtr exposed_services, | 121 ServiceProviderPtr exposed_services, |
| 120 const base::Closure& on_application_end) { | 122 const base::Closure& on_application_end) { |
| 123 GURL requested_gurl(requested_url->url.To<std::string>()); |
| 121 TRACE_EVENT_INSTANT1( | 124 TRACE_EVENT_INSTANT1( |
| 122 "mojo_shell", "ApplicationManager::ConnectToApplication", | 125 "mojo_shell", "ApplicationManager::ConnectToApplication", |
| 123 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_url.spec()); | 126 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_gurl.spec()); |
| 124 DCHECK(requested_url.is_valid()); | 127 DCHECK(requested_gurl.is_valid()); |
| 125 | 128 |
| 126 // We check both the mapped and resolved urls for existing shell_impls because | 129 // We check both the mapped and resolved urls for existing shell_impls because |
| 127 // external applications can be registered for the unresolved mojo:foo urls. | 130 // external applications can be registered for the unresolved mojo:foo urls. |
| 128 | 131 |
| 129 GURL mapped_url = delegate_->ResolveMappings(requested_url); | 132 GURL mapped_url = delegate_->ResolveMappings(requested_gurl); |
| 130 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, | 133 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, |
| 131 &services, &exposed_services)) { | 134 &services, &exposed_services)) { |
| 132 return; | 135 return; |
| 133 } | 136 } |
| 134 | 137 |
| 135 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); | 138 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); |
| 136 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, | 139 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, |
| 137 &services, &exposed_services)) { | 140 &services, &exposed_services)) { |
| 138 return; | 141 return; |
| 139 } | 142 } |
| 140 | 143 |
| 141 // The application is not running, let's compute the parameters. | 144 // The application is not running, let's compute the parameters. |
| 142 if (ConnectToApplicationWithLoader( | 145 if (ConnectToApplicationWithLoader( |
| 143 requested_url, qualifier, mapped_url, requestor_url, &services, | 146 requested_gurl, qualifier, mapped_url, requestor_url, &services, |
| 144 &exposed_services, on_application_end, GetLoaderForURL(mapped_url))) { | 147 &exposed_services, on_application_end, GetLoaderForURL(mapped_url))) { |
| 145 return; | 148 return; |
| 146 } | 149 } |
| 147 | 150 |
| 148 if (ConnectToApplicationWithLoader( | 151 if (ConnectToApplicationWithLoader( |
| 149 requested_url, qualifier, resolved_url, requestor_url, &services, | 152 requested_gurl, qualifier, resolved_url, requestor_url, &services, |
| 150 &exposed_services, on_application_end, | 153 &exposed_services, on_application_end, |
| 151 GetLoaderForURL(resolved_url))) { | 154 GetLoaderForURL(resolved_url))) { |
| 152 return; | 155 return; |
| 153 } | 156 } |
| 154 | 157 |
| 155 if (ConnectToApplicationWithLoader( | 158 if (ConnectToApplicationWithLoader( |
| 156 requested_url, qualifier, resolved_url, requestor_url, &services, | 159 requested_gurl, qualifier, resolved_url, requestor_url, &services, |
| 157 &exposed_services, on_application_end, default_loader_.get())) { | 160 &exposed_services, on_application_end, default_loader_.get())) { |
| 158 return; | 161 return; |
| 159 } | 162 } |
| 160 | 163 |
| 161 auto callback = base::Bind( | 164 auto callback = base::Bind( |
| 162 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), | 165 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
| 163 requested_url, qualifier, requestor_url, base::Passed(services.Pass()), | 166 requested_gurl, qualifier, requestor_url, base::Passed(services.Pass()), |
| 164 base::Passed(exposed_services.Pass()), on_application_end); | 167 base::Passed(exposed_services.Pass()), on_application_end); |
| 165 | 168 |
| 166 if (delegate_->CreateFetcher( | 169 if (delegate_->CreateFetcher( |
| 167 resolved_url, | 170 resolved_url, |
| 168 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { | 171 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { |
| 169 return; | 172 return; |
| 170 } | 173 } |
| 171 | 174 |
| 172 if (resolved_url.SchemeIsFile()) { | 175 if (resolved_url.SchemeIsFile()) { |
| 173 new LocalFetcher( | 176 new LocalFetcher( |
| 174 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 177 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
| 175 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE)); | 178 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE)); |
| 176 return; | 179 return; |
| 177 } | 180 } |
| 178 | 181 |
| 179 if (!network_service_) | 182 if (!network_service_) |
| 180 ConnectToService(GURL("mojo:network_service"), &network_service_); | 183 ConnectToService(GURL("mojo:network_service"), &network_service_); |
| 181 | 184 |
| 182 const NativeApplicationCleanup cleanup = | 185 const NativeApplicationCleanup cleanup = |
| 183 base::CommandLine::ForCurrentProcess()->HasSwitch( | 186 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 184 switches::kDontDeleteOnDownload) | 187 switches::kDontDeleteOnDownload) |
| 185 ? NativeApplicationCleanup::DONT_DELETE | 188 ? NativeApplicationCleanup::DONT_DELETE |
| 186 : NativeApplicationCleanup::DELETE; | 189 : NativeApplicationCleanup::DELETE; |
| 187 | 190 |
| 188 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(), | 191 new NetworkFetcher(disable_cache_, requested_url.Pass(), |
| 189 base::Bind(callback, cleanup)); | 192 network_service_.get(), base::Bind(callback, cleanup)); |
| 190 } | 193 } |
| 191 | 194 |
| 192 bool ApplicationManager::ConnectToRunningApplication( | 195 bool ApplicationManager::ConnectToRunningApplication( |
| 193 const GURL& resolved_url, | 196 const GURL& resolved_url, |
| 194 const std::string& qualifier, | 197 const std::string& qualifier, |
| 195 const GURL& requestor_url, | 198 const GURL& requestor_url, |
| 196 InterfaceRequest<ServiceProvider>* services, | 199 InterfaceRequest<ServiceProvider>* services, |
| 197 ServiceProviderPtr* exposed_services) { | 200 ServiceProviderPtr* exposed_services) { |
| 198 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); | 201 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); |
| 199 ShellImpl* shell_impl = GetShellImpl(application_url, qualifier); | 202 ShellImpl* shell_impl = GetShellImpl(application_url, qualifier); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 scoped_ptr<Fetcher> fetcher) { | 279 scoped_ptr<Fetcher> fetcher) { |
| 277 if (!fetcher) { | 280 if (!fetcher) { |
| 278 // Network error. Drop |application_request| to tell requestor. | 281 // Network error. Drop |application_request| to tell requestor. |
| 279 return; | 282 return; |
| 280 } | 283 } |
| 281 | 284 |
| 282 GURL redirect_url = fetcher->GetRedirectURL(); | 285 GURL redirect_url = fetcher->GetRedirectURL(); |
| 283 if (!redirect_url.is_empty()) { | 286 if (!redirect_url.is_empty()) { |
| 284 // And around we go again... Whee! | 287 // And around we go again... Whee! |
| 285 // TODO(sky): this loses |requested_url|. | 288 // TODO(sky): this loses |requested_url|. |
| 286 ConnectToApplicationInternal(redirect_url, qualifier, requestor_url, | 289 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 290 request->url = mojo::String::From(redirect_url.spec()); |
| 291 HttpHeaderPtr header = HttpHeader::New(); |
| 292 header->name = "Referer"; |
| 293 header->value = fetcher->GetRedirectReferer().spec(); |
| 294 request->headers.push_back(header.Pass()); |
| 295 ConnectToApplicationInternal(request.Pass(), qualifier, requestor_url, |
| 287 services.Pass(), exposed_services.Pass(), | 296 services.Pass(), exposed_services.Pass(), |
| 288 on_application_end); | 297 on_application_end); |
| 289 return; | 298 return; |
| 290 } | 299 } |
| 291 | 300 |
| 292 // We already checked if the application was running before we fetched it, but | 301 // We already checked if the application was running before we fetched it, but |
| 293 // it might have started while the fetch was outstanding. We don't want to | 302 // it might have started while the fetch was outstanding. We don't want to |
| 294 // have two copies of the app running, so check again. | 303 // have two copies of the app running, so check again. |
| 295 // | 304 // |
| 296 // Also, it's possible the original URL was redirected to an app that is | 305 // Also, it's possible the original URL was redirected to an app that is |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 content_handler->content_handler_qualifier())); | 510 content_handler->content_handler_qualifier())); |
| 502 DCHECK(it != url_to_content_handler_.end()); | 511 DCHECK(it != url_to_content_handler_.end()); |
| 503 delete it->second; | 512 delete it->second; |
| 504 url_to_content_handler_.erase(it); | 513 url_to_content_handler_.erase(it); |
| 505 } | 514 } |
| 506 | 515 |
| 507 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 516 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 508 const GURL& application_url, | 517 const GURL& application_url, |
| 509 const std::string& interface_name) { | 518 const std::string& interface_name) { |
| 510 ServiceProviderPtr services; | 519 ServiceProviderPtr services; |
| 511 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr, | 520 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 521 request->url = mojo::String::From(application_url.spec()); |
| 522 ConnectToApplication(request.Pass(), GURL(), GetProxy(&services), nullptr, |
| 512 base::Closure()); | 523 base::Closure()); |
| 513 MessagePipe pipe; | 524 MessagePipe pipe; |
| 514 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 525 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
| 515 return pipe.handle0.Pass(); | 526 return pipe.handle0.Pass(); |
| 516 } | 527 } |
| 517 | 528 |
| 518 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 529 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 519 native_runners_.erase( | 530 native_runners_.erase( |
| 520 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 531 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
| 521 } | 532 } |
| 522 | 533 |
| 523 } // namespace shell | 534 } // namespace shell |
| 524 } // namespace mojo | 535 } // namespace mojo |
| OLD | NEW |