diff options
author | sky <sky@chromium.org> | 2016-02-08 11:48:05 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-08 19:50:42 +0000 |
commit | 468d726832348bc0c6415fb8604ccc4e43c84664 (patch) | |
tree | f19e18a1ed464867225afc856f248b7d5892bc6c /mojo/shell/background | |
parent | 254a34e2ad1a277e943db2bc129333c2010e4eac (diff) | |
download | chromium_src-468d726832348bc0c6415fb8604ccc4e43c84664.zip chromium_src-468d726832348bc0c6415fb8604ccc4e43c84664.tar.gz chromium_src-468d726832348bc0c6415fb8604ccc4e43c84664.tar.bz2 |
Creates BackgroundShell and uses it in test
BackgroundShell creates the necessary mojo state in a background
thread and then vends an ApplicationImpl to the main thread so that
the main thread can use mojo.
I also converted views_apptests to a unittest that makes use of
BackgroundShell.
BUG=577242, 577274
TEST=none
R=ben@chromium.org
Review URL: https://codereview.chromium.org/1667273002
Cr-Commit-Position: refs/heads/master@{#374156}
Diffstat (limited to 'mojo/shell/background')
-rw-r--r-- | mojo/shell/background/BUILD.gn | 33 | ||||
-rw-r--r-- | mojo/shell/background/background_shell.cc | 179 | ||||
-rw-r--r-- | mojo/shell/background/background_shell.h | 43 | ||||
-rw-r--r-- | mojo/shell/background/background_shell_main.cc | 43 | ||||
-rw-r--r-- | mojo/shell/background/background_shell_main.h | 12 |
5 files changed, 310 insertions, 0 deletions
diff --git a/mojo/shell/background/BUILD.gn b/mojo/shell/background/BUILD.gn new file mode 100644 index 0000000..c5a1faa --- /dev/null +++ b/mojo/shell/background/BUILD.gn @@ -0,0 +1,33 @@ +# 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. + +source_set("lib") { + sources = [ + "background_shell.cc", + "background_shell.h", + ] + deps = [ + "//base", + "//mojo/message_pump", + "//mojo/shell", + "//mojo/shell/public/cpp:sources", + "//mojo/shell/standalone:lib", + ] +} + +source_set("main") { + sources = [ + "background_shell_main.cc", + "background_shell_main.h", + ] + deps = [ + "//base", + "//mojo/message_pump", + "//mojo/shell", + "//mojo/shell/public/cpp:sources", + "//mojo/shell/runner/common", + "//mojo/shell/runner/host:lib", + "//mojo/shell/standalone:lib", + ] +} diff --git a/mojo/shell/background/background_shell.cc b/mojo/shell/background/background_shell.cc new file mode 100644 index 0000000..0de797c --- /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 diff --git a/mojo/shell/background/background_shell.h b/mojo/shell/background/background_shell.h new file mode 100644 index 0000000..ce68649 --- /dev/null +++ b/mojo/shell/background/background_shell.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_H_ +#define MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/shell/public/interfaces/application.mojom.h" + +class GURL; + +namespace mojo { +namespace shell { + +// BackgroundShell starts up the mojo shell on a background thread, and +// destroys the thread in the destructor. Once created use CreateApplication() +// to obtain an InterfaceRequest for the Application. The InterfaceRequest can +// then be bound to an ApplicationImpl. +class BackgroundShell { + public: + BackgroundShell(); + ~BackgroundShell(); + + void Init(); + + // Obtains an InterfaceRequest for the specified url. + InterfaceRequest<mojom::Application> CreateApplication(const GURL& url); + + private: + class MojoThread; + + scoped_ptr<MojoThread> thread_; + + DISALLOW_COPY_AND_ASSIGN(BackgroundShell); +}; + +} // namespace shell +} // namespace mojo + +#endif // MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_H_ diff --git a/mojo/shell/background/background_shell_main.cc b/mojo/shell/background/background_shell_main.cc new file mode 100644 index 0000000..72c082f --- /dev/null +++ b/mojo/shell/background/background_shell_main.cc @@ -0,0 +1,43 @@ +// 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_main.h" + +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/debug/debugger.h" +#include "base/process/launch.h" +#include "mojo/shell/runner/common/switches.h" +#include "mojo/shell/runner/host/child_process.h" +#include "mojo/shell/runner/init.h" + +namespace mojo { +namespace shell { +namespace { + +int RunChildProcess() { + base::AtExitManager at_exit; + InitializeLogging(); + WaitForDebuggerIfNecessary(); +#if !defined(OFFICIAL_BUILD) && defined(OS_WIN) + base::RouteStdioToConsole(false); +#endif + return ChildProcessMain(); +} + +} // namespace +} // shell +} // mojo + +int main(int argc, char** argv) { + base::CommandLine::Init(argc, argv); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kChildProcess)) { + return mojo::shell::RunChildProcess(); + } + // Reset CommandLine as most likely main() is going to use CommandLine too + // and expect to be able to initialize it. + base::CommandLine::Reset(); + return MasterProcessMain(argc, argv); +} diff --git a/mojo/shell/background/background_shell_main.h b/mojo/shell/background/background_shell_main.h new file mode 100644 index 0000000..6b217d4 --- /dev/null +++ b/mojo/shell/background/background_shell_main.h @@ -0,0 +1,12 @@ +// 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. + +#ifndef MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_MAIN_H_ +#define MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_MAIN_H_ + +// The "main" gn target supplies a file with a main() that calls to the child +// process as necessary. For the main process this function is called. +int MasterProcessMain(int argc, char** argv); + +#endif // MOJO_SHELL_BACKGROUND_BACKGROUND_SHELL_MAIN_H_ |