Chromium Code Reviews| 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..9746b7767612c973de7ea9e8ecfbe7fb743ac176 |
| --- /dev/null |
| +++ b/chrome/app/mash/mash_runner.cc |
| @@ -0,0 +1,201 @@ |
| +// 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/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 "mojo/shell/runner/host/command_line_switch.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)); |
|
Ben Goodger (Google)
2016/02/22 20:20:00
what's the purpose of converting to a URL here? yo
sky
2016/02/23 00:01:33
As mentioned in person so that cannonicalization w
|
| + 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; |
| +} |
| + |
| +} // 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. |
| + mojo::shell::BackgroundShell background_shell; |
| + std::vector<mojo::shell::CommandLineSwitch> additional_command_line_switches( |
| + 1); |
| + additional_command_line_switches[0].key = switches::kProcessType; |
| + additional_command_line_switches[0].value = kMashChild; |
| +#if defined(OS_WIN) |
| + mojo::shell::CommandLineSwitch prefetch_switch; |
| + prefetch_switch.is_switch = false; |
| + prefetch_switch.key = switches::kPrefetchArgumentOther; |
| + additional_command_line_switches.emplace_back(prefetch_switch); |
| +#endif |
| + background_shell.Init(additional_command_line_switches); |
| + shell_client_.reset(new DefaultShellClient); |
| + shell_connection_.reset(new mojo::ShellConnection( |
| + shell_client_.get(), |
| + background_shell.CreateShellClientRequest(GURL("exe:chrome")))); |
| + 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; |
| +} |