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

Unified Diff: mojo/shell/dynamic_service_loader.cc

Issue 323593002: Mojo: Use network service to load non-local Mojo Apps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 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/in_process_dynamic_service_runner.h » ('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 b249c3cff31c70769160eac16d71ace46df80426..16ed3162e1b8e7cf3c55e7a651616d68cf91b063 100644
--- a/mojo/shell/dynamic_service_loader.cc
+++ b/mojo/shell/dynamic_service_loader.cc
@@ -4,83 +4,137 @@
#include "mojo/shell/dynamic_service_loader.h"
-#include "base/location.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/common/data_pipe_utils.h"
+#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
#include "mojo/shell/context.h"
#include "mojo/shell/keep_alive.h"
+#include "mojo/shell/switches.h"
+#include "net/base/filename_util.h"
namespace mojo {
namespace shell {
-
namespace {
-std::string MakeSharedLibraryName(const std::string& file_name) {
-#if defined(OS_WIN)
- return file_name + ".dll";
-#elif defined(OS_LINUX)
- return "lib" + file_name + ".so";
-#elif defined(OS_MACOSX)
- return "lib" + file_name + ".dylib";
-#else
- NOTREACHED() << "dynamic loading of services not supported";
- return std::string();
-#endif
-}
+class Loader {
+ public:
+ explicit Loader(scoped_ptr<DynamicServiceRunner> runner)
+ : runner_(runner.Pass()) {
+ }
-} // namespace
+ virtual void Start(const GURL& url,
+ ScopedMessagePipeHandle service_handle,
+ Context* context) = 0;
-class DynamicServiceLoader::LoadContext : public mojo::shell::Loader::Delegate {
- public:
- LoadContext(DynamicServiceLoader* loader,
- const GURL& url,
- ScopedMessagePipeHandle service_handle,
- scoped_ptr<DynamicServiceRunner> runner)
- : loader_(loader),
- url_(url),
- service_handle_(service_handle.Pass()),
- runner_(runner.Pass()),
- keep_alive_(loader->context_) {
- GURL url_to_load;
-
- if (url.SchemeIs("mojo")) {
- std::string lib = MakeSharedLibraryName(url.ExtractFileName());
- url_to_load = GURL(loader->context_->mojo_origin() + "/" + lib);
+ 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 {
- url_to_load = url;
+ 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()) {
+ }
- request_ = loader_->context_->loader()->Load(url_to_load, this);
+ virtual void Start(const GURL& url,
+ ScopedMessagePipeHandle service_handle,
+ Context* context) OVERRIDE {
+ base::FilePath path;
+ net::FileURLToFilePath(url, &path);
+
+ // TODO(darin): Check if the given file path exists.
+
+ // Complete asynchronously for consistency with NetworkServiceLoader.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&Loader::StartService,
+ base::Unretained(this),
+ path,
+ base::Passed(&service_handle),
+ true));
}
+};
- virtual ~LoadContext() {
+// For loading services via the network stack.
+class NetworkLoader : public Loader, public URLLoaderClient {
+ public:
+ explicit NetworkLoader(scoped_ptr<DynamicServiceRunner> runner,
+ NetworkService* network_service)
+ : Loader(runner.Pass()) {
+ network_service->CreateURLLoader(Get(&url_loader_));
+ url_loader_.set_client(this);
+ }
+
+ virtual void Start(const GURL& url,
+ ScopedMessagePipeHandle service_handle,
+ Context* context) OVERRIDE {
+ service_handle_ = service_handle.Pass();
+
+ URLRequestPtr request(URLRequest::New());
+ request->url = url.spec();
+ request->follow_redirects = true;
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableCache)) {
+ request->bypass_cache = true;
+ }
+
+ DataPipe data_pipe;
+ url_loader_->Start(request.Pass(), data_pipe.producer_handle.Pass());
+
+ base::CreateTemporaryFile(&file_);
+ common::CopyToFile(data_pipe.consumer_handle.Pass(),
+ file_,
+ context->task_runners()->blocking_pool(),
+ base::Bind(&Loader::StartService,
+ base::Unretained(this),
+ file_,
+ base::Passed(&service_handle_)));
}
private:
- // |Loader::Delegate| method:
- virtual void DidCompleteLoad(const GURL& app_url,
- const base::FilePath& app_path,
- const std::string* mime_type) OVERRIDE {
- DVLOG(2) << "Completed load of " << app_url << " (" << url_ << ") to "
- << app_path.value();
- DCHECK(loader_->context_->task_runners()->ui_runner()->
- BelongsToCurrentThread());
-
- runner_->Start(
- app_path,
- service_handle_.Pass(),
- base::Bind(&DynamicServiceLoader::AppCompleted,
- base::Unretained(loader_), url_));
+ // URLLoaderClient methods:
+ virtual void OnReceivedRedirect(URLResponsePtr response,
+ const String& new_url,
+ const String& new_method) OVERRIDE {
+ // TODO(darin): Handle redirects properly!
}
+ virtual void OnReceivedResponse(URLResponsePtr response) OVERRIDE {}
+ virtual void OnReceivedError(NetworkErrorPtr error) OVERRIDE {}
+ virtual void OnReceivedEndOfResponseBody() OVERRIDE {}
- DynamicServiceLoader* const loader_;
- const GURL url_;
- scoped_ptr<mojo::shell::Loader::Job> request_;
+ NetworkServicePtr network_service_;
+ URLLoaderPtr url_loader_;
ScopedMessagePipeHandle service_handle_;
- scoped_ptr<DynamicServiceRunner> runner_;
- KeepAlive keep_alive_;
-
- DISALLOW_COPY_AND_ASSIGN(LoadContext);
+ base::FilePath file_;
};
+} // namespace
+
DynamicServiceLoader::DynamicServiceLoader(
Context* context,
scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
@@ -89,32 +143,38 @@ DynamicServiceLoader::DynamicServiceLoader(
}
DynamicServiceLoader::~DynamicServiceLoader() {
- DCHECK(url_to_load_context_.empty());
}
void DynamicServiceLoader::LoadService(ServiceManager* manager,
const GURL& url,
ScopedMessagePipeHandle service_handle) {
- DCHECK(url_to_load_context_.find(url) == url_to_load_context_.end());
- url_to_load_context_[url] = new LoadContext(
- this, url, service_handle.Pass(), runner_factory_->Create(context_));
+ scoped_ptr<DynamicServiceRunner> runner = runner_factory_->Create(context_);
+
+ GURL resolved_url;
+ if (url.SchemeIs("mojo")) {
+ resolved_url = context_->mojo_url_resolver()->Resolve(url);
+ } else {
+ resolved_url = url;
+ }
+
+ Loader* loader;
+ if (resolved_url.SchemeIsFile()) {
+ loader = new LocalLoader(runner.Pass());
+ } else {
+ if (!network_service_.get()) {
+ context_->service_manager()->ConnectTo(GURL("mojo:mojo_network_service"),
+ &network_service_,
+ GURL());
+ }
+ loader = new NetworkLoader(runner.Pass(), network_service_.get());
+ }
+ loader->Start(resolved_url, service_handle.Pass(), context_);
}
void DynamicServiceLoader::OnServiceError(ServiceManager* manager,
const GURL& url) {
-}
-
-void DynamicServiceLoader::AppCompleted(const GURL& url) {
- DCHECK(context_->task_runners()->ui_runner()->BelongsToCurrentThread());
- DVLOG(2) << "App completed (url: " << url << ")";
-
- LoadContextMap::iterator it = url_to_load_context_.find(url);
- DCHECK(it != url_to_load_context_.end()) << url;
-
- LoadContext* doomed = it->second;
- url_to_load_context_.erase(it);
-
- delete doomed;
+ // TODO(darin): What should we do about service errors? This implies that
+ // the app closed its handle to the service manager. Maybe we don't care?
}
} // namespace shell
« no previous file with comments | « mojo/shell/dynamic_service_loader.h ('k') | mojo/shell/in_process_dynamic_service_runner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698