Remove mojo core shared library support
Don't build it anymore and don't depend on it anywhere. Bug: 359926651 Change-Id: Id6c84d1ddb4f0080a3e0cda99487efa31beba9fa Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5792650 Reviewed-by: Yuzhu Shen <yzshen@chromium.org> Reviewed-by: Francois Pierre Doray <fdoray@chromium.org> Commit-Queue: Ken Rockot <rockot@google.com> Reviewed-by: Erik Staab <estaab@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Cr-Commit-Position: refs/heads/main@{#1342938}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
311a10f616
commit
b8094422db
base/threading
chrome
content
app
browser
child
common
public
test
infra/archive_config
mojo
@@ -355,7 +355,6 @@ namespace module_installer {
|
||||
class ScopedAllowModulePakLoad;
|
||||
}
|
||||
namespace mojo {
|
||||
class CoreLibraryInitializer;
|
||||
class SyncCallRestrictions;
|
||||
namespace core {
|
||||
class ScopedIPCSupport;
|
||||
@@ -644,7 +643,6 @@ class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBlocking {
|
||||
friend class metrics::AndroidMetricsServiceClient;
|
||||
friend class metrics::CleanExitBeacon;
|
||||
friend class module_installer::ScopedAllowModulePakLoad;
|
||||
friend class mojo::CoreLibraryInitializer;
|
||||
friend class net::GSSAPISharedLibrary; // http://crbug.com/66702
|
||||
friend class net::ProxyConfigServiceWin; // http://crbug.com/61453
|
||||
friend class net::
|
||||
|
@@ -24,7 +24,6 @@ import("//components/nacl/features.gni")
|
||||
import("//components/optimization_guide/features.gni")
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
import("//media/media_options.gni")
|
||||
import("//mojo/features.gni")
|
||||
import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//third_party/blink/public/public_features.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
@@ -370,10 +369,6 @@ if (!is_android && !is_mac) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((is_chromeos_ash || is_win) && mojo_support_legacy_core) {
|
||||
data_deps += [ "//mojo/core:shared_library" ]
|
||||
}
|
||||
|
||||
# These files are used by the installer so we need a public dep.
|
||||
public_deps += [ ":packed_resources" ]
|
||||
|
||||
|
@@ -8,7 +8,6 @@ import("//build/config/python.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/timestamp.gni")
|
||||
import("//chrome/process_version_rc_template.gni")
|
||||
import("//mojo/features.gni")
|
||||
import("//third_party/dawn/scripts/dawn_features.gni")
|
||||
import("//third_party/ffmpeg/ffmpeg_options.gni")
|
||||
import("//third_party/icu/config.gni")
|
||||
@@ -243,10 +242,6 @@ action("mini_installer_archive") {
|
||||
args += [ "--include_dxc=1" ]
|
||||
}
|
||||
|
||||
if (mojo_support_legacy_core) {
|
||||
deps += [ "//mojo/core:shared_library" ]
|
||||
}
|
||||
|
||||
depfile = "$target_gen_dir/archive.d"
|
||||
args += [
|
||||
"--depfile",
|
||||
|
@@ -33,14 +33,12 @@
|
||||
#include "components/tracing/common/trace_to_console.h"
|
||||
#include "components/tracing/common/tracing_switches.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 "mojo/core/embedder/configuration.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
#include "mojo/core/embedder/scoped_ipc_support.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "partition_alloc/buildflags.h"
|
||||
#include "sandbox/policy/sandbox_type.h"
|
||||
#include "ui/base/ui_base_paths.h"
|
||||
|
@@ -74,7 +74,6 @@
|
||||
#include "content/browser/utility_process_host.h"
|
||||
#include "content/child/field_trial.h"
|
||||
#include "content/common/content_constants_internal.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/common/process_visibility_tracker.h"
|
||||
#include "content/common/url_schemes.h"
|
||||
#include "content/gpu/in_process_gpu_thread.h"
|
||||
@@ -105,7 +104,6 @@
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/sync_call_restrictions.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/cpp/system/message_pipe.h"
|
||||
#include "net/first_party_sets/local_set_declaration.h"
|
||||
@@ -338,7 +336,6 @@ pid_t LaunchZygoteHelper(base::CommandLine* cmd_line,
|
||||
// becomes a renderer process.
|
||||
switches::kForceDeviceScaleFactor,
|
||||
switches::kLoggingLevel,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kPpapiInProcess,
|
||||
switches::kRegisterPepperPlugins,
|
||||
switches::kV,
|
||||
@@ -1132,18 +1129,6 @@ int NO_STACK_PROTECTOR ContentMainRunnerImpl::Run() {
|
||||
base::allocator::PartitionAllocSupport::Get()
|
||||
->ReconfigureAfterFeatureListInit(process_type);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
// 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 // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
}
|
||||
|
||||
MainFunctionParams main_params(command_line);
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include "base/feature_list.h"
|
||||
#include "base/logging.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "mojo/core/embedder/configuration.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
@@ -17,7 +16,6 @@
|
||||
#include "mojo/public/c/system/types.h"
|
||||
#include "mojo/public/cpp/base/shared_memory_utils.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "sandbox/policy/sandbox_type.h"
|
||||
|
||||
namespace content {
|
||||
@@ -58,18 +56,7 @@ void InitializeMojoCore() {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!IsMojoCoreSharedLibraryEnabled()) {
|
||||
mojo::core::Init(config);
|
||||
} else if (is_browser) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Note #1: the installed shared memory hooks require a live instance of
|
||||
// mojo::core::ScopedIPCSupport to function, which is instantiated below by
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include "content/browser/browser_process_io_thread.h"
|
||||
#include "content/browser/startup_data_impl.h"
|
||||
#include "content/common/features.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
#include "mojo/core/embedder/scoped_ipc_support.h"
|
||||
|
||||
@@ -23,18 +22,13 @@ MojoIpcSupport::MojoIpcSupport(
|
||||
: io_thread_(std::move(io_thread)) {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> mojo_ipc_task_runner =
|
||||
io_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_task_runner, mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||
}
|
||||
|
||||
MojoIpcSupport::~MojoIpcSupport() = default;
|
||||
|
@@ -326,7 +326,6 @@ void BrowserChildProcessHostImpl::LaunchWithoutExtraCommandLineSwitches(
|
||||
switches::kDisableBestEffortTasks,
|
||||
switches::kIPCConnectionTimeout,
|
||||
switches::kLogBestEffortTasks,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kPerfettoDisableInterning,
|
||||
switches::kTraceToConsole,
|
||||
};
|
||||
|
@@ -41,7 +41,6 @@ namespace {
|
||||
const char kShellExecutableName[] = "content_shell.exe";
|
||||
#else
|
||||
const char kShellExecutableName[] = "content_shell";
|
||||
const char kMojoCoreLibraryName[] = "libmojo_core.so";
|
||||
#endif
|
||||
|
||||
base::FilePath GetCurrentDirectory() {
|
||||
@@ -136,12 +135,6 @@ class LaunchAsMojoClientBrowserTest : public ContentBrowserTest {
|
||||
return controller;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
base::FilePath GetMojoCoreLibraryPath() {
|
||||
return GetFilePathNextToCurrentExecutable(kMojoCoreLibraryName);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
base::FilePath GetFilePathNextToCurrentExecutable(
|
||||
const std::string& filename) {
|
||||
@@ -195,43 +188,5 @@ IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest, LaunchAndBindInterface) {
|
||||
}
|
||||
#endif // !BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
// TODO(crbug.com/40057593): This test implementation fundamentally conflicts
|
||||
// with a fix for the linked bug because it causes a browser process to behave
|
||||
// partially as a broker and partially as a non-broker. This can be re-enabled
|
||||
// when we migrate away from the current Mojo implementation. It's OK to disable
|
||||
// for now because no production code relies on this feature.
|
||||
IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest,
|
||||
DISABLED_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 // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
|
||||
} // namespace
|
||||
} // namespace content
|
||||
|
@@ -3259,7 +3259,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
switches::kAllowLoopbackInPeerConnection,
|
||||
switches::kAudioBufferSize,
|
||||
switches::kAutoplayPolicy,
|
||||
switches::kMojoCoreLibraryPath,
|
||||
switches::kDisable2dCanvasImageChromium,
|
||||
switches::kDisableYUVImageDecoding,
|
||||
switches::kDisableAcceleratedVideoDecode,
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "base/clang_profiling_buildflags.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/message_loop/message_pump_type.h"
|
||||
#include "base/process/process_handle.h"
|
||||
@@ -18,10 +17,7 @@
|
||||
#include "build/build_config.h"
|
||||
#include "build/config/compiler/compiler_buildflags.h"
|
||||
#include "content/child/child_thread_impl.h"
|
||||
#include "content/common/mojo_core_library_support.h"
|
||||
#include "content/common/process_visibility_tracker.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "sandbox/policy/sandbox_type.h"
|
||||
#include "services/tracing/public/cpp/trace_startup.h"
|
||||
#include "third_party/abseil-cpp/absl/base/attributes.h"
|
||||
@@ -70,25 +66,6 @@ ChildProcess::ChildProcess(base::ThreadType io_thread_type,
|
||||
thread_pool_init_params)
|
||||
: resetter_(&child_process, this, nullptr),
|
||||
io_thread_(std::make_unique<ChildIOThread>()) {
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
const bool is_embedded_in_browser_process =
|
||||
!command_line.HasSwitch(switches::kProcessType);
|
||||
if (IsMojoCoreSharedLibraryEnabled() && !is_embedded_in_browser_process) {
|
||||
// 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 (sandbox::policy::IsUnsandboxedSandboxType(
|
||||
sandbox::policy::SandboxTypeFromCommandLine(command_line))) {
|
||||
flags |= MOJO_INITIALIZE_FLAG_FORCE_DIRECT_SHARED_MEMORY_ALLOCATION;
|
||||
}
|
||||
CHECK_EQ(MOJO_RESULT_OK, mojo::InitializeCoreLibrary(flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start ThreadPoolInstance if not already done. A ThreadPoolInstance
|
||||
// should already exist, and may already be running when ChildProcess is
|
||||
// instantiated in the browser process or in a test process.
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "content/common/features.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/common/pseudonymization_salt.h"
|
||||
#include "content/public/child/child_thread.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
@@ -645,8 +644,6 @@ void ChildThreadImpl::Init(const Options& options) {
|
||||
mojo::ScopedMessagePipeHandle child_process_host_pipe_for_remote;
|
||||
mojo::ScopedMessagePipeHandle legacy_ipc_bootstrap_pipe;
|
||||
if (!IsInBrowserProcess()) {
|
||||
// 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)) {
|
||||
@@ -657,7 +654,7 @@ void ChildThreadImpl::Init(const Options& options) {
|
||||
mojo_ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
|
||||
mojo_ipc_task_runner,
|
||||
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||
}
|
||||
|
||||
mojo::IncomingInvitation invitation = InitializeMojoIPCChannel();
|
||||
if (!invitation.is_valid()) {
|
||||
LOG(ERROR) << "Child process could not find its Mojo invitation";
|
||||
|
@@ -156,8 +156,6 @@ source_set("common") {
|
||||
"input/synthetic_touchscreen_pinch_gesture.cc",
|
||||
"input/synthetic_touchscreen_pinch_gesture.h",
|
||||
"media/cdm_info.cc",
|
||||
"mojo_core_library_support.cc",
|
||||
"mojo_core_library_support.h",
|
||||
"navigation_gesture.h",
|
||||
"navigation_params_utils.h",
|
||||
"origin_util.cc",
|
||||
|
@@ -1,31 +0,0 @@
|
||||
// Copyright 2020 The Chromium Authors
|
||||
// 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() != std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<base::FilePath> GetMojoCoreSharedLibraryPath() {
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kMojoCoreLibraryPath))
|
||||
return std::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 std::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace content
|
@@ -1,26 +0,0 @@
|
||||
// Copyright 2020 The Chromium Authors
|
||||
// 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 <optional>
|
||||
|
||||
#include "base/files/file_path.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.
|
||||
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.
|
||||
std::optional<base::FilePath> GetMojoCoreSharedLibraryPath();
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_COMMON_MOJO_CORE_LIBRARY_SUPPORT_H_
|
@@ -526,10 +526,6 @@ 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";
|
||||
|
||||
|
@@ -159,7 +159,6 @@ 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 kNoUnsandboxedZygote[];
|
||||
CONTENT_EXPORT extern const char kNoZygote[];
|
||||
|
@@ -2225,10 +2225,7 @@ test("content_browsertests") {
|
||||
"//mojo/public/cpp/platform",
|
||||
"//mojo/public/mojom/base",
|
||||
]
|
||||
data_deps += [
|
||||
"//content/shell:content_shell",
|
||||
"//mojo/core:shared_library",
|
||||
]
|
||||
data_deps += [ "//content/shell:content_shell" ]
|
||||
if (use_ozone) {
|
||||
deps += [ "//ui/ozone" ]
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@
|
||||
"libEGL.so",
|
||||
"libGLESv2.so",
|
||||
"libminigbm.so",
|
||||
"libmojo_core.so",
|
||||
"MEIPreload/manifest.json",
|
||||
"MEIPreload/preloaded_data.pb",
|
||||
"nacl_helper",
|
||||
|
@@ -53,29 +53,6 @@ executables built within the tree.
|
||||
|
||||
To support other scenarios, use dynamic linking.
|
||||
|
||||
### Dynamic Linking
|
||||
On some platforms, it's also possible for applications to rely on a
|
||||
dynamically-linked Mojo Core library (`libmojo_core.so` or `mojo_core.dll`)
|
||||
instead of statically linking against Mojo Core.
|
||||
|
||||
In order to take advantage of this mechanism, the library's binary must be
|
||||
present in either:
|
||||
|
||||
- The working directory of the application
|
||||
- A directory named by the `MOJO_CORE_LIBRARY_PATH` environment variable
|
||||
- A directory named explicitly by the application at runtime
|
||||
|
||||
Instead of calling `mojo::core::Init()` as embedders do, an application using
|
||||
dynamic Mojo Core instead calls `MojoInitialize()` from the C System API. This
|
||||
call will attempt to locate (see above) and load the Mojo Core library to
|
||||
support subsequent Mojo API usage within the process.
|
||||
|
||||
Note that the Mojo Core shared library presents a **stable C ABI** designed with
|
||||
both forward- and backward-compatibility in mind. Thus old applications will
|
||||
work with new versions of the shared library, and new applications can work
|
||||
with old versions of the shared library (modulo any dependency on newer
|
||||
features, whose absence can be gracefully detected at runtime).
|
||||
|
||||
## C System API
|
||||
Once Mojo is initialized within a process, the public
|
||||
[**C System API**](/mojo/public/c/system/README.md) is usable on any thread for
|
||||
|
@@ -5,7 +5,6 @@
|
||||
import("//build/config/chromeos/ui_mode.gni")
|
||||
import("//build/config/compiler/compiler.gni")
|
||||
import("//build/config/nacl/config.gni")
|
||||
import("//chrome/process_version_rc_template.gni")
|
||||
import("//mojo/features.gni")
|
||||
import("//testing/libfuzzer/fuzzer_test.gni")
|
||||
import("//testing/test.gni")
|
||||
@@ -29,22 +28,11 @@ component("embedder_internal") {
|
||||
# Bits of the EDK library which do not depend on public API linkage. It is
|
||||
# not allowed for this target or any of its transitive dependencies to depend
|
||||
# on anything under //mojo/public beyond strict C type definitions.
|
||||
#
|
||||
# This is templated because it's consumed by both the ":embedder_internal"
|
||||
# component library as well as the ":mojo_core" shared library. In the former
|
||||
# case we want to export symbols, but in the latter case we don't. The template
|
||||
# stamps out two nearly identical targets which differ only in what symbols they
|
||||
# export.
|
||||
template("core_impl_source_set") {
|
||||
source_set(target_name) {
|
||||
if (invoker.for_shared_library) {
|
||||
visibility = [ ":shared_library" ]
|
||||
} else {
|
||||
source_set("impl_for_embedder") {
|
||||
visibility = [
|
||||
":core_impl_for_fuzzers",
|
||||
":embedder_internal",
|
||||
]
|
||||
}
|
||||
|
||||
public = [
|
||||
"channel.h",
|
||||
@@ -196,13 +184,7 @@ template("core_impl_source_set") {
|
||||
|
||||
configs += [ "//build/config/compiler:wexit_time_destructors" ]
|
||||
|
||||
defines = []
|
||||
if (invoker.for_shared_library) {
|
||||
defines += [ "MOJO_CORE_SHARED_LIBRARY" ]
|
||||
} else {
|
||||
defines += [ "MOJO_SYSTEM_IMPL_IMPLEMENTATION" ]
|
||||
}
|
||||
|
||||
defines = [ "MOJO_SYSTEM_IMPL_IMPLEMENTATION" ]
|
||||
deps = []
|
||||
if (is_android) {
|
||||
sources += [
|
||||
@@ -233,11 +215,6 @@ template("core_impl_source_set") {
|
||||
configs -= [ "//build/config/compiler:default_optimization" ]
|
||||
configs += [ "//build/config/compiler:optimize_max" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
core_impl_source_set("impl_for_embedder") {
|
||||
for_shared_library = false
|
||||
}
|
||||
|
||||
source_set("driver_for_ipcz_tests") {
|
||||
@@ -251,66 +228,6 @@ source_set("driver_for_ipcz_tests") {
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
process_version_rc_template("mojo_core_version") {
|
||||
sources = [ "mojo_core.ver" ]
|
||||
output = "$target_gen_dir/mojo_core_version.rc"
|
||||
}
|
||||
}
|
||||
|
||||
if ((is_chromeos || is_linux || is_android || is_win || is_fuchsia) &&
|
||||
mojo_support_legacy_core) {
|
||||
core_impl_source_set("impl_for_shared_library") {
|
||||
for_shared_library = true
|
||||
}
|
||||
|
||||
shared_library("shared_library") {
|
||||
output_name = "mojo_core"
|
||||
sources = [ "mojo_core.cc" ]
|
||||
configs += [ "//build/config/compiler:wexit_time_destructors" ]
|
||||
defines = [ "MOJO_CORE_SHARED_LIBRARY" ]
|
||||
deps = [
|
||||
":impl_for_shared_library",
|
||||
"//base:base_static",
|
||||
"//mojo/public/c/system:headers",
|
||||
]
|
||||
if (is_win) {
|
||||
sources += [ "mojo_core.def" ]
|
||||
deps += [ ":mojo_core_version" ]
|
||||
} else {
|
||||
configs += [ ":export_only_thunks_api" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("export_only_thunks_api") {
|
||||
inputs = [ "export_only_thunks_api.lst" ]
|
||||
ldflags = [ "-Wl,--version-script=" +
|
||||
rebase_path("//mojo/core/export_only_thunks_api.lst",
|
||||
root_build_dir) ]
|
||||
}
|
||||
|
||||
if (is_chromeos || is_linux || is_win || is_fuchsia) {
|
||||
test("mojo_core_unittests") {
|
||||
sources = [
|
||||
"mojo_core_unittest.cc",
|
||||
"mojo_core_unittest.h",
|
||||
"run_all_core_unittests.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//mojo/public/c/system",
|
||||
"//mojo/public/cpp/platform",
|
||||
"//mojo/public/cpp/system",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
data_deps = [ ":shared_library" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source_set("test_sources") {
|
||||
testonly = true
|
||||
sources = [
|
||||
|
@@ -1,12 +0,0 @@
|
||||
# Copyright 2018 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Linker script that ensures only MojoGetSystemThunks is exposed from the
|
||||
# mojo_core library.
|
||||
{
|
||||
global:
|
||||
MojoGetSystemThunks;
|
||||
local:
|
||||
*;
|
||||
};
|
@@ -1,228 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "base/at_exit.h"
|
||||
#include "base/base_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/message_loop/message_pump_type.h"
|
||||
#include "base/metrics/field_trial.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/rand_util.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/time/time.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/core/configuration.h"
|
||||
#include "mojo/core/core.h"
|
||||
#include "mojo/core/entrypoints.h"
|
||||
#include "mojo/public/c/system/core.h"
|
||||
#include "mojo/public/c/system/macros.h"
|
||||
#include "mojo/public/c/system/thunks.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class IPCSupport {
|
||||
public:
|
||||
IPCSupport() : ipc_thread_("Mojo IPC") {
|
||||
base::Thread::Options options(base::MessagePumpType::IO, 0);
|
||||
ipc_thread_.StartWithOptions(std::move(options));
|
||||
mojo::core::Core::Get()->SetIOTaskRunner(ipc_thread_.task_runner());
|
||||
}
|
||||
|
||||
IPCSupport(const IPCSupport&) = delete;
|
||||
IPCSupport& operator=(const IPCSupport&) = delete;
|
||||
|
||||
~IPCSupport() {
|
||||
base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::MANUAL,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED);
|
||||
mojo::core::Core::Get()->RequestShutdown(
|
||||
base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&wait)));
|
||||
wait.Wait();
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(COMPONENT_BUILD)
|
||||
// NOTE: For component builds, we assume the consumer is always a target in
|
||||
// the Chromium tree which already depends on base initialization stuff and
|
||||
// therefore already has an AtExitManager. For non-component builds, use of
|
||||
// this AtExitManager is strictly isolated to Mojo Core internals, so running
|
||||
// hooks on |MojoShutdown()| (where |this| is destroyed) makes sense.
|
||||
base::AtExitManager at_exit_manager_;
|
||||
#endif // !defined(COMPONENT_BUILD)
|
||||
|
||||
base::Thread ipc_thread_;
|
||||
};
|
||||
|
||||
std::unique_ptr<IPCSupport>& GetIPCSupport() {
|
||||
static base::NoDestructor<std::unique_ptr<IPCSupport>> state;
|
||||
return *state;
|
||||
}
|
||||
|
||||
// This helper is only called from within the context of a newly loaded Mojo
|
||||
// Core shared library, where various bits of static state (e.g. //base globals)
|
||||
// will not yet be initialized. Base library initialization steps are thus
|
||||
// consolidated here so that base APIs work as expected from within the loaded
|
||||
// Mojo Core implementation.
|
||||
//
|
||||
// NOTE: This is a no-op in component builds, as we expect both the client
|
||||
// application and the Mojo Core library to have been linked against the same
|
||||
// base component library, and we furthermore expect that the client application
|
||||
// has already initialized base globals by this point.
|
||||
class GlobalStateInitializer {
|
||||
public:
|
||||
GlobalStateInitializer() = default;
|
||||
~GlobalStateInitializer() = delete;
|
||||
|
||||
bool Initialize(int argc, const char* const* argv) {
|
||||
if (initialized_)
|
||||
return false;
|
||||
initialized_ = true;
|
||||
#if !defined(COMPONENT_BUILD)
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
settings.logging_dest =
|
||||
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
|
||||
logging::InitLogging(settings);
|
||||
logging::SetLogItems(true, // Process ID
|
||||
true, // Thread ID
|
||||
true, // Timestamp
|
||||
true); // Tick count
|
||||
|
||||
#if !defined(OFFICIAL_BUILD) && !BUILDFLAG(IS_WIN)
|
||||
// Correct stack dumping behavior requires symbol names in all loaded
|
||||
// libraries to be cached. We do this here in case the calling process will
|
||||
// imminently enter a sandbox.
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_POSIX)
|
||||
// Tickle base's PRNG. This lazily opens a static handle to /dev/urandom.
|
||||
// Mojo Core uses the API internally, so it's important to warm the handle
|
||||
// before potentially entering a sandbox.
|
||||
base::RandUint64();
|
||||
#endif
|
||||
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
// If FieldTrialList::GetInstance() returns nullptr,
|
||||
// FeatureList::InitFromCommandLine(), used by FeatureList::
|
||||
// InitInstance internally, creates no field trials. This causes
|
||||
// DCHECK() failure if we have an command line like
|
||||
// --enable-features=TestFeature:TestParam/TestValue.
|
||||
// We don't need to care about FieldTrialList duplication here, because
|
||||
// this code is available for static build. If base library is not shared,
|
||||
// libmojo_core.so and the caller of LoadAndInitializeCoreLibrary doesn't
|
||||
// share FieldTrialList::GetInstance().
|
||||
field_trial_list_ = std::make_unique<base::FieldTrialList>();
|
||||
base::FeatureList::InitInstance(
|
||||
command_line->GetSwitchValueASCII(switches::kEnableFeatures),
|
||||
command_line->GetSwitchValueASCII(switches::kDisableFeatures));
|
||||
#endif // !defined(COMPONENT_BUILD)
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool initialized_ = false;
|
||||
std::unique_ptr<base::FieldTrialList> field_trial_list_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
namespace {
|
||||
|
||||
MojoResult InitializeImpl(const struct MojoInitializeOptions* options) {
|
||||
std::unique_ptr<IPCSupport>& ipc_support = GetIPCSupport();
|
||||
if (ipc_support) {
|
||||
// Already fully initialized, so there's nothing to do.
|
||||
return MOJO_RESULT_FAILED_PRECONDITION;
|
||||
}
|
||||
|
||||
// NOTE: |MojoInitialize()| may be called more than once if the caller wishes
|
||||
// to separate basic initialization from IPC support initialization. We only
|
||||
// do basic initialization the first time this is called.
|
||||
const bool should_initialize_ipc_support =
|
||||
!options || ((options->flags & MOJO_INITIALIZE_FLAG_LOAD_ONLY) == 0);
|
||||
|
||||
int argc = 0;
|
||||
const char* const* argv = nullptr;
|
||||
if (options && MOJO_IS_STRUCT_FIELD_PRESENT(options, argv)) {
|
||||
argc = options->argc;
|
||||
argv = options->argv;
|
||||
}
|
||||
|
||||
static base::NoDestructor<GlobalStateInitializer> global_state_initializer;
|
||||
const bool was_global_state_already_initialized =
|
||||
!global_state_initializer->Initialize(argc, argv);
|
||||
|
||||
if (!should_initialize_ipc_support) {
|
||||
if (was_global_state_already_initialized)
|
||||
return MOJO_RESULT_ALREADY_EXISTS;
|
||||
else
|
||||
return MOJO_RESULT_OK;
|
||||
}
|
||||
|
||||
DCHECK(!mojo::core::Core::Get());
|
||||
mojo::core::Configuration config;
|
||||
config.is_broker_process =
|
||||
options && options->flags & MOJO_INITIALIZE_FLAG_AS_BROKER;
|
||||
config.force_direct_shared_memory_allocation =
|
||||
options && options->flags &
|
||||
MOJO_INITIALIZE_FLAG_FORCE_DIRECT_SHARED_MEMORY_ALLOCATION;
|
||||
mojo::core::internal::g_configuration = config;
|
||||
mojo::core::InitializeCore();
|
||||
ipc_support = std::make_unique<IPCSupport>();
|
||||
|
||||
return MOJO_RESULT_OK;
|
||||
}
|
||||
|
||||
MojoResult ShutdownImpl(const struct MojoShutdownOptions* options) {
|
||||
if (options && options->struct_size < sizeof(*options))
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
|
||||
std::unique_ptr<IPCSupport>& ipc_support = GetIPCSupport();
|
||||
if (!ipc_support)
|
||||
return MOJO_RESULT_FAILED_PRECONDITION;
|
||||
|
||||
ipc_support.reset();
|
||||
return MOJO_RESULT_OK;
|
||||
}
|
||||
|
||||
MojoSystemThunks2 g_thunks = {0};
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(WIN32)
|
||||
#define EXPORT_FROM_MOJO_CORE __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT_FROM_MOJO_CORE __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
EXPORT_FROM_MOJO_CORE void MojoGetSystemThunks(MojoSystemThunks2* thunks) {
|
||||
if (!g_thunks.size) {
|
||||
g_thunks = mojo::core::GetSystemThunks();
|
||||
g_thunks.Initialize = InitializeImpl;
|
||||
g_thunks.Shutdown = ShutdownImpl;
|
||||
}
|
||||
|
||||
// Caller must provide a thunk structure at least large enough to hold Core
|
||||
// ABI version 0. SetQuota is the first function introduced in ABI version 1.
|
||||
CHECK_GE(thunks->size, offsetof(MojoSystemThunks2, SetQuota));
|
||||
|
||||
// NOTE: This also overrites |thunks->size| with the actual size of our own
|
||||
// thunks if smaller than the caller's. This informs the caller that we
|
||||
// implement an older version of the ABI.
|
||||
if (thunks->size > g_thunks.size)
|
||||
thunks->size = g_thunks.size;
|
||||
memcpy(thunks, &g_thunks, thunks->size);
|
||||
}
|
||||
|
||||
} // extern "C"
|
@@ -1,10 +0,0 @@
|
||||
; Copyright 2018 The Chromium Authors
|
||||
; Use of this source code is governed by a BSD-style license that can be
|
||||
; found in the LICENSE file.
|
||||
|
||||
; Ensure that we export only MojoGetSystemThunks from the mojo_core library.
|
||||
|
||||
LIBRARY "mojo_core.dll"
|
||||
|
||||
EXPORTS
|
||||
MojoGetSystemThunks
|
@@ -1,2 +0,0 @@
|
||||
INTERNAL_NAME=mojo_core
|
||||
ORIGINAL_FILENAME=mojo_core.dll
|
@@ -1,146 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/test/multiprocess_test.h"
|
||||
#include "base/test/test_timeouts.h"
|
||||
#include "mojo/core/mojo_core_unittest.h"
|
||||
#include "mojo/public/c/system/core.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/platform/platform_handle.h"
|
||||
#include "mojo/public/cpp/system/invitation.h"
|
||||
#include "mojo/public/cpp/system/message_pipe.h"
|
||||
#include "mojo/public/cpp/system/wait.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "testing/multiprocess_func_list.h"
|
||||
|
||||
namespace switches {
|
||||
const char kMojoLoadBeforeInit[] = "mojo-load-before-init";
|
||||
const char kMojoUseExplicitLibraryPath[] = "mojo-use-explicit-library-path";
|
||||
} // namespace switches
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(crbug.com/41424555): Re-enable this on MSAN. Currently hangs
|
||||
// because of an apparent deadlock in MSAN's fork() in multithreaded
|
||||
// environments.
|
||||
#if !defined(MEMORY_SANITIZER)
|
||||
|
||||
uint64_t kTestPipeName = 0;
|
||||
const char kTestMessage[] = "hai";
|
||||
const char kTestReply[] = "bai";
|
||||
|
||||
std::string ReadMessageAsString(mojo::MessagePipeHandle handle) {
|
||||
std::vector<uint8_t> data;
|
||||
CHECK_EQ(MOJO_RESULT_OK, mojo::ReadMessageRaw(handle, &data, nullptr,
|
||||
MOJO_READ_MESSAGE_FLAG_NONE));
|
||||
return std::string(data.begin(), data.end());
|
||||
}
|
||||
|
||||
TEST(MojoCoreTest, SanityCheck) {
|
||||
// Exercises some APIs against the mojo_core library and expects them to work
|
||||
// as intended.
|
||||
|
||||
MojoHandle a, b;
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &a, &b));
|
||||
|
||||
MojoMessageHandle m;
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessage(nullptr, &m));
|
||||
EXPECT_EQ(MOJO_RESULT_OK,
|
||||
MojoSetMessageContext(m, 42, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoWriteMessage(a, m, nullptr));
|
||||
m = MOJO_MESSAGE_HANDLE_INVALID;
|
||||
|
||||
MojoHandleSignalsState state;
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(b, &state));
|
||||
EXPECT_TRUE(state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
|
||||
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoReadMessage(b, nullptr, &m));
|
||||
|
||||
uintptr_t context = 0;
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoGetMessageContext(m, nullptr, &context));
|
||||
EXPECT_EQ(42u, context);
|
||||
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(m));
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
|
||||
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
|
||||
}
|
||||
|
||||
enum class InitializationMode { kCombinedLoadAndInit, kLoadBeforeInit };
|
||||
|
||||
enum class LoadPathSpec { kImplicit, kExplicit };
|
||||
|
||||
class MojoCoreMultiprocessTest
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<InitializationMode, LoadPathSpec>> {
|
||||
public:
|
||||
void SetChildCommandLineForTestParams(base::CommandLine* command_line) {
|
||||
if (std::get<0>(GetParam()) == InitializationMode::kLoadBeforeInit)
|
||||
command_line->AppendSwitch(switches::kMojoLoadBeforeInit);
|
||||
if (std::get<1>(GetParam()) == LoadPathSpec::kExplicit)
|
||||
command_line->AppendSwitch(switches::kMojoUseExplicitLibraryPath);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(MojoCoreMultiprocessTest, BasicMultiprocess) {
|
||||
base::CommandLine child_cmd(base::GetMultiProcessTestChildBaseCommandLine());
|
||||
SetChildCommandLineForTestParams(&child_cmd);
|
||||
|
||||
base::LaunchOptions options;
|
||||
mojo::PlatformChannel channel;
|
||||
channel.PrepareToPassRemoteEndpoint(&options, &child_cmd);
|
||||
base::Process child_process = base::SpawnMultiProcessTestChild(
|
||||
"BasicMultiprocessClientMain", child_cmd, options);
|
||||
channel.RemoteProcessLaunchAttempted();
|
||||
|
||||
mojo::OutgoingInvitation invitation;
|
||||
auto child_pipe = invitation.AttachMessagePipe(kTestPipeName);
|
||||
mojo::OutgoingInvitation::Send(std::move(invitation), child_process.Handle(),
|
||||
channel.TakeLocalEndpoint());
|
||||
|
||||
mojo::Wait(child_pipe.get(), MOJO_HANDLE_SIGNAL_READABLE);
|
||||
EXPECT_EQ(kTestMessage, ReadMessageAsString(child_pipe.get()));
|
||||
|
||||
mojo::WriteMessageRaw(child_pipe.get(), kTestReply, sizeof(kTestReply) - 1,
|
||||
nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
|
||||
|
||||
int rv = -1;
|
||||
ASSERT_TRUE(base::WaitForMultiprocessTestChildExit(
|
||||
child_process, TestTimeouts::action_timeout(), &rv));
|
||||
EXPECT_EQ(0, rv);
|
||||
}
|
||||
|
||||
MULTIPROCESS_TEST_MAIN(BasicMultiprocessClientMain) {
|
||||
auto endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(
|
||||
*base::CommandLine::ForCurrentProcess());
|
||||
auto invitation = mojo::IncomingInvitation::Accept(std::move(endpoint));
|
||||
auto parent_pipe = invitation.ExtractMessagePipe(kTestPipeName);
|
||||
|
||||
mojo::WriteMessageRaw(parent_pipe.get(), kTestMessage,
|
||||
sizeof(kTestMessage) - 1, nullptr, 0,
|
||||
MOJO_WRITE_MESSAGE_FLAG_NONE);
|
||||
|
||||
mojo::Wait(parent_pipe.get(), MOJO_HANDLE_SIGNAL_READABLE);
|
||||
EXPECT_EQ(kTestReply, ReadMessageAsString(parent_pipe.get()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
,
|
||||
MojoCoreMultiprocessTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(InitializationMode::kCombinedLoadAndInit,
|
||||
InitializationMode::kLoadBeforeInit),
|
||||
::testing::Values(LoadPathSpec::kImplicit, LoadPathSpec::kExplicit)));
|
||||
|
||||
#endif // !defined(MEMORY_SANITIZER)
|
||||
|
||||
} // namespace
|
@@ -1,70 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "base/base_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/test/launcher/unit_test_launcher.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/test_suite.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/core/mojo_core_unittest.h"
|
||||
#include "mojo/public/c/system/core.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
|
||||
base::FilePath GetMojoCoreLibraryPath() {
|
||||
#if BUILDFLAG(IS_FUCHSIA)
|
||||
return base::FilePath("libmojo_core.so");
|
||||
#else // BUILDFLAG(IS_FUCHSIA)
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const char kLibraryFilename[] = "mojo_core.dll";
|
||||
#else
|
||||
const char kLibraryFilename[] = "libmojo_core.so";
|
||||
#endif
|
||||
base::FilePath executable_dir =
|
||||
base::CommandLine::ForCurrentProcess()->GetProgram().DirName();
|
||||
if (executable_dir.IsAbsolute())
|
||||
return executable_dir.AppendASCII(kLibraryFilename);
|
||||
|
||||
base::FilePath current_directory;
|
||||
CHECK(base::GetCurrentDirectory(¤t_directory));
|
||||
return current_directory.Append(executable_dir).AppendASCII(kLibraryFilename);
|
||||
|
||||
#endif // BUILDFLAG(IS_FUCHSIA)
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
base::TestSuite test_suite(argc, argv);
|
||||
|
||||
MojoInitializeFlags flags = MOJO_INITIALIZE_FLAG_NONE;
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kTestChildProcess))
|
||||
flags |= MOJO_INITIALIZE_FLAG_AS_BROKER;
|
||||
|
||||
std::optional<base::FilePath> library_path;
|
||||
if (command_line.HasSwitch(switches::kMojoUseExplicitLibraryPath))
|
||||
library_path = GetMojoCoreLibraryPath();
|
||||
|
||||
if (command_line.HasSwitch(switches::kMojoLoadBeforeInit)) {
|
||||
CHECK_EQ(MOJO_RESULT_OK, mojo::LoadCoreLibrary(library_path));
|
||||
CHECK_EQ(MOJO_RESULT_OK, mojo::InitializeCoreLibrary(flags));
|
||||
} else {
|
||||
CHECK_EQ(MOJO_RESULT_OK,
|
||||
mojo::LoadAndInitializeCoreLibrary(library_path, flags));
|
||||
}
|
||||
|
||||
int result = base::LaunchUnitTests(
|
||||
argc, argv,
|
||||
base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
|
||||
|
||||
CHECK_EQ(MOJO_RESULT_OK, MojoShutdown(nullptr));
|
||||
return result;
|
||||
}
|
@@ -29,14 +29,6 @@
|
||||
#include "mojo/public/c/system/macros.h"
|
||||
#include "mojo/public/c/system/message_pipe.h"
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
|
||||
BUILDFLAG(IS_FUCHSIA)
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/scoped_native_library.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (*MojoGetSystemThunksFunction)(MojoSystemThunks2* thunks);
|
||||
@@ -50,10 +42,8 @@ MojoResult NotImplemented(const char* name) {
|
||||
return MOJO_RESULT_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
LOG(FATAL)
|
||||
<< "Mojo has not been initialized in this process. You must call "
|
||||
<< "either mojo::core::Init() as an embedder, or |MojoInitialize()| if "
|
||||
<< "using the mojo_core shared library.";
|
||||
LOG(FATAL) << "Mojo has not been initialized in this process. You must call "
|
||||
<< "either mojo::core::Init() as an embedder.";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -63,117 +53,10 @@ MojoResult NotImplemented(const char* name) {
|
||||
? g_thunks.name(__VA_ARGS__) \
|
||||
: NotImplemented(#name)
|
||||
|
||||
namespace mojo {
|
||||
|
||||
// NOTE: This is defined within the global mojo namespace so that it can be
|
||||
// referenced as a friend to base::ScopedAllowBlocking when library support is
|
||||
// enabled.
|
||||
class CoreLibraryInitializer {
|
||||
public:
|
||||
CoreLibraryInitializer() = default;
|
||||
CoreLibraryInitializer(const CoreLibraryInitializer&) = delete;
|
||||
CoreLibraryInitializer& operator=(const CoreLibraryInitializer&) = delete;
|
||||
~CoreLibraryInitializer() = delete;
|
||||
|
||||
MojoResult LoadLibrary(base::FilePath library_path) {
|
||||
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
|
||||
BUILDFLAG(IS_FUCHSIA)
|
||||
if (library_ && library_->is_valid())
|
||||
return MOJO_RESULT_OK;
|
||||
|
||||
if (library_path.empty()) {
|
||||
auto environment = base::Environment::Create();
|
||||
std::string library_path_value;
|
||||
const char kLibraryPathEnvironmentVar[] = "MOJO_CORE_LIBRARY_PATH";
|
||||
if (environment->GetVar(kLibraryPathEnvironmentVar, &library_path_value))
|
||||
library_path = base::FilePath::FromUTF8Unsafe(library_path_value);
|
||||
}
|
||||
|
||||
if (library_path.empty()) {
|
||||
// Default to looking for the library in the current working directory.
|
||||
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
|
||||
const base::FilePath::CharType kDefaultLibraryPathValue[] =
|
||||
FILE_PATH_LITERAL("./libmojo_core.so");
|
||||
#elif BUILDFLAG(IS_FUCHSIA)
|
||||
const base::FilePath::CharType kDefaultLibraryPathValue[] =
|
||||
FILE_PATH_LITERAL("libmojo_core.so");
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
const base::FilePath::CharType kDefaultLibraryPathValue[] =
|
||||
FILE_PATH_LITERAL("mojo_core.dll");
|
||||
#endif
|
||||
library_path = base::FilePath(kDefaultLibraryPathValue);
|
||||
}
|
||||
|
||||
// NOTE: |prefer_own_symbols| on POSIX implies that the library is loaded
|
||||
// with RTLD_DEEPBIND, which is critical given that libmojo_core.so links
|
||||
// against base's allocator shim. Essentially, this ensures that mojo_core
|
||||
// internals get their own heap, and this is OK since heap pointer ownership
|
||||
// is never passed across the ABI boundary.
|
||||
base::ScopedAllowBlocking allow_blocking;
|
||||
base::NativeLibraryOptions library_options;
|
||||
#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
|
||||
!defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER)
|
||||
// Sanitizer builds cannnot support RTLD_DEEPBIND, but they also disable
|
||||
// allocator shims, so it's unnecessary there.
|
||||
library_options.prefer_own_symbols = true;
|
||||
#endif
|
||||
base::ScopedNativeLibrary library(base::LoadNativeLibraryWithOptions(
|
||||
library_path, library_options, nullptr));
|
||||
if (!library.is_valid())
|
||||
return MOJO_RESULT_NOT_FOUND;
|
||||
|
||||
const char kGetThunksFunctionName[] = "MojoGetSystemThunks";
|
||||
|
||||
MojoGetSystemThunksFunction g_get_thunks =
|
||||
reinterpret_cast<MojoGetSystemThunksFunction>(
|
||||
library.GetFunctionPointer(kGetThunksFunctionName));
|
||||
if (!g_get_thunks)
|
||||
return MOJO_RESULT_NOT_FOUND;
|
||||
|
||||
DCHECK_EQ(g_thunks.size, 0u);
|
||||
g_thunks.size = sizeof(g_thunks);
|
||||
g_get_thunks(&g_thunks);
|
||||
if (g_thunks.size == 0)
|
||||
return MOJO_RESULT_NOT_FOUND;
|
||||
|
||||
library_ = std::move(library);
|
||||
return MOJO_RESULT_OK;
|
||||
#else // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) ||
|
||||
// BUILDFLAG(IS_FUCHSIA)
|
||||
return MOJO_RESULT_UNIMPLEMENTED;
|
||||
#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) ||
|
||||
// BUILDFLAG(IS_FUCHSIA)
|
||||
}
|
||||
|
||||
private:
|
||||
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
|
||||
BUILDFLAG(IS_FUCHSIA)
|
||||
std::optional<base::ScopedNativeLibrary> library_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace mojo
|
||||
|
||||
extern "C" {
|
||||
|
||||
MojoResult MojoInitialize(const struct MojoInitializeOptions* options) {
|
||||
static base::NoDestructor<mojo::CoreLibraryInitializer> initializer;
|
||||
|
||||
std::string_view library_path_utf8;
|
||||
if (options) {
|
||||
if (!MOJO_IS_STRUCT_FIELD_PRESENT(options, mojo_core_path_length))
|
||||
return MOJO_RESULT_INVALID_ARGUMENT;
|
||||
library_path_utf8 = std::string_view(options->mojo_core_path,
|
||||
options->mojo_core_path_length);
|
||||
}
|
||||
|
||||
MojoResult load_result = initializer->LoadLibrary(
|
||||
base::FilePath::FromUTF8Unsafe(library_path_utf8));
|
||||
if (load_result != MOJO_RESULT_OK)
|
||||
return load_result;
|
||||
|
||||
DCHECK(g_thunks.Initialize);
|
||||
return INVOKE_THUNK(Initialize, options);
|
||||
return MOJO_RESULT_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
MojoTimeTicks MojoGetTimeTicksNow() {
|
||||
@@ -501,7 +384,7 @@ MojoResult MojoQueryQuota(MojoHandle handle,
|
||||
}
|
||||
|
||||
MojoResult MojoShutdown(const MojoShutdownOptions* options) {
|
||||
return INVOKE_THUNK(Shutdown, options);
|
||||
return MOJO_RESULT_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
MojoResult MojoSetDefaultProcessErrorHandler(
|
||||
|
@@ -15,8 +15,6 @@ component("system") {
|
||||
"data_pipe_producer.h",
|
||||
"data_pipe_utils.cc",
|
||||
"data_pipe_utils.h",
|
||||
"dynamic_library_support.cc",
|
||||
"dynamic_library_support.h",
|
||||
"file_data_source.cc",
|
||||
"file_data_source.h",
|
||||
"filtered_data_source.cc",
|
||||
|
@@ -1,65 +0,0 @@
|
||||
// Copyright 2020 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "base/check_op.h"
|
||||
#include "base/command_line.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/public/c/system/functions.h"
|
||||
|
||||
namespace mojo {
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper for temporary storage related to |MojoInitialize()| calls.
|
||||
struct InitializationState {
|
||||
InitializationState(const std::optional<base::FilePath>& path,
|
||||
MojoInitializeFlags flags) {
|
||||
options.flags = flags;
|
||||
|
||||
if (path) {
|
||||
utf8_path = path->AsUTF8Unsafe();
|
||||
options.mojo_core_path = utf8_path.c_str();
|
||||
options.mojo_core_path_length = static_cast<uint32_t>(utf8_path.size());
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
|
||||
// Build a temporary reconstructed argv to pass into the library so it can
|
||||
// inspect the application command line if needed.
|
||||
for (const std::string& s : base::CommandLine::ForCurrentProcess()->argv())
|
||||
argv.push_back(s.c_str());
|
||||
options.argc = static_cast<uint32_t>(argv.size());
|
||||
options.argv = argv.data();
|
||||
#endif
|
||||
}
|
||||
|
||||
MojoInitializeOptions options = {sizeof(MojoInitializeOptions)};
|
||||
std::string utf8_path;
|
||||
std::vector<const char*> argv;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
MojoResult LoadCoreLibrary(std::optional<base::FilePath> path) {
|
||||
InitializationState state(path, MOJO_INITIALIZE_FLAG_LOAD_ONLY);
|
||||
return MojoInitialize(&state.options);
|
||||
}
|
||||
|
||||
MojoResult InitializeCoreLibrary(MojoInitializeFlags flags) {
|
||||
DCHECK_EQ(flags & MOJO_INITIALIZE_FLAG_LOAD_ONLY, 0u);
|
||||
InitializationState state(std::nullopt, flags);
|
||||
return MojoInitialize(&state.options);
|
||||
}
|
||||
|
||||
MojoResult LoadAndInitializeCoreLibrary(std::optional<base::FilePath> path,
|
||||
MojoInitializeFlags flags) {
|
||||
DCHECK_EQ(flags & MOJO_INITIALIZE_FLAG_LOAD_ONLY, 0u);
|
||||
InitializationState state(path, flags);
|
||||
return MojoInitialize(&state.options);
|
||||
}
|
||||
|
||||
} // namespace mojo
|
@@ -1,46 +0,0 @@
|
||||
// Copyright 2020 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef MOJO_PUBLIC_CPP_SYSTEM_DYNAMIC_LIBRARY_SUPPORT_H_
|
||||
#define MOJO_PUBLIC_CPP_SYSTEM_DYNAMIC_LIBRARY_SUPPORT_H_
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "mojo/public/c/system/types.h"
|
||||
#include "mojo/public/cpp/system/system_export.h"
|
||||
|
||||
namespace mojo {
|
||||
|
||||
// Helper to load Mojo Core dynamically from a shared library. If |path| is
|
||||
// not given, the library path is assumed to be set in the
|
||||
// MOJO_CORE_LIBRARY_PATH environment variable, or the library is searched for
|
||||
// in the current working directory.
|
||||
//
|
||||
// This may only be called in a process that hasn't already initialized Mojo.
|
||||
// Mojo is still not fully initialized or usable until |InitializeCoreLibrary()|
|
||||
// is also called. These two functions are kept distinct to facilitate use
|
||||
// cases where the client application must perform some work (e.g. sandbox
|
||||
// configuration, forking, etc) between the loading and initialization steps.
|
||||
MOJO_CPP_SYSTEM_EXPORT MojoResult
|
||||
LoadCoreLibrary(std::optional<base::FilePath> path);
|
||||
|
||||
// Initializes the dynamic Mojo Core library previously loaded by
|
||||
// |LoadCoreLibrary()| above.
|
||||
//
|
||||
// This may only be called in a process that hasn't already initialized Mojo.
|
||||
MOJO_CPP_SYSTEM_EXPORT MojoResult
|
||||
InitializeCoreLibrary(MojoInitializeFlags flags);
|
||||
|
||||
// Loads and initializes Mojo Core from a shared library. This combines
|
||||
// |LoadCoreLibrary()| and |InitializeCoreLibrary()| for convenience in cases
|
||||
// where they don't need to be performed at different times by the client
|
||||
// application.
|
||||
MOJO_CPP_SYSTEM_EXPORT MojoResult
|
||||
LoadAndInitializeCoreLibrary(std::optional<base::FilePath> path,
|
||||
MojoInitializeFlags flags);
|
||||
|
||||
} // namespace mojo
|
||||
|
||||
#endif // MOJO_PUBLIC_CPP_SYSTEM_DYNAMIC_LIBRARY_SUPPORT_H_
|
Reference in New Issue
Block a user