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 |
| index c545013c9a5e2f621413475f666651a3f4aa81ec..bc3170ca7047634a5f82f688c8004c040c55ee38 100644 |
| --- a/chrome/app/mash/mash_runner.cc |
| +++ b/chrome/app/mash/mash_runner.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/app/mash/mash_runner.h" |
| #include "base/at_exit.h" |
| +#include "base/barrier_closure.h" |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/debug/debugger.h" |
| @@ -18,8 +19,10 @@ |
| #include "components/tracing/common/trace_to_console.h" |
| #include "components/tracing/common/tracing_switches.h" |
| #include "content/public/common/content_switches.h" |
| +#include "content/public/common/service_names.h" |
| #include "mash/package/mash_packaged_service.h" |
| #include "mojo/public/cpp/bindings/binding_set.h" |
| +#include "services/catalog/public/interfaces/catalog.mojom.h" |
| #include "services/shell/background/background_shell.h" |
| #include "services/shell/native_runner_delegate.h" |
| #include "services/shell/public/cpp/connector.h" |
| @@ -40,6 +43,24 @@ namespace { |
| // kProcessType used to identify child processes. |
| const char* kMashChild = "mash-child"; |
| +const char kChromeMashServiceName[] = "exe:chrome_mash"; |
|
Ben Goodger (Google)
2016/10/06 21:46:26
Can we not use exe: prefixes for synthetic names?
Ken Rockot(use gerrit already)
2016/10/06 22:37:07
Done. This means we don't need the ServiceManagerC
|
| +const char kChromeMashManifestFilename[] = "chrome_mash_manifest.json"; |
| + |
| +const char kChromeMashContentBrowserPackageName[] = |
| + "chrome_mash_content_browser"; |
| +const char kChromeContentGpuPackageName[] = "chrome_content_gpu"; |
| +const char kChromeContentRendererPackageName[] = "chrome_content_renderer"; |
| +const char kChromeContentUtilityPackageName[] = "chrome_content_utility"; |
| + |
| +const char kPackagesPath[] = "Packages"; |
| +const char kManifestFilename[] = "manifest.json"; |
| + |
| +base::FilePath GetPackageManifestPath(const std::string& package_name) { |
| + base::FilePath exe = base::CommandLine::ForCurrentProcess()->GetProgram(); |
| + return exe.DirName().AppendASCII(kPackagesPath).AppendASCII(package_name) |
| + .AppendASCII(kManifestFilename); |
| +} |
| + |
| bool IsChild() { |
| return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kProcessType) && |
| @@ -57,18 +78,6 @@ void InitializeResources() { |
| locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); |
| } |
| -// 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 shell::NativeRunnerDelegate { |
| public: |
| NativeRunnerDelegateImpl() {} |
| @@ -79,9 +88,9 @@ class NativeRunnerDelegateImpl : public shell::NativeRunnerDelegate { |
| void AdjustCommandLineArgumentsForTarget( |
| const shell::Identity& target, |
| base::CommandLine* command_line) override { |
| - if (target.name() != "exe:chrome") { |
| - if (target.name() == "exe:chrome_mash") |
| - ChangeChromeMashToChrome(command_line); |
| + if (target.name() != content::kBrowserMojoApplicationName) { |
| + // If running anything other than the browser process, launch a mash |
| + // child process. The new process will execute MashRunner::RunChild(). |
| command_line->AppendSwitchASCII(switches::kProcessType, kMashChild); |
| #if defined(OS_WIN) |
| command_line->AppendArg(switches::kPrefetchArgumentOther); |
| @@ -89,6 +98,8 @@ class NativeRunnerDelegateImpl : public shell::NativeRunnerDelegate { |
| return; |
| } |
| + // When launching the browser process, ensure that we don't inherit the |
| + // --mash flag so it proceeds with the normal content/browser startup path. |
| base::CommandLine::StringVector argv(command_line->argv()); |
| auto iter = |
| std::find(argv.begin(), argv.end(), FILE_PATH_LITERAL("--mash")); |
| @@ -126,7 +137,53 @@ void MashRunner::RunMain() { |
| service_.reset(new mash::MashPackagedService); |
| service_->set_context(base::MakeUnique<shell::ServiceContext>( |
| service_.get(), |
| - background_shell.CreateServiceRequest("exe:chrome_mash"))); |
| + background_shell.CreateServiceRequest(kChromeMashServiceName))); |
| + |
| + // We need to send sync messages to the ServiceManager and Catalog. Wait for |
| + // completed connections to them. |
| + std::unique_ptr<shell::Connection> service_manager_connection = |
| + service_->connector()->Connect("service:shell"); |
| + std::unique_ptr<shell::Connection> catalog_connection = |
| + service_->connector()->Connect("service:catalog"); |
| + { |
| + base::RunLoop run_loop; |
| + auto on_connect = base::BarrierClosure(2, run_loop.QuitClosure()); |
| + service_manager_connection->AddConnectionCompletedClosure(on_connect); |
| + catalog_connection->AddConnectionCompletedClosure(on_connect); |
| + run_loop.Run(); |
| + } |
| + |
| + // Synchronously override "service:content_browser" and "exe:chrome_mash" to |
| + // resolve to this executable. |
| + base::FilePath this_executable = |
| + base::CommandLine::ForCurrentProcess()->GetProgram(); |
| + shell::mojom::ServiceManagerControlPtr service_manager_control; |
| + service_manager_connection->GetInterface(&service_manager_control); |
| + CHECK(service_manager_control ->OverridePackagePath( |
| + content::kBrowserMojoApplicationName, this_executable)); |
| + CHECK(service_manager_control->OverridePackagePath( |
| + kChromeMashServiceName, this_executable)); |
| + |
| + // Synchronously override manifests needed for various services. |
| + catalog::mojom::CatalogControlPtr catalog_control; |
| + catalog_connection->GetInterface(&catalog_control); |
| + CHECK(catalog_control->OverrideManifestPath( |
| + kChromeMashServiceName, |
| + this_executable.DirName().AppendASCII(kChromeMashManifestFilename))); |
| + CHECK(catalog_control->OverrideManifestPath( |
| + content::kBrowserMojoApplicationName, |
| + GetPackageManifestPath(kChromeMashContentBrowserPackageName))); |
| + CHECK(catalog_control->OverrideManifestPath( |
| + content::kGpuMojoApplicationName, |
| + GetPackageManifestPath(kChromeContentGpuPackageName))); |
| + CHECK(catalog_control->OverrideManifestPath( |
| + content::kRendererMojoApplicationName, |
| + GetPackageManifestPath(kChromeContentRendererPackageName))); |
| + CHECK(catalog_control->OverrideManifestPath( |
| + content::kUtilityMojoApplicationName, |
| + GetPackageManifestPath(kChromeContentUtilityPackageName))); |
| + |
| + // Ping mash_session to ensure an instance is brought up |
| service_->connector()->Connect("service:mash_session"); |
| base::RunLoop().Run(); |
| } |