Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: mojo/shell/dynamic_service_loader.cc

Issue 423963004: First cut at "content handling" support in Mojo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more gn Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/shell/dynamic_service_loader.h ('k') | mojo/shell/dynamic_service_loader_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/shell/dynamic_service_loader.cc
diff --git a/mojo/shell/dynamic_service_loader.cc b/mojo/shell/dynamic_service_loader.cc
index a8e6914ae9e5a8bb3cd18ffa4e22dc51fd75b58d..73dd6dd47ef124dba99e7a33a1d3bcdfa621ad11 100644
--- a/mojo/shell/dynamic_service_loader.cc
+++ b/mojo/shell/dynamic_service_loader.cc
@@ -20,122 +20,15 @@
namespace mojo {
namespace shell {
-namespace {
-
-class Loader {
- public:
- explicit Loader(scoped_ptr<DynamicServiceRunner> runner)
- : runner_(runner.Pass()) {
- }
-
- virtual void Start(const GURL& url,
- ScopedMessagePipeHandle service_handle,
- Context* context) = 0;
-
- void StartService(const base::FilePath& path,
- ScopedMessagePipeHandle service_handle,
- bool path_is_valid) {
- if (path_is_valid) {
- runner_->Start(path, service_handle.Pass(),
- base::Bind(&Loader::AppCompleted, base::Unretained(this)));
- } else {
- AppCompleted();
- }
- }
-
- protected:
- virtual ~Loader() {}
-
- private:
- void AppCompleted() {
- delete this;
- }
-
- scoped_ptr<DynamicServiceRunner> runner_;
-};
-
-// For loading services via file:// URLs.
-class LocalLoader : public Loader {
- public:
- explicit LocalLoader(scoped_ptr<DynamicServiceRunner> runner)
- : Loader(runner.Pass()) {
- }
-
- virtual void Start(const GURL& url,
- ScopedMessagePipeHandle service_handle,
- Context* context) OVERRIDE {
- base::FilePath path;
- net::FileURLToFilePath(url, &path);
-
- // Complete asynchronously for consistency with NetworkServiceLoader.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&Loader::StartService,
- base::Unretained(this),
- path,
- base::Passed(&service_handle),
- base::PathExists(path)));
- }
-};
-
-// For loading services via the network stack.
-class NetworkLoader : public Loader {
- public:
- explicit NetworkLoader(scoped_ptr<DynamicServiceRunner> runner,
- NetworkService* network_service)
- : Loader(runner.Pass()) {
- network_service->CreateURLLoader(Get(&url_loader_));
- }
-
- virtual void Start(const GURL& url,
- ScopedMessagePipeHandle service_handle,
- Context* context) OVERRIDE {
- service_handle_ = service_handle.Pass();
- context_ = context;
-
- URLRequestPtr request(URLRequest::New());
- request->url = String::From(url);
- request->auto_follow_redirects = true;
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableCache)) {
- request->bypass_cache = true;
- }
-
- url_loader_->Start(request.Pass(),
- base::Bind(&NetworkLoader::OnReceivedResponse,
- base::Unretained(this)));
- }
-
- private:
- virtual ~NetworkLoader() {
- if (!file_.empty())
- base::DeleteFile(file_, false);
- }
- void OnReceivedResponse(URLResponsePtr response) {
- if (response->error) {
- LOG(ERROR) << "Error (" << response->error->code << ": "
- << response->error->description << ") while fetching "
- << response->url;
- }
-
- base::CreateTemporaryFile(&file_);
- common::CopyToFile(response->body.Pass(),
- file_,
- context_->task_runners()->blocking_pool(),
- base::Bind(&Loader::StartService,
- base::Unretained(this),
- file_,
- base::Passed(&service_handle_)));
- }
+namespace {
- Context* context_;
- NetworkServicePtr network_service_;
- URLLoaderPtr url_loader_;
- ScopedMessagePipeHandle service_handle_;
- base::FilePath file_;
-};
+void RunLibraryComplete(DynamicServiceRunner* runner,
+ const base::FilePath& temp_file) {
+ delete runner;
+ if (!temp_file.empty())
+ base::DeleteFile(temp_file, false);
+}
} // namespace
@@ -143,17 +36,22 @@ DynamicServiceLoader::DynamicServiceLoader(
Context* context,
scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
: context_(context),
- runner_factory_(runner_factory.Pass()) {
+ runner_factory_(runner_factory.Pass()),
+ weak_ptr_factory_(this) {
}
DynamicServiceLoader::~DynamicServiceLoader() {
}
-void DynamicServiceLoader::LoadService(ServiceManager* manager,
- const GURL& url,
- ScopedMessagePipeHandle shell_handle) {
- scoped_ptr<DynamicServiceRunner> runner = runner_factory_->Create(context_);
+void DynamicServiceLoader::RegisterContentHandler(
+ const std::string& mime_type,
+ const GURL& content_handler_url) {
+ mime_type_to_url_[mime_type] = content_handler_url;
+}
+void DynamicServiceLoader::Load(ServiceManager* manager,
+ const GURL& url,
+ scoped_refptr<LoadCallbacks> callbacks) {
GURL resolved_url;
if (url.SchemeIs("mojo")) {
resolved_url = context_->mojo_url_resolver()->Resolve(url);
@@ -161,18 +59,109 @@ void DynamicServiceLoader::LoadService(ServiceManager* manager,
resolved_url = url;
}
- Loader* loader;
- if (resolved_url.SchemeIsFile()) {
- loader = new LocalLoader(runner.Pass());
- } else {
- if (!network_service_) {
- context_->service_manager()->ConnectToService(
- GURL("mojo:mojo_network_service"),
- &network_service_);
- }
- loader = new NetworkLoader(runner.Pass(), network_service_.get());
+ if (resolved_url.SchemeIsFile())
+ LoadLocalService(resolved_url, callbacks);
+ else
+ LoadNetworkService(resolved_url, callbacks);
+}
+
+void DynamicServiceLoader::LoadLocalService(
+ const GURL& resolved_url,
+ scoped_refptr<LoadCallbacks> callbacks) {
+ base::FilePath path;
+ net::FileURLToFilePath(resolved_url, &path);
+ const bool kDeleteFileAfter = false;
+
+ // Async for consistency with network case.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&DynamicServiceLoader::RunLibrary,
+ weak_ptr_factory_.GetWeakPtr(),
+ path,
+ callbacks,
+ kDeleteFileAfter,
+ base::PathExists(path)));
+}
+
+void DynamicServiceLoader::LoadNetworkService(
+ const GURL& resolved_url,
+ scoped_refptr<LoadCallbacks> callbacks) {
+ if (!network_service_) {
+ context_->service_manager()->ConnectToService(
+ GURL("mojo:mojo_network_service"),
+ &network_service_);
}
- loader->Start(resolved_url, shell_handle.Pass(), context_);
+ if (!url_loader_)
+ network_service_->CreateURLLoader(Get(&url_loader_));
+
+ URLRequestPtr request(URLRequest::New());
+ request->url = String::From(resolved_url);
+ request->auto_follow_redirects = true;
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableCache)) {
+ request->bypass_cache = true;
+ }
+
+ url_loader_->Start(
+ request.Pass(),
+ base::Bind(&DynamicServiceLoader::OnLoadNetworkServiceComplete,
+ weak_ptr_factory_.GetWeakPtr(),
+ callbacks));
+}
+
+void DynamicServiceLoader::OnLoadNetworkServiceComplete(
+ scoped_refptr<LoadCallbacks> callbacks, URLResponsePtr response) {
+ if (response->error) {
+ LOG(ERROR) << "Error (" << response->error->code << ": "
+ << response->error->description << ") while fetching "
+ << response->url;
+ }
+
+ MimeTypeToURLMap::iterator iter =
+ mime_type_to_url_.find(response->mime_type);
+ if (iter != mime_type_to_url_.end()) {
+ callbacks->LoadWithContentHandler(iter->second, response.Pass());
+ return;
+ }
+
+ base::FilePath file;
+ base::CreateTemporaryFile(&file);
+
+ const bool kDeleteFileAfter = true;
+ common::CopyToFile(response->body.Pass(),
+ file,
+ context_->task_runners()->blocking_pool(),
+ base::Bind(&DynamicServiceLoader::RunLibrary,
+ weak_ptr_factory_.GetWeakPtr(),
+ file,
+ callbacks,
+ kDeleteFileAfter));
+}
+
+void DynamicServiceLoader::RunLibrary(const base::FilePath& path,
+ scoped_refptr<LoadCallbacks> callbacks,
+ bool delete_file_after,
+ bool path_exists) {
+ // TODO(aa): We need to create a runner, even if we're not going to use it,
+ // because it getting destroyed is what causes shell to shut down. If we don't
+ // create this, in the case where shell never successfully creates even one
+ // app, then shell will never shut down, because no runners are ever
+ // destroyed.
+ scoped_ptr<DynamicServiceRunner> runner(runner_factory_->Create(context_));
+ if (!path_exists)
+ return;
+
+ ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
+ if (!shell_handle.is_valid())
+ return;
+
+ DynamicServiceRunner* runner_raw = runner.release();
+ runner_raw->Start(path,
+ shell_handle.Pass(),
+ base::Bind(&RunLibraryComplete,
+ base::Unretained(runner_raw),
+ delete_file_after ? path : base::FilePath()));
}
void DynamicServiceLoader::OnServiceError(ServiceManager* manager,
« no previous file with comments | « mojo/shell/dynamic_service_loader.h ('k') | mojo/shell/dynamic_service_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698