| Index: chrome/app/mash/mash_runner.cc
|
| diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..787afc7b2f6c3646272e224ac3b74e075d5c88ca
|
| --- /dev/null
|
| +++ b/chrome/app/mash/mash_runner.cc
|
| @@ -0,0 +1,236 @@
|
| +// 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 "chrome/app/mash/mash_runner.h"
|
| +
|
| +#include "ash/mus/sysui_application.h"
|
| +#include "base/at_exit.h"
|
| +#include "base/bind.h"
|
| +#include "base/command_line.h"
|
| +#include "base/debug/debugger.h"
|
| +#include "base/i18n/icu_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/process/launch.h"
|
| +#include "components/mus/mus_app.h"
|
| +#include "components/resource_provider/resource_provider_app.h"
|
| +#include "content/public/common/content_switches.h"
|
| +#include "mash/quick_launch/quick_launch_application.h"
|
| +#include "mash/shell/shell_application_delegate.h"
|
| +#include "mash/wm/window_manager_application.h"
|
| +#include "mojo/common/mojo_scheme_register.h"
|
| +#include "mojo/public/cpp/bindings/weak_binding_set.h"
|
| +#include "mojo/shell/background/background_shell.h"
|
| +#include "mojo/shell/identity.h"
|
| +#include "mojo/shell/native_runner_delegate.h"
|
| +#include "mojo/shell/public/cpp/shell_client.h"
|
| +#include "mojo/shell/public/cpp/shell_connection.h"
|
| +#include "mojo/shell/public/interfaces/shell_client_factory.mojom.h"
|
| +#include "mojo/shell/runner/common/switches.h"
|
| +#include "mojo/shell/runner/host/child_process_base.h"
|
| +#include "url/gurl.h"
|
| +#include "url/url_util.h"
|
| +
|
| +#if defined(OS_LINUX)
|
| +#include "components/font_service/font_service_app.h"
|
| +#endif
|
| +
|
| +using mojo::shell::mojom::ShellClientFactory;
|
| +
|
| +namespace {
|
| +
|
| +// kProcessType used to identify child processes.
|
| +const char* kMashChild = "mash-child";
|
| +
|
| +// ShellClient responsible for starting the appropriate app.
|
| +class DefaultShellClient : public mojo::ShellClient,
|
| + public ShellClientFactory,
|
| + public mojo::InterfaceFactory<ShellClientFactory> {
|
| + public:
|
| + DefaultShellClient() {}
|
| + ~DefaultShellClient() override {}
|
| +
|
| + // mojo::ShellClient:
|
| + bool AcceptConnection(mojo::Connection* connection) override {
|
| + connection->AddInterface<ShellClientFactory>(this);
|
| + return true;
|
| + }
|
| +
|
| + // mojo::InterfaceFactory<ShellClientFactory>
|
| + void Create(mojo::Connection* connection,
|
| + mojo::InterfaceRequest<ShellClientFactory> request) override {
|
| + shell_client_factory_bindings_.AddBinding(this, std::move(request));
|
| + }
|
| +
|
| + // ShellClientFactory:
|
| + void CreateShellClient(mojo::shell::mojom::ShellClientRequest request,
|
| + const mojo::String& mojo_url) override {
|
| + const GURL url = GURL(std::string(mojo_url));
|
| + if (shell_client_) {
|
| + LOG(ERROR) << "request to create additional app " << url;
|
| + return;
|
| + }
|
| + shell_client_ = CreateShellClient(url);
|
| + if (shell_client_) {
|
| + shell_connection_.reset(
|
| + new mojo::ShellConnection(shell_client_.get(), std::move(request)));
|
| + return;
|
| + }
|
| + LOG(ERROR) << "unknown url " << url;
|
| + NOTREACHED();
|
| + }
|
| +
|
| + private:
|
| + // TODO(sky): move this into mash.
|
| + scoped_ptr<mojo::ShellClient> CreateShellClient(const GURL& url) {
|
| + if (url == GURL("mojo:ash_sysui"))
|
| + return make_scoped_ptr(new ash::sysui::SysUIApplication);
|
| + if (url == GURL("mojo:desktop_wm"))
|
| + return make_scoped_ptr(new mash::wm::WindowManagerApplication);
|
| + if (url == GURL("mojo:mash_shell"))
|
| + return make_scoped_ptr(new mash::shell::ShellApplicationDelegate);
|
| + if (url == GURL("mojo:mus"))
|
| + return make_scoped_ptr(new mus::MandolineUIServicesApp);
|
| + if (url == GURL("mojo:quick_launch"))
|
| + return make_scoped_ptr(new mash::quick_launch::QuickLaunchApplication);
|
| + if (url == GURL("mojo:resource_provider")) {
|
| + return make_scoped_ptr(
|
| + new resource_provider::ResourceProviderApp("mojo:resource_provider"));
|
| + }
|
| +#if defined(OS_LINUX)
|
| + if (url == GURL("mojo:font_service"))
|
| + return make_scoped_ptr(new font_service::FontServiceApp);
|
| +#endif
|
| + return nullptr;
|
| + }
|
| +
|
| + mojo::WeakBindingSet<ShellClientFactory> shell_client_factory_bindings_;
|
| + scoped_ptr<mojo::ShellClient> shell_client_;
|
| + scoped_ptr<mojo::ShellConnection> shell_connection_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DefaultShellClient);
|
| +};
|
| +
|
| +bool IsChild() {
|
| + return base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kProcessType) &&
|
| + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
| + switches::kProcessType) == kMashChild;
|
| +}
|
| +
|
| +// Convert the command line program from chrome_mash to chrome. This is
|
| +// necessary as the shell will attempt to start chrome_mash. We want chrome.
|
| +void ChangeChromeMashToChrome(base::CommandLine* command_line) {
|
| + base::FilePath exe_path(command_line->GetProgram());
|
| +#if defined(OS_WIN)
|
| + exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("chrome.exe"));
|
| +#else
|
| + exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("chrome"));
|
| +#endif
|
| + command_line->SetProgram(exe_path);
|
| +}
|
| +
|
| +class NativeRunnerDelegateImpl : public mojo::shell::NativeRunnerDelegate {
|
| + public:
|
| + NativeRunnerDelegateImpl() {}
|
| + ~NativeRunnerDelegateImpl() override {}
|
| +
|
| + private:
|
| + // mojo::shell::NativeRunnerDelegate:
|
| + void AdjustCommandLineArgumentsForTarget(
|
| + const mojo::shell::Identity& target,
|
| + base::CommandLine* command_line) override {
|
| + if (target.url() != GURL("exe:chrome")) {
|
| + if (target.url() == GURL("exe:chrome_mash"))
|
| + ChangeChromeMashToChrome(command_line);
|
| + command_line->AppendSwitchASCII(switches::kProcessType, kMashChild);
|
| +#if defined(OS_WIN)
|
| + command_line->AppendArg(switches::kPrefetchArgumentOther);
|
| +#endif
|
| + return;
|
| + }
|
| +
|
| + base::CommandLine::StringVector argv(command_line->argv());
|
| + auto iter =
|
| + std::find(argv.begin(), argv.end(), FILE_PATH_LITERAL("--mash"));
|
| + if (iter != argv.end())
|
| + argv.erase(iter);
|
| + *command_line = base::CommandLine(argv);
|
| + }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NativeRunnerDelegateImpl);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +MashRunner::MashRunner() {}
|
| +
|
| +MashRunner::~MashRunner() {}
|
| +
|
| +void MashRunner::Run() {
|
| + if (IsChild())
|
| + RunChild();
|
| + else
|
| + RunMain();
|
| +}
|
| +
|
| +void MashRunner::RunMain() {
|
| + // TODO(sky): refactor backgroundshell so can supply own context, we
|
| + // shouldn't we using context as it has a lot of stuff we don't really want
|
| + // in chrome.
|
| + NativeRunnerDelegateImpl native_runner_delegate;
|
| + mojo::shell::BackgroundShell background_shell;
|
| + background_shell.Init(&native_runner_delegate);
|
| + shell_client_.reset(new DefaultShellClient);
|
| + shell_connection_.reset(new mojo::ShellConnection(
|
| + shell_client_.get(),
|
| + background_shell.CreateShellClientRequest(GURL("exe:chrome_mash"))));
|
| + shell_connection_->WaitForInitialize();
|
| + static_cast<mojo::Shell*>(shell_connection_.get())
|
| + ->Connect("mojo:mash_shell");
|
| + base::MessageLoop::current()->Run();
|
| +}
|
| +
|
| +void MashRunner::RunChild() {
|
| + base::i18n::InitializeICU();
|
| + mojo::shell::ChildProcessMain(
|
| + base::Bind(&MashRunner::StartChildApp, base::Unretained(this)));
|
| +}
|
| +
|
| +void MashRunner::StartChildApp(
|
| + mojo::shell::mojom::ShellClientRequest client_request) {
|
| + // TODO(sky): use MessagePumpMojo.
|
| + base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
|
| + shell_client_.reset(new DefaultShellClient);
|
| + shell_connection_.reset(new mojo::ShellConnection(shell_client_.get(),
|
| + std::move(client_request)));
|
| + message_loop.Run();
|
| +}
|
| +
|
| +int MashMain() {
|
| +#if defined(OS_WIN)
|
| + base::RouteStdioToConsole(false);
|
| +#endif
|
| + // TODO(sky): wire this up correctly.
|
| + logging::LoggingSettings settings;
|
| + settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
| + logging::InitLogging(settings);
|
| + // To view log output with IDs and timestamps use "adb logcat -v threadtime".
|
| + logging::SetLogItems(false, // Process ID
|
| + false, // Thread ID
|
| + false, // Timestamp
|
| + false); // Tick count
|
| +
|
| + mojo::RegisterMojoSchemes();
|
| + // TODO(sky): use MessagePumpMojo.
|
| + scoped_ptr<base::MessageLoop> message_loop;
|
| +#if defined(OS_LINUX)
|
| + base::AtExitManager exit_manager;
|
| +#endif
|
| + if (!IsChild())
|
| + message_loop.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
|
| + MashRunner mash_runner;
|
| + mash_runner.Run();
|
| + return 0;
|
| +}
|
|
|