diff options
author | ben <ben@chromium.org> | 2015-09-16 22:06:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-17 05:07:28 +0000 |
commit | 59e4ed2dd7f05972f687d628df0ba9c9cc35eb97 (patch) | |
tree | 2ef0578b26650c7faa95ead36699554a59ebba42 | |
parent | f300c091c99ac3955def417a28ea0df328d4290d (diff) | |
download | chromium_src-59e4ed2dd7f05972f687d628df0ba9c9cc35eb97.zip chromium_src-59e4ed2dd7f05972f687d628df0ba9c9cc35eb97.tar.gz chromium_src-59e4ed2dd7f05972f687d628df0ba9c9cc35eb97.tar.bz2 |
Extract some stuff into PackageManager:
- content handler determination from ApplicationManager::HandleFetchCallback
- content handler registration
- renames BaseApplicationFetcher to PackageManagerImpl.
R=yzshen@chromium.org
BUG=
Review URL: https://codereview.chromium.org/1352663002
Cr-Commit-Position: refs/heads/master@{#349357}
27 files changed, 558 insertions, 371 deletions
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 212acbe..599a555 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -39,7 +39,7 @@ source_set("browser") { "//mojo/application/public/cpp:cpp_for_chromium", "//mojo/application/public/interfaces", "//mojo/common", - "//mojo/fetcher", + "//mojo/package_manager", "//mojo/shell", "//net", "//net:extras", diff --git a/content/browser/mojo/mojo_shell_context.cc b/content/browser/mojo/mojo_shell_context.cc index 80120da..45d2273 100644 --- a/content/browser/mojo/mojo_shell_context.cc +++ b/content/browser/mojo/mojo_shell_context.cc @@ -18,7 +18,7 @@ #include "content/public/common/service_registry.h" #include "mojo/application/public/cpp/application_delegate.h" #include "mojo/common/url_type_converters.h" -#include "mojo/fetcher/base_application_fetcher.h" +#include "mojo/package_manager/package_manager_impl.h" #include "mojo/shell/application_loader.h" #include "mojo/shell/connect_to_application_params.h" #include "mojo/shell/identity.h" @@ -159,10 +159,10 @@ MojoShellContext::MojoShellContext() { // Construct with an empty filepath since mojo: urls can't be registered now // the url scheme registry is locked. - scoped_ptr<mojo::fetcher::BaseApplicationFetcher> fetcher( - new mojo::fetcher::BaseApplicationFetcher(base::FilePath())); + scoped_ptr<mojo::package_manager::PackageManagerImpl> package_manager( + new mojo::package_manager::PackageManagerImpl(base::FilePath())); application_manager_.reset( - new mojo::shell::ApplicationManager(fetcher.Pass())); + new mojo::shell::ApplicationManager(package_manager.Pass())); application_manager_->set_default_loader( scoped_ptr<mojo::shell::ApplicationLoader>(new DefaultApplicationLoader)); diff --git a/mandoline/app/android/BUILD.gn b/mandoline/app/android/BUILD.gn index 4afc198..20c3fac 100644 --- a/mandoline/app/android/BUILD.gn +++ b/mandoline/app/android/BUILD.gn @@ -24,6 +24,7 @@ executable("mandoline_runner") { "//mandoline/ui/desktop_ui/public/interfaces", "//mojo/common", "//mojo/environment:chromium", + "//mojo/package_manager", "//mojo/runner:lib", "//mojo/runner:mojo_runner_lib", ] diff --git a/mandoline/app/core_services_initialization.cc b/mandoline/app/core_services_initialization.cc index 17ee8f0..b56343d 100644 --- a/mandoline/app/core_services_initialization.cc +++ b/mandoline/app/core_services_initialization.cc @@ -4,6 +4,7 @@ #include "mandoline/app/core_services_initialization.h" +#include "mojo/package_manager/package_manager_impl.h" #include "mojo/runner/context.h" namespace mandoline { @@ -11,7 +12,8 @@ namespace mandoline { void InitCoreServicesForContext(mojo::runner::Context* context) { // TODO(erg): We should probably handle this differently; these could be // autogenerated from package manifests. - mojo::shell::ApplicationManager* manager = context->application_manager(); + mojo::package_manager::PackageManagerImpl* manager = + context->package_manager(); manager->RegisterApplicationPackageAlias( GURL("mojo:clipboard"), GURL("mojo:core_services"), "Core"); manager->RegisterApplicationPackageAlias(GURL("mojo:filesystem"), diff --git a/mandoline/app/desktop/BUILD.gn b/mandoline/app/desktop/BUILD.gn index ca2140d..6860a0d 100644 --- a/mandoline/app/desktop/BUILD.gn +++ b/mandoline/app/desktop/BUILD.gn @@ -22,6 +22,7 @@ executable("mandoline") { "//components/tracing:startup_tracing", "//mojo/common", "//mojo/environment:chromium", + "//mojo/package_manager", "//mojo/runner:lib", ] diff --git a/mojo/fetcher/BUILD.gn b/mojo/fetcher/BUILD.gn index f362129..c1a49bc 100644 --- a/mojo/fetcher/BUILD.gn +++ b/mojo/fetcher/BUILD.gn @@ -8,8 +8,6 @@ source_set("fetcher") { sources = [ "about_fetcher.cc", "about_fetcher.h", - "base_application_fetcher.cc", - "base_application_fetcher.h", "local_fetcher.cc", "local_fetcher.h", "network_fetcher.cc", diff --git a/mojo/fetcher/about_fetcher_unittest.cc b/mojo/fetcher/about_fetcher_unittest.cc index 79c487a..b69d349 100644 --- a/mojo/fetcher/about_fetcher_unittest.cc +++ b/mojo/fetcher/about_fetcher_unittest.cc @@ -15,7 +15,7 @@ #include "mojo/application/public/interfaces/content_handler.mojom.h" #include "mojo/common/weak_binding_set.h" #include "mojo/fetcher/about_fetcher.h" -#include "mojo/fetcher/base_application_fetcher.h" +#include "mojo/package_manager/package_manager_impl.h" #include "mojo/runner/context.h" #include "mojo/shell/application_loader.h" #include "mojo/shell/application_manager.h" @@ -125,13 +125,15 @@ class AboutFetcherTest : public testing::Test { runner::Context::EnsureEmbedderIsInitialized(); base::FilePath shell_dir; PathService::Get(base::DIR_MODULE, &shell_dir); - application_manager_.reset(new shell::ApplicationManager( - make_scoped_ptr(new BaseApplicationFetcher(shell_dir)))); + scoped_ptr<package_manager::PackageManagerImpl> package_manager( + new package_manager::PackageManagerImpl(shell_dir)); + package_manager->RegisterContentHandler( + "text/html", GURL("test:html_content_handler")); + application_manager_.reset( + new shell::ApplicationManager(package_manager.Pass())); application_manager_->SetLoaderForURL( make_scoped_ptr(new TestLoader(&html_content_handler_)), GURL("test:html_content_handler")); - application_manager_->RegisterContentHandler( - "text/html", GURL("test:html_content_handler")); } void TearDown() override { application_manager_.reset(); } diff --git a/mojo/fetcher/base_application_fetcher.cc b/mojo/fetcher/base_application_fetcher.cc deleted file mode 100644 index 68909b5..0000000 --- a/mojo/fetcher/base_application_fetcher.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/fetcher/base_application_fetcher.h" - -#include "mojo/fetcher/about_fetcher.h" -#include "mojo/fetcher/local_fetcher.h" -#include "mojo/fetcher/network_fetcher.h" -#include "mojo/fetcher/switches.h" -#include "mojo/fetcher/update_fetcher.h" -#include "mojo/shell/application_manager.h" -#include "mojo/shell/query_util.h" -#include "mojo/util/filename_util.h" -#include "url/gurl.h" - -namespace mojo { -namespace fetcher { - -BaseApplicationFetcher::BaseApplicationFetcher( - const base::FilePath& shell_file_root) - : application_manager_(nullptr), - disable_cache_(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableCache)) { - if (!shell_file_root.empty()) { - GURL mojo_root_file_url = - util::FilePathToFileURL(shell_file_root).Resolve(std::string()); - url_resolver_.reset(new URLResolver(mojo_root_file_url)); - } -} - -BaseApplicationFetcher::~BaseApplicationFetcher() { -} - -void BaseApplicationFetcher::SetApplicationManager( - shell::ApplicationManager* manager) { - application_manager_ = manager; -} - -GURL BaseApplicationFetcher::ResolveURL(const GURL& url) { - return url_resolver_.get() ? url_resolver_->ResolveMojoURL(url) : url; -} - -void BaseApplicationFetcher::FetchRequest( - URLRequestPtr request, - const shell::Fetcher::FetchCallback& loader_callback) { - GURL url(request->url); - if (url.SchemeIs(AboutFetcher::kAboutScheme)) { - AboutFetcher::Start(url, loader_callback); - return; - } - - GURL resolved_url = ResolveURL(url); - - if (resolved_url.SchemeIsFile()) { - // LocalFetcher uses the network service to infer MIME types from URLs. - // Skip this for mojo URLs to avoid recursively loading the network service. - if (!network_service_ && !url.SchemeIs("mojo")) { - application_manager_->ConnectToService(GURL("mojo:network_service"), - &network_service_); - } - // Ownership of this object is transferred to |loader_callback|. - // TODO(beng): this is eff'n weird. - new LocalFetcher( - network_service_.get(), resolved_url, - shell::GetBaseURLAndQuery(resolved_url, nullptr), - loader_callback); - return; - } - -#if 0 - // TODO(beng): figure out how this should be integrated now that mapped_url - // is toast. - // TODO(scottmg): to quote someone I know, if you liked this you shouldda put - // a test on it. - if (url.SchemeIs("mojo") && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseUpdater)) { - application_manager_->ConnectToService(GURL("mojo:updater"), &updater_); - // Ownership of this object is transferred to |loader_callback|. - // TODO(beng): this is eff'n weird. - new UpdateFetcher(url, updater_.get(), loader_callback); - return; - } -#endif - - if (!url_loader_factory_) { - application_manager_->ConnectToService(GURL("mojo:network_service"), - &url_loader_factory_); - } - - // Ownership of this object is transferred to |loader_callback|. - // TODO(beng): this is eff'n weird. - new NetworkFetcher(disable_cache_, request.Pass(), url_loader_factory_.get(), - loader_callback); -} - -} // namespace fetcher -} // namespace mojo diff --git a/mojo/fetcher/base_application_fetcher.h b/mojo/fetcher/base_application_fetcher.h deleted file mode 100644 index 5e39f29..0000000 --- a/mojo/fetcher/base_application_fetcher.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/files/file_path.h" -#include "mojo/fetcher/url_resolver.h" -#include "mojo/services/network/public/interfaces/network_service.mojom.h" -#include "mojo/services/network/public/interfaces/url_loader_factory.mojom.h" -#include "mojo/shell/application_fetcher.h" - -namespace mojo { -namespace fetcher { - -// This is the default implementation of shell::ApplicationFetcher. It loads -// http/s urls off the network as well as providing special handling for mojo: -// and about: urls. -class BaseApplicationFetcher : public shell::ApplicationFetcher { - public: - // mojo: urls are only supported if |shell_file_root| is non-empty. - BaseApplicationFetcher(const base::FilePath& shell_file_root); - ~BaseApplicationFetcher() override; - - private: - // Overridden from shell::ApplicationFetcher: - void SetApplicationManager(shell::ApplicationManager* manager) override; - GURL ResolveURL(const GURL& url) override; - void FetchRequest( - URLRequestPtr request, - const shell::Fetcher::FetchCallback& loader_callback) override; - - shell::ApplicationManager* application_manager_; - scoped_ptr<URLResolver> url_resolver_; - const bool disable_cache_; - NetworkServicePtr network_service_; - URLLoaderFactoryPtr url_loader_factory_; - - DISALLOW_COPY_AND_ASSIGN(BaseApplicationFetcher); -}; - -} // namespace fetcher -} // namespace mojo diff --git a/mojo/mojo_shell.gyp b/mojo/mojo_shell.gyp index 598ef3d..62bba84 100644 --- a/mojo/mojo_shell.gyp +++ b/mojo/mojo_shell.gyp @@ -25,6 +25,7 @@ 'shell/identity.cc', 'shell/identity.h', 'shell/native_runner.h', + 'shell/package_manager.h', 'shell/query_util.cc', 'shell/query_util.h', 'shell/static_application_loader.cc', @@ -50,8 +51,6 @@ 'sources': [ 'fetcher/about_fetcher.cc', 'fetcher/about_fetcher.h', - 'fetcher/base_application_fetcher.cc', - 'fetcher/base_application_fetcher.h', 'fetcher/local_fetcher.cc', 'fetcher/local_fetcher.h', 'fetcher/network_fetcher.cc', @@ -62,6 +61,8 @@ 'fetcher/update_fetcher.h', 'fetcher/url_resolver.cc', 'fetcher/url_resolver.h', + 'package_manager/package_manager_impl.cc', + 'package_manager/package_manager_impl.h', ], 'dependencies': [ '<(DEPTH)/base/base.gyp:base', @@ -84,6 +85,8 @@ 'shell/application_manager_unittest.cc', 'shell/capability_filter_unittest.cc', 'shell/query_util_unittest.cc', + 'shell/test_package_manager.cc', + 'shell/test_package_manager.h', ], 'dependencies': [ '<(DEPTH)/mojo/mojo_shell.gyp:mojo_shell_lib', diff --git a/mojo/package_manager/BUILD.gn b/mojo/package_manager/BUILD.gn new file mode 100644 index 0000000..913a36d --- /dev/null +++ b/mojo/package_manager/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("package_manager") { + sources = [ + "package_manager_impl.cc", + "package_manager_impl.h", + ] + + deps = [ + "//mojo/fetcher", + "//mojo/shell", + "//mojo/util:filename_util", + ] +} diff --git a/mojo/package_manager/DEPS b/mojo/package_manager/DEPS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/mojo/package_manager/DEPS diff --git a/mojo/package_manager/package_manager_impl.cc b/mojo/package_manager/package_manager_impl.cc new file mode 100644 index 0000000..f1a1fc6 --- /dev/null +++ b/mojo/package_manager/package_manager_impl.cc @@ -0,0 +1,172 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/package_manager/package_manager_impl.h" + +#include "mojo/fetcher/about_fetcher.h" +#include "mojo/fetcher/local_fetcher.h" +#include "mojo/fetcher/network_fetcher.h" +#include "mojo/fetcher/switches.h" +#include "mojo/fetcher/update_fetcher.h" +#include "mojo/shell/application_manager.h" +#include "mojo/shell/query_util.h" +#include "mojo/shell/switches.h" +#include "mojo/util/filename_util.h" +#include "url/gurl.h" + +namespace mojo { +namespace package_manager { + +PackageManagerImpl::PackageManagerImpl( + const base::FilePath& shell_file_root) + : application_manager_(nullptr), + disable_cache_(base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableCache)) { + if (!shell_file_root.empty()) { + GURL mojo_root_file_url = + util::FilePathToFileURL(shell_file_root).Resolve(std::string()); + url_resolver_.reset(new fetcher::URLResolver(mojo_root_file_url)); + } +} + +PackageManagerImpl::~PackageManagerImpl() { +} + +void PackageManagerImpl::RegisterContentHandler( + const std::string& mime_type, + const GURL& content_handler_url) { + DCHECK(content_handler_url.is_valid()) + << "Content handler URL is invalid for mime type " << mime_type; + mime_type_to_url_[mime_type] = content_handler_url; +} + +void PackageManagerImpl::RegisterApplicationPackageAlias( + const GURL& alias, + const GURL& content_handler_package, + const std::string& qualifier) { + application_package_alias_[alias] = + std::make_pair(content_handler_package, qualifier); +} + +void PackageManagerImpl::SetApplicationManager( + shell::ApplicationManager* manager) { + application_manager_ = manager; +} + +GURL PackageManagerImpl::ResolveURL(const GURL& url) { + return url_resolver_.get() ? url_resolver_->ResolveMojoURL(url) : url; +} + +void PackageManagerImpl::FetchRequest( + URLRequestPtr request, + const shell::Fetcher::FetchCallback& loader_callback) { + GURL url(request->url); + if (url.SchemeIs(fetcher::AboutFetcher::kAboutScheme)) { + fetcher::AboutFetcher::Start(url, loader_callback); + return; + } + + GURL resolved_url = ResolveURL(url); + + if (resolved_url.SchemeIsFile()) { + // LocalFetcher uses the network service to infer MIME types from URLs. + // Skip this for mojo URLs to avoid recursively loading the network service. + if (!network_service_ && !url.SchemeIs("mojo")) { + application_manager_->ConnectToService(GURL("mojo:network_service"), + &network_service_); + } + // Ownership of this object is transferred to |loader_callback|. + // TODO(beng): this is eff'n weird. + new fetcher::LocalFetcher( + network_service_.get(), resolved_url, + shell::GetBaseURLAndQuery(resolved_url, nullptr), + loader_callback); + return; + } + +#if 0 + // TODO(beng): figure out how this should be integrated now that mapped_url + // is toast. + // TODO(scottmg): to quote someone I know, if you liked this you shouldda put + // a test on it. + if (url.SchemeIs("mojo") && + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUseUpdater)) { + application_manager_->ConnectToService(GURL("mojo:updater"), &updater_); + // Ownership of this object is transferred to |loader_callback|. + // TODO(beng): this is eff'n weird. + new fetcher::UpdateFetcher(url, updater_.get(), loader_callback); + return; + } +#endif + + if (!url_loader_factory_) { + application_manager_->ConnectToService(GURL("mojo:network_service"), + &url_loader_factory_); + } + + // Ownership of this object is transferred to |loader_callback|. + // TODO(beng): this is eff'n weird. + new fetcher::NetworkFetcher(disable_cache_, request.Pass(), + url_loader_factory_.get(), loader_callback); +} + +bool PackageManagerImpl::HandleWithContentHandler(shell::Fetcher* fetcher, + const GURL& unresolved_url, + base::TaskRunner* task_runner, + URLResponsePtr* new_response, + GURL* content_handler_url, + std::string* qualifier) { + // TODO(beng): it seems like some delegate should/would want to have a say in + // configuring the qualifier also. + bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableMultiprocess); + + // The response begins with a #!mojo <content-handler-url>. + std::string shebang; + if (fetcher->PeekContentHandler(&shebang, content_handler_url)) { + *new_response = fetcher->AsURLResponse( + task_runner, static_cast<int>(shebang.size())); + *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() + : std::string(); + return true; + } + + // The response MIME type matches a registered content handler. + MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); + if (iter != mime_type_to_url_.end()) { + *new_response = fetcher->AsURLResponse(task_runner, 0); + *content_handler_url = iter->second; + *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() + : std::string(); + return true; + } + + // The response URL matches a registered content handler. + auto alias_iter = application_package_alias_.find(unresolved_url); + if (alias_iter != application_package_alias_.end()) { + // We replace the qualifier with the one our package alias requested. + *new_response = URLResponse::New(); + (*new_response)->url = unresolved_url.spec(); + + // Why can't we use this in single process mode? Because of + // base::AtExitManager. If you link in ApplicationRunner 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 = enable_multi_process ? alias_iter->second.second + : std::string(); + *content_handler_url = alias_iter->second.first; + return true; + } + + return false; +} + +} // namespace package_manager +} // namespace mojo diff --git a/mojo/package_manager/package_manager_impl.h b/mojo/package_manager/package_manager_impl.h new file mode 100644 index 0000000..56961be4 --- /dev/null +++ b/mojo/package_manager/package_manager_impl.h @@ -0,0 +1,76 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PACKAGE_MANAGER_PACKAGE_MANAGER_IMPL_H_ +#define MOJO_PACKAGE_MANAGER_PACKAGE_MANAGER_IMPL_H_ + +#include "base/files/file_path.h" +#include "mojo/fetcher/url_resolver.h" +#include "mojo/services/network/public/interfaces/network_service.mojom.h" +#include "mojo/services/network/public/interfaces/url_loader_factory.mojom.h" +#include "mojo/shell/package_manager.h" + +namespace mojo { +namespace shell { +class Fetcher; +} +namespace package_manager { + +// This is the default implementation of shell::PackageManager. It loads +// http/s urls off the network as well as providing special handling for mojo: +// and about: urls. +class PackageManagerImpl : public shell::PackageManager { + public: + // mojo: urls are only supported if |shell_file_root| is non-empty. + explicit PackageManagerImpl(const base::FilePath& shell_file_root); + ~PackageManagerImpl() override; + + // Register a content handler to handle content of |mime_type|. + void RegisterContentHandler(const std::string& mime_type, + const GURL& content_handler_url); + + // Registers a package alias. When attempting to load |alias|, it will + // instead redirect to |content_handler_package|, which is a content handler + // which will be passed the |alias| as the URLResponse::url. Different values + // of |alias| with the same |qualifier| that are in the same + // |content_handler_package| will run in the same process in multi-process + // mode. + void RegisterApplicationPackageAlias( + const GURL& alias, + const GURL& content_handler_package, + const std::string& qualifier); + + private: + using ApplicationPackagedAlias = std::map<GURL, std::pair<GURL, std::string>>; + using MimeTypeToURLMap = std::map<std::string, GURL>; + + // Overridden from shell::PackageManager: + void SetApplicationManager(shell::ApplicationManager* manager) override; + GURL ResolveURL(const GURL& url) override; + void FetchRequest( + URLRequestPtr request, + const shell::Fetcher::FetchCallback& loader_callback) override; + bool HandleWithContentHandler(shell::Fetcher* fetcher, + const GURL& unresolved_url, + base::TaskRunner* task_runner, + URLResponsePtr* new_response, + GURL* content_handler_url, + std::string* qualifier) override; + + + shell::ApplicationManager* application_manager_; + scoped_ptr<fetcher::URLResolver> url_resolver_; + const bool disable_cache_; + NetworkServicePtr network_service_; + URLLoaderFactoryPtr url_loader_factory_; + ApplicationPackagedAlias application_package_alias_; + MimeTypeToURLMap mime_type_to_url_; + + DISALLOW_COPY_AND_ASSIGN(PackageManagerImpl); +}; + +} // namespace package_manager +} // namespace mojo + +#endif // MOJO_PACKAGE_MANAGER_PACKAGE_MANAGER_IMPL_H_ diff --git a/mojo/runner/BUILD.gn b/mojo/runner/BUILD.gn index f58a23f..5488248 100644 --- a/mojo/runner/BUILD.gn +++ b/mojo/runner/BUILD.gn @@ -123,8 +123,8 @@ source_set("lib") { "//components/devtools_service/public/interfaces", "//mojo/application/public/cpp", "//mojo/common:tracing_impl", - "//mojo/fetcher", "//mojo/message_pump", + "//mojo/package_manager", "//mojo/services/network/public/interfaces", "//mojo/services/tracing/public/cpp", "//mojo/services/tracing/public/interfaces", @@ -441,6 +441,7 @@ test("mojo_runner_unittests") { "//mojo/environment:chromium", "//mojo/fetcher", "//mojo/message_pump", + "//mojo/package_manager", "//mojo/services/test_service:bindings", "//mojo/shell", "//mojo/util:filename_util", diff --git a/mojo/runner/context.cc b/mojo/runner/context.cc index fc312bf..a1e5989 100644 --- a/mojo/runner/context.cc +++ b/mojo/runner/context.cc @@ -29,7 +29,7 @@ #include "mojo/common/tracing_impl.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/simple_platform_support.h" -#include "mojo/fetcher/base_application_fetcher.h" +#include "mojo/package_manager/package_manager_impl.h" #include "mojo/runner/in_process_native_runner.h" #include "mojo/runner/out_of_process_native_runner.h" #include "mojo/runner/switches.h" @@ -59,7 +59,7 @@ class Setup { DISALLOW_COPY_AND_ASSIGN(Setup); }; -void InitContentHandlers(shell::ApplicationManager* manager, +void InitContentHandlers(package_manager::PackageManagerImpl* manager, const base::CommandLine& command_line) { // Default content handlers. manager->RegisterContentHandler("application/pdf", GURL("mojo:pdf_viewer")); @@ -162,9 +162,7 @@ class TracingServiceProvider : public ServiceProvider { } // namespace Context::Context(const base::FilePath& shell_file_root) - : application_manager_(new shell::ApplicationManager(make_scoped_ptr( - new fetcher::BaseApplicationFetcher(shell_file_root)))), - main_entry_time_(base::Time::Now()) {} + : shell_file_root_(shell_file_root), main_entry_time_(base::Time::Now()) {} Context::~Context() { DCHECK(!base::MessageLoop::current()); @@ -190,6 +188,12 @@ bool Context::Init() { embedder::ProcessType::NONE, task_runners_->shell_runner(), this, task_runners_->io_runner(), embedder::ScopedPlatformHandle()); + package_manager_ = new package_manager::PackageManagerImpl(shell_file_root_); + InitContentHandlers(package_manager_, command_line); + + application_manager_.reset( + new shell::ApplicationManager(make_scoped_ptr(package_manager_))); + scoped_ptr<shell::NativeRunnerFactory> runner_factory; if (command_line.HasSwitch(switches::kEnableMultiprocess)) runner_factory.reset(new OutOfProcessNativeRunnerFactory(this)); @@ -198,8 +202,6 @@ bool Context::Init() { application_manager_->set_blocking_pool(task_runners_->blocking_pool()); application_manager_->set_native_runner_factory(runner_factory.Pass()); - InitContentHandlers(application_manager_.get(), command_line); - ServiceProviderPtr service_provider_ptr; ServiceProviderPtr tracing_service_provider_ptr; new TracingServiceProvider(GetProxy(&tracing_service_provider_ptr)); diff --git a/mojo/runner/context.h b/mojo/runner/context.h index 52537666..5667385 100644 --- a/mojo/runner/context.h +++ b/mojo/runner/context.h @@ -18,6 +18,9 @@ #include "url/gurl.h" namespace mojo { +namespace package_manager { +class PackageManagerImpl; +} namespace runner { class NativeApplicationLoader; @@ -52,6 +55,10 @@ class Context : public embedder::ProcessDelegate { return application_manager_.get(); } + package_manager::PackageManagerImpl* package_manager() { + return package_manager_; + } + private: class NativeViewportApplicationLoader; @@ -63,6 +70,9 @@ class Context : public embedder::ProcessDelegate { ScopedUserDataDir scoped_user_data_dir; std::set<GURL> app_urls_; scoped_ptr<TaskRunners> task_runners_; + base::FilePath shell_file_root_; + // Owned by |application_manager_|. + package_manager::PackageManagerImpl* package_manager_; scoped_ptr<shell::ApplicationManager> application_manager_; base::Closure app_complete_callback_; base::Time main_entry_time_; diff --git a/mojo/runner/native_runner_unittest.cc b/mojo/runner/native_runner_unittest.cc index 5dba563..bfb77b8 100644 --- a/mojo/runner/native_runner_unittest.cc +++ b/mojo/runner/native_runner_unittest.cc @@ -4,7 +4,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/path_service.h" -#include "mojo/fetcher/base_application_fetcher.h" #include "mojo/runner/context.h" #include "mojo/shell/application_manager.h" #include "mojo/util/filename_util.h" diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn index 8b98e93..38fca1e 100644 --- a/mojo/shell/BUILD.gn +++ b/mojo/shell/BUILD.gn @@ -8,7 +8,6 @@ import("//testing/test.gni") source_set("shell") { output_name = "mojo_shell" sources = [ - "application_fetcher.h", "application_instance.cc", "application_instance.h", "application_loader.h", @@ -27,6 +26,7 @@ source_set("shell") { "identity.cc", "identity.h", "native_runner.h", + "package_manager.h", "query_util.cc", "query_util.h", "static_application_loader.cc", @@ -60,6 +60,8 @@ test("mojo_shell_unittests") { "application_manager_unittest.cc", "capability_filter_unittest.cc", "query_util_unittest.cc", + "test_package_manager.cc", + "test_package_manager.h", ] deps = [ diff --git a/mojo/shell/application_fetcher.h b/mojo/shell/application_fetcher.h deleted file mode 100644 index 4f88001..0000000 --- a/mojo/shell/application_fetcher.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_SHELL_APPLICATION_FETCHER_H_ -#define MOJO_SHELL_APPLICATION_FETCHER_H_ - -#include "mojo/shell/fetcher.h" -#include "mojo/services/network/public/interfaces/url_loader.mojom.h" - -class GURL; - -namespace mojo { -namespace shell { - -class ApplicationManager; - -// A class implementing this interface assists Shell::ConnectToApplication in -// resolving URLs and fetching the applications located therein. -class ApplicationFetcher { - public: - virtual ~ApplicationFetcher() {} - - // Called once, during initialization, to tell the fetcher about the - // associated ApplicationManager. - virtual void SetApplicationManager(ApplicationManager* manager) = 0; - - // Resolves |url| to its canonical form. e.g. for mojo: urls, returns a file: - // url with a path ending in .mojo. - virtual GURL ResolveURL(const GURL& url) = 0; - - // Asks the delegate to fetch the specified url. |url| must be unresolved, - // i.e. ResolveURL() above must not have been called on it. - // TODO(beng): figure out how not to expose Fetcher at all at this layer. - virtual void FetchRequest( - URLRequestPtr request, - const Fetcher::FetchCallback& loader_callback) = 0; -}; - -} // namespace shell -} // namespace mojo - -#endif // MOJO_SHELL_APPLICATION_FETCHER_H_ diff --git a/mojo/shell/application_manager.cc b/mojo/shell/application_manager.cc index 934ea7d..d520304 100644 --- a/mojo/shell/application_manager.cc +++ b/mojo/shell/application_manager.cc @@ -13,10 +13,10 @@ #include "base/trace_event/trace_event.h" #include "mojo/application/public/interfaces/content_handler.mojom.h" #include "mojo/public/cpp/bindings/binding.h" -#include "mojo/shell/application_fetcher.h" #include "mojo/shell/application_instance.h" #include "mojo/shell/content_handler_connection.h" #include "mojo/shell/fetcher.h" +#include "mojo/shell/package_manager.h" #include "mojo/shell/query_util.h" #include "mojo/shell/switches.h" @@ -50,11 +50,12 @@ bool ApplicationManager::TestAPI::HasRunningInstanceForURL( manager_->identity_to_instance_.end(); } -ApplicationManager::ApplicationManager(scoped_ptr<ApplicationFetcher> fetcher) - : fetcher_(fetcher.Pass()), +ApplicationManager::ApplicationManager( + scoped_ptr<PackageManager> package_manager) + : package_manager_(package_manager.Pass()), content_handler_id_counter_(0u), weak_ptr_factory_(this) { - fetcher_->SetApplicationManager(this); + package_manager_->SetApplicationManager(this); } ApplicationManager::~ApplicationManager() { @@ -107,7 +108,7 @@ void ApplicationManager::ConnectToApplication( if (ConnectToRunningApplication(¶ms)) return; - GURL resolved_url = fetcher_->ResolveURL(original_url); + GURL resolved_url = package_manager_->ResolveURL(original_url); params->SetURLInfo(resolved_url); if (ConnectToRunningApplication(¶ms)) return; @@ -126,7 +127,7 @@ void ApplicationManager::ConnectToApplication( auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms)); - fetcher_->FetchRequest(original_url_request.Pass(), callback); + package_manager_->FetchRequest(original_url_request.Pass(), callback); } bool ApplicationManager::ConnectToRunningApplication( @@ -226,85 +227,39 @@ void ApplicationManager::HandleFetchCallback( ApplicationInstance* app = nullptr; InterfaceRequest<Application> request(RegisterInstance(params.Pass(), &app)); - // For resources that are loaded with content handlers, we group app instances - // by site. - // If the response begins with a #!mojo <content-handler-url>, use it. GURL content_handler_url; - std::string shebang; - // TODO(beng): it seems like some delegate should/would want to have a say in - // configuring the qualifier also. - bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableMultiprocess); - - if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { - URLResponsePtr response(fetcher->AsURLResponse( - blocking_pool_, static_cast<int>(shebang.size()))); - std::string site = - enable_multi_process ? response->site.To<std::string>() : std::string(); + URLResponsePtr new_response; + if (package_manager_->HandleWithContentHandler(fetcher.get(), + app_url, + blocking_pool_, + &new_response, + &content_handler_url, + &qualifier)) { LoadWithContentHandler(originator_identity, originator_filter, - content_handler_url, site, filter, connect_callback, - app, request.Pass(), response.Pass()); - return; - } - - MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); - if (iter != mime_type_to_url_.end()) { - URLResponsePtr response(fetcher->AsURLResponse(blocking_pool_, 0)); - std::string site = - enable_multi_process ? response->site.To<std::string>() : std::string(); - LoadWithContentHandler(originator_identity, originator_filter, iter->second, - site, filter, connect_callback, app, request.Pass(), - response.Pass()); - 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 = app_url.spec(); - - 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 ApplicationRunner 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; + content_handler_url, qualifier, filter, + connect_callback, app, request.Pass(), + new_response.Pass()); + } else { + // TODO(erg): Have a better way of switching the sandbox on. For now, switch + // it on hard coded when we're using some of the sandboxable core services. + bool start_sandboxed = false; + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMojoNoSandbox)) { + if (app_url == GURL("mojo://core_services/") && qualifier == "Core") + start_sandboxed = true; + else if (app_url == GURL("mojo://html_viewer/")) + start_sandboxed = true; } - LoadWithContentHandler(originator_identity, originator_filter, - alias_iter->second.first, qualifier, filter, - connect_callback, app, request.Pass(), - response.Pass()); - return; - } + connect_callback.Run(Shell::kInvalidContentHandlerID); - // TODO(erg): Have a better way of switching the sandbox on. For now, switch - // it on hard coded when we're using some of the sandboxable core services. - bool start_sandboxed = false; - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kMojoNoSandbox)) { - if (app_url == GURL("mojo://core_services/") && qualifier == "Core") - start_sandboxed = true; - else if (app_url == GURL("mojo://html_viewer/")) - start_sandboxed = true; + fetcher->AsPath(blocking_pool_, + base::Bind(&ApplicationManager::RunNativeApplication, + weak_ptr_factory_.GetWeakPtr(), + base::Passed(request.Pass()), start_sandboxed, + base::Passed(fetcher.Pass()))); } - - connect_callback.Run(Shell::kInvalidContentHandlerID); - - fetcher->AsPath(blocking_pool_, - base::Bind(&ApplicationManager::RunNativeApplication, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(request.Pass()), start_sandboxed, - base::Passed(fetcher.Pass()))); } void ApplicationManager::RunNativeApplication( @@ -333,22 +288,6 @@ void ApplicationManager::RunNativeApplication( weak_ptr_factory_.GetWeakPtr(), runner)); } -void ApplicationManager::RegisterContentHandler( - const std::string& mime_type, - const GURL& content_handler_url) { - DCHECK(content_handler_url.is_valid()) - << "Content handler URL is invalid for mime type " << mime_type; - mime_type_to_url_[mime_type] = content_handler_url; -} - -void ApplicationManager::RegisterApplicationPackageAlias( - const GURL& alias, - const GURL& content_handler_package, - const std::string& qualifier) { - application_package_alias_[alias] = - std::make_pair(content_handler_package, qualifier); -} - void ApplicationManager::LoadWithContentHandler( const Identity& originator_identity, const CapabilityFilter& originator_filter, diff --git a/mojo/shell/application_manager.h b/mojo/shell/application_manager.h index b0c742f..0ec2a6e 100644 --- a/mojo/shell/application_manager.h +++ b/mojo/shell/application_manager.h @@ -33,7 +33,7 @@ class SequencedWorkerPool; namespace mojo { namespace shell { -class ApplicationFetcher; +class PackageManager; class ApplicationInstance; class ContentHandlerConnection; @@ -55,7 +55,7 @@ class ApplicationManager { DISALLOW_COPY_AND_ASSIGN(TestAPI); }; - explicit ApplicationManager(scoped_ptr<ApplicationFetcher> fetcher); + explicit ApplicationManager(scoped_ptr<PackageManager> package_manager); ~ApplicationManager(); // Loads a service if necessary and establishes a new client connection. @@ -86,19 +86,6 @@ class ApplicationManager { ptr->Bind(InterfacePtrInfo<Interface>(service_handle.Pass(), 0u)); } - void RegisterContentHandler(const std::string& mime_type, - const GURL& content_handler_url); - - // Registers a package alias. When attempting to load |alias|, it will - // instead redirect to |content_handler_package|, which is a content handler - // which will be passed the |alias| as the URLResponse::url. Different values - // of |alias| with the same |qualifier| that are in the same - // |content_handler_package| will run in the same process in multi-process - // mode. - void RegisterApplicationPackageAlias(const GURL& alias, - const GURL& content_handler_package, - const std::string& qualifier); - // Sets the default Loader to be used if not overridden by SetLoaderForURL(). void set_default_loader(scoped_ptr<ApplicationLoader> loader) { default_loader_ = loader.Pass(); @@ -128,10 +115,8 @@ class ApplicationManager { ApplicationInstance* GetApplicationInstance(const Identity& identity) const; private: - using ApplicationPackagedAlias = std::map<GURL, std::pair<GURL, std::string>>; using IdentityToApplicationInstanceMap = std::map<Identity, ApplicationInstance*>; - using MimeTypeToURLMap = std::map<std::string, GURL>; using URLToContentHandlerMap = std::map<std::pair<GURL, std::string>, ContentHandlerConnection*>; using URLToLoaderMap = std::map<GURL, ApplicationLoader*>; @@ -185,20 +170,18 @@ class ApplicationManager { const GURL& application_url, const std::string& interface_name); - scoped_ptr<ApplicationFetcher> const fetcher_; + scoped_ptr<PackageManager> const package_manager_; // Loader management. // Loaders are chosen in the order they are listed here. URLToLoaderMap url_to_loader_; scoped_ptr<ApplicationLoader> default_loader_; scoped_ptr<NativeRunnerFactory> native_runner_factory_; - ApplicationPackagedAlias application_package_alias_; IdentityToApplicationInstanceMap identity_to_instance_; URLToContentHandlerMap url_to_content_handler_; base::SequencedWorkerPool* blocking_pool_; updater::UpdaterPtr updater_; - MimeTypeToURLMap mime_type_to_url_; ScopedVector<NativeRunner> native_runners_; // Counter used to assign ids to content_handlers. uint32_t content_handler_id_counter_; diff --git a/mojo/shell/application_manager_unittest.cc b/mojo/shell/application_manager_unittest.cc index 644c965..77a959c 100644 --- a/mojo/shell/application_manager_unittest.cc +++ b/mojo/shell/application_manager_unittest.cc @@ -15,11 +15,11 @@ #include "mojo/application/public/interfaces/content_handler.mojom.h" #include "mojo/application/public/interfaces/service_provider.mojom.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/shell/application_fetcher.h" #include "mojo/shell/application_loader.h" #include "mojo/shell/application_manager.h" #include "mojo/shell/fetcher.h" #include "mojo/shell/test.mojom.h" +#include "mojo/shell/test_package_manager.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { @@ -456,13 +456,13 @@ class Tester : public ApplicationDelegate, ScopedVector<TestAImpl> a_bindings_; }; -class TestApplicationFetcher : public ApplicationFetcher { +class AMTestPackageManager : public TestPackageManager { public: - TestApplicationFetcher() + AMTestPackageManager() : create_test_fetcher_(false), fetcher_url_("xxx"), mime_type_(kTestMimeType) {} - ~TestApplicationFetcher() override {} + ~AMTestPackageManager() override {} void set_create_test_fetcher(bool create_test_fetcher) { create_test_fetcher_ = create_test_fetcher; @@ -472,8 +472,7 @@ class TestApplicationFetcher : public ApplicationFetcher { void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; } - // ApplicationManager::Delegate - void SetApplicationManager(ApplicationManager* manager) override {} + // TestPackageManager: GURL ResolveURL(const GURL& url) override { GURL resolved_url = url; // The shell automatically map mojo URLs. @@ -495,7 +494,7 @@ class TestApplicationFetcher : public ApplicationFetcher { GURL fetcher_url_; std::string mime_type_; - DISALLOW_COPY_AND_ASSIGN(TestApplicationFetcher); + DISALLOW_COPY_AND_ASSIGN(AMTestPackageManager); }; class ApplicationManagerTest : public testing::Test { @@ -506,7 +505,7 @@ class ApplicationManagerTest : public testing::Test { void SetUp() override { application_manager_.reset(new ApplicationManager( - make_scoped_ptr(new TestApplicationFetcher))); + make_scoped_ptr(new AMTestPackageManager))); test_loader_ = new TestApplicationLoader; test_loader_->set_context(&context_); application_manager_->set_default_loader( @@ -563,7 +562,7 @@ TEST_F(ApplicationManagerTest, ClientError) { TEST_F(ApplicationManagerTest, Deletes) { { - ApplicationManager am(make_scoped_ptr(new TestApplicationFetcher)); + ApplicationManager am(make_scoped_ptr(new AMTestPackageManager)); TestApplicationLoader* default_loader = new TestApplicationLoader; default_loader->set_context(&context_); TestApplicationLoader* url_loader1 = new TestApplicationLoader; @@ -709,13 +708,13 @@ TEST(ApplicationManagerTest2, ContentHandlerConnectionGetsRequestorURL) { const GURL requestor_url("http://requestor.url"); TestContext test_context; base::MessageLoop loop; - scoped_ptr<TestApplicationFetcher> test_application_fetcher( - new TestApplicationFetcher); - test_application_fetcher->set_create_test_fetcher(true); - ApplicationManager application_manager(test_application_fetcher.Pass()); + scoped_ptr<AMTestPackageManager> test_package_manager( + new AMTestPackageManager); + test_package_manager->set_create_test_fetcher(true); + test_package_manager->RegisterContentHandler(kTestMimeType, + content_handler_url); + ApplicationManager application_manager(test_package_manager.Pass()); application_manager.set_default_loader(nullptr); - application_manager.RegisterContentHandler(kTestMimeType, - content_handler_url); TestApplicationLoader* loader = new TestApplicationLoader; loader->set_context(&test_context); @@ -775,14 +774,14 @@ TEST(ApplicationManagerTest2, const GURL content_handler_url("http://test.content.handler"); const GURL requestor_url("http://requestor.url"); TestContext test_context; - scoped_ptr<TestApplicationFetcher> test_application_fetcher( - new TestApplicationFetcher); - test_application_fetcher->set_fetcher_url(GURL("test:test")); - test_application_fetcher->set_create_test_fetcher(true); - ApplicationManager application_manager(test_application_fetcher.Pass()); + scoped_ptr<AMTestPackageManager> test_package_manager( + new AMTestPackageManager); + test_package_manager->set_fetcher_url(GURL("test:test")); + test_package_manager->set_create_test_fetcher(true); + test_package_manager->RegisterContentHandler(kTestMimeType, + content_handler_url); + ApplicationManager application_manager(test_package_manager.Pass()); application_manager.set_default_loader(nullptr); - application_manager.RegisterContentHandler(kTestMimeType, - content_handler_url); TestApplicationLoader* content_handler_loader = new TestApplicationLoader; content_handler_loader->set_create_content_handler(true); @@ -834,14 +833,13 @@ TEST(ApplicationManagerTest2, DifferedContentHandlersGetDifferentIDs) { const GURL content_handler_url("http://test.content.handler"); const GURL requestor_url("http://requestor.url"); TestContext test_context; - TestApplicationFetcher* test_application_fetcher = new TestApplicationFetcher; - test_application_fetcher->set_fetcher_url(GURL("test:test")); - test_application_fetcher->set_create_test_fetcher(true); - ApplicationManager application_manager( - make_scoped_ptr(test_application_fetcher)); + AMTestPackageManager* test_package_manager = new AMTestPackageManager; + test_package_manager->set_fetcher_url(GURL("test:test")); + test_package_manager->set_create_test_fetcher(true); + test_package_manager->RegisterContentHandler(kTestMimeType, + content_handler_url); + ApplicationManager application_manager(make_scoped_ptr(test_package_manager)); application_manager.set_default_loader(nullptr); - application_manager.RegisterContentHandler(kTestMimeType, - content_handler_url); TestApplicationLoader* content_handler_loader = new TestApplicationLoader; content_handler_loader->set_create_content_handler(true); @@ -870,9 +868,10 @@ TEST(ApplicationManagerTest2, DifferedContentHandlersGetDifferentIDs) { const std::string mime_type2("test/mime-type2"); const GURL content_handler_url2("http://test.content2.handler"); - test_application_fetcher->set_fetcher_url(GURL("test2:test2")); - test_application_fetcher->set_mime_type(mime_type2); - application_manager.RegisterContentHandler(mime_type2, content_handler_url2); + test_package_manager->set_fetcher_url(GURL("test2:test2")); + test_package_manager->set_mime_type(mime_type2); + test_package_manager->RegisterContentHandler(mime_type2, + content_handler_url2); TestApplicationLoader* content_handler_loader2 = new TestApplicationLoader; content_handler_loader->set_create_content_handler(true); diff --git a/mojo/shell/capability_filter_unittest.cc b/mojo/shell/capability_filter_unittest.cc index a659d42..0c33a8f 100644 --- a/mojo/shell/capability_filter_unittest.cc +++ b/mojo/shell/capability_filter_unittest.cc @@ -18,10 +18,10 @@ #include "mojo/application/public/interfaces/content_handler.mojom.h" #include "mojo/common/weak_binding_set.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/shell/application_fetcher.h" #include "mojo/shell/application_loader.h" #include "mojo/shell/application_manager.h" #include "mojo/shell/capability_filter_unittest.mojom.h" +#include "mojo/shell/test_package_manager.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { @@ -285,21 +285,17 @@ class TestFetcher : public Fetcher { DISALLOW_COPY_AND_ASSIGN(TestFetcher); }; -class TestApplicationFetcher : public ApplicationFetcher { +class CFTestPackageManager : public TestPackageManager { public: - TestApplicationFetcher() {} - ~TestApplicationFetcher() override {} + CFTestPackageManager() {} + ~CFTestPackageManager() override {} void set_use_test_fetcher(bool use_test_fetcher) { use_test_fetcher_ = use_test_fetcher; } private: - // Overridden from ApplicationFetcher: - void SetApplicationManager(ApplicationManager* manager) override {} - GURL ResolveURL(const GURL& url) override { - return url; - } + // Overridden from TestPackageManager: void FetchRequest(URLRequestPtr request, const Fetcher::FetchCallback& loader_callback) override { if (use_test_fetcher_) @@ -308,7 +304,7 @@ class TestApplicationFetcher : public ApplicationFetcher { bool use_test_fetcher_; - DISALLOW_COPY_AND_ASSIGN(TestApplicationFetcher); + DISALLOW_COPY_AND_ASSIGN(CFTestPackageManager); }; class TestLoader : public ApplicationLoader { @@ -331,7 +327,7 @@ class TestLoader : public ApplicationLoader { class CapabilityFilterTest : public testing::Test { public: CapabilityFilterTest() - : test_application_fetcher_(nullptr), + : test_package_manager_(nullptr), validator_(nullptr) {} ~CapabilityFilterTest() override {} @@ -376,7 +372,7 @@ class CapabilityFilterTest : public testing::Test { set_use_test_fetcher(); GURL content_handler_url("test:content_handler"); - application_manager()->RegisterContentHandler(kTestMimeType, + test_package_manager_->RegisterContentHandler(kTestMimeType, content_handler_url); CreateLoader<TestContentHandler>(content_handler_url.spec()); @@ -389,20 +385,20 @@ class CapabilityFilterTest : public testing::Test { } ConnectionValidator* validator() { return validator_; } void set_use_test_fetcher() { - test_application_fetcher_->set_use_test_fetcher(true); + test_package_manager_->set_use_test_fetcher(true); } // Overridden from testing::Test: void SetUp() override { - test_application_fetcher_ = new TestApplicationFetcher; + test_package_manager_ = new CFTestPackageManager; application_manager_.reset( - new ApplicationManager(make_scoped_ptr(test_application_fetcher_))); + new ApplicationManager(make_scoped_ptr(test_package_manager_))); CreateLoader<ServiceApplication>("test:service"); CreateLoader<ServiceApplication>("test:service2"); } void TearDown() override { application_manager_.reset(); - test_application_fetcher_->set_use_test_fetcher(false); + test_package_manager_->set_use_test_fetcher(false); } private: @@ -411,7 +407,7 @@ class CapabilityFilterTest : public testing::Test { return scoped_ptr<ApplicationDelegate>(new T); } - TestApplicationFetcher* test_application_fetcher_; + CFTestPackageManager* test_package_manager_; base::ShadowingAtExitManager at_exit_; base::MessageLoop loop_; scoped_ptr<ApplicationManager> application_manager_; diff --git a/mojo/shell/package_manager.h b/mojo/shell/package_manager.h new file mode 100644 index 0000000..ffd84cd --- /dev/null +++ b/mojo/shell/package_manager.h @@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SHELL_PACKAGE_MANAGER_H_ +#define MOJO_SHELL_PACKAGE_MANAGER_H_ + +#include "mojo/services/network/public/interfaces/url_loader.mojom.h" +#include "mojo/shell/fetcher.h" + +class GURL; + +namespace mojo { +namespace shell { + +class ApplicationManager; + +// A class implementing this interface assists Shell::ConnectToApplication in +// resolving URLs and fetching the applications located therein. +class PackageManager { + public: + PackageManager() {} + virtual ~PackageManager() {} + + // Called once, during initialization, to tell the package manager about the + // associated ApplicationManager. + virtual void SetApplicationManager(ApplicationManager* manager) = 0; + + // Resolves |url| to its canonical form. e.g. for mojo: urls, returns a file: + // url with a path ending in .mojo. + virtual GURL ResolveURL(const GURL& url) = 0; + + // Asks the delegate to fetch the specified url. |url| must be unresolved, + // i.e. ResolveURL() above must not have been called on it. + // TODO(beng): figure out how not to expose Fetcher at all at this layer. + virtual void FetchRequest( + URLRequestPtr request, + const Fetcher::FetchCallback& loader_callback) = 0; + + // Determine if a content handler should handle the response received by + // |fetcher|. + // |unresolved_url| is the url requested initially by a call to + // Shell::ConnectToApplication() before any resolution is applied. + // |task_runner| is a base::TaskRunner* that can be used to post callbacks. + // |new_response| is the response that should be passed to + // ContentHandler::StartApplication(), unchanged if the return value is false. + // |content_handler_url| is the url of the content handler application to + // run, unchanged if the return value is false. + // |qualifier| is the Identity qualifier that the content handler application + // instance should be associated with, unchanged if the return value is false. + virtual bool HandleWithContentHandler(Fetcher* fetcher, + const GURL& unresolved_url, + base::TaskRunner* task_runner, + URLResponsePtr* new_response, + GURL* content_handler_url, + std::string* qualifier) = 0; +}; + +} // namespace shell +} // namespace mojo + +#endif // MOJO_SHELL_PACKAGE_MANAGER_H_ diff --git a/mojo/shell/test_package_manager.cc b/mojo/shell/test_package_manager.cc new file mode 100644 index 0000000..726d3c8 --- /dev/null +++ b/mojo/shell/test_package_manager.cc @@ -0,0 +1,54 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/shell/test_package_manager.h" + +#include "base/logging.h" +#include "mojo/shell/fetcher.h" +#include "url/gurl.h" + +namespace mojo { +namespace shell { + +TestPackageManager::TestPackageManager() {} +TestPackageManager::~TestPackageManager() {} + +void TestPackageManager::RegisterContentHandler( + const std::string& mime_type, + const GURL& content_handler_url) { + DCHECK(content_handler_url.is_valid()) + << "Content handler URL is invalid for mime type " << mime_type; + mime_type_to_url_[mime_type] = content_handler_url; +} + +void TestPackageManager::SetApplicationManager(ApplicationManager* manager) { +} + +GURL TestPackageManager::ResolveURL(const GURL& url) { + return url; +} + +void TestPackageManager::FetchRequest( + URLRequestPtr request, + const Fetcher::FetchCallback& loader_callback) {} + +bool TestPackageManager::HandleWithContentHandler( + Fetcher* fetcher, + const GURL& unresolved_url, + base::TaskRunner* task_runner, + URLResponsePtr* new_response, + GURL* content_handler_url, + std::string* qualifier) { + MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); + if (iter != mime_type_to_url_.end()) { + *new_response = fetcher->AsURLResponse(task_runner, 0); + *content_handler_url = iter->second; + *qualifier = (*new_response)->site.To<std::string>(); + return true; + } + return false; +} + +} // namespace shell +} // namespace mojo diff --git a/mojo/shell/test_package_manager.h b/mojo/shell/test_package_manager.h new file mode 100644 index 0000000..6a3e29f --- /dev/null +++ b/mojo/shell/test_package_manager.h @@ -0,0 +1,52 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SHELL_TEST_PACKAGE_MANAGER_H_ +#define MOJO_SHELL_TEST_PACKAGE_MANAGER_H_ + +#include <map> +#include <string> + +#include "mojo/shell/package_manager.h" + +class GURL; + +namespace mojo { +namespace shell { + +// An implementation of PackageManager used by tests to support content handler +// registration for MIME types. +class TestPackageManager : public PackageManager { + public: + TestPackageManager(); + virtual ~TestPackageManager(); + + void RegisterContentHandler(const std::string& mime_type, + const GURL& content_handler_url); + + private: + using MimeTypeToURLMap = std::map<std::string, GURL>; + + // Overridden from PackageManager: + void SetApplicationManager(ApplicationManager* manager) override; + GURL ResolveURL(const GURL& url) override; + void FetchRequest( + URLRequestPtr request, + const Fetcher::FetchCallback& loader_callback) override; + bool HandleWithContentHandler(Fetcher* fetcher, + const GURL& unresolved_url, + base::TaskRunner* task_runner, + URLResponsePtr* new_response, + GURL* content_handler_url, + std::string* qualifier) override; + + MimeTypeToURLMap mime_type_to_url_; + + DISALLOW_COPY_AND_ASSIGN(TestPackageManager); +}; + +} // namespace shell +} // namespace mojo + +#endif // MOJO_SHELL_TEST_PACKAGE_MANAGER_H_ |