chromium/content/app/content_main_runner_impl.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "content/app/content_main_runner_impl.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "base/allocator/allocator_check.h"
#include "base/allocator/partition_alloc_support.h"
#include "base/at_exit.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/debug/debugger.h"
#include "base/debug/leak_annotations.h"
#include "base/debug/stack_trace.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/shared_memory_hooks.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_base.h"
#include "base/path_service.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/process/launch.h"
#include "base/process/memory.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool/environment_config.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/hang_watcher.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "components/download/public/common/download_task_runner.h"
#include "components/power_monitor/make_power_monitor_device_source.h"
#include "components/variations/variations_ids_provider.h"
#include "content/app/mojo_ipc_support.h"
#include "content/browser/browser_main.h"
#include "content/browser/browser_process_io_thread.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/first_party_sets/first_party_sets_handler_impl.h"
#include "content/browser/gpu/gpu_main_thread_factory.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/startup_data_impl.h"
#include "content/browser/startup_helper.h"
#include "content/browser/tracing/memory_instrumentation_util.h"
#include "content/browser/utility_process_host.h"
#include "content/child/field_trial.h"
#include "content/common/content_constants_internal.h"
#include "content/common/process_visibility_tracker.h"
#include "content/common/url_schemes.h"
#include "content/gpu/in_process_gpu_thread.h"
#include "content/public/app/content_main_delegate.h"
#include "content/public/app/initialize_mojo_core.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/browser/tracing_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_descriptor_keys.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/zygote/zygote_buildflags.h"
#include "content/public/gpu/content_gpu_client.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/utility/content_utility_client.h"
#include "content/renderer/in_process_renderer_thread.h"
#include "content/utility/in_process_utility_thread.h"
#include "gin/thread_isolation.h"
#include "gin/v8_initializer.h"
#include "media/base/media.h"
#include "media/media_buildflags.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/base/shared_memory_utils.h"
#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/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "net/first_party_sets/local_set_declaration.h"
#include "ppapi/buildflags/buildflags.h"
#include "sandbox/policy/sandbox.h"
#include "sandbox/policy/sandbox_type.h"
#include "sandbox/policy/switches.h"
#include "services/network/public/cpp/features.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
#include "third_party/tflite/buildflags.h"
#include "tools/v8_context_snapshot/buildflags.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/switches.h"

#if BUILDFLAG(IS_WIN)
#include <malloc.h>
#include <cstring>

#include "base/trace_event/trace_event_etw_export_win.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/display/win/dpi.h"
#elif BUILDFLAG(IS_MAC)
#include "sandbox/mac/seatbelt.h"
#include "sandbox/mac/seatbelt_exec.h"
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_IOS)
#include "base/threading/thread_restrictions.h"
#endif  // BUILDFLAG(IS_IOS)

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <signal.h>

#include "base/file_descriptor_store.h"
#include "base/posix/global_descriptors.h"
#include "content/browser/posix_file_descriptor_info_impl.h"
#include "content/public/common/content_descriptors.h"

#if !BUILDFLAG(IS_MAC)
#include "content/public/common/zygote/zygote_fork_delegate_linux.h"
#endif

#endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "base/files/file_path_watcher_inotify.h"
#include "base/native_library.h"
#include "base/rand_util.h"
#include "content/public/common/zygote/sandbox_support_linux.h"
#include "sandbox/policy/linux/sandbox_linux.h"
#include "third_party/boringssl/src/include/openssl/crypto.h"
#include "third_party/webrtc_overrides/init_webrtc.h"  // nogncheck

#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/startup/browser_init_params.h"
#include "chromeos/startup/startup_switches.h"
#endif

#if BUILDFLAG(ENABLE_PPAPI)
#include "content/common/pepper_plugin_list.h"
#include "content/public/common/content_plugin_info.h"
#endif

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_client.h"
#endif

#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(USE_ZYGOTE)
#include "base/stack_canary_linux.h"
#include "content/browser/sandbox_host_linux.h"
#include "content/browser/zygote_host/zygote_host_impl_linux.h"
#include "content/common/shared_file_util.h"
#include "content/common/zygote/zygote_communication_linux.h"
#include "content/common/zygote/zygote_handle_impl_linux.h"
#include "content/public/common/zygote/sandbox_support_linux.h"
#include "content/public/common/zygote/zygote_handle.h"
#include "content/zygote/zygote_main.h"
#include "media/base/media_switches.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "base/system/sys_info.h"
#include "content/browser/android/battery_metrics.h"
#include "content/browser/android/browser_startup_controller.h"
#include "content/common/android/cpu_time_metrics.h"
#endif

#if BUILDFLAG(IS_FUCHSIA)
#include "base/fuchsia/system_info.h"
#endif

#if BUILDFLAG(BUILD_TFLITE_WITH_XNNPACK)
#include "third_party/cpuinfo/src/include/cpuinfo.h"
#endif

#if defined(ADDRESS_SANITIZER)
#include "base/debug/asan_service.h"
#endif

namespace content {
extern int GpuMain(MainFunctionParams);
#if BUILDFLAG(ENABLE_PPAPI)
extern int PpapiPluginMain(MainFunctionParams);
#endif
extern int RendererMain(MainFunctionParams);
extern int UtilityMain(MainFunctionParams);
}  // namespace content

namespace content {

namespace {

#if defined(V8_USE_EXTERNAL_STARTUP_DATA) && BUILDFLAG(IS_ANDROID)
#if defined __LP64__
#define kV8SnapshotDataDescriptor
#define kV8ContextSnapshotDataDescriptor
#else
#define kV8SnapshotDataDescriptor
#define kV8ContextSnapshotDataDescriptor
#endif
#endif

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

gin::V8SnapshotFileType GetSnapshotType(const base::CommandLine& command_line) {}

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
std::string GetSnapshotDataDescriptor(const base::CommandLine& command_line) {}

#endif

#if defined(ADDRESS_SANITIZER)
NO_SANITIZE("address")
void AsanProcessInfoCB(const char*, bool*) {
  auto* cmd_line = base::CommandLine::ForCurrentProcess();
#if BUILDFLAG(IS_WIN)
  std::string cmd_string = base::WideToUTF8(cmd_line->GetCommandLineString());
#else
  std::string cmd_string = cmd_line->GetCommandLineString();
#endif
  base::debug::AsanService::GetInstance()->Log("\nCommand line: `%s`\n",
                                               cmd_string.c_str());
}
#endif  // defined(ADDRESS_SANITIZER)

void LoadV8SnapshotFile(const base::CommandLine& command_line) {}

bool ShouldLoadV8Snapshot(const base::CommandLine& command_line,
                          const std::string& process_type) {}

#endif  // V8_USE_EXTERNAL_STARTUP_DATA

void LoadV8SnapshotIfNeeded(const base::CommandLine& command_line,
                            const std::string& process_type) {}

#if BUILDFLAG(USE_ZYGOTE)
pid_t LaunchZygoteHelper(base::CommandLine* cmd_line,
                         base::ScopedFD* control_fd) {}

// Initializes the Zygote sandbox host. No thread should be created before this
// call, as InitializeZygoteSandboxForBrowserProcess() will end-up using fork().
void InitializeZygoteSandboxForBrowserProcess(
    const base::CommandLine& parsed_command_line) {}
#endif  // BUILDFLAG(USE_ZYGOTE)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(ENABLE_PPAPI)
// Loads the (native) libraries but does not initialize them (i.e., does not
// call PPP_InitializeModule). This is needed by the zygote on Linux to get
// access to the plugins before entering the sandbox.
void PreloadPepperPlugins() {
  std::vector<ContentPluginInfo> plugins;
  ComputePepperPluginList(&plugins);
  for (const auto& plugin : plugins) {
    if (!plugin.is_internal) {
      base::NativeLibraryLoadError error;
      base::NativeLibrary library =
          base::LoadNativeLibrary(plugin.path, &error);
      LOG_IF(ERROR, !library) << "Unable to load plugin " << plugin.path.value()
                              << " " << error.ToString();
    }
  }
}
#endif  // BUILDFLAG(ENABLE_PPAPI)

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// Loads registered library CDMs but does not initialize them. This is needed by
// the zygote on Linux to get access to the CDMs before entering the sandbox.
void PreloadLibraryCdms() {}
#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)

void PreSandboxInit() {}

#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

mojo::ScopedMessagePipeHandle MaybeAcceptMojoInvitation() {}

#if BUILDFLAG(IS_WIN)
void HandleConsoleControlEventOnBrowserUiThread(DWORD control_type) {
  GetContentClient()->browser()->SessionEnding(control_type);
}

// A console control event handler for browser processes that initiates end
// session handling on the main thread and hangs the control thread.
BOOL WINAPI BrowserConsoleControlHandler(DWORD control_type) {
  BrowserTaskExecutor::GetUIThreadTaskRunner(
      {base::TaskPriority::USER_BLOCKING})
      ->PostTask(FROM_HERE,
                 base::BindOnce(&HandleConsoleControlEventOnBrowserUiThread,
                                control_type));

  // Block the control thread while waiting for SessionEnding to be handled.
  base::PlatformThread::Sleep(base::Hours(1));

  // This should never be hit. The process will be terminated either by
  // ContentBrowserClient::SessionEnding or by Windows, if the former takes too
  // long.
  return TRUE;  // Handled.
}

// A console control event handler for non-browser processes that hangs the
// control thread. The event will be handled by the browser process.
BOOL WINAPI OtherConsoleControlHandler(DWORD control_type) {
  // Block the control thread while waiting for the browser process.
  base::PlatformThread::Sleep(base::Hours(1));

  // This should never be hit. The process will be terminated by the browser
  // process or by Windows, if the former takes too long.
  return TRUE;  // Handled.
}

void InstallConsoleControlHandler(bool is_browser_process) {
  if (!::SetConsoleCtrlHandler(is_browser_process
                                   ? &BrowserConsoleControlHandler
                                   : &OtherConsoleControlHandler,
                               /*Add=*/TRUE)) {
    DPLOG(ERROR) << "Failed to set console hook function";
  }
}
#endif  // BUILDFLAG(IS_WIN)

bool ShouldAllowSystemTracingConsumer() {}

void CreateChildThreadPool(const std::string& process_type) {}

}  // namespace

class ContentClientCreator {};

class ContentClientInitializer {};

// We dispatch to a process-type-specific FooMain() based on a command-line
// flag.  This struct is used to build a table of (flag, main function) pairs.
struct MainFunction {};

#if BUILDFLAG(USE_ZYGOTE)
// On platforms that use the zygote, we have a special subset of
// subprocesses that are launched via the zygote.  This function
// fills in some process-launching bits around ZygoteMain().
// Returns the exit code of the subprocess.
// This function must be marked with NO_STACK_PROTECTOR or it may crash on
// return, see the --change-stack-guard-on-fork command line flag.
int NO_STACK_PROTECTOR RunZygote(ContentMainDelegate* delegate) {}
#endif  // BUILDFLAG(USE_ZYGOTE)

static void RegisterMainThreadFactories() {}

// Run the main function for browser process.
// Returns the exit code for this process.
int RunBrowserProcessMain(MainFunctionParams main_function_params,
                          ContentMainDelegate* delegate) {}

// Run the FooMain() for a given process type.
// Returns the exit code for this process.
// This function must be marked with NO_STACK_PROTECTOR or it may crash on
// return, see the --change-stack-guard-on-fork command line flag.
int NO_STACK_PROTECTOR
RunOtherNamedProcessTypeMain(const std::string& process_type,
                             MainFunctionParams main_function_params,
                             ContentMainDelegate* delegate) {}

// static
std::unique_ptr<ContentMainRunnerImpl> ContentMainRunnerImpl::Create() {}

ContentMainRunnerImpl::ContentMainRunnerImpl() = default;

ContentMainRunnerImpl::~ContentMainRunnerImpl() {}

int ContentMainRunnerImpl::TerminateForFatalInitializationError() {}

int ContentMainRunnerImpl::Initialize(ContentMainParams params) {}

void ContentMainRunnerImpl::ReInitializeParams(ContentMainParams new_params) {}

// This function must be marked with NO_STACK_PROTECTOR or it may crash on
// return, see the --change-stack-guard-on-fork command line flag.
int NO_STACK_PROTECTOR ContentMainRunnerImpl::Run() {}

int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params,
                                      bool start_minimal_browser) {}

void ContentMainRunnerImpl::Shutdown() {}

// static
std::unique_ptr<ContentMainRunner> ContentMainRunner::Create() {}

}  // namespace content