| 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,
|
|
|