Commit 74946c37 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Migrate Mash to use embedded services

Extends the Service Manager embedder API to allow embedders to run
a standalone Service Manager process as well as standalone service
processes for embedded services.

Eliminates MashRunner and all Mash-related service packaging, instead
treating Mash services as embedded services. Chrome (via content)
provides the implementation details necessary to mirror the existing
MashRunner behavior on top of the Service Manager embedder API.

BUG=654986

Change-Id: I79d8eb66e0b98746fd5b5b7f7ea8e8f6b217b6fd
Reviewed-on: https://chromium-review.googlesource.com/477393Reviewed-by: default avatarBen Goodger <ben@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarOystein Eftevaag <oysteine@chromium.org>
Commit-Queue: Ken Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#467230}
parent 368d0cd0
......@@ -68,6 +68,22 @@ if (is_win) {
}
}
# Dependencies which must accompany ChromeMainDelegate when embedded
# Mash services are enabled.
if (enable_package_mash_services) {
embedded_mash_service_deps = [
"//chrome/app/mash:chrome_mash_catalog",
"//chrome/app/mash:embedded_services",
"//mash/common",
"//mash/quick_launch/public/interfaces:constants",
"//services/ui/public/interfaces:constants",
]
if (is_chromeos) {
embedded_mash_service_deps += [ "//chrome/app/mash:chrome_mus_catalog" ]
}
}
# This target exists above chrome and it's main components in the dependency
# tree as a central place to put assert_no_deps annotations. Since this depends
# on Chrome and the main DLLs it uses, it will transitively assert that those
......@@ -243,9 +259,11 @@ if (!is_android && !is_mac) {
# Needed to use the master_preferences functions
"//chrome/installer/util:with_no_strings",
"//content/public/app:both",
"//content/public/common:service_names",
# For headless mode.
"//headless:headless_shell_lib",
"//services/service_manager/embedder",
]
public_deps = [
......@@ -274,8 +292,7 @@ if (!is_android && !is_mac) {
}
if (enable_package_mash_services) {
deps += [ "//chrome/app/mash" ]
data_deps += [ "//chrome/app:service_manifests" ]
deps += embedded_mash_service_deps
}
}
......@@ -341,9 +358,11 @@ if (is_win) {
"//components/crash/content/app",
"//components/policy:generated",
"//content/app/resources",
"//content/public/common:service_names",
"//crypto",
"//net:net_resources",
"//ppapi/features",
"//services/service_manager/embedder",
"//third_party/cld",
"//third_party/wtl",
"//ui/views",
......@@ -396,7 +415,7 @@ if (is_win) {
}
if (enable_package_mash_services) {
deps += [ "//chrome/app/mash" ]
deps += embedded_mash_service_deps
}
}
......@@ -432,6 +451,8 @@ if (is_win) {
"//components/browser_watcher:browser_watcher_client",
"//components/crash/content/app",
"//content/public/app:child",
"//content/public/common:service_names",
"//services/service_manager/embedder",
]
ldflags = [
......@@ -1088,7 +1109,9 @@ if (is_win) {
"//components/crash/content/app",
"//components/policy:generated",
"//content/public/app:both",
"//content/public/common:service_names",
"//headless:headless_shell_lib",
"//services/service_manager/embedder",
"//third_party/cld",
]
......@@ -1103,7 +1126,7 @@ if (is_win) {
]
if (enable_package_mash_services) {
deps += [ "//chrome/app/mash" ]
deps += embedded_mash_service_deps
}
configs += [ "//build/config/compiler:wexit_time_destructors" ]
......@@ -1645,6 +1668,8 @@ if (is_android) {
"//chrome/utility",
"//components/safe_browsing_db:safe_browsing_db_mobile",
"//content/public/app:both",
"//content/public/common:service_names",
"//services/service_manager/embedder",
]
}
}
......
......@@ -316,6 +316,7 @@ static_library("test_support") {
deps = [
"//base",
"//chrome/app:shutdown_signal_handlers",
"//chrome/browser",
"//chrome/browser/policy:path_parser",
"//chrome/child",
......@@ -328,9 +329,11 @@ static_library("test_support") {
"//components/startup_metric_utils/browser:lib",
"//content/public/app:both",
"//content/public/common",
"//content/public/common:service_names",
"//pdf",
"//ppapi/features",
"//printing/features",
"//services/service_manager/embedder",
"//ui/base",
]
......@@ -361,6 +364,20 @@ static_library("test_support") {
"//components/nacl/renderer/plugin:nacl_trusted_plugin",
]
}
if (enable_package_mash_services) {
deps += [
"//chrome/app/mash:chrome_mash_catalog",
"//chrome/app/mash:embedded_services",
"//mash/common",
"//mash/quick_launch/public/interfaces:constants",
"//services/ui/public/interfaces:constants",
]
if (is_chromeos) {
deps += [ "//chrome/app/mash:chrome_mus_catalog" ]
}
}
}
chrome_packaged_services = [ ":chrome_manifest" ]
......
......@@ -30,9 +30,12 @@ include_rules = [
"+content/public/browser/browser_main_runner.h",
"+extensions/common/constants.h",
"+headless/public", # For headless mode.
"+mash/common",
"+mash/quick_launch/public",
"+native_client/src/trusted/service_runtime/osx",
"+remoting/client/plugin",
"+sandbox",
"+services/service_manager/runner/common/client_util.h",
"+services/service_manager",
"+services/ui/public",
"+third_party/crashpad/crashpad",
]
......@@ -16,9 +16,6 @@
#include "ui/gfx/switches.h"
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
#include "chrome/app/mash/mash_runner.h"
#include "chrome/common/channel_info.h"
#include "components/version_info/version_info.h"
#include "services/service_manager/runner/common/client_util.h"
#endif
......@@ -107,17 +104,8 @@ int ChromeMain(int argc, const char** argv) {
#endif // defined(OS_LINUX) || defined(OS_MACOSX)
#if defined(OS_CHROMEOS) && BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
version_info::Channel channel = chrome::GetChannel();
if (channel == version_info::Channel::CANARY ||
channel == version_info::Channel::UNKNOWN) {
if (command_line->HasSwitch(switches::kMash) ||
command_line->HasSwitch(switches::kMus)) {
return MashMain();
}
WaitForMashDebuggerIfNecessary();
if (service_manager::ServiceManagerIsRemote())
params.env_mode = aura::Env::Mode::MUS;
}
if (service_manager::ServiceManagerIsRemote())
params.env_mode = aura::Env::Mode::MUS;
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
int rv = content::ContentMain(params);
......
......@@ -21,6 +21,7 @@
#include "base/process/process_handle.h"
#include "base/process/process_info.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event_impl.h"
#include "build/build_config.h"
......@@ -51,10 +52,12 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "extensions/common/constants.h"
#include "pdf/features.h"
#include "ppapi/features/features.h"
#include "printing/features/features.h"
#include "services/service_manager/embedder/switches.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
......@@ -86,7 +89,9 @@
#if defined(OS_POSIX)
#include <locale.h>
#include <signal.h>
#include "chrome/app/chrome_crash_reporter_client.h"
#include "chrome/app/shutdown_signal_handlers_posix.h"
#endif
#if !defined(DISABLE_NACL) && defined(OS_LINUX)
......@@ -102,6 +107,19 @@
#include "chromeos/hugepage_text/hugepage_text.h"
#endif
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
#include "chrome/app/mash/chrome_mash_catalog.h"
#include "chrome/app/mash/embedded_services.h"
#include "mash/common/config.h" // nogncheck
#include "mash/quick_launch/public/interfaces/constants.mojom.h" // nogncheck
#include "services/ui/public/interfaces/constants.mojom.h" // nogncheck
#if defined(OS_CHROMEOS)
#include "chrome/app/mash/chrome_mus_catalog.h"
#endif
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
#if defined(OS_ANDROID)
#include "base/android/java_exception_reporter.h"
#include "chrome/common/descriptors_android.h"
......@@ -250,7 +268,8 @@ void AdjustLinuxOOMScore(const std::string& process_type) {
score = kPluginScore + kScoreBump;
} else if (process_type == switches::kUtilityProcess ||
process_type == switches::kGpuProcess ||
process_type == switches::kCloudPrintServiceProcess) {
process_type == switches::kCloudPrintServiceProcess ||
process_type == service_manager::switches::kProcessTypeService) {
score = kMiscScore;
#ifndef DISABLE_NACL
} else if (process_type == switches::kNaClLoaderProcess ||
......@@ -258,6 +277,8 @@ void AdjustLinuxOOMScore(const std::string& process_type) {
score = kPluginScore;
#endif
} else if (process_type == switches::kZygoteProcess ||
process_type ==
service_manager::switches::kProcessTypeServiceManager ||
process_type.empty()) {
// For zygotes and unlabeled process types, we want to still make
// them killable by the OOM killer.
......@@ -1091,3 +1112,113 @@ bool ChromeMainDelegate::ShouldEnableProfilerRecording() {
return false;
}
}
service_manager::ProcessType ChromeMainDelegate::OverrideProcessType() {
const auto& command_line = *base::CommandLine::ForCurrentProcess();
if (command_line.GetSwitchValueASCII(switches::kProcessType) ==
service_manager::switches::kProcessTypeService) {
// Don't mess with embedded service command lines.
return service_manager::ProcessType::kDefault;
}
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
if (command_line.HasSwitch(switches::kMus) ||
command_line.HasSwitch(switches::kMash)) {
return service_manager::ProcessType::kServiceManager;
}
#endif
return service_manager::ProcessType::kDefault;
}
std::unique_ptr<base::Value> ChromeMainDelegate::CreateServiceCatalog() {
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
const auto& command_line = *base::CommandLine::ForCurrentProcess();
#if defined(OS_CHROMEOS)
if (command_line.HasSwitch(switches::kMus))
return CreateChromeMusCatalog();
#endif // defined(OS_CHROMEOS)
if (command_line.HasSwitch(switches::kMash))
return CreateChromeMashCatalog();
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
return nullptr;
}
void ChromeMainDelegate::AdjustServiceProcessCommandLine(
const service_manager::Identity& identity,
base::CommandLine* command_line) {
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
// Add kMusConfig so that launched processes know what config they are
// running in.
const bool is_mash = command_line->HasSwitch(switches::kMash);
command_line->AppendSwitchASCII(switches::kMusConfig,
is_mash ? switches::kMash : switches::kMus);
if (identity.name() == content::mojom::kPackagedServicesServiceName) {
// Ensure the browser process doesn't inherit mash or mus flags, since these
// flags would cause the process to run as a Service Manager instead.
base::CommandLine::SwitchMap switches = command_line->GetSwitches();
switches.erase(switches::kMash);
switches.erase(switches::kMus);
*command_line = base::CommandLine(command_line->GetProgram());
for (const auto& sw : switches)
command_line->AppendSwitchNative(sw.first, sw.second);
}
#endif
}
bool ChromeMainDelegate::ShouldTerminateServiceManagerOnInstanceQuit(
const service_manager::Identity& identity,
int* exit_code) {
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
if (identity.name() == mash::common::GetWindowManagerServiceName() ||
identity.name() == ui::mojom::kServiceName ||
identity.name() == content::mojom::kPackagedServicesServiceName) {
// Quit the main process if an important child (e.g. window manager) dies.
// On Chrome OS the OS-level session_manager will restart the main process.
*exit_code = 1;
LOG(ERROR) << "Main process exiting because service " << identity.name()
<< " quit unexpectedly.";
return true;
}
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
return false;
}
void ChromeMainDelegate::OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) {
#if defined(OS_POSIX)
// Quit the main process in response to shutdown signals (like SIGTERM).
// These signals are used by Linux distributions to request clean shutdown.
// On Chrome OS the SIGTERM signal is sent by session_manager.
InstallShutdownSignalHandlers(quit_closure,
base::ThreadTaskRunnerHandle::Get());
#endif
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
// Start services that we know we want to launch on startup (UI service,
// window manager, quick launch app).
service_manager->StartService(
service_manager::Identity(ui::mojom::kServiceName));
service_manager->StartService(
service_manager::Identity(content::mojom::kPackagedServicesServiceName));
if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash)) {
service_manager->StartService(
service_manager::Identity(mash::common::GetWindowManagerServiceName()));
service_manager->StartService(
service_manager::Identity(mash::quick_launch::mojom::kServiceName));
}
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
}
std::unique_ptr<service_manager::Service>
ChromeMainDelegate::CreateEmbeddedService(const std::string& service_name) {
#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
auto mash_service = CreateEmbeddedMashService(service_name);
if (mash_service)
return mash_service;
#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
return nullptr;
}
......@@ -48,6 +48,19 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
void ZygoteForked() override;
#endif
bool ShouldEnableProfilerRecording() override;
service_manager::ProcessType OverrideProcessType() override;
std::unique_ptr<base::Value> CreateServiceCatalog() override;
void AdjustServiceProcessCommandLine(
const service_manager::Identity& identity,
base::CommandLine* command_line) override;
bool ShouldTerminateServiceManagerOnInstanceQuit(
const service_manager::Identity& identity,
int* exit_code) override;
void OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) override;
std::unique_ptr<service_manager::Service> CreateEmbeddedService(
const std::string& service_name) override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override;
......
......@@ -9,20 +9,27 @@ import("//services/service_manager/public/service_manifest.gni")
assert(enable_package_mash_services)
source_set("mash") {
source_set("embedded_services") {
sources = [
"mash_runner.cc",
"mash_runner.h",
"embedded_services.cc",
"embedded_services.h",
]
deps = [
":chrome_mash_catalog",
"//base:i18n",
"//chrome/common:constants",
"//components/tracing:startup_tracing",
"//content/public/common",
"//mash/catalog_viewer:lib",
"//mash/catalog_viewer/public/interfaces:constants",
"//mash/common",
"//mash/package",
"//mash/quick_launch:lib",
"//mash/quick_launch/public/interfaces:constants",
"//mash/session:lib",
"//mash/session/public/interfaces:constants",
"//mash/task_viewer:lib",
"//mash/task_viewer/public/interfaces:constants",
"//services/catalog/public/interfaces",
"//services/service_manager",
"//services/service_manager/background:lib",
......@@ -33,6 +40,8 @@ source_set("mash") {
"//services/service_manager/runner/common",
"//services/service_manager/runner/host:lib",
"//services/service_manager/standalone",
"//services/ui:lib",
"//services/ui/ime/test_ime_driver:lib",
"//services/ui/public/interfaces:constants",
"//url",
]
......@@ -40,7 +49,10 @@ source_set("mash") {
if (is_chromeos) {
deps += [
":chrome_mus_catalog",
"//ash/autoclick/mus:lib",
"//ash/mus:lib",
"//ash/resources",
"//ash/touch_hud/mus:lib",
]
}
......@@ -53,75 +65,46 @@ source_set("mash") {
}
}
service_manifest("mash_manifest") {
name = "chrome_mash"
source = "chrome_mash_manifest.json"
packaged_services = [
catalog("catalog") {
embedded_services = [
"//ash/autoclick/mus:manifest",
"//ash/touch_hud/mus:manifest",
"//mash/catalog_viewer:manifest",
"//mash/quick_launch:manifest",
"//mash/session:manifest",
"//mash/task_viewer:manifest",
"//services/ui:manifest",
"//services/ui/ime/test_ime_driver:manifest",
]
catalog_deps = [ "//chrome/app:catalog_for_mash" ]
standalone_services = [
"//mash/example/views_examples:manifest",
"//mash/simple_wm:manifest",
]
if (is_chromeos) {
packaged_services += [ "//ash/mus:manifest" ]
embedded_services += [ "//ash/mus:manifest" ]
}
if (is_linux && !is_android) {
packaged_services += [ "//components/font_service:manifest" ]
}
if (enable_nacl) {
packaged_services += [ "//components/nacl/loader:nacl_loader_manifest" ]
if (is_win && target_cpu == "x86") {
packaged_services += [ "//components/nacl/broker:nacl_broker_manifest" ]
}
embedded_services += [ "//components/font_service:manifest" ]
}
}
catalog("catalog") {
embedded_services = [ ":mash_manifest" ]
catalog_deps = [ "//chrome/app:catalog_for_mash" ]
standalone_services = [
"//mash/example/views_examples:manifest",
"//mash/simple_wm:manifest",
]
}
catalog_cpp_source("chrome_mash_catalog") {
catalog = ":catalog"
generated_function_name = "CreateChromeMashCatalog"
}
source_set("mash_service_overrides") {
testonly = true
data = [
"mash_service_overrides.json",
]
}
if (is_chromeos) {
service_manifest("mus_manifest") {
name = "chrome_mus"
source = "chrome_mus_manifest.json"
packaged_services = [
catalog("catalog_mus") {
catalog_deps = [ "//chrome/app:catalog" ]
embedded_services = [
"//services/ui:manifest",
# TODO(sky): verify if we need this.
"//services/ui/ime/test_ime_driver:manifest",
]
if (enable_nacl) {
packaged_services += [ "//components/nacl/loader:nacl_loader_manifest" ]
}
}
catalog("catalog_mus") {
embedded_services = [ ":mus_manifest" ]
catalog_deps = [ "//chrome/app:catalog" ]
}
catalog_cpp_source("chrome_mus_catalog") {
......
{
// NOTE: This is the manifest for service:chrome_mash, which is only used to
// package services for the Mash environment when baked into the Chrome binary
// (i.e. "chrome --mash")
//
// If you need to require or provide capabilities from Chrome itself within
// the you should instead modify chrome_content_browser_manifest_overlay.json.
"name": "chrome_mash",
"display_name": "Chrome Mash Packaged Services",
"interface_provider_specs": {
"service_manager:connector": {
"provides": {
"service_manager:service_factory": [
"service_manager::mojom::ServiceFactory"
]
},
"requires": {
"*": [ "app" ],
"ash": [ "app" ],
"catalog": [ "control" ],
"content_browser": [ "app" ],
"quick_launch": [ "app" ],
"service_manager": [ "service_manager:instance_per_child" ],
"ui": [ "app" ]
}
}
}
}
{
// NOTE: This is the manifest for service:chrome_mus, which is only used to
// package services for the Mus environment when baked into the Chrome binary
// (i.e. "chrome --mus")
//
// If you need to require or provide capabilities from Chrome itself within
// the you should instead modify chrome_content_browser_manifest_overlay.json.
"name": "chrome_mus",
"display_name": "Chrome Mus Packaged Services",
"interface_provider_specs": {
"service_manager:connector": {
"provides": {
"service_manager:service_factory": [
"service_manager::mojom::ServiceFactory"
]
},
"requires": {
"*": [ "app" ],
"catalog": [ "control" ],
"content_browser": [ "app" ],
"service_manager": [ "service_manager:instance_per_child" ],
"ui": [ "app" ]
}
}
}
}
// Copyright 2017 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/embedded_services.h"
#include "mash/catalog_viewer/catalog_viewer.h"
#include "mash/catalog_viewer/public/interfaces/constants.mojom.h"
#include "mash/common/config.h"
#include "mash/quick_launch/public/interfaces/constants.mojom.h"
#include "mash/quick_launch/quick_launch.h"
#include "mash/session/public/interfaces/constants.mojom.h"
#include "mash/session/session.h"
#include "mash/task_viewer/public/interfaces/constants.mojom.h"
#include "mash/task_viewer/task_viewer.h"
#include "services/ui/ime/test_ime_driver/test_ime_application.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/service.h"
#if defined(OS_CHROMEOS)
#include "ash/autoclick/mus/autoclick_application.h" // nogncheck
#include "ash/mus/window_manager_application.h" // nogncheck
#include "ash/public/interfaces/constants.mojom.h" // nogncheck
#include "ash/touch_hud/mus/touch_hud_application.h" // nogncheck
#endif // defined(OS_CHROMEOS)
#if defined(OS_LINUX) && !defined(OS_ANDROID)
#include "components/font_service/font_service_app.h"
#endif // defined(OS_LINUX) && !defined(OS_ANDROID)
std::unique_ptr<service_manager::Service> CreateEmbeddedMashService(
const std::string& service_name) {
#if defined(OS_CHROMEOS)
if (service_name == ash::mojom::kServiceName)
return base::MakeUnique<ash::mus::WindowManagerApplication>();
if (service_name == "accessibility_autoclick")
return base::MakeUnique<ash::autoclick::AutoclickApplication>();
if (service_name == "touch_hud")
return base::MakeUnique<ash::touch_hud::TouchHudApplication>();
#endif // defined(OS_CHROMEOS)
if (service_name == mash::catalog_viewer::mojom::kServiceName)
return base::MakeUnique<mash::catalog_viewer::CatalogViewer>();
if (service_name == mash::session::mojom::kServiceName)
return base::MakeUnique<mash::session::Session>();
if (service_name == ui::mojom::kServiceName)
return base::MakeUnique<ui::Service>();
if (service_name == mash::quick_launch::mojom::kServiceName)
return base::MakeUnique<mash::quick_launch::QuickLaunch>();
if (service_name == mash::task_viewer::mojom::kServiceName)
return base::MakeUnique<mash::task_viewer::TaskViewer>();
if (service_name == "test_ime_driver")
return base::MakeUnique<ui::test::TestIMEApplication>();
#if defined(OS_LINUX) && !defined(OS_ANDROID)
if (service_name == "font_service")
return base::MakeUnique<font_service::FontServiceApp>();
#endif // defined(OS_LINUX) && !defined(OS_ANDROID)
return nullptr;
}
// Copyright 2017 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 CHROME_APP_MASH_EMBEDDED_SERVICES_H_
#define CHROME_APP_MASH_EMBEDDED_SERVICES_H_
#include <memory>
#include "services/service_manager/public/cpp/service.h"
// Starts one of Mash's embedded services.
std::unique_ptr<service_manager::Service> CreateEmbeddedMashService(
const std::string& service_name);
#endif // CHROME_APP_MASH_EMBEDDED_SERVICES_H_
This diff is collapsed.
// 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 CHROME_APP_MASH_MASH_RUNNER_H_
#define CHROME_APP_MASH_MASH_RUNNER_H_
#include <memory>
#include "base/macros.h"
#include "services/service_manager/public/interfaces/service.mojom.h"
// Responsible for running mash, both child and main processes.
class MashRunner {
public:
MashRunner();
~MashRunner();