| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 TerminateShellConnections(); | 62 TerminateShellConnections(); |
| 63 STLDeleteValues(&url_to_loader_); | 63 STLDeleteValues(&url_to_loader_); |
| 64 STLDeleteValues(&scheme_to_loader_); | 64 STLDeleteValues(&scheme_to_loader_); |
| 65 } | 65 } |
| 66 | 66 |
| 67 void ApplicationManager::TerminateShellConnections() { | 67 void ApplicationManager::TerminateShellConnections() { |
| 68 STLDeleteValues(&identity_to_instance_); | 68 STLDeleteValues(&identity_to_instance_); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void ApplicationManager::ConnectToApplication( | 71 void ApplicationManager::ConnectToApplication( |
| 72 ApplicationInstance* originator, |
| 72 mojo::URLRequestPtr requested_url, | 73 mojo::URLRequestPtr requested_url, |
| 73 const std::string& qualifier, | 74 const std::string& qualifier, |
| 74 const GURL& requestor_url, | 75 const GURL& requestor_url, |
| 75 InterfaceRequest<ServiceProvider> services, | 76 InterfaceRequest<ServiceProvider> services, |
| 76 ServiceProviderPtr exposed_services, | 77 ServiceProviderPtr exposed_services, |
| 78 CapabilityFilterPtr filter, |
| 77 const base::Closure& on_application_end) { | 79 const base::Closure& on_application_end) { |
| 78 GURL requested_gurl(requested_url->url.To<std::string>()); | 80 GURL requested_gurl(requested_url->url.To<std::string>()); |
| 79 TRACE_EVENT_INSTANT1( | 81 TRACE_EVENT_INSTANT1( |
| 80 "mojo_shell", "ApplicationManager::ConnectToApplication", | 82 "mojo_shell", "ApplicationManager::ConnectToApplication", |
| 81 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_gurl.spec()); | 83 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_gurl.spec()); |
| 82 DCHECK(requested_gurl.is_valid()); | 84 DCHECK(requested_gurl.is_valid()); |
| 83 | 85 |
| 84 // We check both the mapped and resolved urls for existing instances because | 86 // We check both the mapped and resolved urls for existing instances because |
| 85 // external applications can be registered for the unresolved mojo:foo urls. | 87 // external applications can be registered for the unresolved mojo:foo urls. |
| 86 | 88 |
| 87 GURL mapped_url = delegate_->ResolveMappings(requested_gurl); | 89 GURL mapped_url = delegate_->ResolveMappings(requested_gurl); |
| 88 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, | 90 if (ConnectToRunningApplication(originator, mapped_url, qualifier, |
| 89 &services, &exposed_services)) { | 91 requestor_url, &services, |
| 92 &exposed_services, &filter)) { |
| 90 return; | 93 return; |
| 91 } | 94 } |
| 92 | 95 |
| 93 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); | 96 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); |
| 94 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, | 97 if (ConnectToRunningApplication(originator, resolved_url, qualifier, |
| 95 &services, &exposed_services)) { | 98 requestor_url, &services, |
| 99 &exposed_services, &filter)) { |
| 96 return; | 100 return; |
| 97 } | 101 } |
| 98 | 102 |
| 99 // The application is not running, let's compute the parameters. | 103 // The application is not running, let's compute the parameters. |
| 100 if (ConnectToApplicationWithLoader( | 104 if (ConnectToApplicationWithLoader( |
| 101 requested_gurl, qualifier, mapped_url, requestor_url, &services, | 105 originator, requested_gurl, qualifier, mapped_url, requestor_url, |
| 102 &exposed_services, on_application_end, GetLoaderForURL(mapped_url))) { | 106 &services, &exposed_services, &filter, on_application_end, |
| 107 GetLoaderForURL(mapped_url))) { |
| 103 return; | 108 return; |
| 104 } | 109 } |
| 105 | 110 |
| 106 if (ConnectToApplicationWithLoader( | 111 if (ConnectToApplicationWithLoader( |
| 107 requested_gurl, qualifier, resolved_url, requestor_url, &services, | 112 originator, requested_gurl, qualifier, resolved_url, requestor_url, |
| 108 &exposed_services, on_application_end, | 113 &services, &exposed_services, &filter, on_application_end, |
| 109 GetLoaderForURL(resolved_url))) { | 114 GetLoaderForURL(resolved_url))) { |
| 110 return; | 115 return; |
| 111 } | 116 } |
| 112 | 117 |
| 113 if (ConnectToApplicationWithLoader( | 118 if (ConnectToApplicationWithLoader( |
| 114 requested_gurl, qualifier, resolved_url, requestor_url, &services, | 119 originator, requested_gurl, qualifier, resolved_url, requestor_url, |
| 115 &exposed_services, on_application_end, default_loader_.get())) { | 120 &services, &exposed_services, &filter, on_application_end, |
| 121 default_loader_.get())) { |
| 116 return; | 122 return; |
| 117 } | 123 } |
| 118 | 124 |
| 119 auto callback = base::Bind( | 125 auto callback = base::Bind( |
| 120 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), | 126 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
| 121 requested_gurl, qualifier, requestor_url, base::Passed(services.Pass()), | 127 originator, requested_gurl, qualifier, requestor_url, |
| 122 base::Passed(exposed_services.Pass()), on_application_end); | 128 base::Passed(services.Pass()), base::Passed(exposed_services.Pass()), |
| 129 base::Passed(filter.Pass()), |
| 130 on_application_end); |
| 123 | 131 |
| 124 if (delegate_->CreateFetcher( | 132 if (delegate_->CreateFetcher( |
| 125 resolved_url, | 133 resolved_url, |
| 126 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { | 134 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { |
| 127 return; | 135 return; |
| 128 } | 136 } |
| 129 | 137 |
| 130 if (resolved_url.SchemeIsFile()) { | 138 if (resolved_url.SchemeIsFile()) { |
| 131 new LocalFetcher( | 139 new LocalFetcher( |
| 132 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 140 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 161 url_loader_factory_.get(), | 169 url_loader_factory_.get(), |
| 162 base::Bind(callback, cleanup)); | 170 base::Bind(callback, cleanup)); |
| 163 return; | 171 return; |
| 164 } | 172 } |
| 165 | 173 |
| 166 new NetworkFetcher(disable_cache_, requested_url.Pass(), | 174 new NetworkFetcher(disable_cache_, requested_url.Pass(), |
| 167 url_loader_factory_.get(), base::Bind(callback, cleanup)); | 175 url_loader_factory_.get(), base::Bind(callback, cleanup)); |
| 168 } | 176 } |
| 169 | 177 |
| 170 bool ApplicationManager::ConnectToRunningApplication( | 178 bool ApplicationManager::ConnectToRunningApplication( |
| 179 ApplicationInstance* originator, |
| 171 const GURL& resolved_url, | 180 const GURL& resolved_url, |
| 172 const std::string& qualifier, | 181 const std::string& qualifier, |
| 173 const GURL& requestor_url, | 182 const GURL& requestor_url, |
| 174 InterfaceRequest<ServiceProvider>* services, | 183 InterfaceRequest<ServiceProvider>* services, |
| 175 ServiceProviderPtr* exposed_services) { | 184 ServiceProviderPtr* exposed_services, |
| 185 CapabilityFilterPtr* filter) { |
| 176 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); | 186 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); |
| 177 ApplicationInstance* instance = | 187 ApplicationInstance* instance = |
| 178 GetApplicationInstance(application_url, qualifier); | 188 GetApplicationInstance(application_url, qualifier); |
| 179 if (!instance) | 189 if (!instance) |
| 180 return false; | 190 return false; |
| 181 | 191 |
| 182 ConnectToClient(instance, resolved_url, requestor_url, services->Pass(), | 192 instance->ConnectToClient(originator, resolved_url, requestor_url, |
| 183 exposed_services->Pass()); | 193 services->Pass(), exposed_services->Pass(), |
| 194 filter->Pass()); |
| 184 return true; | 195 return true; |
| 185 } | 196 } |
| 186 | 197 |
| 187 bool ApplicationManager::ConnectToApplicationWithLoader( | 198 bool ApplicationManager::ConnectToApplicationWithLoader( |
| 199 ApplicationInstance* originator, |
| 188 const GURL& requested_url, | 200 const GURL& requested_url, |
| 189 const std::string& qualifier, | 201 const std::string& qualifier, |
| 190 const GURL& resolved_url, | 202 const GURL& resolved_url, |
| 191 const GURL& requestor_url, | 203 const GURL& requestor_url, |
| 192 InterfaceRequest<ServiceProvider>* services, | 204 InterfaceRequest<ServiceProvider>* services, |
| 193 ServiceProviderPtr* exposed_services, | 205 ServiceProviderPtr* exposed_services, |
| 206 CapabilityFilterPtr* filter, |
| 194 const base::Closure& on_application_end, | 207 const base::Closure& on_application_end, |
| 195 ApplicationLoader* loader) { | 208 ApplicationLoader* loader) { |
| 196 if (!loader) | 209 if (!loader) |
| 197 return false; | 210 return false; |
| 198 | 211 |
| 199 const GURL app_url = | 212 const GURL app_url = |
| 200 requested_url.SchemeIs("mojo") ? requested_url : resolved_url; | 213 requested_url.SchemeIs("mojo") ? requested_url : resolved_url; |
| 201 | 214 |
| 202 loader->Load( | 215 loader->Load( |
| 203 resolved_url, | 216 resolved_url, |
| 204 RegisterInstance(app_url, qualifier, requestor_url, services->Pass(), | 217 RegisterInstance(originator, app_url, qualifier, requestor_url, |
| 205 exposed_services->Pass(), on_application_end)); | 218 services->Pass(), exposed_services->Pass(), |
| 219 filter->Pass(), on_application_end)); |
| 206 return true; | 220 return true; |
| 207 } | 221 } |
| 208 | 222 |
| 209 InterfaceRequest<Application> ApplicationManager::RegisterInstance( | 223 InterfaceRequest<Application> ApplicationManager::RegisterInstance( |
| 224 ApplicationInstance* originator, |
| 210 const GURL& app_url, | 225 const GURL& app_url, |
| 211 const std::string& qualifier, | 226 const std::string& qualifier, |
| 212 const GURL& requestor_url, | 227 const GURL& requestor_url, |
| 213 InterfaceRequest<ServiceProvider> services, | 228 InterfaceRequest<ServiceProvider> services, |
| 214 ServiceProviderPtr exposed_services, | 229 ServiceProviderPtr exposed_services, |
| 230 CapabilityFilterPtr filter, |
| 215 const base::Closure& on_application_end) { | 231 const base::Closure& on_application_end) { |
| 216 Identity app_identity(app_url, qualifier); | 232 Identity app_identity(app_url, qualifier); |
| 217 | 233 |
| 218 ApplicationPtr application; | 234 ApplicationPtr application; |
| 219 InterfaceRequest<Application> application_request = GetProxy(&application); | 235 InterfaceRequest<Application> application_request = GetProxy(&application); |
| 220 ApplicationInstance* instance = new ApplicationInstance(application.Pass(), | 236 ApplicationInstance::CapabilityFilter capability_filter; |
| 221 this, | 237 capability_filter["*"] = std::set<std::string>(); |
| 222 app_identity, | 238 if (!filter.is_null()) { |
| 223 on_application_end); | 239 capability_filter = |
| 240 filter->filter.To<ApplicationInstance::CapabilityFilter>(); |
| 241 } |
| 242 ApplicationInstance* instance = new ApplicationInstance( |
| 243 application.Pass(), this, app_identity, capability_filter, |
| 244 on_application_end); |
| 224 identity_to_instance_[app_identity] = instance; | 245 identity_to_instance_[app_identity] = instance; |
| 225 instance->InitializeApplication(); | 246 instance->InitializeApplication(); |
| 226 ConnectToClient(instance, app_url, requestor_url, services.Pass(), | 247 instance->ConnectToClient(originator, app_url, requestor_url, services.Pass(), |
| 227 exposed_services.Pass()); | 248 exposed_services.Pass(), filter.Pass()); |
| 228 return application_request.Pass(); | 249 return application_request.Pass(); |
| 229 } | 250 } |
| 230 | 251 |
| 231 ApplicationInstance* ApplicationManager::GetApplicationInstance( | 252 ApplicationInstance* ApplicationManager::GetApplicationInstance( |
| 232 const GURL& url, | 253 const GURL& url, |
| 233 const std::string& qualifier) { | 254 const std::string& qualifier) { |
| 234 const auto& instance_it = | 255 const auto& instance_it = |
| 235 identity_to_instance_.find(Identity(url, qualifier)); | 256 identity_to_instance_.find(Identity(url, qualifier)); |
| 236 if (instance_it != identity_to_instance_.end()) | 257 if (instance_it != identity_to_instance_.end()) |
| 237 return instance_it->second; | 258 return instance_it->second; |
| 238 return nullptr; | 259 return nullptr; |
| 239 } | 260 } |
| 240 | 261 |
| 241 void ApplicationManager::ConnectToClient( | |
| 242 ApplicationInstance* instance, | |
| 243 const GURL& resolved_url, | |
| 244 const GURL& requestor_url, | |
| 245 InterfaceRequest<ServiceProvider> services, | |
| 246 ServiceProviderPtr exposed_services) { | |
| 247 instance->ConnectToClient(resolved_url, requestor_url, services.Pass(), | |
| 248 exposed_services.Pass()); | |
| 249 } | |
| 250 | |
| 251 void ApplicationManager::HandleFetchCallback( | 262 void ApplicationManager::HandleFetchCallback( |
| 263 ApplicationInstance* originator, |
| 252 const GURL& requested_url, | 264 const GURL& requested_url, |
| 253 const std::string& qualifier, | 265 const std::string& qualifier, |
| 254 const GURL& requestor_url, | 266 const GURL& requestor_url, |
| 255 InterfaceRequest<ServiceProvider> services, | 267 InterfaceRequest<ServiceProvider> services, |
| 256 ServiceProviderPtr exposed_services, | 268 ServiceProviderPtr exposed_services, |
| 269 CapabilityFilterPtr filter, |
| 257 const base::Closure& on_application_end, | 270 const base::Closure& on_application_end, |
| 258 NativeApplicationCleanup cleanup, | 271 NativeApplicationCleanup cleanup, |
| 259 scoped_ptr<Fetcher> fetcher) { | 272 scoped_ptr<Fetcher> fetcher) { |
| 260 if (!fetcher) { | 273 if (!fetcher) { |
| 261 // Network error. Drop |application_request| to tell requestor. | 274 // Network error. Drop |application_request| to tell requestor. |
| 262 return; | 275 return; |
| 263 } | 276 } |
| 264 | 277 |
| 265 GURL redirect_url = fetcher->GetRedirectURL(); | 278 GURL redirect_url = fetcher->GetRedirectURL(); |
| 266 if (!redirect_url.is_empty()) { | 279 if (!redirect_url.is_empty()) { |
| 267 // And around we go again... Whee! | 280 // And around we go again... Whee! |
| 268 // TODO(sky): this loses |requested_url|. | 281 // TODO(sky): this loses |requested_url|. |
| 269 mojo::URLRequestPtr request(mojo::URLRequest::New()); | 282 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 270 request->url = mojo::String::From(redirect_url.spec()); | 283 request->url = mojo::String::From(redirect_url.spec()); |
| 271 HttpHeaderPtr header = HttpHeader::New(); | 284 HttpHeaderPtr header = HttpHeader::New(); |
| 272 header->name = "Referer"; | 285 header->name = "Referer"; |
| 273 header->value = fetcher->GetRedirectReferer().spec(); | 286 header->value = fetcher->GetRedirectReferer().spec(); |
| 274 request->headers.push_back(header.Pass()); | 287 request->headers.push_back(header.Pass()); |
| 275 ConnectToApplication(request.Pass(), qualifier, requestor_url, | 288 ConnectToApplication(originator, request.Pass(), qualifier, requestor_url, |
| 276 services.Pass(), exposed_services.Pass(), | 289 services.Pass(), exposed_services.Pass(), nullptr, |
| 277 on_application_end); | 290 on_application_end); |
| 278 return; | 291 return; |
| 279 } | 292 } |
| 280 | 293 |
| 281 // We already checked if the application was running before we fetched it, but | 294 // We already checked if the application was running before we fetched it, but |
| 282 // it might have started while the fetch was outstanding. We don't want to | 295 // it might have started while the fetch was outstanding. We don't want to |
| 283 // have two copies of the app running, so check again. | 296 // have two copies of the app running, so check again. |
| 284 // | 297 // |
| 285 // Also, it's possible the original URL was redirected to an app that is | 298 // Also, it's possible the original URL was redirected to an app that is |
| 286 // already running. | 299 // already running. |
| 287 if (ConnectToRunningApplication(requested_url, qualifier, requestor_url, | 300 if (ConnectToRunningApplication(originator, requested_url, qualifier, |
| 288 &services, &exposed_services)) { | 301 requestor_url, &services, |
| 302 &exposed_services, &filter)) { |
| 289 return; | 303 return; |
| 290 } | 304 } |
| 291 | 305 |
| 292 const GURL app_url = | 306 const GURL app_url = |
| 293 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); | 307 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); |
| 294 | 308 |
| 295 InterfaceRequest<Application> request( | 309 InterfaceRequest<Application> request( |
| 296 RegisterInstance(app_url, qualifier, requestor_url, services.Pass(), | 310 RegisterInstance(originator, app_url, qualifier, requestor_url, |
| 297 exposed_services.Pass(), on_application_end)); | 311 services.Pass(), exposed_services.Pass(), filter.Pass(), |
| 312 on_application_end)); |
| 298 | 313 |
| 299 // For resources that are loaded with content handlers, we group app instances | 314 // For resources that are loaded with content handlers, we group app instances |
| 300 // by site. | 315 // by site. |
| 301 | 316 |
| 302 // If the response begins with a #!mojo <content-handler-url>, use it. | 317 // If the response begins with a #!mojo <content-handler-url>, use it. |
| 303 GURL content_handler_url; | 318 GURL content_handler_url; |
| 304 std::string shebang; | 319 std::string shebang; |
| 305 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( | 320 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 306 switches::kEnableMultiprocess); | 321 switches::kEnableMultiprocess); |
| 307 | 322 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 void ApplicationManager::OnContentHandlerConnectionClosed( | 511 void ApplicationManager::OnContentHandlerConnectionClosed( |
| 497 ContentHandlerConnection* content_handler) { | 512 ContentHandlerConnection* content_handler) { |
| 498 // Remove the mapping to the content handler. | 513 // Remove the mapping to the content handler. |
| 499 auto it = url_to_content_handler_.find( | 514 auto it = url_to_content_handler_.find( |
| 500 std::make_pair(content_handler->content_handler_url(), | 515 std::make_pair(content_handler->content_handler_url(), |
| 501 content_handler->content_handler_qualifier())); | 516 content_handler->content_handler_qualifier())); |
| 502 DCHECK(it != url_to_content_handler_.end()); | 517 DCHECK(it != url_to_content_handler_.end()); |
| 503 url_to_content_handler_.erase(it); | 518 url_to_content_handler_.erase(it); |
| 504 } | 519 } |
| 505 | 520 |
| 521 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 522 native_runners_.erase( |
| 523 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
| 524 } |
| 525 |
| 506 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 526 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 507 const GURL& application_url, | 527 const GURL& application_url, |
| 508 const std::string& interface_name) { | 528 const std::string& interface_name) { |
| 509 ServiceProviderPtr services; | 529 ServiceProviderPtr services; |
| 510 mojo::URLRequestPtr request(mojo::URLRequest::New()); | 530 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 511 request->url = mojo::String::From(application_url.spec()); | 531 request->url = mojo::String::From(application_url.spec()); |
| 512 ConnectToApplication(request.Pass(), std::string(), GURL(), | 532 ConnectToApplication(nullptr, request.Pass(), std::string(), GURL(), |
| 513 GetProxy(&services), nullptr, base::Closure()); | 533 GetProxy(&services), nullptr, nullptr, base::Closure()); |
| 514 MessagePipe pipe; | 534 MessagePipe pipe; |
| 515 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 535 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
| 516 return pipe.handle0.Pass(); | 536 return pipe.handle0.Pass(); |
| 517 } | 537 } |
| 518 | 538 |
| 519 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | |
| 520 native_runners_.erase( | |
| 521 std::find(native_runners_.begin(), native_runners_.end(), runner)); | |
| 522 } | |
| 523 | |
| 524 } // namespace shell | 539 } // namespace shell |
| 525 } // namespace mojo | 540 } // namespace mojo |
| OLD | NEW |