Fix build and initial Chrome runtime issues on macOS (see issue #2969)

This change moves shared resource initialization to a common location and
disables crash reporting initialization in chrome/ code via patch files.

When using the Chrome runtime on macOS the Chrome application window will
display, but web content is currently blank and the application does not
exit cleanly. This will need to be debugged further in the future.
This commit is contained in:
Marshall Greenblatt 2020-07-06 14:14:57 -04:00
parent 02cdf05848
commit 03c9156c80
20 changed files with 745 additions and 326 deletions

View File

@ -714,6 +714,8 @@ static_library("libcef_static") {
"libcef/common/resource_bundle_delegate.h",
"libcef/common/resource_bundle_impl.cc",
"libcef/common/resource_bundle_impl.h",
"libcef/common/resource_util.cc",
"libcef/common/resource_util.h",
"libcef/common/response_impl.cc",
"libcef/common/response_impl.h",
"libcef/common/response_manager.cc",
@ -1731,10 +1733,6 @@ if (is_mac) {
gypi_paths2.libcef_sources_common +
gypi_paths.autogen_library_side
# TODO(rsesek): Handle these missing pieces:
# - crash_inspector
# - crash_report_sender.app
deps = [
":cef_framework_angle_library",
":cef_framework_locales",

View File

@ -9,7 +9,10 @@
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "base/path_service.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
ChromeContentBrowserClientCef::ChromeContentBrowserClientCef(
StartupData* startup_data)
@ -35,6 +38,13 @@ void ChromeContentBrowserClientCef::AppendExtraCommandLineSwitches(
// Necessary to launch sub-processes in the correct mode.
command_line->AppendSwitch(switches::kEnableChromeRuntime);
// Necessary to populate DIR_USER_DATA in sub-processes.
// See resource_util.cc GetUserDataPath.
base::FilePath user_data_dir;
if (base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
}
}
CefRefPtr<CefRequestContextImpl>

View File

@ -59,7 +59,8 @@ std::unique_ptr<CefMainRunnerDelegate> MakeDelegate(
application);
} else {
g_runtime_type = RuntimeType::CHROME;
return std::make_unique<ChromeMainRunnerDelegate>(runner, application);
return std::make_unique<ChromeMainRunnerDelegate>(runner, settings,
application);
}
}

View File

@ -4,16 +4,13 @@
#include "libcef/common/alloy/alloy_main_delegate.h"
#if defined(OS_LINUX)
#include <dlfcn.h>
#endif
#include "libcef/browser/alloy/alloy_browser_context.h"
#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/common/resource_util.h"
#include "libcef/renderer/alloy/alloy_content_renderer_client.h"
#include "base/base_switches.h"
@ -30,7 +27,6 @@
#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"
@ -45,12 +41,15 @@
#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 defined(OS_MACOSX)
#include "libcef/common/util_mac.h"
#endif
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
#include "content/public/common/content_ipc_logging.h"
@ -59,22 +58,6 @@
#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[] = {
@ -82,241 +65,6 @@ const char* const kNonWildcardDomainNonPortSchemes[] = {
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,
@ -329,7 +77,7 @@ AlloyMainDelegate::AlloyMainDelegate(CefMainRunnerHandler* runner,
base_impl_stub();
#if defined(OS_LINUX)
OverrideAssetPath();
resource_util::OverrideAssetPath();
#endif
}
@ -423,7 +171,7 @@ bool AlloyMainDelegate::BasicStartupComplete(int* exit_code) {
has_log_file_cmdline = true;
}
if (log_file.empty())
log_file = GetDefaultLogFile();
log_file = resource_util::GetDefaultLogFilePath();
DCHECK(!log_file.empty());
if (!has_log_file_cmdline)
command_line->AppendSwitchPath(switches::kLogFile, log_file);
@ -614,9 +362,7 @@ bool AlloyMainDelegate::BasicStartupComplete(int* exit_code) {
content::SetContentClient(&content_client_);
#if defined(OS_MACOSX)
OverrideFrameworkBundlePath();
OverrideOuterBundlePath();
OverrideBaseBundleID();
util_mac::BasicStartupComplete();
#endif
return false;
@ -631,34 +377,12 @@ void AlloyMainDelegate::PreSandboxStartup() {
if (process_type.empty()) {
// Only override these paths when executing the main process.
#if defined(OS_MACOSX)
OverrideChildProcessPath();
util_mac::PreSandboxStartup();
#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.
resource_util::OverridePepperFlashSystemPluginPath();
resource_util::OverrideDefaultDownloadDir();
resource_util::OverrideUserDataDir(settings_, command_line);
}
if (command_line->HasSwitch(switches::kDisablePackLoading))
@ -779,7 +503,7 @@ void AlloyMainDelegate::InitializeResourceBundle() {
command_line->GetSwitchValuePath(switches::kResourcesDirPath);
}
if (resources_dir.empty())
resources_dir = GetResourcesFilePath();
resources_dir = resource_util::GetResourcesDir();
if (!resources_dir.empty())
base::PathService::Override(chrome::DIR_RESOURCES, resources_dir);
@ -832,7 +556,7 @@ void AlloyMainDelegate::InitializeResourceBundle() {
// pack contains both 1x and 2x images.
const bool load_100_percent =
#if defined(OS_WIN)
IsScaleFactorSupported(ui::SCALE_FACTOR_100P);
resource_util::IsScaleFactorSupported(ui::SCALE_FACTOR_100P);
#else
true;
#endif
@ -846,7 +570,7 @@ void AlloyMainDelegate::InitializeResourceBundle() {
}
}
if (IsScaleFactorSupported(ui::SCALE_FACTOR_200P)) {
if (resource_util::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);

View File

@ -7,17 +7,78 @@
#include "libcef/browser/chrome/chrome_browser_context.h"
#include "libcef/browser/chrome/chrome_content_browser_client_cef.h"
#include "libcef/common/crash_reporting.h"
#include "libcef/common/resource_util.h"
#include "content/public/common/content_switches.h"
#if defined(OS_MACOSX)
#include "libcef/common/util_mac.h"
#endif
ChromeMainDelegateCef::ChromeMainDelegateCef(CefMainRunnerHandler* runner,
CefSettings* settings,
CefRefPtr<CefApp> application)
: ChromeMainDelegate(base::TimeTicks::Now()),
runner_(runner),
application_(application) {}
settings_(settings),
application_(application) {
#if defined(OS_LINUX)
resource_util::OverrideAssetPath();
#endif
}
ChromeMainDelegateCef::~ChromeMainDelegateCef() = default;
bool ChromeMainDelegateCef::BasicStartupComplete(int* exit_code) {
// Returns false if startup should proceed.
bool result = ChromeMainDelegate::BasicStartupComplete(exit_code);
if (!result) {
#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(
base::CommandLine::ForCurrentProcess());
#endif
#if defined(OS_MACOSX)
util_mac::BasicStartupComplete();
#endif
}
return result;
}
void ChromeMainDelegateCef::PreSandboxStartup() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const std::string& process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
#if defined(OS_MACOSX)
if (process_type.empty()) {
util_mac::PreSandboxStartup();
}
#endif // defined(OS_MACOSX)
// Since this may be configured via CefSettings we override the value on
// all platforms. We can't use the default implementation on macOS because
// chrome::GetDefaultUserDataDirectory expects to find the Chromium version
// number in the app bundle path.
resource_util::OverrideUserDataDir(settings_, command_line);
ChromeMainDelegate::PreSandboxStartup();
// 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);
}
void ChromeMainDelegateCef::PreCreateMainMessageLoop() {
// The parent ChromeMainDelegate implementation creates the NSApplication
// instance on macOS, and we intentionally don't want to do that here.
// TODO(macos): Do we need l10n_util::OverrideLocaleWithCocoaLocale()?
runner_->PreCreateMainMessageLoop();
}
@ -31,6 +92,19 @@ int ChromeMainDelegateCef::RunProcess(
return ChromeMainDelegate::RunProcess(process_type, main_function_params);
}
#if defined(OS_LINUX)
void ChromeMainDelegateCef::ZygoteForked() {
ChromeMainDelegate::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 // defined(OS_LINUX)
content::ContentClient* ChromeMainDelegateCef::CreateContentClient() {
return &chrome_content_client_cef_;
}

View File

@ -27,14 +27,20 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
// |runner| will be non-nullptr for the main process only, and will outlive
// this object.
ChromeMainDelegateCef(CefMainRunnerHandler* runner,
CefSettings* settings,
CefRefPtr<CefApp> application);
~ChromeMainDelegateCef() override;
// ChromeMainDelegate overrides.
bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override;
void PreCreateMainMessageLoop() override;
int RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) override;
#if defined(OS_LINUX)
void ZygoteForked() override;
#endif
content::ContentClient* CreateContentClient() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
@ -62,6 +68,7 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
ChromeContentBrowserClientCef* content_browser_client() const;
CefMainRunnerHandler* const runner_;
CefSettings* const settings_;
CefRefPtr<CefApp> application_;
// We use this instead of ChromeMainDelegate::chrome_content_client_.

View File

@ -14,21 +14,19 @@
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#if defined(OS_MACOSX)
#include "chrome/app/chrome_main_mac.h"
#endif
ChromeMainRunnerDelegate::ChromeMainRunnerDelegate(
CefMainRunnerHandler* runner,
CefSettings* settings,
CefRefPtr<CefApp> application)
: runner_(runner), application_(application) {}
: runner_(runner), settings_(settings), application_(application) {}
ChromeMainRunnerDelegate::~ChromeMainRunnerDelegate() = default;
content::ContentMainDelegate*
ChromeMainRunnerDelegate::GetContentMainDelegate() {
if (!main_delegate_) {
main_delegate_ =
std::make_unique<ChromeMainDelegateCef>(runner_, application_);
main_delegate_ = std::make_unique<ChromeMainDelegateCef>(runner_, settings_,
application_);
}
return main_delegate_.get();
}
@ -41,10 +39,6 @@ void ChromeMainRunnerDelegate::BeforeMainThreadInitialize(
base::CommandLine::Init(args.argc, args.argv);
#endif
#if defined(OS_MACOSX)
SetUpBundleOverrides();
#endif
sampling_profiler_ = std::make_unique<MainThreadStackSamplingProfiler>();
}

View File

@ -21,6 +21,7 @@ class ChromeMainRunnerDelegate : public CefMainRunnerDelegate {
// |runner| will be non-nullptr for the main process only, and will outlive
// this object.
ChromeMainRunnerDelegate(CefMainRunnerHandler* runner,
CefSettings* settings,
CefRefPtr<CefApp> application);
~ChromeMainRunnerDelegate() override;
@ -41,6 +42,7 @@ class ChromeMainRunnerDelegate : public CefMainRunnerDelegate {
std::unique_ptr<ScopedKeepAlive> keep_alive_;
CefMainRunnerHandler* const runner_;
CefSettings* const settings_;
CefRefPtr<CefApp> application_;
DISALLOW_COPY_AND_ASSIGN(ChromeMainRunnerDelegate);

View File

@ -6,6 +6,7 @@
#include "include/cef_crash_util.h"
#include "libcef/common/cef_switches.h"
#include "libcef/features/runtime.h"
#include "base/base_switches.h"
#include "base/command_line.h"
@ -258,3 +259,12 @@ void CefSetCrashKeyValue(const CefString& key, const CefString& value) {
<< " with value: " << value.ToString();
}
}
// From libcef/features/runtime.h:
namespace cef {
bool IsCrashReportingEnabled() {
return crash_reporting::Enabled();
}
} // namespace cef

View File

@ -0,0 +1,273 @@
// Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
// 2011 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/resource_util.h"
#if defined(OS_LINUX)
#include <dlfcn.h>
#endif
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.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 "ui/base/layout.h"
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#include "libcef/common/util_mac.h"
#endif
#if defined(OS_LINUX)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#endif
#if defined(OS_WIN)
#include "base/win/registry.h"
#endif
namespace resource_util {
namespace {
#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
#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,
const base::CommandLine* command_line) {
// |settings| will be non-nullptr in the main process only.
if (settings && settings->user_data_path.length > 0)
return base::FilePath(CefString(&settings->user_data_path));
// This may be set for sub-processes.
base::FilePath result =
command_line->GetSwitchValuePath(switches::kUserDataDir);
if (!result.empty())
return result;
if (GetDefaultUserDataDirectory(&result))
return result;
if (base::PathService::Get(base::DIR_TEMP, &result))
return result;
NOTREACHED();
return result;
}
// Consider downloads 'dangerous' if they go to the home directory on Linux and
// to the desktop on any platform.
// From chrome/browser/download/download_prefs.cc.
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 GetDefaultDownloadDirectory(base::FilePath* result) {
// This will return the safe download directory if necessary.
return chrome::GetUserDownloadsDirectory(result);
}
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;
}
} // namespace
#if defined(OS_MACOSX)
base::FilePath GetResourcesDir() {
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 GetDefaultLogFilePath() {
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"));
}
#else // !defined(OS_MACOSX)
base::FilePath GetResourcesDir() {
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 GetDefaultLogFilePath() {
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)
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
}
void OverrideDefaultDownloadDir() {
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);
}
}
void OverrideUserDataDir(CefSettings* settings,
const base::CommandLine* command_line) {
const base::FilePath& user_data_path =
GetUserDataPath(settings, command_line);
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.
}
// 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)
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 resource_util

View File

@ -0,0 +1,45 @@
// Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
// 2011 The Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEF_LIBCEF_COMMON_RESOURCE_UTIL_H_
#define CEF_LIBCEF_COMMON_RESOURCE_UTIL_H_
#pragma once
#include "include/cef_base.h"
#include "ui/base/resource/scale_factor.h"
namespace base {
class CommandLine;
class FilePath;
} // namespace base
namespace resource_util {
// Returns the directory that contains resource files (*.bin, *.dat, *.pak,
// etc).
base::FilePath GetResourcesDir();
// Returns the default path for the debug.log file.
base::FilePath GetDefaultLogFilePath();
// Called from MainDelegate::PreSandboxStartup.
void OverridePepperFlashSystemPluginPath();
void OverrideDefaultDownloadDir();
void OverrideUserDataDir(CefSettings* settings,
const base::CommandLine* command_line);
// Returns true if |scale_factor| is supported by this platform.
bool IsScaleFactorSupported(ui::ScaleFactor scale_factor);
#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();
#endif
} // namespace resource_util
#endif // CEF_LIBCEF_COMMON_RESOURCE_UTIL_H_

View File

@ -50,6 +50,12 @@ base::FilePath GetMainResourcesDirectory();
// return an empty value if not running in an app bundle.
base::FilePath GetChildProcessPath();
// Called from MainDelegate::PreSandboxStartup for the main process.
void PreSandboxStartup();
// Called from MainDelegate::BasicStartupComplete for all processes.
void BasicStartupComplete();
} // namespace util_mac
#endif // CEF_LIBCEF_COMMON_UTIL_MAC_H_

View File

@ -9,10 +9,13 @@
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
namespace util_mac {
@ -28,6 +31,41 @@ base::FilePath GetFrameworksPath() {
.Append(FILE_PATH_LITERAL("Frameworks"));
}
void OverrideFrameworkBundlePath() {
base::FilePath framework_path = GetFrameworkDirectory();
DCHECK(!framework_path.empty());
base::mac::SetOverrideFrameworkBundlePath(framework_path);
}
void OverrideOuterBundlePath() {
base::FilePath bundle_path = GetMainBundlePath();
DCHECK(!bundle_path.empty());
base::mac::SetOverrideOuterBundlePath(bundle_path);
}
void OverrideBaseBundleID() {
std::string bundle_id = 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);
}
} // namespace
bool GetLocalLibraryDirectory(base::FilePath* result) {
@ -100,4 +138,14 @@ base::FilePath GetChildProcessPath() {
.Append(FILE_PATH_LITERAL(exe_name + " Helper"));
}
void PreSandboxStartup() {
OverrideChildProcessPath();
}
void BasicStartupComplete() {
OverrideFrameworkBundlePath();
OverrideOuterBundlePath();
OverrideBaseBundleID();
}
} // namespace util_mac

View File

@ -22,6 +22,9 @@ bool IsAlloyRuntimeEnabled();
// True if CEF was initialized with the Chrome runtime.
bool IsChromeRuntimeEnabled();
// True if CEF crash reporting is enabled.
bool IsCrashReportingEnabled();
#else
inline bool IsCefBuildEnabled() {
@ -33,6 +36,9 @@ inline bool IsAlloyRuntimeEnabled() {
inline bool IsChromeRuntimeEnabled() {
return false;
}
inline bool IsCrashReportingEnabled() {
return false;
}
#endif

View File

@ -23,8 +23,8 @@ patches = [
{
# Necessary for GN integration.
#
# Move chrome target locales output to a chrome/ directory to avoid
# conflicts with the CEF configuration.
# Exclude the //chrome:packed_resources_locales target from the CEF build
# due to conflicting outputs with the //cef:repack_locales_pack target.
#
# Write environment.* files with the correct SDK version on Windows.
# https://bugs.chromium.org/p/chromium/issues/detail?id=634788

View File

@ -1,3 +1,39 @@
diff --git chrome/browser/app_controller_mac.mm chrome/browser/app_controller_mac.mm
index 559e51776e42..a429421f7c61 100644
--- chrome/browser/app_controller_mac.mm
+++ chrome/browser/app_controller_mac.mm
@@ -1140,6 +1140,7 @@ - (void)commandDispatch:(id)sender {
// Run a (background) application in a new tab.
- (void)executeApplication:(id)sender {
+#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
NSInteger tag = [sender tag];
Profile* profile = [self lastProfile];
DCHECK(profile);
@@ -1148,6 +1149,7 @@ - (void)executeApplication:(id)sender {
tag < static_cast<int>(applications.size()));
const extensions::Extension* extension = applications.GetExtension(tag);
BackgroundModeManager::LaunchBackgroundApplication(profile, extension);
+#endif // BUILDFLAG(ENABLE_BACKGROUND_MODE)
}
// Same as |-commandDispatch:|, but executes commands using a disposition
@@ -1529,6 +1531,7 @@ - (NSMenu*)applicationDockMenu:(NSApplication*)sender {
// TODO(rickcam): Mock out BackgroundApplicationListModel, then add unit
// tests which use the mock in place of the profile-initialized model.
+#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
// Avoid breaking unit tests which have no profile.
if (profile) {
BackgroundApplicationListModel applications(profile);
@@ -1555,6 +1558,7 @@ - (NSMenu*)applicationDockMenu:(NSApplication*)sender {
}
}
}
+#endif // BUILDFLAG(ENABLE_BACKGROUND_MODE)
return dockMenu;
}
diff --git chrome/browser/browser_process.h chrome/browser/browser_process.h
index 6332572ac884..bf555124ce59 100644
--- chrome/browser/browser_process.h

View File

@ -1,3 +1,82 @@
diff --git chrome/app/chrome_main_delegate.cc chrome/app/chrome_main_delegate.cc
index d18dbaa7d058..650031520b25 100644
--- chrome/app/chrome_main_delegate.cc
+++ chrome/app/chrome_main_delegate.cc
@@ -25,6 +25,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event_impl.h"
#include "build/build_config.h"
+#include "cef/libcef/features/runtime.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/chrome_resource_bundle_helper.h"
#include "chrome/browser/defaults.h"
@@ -391,6 +392,8 @@ struct MainFunction {
// Initializes the user data dir. Must be called before InitializeLocalState().
void InitializeUserDataDir(base::CommandLine* command_line) {
+ if (cef::IsChromeRuntimeEnabled())
+ return;
#if defined(OS_WIN)
// Reach out to chrome_elf for the truth on the user data directory.
// Note that in tests, this links to chrome_elf_test_stubs.
@@ -628,7 +631,9 @@ void ChromeMainDelegate::PostFieldTrialInitialization() {
}
#if defined(OS_WIN)
+ if (!cef::IsChromeRuntimeEnabled()) {
SetUpExtendedCrashReporting(is_browser_process);
+ }
base::Time::ReadMinTimerIntervalLowResMs();
base::sequence_manager::PostFieldTrialInitialization();
#endif
@@ -904,6 +909,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
+ if (!cef::IsChromeRuntimeEnabled()) {
crash_reporter::InitializeCrashKeys();
#if defined(OS_POSIX)
@@ -914,6 +920,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
InitMacCrashReporter(command_line, process_type);
SetUpInstallerPreferences(command_line);
#endif
+ } // !cef::IsChromeRuntimeEnabled()
#if defined(OS_WIN)
child_process_logging::Init();
@@ -1037,6 +1044,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
locale;
}
+ if (!cef::IsChromeRuntimeEnabled()) {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
// Zygote needs to call InitCrashReporter() in RunZygote().
if (process_type != service_manager::switches::kZygoteProcess) {
@@ -1063,6 +1071,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
// After all the platform Breakpads have been initialized, store the command
// line for crash reporting.
crash_keys::SetCrashKeysFromCommandLine(command_line);
+ } // !cef::IsChromeRuntimeEnabled()
#if BUILDFLAG(ENABLE_PDF)
MaybeInitializeGDI();
@@ -1162,6 +1171,7 @@ void ChromeMainDelegate::ZygoteForked() {
SetUpProfilingShutdownHandler();
}
+ if (!cef::IsChromeRuntimeEnabled()) {
// Needs to be called after we have chrome::DIR_USER_DATA. BrowserMain sets
// this up for the browser process in a different manner.
const base::CommandLine* command_line =
@@ -1178,6 +1188,7 @@ void ChromeMainDelegate::ZygoteForked() {
// Reset the command line for the newly spawned process.
crash_keys::SetCrashKeysFromCommandLine(*command_line);
+ } // !cef::IsChromeRuntimeEnabled()
}
#endif // defined(OS_LINUX)
diff --git chrome/browser/chrome_browser_main.cc chrome/browser/chrome_browser_main.cc
index c06585b15b8f..763212a575ce 100644
--- chrome/browser/chrome_browser_main.cc
@ -37,6 +116,31 @@ index c06585b15b8f..763212a575ce 100644
#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
// Initialize autoupdate timer. Timer callback costs basically nothing
// when browser is not in persistent mode, so it's OK to let it ride on
diff --git chrome/browser/notifications/notification_platform_bridge_mac.mm chrome/browser/notifications/notification_platform_bridge_mac.mm
index acf1849aa1b3..27efc35d74d6 100644
--- chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -25,6 +25,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
#include "base/task/post_task.h"
+#include "cef/libcef/features/runtime.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/notifications/notification_common.h"
#include "chrome/browser/notifications/notification_display_service_impl.h"
@@ -642,6 +643,12 @@ - (void)notificationClick:(NSDictionary*)notificationResponseData {
- (id<NotificationDelivery>)serviceProxy {
id<NotificationDelivery> proxy = [_xpcConnection remoteObjectProxy];
+ // Skip exception port configuration when running CEF with crash reporting disabled.
+ if (!_setExceptionPort && cef::IsChromeRuntimeEnabled() &&
+ !cef::IsCrashReportingEnabled()) {
+ _setExceptionPort = YES;
+ }
+
if (!_setExceptionPort) {
base::mac::ScopedMachSendRight exceptionPort(
crash_reporter::GetCrashpadClient().GetHandlerMachPort());
diff --git ui/gtk/select_file_dialog_impl_kde.cc ui/gtk/select_file_dialog_impl_kde.cc
index f09501d6cd8e..edfc2a4c9bb5 100644
--- ui/gtk/select_file_dialog_impl_kde.cc

View File

@ -56,28 +56,68 @@ index 982fbe8d3f0d..e757be4688f1 100644
+ "studio path")
}
diff --git chrome/chrome_paks.gni chrome/chrome_paks.gni
index deef406b9273..2dfd2cd8c2ef 100644
index deef406b9273..ad338636cf5d 100644
--- chrome/chrome_paks.gni
+++ chrome/chrome_paks.gni
@@ -303,7 +303,7 @@ template("chrome_paks") {
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/locales.gni")
+import("//cef/libcef/features/features.gni")
import("//chrome/browser/buildflags.gni")
import("//chrome/common/features.gni")
import("//chromeos/components/media_app_ui/media_app_ui.gni")
@@ -289,6 +290,7 @@ template("chrome_paks") {
}
}
input_locales = locales
- output_dir = "${invoker.output_dir}/locales"
+ output_dir = "${invoker.output_dir}/chrome/locales"
+ if (!enable_cef) {
chrome_repack_locales("${target_name}_locales") {
forward_variables_from(invoker,
[
@@ -311,14 +313,17 @@ template("chrome_paks") {
output_locales = locales
}
}
+ } # !enable_cef
if (is_mac) {
output_locales = locales_as_mac_outputs
group(target_name) {
forward_variables_from(invoker, [ "deps" ])
public_deps = [
":${target_name}_100_percent",
":${target_name}_extra",
- ":${target_name}_locales",
]
+ if (!enable_cef) {
+ public_deps += [ ":${target_name}_locales" ]
+ }
if (enable_hidpi) {
public_deps += [ ":${target_name}_200_percent" ]
}
diff --git chrome/installer/mini_installer/BUILD.gn chrome/installer/mini_installer/BUILD.gn
index 056d425c4194..dd1a5094ec8d 100644
index 056d425c4194..0c0e0f22ab66 100644
--- chrome/installer/mini_installer/BUILD.gn
+++ chrome/installer/mini_installer/BUILD.gn
@@ -134,7 +134,7 @@ template("generate_mini_installer") {
@@ -5,6 +5,7 @@
import("//build/config/compiler/compiler.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
+import("//cef/libcef/features/features.gni")
import("//chrome/process_version_rc_template.gni")
import("//components/nacl/features.gni")
import("//third_party/icu/config.gni")
@@ -134,11 +135,13 @@ template("generate_mini_installer") {
inputs = [
"$chrome_dll_file",
"$root_out_dir/chrome.exe",
- "$root_out_dir/locales/en-US.pak",
+ "$root_out_dir/chrome/locales/en-US.pak",
"$root_out_dir/setup.exe",
"//chrome/tools/build/win/makecab.py",
release_file,
]
+ if (!enable_cef) {
+ inputs += [ "$root_out_dir/locales/en-US.pak" ]
+ }
outputs = [
# See also chrome.packed.7z conditionally added below.

View File

@ -363,6 +363,11 @@ int RunMain(int argc, char* argv[]) {
// Initialize the ClientApplication instance.
[ClientApplication sharedApplication];
// If there was an invocation to NSApp prior to this method, then the NSApp
// will not be a ClientApplication, but will instead be an NSApplication.
// This is undesirable and we must enforce that this doesn't happen.
CHECK([NSApp isKindOfClass:[ClientApplication class]]);
// Parse command-line arguments.
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::CreateCommandLine();

View File

@ -6,13 +6,19 @@
#import <Cocoa/Cocoa.h>
#include "include/cef_application_mac.h"
#include "include/cef_command_line.h"
#include "include/wrapper/cef_helpers.h"
#include "include/wrapper/cef_library_loader.h"
#include "tests/cefsimple/simple_app.h"
#include "tests/cefsimple/simple_handler.h"
// Receives notifications from the application.
@interface SimpleAppDelegate : NSObject <NSApplicationDelegate>
@interface SimpleAppDelegate : NSObject <NSApplicationDelegate> {
@private
bool with_chrome_runtime_;
}
- (id)initWithChromeRuntime:(bool)with_chrome_runtime;
- (void)createApplication:(id)object;
- (void)tryToTerminateApplication:(NSApplication*)app;
@end
@ -85,12 +91,23 @@
@implementation SimpleAppDelegate
- (id)initWithChromeRuntime:(bool)with_chrome_runtime {
if (self = [super init]) {
with_chrome_runtime_ = with_chrome_runtime;
}
return self;
}
// Create the application on the UI thread.
- (void)createApplication:(id)object {
[NSApplication sharedApplication];
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:nil];
if (!with_chrome_runtime_) {
// Chrome will create the top-level menu programmatically in
// chrome/browser/ui/cocoa/main_menu_builder.h
// TODO(chrome-runtime): Expose a way to customize this menu.
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:nil];
}
// Set the delegate for application events.
[[NSApplication sharedApplication] setDelegate:self];
@ -123,9 +140,27 @@ int main(int argc, char* argv[]) {
// Initialize the SimpleApplication instance.
[SimpleApplication sharedApplication];
// If there was an invocation to NSApp prior to this method, then the NSApp
// will not be a SimpleApplication, but will instead be an NSApplication.
// This is undesirable and we must enforce that this doesn't happen.
CHECK([NSApp isKindOfClass:[SimpleApplication class]]);
// Parse command-line arguments for use in this method.
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::CreateCommandLine();
command_line->InitFromArgv(argc, argv);
// Specify CEF global settings here.
CefSettings settings;
const bool with_chrome_runtime =
command_line->HasSwitch("enable-chrome-runtime");
if (with_chrome_runtime) {
// Enable experimental Chrome runtime. See issue #2969 for details.
settings.chrome_runtime = true;
}
// When generating projects with CMake the CEF_USE_SANDBOX value will be
// defined automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line
// to disable use of the sandbox.
@ -142,7 +177,8 @@ int main(int argc, char* argv[]) {
CefInitialize(main_args, settings, app.get(), NULL);
// Create the application delegate.
NSObject* delegate = [[SimpleAppDelegate alloc] init];
NSObject* delegate =
[[SimpleAppDelegate alloc] initWithChromeRuntime:with_chrome_runtime];
[delegate performSelectorOnMainThread:@selector(createApplication:)
withObject:nil
waitUntilDone:NO];