This source file includes following definitions.
- MakeSharedLibraryName
- keep_alive_
- LoadContext
- DidCompleteLoad
- runner_factory_
- LoadService
- OnServiceError
- AppCompleted
#include "mojo/shell/dynamic_service_loader.h"
#include "base/command_line.h"
#include "base/location.h"
#include "mojo/shell/context.h"
#include "mojo/shell/keep_alive.h"
#include "mojo/shell/switches.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 DynamicServiceLoader::LoadContext : public mojo::shell::Loader::Delegate {
public:
LoadContext(DynamicServiceLoader* loader,
const GURL& url,
ScopedShellHandle 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 origin =
CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kOrigin);
std::string lib = MakeSharedLibraryName(url.ExtractFileName());
url_to_load = GURL(origin + "/" + lib);
} else {
url_to_load = url;
}
request_ = loader_->context_->loader()->Load(url_to_load, this);
}
virtual ~LoadContext() {
}
private:
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_));
}
DynamicServiceLoader* const loader_;
const GURL url_;
scoped_ptr<mojo::shell::Loader::Job> request_;
ScopedShellHandle service_handle_;
scoped_ptr<DynamicServiceRunner> runner_;
KeepAlive keep_alive_;
DISALLOW_COPY_AND_ASSIGN(LoadContext);
};
DynamicServiceLoader::DynamicServiceLoader(
Context* context,
scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
: context_(context),
runner_factory_(runner_factory.Pass()) {
}
DynamicServiceLoader::~DynamicServiceLoader() {
DCHECK(url_to_load_context_.empty());
}
void DynamicServiceLoader::LoadService(ServiceManager* manager,
const GURL& url,
ScopedShellHandle 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_));
}
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;
}
}
}