| Index: mojo/shell/application_manager.cc
|
| diff --git a/mojo/shell/application_manager.cc b/mojo/shell/application_manager.cc
|
| index 44a0c0d410501711eeab625b5a592601ac0fb1f9..c8aa78a415f6ec7af008ffc8c970306e7af83485 100644
|
| --- a/mojo/shell/application_manager.cc
|
| +++ b/mojo/shell/application_manager.cc
|
| @@ -34,12 +34,15 @@ bool has_created_instance = false;
|
| class ApplicationManager::ContentHandlerConnection : public ErrorHandler {
|
| public:
|
| ContentHandlerConnection(ApplicationManager* manager,
|
| - const GURL& content_handler_url)
|
| - : manager_(manager), content_handler_url_(content_handler_url) {
|
| + const GURL& content_handler_url,
|
| + const std::string& qualifier)
|
| + : manager_(manager),
|
| + content_handler_url_(content_handler_url),
|
| + content_handler_qualifier_(qualifier) {
|
| ServiceProviderPtr services;
|
| - manager->ConnectToApplication(content_handler_url, GURL(),
|
| - GetProxy(&services), nullptr,
|
| - base::Closure());
|
| + manager->ConnectToApplicationWithParameters(
|
| + content_handler_url, qualifier, GURL(), GetProxy(&services), nullptr,
|
| + base::Closure(), std::vector<std::string>());
|
| MessagePipe pipe;
|
| content_handler_.Bind(pipe.handle0.Pass());
|
| services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass());
|
| @@ -49,6 +52,7 @@ class ApplicationManager::ContentHandlerConnection : public ErrorHandler {
|
| ContentHandler* content_handler() { return content_handler_.get(); }
|
|
|
| GURL content_handler_url() { return content_handler_url_; }
|
| + std::string content_handler_qualifier() { return content_handler_qualifier_; }
|
|
|
| private:
|
| // ErrorHandler implementation:
|
| @@ -56,6 +60,7 @@ class ApplicationManager::ContentHandlerConnection : public ErrorHandler {
|
|
|
| ApplicationManager* manager_;
|
| GURL content_handler_url_;
|
| + std::string content_handler_qualifier_;
|
| ContentHandlerPtr content_handler_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection);
|
| @@ -100,12 +105,13 @@ void ApplicationManager::ConnectToApplication(
|
| ServiceProviderPtr exposed_services,
|
| const base::Closure& on_application_end) {
|
| ConnectToApplicationWithParameters(
|
| - requested_url, requestor_url, services.Pass(), exposed_services.Pass(),
|
| - on_application_end, std::vector<std::string>());
|
| + requested_url, std::string(), requestor_url, services.Pass(),
|
| + exposed_services.Pass(), on_application_end, std::vector<std::string>());
|
| }
|
|
|
| void ApplicationManager::ConnectToApplicationWithParameters(
|
| const GURL& requested_url,
|
| + const std::string& qualifier,
|
| const GURL& requestor_url,
|
| InterfaceRequest<ServiceProvider> services,
|
| ServiceProviderPtr exposed_services,
|
| @@ -120,44 +126,44 @@ void ApplicationManager::ConnectToApplicationWithParameters(
|
| // external applications can be registered for the unresolved mojo:foo urls.
|
|
|
| GURL mapped_url = delegate_->ResolveMappings(requested_url);
|
| - if (ConnectToRunningApplication(mapped_url, requestor_url, &services,
|
| - &exposed_services)) {
|
| + if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url,
|
| + &services, &exposed_services)) {
|
| return;
|
| }
|
|
|
| GURL resolved_url = delegate_->ResolveMojoURL(mapped_url);
|
| - if (ConnectToRunningApplication(resolved_url, requestor_url, &services,
|
| - &exposed_services)) {
|
| + if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url,
|
| + &services, &exposed_services)) {
|
| return;
|
| }
|
|
|
| // The application is not running, let's compute the parameters.
|
| if (ConnectToApplicationWithLoader(
|
| - requested_url, mapped_url, requestor_url, &services,
|
| + requested_url, qualifier, mapped_url, requestor_url, &services,
|
| &exposed_services, on_application_end, pre_redirect_parameters,
|
| GetLoaderForURL(mapped_url))) {
|
| return;
|
| }
|
|
|
| if (ConnectToApplicationWithLoader(
|
| - requested_url, resolved_url, requestor_url, &services,
|
| + requested_url, qualifier, resolved_url, requestor_url, &services,
|
| &exposed_services, on_application_end, pre_redirect_parameters,
|
| GetLoaderForURL(resolved_url))) {
|
| return;
|
| }
|
|
|
| if (ConnectToApplicationWithLoader(
|
| - requested_url, resolved_url, requestor_url, &services,
|
| + requested_url, qualifier, resolved_url, requestor_url, &services,
|
| &exposed_services, on_application_end, pre_redirect_parameters,
|
| default_loader_.get())) {
|
| return;
|
| }
|
|
|
| - auto callback = base::Bind(&ApplicationManager::HandleFetchCallback,
|
| - weak_ptr_factory_.GetWeakPtr(), requested_url,
|
| - requestor_url, base::Passed(services.Pass()),
|
| - base::Passed(exposed_services.Pass()),
|
| - on_application_end, pre_redirect_parameters);
|
| + auto callback = base::Bind(
|
| + &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(),
|
| + requested_url, qualifier, requestor_url, base::Passed(services.Pass()),
|
| + base::Passed(exposed_services.Pass()), on_application_end,
|
| + pre_redirect_parameters);
|
|
|
| if (resolved_url.SchemeIsFile()) {
|
| new LocalFetcher(
|
| @@ -181,11 +187,12 @@ void ApplicationManager::ConnectToApplicationWithParameters(
|
|
|
| bool ApplicationManager::ConnectToRunningApplication(
|
| const GURL& resolved_url,
|
| + const std::string& qualifier,
|
| const GURL& requestor_url,
|
| InterfaceRequest<ServiceProvider>* services,
|
| ServiceProviderPtr* exposed_services) {
|
| GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr);
|
| - ShellImpl* shell_impl = GetShellImpl(application_url);
|
| + ShellImpl* shell_impl = GetShellImpl(application_url, qualifier);
|
| if (!shell_impl)
|
| return false;
|
|
|
| @@ -196,6 +203,7 @@ bool ApplicationManager::ConnectToRunningApplication(
|
|
|
| bool ApplicationManager::ConnectToApplicationWithLoader(
|
| const GURL& requested_url,
|
| + const std::string& qualifier,
|
| const GURL& resolved_url,
|
| const GURL& requestor_url,
|
| InterfaceRequest<ServiceProvider>* services,
|
| @@ -211,19 +219,20 @@ bool ApplicationManager::ConnectToApplicationWithLoader(
|
|
|
| loader->Load(
|
| resolved_url,
|
| - RegisterShell(app_url, requestor_url, services->Pass(),
|
| + RegisterShell(app_url, qualifier, requestor_url, services->Pass(),
|
| exposed_services->Pass(), on_application_end, parameters));
|
| return true;
|
| }
|
|
|
| InterfaceRequest<Application> ApplicationManager::RegisterShell(
|
| const GURL& app_url,
|
| + const std::string& qualifier,
|
| const GURL& requestor_url,
|
| InterfaceRequest<ServiceProvider> services,
|
| ServiceProviderPtr exposed_services,
|
| const base::Closure& on_application_end,
|
| const std::vector<std::string>& parameters) {
|
| - Identity app_identity(app_url);
|
| + Identity app_identity(app_url, qualifier);
|
|
|
| ApplicationPtr application;
|
| InterfaceRequest<Application> application_request = GetProxy(&application);
|
| @@ -236,8 +245,9 @@ InterfaceRequest<Application> ApplicationManager::RegisterShell(
|
| return application_request.Pass();
|
| }
|
|
|
| -ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
|
| - const auto& shell_it = identity_to_shell_impl_.find(Identity(url));
|
| +ShellImpl* ApplicationManager::GetShellImpl(const GURL& url,
|
| + const std::string& qualifier) {
|
| + const auto& shell_it = identity_to_shell_impl_.find(Identity(url, qualifier));
|
| if (shell_it != identity_to_shell_impl_.end())
|
| return shell_it->second;
|
| return nullptr;
|
| @@ -255,6 +265,7 @@ void ApplicationManager::ConnectToClient(
|
|
|
| void ApplicationManager::HandleFetchCallback(
|
| const GURL& requested_url,
|
| + const std::string& qualifier,
|
| const GURL& requestor_url,
|
| InterfaceRequest<ServiceProvider> services,
|
| ServiceProviderPtr exposed_services,
|
| @@ -271,7 +282,7 @@ void ApplicationManager::HandleFetchCallback(
|
| if (!redirect_url.is_empty()) {
|
| // And around we go again... Whee!
|
| // TODO(sky): this loses |requested_url|.
|
| - ConnectToApplicationWithParameters(redirect_url, requestor_url,
|
| + ConnectToApplicationWithParameters(redirect_url, qualifier, requestor_url,
|
| services.Pass(), exposed_services.Pass(),
|
| on_application_end, parameters);
|
| return;
|
| @@ -283,8 +294,8 @@ void ApplicationManager::HandleFetchCallback(
|
| //
|
| // Also, it's possible the original URL was redirected to an app that is
|
| // already running.
|
| - if (ConnectToRunningApplication(requested_url, requestor_url, &services,
|
| - &exposed_services)) {
|
| + if (ConnectToRunningApplication(requested_url, qualifier, requestor_url,
|
| + &services, &exposed_services)) {
|
| return;
|
| }
|
|
|
| @@ -292,7 +303,7 @@ void ApplicationManager::HandleFetchCallback(
|
| requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL();
|
|
|
| InterfaceRequest<Application> request(
|
| - RegisterShell(app_url, requestor_url, services.Pass(),
|
| + RegisterShell(app_url, qualifier, requestor_url, services.Pass(),
|
| exposed_services.Pass(), on_application_end, parameters));
|
|
|
| // If the response begins with a #!mojo <content-handler-url>, use it.
|
| @@ -300,7 +311,7 @@ void ApplicationManager::HandleFetchCallback(
|
| std::string shebang;
|
| if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) {
|
| LoadWithContentHandler(
|
| - content_handler_url, request.Pass(),
|
| + content_handler_url, qualifier, request.Pass(),
|
| fetcher->AsURLResponse(blocking_pool_,
|
| static_cast<int>(shebang.size())));
|
| return;
|
| @@ -308,17 +319,33 @@ void ApplicationManager::HandleFetchCallback(
|
|
|
| MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType());
|
| if (iter != mime_type_to_url_.end()) {
|
| - LoadWithContentHandler(iter->second, request.Pass(),
|
| + LoadWithContentHandler(iter->second, qualifier, request.Pass(),
|
| fetcher->AsURLResponse(blocking_pool_, 0));
|
| return;
|
| }
|
|
|
| auto alias_iter = application_package_alias_.find(app_url);
|
| if (alias_iter != application_package_alias_.end()) {
|
| + // We replace the qualifier with the one our package alias requested.
|
| URLResponsePtr response(URLResponse::New());
|
| response->url = String::From(app_url.spec());
|
| - LoadWithContentHandler(alias_iter->second,
|
| - request.Pass(),
|
| +
|
| + std::string qualifier;
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableMultiprocess)) {
|
| + // Why can't we use this in single process mode? Because of
|
| + // base::AtExitManager. If you link in ApplicationRunnerChromium into
|
| + // your code, and then we make initialize multiple copies of the
|
| + // application, we end up with multiple AtExitManagers and will check on
|
| + // the second one being created.
|
| + //
|
| + // Why doesn't that happen when running different apps? Because
|
| + // your_thing.mojo!base::AtExitManager and
|
| + // my_thing.mojo!base::AtExitManager are different symbols.
|
| + qualifier = alias_iter->second.second;
|
| + }
|
| +
|
| + LoadWithContentHandler(alias_iter->second.first, qualifier, request.Pass(),
|
| response.Pass());
|
| return;
|
| }
|
| @@ -380,25 +407,28 @@ void ApplicationManager::RegisterContentHandler(
|
| mime_type_to_url_[mime_type] = content_handler_url;
|
| }
|
|
|
| -
|
| void ApplicationManager::RegisterApplicationPackageAlias(
|
| const GURL& alias,
|
| - const GURL& content_handler_package) {
|
| - application_package_alias_[alias] = content_handler_package;
|
| + const GURL& content_handler_package,
|
| + const std::string& qualifier) {
|
| + application_package_alias_[alias] =
|
| + std::make_pair(content_handler_package, qualifier);
|
| }
|
|
|
| void ApplicationManager::LoadWithContentHandler(
|
| const GURL& content_handler_url,
|
| + const std::string& qualifier,
|
| InterfaceRequest<Application> application_request,
|
| URLResponsePtr url_response) {
|
| ContentHandlerConnection* connection = nullptr;
|
| - URLToContentHandlerMap::iterator iter =
|
| - url_to_content_handler_.find(content_handler_url);
|
| + std::pair<GURL, std::string> key(content_handler_url, qualifier);
|
| + URLToContentHandlerMap::iterator iter = url_to_content_handler_.find(key);
|
| if (iter != url_to_content_handler_.end()) {
|
| connection = iter->second;
|
| } else {
|
| - connection = new ContentHandlerConnection(this, content_handler_url);
|
| - url_to_content_handler_[content_handler_url] = connection;
|
| + connection =
|
| + new ContentHandlerConnection(this, content_handler_url, qualifier);
|
| + url_to_content_handler_[key] = connection;
|
| }
|
|
|
| connection->content_handler()->StartApplication(application_request.Pass(),
|
| @@ -463,8 +493,9 @@ void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) {
|
| void ApplicationManager::OnContentHandlerError(
|
| ContentHandlerConnection* content_handler) {
|
| // Remove the mapping to the content handler.
|
| - auto it =
|
| - url_to_content_handler_.find(content_handler->content_handler_url());
|
| + auto it = url_to_content_handler_.find(
|
| + std::make_pair(content_handler->content_handler_url(),
|
| + content_handler->content_handler_qualifier()));
|
| DCHECK(it != url_to_content_handler_.end());
|
| delete it->second;
|
| url_to_content_handler_.erase(it);
|
|
|