Chromium Code Reviews| 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" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "shell/switches.h" | 21 #include "shell/switches.h" |
| 22 | 22 |
| 23 namespace mojo { | 23 namespace mojo { |
| 24 namespace shell { | 24 namespace shell { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 // Used by TestAPI. | 28 // Used by TestAPI. |
| 29 bool has_created_instance = false; | 29 bool has_created_instance = false; |
| 30 | 30 |
| 31 std::vector<std::string> Concatenate(const std::vector<std::string>& v1, | |
| 32 const std::vector<std::string>& v2) { | |
| 33 if (!v1.size()) { | |
|
DaveMoore
2015/03/23 15:47:48
Nit: no braces
qsr
2015/03/23 16:04:38
Done.
| |
| 34 return v2; | |
| 35 } | |
| 36 if (!v2.size()) { | |
| 37 return v1; | |
|
DaveMoore
2015/03/23 15:47:48
Nit: ditto
qsr
2015/03/23 16:04:37
Done.
| |
| 38 } | |
| 39 std::vector<std::string> result(v1); | |
| 40 result.insert(result.end(), v1.begin(), v1.end()); | |
| 41 return result; | |
| 42 } | |
| 43 | |
| 31 } // namespace | 44 } // namespace |
| 32 | 45 |
| 33 ApplicationManager::Delegate::~Delegate() { | 46 ApplicationManager::Delegate::~Delegate() { |
| 34 } | 47 } |
| 35 | 48 |
| 36 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { | 49 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { |
| 37 LOG(ERROR) << "Communication error with application: " << url.spec(); | 50 LOG(ERROR) << "Communication error with application: " << url.spec(); |
| 38 } | 51 } |
| 39 | 52 |
| 40 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { | 53 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 | 117 |
| 105 void ApplicationManager::TerminateShellConnections() { | 118 void ApplicationManager::TerminateShellConnections() { |
| 106 STLDeleteValues(&identity_to_shell_impl_); | 119 STLDeleteValues(&identity_to_shell_impl_); |
| 107 } | 120 } |
| 108 | 121 |
| 109 void ApplicationManager::ConnectToApplication( | 122 void ApplicationManager::ConnectToApplication( |
| 110 const GURL& requested_url, | 123 const GURL& requested_url, |
| 111 const GURL& requestor_url, | 124 const GURL& requestor_url, |
| 112 InterfaceRequest<ServiceProvider> services, | 125 InterfaceRequest<ServiceProvider> services, |
| 113 ServiceProviderPtr exposed_services) { | 126 ServiceProviderPtr exposed_services) { |
| 127 ConnectToApplicationWithParameters(requested_url, requestor_url, | |
| 128 services.Pass(), exposed_services.Pass(), | |
| 129 std::vector<std::string>()); | |
| 130 } | |
| 131 | |
| 132 void ApplicationManager::ConnectToApplicationWithParameters( | |
| 133 const GURL& requested_url, | |
| 134 const GURL& requestor_url, | |
| 135 InterfaceRequest<ServiceProvider> services, | |
| 136 ServiceProviderPtr exposed_services, | |
| 137 const std::vector<std::string>& parameters) { | |
| 114 DCHECK(requested_url.is_valid()); | 138 DCHECK(requested_url.is_valid()); |
| 115 | 139 |
| 116 // We check both the mapped and resolved urls for existing shell_impls because | 140 // We check both the mapped and resolved urls for existing shell_impls because |
| 117 // external applications can be registered for the unresolved mojo:foo urls. | 141 // external applications can be registered for the unresolved mojo:foo urls. |
| 118 | 142 |
| 119 GURL mapped_url = delegate_->ResolveMappings(requested_url); | 143 GURL mapped_url = delegate_->ResolveMappings(requested_url); |
| 120 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, | 144 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, |
| 121 &exposed_services)) { | 145 &exposed_services)) { |
| 122 return; | 146 return; |
| 123 } | 147 } |
| 124 | 148 |
| 125 GURL resolved_url = delegate_->ResolveURL(mapped_url); | 149 GURL resolved_url = delegate_->ResolveURL(mapped_url); |
| 126 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, | 150 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, |
| 127 &exposed_services)) { | 151 &exposed_services)) { |
| 128 return; | 152 return; |
| 129 } | 153 } |
| 130 | 154 |
| 131 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, | 155 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, |
| 132 &services, &exposed_services, | 156 &services, &exposed_services, parameters, |
| 133 GetLoaderForURL(mapped_url))) { | 157 GetLoaderForURL(mapped_url))) { |
| 134 return; | 158 return; |
| 135 } | 159 } |
| 136 | 160 |
| 137 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, | 161 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, |
| 138 &services, &exposed_services, | 162 &services, &exposed_services, parameters, |
| 139 GetLoaderForURL(resolved_url))) { | 163 GetLoaderForURL(resolved_url))) { |
| 140 return; | 164 return; |
| 141 } | 165 } |
| 142 | 166 |
| 143 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, | 167 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, |
| 144 &services, &exposed_services, | 168 &services, &exposed_services, parameters, |
| 145 default_loader_.get())) { | 169 default_loader_.get())) { |
| 146 return; | 170 return; |
| 147 } | 171 } |
| 148 | 172 |
| 149 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, | 173 auto callback = base::Bind( |
| 150 weak_ptr_factory_.GetWeakPtr(), requested_url, | 174 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
| 151 requestor_url, base::Passed(services.Pass()), | 175 requested_url, requestor_url, base::Passed(services.Pass()), |
| 152 base::Passed(exposed_services.Pass())); | 176 base::Passed(exposed_services.Pass()), |
| 177 Concatenate(parameters, GetArgsForURL(resolved_url))); | |
| 153 | 178 |
| 154 if (resolved_url.SchemeIsFile()) { | 179 if (resolved_url.SchemeIsFile()) { |
| 155 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 180 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
| 156 base::Bind(callback, NativeRunner::DontDeleteAppPath)); | 181 base::Bind(callback, NativeRunner::DontDeleteAppPath)); |
| 157 return; | 182 return; |
| 158 } | 183 } |
| 159 | 184 |
| 160 if (!network_service_) | 185 if (!network_service_) |
| 161 ConnectToService(GURL("mojo:network_service"), &network_service_); | 186 ConnectToService(GURL("mojo:network_service"), &network_service_); |
| 162 | 187 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 184 exposed_services->Pass()); | 209 exposed_services->Pass()); |
| 185 return true; | 210 return true; |
| 186 } | 211 } |
| 187 | 212 |
| 188 bool ApplicationManager::ConnectToApplicationWithLoader( | 213 bool ApplicationManager::ConnectToApplicationWithLoader( |
| 189 const GURL& requested_url, | 214 const GURL& requested_url, |
| 190 const GURL& resolved_url, | 215 const GURL& resolved_url, |
| 191 const GURL& requestor_url, | 216 const GURL& requestor_url, |
| 192 InterfaceRequest<ServiceProvider>* services, | 217 InterfaceRequest<ServiceProvider>* services, |
| 193 ServiceProviderPtr* exposed_services, | 218 ServiceProviderPtr* exposed_services, |
| 219 const std::vector<std::string>& parameters, | |
| 194 ApplicationLoader* loader) { | 220 ApplicationLoader* loader) { |
| 195 if (!loader) | 221 if (!loader) |
| 196 return false; | 222 return false; |
| 197 | 223 |
| 198 loader->Load(resolved_url, | 224 loader->Load( |
| 199 RegisterShell(requested_url, resolved_url, requestor_url, | 225 resolved_url, |
| 200 services->Pass(), exposed_services->Pass())); | 226 RegisterShell(requested_url, resolved_url, requestor_url, |
| 227 services->Pass(), exposed_services->Pass(), parameters)); | |
| 201 return true; | 228 return true; |
| 202 } | 229 } |
| 203 | 230 |
| 204 InterfaceRequest<Application> ApplicationManager::RegisterShell( | 231 InterfaceRequest<Application> ApplicationManager::RegisterShell( |
| 205 const GURL& original_url, | 232 const GURL& original_url, |
| 206 const GURL& resolved_url, | 233 const GURL& resolved_url, |
| 207 const GURL& requestor_url, | 234 const GURL& requestor_url, |
| 208 InterfaceRequest<ServiceProvider> services, | 235 InterfaceRequest<ServiceProvider> services, |
| 209 ServiceProviderPtr exposed_services) { | 236 ServiceProviderPtr exposed_services, |
| 237 const std::vector<std::string>& parameters) { | |
| 210 Identity app_identity(resolved_url); | 238 Identity app_identity(resolved_url); |
| 211 | 239 |
| 212 ApplicationPtr application; | 240 ApplicationPtr application; |
| 213 InterfaceRequest<Application> application_request = GetProxy(&application); | 241 InterfaceRequest<Application> application_request = GetProxy(&application); |
| 214 ShellImpl* shell = | 242 ShellImpl* shell = |
| 215 new ShellImpl(application.Pass(), this, original_url, app_identity); | 243 new ShellImpl(application.Pass(), this, original_url, app_identity); |
| 216 identity_to_shell_impl_[app_identity] = shell; | 244 identity_to_shell_impl_[app_identity] = shell; |
| 217 shell->InitializeApplication(GetArgsForURL(original_url)); | 245 shell->InitializeApplication(Array<String>::From( |
| 246 Concatenate(parameters, GetArgsForURL(app_identity.url)))); | |
| 218 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), | 247 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), |
| 219 exposed_services.Pass()); | 248 exposed_services.Pass()); |
| 220 return application_request.Pass(); | 249 return application_request.Pass(); |
| 221 } | 250 } |
| 222 | 251 |
| 223 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { | 252 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { |
| 224 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); | 253 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); |
| 225 if (shell_it != identity_to_shell_impl_.end()) | 254 if (shell_it != identity_to_shell_impl_.end()) |
| 226 return shell_it->second; | 255 return shell_it->second; |
| 227 return nullptr; | 256 return nullptr; |
| 228 } | 257 } |
| 229 | 258 |
| 230 void ApplicationManager::ConnectToClient( | 259 void ApplicationManager::ConnectToClient( |
| 231 ShellImpl* shell_impl, | 260 ShellImpl* shell_impl, |
| 232 const GURL& resolved_url, | 261 const GURL& resolved_url, |
| 233 const GURL& requestor_url, | 262 const GURL& requestor_url, |
| 234 InterfaceRequest<ServiceProvider> services, | 263 InterfaceRequest<ServiceProvider> services, |
| 235 ServiceProviderPtr exposed_services) { | 264 ServiceProviderPtr exposed_services) { |
| 236 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), | 265 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), |
| 237 exposed_services.Pass()); | 266 exposed_services.Pass()); |
| 238 } | 267 } |
| 239 | 268 |
| 240 void ApplicationManager::HandleFetchCallback( | 269 void ApplicationManager::HandleFetchCallback( |
| 241 const GURL& requested_url, | 270 const GURL& requested_url, |
| 242 const GURL& requestor_url, | 271 const GURL& requestor_url, |
| 243 InterfaceRequest<ServiceProvider> services, | 272 InterfaceRequest<ServiceProvider> services, |
| 244 ServiceProviderPtr exposed_services, | 273 ServiceProviderPtr exposed_services, |
| 274 const std::vector<std::string>& parameters, | |
| 245 NativeRunner::CleanupBehavior cleanup_behavior, | 275 NativeRunner::CleanupBehavior cleanup_behavior, |
| 246 scoped_ptr<Fetcher> fetcher) { | 276 scoped_ptr<Fetcher> fetcher) { |
| 247 if (!fetcher) { | 277 if (!fetcher) { |
| 248 // Network error. Drop |application_request| to tell requestor. | 278 // Network error. Drop |application_request| to tell requestor. |
| 249 return; | 279 return; |
| 250 } | 280 } |
| 251 | 281 |
| 252 GURL redirect_url = fetcher->GetRedirectURL(); | 282 GURL redirect_url = fetcher->GetRedirectURL(); |
| 253 if (!redirect_url.is_empty()) { | 283 if (!redirect_url.is_empty()) { |
| 254 // And around we go again... Whee! | 284 // And around we go again... Whee! |
| 255 ConnectToApplication(redirect_url, requestor_url, services.Pass(), | 285 ConnectToApplicationWithParameters(redirect_url, requestor_url, |
| 256 exposed_services.Pass()); | 286 services.Pass(), exposed_services.Pass(), |
| 287 parameters); | |
| 257 return; | 288 return; |
| 258 } | 289 } |
| 259 | 290 |
| 260 // We already checked if the application was running before we fetched it, but | 291 // We already checked if the application was running before we fetched it, but |
| 261 // it might have started while the fetch was outstanding. We don't want to | 292 // it might have started while the fetch was outstanding. We don't want to |
| 262 // have two copies of the app running, so check again. | 293 // have two copies of the app running, so check again. |
| 263 // | 294 // |
| 264 // Also, it's possible the original URL was redirected to an app that is | 295 // Also, it's possible the original URL was redirected to an app that is |
| 265 // already running. | 296 // already running. |
| 266 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, | 297 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, |
| 267 &exposed_services)) { | 298 &exposed_services)) { |
| 268 return; | 299 return; |
| 269 } | 300 } |
| 270 | 301 |
| 271 InterfaceRequest<Application> request( | 302 InterfaceRequest<Application> request( |
| 272 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, | 303 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, |
| 273 services.Pass(), exposed_services.Pass())); | 304 services.Pass(), exposed_services.Pass(), parameters)); |
| 274 | 305 |
| 275 // If the response begins with a #!mojo <content-handler-url>, use it. | 306 // If the response begins with a #!mojo <content-handler-url>, use it. |
| 276 GURL content_handler_url; | 307 GURL content_handler_url; |
| 277 std::string shebang; | 308 std::string shebang; |
| 278 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { | 309 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { |
| 279 LoadWithContentHandler( | 310 LoadWithContentHandler( |
| 280 content_handler_url, request.Pass(), | 311 content_handler_url, request.Pass(), |
| 281 fetcher->AsURLResponse(blocking_pool_, | 312 fetcher->AsURLResponse(blocking_pool_, |
| 282 static_cast<int>(shebang.size()))); | 313 static_cast<int>(shebang.size()))); |
| 283 return; | 314 return; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 scoped_ptr<ApplicationLoader> loader, | 422 scoped_ptr<ApplicationLoader> loader, |
| 392 const std::string& scheme) { | 423 const std::string& scheme) { |
| 393 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); | 424 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); |
| 394 if (it != scheme_to_loader_.end()) | 425 if (it != scheme_to_loader_.end()) |
| 395 delete it->second; | 426 delete it->second; |
| 396 scheme_to_loader_[scheme] = loader.release(); | 427 scheme_to_loader_[scheme] = loader.release(); |
| 397 } | 428 } |
| 398 | 429 |
| 399 void ApplicationManager::SetArgsForURL(const std::vector<std::string>& args, | 430 void ApplicationManager::SetArgsForURL(const std::vector<std::string>& args, |
| 400 const GURL& url) { | 431 const GURL& url) { |
| 401 url_to_args_[url] = args; | 432 url_to_args_[url].insert(url_to_args_[url].end(), args.begin(), args.end()); |
| 433 GURL mapped_url = delegate_->ResolveMappings(url); | |
| 434 if (mapped_url != url) { | |
| 435 url_to_args_[mapped_url].insert(url_to_args_[mapped_url].end(), | |
| 436 args.begin(), args.end()); | |
| 437 } | |
| 438 GURL resolved_url = delegate_->ResolveURL(mapped_url); | |
| 439 if (resolved_url != mapped_url) { | |
| 440 url_to_args_[resolved_url].insert(url_to_args_[resolved_url].end(), | |
| 441 args.begin(), args.end()); | |
| 442 } | |
| 402 } | 443 } |
| 403 | 444 |
| 404 void ApplicationManager::SetNativeOptionsForURL( | 445 void ApplicationManager::SetNativeOptionsForURL( |
| 405 const NativeRunnerFactory::Options& options, | 446 const NativeRunnerFactory::Options& options, |
| 406 const GURL& url) { | 447 const GURL& url) { |
| 407 DCHECK(!url.has_query()); // Precondition. | 448 DCHECK(!url.has_query()); // Precondition. |
| 408 // Apply mappings and resolution to get the resolved URL. | 449 // Apply mappings and resolution to get the resolved URL. |
| 409 GURL resolved_url = delegate_->ResolveURL(delegate_->ResolveMappings(url)); | 450 GURL resolved_url = delegate_->ResolveURL(delegate_->ResolveMappings(url)); |
| 410 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. | 451 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. |
| 411 // TODO(vtl): We should probably also remove/disregard the query string (and | 452 // TODO(vtl): We should probably also remove/disregard the query string (and |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 491 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 451 const GURL& application_url, | 492 const GURL& application_url, |
| 452 const std::string& interface_name) { | 493 const std::string& interface_name) { |
| 453 ServiceProviderPtr services; | 494 ServiceProviderPtr services; |
| 454 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr); | 495 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr); |
| 455 MessagePipe pipe; | 496 MessagePipe pipe; |
| 456 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 497 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
| 457 return pipe.handle0.Pass(); | 498 return pipe.handle0.Pass(); |
| 458 } | 499 } |
| 459 | 500 |
| 460 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { | 501 std::vector<std::string> ApplicationManager::GetArgsForURL(const GURL& url) { |
| 461 const auto& args_it = url_to_args_.find(url); | 502 const auto& args_it = url_to_args_.find(url); |
| 462 if (args_it != url_to_args_.end()) | 503 if (args_it != url_to_args_.end()) |
| 463 return Array<String>::From(args_it->second); | 504 return args_it->second; |
| 464 return Array<String>(); | 505 return std::vector<std::string>(); |
| 465 } | 506 } |
| 466 | 507 |
| 467 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 508 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 468 native_runners_.erase( | 509 native_runners_.erase( |
| 469 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 510 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
| 470 } | 511 } |
| 471 | 512 |
| 472 } // namespace shell | 513 } // namespace shell |
| 473 } // namespace mojo | 514 } // namespace mojo |
| OLD | NEW |