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