cef/libcef/common/alloy/alloy_main_delegate.cc
Marshall Greenblatt b3a8da9b25 Add CefAppManager and remove global ContentClient accessors (see issue #2969)
This is the first pass in removing direct dependencies on the Alloy
runtime from code that can potentially be shared between runtimes.

CefBrowserHost and CefRequestContext APIs (including CefCookieManager,
CefURLRequest, etc.) are not yet implemented for the Chrome runtime.
Assert early if these API methods are called while the Chrome runtime
is enabled.
2020-06-29 16:17:58 -04:00

868 lines
30 KiB
C++

// Copyright (c) 2012 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 "libcef/common/alloy/alloy_main_delegate.h"
#if defined(OS_LINUX)
#include <dlfcn.h>
#endif
#include "libcef/browser/alloy/alloy_content_browser_client.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
#include "libcef/common/crash_reporting.h"
#include "libcef/common/extensions/extensions_util.h"
#include "libcef/renderer/alloy/alloy_content_renderer_client.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/child/pdf_child_init.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/utility/chrome_content_utility_client.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/viz/common/features.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "extensions/common/constants.h"
#include "ipc/ipc_buildflags.h"
#include "net/base/features.h"
#include "pdf/pdf_ppapi.h"
#include "services/network/public/cpp/features.h"
#include "services/service_manager/sandbox/switches.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
#include "content/public/common/content_ipc_logging.h"
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
content::RegisterIPCLogger(msg_id, logger)
#include "libcef/common/cef_message_generator.h"
#endif
#if defined(OS_WIN)
#include "base/win/registry.h"
#endif
#if defined(OS_MACOSX)
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "content/public/common/content_paths.h"
#include "libcef/common/util_mac.h"
#endif
#if defined(OS_LINUX)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#endif
namespace {
const char* const kNonWildcardDomainNonPortSchemes[] = {
extensions::kExtensionScheme};
const size_t kNonWildcardDomainNonPortSchemesSize =
base::size(kNonWildcardDomainNonPortSchemes);
#if defined(OS_MACOSX)
base::FilePath GetResourcesFilePath() {
return util_mac::GetFrameworkResourcesDirectory();
}
// Use a "~/Library/Logs/<app name>_debug.log" file where <app name> is the name
// of the running executable.
base::FilePath GetDefaultLogFile() {
std::string exe_name = util_mac::GetMainProcessPath().BaseName().value();
return base::mac::GetUserLibraryPath()
.Append(FILE_PATH_LITERAL("Logs"))
.Append(FILE_PATH_LITERAL(exe_name + "_debug.log"));
}
void OverrideFrameworkBundlePath() {
base::FilePath framework_path = util_mac::GetFrameworkDirectory();
DCHECK(!framework_path.empty());
base::mac::SetOverrideFrameworkBundlePath(framework_path);
}
void OverrideOuterBundlePath() {
base::FilePath bundle_path = util_mac::GetMainBundlePath();
DCHECK(!bundle_path.empty());
base::mac::SetOverrideOuterBundlePath(bundle_path);
}
void OverrideBaseBundleID() {
std::string bundle_id = util_mac::GetMainBundleID();
DCHECK(!bundle_id.empty());
base::mac::SetBaseBundleID(bundle_id.c_str());
}
void OverrideChildProcessPath() {
base::FilePath child_process_path =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kBrowserSubprocessPath);
if (child_process_path.empty()) {
child_process_path = util_mac::GetChildProcessPath();
DCHECK(!child_process_path.empty());
}
// Used by ChildProcessHost::GetChildPath and PlatformCrashpadInitialization.
base::PathService::Override(content::CHILD_PROCESS_EXE, child_process_path);
}
#else // !defined(OS_MACOSX)
base::FilePath GetResourcesFilePath() {
base::FilePath pak_dir;
base::PathService::Get(base::DIR_ASSETS, &pak_dir);
return pak_dir;
}
// Use a "debug.log" file in the running executable's directory.
base::FilePath GetDefaultLogFile() {
base::FilePath log_path;
base::PathService::Get(base::DIR_EXE, &log_path);
return log_path.Append(FILE_PATH_LITERAL("debug.log"));
}
#endif // !defined(OS_MACOSX)
#if defined(OS_WIN)
// Gets the Flash path if installed on the system.
bool GetSystemFlashFilename(base::FilePath* out_path) {
const wchar_t kPepperFlashRegistryRoot[] =
L"SOFTWARE\\Macromedia\\FlashPlayerPepper";
const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath";
base::win::RegKey path_key(HKEY_LOCAL_MACHINE, kPepperFlashRegistryRoot,
KEY_READ);
base::string16 path_str;
if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str)))
return false;
*out_path = base::FilePath(path_str);
return true;
}
#elif defined(OS_MACOSX)
const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] =
FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer");
#endif
void OverridePepperFlashSystemPluginPath() {
#if defined(OS_WIN) || defined(OS_MACOSX)
base::FilePath plugin_filename;
#if defined(OS_WIN)
if (!GetSystemFlashFilename(&plugin_filename))
return;
#elif defined(OS_MACOSX)
if (!util_mac::GetLocalLibraryDirectory(&plugin_filename))
return;
plugin_filename = plugin_filename.Append(kPepperFlashSystemBaseDirectory)
.Append(chrome::kPepperFlashPluginFilename);
#endif // defined(OS_MACOSX)
if (!plugin_filename.empty()) {
base::PathService::Override(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
plugin_filename);
}
#else // !(defined(OS_WIN) || defined(OS_MACOSX))
// A system plugin is not available on other platforms.
return;
#endif
}
#if defined(OS_LINUX)
// Based on chrome/common/chrome_paths_linux.cc.
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// for a spec on where config files go. The net effect for most
// systems is we use ~/.config/chromium/ for Chromium and
// ~/.config/google-chrome/ for official builds.
// (This also helps us sidestep issues with other apps grabbing ~/.chromium .)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
std::unique_ptr<base::Environment> env(base::Environment::Create());
base::FilePath config_dir(base::nix::GetXDGDirectory(
env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir));
*result = config_dir.Append(FILE_PATH_LITERAL("cef_user_data"));
return true;
}
#elif defined(OS_MACOSX)
// Based on chrome/common/chrome_paths_mac.mm.
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!base::PathService::Get(base::DIR_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#elif defined(OS_WIN)
// Based on chrome/common/chrome_paths_win.cc.
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#endif
base::FilePath GetUserDataPath(CefSettings* settings) {
if (settings->user_data_path.length > 0)
return base::FilePath(CefString(&settings->user_data_path));
base::FilePath result;
if (GetDefaultUserDataDirectory(&result))
return result;
if (base::PathService::Get(base::DIR_TEMP, &result))
return result;
NOTREACHED();
return result;
}
bool GetDefaultDownloadDirectory(base::FilePath* result) {
// This will return the safe download directory if necessary.
return chrome::GetUserDownloadsDirectory(result);
}
// From chrome/browser/download/download_prefs.cc.
// Consider downloads 'dangerous' if they go to the home directory on Linux and
// to the desktop on any platform.
bool DownloadPathIsDangerous(const base::FilePath& download_path) {
#if defined(OS_LINUX)
base::FilePath home_dir = base::GetHomeDir();
if (download_path == home_dir) {
return true;
}
#endif
base::FilePath desktop_dir;
if (!base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_dir)) {
NOTREACHED();
return false;
}
return (download_path == desktop_dir);
}
bool GetDefaultDownloadSafeDirectory(base::FilePath* result) {
// Start with the default download directory.
if (!GetDefaultDownloadDirectory(result))
return false;
if (DownloadPathIsDangerous(*result)) {
#if defined(OS_WIN) || defined(OS_LINUX)
// Explicitly switch to the safe download directory.
return chrome::GetUserDownloadsDirectorySafe(result);
#else
// No viable alternative on macOS.
return false;
#endif
}
return true;
}
// Returns true if |scale_factor| is supported by this platform.
// Same as ui::ResourceBundle::IsScaleFactorSupported.
bool IsScaleFactorSupported(ui::ScaleFactor scale_factor) {
const std::vector<ui::ScaleFactor>& supported_scale_factors =
ui::GetSupportedScaleFactors();
return std::find(supported_scale_factors.begin(),
supported_scale_factors.end(),
scale_factor) != supported_scale_factors.end();
}
#if defined(OS_LINUX)
// Look for binary files (*.bin, *.dat, *.pak, chrome-sandbox, libGLESv2.so,
// libEGL.so, locales/*.pak, swiftshader/*.so) next to libcef instead of the exe
// on Linux. This is already the default on Windows.
void OverrideAssetPath() {
Dl_info dl_info;
if (dladdr(reinterpret_cast<const void*>(&OverrideAssetPath), &dl_info)) {
base::FilePath path = base::FilePath(dl_info.dli_fname).DirName();
base::PathService::Override(base::DIR_ASSETS, path);
}
}
#endif
} // namespace
AlloyMainDelegate::AlloyMainDelegate(CefMainRunnerHandler* runner,
CefSettings* settings,
CefRefPtr<CefApp> application)
: runner_(runner), settings_(settings), application_(application) {
// Necessary so that exported functions from base_impl.cc will be included
// in the binary.
extern void base_impl_stub();
base_impl_stub();
#if defined(OS_LINUX)
OverrideAssetPath();
#endif
}
AlloyMainDelegate::~AlloyMainDelegate() {}
void AlloyMainDelegate::PreCreateMainMessageLoop() {
runner_->PreCreateMainMessageLoop();
}
bool AlloyMainDelegate::BasicStartupComplete(int* exit_code) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
#if defined(OS_POSIX)
// Read the crash configuration file. Platforms using Breakpad also add a
// command-line switch. On Windows this is done from chrome_elf.
crash_reporting::BasicStartupComplete(command_line);
#endif
if (process_type.empty()) {
// In the browser process. Populate the global command-line object.
if (settings_->command_line_args_disabled) {
// Remove any existing command-line arguments.
base::CommandLine::StringVector argv;
argv.push_back(command_line->GetProgram().value());
command_line->InitFromArgv(argv);
const base::CommandLine::SwitchMap& map = command_line->GetSwitches();
const_cast<base::CommandLine::SwitchMap*>(&map)->clear();
}
bool no_sandbox = settings_->no_sandbox ? true : false;
if (settings_->browser_subprocess_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings_->browser_subprocess_path));
if (!file_path.empty()) {
command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
file_path);
#if defined(OS_WIN)
// The sandbox is not supported when using a separate subprocess
// executable on Windows.
no_sandbox = true;
#endif
}
}
#if defined(OS_MACOSX)
if (settings_->framework_dir_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings_->framework_dir_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kFrameworkDirPath, file_path);
}
if (settings_->main_bundle_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings_->main_bundle_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kMainBundlePath, file_path);
}
#endif
if (no_sandbox)
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
if (settings_->user_agent.length > 0) {
command_line->AppendSwitchASCII(switches::kUserAgent,
CefString(&settings_->user_agent));
} else if (settings_->product_version.length > 0) {
command_line->AppendSwitchASCII(switches::kProductVersion,
CefString(&settings_->product_version));
}
if (settings_->locale.length > 0) {
command_line->AppendSwitchASCII(switches::kLang,
CefString(&settings_->locale));
} else if (!command_line->HasSwitch(switches::kLang)) {
command_line->AppendSwitchASCII(switches::kLang, "en-US");
}
base::FilePath log_file;
bool has_log_file_cmdline = false;
if (settings_->log_file.length > 0)
log_file = base::FilePath(CefString(&settings_->log_file));
if (log_file.empty() && command_line->HasSwitch(switches::kLogFile)) {
log_file = command_line->GetSwitchValuePath(switches::kLogFile);
if (!log_file.empty())
has_log_file_cmdline = true;
}
if (log_file.empty())
log_file = GetDefaultLogFile();
DCHECK(!log_file.empty());
if (!has_log_file_cmdline)
command_line->AppendSwitchPath(switches::kLogFile, log_file);
if (settings_->log_severity != LOGSEVERITY_DEFAULT) {
std::string log_severity;
switch (settings_->log_severity) {
case LOGSEVERITY_VERBOSE:
log_severity = switches::kLogSeverity_Verbose;
break;
case LOGSEVERITY_INFO:
log_severity = switches::kLogSeverity_Info;
break;
case LOGSEVERITY_WARNING:
log_severity = switches::kLogSeverity_Warning;
break;
case LOGSEVERITY_ERROR:
log_severity = switches::kLogSeverity_Error;
break;
case LOGSEVERITY_FATAL:
log_severity = switches::kLogSeverity_Fatal;
break;
case LOGSEVERITY_DISABLE:
log_severity = switches::kLogSeverity_Disable;
break;
default:
break;
}
if (!log_severity.empty())
command_line->AppendSwitchASCII(switches::kLogSeverity, log_severity);
}
if (settings_->javascript_flags.length > 0) {
command_line->AppendSwitchASCII(switches::kJavaScriptFlags,
CefString(&settings_->javascript_flags));
}
if (settings_->pack_loading_disabled) {
command_line->AppendSwitch(switches::kDisablePackLoading);
} else {
if (settings_->resources_dir_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings_->resources_dir_path));
if (!file_path.empty()) {
command_line->AppendSwitchPath(switches::kResourcesDirPath,
file_path);
}
}
if (settings_->locales_dir_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings_->locales_dir_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kLocalesDirPath, file_path);
}
}
if (settings_->remote_debugging_port >= 1024 &&
settings_->remote_debugging_port <= 65535) {
command_line->AppendSwitchASCII(
switches::kRemoteDebuggingPort,
base::NumberToString(settings_->remote_debugging_port));
}
if (settings_->uncaught_exception_stack_size > 0) {
command_line->AppendSwitchASCII(
switches::kUncaughtExceptionStackSize,
base::NumberToString(settings_->uncaught_exception_stack_size));
}
std::vector<std::string> disable_features;
if (network::features::kOutOfBlinkCors.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {
// TODO: Add support for out-of-Blink CORS (see issue #2716)
disable_features.push_back(network::features::kOutOfBlinkCors.name);
}
#if defined(OS_WIN)
if (features::kCalculateNativeWinOcclusion.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {
// TODO: Add support for occlusion detection in combination with native
// parent windows (see issue #2805).
disable_features.push_back(features::kCalculateNativeWinOcclusion.name);
}
#endif // defined(OS_WIN)
if (!disable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance());
std::string disable_features_str =
command_line->GetSwitchValueASCII(switches::kDisableFeatures);
for (auto feature_str : disable_features) {
if (!disable_features_str.empty())
disable_features_str += ",";
disable_features_str += feature_str;
}
command_line->AppendSwitchASCII(switches::kDisableFeatures,
disable_features_str);
}
std::vector<std::string> enable_features;
if (media_router::kDialMediaRouteProvider.default_state ==
base::FEATURE_DISABLED_BY_DEFAULT) {
// Enable discovery of DIAL devices.
enable_features.push_back(media_router::kDialMediaRouteProvider.name);
}
if (media_router::kCastMediaRouteProvider.default_state ==
base::FEATURE_DISABLED_BY_DEFAULT) {
// Enable discovery of Cast devices.
enable_features.push_back(media_router::kCastMediaRouteProvider.name);
}
if (!enable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance());
std::string enable_features_str =
command_line->GetSwitchValueASCII(switches::kEnableFeatures);
for (auto feature_str : enable_features) {
if (!enable_features_str.empty())
enable_features_str += ",";
enable_features_str += feature_str;
}
command_line->AppendSwitchASCII(switches::kEnableFeatures,
enable_features_str);
}
}
if (application_) {
// Give the application a chance to view/modify the command line.
CefRefPtr<CefCommandLineImpl> commandLinePtr(
new CefCommandLineImpl(command_line, false, false));
application_->OnBeforeCommandLineProcessing(CefString(process_type),
commandLinePtr.get());
commandLinePtr->Detach(nullptr);
}
// Initialize logging.
logging::LoggingSettings log_settings;
const base::FilePath& log_file =
command_line->GetSwitchValuePath(switches::kLogFile);
DCHECK(!log_file.empty());
log_settings.log_file_path = log_file.value().c_str();
log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
logging::LogSeverity log_severity = logging::LOG_INFO;
std::string log_severity_str =
command_line->GetSwitchValueASCII(switches::kLogSeverity);
if (!log_severity_str.empty()) {
if (base::LowerCaseEqualsASCII(log_severity_str,
switches::kLogSeverity_Verbose)) {
log_severity = logging::LOG_VERBOSE;
} else if (base::LowerCaseEqualsASCII(log_severity_str,
switches::kLogSeverity_Warning)) {
log_severity = logging::LOG_WARNING;
} else if (base::LowerCaseEqualsASCII(log_severity_str,
switches::kLogSeverity_Error)) {
log_severity = logging::LOG_ERROR;
} else if (base::LowerCaseEqualsASCII(log_severity_str,
switches::kLogSeverity_Fatal)) {
log_severity = logging::LOG_FATAL;
} else if (base::LowerCaseEqualsASCII(log_severity_str,
switches::kLogSeverity_Disable)) {
log_severity = LOGSEVERITY_DISABLE;
}
}
if (log_severity == LOGSEVERITY_DISABLE) {
log_settings.logging_dest = logging::LOG_NONE;
// By default, ERROR and FATAL messages will always be output to stderr due
// to the kAlwaysPrintErrorLevel value in base/logging.cc. We change the log
// level here so that only FATAL messages are output.
logging::SetMinLogLevel(logging::LOG_FATAL);
} else {
log_settings.logging_dest = logging::LOG_TO_ALL;
logging::SetMinLogLevel(log_severity);
}
logging::InitLogging(log_settings);
ContentSettingsPattern::SetNonWildcardDomainNonPortSchemes(
kNonWildcardDomainNonPortSchemes, kNonWildcardDomainNonPortSchemesSize);
content::SetContentClient(&content_client_);
#if defined(OS_MACOSX)
OverrideFrameworkBundlePath();
OverrideOuterBundlePath();
OverrideBaseBundleID();
#endif
return false;
}
void AlloyMainDelegate::PreSandboxStartup() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const std::string& process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty()) {
// Only override these paths when executing the main process.
#if defined(OS_MACOSX)
OverrideChildProcessPath();
#endif
OverridePepperFlashSystemPluginPath();
base::FilePath dir_default_download;
base::FilePath dir_default_download_safe;
if (GetDefaultDownloadDirectory(&dir_default_download)) {
base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS,
dir_default_download);
}
if (GetDefaultDownloadSafeDirectory(&dir_default_download_safe)) {
base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS_SAFE,
dir_default_download_safe);
}
const base::FilePath& user_data_path = GetUserDataPath(settings_);
base::PathService::Override(chrome::DIR_USER_DATA, user_data_path);
// Path used for crash dumps.
base::PathService::Override(chrome::DIR_CRASH_DUMPS, user_data_path);
// Path used for spell checking dictionary files.
base::PathService::OverrideAndCreateIfNeeded(
chrome::DIR_APP_DICTIONARIES,
user_data_path.AppendASCII("Dictionaries"),
false, // May not be an absolute path.
true); // Create if necessary.
}
if (command_line->HasSwitch(switches::kDisablePackLoading))
resource_bundle_delegate_.set_pack_loading_disabled(true);
// Initialize crash reporting state for this process/module.
// chrome::DIR_CRASH_DUMPS must be configured before calling this function.
crash_reporting::PreSandboxStartup(*command_line, process_type);
InitializeResourceBundle();
MaybeInitializeGDI();
}
void AlloyMainDelegate::SandboxInitialized(const std::string& process_type) {
AlloyContentClient::SetPDFEntryFunctions(chrome_pdf::PPP_GetInterface,
chrome_pdf::PPP_InitializeModule,
chrome_pdf::PPP_ShutdownModule);
}
int AlloyMainDelegate::RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) {
if (process_type.empty()) {
return runner_->RunMainProcess(main_function_params);
}
return -1;
}
void AlloyMainDelegate::ProcessExiting(const std::string& process_type) {
ui::ResourceBundle::CleanupSharedInstance();
}
#if defined(OS_LINUX)
void AlloyMainDelegate::ZygoteForked() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
const std::string& process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
// Initialize crash reporting state for the newly forked process.
crash_reporting::ZygoteForked(command_line, process_type);
}
#endif
content::ContentBrowserClient* AlloyMainDelegate::CreateContentBrowserClient() {
browser_client_.reset(new AlloyContentBrowserClient);
return browser_client_.get();
}
content::ContentRendererClient*
AlloyMainDelegate::CreateContentRendererClient() {
renderer_client_.reset(new AlloyContentRendererClient);
return renderer_client_.get();
}
content::ContentUtilityClient* AlloyMainDelegate::CreateContentUtilityClient() {
utility_client_.reset(new ChromeContentUtilityClient);
return utility_client_.get();
}
CefRefPtr<CefRequestContext> AlloyMainDelegate::GetGlobalRequestContext() {
if (!browser_client_)
return nullptr;
return browser_client_->request_context();
}
scoped_refptr<base::SingleThreadTaskRunner>
AlloyMainDelegate::GetBackgroundTaskRunner() {
if (browser_client_)
return browser_client_->background_task_runner();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
AlloyMainDelegate::GetUserVisibleTaskRunner() {
if (browser_client_)
return browser_client_->user_visible_task_runner();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
AlloyMainDelegate::GetUserBlockingTaskRunner() {
if (browser_client_)
return browser_client_->user_blocking_task_runner();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
AlloyMainDelegate::GetRenderTaskRunner() {
if (renderer_client_)
return renderer_client_->render_task_runner();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
AlloyMainDelegate::GetWebWorkerTaskRunner() {
if (renderer_client_)
return renderer_client_->GetCurrentTaskRunner();
return nullptr;
}
void AlloyMainDelegate::InitializeResourceBundle() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
base::FilePath cef_pak_file, cef_100_percent_pak_file,
cef_200_percent_pak_file, cef_extensions_pak_file, devtools_pak_file,
locales_dir;
base::FilePath resources_dir;
if (command_line->HasSwitch(switches::kResourcesDirPath)) {
resources_dir =
command_line->GetSwitchValuePath(switches::kResourcesDirPath);
}
if (resources_dir.empty())
resources_dir = GetResourcesFilePath();
if (!resources_dir.empty())
base::PathService::Override(chrome::DIR_RESOURCES, resources_dir);
if (!resource_bundle_delegate_.pack_loading_disabled()) {
if (!resources_dir.empty()) {
CHECK(resources_dir.IsAbsolute());
cef_pak_file = resources_dir.Append(FILE_PATH_LITERAL("cef.pak"));
cef_100_percent_pak_file =
resources_dir.Append(FILE_PATH_LITERAL("cef_100_percent.pak"));
cef_200_percent_pak_file =
resources_dir.Append(FILE_PATH_LITERAL("cef_200_percent.pak"));
cef_extensions_pak_file =
resources_dir.Append(FILE_PATH_LITERAL("cef_extensions.pak"));
devtools_pak_file =
resources_dir.Append(FILE_PATH_LITERAL("devtools_resources.pak"));
}
if (command_line->HasSwitch(switches::kLocalesDirPath))
locales_dir = command_line->GetSwitchValuePath(switches::kLocalesDirPath);
if (!locales_dir.empty())
base::PathService::Override(ui::DIR_LOCALES, locales_dir);
}
std::string locale = command_line->GetSwitchValueASCII(switches::kLang);
DCHECK(!locale.empty());
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(
locale, &resource_bundle_delegate_,
ui::ResourceBundle::LOAD_COMMON_RESOURCES);
if (!loaded_locale.empty() && g_browser_process)
g_browser_process->SetApplicationLocale(loaded_locale);
ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
if (!resource_bundle_delegate_.pack_loading_disabled()) {
if (loaded_locale.empty())
LOG(ERROR) << "Could not load locale pak for " << locale;
resource_bundle_delegate_.set_allow_pack_file_load(true);
if (base::PathExists(cef_pak_file)) {
resource_bundle.AddDataPackFromPath(cef_pak_file, ui::SCALE_FACTOR_NONE);
} else {
LOG(ERROR) << "Could not load cef.pak";
}
// On OS X and Linux/Aura always load the 1x data pack first as the 2x data
// pack contains both 1x and 2x images.
const bool load_100_percent =
#if defined(OS_WIN)
IsScaleFactorSupported(ui::SCALE_FACTOR_100P);
#else
true;
#endif
if (load_100_percent) {
if (base::PathExists(cef_100_percent_pak_file)) {
resource_bundle.AddDataPackFromPath(cef_100_percent_pak_file,
ui::SCALE_FACTOR_100P);
} else {
LOG(ERROR) << "Could not load cef_100_percent.pak";
}
}
if (IsScaleFactorSupported(ui::SCALE_FACTOR_200P)) {
if (base::PathExists(cef_200_percent_pak_file)) {
resource_bundle.AddDataPackFromPath(cef_200_percent_pak_file,
ui::SCALE_FACTOR_200P);
} else {
LOG(ERROR) << "Could not load cef_200_percent.pak";
}
}
if (extensions::ExtensionsEnabled() ||
!command_line->HasSwitch(switches::kDisablePlugins)) {
if (base::PathExists(cef_extensions_pak_file)) {
resource_bundle.AddDataPackFromPath(cef_extensions_pak_file,
ui::SCALE_FACTOR_NONE);
} else {
LOG(ERROR) << "Could not load cef_extensions.pak";
}
}
if (base::PathExists(devtools_pak_file)) {
resource_bundle.AddDataPackFromPath(devtools_pak_file,
ui::SCALE_FACTOR_NONE);
}
resource_bundle_delegate_.set_allow_pack_file_load(false);
}
}