| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 weak_ptr_factory_(this) { | 56 weak_ptr_factory_(this) { |
| 57 fetcher_->SetApplicationManager(this); | 57 fetcher_->SetApplicationManager(this); |
| 58 } | 58 } |
| 59 | 59 |
| 60 ApplicationManager::~ApplicationManager() { | 60 ApplicationManager::~ApplicationManager() { |
| 61 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_); | 61 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_); |
| 62 for (auto& pair : url_to_content_handler) | 62 for (auto& pair : url_to_content_handler) |
| 63 pair.second->CloseConnection(); | 63 pair.second->CloseConnection(); |
| 64 TerminateShellConnections(); | 64 TerminateShellConnections(); |
| 65 STLDeleteValues(&url_to_loader_); | 65 STLDeleteValues(&url_to_loader_); |
| 66 STLDeleteValues(&scheme_to_loader_); | |
| 67 } | 66 } |
| 68 | 67 |
| 69 void ApplicationManager::TerminateShellConnections() { | 68 void ApplicationManager::TerminateShellConnections() { |
| 70 STLDeleteValues(&identity_to_instance_); | 69 STLDeleteValues(&identity_to_instance_); |
| 71 } | 70 } |
| 72 | 71 |
| 73 void ApplicationManager::ConnectToApplication( | 72 void ApplicationManager::ConnectToApplication( |
| 74 ApplicationInstance* originator, | 73 ApplicationInstance* originator, |
| 75 URLRequestPtr app_url_request, | 74 URLRequestPtr app_url_request, |
| 76 const std::string& qualifier, | 75 const std::string& qualifier, |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 qualifier = alias_iter->second.second; | 280 qualifier = alias_iter->second.second; |
| 282 } | 281 } |
| 283 | 282 |
| 284 LoadWithContentHandler(originator_identity, originator_filter, | 283 LoadWithContentHandler(originator_identity, originator_filter, |
| 285 alias_iter->second.first, qualifier, filter, | 284 alias_iter->second.first, qualifier, filter, |
| 286 connect_callback, app, request.Pass(), | 285 connect_callback, app, request.Pass(), |
| 287 response.Pass()); | 286 response.Pass()); |
| 288 return; | 287 return; |
| 289 } | 288 } |
| 290 | 289 |
| 291 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo | |
| 292 // application. That could either mean looking for the platform-specific dll | |
| 293 // header, or looking for some specific mojo signature prepended to the | |
| 294 // library. | |
| 295 // TODO(vtl): (Maybe this should be done by the factory/runner?) | |
| 296 | |
| 297 GURL base_resolved_url = GetBaseURLAndQuery(fetcher->GetURL(), nullptr); | |
| 298 NativeRunnerFactory::Options options; | |
| 299 if (url_to_native_options_.find(base_resolved_url) != | |
| 300 url_to_native_options_.end()) { | |
| 301 DVLOG(2) << "Applying stored native options to resolved URL " | |
| 302 << fetcher->GetURL(); | |
| 303 options = url_to_native_options_[base_resolved_url]; | |
| 304 } | |
| 305 | |
| 306 // TODO(erg): Have a better way of switching the sandbox on. For now, switch | 290 // TODO(erg): Have a better way of switching the sandbox on. For now, switch |
| 307 // it on hard coded when we're using some of the sandboxable core services. | 291 // it on hard coded when we're using some of the sandboxable core services. |
| 308 bool start_sandboxed = false; | 292 bool start_sandboxed = false; |
| 309 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 293 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 310 switches::kMojoNoSandbox)) { | 294 switches::kMojoNoSandbox)) { |
| 311 if (app_url == GURL("mojo://core_services/") && qualifier == "Core") | 295 if (app_url == GURL("mojo://core_services/") && qualifier == "Core") |
| 312 start_sandboxed = true; | 296 start_sandboxed = true; |
| 313 else if (app_url == GURL("mojo://html_viewer/")) | 297 else if (app_url == GURL("mojo://html_viewer/")) |
| 314 start_sandboxed = true; | 298 start_sandboxed = true; |
| 315 } | 299 } |
| 316 | 300 |
| 317 connect_callback.Run(Shell::kInvalidContentHandlerID); | 301 connect_callback.Run(Shell::kInvalidContentHandlerID); |
| 318 | 302 |
| 319 fetcher->AsPath(blocking_pool_, | 303 fetcher->AsPath(blocking_pool_, |
| 320 base::Bind(&ApplicationManager::RunNativeApplication, | 304 base::Bind(&ApplicationManager::RunNativeApplication, |
| 321 weak_ptr_factory_.GetWeakPtr(), | 305 weak_ptr_factory_.GetWeakPtr(), |
| 322 base::Passed(request.Pass()), start_sandboxed, | 306 base::Passed(request.Pass()), start_sandboxed, |
| 323 options, base::Passed(fetcher.Pass()))); | 307 base::Passed(fetcher.Pass()))); |
| 324 } | 308 } |
| 325 | 309 |
| 326 void ApplicationManager::RunNativeApplication( | 310 void ApplicationManager::RunNativeApplication( |
| 327 InterfaceRequest<Application> application_request, | 311 InterfaceRequest<Application> application_request, |
| 328 bool start_sandboxed, | 312 bool start_sandboxed, |
| 329 const NativeRunnerFactory::Options& options, | |
| 330 scoped_ptr<Fetcher> fetcher, | 313 scoped_ptr<Fetcher> fetcher, |
| 331 const base::FilePath& path, | 314 const base::FilePath& path, |
| 332 bool path_exists) { | 315 bool path_exists) { |
| 333 // We only passed fetcher to keep it alive. Done with it now. | 316 // We only passed fetcher to keep it alive. Done with it now. |
| 334 fetcher.reset(); | 317 fetcher.reset(); |
| 335 | 318 |
| 336 DCHECK(application_request.is_pending()); | 319 DCHECK(application_request.is_pending()); |
| 337 | 320 |
| 338 if (!path_exists) { | 321 if (!path_exists) { |
| 339 LOG(ERROR) << "Library not started because library path '" << path.value() | 322 LOG(ERROR) << "Library not started because library path '" << path.value() |
| 340 << "' does not exist."; | 323 << "' does not exist."; |
| 341 return; | 324 return; |
| 342 } | 325 } |
| 343 | 326 |
| 344 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", | 327 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", |
| 345 path.AsUTF8Unsafe()); | 328 path.AsUTF8Unsafe()); |
| 346 NativeRunner* runner = native_runner_factory_->Create(options).release(); | 329 NativeRunner* runner = native_runner_factory_->Create().release(); |
| 347 native_runners_.push_back(runner); | 330 native_runners_.push_back(runner); |
| 348 runner->Start(path, start_sandboxed, NativeApplicationCleanup::DONT_DELETE, | 331 runner->Start(path, start_sandboxed, application_request.Pass(), |
| 349 application_request.Pass(), | |
| 350 base::Bind(&ApplicationManager::CleanupRunner, | 332 base::Bind(&ApplicationManager::CleanupRunner, |
| 351 weak_ptr_factory_.GetWeakPtr(), runner)); | 333 weak_ptr_factory_.GetWeakPtr(), runner)); |
| 352 } | 334 } |
| 353 | 335 |
| 354 void ApplicationManager::RegisterContentHandler( | 336 void ApplicationManager::RegisterContentHandler( |
| 355 const std::string& mime_type, | 337 const std::string& mime_type, |
| 356 const GURL& content_handler_url) { | 338 const GURL& content_handler_url) { |
| 357 DCHECK(content_handler_url.is_valid()) | 339 DCHECK(content_handler_url.is_valid()) |
| 358 << "Content handler URL is invalid for mime type " << mime_type; | 340 << "Content handler URL is invalid for mime type " << mime_type; |
| 359 mime_type_to_url_[mime_type] = content_handler_url; | 341 mime_type_to_url_[mime_type] = content_handler_url; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 } | 380 } |
| 399 | 381 |
| 400 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 382 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
| 401 const GURL& url) { | 383 const GURL& url) { |
| 402 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 384 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
| 403 if (it != url_to_loader_.end()) | 385 if (it != url_to_loader_.end()) |
| 404 delete it->second; | 386 delete it->second; |
| 405 url_to_loader_[url] = loader.release(); | 387 url_to_loader_[url] = loader.release(); |
| 406 } | 388 } |
| 407 | 389 |
| 408 void ApplicationManager::SetLoaderForScheme( | |
| 409 scoped_ptr<ApplicationLoader> loader, | |
| 410 const std::string& scheme) { | |
| 411 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); | |
| 412 if (it != scheme_to_loader_.end()) | |
| 413 delete it->second; | |
| 414 scheme_to_loader_[scheme] = loader.release(); | |
| 415 } | |
| 416 | |
| 417 void ApplicationManager::SetNativeOptionsForURL( | |
| 418 const NativeRunnerFactory::Options& options, | |
| 419 const GURL& url) { | |
| 420 DCHECK(!url.has_query()); // Precondition. | |
| 421 // Apply mappings and resolution to get the resolved URL. | |
| 422 GURL resolved_url = fetcher_->ResolveURL(url); | |
| 423 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. | |
| 424 // TODO(vtl): We should probably also remove/disregard the query string (and | |
| 425 // maybe canonicalize in other ways). | |
| 426 DVLOG(2) << "Storing native options for resolved URL " << resolved_url | |
| 427 << " (original URL " << url << ")"; | |
| 428 url_to_native_options_[resolved_url] = options; | |
| 429 } | |
| 430 | |
| 431 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { | 390 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { |
| 432 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr)); | 391 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr)); |
| 433 if (url_it != url_to_loader_.end()) | 392 if (url_it != url_to_loader_.end()) |
| 434 return url_it->second; | 393 return url_it->second; |
| 435 auto scheme_it = scheme_to_loader_.find(url.scheme()); | |
| 436 if (scheme_it != scheme_to_loader_.end()) | |
| 437 return scheme_it->second; | |
| 438 return default_loader_.get(); | 394 return default_loader_.get(); |
| 439 } | 395 } |
| 440 | 396 |
| 441 void ApplicationManager::OnApplicationInstanceError( | 397 void ApplicationManager::OnApplicationInstanceError( |
| 442 ApplicationInstance* instance) { | 398 ApplicationInstance* instance) { |
| 443 // Called from ~ApplicationInstance, so we do not need to call Destroy here. | 399 // Called from ~ApplicationInstance, so we do not need to call Destroy here. |
| 444 const Identity identity = instance->identity(); | 400 const Identity identity = instance->identity(); |
| 445 base::Closure on_application_end = instance->on_application_end(); | 401 base::Closure on_application_end = instance->on_application_end(); |
| 446 // Remove the shell. | 402 // Remove the shell. |
| 447 auto it = identity_to_instance_.find(identity); | 403 auto it = identity_to_instance_.find(identity); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 436 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
| 481 return pipe.handle0.Pass(); | 437 return pipe.handle0.Pass(); |
| 482 } | 438 } |
| 483 | 439 |
| 484 Shell::ConnectToApplicationCallback EmptyConnectCallback() { | 440 Shell::ConnectToApplicationCallback EmptyConnectCallback() { |
| 485 return base::Bind(&OnEmptyOnConnectCallback); | 441 return base::Bind(&OnEmptyOnConnectCallback); |
| 486 } | 442 } |
| 487 | 443 |
| 488 } // namespace shell | 444 } // namespace shell |
| 489 } // namespace mojo | 445 } // namespace mojo |
| OLD | NEW |