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(); |
} |