| Index: mojo/shell/background/background_shell.cc
|
| diff --git a/mojo/shell/background/background_shell.cc b/mojo/shell/background/background_shell.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0de797c56335876ecebfff51f2feb9a2d3275ed3
|
| --- /dev/null
|
| +++ b/mojo/shell/background/background_shell.cc
|
| @@ -0,0 +1,179 @@
|
| +// Copyright 2016 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/background/background_shell.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/path_service.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "base/threading/simple_thread.h"
|
| +#include "mojo/message_pump/message_pump_mojo.h"
|
| +#include "mojo/shell/application_loader.h"
|
| +#include "mojo/shell/application_manager.h"
|
| +#include "mojo/shell/capability_filter.h"
|
| +#include "mojo/shell/connect_to_application_params.h"
|
| +#include "mojo/shell/public/cpp/application_impl.h"
|
| +#include "mojo/shell/public/cpp/shell_client.h"
|
| +#include "mojo/shell/standalone/context.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace mojo {
|
| +namespace shell {
|
| +namespace {
|
| +
|
| +scoped_ptr<base::MessagePump> CreateMessagePumpMojo() {
|
| + return make_scoped_ptr(new common::MessagePumpMojo);
|
| +}
|
| +
|
| +// Used to obtain the InterfaceRequest for an application.
|
| +class BackgroundApplicationLoader : public ApplicationLoader {
|
| + public:
|
| + BackgroundApplicationLoader() {}
|
| + ~BackgroundApplicationLoader() override {}
|
| +
|
| + bool got_request() const { return got_request_; }
|
| + InterfaceRequest<mojom::Application> TakeApplicationRequest() {
|
| + return std::move(application_request_);
|
| + }
|
| +
|
| + // ApplicationLoader:
|
| + void Load(const GURL& url,
|
| + InterfaceRequest<mojom::Application> application_request) override {
|
| + got_request_ = true;
|
| + application_request_ = std::move(application_request);
|
| + }
|
| +
|
| + private:
|
| + bool got_request_ = false;
|
| + InterfaceRequest<mojom::Application> application_request_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BackgroundApplicationLoader);
|
| +};
|
| +
|
| +class MojoMessageLoop : public base::MessageLoop {
|
| + public:
|
| + MojoMessageLoop()
|
| + : base::MessageLoop(base::MessageLoop::TYPE_CUSTOM,
|
| + base::Bind(&CreateMessagePumpMojo)) {}
|
| + ~MojoMessageLoop() override {}
|
| +
|
| + void BindToCurrentThread() { base::MessageLoop::BindToCurrentThread(); }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(MojoMessageLoop);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +// Manages the thread to startup mojo.
|
| +class BackgroundShell::MojoThread : public base::SimpleThread {
|
| + public:
|
| + MojoThread() : SimpleThread("mojo-background-shell") {}
|
| + ~MojoThread() override {}
|
| +
|
| + void CreateApplicationImpl(base::WaitableEvent* signal,
|
| + scoped_ptr<ConnectToApplicationParams> params,
|
| + InterfaceRequest<mojom::Application>* request) {
|
| + // Only valid to call this on the background thread.
|
| + DCHECK_EQ(message_loop_, base::MessageLoop::current());
|
| +
|
| + // Ownership of |loader| passes to ApplicationManager.
|
| + BackgroundApplicationLoader* loader = new BackgroundApplicationLoader;
|
| + const GURL url = params->target().url();
|
| + context_->application_manager()->SetLoaderForURL(make_scoped_ptr(loader),
|
| + url);
|
| + context_->application_manager()->ConnectToApplication(std::move(params));
|
| + DCHECK(loader->got_request());
|
| + *request = loader->TakeApplicationRequest();
|
| + // Trigger destruction of the loader.
|
| + context_->application_manager()->SetLoaderForURL(nullptr, url);
|
| + signal->Signal();
|
| + }
|
| +
|
| + base::MessageLoop* message_loop() { return message_loop_; }
|
| +
|
| + // Stops the background thread.
|
| + void Stop() {
|
| + DCHECK_NE(message_loop_, base::MessageLoop::current());
|
| + message_loop_->task_runner()->PostTask(
|
| + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
|
| + Join();
|
| + }
|
| +
|
| + // base::SimpleThread:
|
| + void Start() override {
|
| + DCHECK(!message_loop_);
|
| + message_loop_ = new MojoMessageLoop;
|
| + base::SimpleThread::Start();
|
| + }
|
| + void Run() override {
|
| + // The construction/destruction order is very finicky and has to be done
|
| + // in the order here.
|
| + scoped_ptr<base::MessageLoop> message_loop(message_loop_);
|
| +
|
| + Context::EnsureEmbedderIsInitialized();
|
| +
|
| + message_loop_->BindToCurrentThread();
|
| +
|
| + base::FilePath shell_dir;
|
| + PathService::Get(base::DIR_MODULE, &shell_dir);
|
| +
|
| + scoped_ptr<Context> context(new Context);
|
| + context_ = context.get();
|
| + context_->Init(shell_dir);
|
| +
|
| + message_loop_->Run();
|
| +
|
| + // Has to happen after run, but while messageloop still valid.
|
| + context_->Shutdown();
|
| +
|
| + // Context has to be destroyed after the MessageLoop has been destroyed.
|
| + message_loop.reset();
|
| + context_ = nullptr;
|
| + }
|
| +
|
| + private:
|
| + // We own this. It's created on the main thread, but destroyed on the
|
| + // background thread.
|
| + MojoMessageLoop* message_loop_ = nullptr;
|
| + // Created in Run() on the background thread.
|
| + Context* context_ = nullptr;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MojoThread);
|
| +};
|
| +
|
| +BackgroundShell::BackgroundShell() {}
|
| +
|
| +BackgroundShell::~BackgroundShell() {
|
| + thread_->Stop();
|
| +}
|
| +
|
| +void BackgroundShell::Init() {
|
| + DCHECK(!thread_);
|
| + thread_.reset(new MojoThread);
|
| + thread_->Start();
|
| +}
|
| +
|
| +InterfaceRequest<mojom::Application> BackgroundShell::CreateApplication(
|
| + const GURL& url) {
|
| + scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams);
|
| + params->SetTarget(
|
| + Identity(url, std::string(), GetPermissiveCapabilityFilter()));
|
| + InterfaceRequest<mojom::Application> request;
|
| + base::WaitableEvent signal(true, false);
|
| + thread_->message_loop()->task_runner()->PostTask(
|
| + FROM_HERE, base::Bind(&MojoThread::CreateApplicationImpl,
|
| + base::Unretained(thread_.get()), &signal,
|
| + base::Passed(¶ms), &request));
|
| + signal.Wait();
|
| + return request;
|
| +}
|
| +
|
| +void RegisterLocalAliases(PackageManagerImpl* manager) {}
|
| +
|
| +} // namespace shell
|
| +} // namespace mojo
|
|
|