Reland "Support dynamic Mojo Core on Linux"
This is a reland of 002e044483
No changes other than disabling the test under MSan where
it is broken and probably not worth fixing.
Original change's description:
> Support dynamic Mojo Core on Linux
>
> This introduces a new --mojo-core-library-path Content switch which
> instructs Content to initialize each process with an implementation
> of Mojo Core found in the referenced shared library rather than using
> the version linked into the main binary.
>
> This allows for IPC interoperability between a Content embedder and
> another application which provides its own copy of Mojo Core.
>
> Fixed: 1082473
> Change-Id: I1e50c505e91a53e60056a4b8c691d91728f7a5ea
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2229664
> Reviewed-by: Avi Drissman <avi@chromium.org>
> Commit-Queue: Ken Rockot <rockot@google.com>
> Cr-Commit-Position: refs/heads/master@{#778002}
Tbr: avi@chromium.org
Change-Id: I6a2270c87c294455907fb369640b3be0819b2431
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2247166
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#780151}
This commit is contained in:
content
app
content_main_runner_impl.cccontent_service_manager_main_delegate.cccontent_service_manager_main_delegate.hservice_manager_environment.cc
browser
child
common
public
shell
test
services/service_manager/embedder
@ -62,6 +62,7 @@
|
||||
#include "content/child/field_trial.h"
|
||||
#include "content/common/android/cpu_time_metrics.h"
|
||||
#include "content/common/content_constants_internal.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/common/url_schemes.h"
|
||||
#include "content/gpu/in_process_gpu_thread.h"
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
@ -85,6 +86,7 @@
|
||||
#include "media/media_buildflags.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "mojo/public/cpp/system/invitation.h"
|
||||
#include "mojo/public/mojom/base/binder.mojom.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
@ -235,15 +237,20 @@ pid_t LaunchZygoteHelper(base::CommandLine* cmd_line,
|
||||
// Append any switches from the browser process that need to be forwarded on
|
||||
// to the zygote/renderers.
|
||||
static const char* const kForwardSwitches[] = {
|
||||
switches::kAndroidFontsPath, switches::kClearKeyCdmPathForTesting,
|
||||
switches::kAndroidFontsPath,
|
||||
switches::kClearKeyCdmPathForTesting,
|
||||
switches::kEnableLogging, // Support, e.g., --enable-logging=stderr.
|
||||
// Need to tell the zygote that it is headless so that we don't try to use
|
||||
// the wrong type of main delegate.
|
||||
switches::kHeadless,
|
||||
// Zygote process needs to know what resources to have loaded when it
|
||||
// becomes a renderer process.
|
||||
switches::kForceDeviceScaleFactor, switches::kLoggingLevel,
|
||||
switches::kPpapiInProcess, switches::kRegisterPepperPlugins, switches::kV,
|
||||
switches::kForceDeviceScaleFactor,
|
||||
switches::kLoggingLevel,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kPpapiInProcess,
|
||||
switches::kRegisterPepperPlugins,
|
||||
switches::kV,
|
||||
switches::kVModule,
|
||||
};
|
||||
cmd_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
|
||||
@ -837,13 +844,26 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line.GetSwitchValueASCII(switches::kProcessType);
|
||||
// Run this logic on all child processes.
|
||||
if (!process_type.empty()) {
|
||||
if (process_type != service_manager::switches::kZygoteProcess) {
|
||||
// Zygotes will run this at a later point in time when the command line
|
||||
// has been updated.
|
||||
InitializeFieldTrialAndFeatureList();
|
||||
delegate_->PostFieldTrialInitialization();
|
||||
}
|
||||
|
||||
// Run this logic on all child processes. Zygotes will run this at a later
|
||||
// point in time when the command line has been updated.
|
||||
if (!process_type.empty() &&
|
||||
process_type != service_manager::switches::kZygoteProcess) {
|
||||
InitializeFieldTrialAndFeatureList();
|
||||
delegate_->PostFieldTrialInitialization();
|
||||
#if defined(OS_LINUX)
|
||||
// If dynamic Mojo Core is being used, ensure that it's loaded very early in
|
||||
// the child/zygote process, before any sandbox is initialized. The library
|
||||
// is not fully initialized with IPC support until a ChildProcess is later
|
||||
// constructed, as initialization spawns a background thread which would be
|
||||
// unsafe here.
|
||||
if (IsMojoCoreSharedLibraryEnabled()) {
|
||||
CHECK_EQ(mojo::LoadCoreLibrary(GetMojoCoreSharedLibraryPath()),
|
||||
MOJO_RESULT_OK);
|
||||
}
|
||||
#endif // defined(OS_LINUX)
|
||||
}
|
||||
|
||||
MainFunctionParams main_params(command_line);
|
||||
|
@ -6,10 +6,13 @@
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "content/app/content_main_runner_impl.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/service_names.mojom.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "services/service_manager/embedder/switches.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@ -68,12 +71,13 @@ ContentServiceManagerMainDelegate::OverrideProcessType() {
|
||||
return content_main_params_.delegate->OverrideProcessType();
|
||||
}
|
||||
|
||||
void ContentServiceManagerMainDelegate::OverrideMojoConfiguration(
|
||||
void ContentServiceManagerMainDelegate::InitializeMojo(
|
||||
mojo::core::Configuration* config) {
|
||||
// If this is the browser process and there's no Mojo invitation pipe on the
|
||||
// command line, we will serve as the global Mojo broker.
|
||||
const auto& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kProcessType)) {
|
||||
const bool is_browser = !command_line.HasSwitch(switches::kProcessType);
|
||||
if (is_browser) {
|
||||
if (mojo::PlatformChannel::CommandLineHasPassedEndpoint(command_line)) {
|
||||
config->is_broker_process = false;
|
||||
config->force_direct_shared_memory_allocation = true;
|
||||
@ -90,6 +94,27 @@ void ContentServiceManagerMainDelegate::OverrideMojoConfiguration(
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!IsMojoCoreSharedLibraryEnabled()) {
|
||||
mojo::core::Init(*config);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_browser) {
|
||||
// Note that when dynamic Mojo Core is used, initialization for child
|
||||
// processes happens elsewhere. See ContentMainRunnerImpl::Run() and
|
||||
// ChildProcess construction.
|
||||
return;
|
||||
}
|
||||
|
||||
MojoInitializeFlags flags = MOJO_INITIALIZE_FLAG_NONE;
|
||||
if (config->is_broker_process)
|
||||
flags |= MOJO_INITIALIZE_FLAG_AS_BROKER;
|
||||
if (config->force_direct_shared_memory_allocation)
|
||||
flags |= MOJO_INITIALIZE_FLAG_FORCE_DIRECT_SHARED_MEMORY_ALLOCATION;
|
||||
MojoResult result =
|
||||
mojo::LoadAndInitializeCoreLibrary(GetMojoCoreSharedLibraryPath(), flags);
|
||||
CHECK_EQ(MOJO_RESULT_OK, result);
|
||||
}
|
||||
|
||||
std::vector<service_manager::Manifest>
|
||||
|
@ -29,7 +29,7 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
|
||||
int RunEmbedderProcess() override;
|
||||
void ShutDownEmbedderProcess() override;
|
||||
service_manager::ProcessType OverrideProcessType() override;
|
||||
void OverrideMojoConfiguration(mojo::core::Configuration* config) override;
|
||||
void InitializeMojo(mojo::core::Configuration* config) override;
|
||||
std::vector<service_manager::Manifest> GetServiceManifests() override;
|
||||
bool ShouldLaunchAsServiceProcess(
|
||||
const service_manager::Identity& identity) override;
|
||||
|
@ -6,10 +6,12 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/browser/browser_process_sub_thread.h"
|
||||
#include "content/browser/service_manager/service_manager_context.h"
|
||||
#include "content/browser/startup_data_impl.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/common/service_manager_connection.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
@ -22,13 +24,18 @@ ServiceManagerEnvironment::ServiceManagerEnvironment(
|
||||
: io_thread_(std::move(io_thread)) {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> mojo_ipc_task_runner =
|
||||
io_thread_->task_runner();
|
||||
if (base::FeatureList::IsEnabled(features::kMojoDedicatedThread)) {
|
||||
mojo_ipc_thread_.StartWithOptions(
|
||||
base::Thread::Options(base::MessagePumpType::IO, 0));
|
||||
mojo_ipc_task_runner = mojo_ipc_thread_.task_runner();
|
||||
if (!IsMojoCoreSharedLibraryEnabled()) {
|
||||
// NOTE: If Mojo Core was loaded via shared library, IPC support is already
|
||||
// initialized.
|
||||
if (base::FeatureList::IsEnabled(features::kMojoDedicatedThread)) {
|
||||
mojo_ipc_thread_.StartWithOptions(
|
||||
base::Thread::Options(base::MessagePumpType::IO, 0));
|
||||
mojo_ipc_task_runner = mojo_ipc_thread_.task_runner();
|
||||
}
|
||||
mojo_ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
|
||||
mojo_ipc_task_runner,
|
||||
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||
}
|
||||
mojo_ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
|
||||
mojo_ipc_task_runner, mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||
service_manager_context_ =
|
||||
std::make_unique<ServiceManagerContext>(io_thread_->task_runner());
|
||||
ServiceManagerConnection::GetForProcess()->Start();
|
||||
|
@ -338,6 +338,7 @@ void BrowserChildProcessHostImpl::LaunchWithoutExtraCommandLineSwitches(
|
||||
switches::kLogBestEffortTasks,
|
||||
switches::kLogFile,
|
||||
switches::kLoggingLevel,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kPerfettoDisableInterning,
|
||||
switches::kTraceToConsole,
|
||||
switches::kV,
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/test/bind_test_util.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/shell/common/shell_controller.test-mojom.h"
|
||||
@ -26,6 +28,7 @@ namespace {
|
||||
const char kShellExecutableName[] = "content_shell.exe";
|
||||
#else
|
||||
const char kShellExecutableName[] = "content_shell";
|
||||
const char kMojoCoreLibraryName[] = "libmojo_core.so";
|
||||
#endif
|
||||
|
||||
base::FilePath GetCurrentDirectory() {
|
||||
@ -77,6 +80,12 @@ class LaunchAsMojoClientBrowserTest : public ContentBrowserTest {
|
||||
return controller;
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
base::FilePath GetMojoCoreLibraryPath() {
|
||||
return GetFilePathNextToCurrentExecutable(kMojoCoreLibraryName);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
base::FilePath GetFilePathNextToCurrentExecutable(
|
||||
const std::string& filename) {
|
||||
@ -125,5 +134,44 @@ IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest, LaunchAndBindInterface) {
|
||||
shell_controller->ShutDown();
|
||||
}
|
||||
|
||||
// Running a Content embedder with a dynamically loaded Mojo Core library is
|
||||
// currently only supported on Linux and Chrome OS.
|
||||
//
|
||||
// TODO(crbug.com/1096899): Re-enable on MSan if possible. MSan complains about
|
||||
// spurious uninitialized memory reads inside base::PlatformThread due to what
|
||||
// appears to be poor interaction among MSan, PlatformThread's thread_local
|
||||
// storage, and Mojo's use of dlopen().
|
||||
#if defined(OS_LINUX) && !defined(MEMORY_SANITIZER)
|
||||
IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest, WithMojoCoreLibrary) {
|
||||
// Instructs a newly launched Content Shell browser to initialize Mojo Core
|
||||
// dynamically from a shared library, rather than using the version linked
|
||||
// into the Content Shell binary.
|
||||
//
|
||||
// This exercises end-to-end JS in order to cover real IPC behavior between
|
||||
// the browser and a renderer.
|
||||
|
||||
base::CommandLine command_line = MakeShellCommandLine();
|
||||
command_line.AppendSwitchPath(switches::kMojoCoreLibraryPath,
|
||||
GetMojoCoreLibraryPath());
|
||||
mojo::Remote<mojom::ShellController> shell_controller =
|
||||
LaunchContentShell(command_line);
|
||||
|
||||
// Indisputable proof that we're evaluating JavaScript.
|
||||
const std::string kExpressionToEvaluate = "'ba'+ +'a'+'as'";
|
||||
const base::Value kExpectedValue("baNaNas");
|
||||
|
||||
base::RunLoop loop;
|
||||
shell_controller->ExecuteJavaScript(
|
||||
base::ASCIIToUTF16(kExpressionToEvaluate),
|
||||
base::BindLambdaForTesting([&](base::Value value) {
|
||||
EXPECT_EQ(kExpectedValue, value);
|
||||
loop.Quit();
|
||||
}));
|
||||
loop.Run();
|
||||
|
||||
shell_controller->ShutDown();
|
||||
}
|
||||
#endif // defined(OS_LINUX) && !defined(MEMORY_SANITIZER)
|
||||
|
||||
} // namespace
|
||||
} // namespace content
|
||||
|
@ -3284,6 +3284,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
switches::kDefaultTileWidth,
|
||||
switches::kDefaultTileHeight,
|
||||
switches::kMinHeightForGpuRasterTile,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kDisable2dCanvasImageChromium,
|
||||
switches::kDisableYUVImageDecoding,
|
||||
switches::kDisableAcceleratedVideoDecode,
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include "build/build_config.h"
|
||||
#include "content/child/child_thread_impl.h"
|
||||
#include "content/common/android/cpu_time_metrics.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "services/service_manager/sandbox/sandbox_type.h"
|
||||
#include "services/tracing/public/cpp/trace_startup.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
|
||||
@ -38,6 +41,23 @@ ChildProcess::ChildProcess(base::ThreadPriority io_thread_priority,
|
||||
DCHECK(!g_lazy_child_process_tls.Pointer()->Get());
|
||||
g_lazy_child_process_tls.Pointer()->Set(this);
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (IsMojoCoreSharedLibraryEnabled()) {
|
||||
// If we're in a child process on Linux and dynamic Mojo Core is in use, we
|
||||
// expect early process startup code (see ContentMainRunnerImpl::Run()) to
|
||||
// have already loaded the library via |mojo::LoadCoreLibrary()|, rendering
|
||||
// this call safe even from within a strict sandbox.
|
||||
MojoInitializeFlags flags = MOJO_INITIALIZE_FLAG_NONE;
|
||||
if (service_manager::IsUnsandboxedSandboxType(
|
||||
service_manager::SandboxTypeFromCommandLine(command_line))) {
|
||||
flags |= MOJO_INITIALIZE_FLAG_FORCE_DIRECT_SHARED_MEMORY_ALLOCATION;
|
||||
}
|
||||
CHECK_EQ(MOJO_RESULT_OK, mojo::InitializeCoreLibrary(flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize ThreadPoolInstance if not already done. A ThreadPoolInstance may
|
||||
// already exist when ChildProcess is instantiated in the browser process or
|
||||
// in a test process.
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "content/child/child_thread_impl.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
@ -47,6 +49,7 @@
|
||||
#include "content/common/child_process.mojom.h"
|
||||
#include "content/common/field_trial_recorder.mojom.h"
|
||||
#include "content/common/in_process_child_thread_params.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
@ -570,16 +573,19 @@ void ChildThreadImpl::Init(const Options& options) {
|
||||
// IPC mode.
|
||||
mojo::ScopedMessagePipeHandle child_process_pipe;
|
||||
if (!IsInBrowserProcess()) {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> mojo_ipc_task_runner =
|
||||
GetIOTaskRunner();
|
||||
if (base::FeatureList::IsEnabled(features::kMojoDedicatedThread)) {
|
||||
mojo_ipc_thread_.StartWithOptions(
|
||||
base::Thread::Options(base::MessagePumpType::IO, 0));
|
||||
mojo_ipc_task_runner = mojo_ipc_thread_.task_runner();
|
||||
// If using a shared Mojo Core library, IPC support is already initialized.
|
||||
if (!IsMojoCoreSharedLibraryEnabled()) {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> mojo_ipc_task_runner =
|
||||
GetIOTaskRunner();
|
||||
if (base::FeatureList::IsEnabled(features::kMojoDedicatedThread)) {
|
||||
mojo_ipc_thread_.StartWithOptions(
|
||||
base::Thread::Options(base::MessagePumpType::IO, 0));
|
||||
mojo_ipc_task_runner = mojo_ipc_thread_.task_runner();
|
||||
}
|
||||
mojo_ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
|
||||
mojo_ipc_task_runner,
|
||||
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||
}
|
||||
mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
|
||||
mojo_ipc_task_runner,
|
||||
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
|
||||
mojo::IncomingInvitation invitation = InitializeMojoIPCChannel();
|
||||
child_process_pipe = invitation.ExtractMessagePipe(0);
|
||||
} else {
|
||||
|
@ -153,6 +153,8 @@ source_set("common") {
|
||||
"mac/font_loader.mm",
|
||||
"media/cdm_info.cc",
|
||||
"media/media_player_delegate_messages.h",
|
||||
"mojo_core_library_support.cc",
|
||||
"mojo_core_library_support.h",
|
||||
"navigation_gesture.h",
|
||||
"navigation_params.cc",
|
||||
"navigation_params.h",
|
||||
|
31
content/common/mojo_core_library_support.cc
Normal file
31
content/common/mojo_core_library_support.cc
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2020 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 "content/common/mojo_core_library_support.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
bool IsMojoCoreSharedLibraryEnabled() {
|
||||
return GetMojoCoreSharedLibraryPath() != base::nullopt;
|
||||
}
|
||||
|
||||
base::Optional<base::FilePath> GetMojoCoreSharedLibraryPath() {
|
||||
#if defined(OS_LINUX)
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kMojoCoreLibraryPath))
|
||||
return base::nullopt;
|
||||
return command_line.GetSwitchValuePath(switches::kMojoCoreLibraryPath);
|
||||
#else
|
||||
// Content does not yet properly support dynamic Mojo Core on platforms other
|
||||
// than Linux and Chrome OS.
|
||||
return base::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace content
|
26
content/common/mojo_core_library_support.h
Normal file
26
content/common/mojo_core_library_support.h
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2020 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 CONTENT_COMMON_MOJO_CORE_LIBRARY_SUPPORT_H_
|
||||
#define CONTENT_COMMON_MOJO_CORE_LIBRARY_SUPPORT_H_
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/optional.h"
|
||||
#include "content/common/content_export.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
// Indicates whether the calling process was launched with the option to
|
||||
// initialize Mojo Core from a shared library rather than the statically linked
|
||||
// implementation.
|
||||
CONTENT_EXPORT bool IsMojoCoreSharedLibraryEnabled();
|
||||
|
||||
// Returns the path to the Mojo Core shared library passed in on the command
|
||||
// line for the calling process, or null if the process was launched without a
|
||||
// Mojo Core library path on the command line.
|
||||
CONTENT_EXPORT base::Optional<base::FilePath> GetMojoCoreSharedLibraryPath();
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_COMMON_MOJO_CORE_LIBRARY_SUPPORT_H_
|
@ -620,6 +620,10 @@ const char kMessageLoopTypeUi[] = "message-loop-type-ui";
|
||||
const char kMockCertVerifierDefaultResultForTesting[] =
|
||||
"mock-cert-verifier-default-result-for-testing";
|
||||
|
||||
// Initializes Mojo Core from a shared library at the specified path, rather
|
||||
// than using the version of Mojo Core embedded within the Content executable.
|
||||
const char kMojoCoreLibraryPath[] = "mojo-core-library-path";
|
||||
|
||||
// Use a Mojo-based LocalStorage implementation.
|
||||
const char kMojoLocalStorage[] = "mojo-local-storage";
|
||||
|
||||
|
@ -183,6 +183,7 @@ CONTENT_EXPORT extern const char kMHTMLGeneratorOption[];
|
||||
CONTENT_EXPORT extern const char kMHTMLSkipNostoreMain[];
|
||||
CONTENT_EXPORT extern const char kMHTMLSkipNostoreAll[];
|
||||
CONTENT_EXPORT extern const char kMockCertVerifierDefaultResultForTesting[];
|
||||
CONTENT_EXPORT extern const char kMojoCoreLibraryPath[];
|
||||
CONTENT_EXPORT extern const char kMojoLocalStorage[];
|
||||
CONTENT_EXPORT extern const char kNetworkQuietTimeout[];
|
||||
CONTENT_EXPORT extern const char kNoZygote[];
|
||||
|
@ -1091,4 +1091,5 @@ group("content_shell_crash_test") {
|
||||
mojom("shell_controller_mojom") {
|
||||
testonly = true
|
||||
sources = [ "common/shell_controller.test-mojom" ]
|
||||
public_deps = [ "//mojo/public/mojom/base" ]
|
||||
}
|
||||
|
@ -110,6 +110,14 @@ class ShellControllerImpl : public mojom::ShellController {
|
||||
std::move(callback).Run(base::nullopt);
|
||||
}
|
||||
|
||||
void ExecuteJavaScript(const base::string16& script,
|
||||
ExecuteJavaScriptCallback callback) override {
|
||||
CHECK(!Shell::windows().empty());
|
||||
WebContents* contents = Shell::windows()[0]->web_contents();
|
||||
contents->GetMainFrame()->ExecuteJavaScriptForTests(script,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void ShutDown() override { Shell::CloseAllWindows(); }
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,9 @@
|
||||
|
||||
module content.mojom;
|
||||
|
||||
import "mojo/public/mojom/base/string16.mojom";
|
||||
import "mojo/public/mojom/base/values.mojom";
|
||||
|
||||
// A control interface which can be accessed by clients launching Content Shell
|
||||
// with a Mojo invitation on the command line. This is used by
|
||||
// LaunchAsMojoClientBrowserTest to exercise that mode of execution.
|
||||
@ -12,6 +15,11 @@ interface ShellController {
|
||||
// running Content Shell process which receives this message.
|
||||
GetSwitchValue(string name) => (string? value);
|
||||
|
||||
// Asks the shell to execute the JavaScript code in |script| within the first
|
||||
// available window, and returns the resulting value.
|
||||
ExecuteJavaScript(mojo_base.mojom.String16 script)
|
||||
=> (mojo_base.mojom.Value value);
|
||||
|
||||
// Tells Content Shell to close all windows and shut down. After sending this
|
||||
// message, the Content Shell browser process should be expected to terminate
|
||||
// soon.
|
||||
|
@ -1525,7 +1525,10 @@ test("content_browsertests") {
|
||||
"//mojo/public/cpp/platform",
|
||||
"//mojo/public/mojom/base",
|
||||
]
|
||||
data_deps += [ "//content/shell:content_shell" ]
|
||||
data_deps += [
|
||||
"//content/shell:content_shell",
|
||||
"//mojo/core:shared_library",
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_chrome_branded) {
|
||||
|
@ -361,8 +361,7 @@ int Main(const MainParams& params) {
|
||||
mojo_config.is_broker_process = true;
|
||||
}
|
||||
mojo_config.max_message_num_bytes = kMaximumMojoMessageSize;
|
||||
delegate->OverrideMojoConfiguration(&mojo_config);
|
||||
mojo::core::Init(mojo_config);
|
||||
delegate->InitializeMojo(&mojo_config);
|
||||
|
||||
ui::RegisterPathProvider();
|
||||
|
||||
|
@ -24,8 +24,7 @@ ProcessType MainDelegate::OverrideProcessType() {
|
||||
return ProcessType::kDefault;
|
||||
}
|
||||
|
||||
void MainDelegate::OverrideMojoConfiguration(
|
||||
mojo::core::Configuration* config) {}
|
||||
void MainDelegate::InitializeMojo(mojo::core::Configuration* config) {}
|
||||
|
||||
std::vector<Manifest> MainDelegate::GetServiceManifests() {
|
||||
return std::vector<Manifest>();
|
||||
|
@ -71,8 +71,9 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER) MainDelegate {
|
||||
// return |ProcessType::kDefault| to avoid overriding.
|
||||
virtual ProcessType OverrideProcessType();
|
||||
|
||||
// Allows the embedder to override the process-wide Mojop configuration.
|
||||
virtual void OverrideMojoConfiguration(mojo::core::Configuration* config);
|
||||
// Allows the embedder to override the process-wide Mojo configuration and
|
||||
// initialization.
|
||||
virtual void InitializeMojo(mojo::core::Configuration* config);
|
||||
|
||||
// Gets the list of service manifests with which to initialize the Service
|
||||
// Manager. This list must describe the complete set of usable services in
|
||||
|
Reference in New Issue
Block a user