#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "chrome/app/chrome_main_delegate.h"
#include <stddef.h>
#include <string>
#include "base/base_paths.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/cpu.h"
#include "base/dcheck_is_on.h"
#include "base/features.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/overloaded.h"
#include "base/i18n/rtl.h"
#include "base/immediate_crash.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/process/memory.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/hang_watcher.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/trace_event_impl.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/buildflags.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/chrome_resource_bundle_helper.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/mac/code_sign_clone_manager.h"
#include "chrome/browser/metrics/chrome_feature_list_creator.h"
#include "chrome/browser/startup_data.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/profiler/main_thread_stack_sampling_profiler.h"
#include "chrome/common/profiler/process_type.h"
#include "chrome/common/profiler/unwind_util.h"
#include "chrome/common/url_constants.h"
#include "chrome/gpu/chrome_content_gpu_client.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/utility/chrome_content_utility_client.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/crash/core/app/crash_reporter_client.h"
#include "components/crash/core/common/crash_key.h"
#include "components/crash/core/common/crash_keys.h"
#include "components/devtools/devtools_pipe/devtools_pipe.h"
#include "components/memory_system/initializer.h"
#include "components/memory_system/parameters.h"
#include "components/metrics/persistent_histograms.h"
#include "components/nacl/common/buildflags.h"
#include "components/startup_metric_utils/common/startup_metric_utils.h"
#include "components/version_info/channel.h"
#include "components/version_info/version_info.h"
#include "content/public/app/initialize_mojo_core.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.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/profiling.h"
#include "content/public/common/url_constants.h"
#include "extensions/buildflags/buildflags.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request.h"
#include "pdf/buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/features.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#if BUILDFLAG(IS_WIN)
#include <malloc.h>
#include <algorithm>
#include "base/base_switches.h"
#include "base/files/important_file_writer_cleaner.h"
#include "base/win/atl.h"
#include "base/win/dark_mode_support.h"
#include "base/win/resource_exhaustion.h"
#include "chrome/browser/chrome_browser_main_win.h"
#include "chrome/browser/win/browser_util.h"
#include "chrome/child/v8_crashpad_support_win.h"
#include "chrome/chrome_elf/chrome_elf_main.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_version.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "ui/base/resource/resource_bundle_win.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "base/apple/foundation_util.h"
#include "chrome/app/chrome_main_mac.h"
#include "chrome/browser/chrome_browser_application_mac.h"
#include "chrome/browser/headless/headless_mode_util.h"
#include "chrome/browser/mac/relauncher.h"
#include "chrome/browser/shell_integration.h"
#include "components/crash/core/common/objc_zombie.h"
#include "ui/base/l10n/l10n_util_mac.h"
#endif
#if BUILDFLAG(IS_POSIX)
#include <locale.h>
#include <signal.h>
#include "chrome/app/chrome_crash_reporter_client.h"
#include "components/about_ui/credit_utils.h"
#endif
#if BUILDFLAG(ENABLE_NACL) && (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
#include "components/nacl/common/nacl_paths.h"
#include "components/nacl/zygote/nacl_fork_delegate_linux.h"
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/dbus/constants/dbus_paths.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/components/arc/arc_util.h"
#include "ash/constants/ash_paths.h"
#include "ash/constants/ash_switches.h"
#include "base/system/sys_info.h"
#include "chrome/browser/ash/boot_times_recorder/boot_times_recorder.h"
#include "chrome/browser/ash/dbus/ash_dbus_helper.h"
#include "chrome/browser/ash/locale/startup_settings_cache.h"
#include "chrome/browser/ash/schedqos/dbus_schedqos_state_handler.h"
#include "chromeos/ash/components/memory/memory.h"
#include "chromeos/ash/components/memory/mglru.h"
#include "content/public/common/content_features.h"
#include "ui/lottie/resource.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/java_exception_reporter.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "chrome/browser/android/flags/chrome_cached_flags.h"
#include "chrome/browser/android/metrics/uma_session_stats.h"
#include "chrome/browser/flags/android/chrome_feature_list.h"
#include "chrome/common/chrome_descriptors.h"
#include "components/crash/android/pure_java_exception_handler.h"
#include "net/android/network_change_notifier_factory_android.h"
#else
#include "chrome/browser/diagnostics/diagnostics_controller.h"
#include "chrome/browser/diagnostics/diagnostics_writer.h"
#endif
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
#include "v8/include/v8-wasm-trap-handler-posix.h"
#include "v8/include/v8.h"
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "base/environment.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "base/nix/scoped_xdg_activation_token_injector.h"
#include "ui/linux/display_server_utils.h"
#endif
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/policy/policy_path_parser.h"
#include "components/crash/core/app/crashpad.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/startup_helper.h"
#include "extensions/common/constants.h"
#endif
#if BUILDFLAG(ENABLE_NACL)
#include "components/nacl/common/nacl_switches.h"
#include "components/nacl/renderer/plugin/ppapi_entrypoints.h"
#endif
#if BUILDFLAG(ENABLE_PDF)
#include "chrome/child/pdf_child_init.h"
#endif
#if BUILDFLAG(ENABLE_PROCESS_SINGLETON)
#include "chrome/browser/chrome_process_singleton.h"
#include "chrome/browser/process_singleton.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "base/scoped_add_feature_flags.h"
#include "chrome/common/chrome_paths_lacros.h"
#include "chromeos/crosapi/cpp/crosapi_constants.h"
#include "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/lacros/dbus/lacros_dbus_helper.h"
#include "chromeos/lacros/lacros_paths.h"
#include "chromeos/lacros/lacros_service.h"
#include "chromeos/startup/browser_params_proxy.h"
#include "chromeos/startup/browser_postlogin_params.h"
#include "chromeos/startup/startup.h"
#include "chromeos/startup/startup_switches.h"
#include "components/crash/core/app/client_upload_info.h"
#include "content/public/browser/zygote_host/zygote_host_linux.h"
#include "media/base/media_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/base/resource/data_pack_with_resource_sharing_lacros.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/switches.h"
#endif
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
base::LazyInstance<ChromeContentGpuClient>::DestructorAtExit
g_chrome_content_gpu_client = …;
base::LazyInstance<ChromeContentRendererClient>::DestructorAtExit
g_chrome_content_renderer_client = …;
extern int NaClMain(content::MainFunctionParams);
const char* const ChromeMainDelegate::kNonWildcardDomainNonPortSchemes[] = …;
const size_t ChromeMainDelegate::kNonWildcardDomainNonPortSchemesSize = …;
namespace {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
const base::FilePath::CharType kUserHomeDirPrefix[] =
FILE_PATH_LITERAL("/home/user");
#endif
#if BUILDFLAG(IS_WIN)
bool HasDeprecatedArguments(const std::wstring& command_line) {
const wchar_t kChromeHtml[] = L"chromehtml:";
std::wstring command_line_lower = base::ToLowerASCII(command_line);
return (command_line_lower.find(kChromeHtml) != std::wstring::npos);
}
void SuppressWindowsErrorDialogs() {
UINT new_flags = SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
UINT existing_flags = SetErrorMode(new_flags);
SetErrorMode(existing_flags | new_flags);
}
bool IsSandboxedProcess() {
typedef bool (*IsSandboxedProcessFunc)();
IsSandboxedProcessFunc is_sandboxed_process_func =
reinterpret_cast<IsSandboxedProcessFunc>(
GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess"));
return is_sandboxed_process_func && is_sandboxed_process_func();
}
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
void AdjustLinuxOOMScore(const std::string& process_type) { … }
#endif
bool SubprocessNeedsResourceBundle(const std::string& process_type) { … }
#if BUILDFLAG(IS_POSIX)
bool HandleCreditsSwitch(const base::CommandLine& command_line) { … }
bool HandleVersionSwitches(const base::CommandLine& command_line) { … }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
void HandleHelpSwitches(const base::CommandLine& command_line) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void RedirectLacrosLogging() {
const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
uint32_t logging_dest = logging::DetermineLoggingDestination(cmdline);
base::FilePath log_file =
cmdline.GetSwitchValuePath(chromeos::switches::kCrosPostLoginLogFile);
if (!log_file.empty() && (logging_dest & logging::LOG_TO_STDERR)) {
log_file = logging::SetUpLogFile(log_file, true);
FILE* result = freopen(log_file.value().c_str(), "a", stderr);
DPCHECK(result != nullptr);
if (result) {
content::ZygoteHost::GetInstance()->ReinitializeLogging(logging_dest,
STDERR_FILENO);
}
}
}
void SetCrashpadUploadConsentPostLogin() {
crash_reporter::SetUploadConsent(
crash_reporter::GetClientCollectStatsConsent());
}
#endif
#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
void SIGTERMProfilingShutdown(int signal) { … }
void SetUpProfilingShutdownHandler() { … }
#endif
#endif
bool WillExitBeforeBrowserFeatureListInitialization() { … }
#if BUILDFLAG(ENABLE_EXTENSIONS)
std::optional<int> HandlePackExtensionSwitches(
const base::CommandLine& command_line) { … }
#endif
#if BUILDFLAG(ENABLE_PROCESS_SINGLETON)
std::optional<int> AcquireProcessSingleton(
const base::FilePath& user_data_dir) { … }
#endif
struct MainFunction { … };
void InitializeUserDataDir(base::CommandLine* command_line) { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void MaybeBlockAtLoginScreen(bool after_zygotes_fork) {
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty() && chromeos::IsLaunchedWithPostLoginParams()) {
chromeos::BrowserParamsProxy::WaitForLogin();
if (chrome::ProcessNeedsProfileDir(process_type)) {
InitializeUserDataDir(base::CommandLine::ForCurrentProcess());
}
RedirectLacrosLogging();
if (after_zygotes_fork) {
SetCrashpadUploadConsentPostLogin();
}
}
}
#endif
#if !BUILDFLAG(IS_ANDROID)
void InitLogging(const std::string& process_type) { … }
#endif
void RecordMainStartupMetrics(const StartupTimestamps& timestamps) { … }
#if BUILDFLAG(IS_WIN)
void OnResourceExhausted() {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kNoErrorDialogs)) {
static constexpr wchar_t kMessageBoxTitle[] = L"System resource exhausted";
static constexpr wchar_t kMessage[] =
L"Your computer has run out of resources and cannot start "
PRODUCT_SHORTNAME_STRING
L". Sign out of Windows or restart your computer and try again.";
::MessageBox(nullptr, kMessage, kMessageBoxTitle, MB_OK);
}
base::Process::TerminateCurrentProcessImmediately(
chrome::RESULT_CODE_SYSTEM_RESOURCE_EXHAUSTED);
}
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
void AddFeatureFlagsToCommandLine() {
CHECK(!base::FeatureList::GetInstance());
base::ScopedAddFeatureFlags flags(base::CommandLine::ForCurrentProcess());
const auto& init_params = *chromeos::BrowserParamsProxy::Get();
if (init_params.IsVariableRefreshRateAlwaysOn()) {
flags.EnableIfNotSet(features::kEnableVariableRefreshRateAlwaysOn);
}
if (init_params.IsPdfOcrEnabled()) {
flags.EnableIfNotSet(features::kPdfOcr);
}
}
#endif
bool IsCanaryDev() { … }
}
#if BUILDFLAG(IS_ANDROID)
ChromeMainDelegate::ChromeMainDelegate()
: ChromeMainDelegate(StartupTimestamps{}) {}
#endif
ChromeMainDelegate::ChromeMainDelegate(const StartupTimestamps& timestamps) { … }
#if !BUILDFLAG(IS_ANDROID)
ChromeMainDelegate::~ChromeMainDelegate() { … }
#else
ChromeMainDelegate::~ChromeMainDelegate() = default;
#endif
std::optional<int> ChromeMainDelegate::PostEarlyInitialization(
InvokedIn invoked_in) { … }
bool ChromeMainDelegate::ShouldCreateFeatureList(InvokedIn invoked_in) { … }
bool ChromeMainDelegate::ShouldInitializeMojo(InvokedIn invoked_in) { … }
void ChromeMainDelegate::CreateThreadPool(std::string_view name) { … }
void ChromeMainDelegate::CommonEarlyInitialization(InvokedIn invoked_in) { … }
#if BUILDFLAG(IS_WIN)
bool ChromeMainDelegate::ShouldHandleConsoleControlEvents() {
return true;
}
#endif
void ChromeMainDelegate::SetupTracing() { … }
std::optional<int> ChromeMainDelegate::BasicStartupComplete() { … }
#if BUILDFLAG(IS_MAC)
void ChromeMainDelegate::InitMacCrashReporter(
const base::CommandLine& command_line,
const std::string& process_type) {
const bool browser_process = process_type.empty();
const bool install_from_dmg_relauncher_process =
process_type == switches::kRelauncherProcess &&
command_line.HasSwitch(switches::kRelauncherProcessDMGDevice);
const bool initial_client =
browser_process || install_from_dmg_relauncher_process;
crash_reporter::InitializeCrashpad(initial_client, process_type);
if (!browser_process) {
std::string metrics_client_id =
command_line.GetSwitchValueASCII(switches::kMetricsClientID);
crash_keys::SetMetricsClientIdFromGUID(metrics_client_id);
}
if (base::apple::IsBackgroundOnlyProcess()) {
CHECK(command_line.HasSwitch(switches::kProcessType) &&
!process_type.empty())
<< "Helper application requires --type.";
} else if (base::apple::AmIBundled()) {
CHECK(!command_line.HasSwitch(switches::kProcessType) &&
process_type.empty())
<< "Main application forbids --type, saw " << process_type;
}
}
void ChromeMainDelegate::SetUpInstallerPreferences(
const base::CommandLine& command_line) {
const bool uma_setting = command_line.HasSwitch(switches::kEnableUserMetrics);
const bool default_browser_setting =
command_line.HasSwitch(switches::kMakeChromeDefault);
if (uma_setting)
crash_reporter::SetUploadConsent(uma_setting);
if (default_browser_setting)
shell_integration::SetAsDefaultBrowser();
}
#endif
void ChromeMainDelegate::PreSandboxStartup() { … }
void ChromeMainDelegate::SandboxInitialized(const std::string& process_type) { … }
absl::variant<int, content::MainFunctionParams> ChromeMainDelegate::RunProcess(
const std::string& process_type,
content::MainFunctionParams main_function_params) { … }
void ChromeMainDelegate::ProcessExiting(const std::string& process_type) { … }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
void ChromeMainDelegate::ZygoteStarting(
std::vector<std::unique_ptr<content::ZygoteForkDelegate>>* delegates) { … }
void ChromeMainDelegate::ZygoteForked() { … }
#endif
content::ContentClient* ChromeMainDelegate::CreateContentClient() { … }
content::ContentBrowserClient*
ChromeMainDelegate::CreateContentBrowserClient() { … }
content::ContentGpuClient* ChromeMainDelegate::CreateContentGpuClient() { … }
content::ContentRendererClient*
ChromeMainDelegate::CreateContentRendererClient() { … }
content::ContentUtilityClient*
ChromeMainDelegate::CreateContentUtilityClient() { … }
std::optional<int> ChromeMainDelegate::PreBrowserMain() { … }
void ChromeMainDelegate::InitializeMemorySystem() { … }