mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
alloy: Add callback for already running app relaunch (fixes #3615)
Executes CefBrowserProcessHandler::OnAlreadyRunningAppRelaunch callback for when an already running app is relaunched with the same CefSettings.root_cache_path. Adds "Root Cache Path" value and related explainer text to chrome://version. Adds a LOG(WARNING) that will be output on startup if CefSettings.root_cache_path is unset in the client app.
This commit is contained in:
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=9e91adb231d67a65ce02294a0806d7effd40d280$
|
||||
// $hash=dad764dddf92655cc580e0e7e85d3f3c34bdd46d$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_
|
||||
@ -122,8 +122,7 @@ typedef struct _cef_browser_process_handler_t {
|
||||
/// therefore check the cef_initialize() return value for early exit before
|
||||
/// proceeding.
|
||||
///
|
||||
/// This function will be called on the browser process UI thread. Currently
|
||||
/// only used with the chrome runtime.
|
||||
/// This function will be called on the browser process UI thread.
|
||||
///
|
||||
int(CEF_CALLBACK* on_already_running_app_relaunch)(
|
||||
struct _cef_browser_process_handler_t* self,
|
||||
|
@ -113,8 +113,7 @@ class CefBrowserProcessHandler : public virtual CefBaseRefCounted {
|
||||
/// therefore check the CefInitialize() return value for early exit before
|
||||
/// proceeding.
|
||||
///
|
||||
/// This method will be called on the browser process UI thread. Currently
|
||||
/// only used with the chrome runtime.
|
||||
/// This method will be called on the browser process UI thread.
|
||||
///
|
||||
/*--cef(optional_param=current_directory)--*/
|
||||
virtual bool OnAlreadyRunningAppRelaunch(
|
||||
|
@ -279,31 +279,46 @@ typedef struct _cef_settings_t {
|
||||
int command_line_args_disabled;
|
||||
|
||||
///
|
||||
/// The location where data for the global browser cache will be stored on
|
||||
/// The directory where data for the global browser cache will be stored on
|
||||
/// disk. If this value is non-empty then it must be an absolute path that is
|
||||
/// either equal to or a child directory of CefSettings.root_cache_path. If
|
||||
/// this value is empty then browsers will be created in "incognito mode"
|
||||
/// where in-memory caches are used for storage and no data is persisted to
|
||||
/// disk. HTML5 databases such as localStorage will only persist across
|
||||
/// sessions if a cache path is specified. Can be overridden for individual
|
||||
/// CefRequestContext instances via the CefRequestContextSettings.cache_path
|
||||
/// value. When using the Chrome runtime the "default" profile will be used if
|
||||
/// |cache_path| and |root_cache_path| have the same value.
|
||||
/// where in-memory caches are used for storage and no profile-specific data
|
||||
/// is persisted to disk (installation-specific data will still be persisted
|
||||
/// in root_cache_path). HTML5 databases such as localStorage will only
|
||||
/// persist across sessions if a cache path is specified. Can be overridden
|
||||
/// for individual CefRequestContext instances via the
|
||||
/// CefRequestContextSettings.cache_path value. When using the Chrome runtime
|
||||
/// any child directory value will be ignored and the "default" profile (also
|
||||
/// a child directory) will be used instead.
|
||||
///
|
||||
cef_string_t cache_path;
|
||||
|
||||
///
|
||||
/// The root directory that all CefSettings.cache_path and
|
||||
/// CefRequestContextSettings.cache_path values must have in common. If this
|
||||
/// value is empty and CefSettings.cache_path is non-empty then it will
|
||||
/// default to the CefSettings.cache_path value. If both values are empty
|
||||
/// then the default platform-specific directory will be used
|
||||
/// The root directory for installation-specific data and the parent directory
|
||||
/// for profile-specific data. All CefSettings.cache_path and
|
||||
/// CefRequestContextSettings.cache_path values must have this parent
|
||||
/// directory in common. If this value is empty and CefSettings.cache_path is
|
||||
/// non-empty then it will default to the CefSettings.cache_path value. Any
|
||||
/// non-empty value must be an absolute path. If both values are empty then
|
||||
/// the default platform-specific directory will be used
|
||||
/// ("~/.config/cef_user_data" directory on Linux, "~/Library/Application
|
||||
/// Support/CEF/User Data" directory on MacOS, "AppData\Local\CEF\User Data"
|
||||
/// directory under the user profile directory on Windows). If this value is
|
||||
/// non-empty then it must be an absolute path. Failure to set this value
|
||||
/// correctly may result in the sandbox blocking read/write access to certain
|
||||
/// files.
|
||||
/// directory under the user profile directory on Windows). Use of the default
|
||||
/// directory is not recommended in production applications (see below).
|
||||
///
|
||||
/// Multiple application instances writing to the same root_cache_path
|
||||
/// directory could result in data corruption. A process singleton lock based
|
||||
/// on the root_cache_path value is therefore used to protect against this.
|
||||
/// This singleton behavior applies to all CEF-based applications using
|
||||
/// version 120 or newer. You should customize root_cache_path for your
|
||||
/// application and implement CefBrowserProcessHandler::
|
||||
/// OnAlreadyRunningAppRelaunch, which will then be called on any app relaunch
|
||||
/// with the same root_cache_path value.
|
||||
///
|
||||
/// Failure to set the root_cache_path value correctly may result in startup
|
||||
/// crashes or other unexpected behaviors (for example, the sandbox blocking
|
||||
/// read/write access to certain files).
|
||||
///
|
||||
cef_string_t root_cache_path;
|
||||
|
||||
@ -506,14 +521,15 @@ typedef struct _cef_request_context_settings_t {
|
||||
size_t size;
|
||||
|
||||
///
|
||||
/// The location where cache data for this request context will be stored on
|
||||
/// The directory where cache data for this request context will be stored on
|
||||
/// disk. If this value is non-empty then it must be an absolute path that is
|
||||
/// either equal to or a child directory of CefSettings.root_cache_path. If
|
||||
/// this value is empty then browsers will be created in "incognito mode"
|
||||
/// where in-memory caches are used for storage and no data is persisted to
|
||||
/// disk. HTML5 databases such as localStorage will only persist across
|
||||
/// sessions if a cache path is specified. To share the global browser cache
|
||||
/// and related configuration set this value to match the
|
||||
/// where in-memory caches are used for storage and no profile-specific data
|
||||
/// is persisted to disk (installation-specific data will still be persisted
|
||||
/// in root_cache_path). HTML5 databases such as localStorage will only
|
||||
/// persist across sessions if a cache path is specified. To share the global
|
||||
/// browser cache and related configuration set this value to match the
|
||||
/// CefSettings.cache_path value.
|
||||
///
|
||||
cef_string_t cache_path;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "libcef/browser/permission_prompt.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/app_manager.h"
|
||||
#include "libcef/common/command_line_impl.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/net/net_resource_provider.h"
|
||||
|
||||
@ -27,6 +28,7 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/chrome_process_singleton.h"
|
||||
#include "chrome/browser/media/router/chrome_media_router_factory.h"
|
||||
#include "chrome/browser/net/system_network_context_manager.h"
|
||||
#include "chrome/browser/ui/color/chrome_color_mixers.h"
|
||||
@ -141,6 +143,56 @@ ui::LinuxUi* GetLinuxUI() {
|
||||
|
||||
#endif // BUILDFLAG(IS_LINUX)
|
||||
|
||||
void ProcessSingletonNotificationCallbackImpl(
|
||||
const base::CommandLine& command_line,
|
||||
const base::FilePath& current_directory) {
|
||||
// Drop the request if the browser process is already shutting down.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (auto app = CefAppManager::Get()->GetApplication()) {
|
||||
if (auto handler = app->GetBrowserProcessHandler()) {
|
||||
CefRefPtr<CefCommandLineImpl> commandLinePtr(
|
||||
new CefCommandLineImpl(command_line));
|
||||
handled = handler->OnAlreadyRunningAppRelaunch(commandLinePtr.get(),
|
||||
current_directory.value());
|
||||
std::ignore = commandLinePtr->Detach(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
LOG(WARNING) << "Unhandled app relaunch; implement "
|
||||
"CefBrowserProcessHandler::OnAlreadyRunningAppRelaunch.";
|
||||
}
|
||||
}
|
||||
|
||||
// Based on ChromeBrowserMainParts::ProcessSingletonNotificationCallback.
|
||||
bool ProcessSingletonNotificationCallback(
|
||||
const base::CommandLine& command_line,
|
||||
const base::FilePath& current_directory) {
|
||||
// Drop the request if the browser process is already shutting down.
|
||||
// Note that we're going to post an async task below. Even if the browser
|
||||
// process isn't shutting down right now, it could be by the time the task
|
||||
// starts running. So, an additional check needs to happen when it starts.
|
||||
// But regardless of any future check, there is no reason to post the task
|
||||
// now if we know we're already shutting down.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In order to handle this request on Windows, there is platform specific
|
||||
// code in browser_finder.cc that requires making outbound COM calls to
|
||||
// cross-apartment shell objects (via IVirtualDesktopManager). That is not
|
||||
// allowed within a SendMessage handler, which this function is a part of.
|
||||
// So, we post a task to asynchronously finish the command line processing.
|
||||
return base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ProcessSingletonNotificationCallbackImpl,
|
||||
command_line, current_directory));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AlloyBrowserMainParts::AlloyBrowserMainParts() = default;
|
||||
@ -262,6 +314,10 @@ int AlloyBrowserMainParts::PreCreateThreads() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AlloyBrowserMainParts::PostCreateThreads() {
|
||||
ChromeProcessSingleton::GetInstance()->StartWatching();
|
||||
}
|
||||
|
||||
int AlloyBrowserMainParts::PreMainMessageLoopRun() {
|
||||
#if defined(USE_AURA)
|
||||
screen_ = views::CreateDesktopScreen();
|
||||
@ -339,6 +395,12 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allow ProcessSingleton to process messages.
|
||||
// This is done here instead of just relying on the main message loop's start
|
||||
// to avoid rendezvous in RunLoops that may precede MainMessageLoopRun.
|
||||
ChromeProcessSingleton::GetInstance()->Unlock(
|
||||
base::BindRepeating(&ProcessSingletonNotificationCallback));
|
||||
|
||||
return content::RESULT_CODE_NORMAL_EXIT;
|
||||
}
|
||||
|
||||
@ -346,6 +408,8 @@ void AlloyBrowserMainParts::PostMainMessageLoopRun() {
|
||||
// NOTE: Destroy objects in reverse order of creation.
|
||||
CefDevToolsManagerDelegate::StopHttpHandler();
|
||||
|
||||
ChromeProcessSingleton::GetInstance()->Cleanup();
|
||||
|
||||
// There should be no additional references to the global CefRequestContext
|
||||
// during shutdown. Did you forget to release a CefBrowser reference?
|
||||
DCHECK(global_request_context_->HasOneRef());
|
||||
|
@ -49,6 +49,7 @@ class AlloyBrowserMainParts : public content::BrowserMainParts {
|
||||
void PreCreateMainMessageLoop() override;
|
||||
void PostCreateMainMessageLoop() override;
|
||||
int PreCreateThreads() override;
|
||||
void PostCreateThreads() override;
|
||||
int PreMainMessageLoopRun() override;
|
||||
void PostMainMessageLoopRun() override;
|
||||
void PostDestroyThreads() override;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "chrome/browser/ui/webui/chrome_untrusted_web_ui_configs.h"
|
||||
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
|
||||
#include "chrome/browser/ui/webui/theme_source.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/url_constants.h"
|
||||
#include "content/browser/renderer_host/debug_urls.h"
|
||||
#include "content/public/browser/browser_url_handler.h"
|
||||
@ -385,6 +386,9 @@ bool OnVersionUI(Profile* profile,
|
||||
return false;
|
||||
}
|
||||
|
||||
base::FilePath user_data_dir =
|
||||
base::PathService::CheckedGet(chrome::DIR_USER_DATA);
|
||||
|
||||
TemplateParser parser;
|
||||
parser.Add("YEAR", MAKE_STRING(COPYRIGHT_YEAR));
|
||||
parser.Add("CEF", CEF_VERSION);
|
||||
@ -400,6 +404,7 @@ bool OnVersionUI(Profile* profile,
|
||||
CefAppManager::Get()->GetContentClient()->browser()->GetUserAgent());
|
||||
parser.Add("COMMANDLINE", GetCommandLine());
|
||||
parser.Add("MODULEPATH", GetModulePath());
|
||||
parser.Add("ROOTCACHEPATH", CefString(user_data_dir.value()));
|
||||
parser.Add("CACHEPATH", CefString(profile->GetPath().value()));
|
||||
|
||||
parser.Parse(&tmpl);
|
||||
|
@ -24,16 +24,22 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/chrome_process_singleton.h"
|
||||
#include "chrome/child/pdf_child_init.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/chrome_result_codes.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/grit/generated_resources.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/embedder_support/switches.h"
|
||||
#include "components/metrics/persistent_histograms.h"
|
||||
#include "components/viz/common/features.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
@ -45,7 +51,9 @@
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
#include "third_party/blink/public/common/switches.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_features.h"
|
||||
#include "ui/base/ui_base_paths.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
@ -69,6 +77,46 @@ const char* const kNonWildcardDomainNonPortSchemes[] = {
|
||||
const size_t kNonWildcardDomainNonPortSchemesSize =
|
||||
std::size(kNonWildcardDomainNonPortSchemes);
|
||||
|
||||
absl::optional<int> AcquireProcessSingleton(
|
||||
const base::FilePath& user_data_dir) {
|
||||
// Take the Chrome process singleton lock. The process can become the
|
||||
// Browser process if it succeed to take the lock. Otherwise, the
|
||||
// command-line is sent to the actual Browser process and the current
|
||||
// process can be exited.
|
||||
ChromeProcessSingleton::CreateInstance(user_data_dir);
|
||||
|
||||
ProcessSingleton::NotifyResult notify_result =
|
||||
ChromeProcessSingleton::GetInstance()->NotifyOtherProcessOrCreate();
|
||||
switch (notify_result) {
|
||||
case ProcessSingleton::PROCESS_NONE:
|
||||
break;
|
||||
|
||||
case ProcessSingleton::PROCESS_NOTIFIED: {
|
||||
// Ensure there is an instance of ResourceBundle that is initialized for
|
||||
// localized string resource accesses.
|
||||
ui::ScopedStartupResourceBundle startup_resource_bundle;
|
||||
printf("%s\n", base::SysWideToNativeMB(
|
||||
base::UTF16ToWide(l10n_util::GetStringUTF16(
|
||||
IDS_USED_EXISTING_BROWSER)))
|
||||
.c_str());
|
||||
return chrome::RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED;
|
||||
}
|
||||
|
||||
case ProcessSingleton::PROFILE_IN_USE:
|
||||
return chrome::RESULT_CODE_PROFILE_IN_USE;
|
||||
|
||||
case ProcessSingleton::LOCK_ERROR:
|
||||
LOG(ERROR) << "Failed to create a ProcessSingleton for your profile "
|
||||
"directory. This means that running multiple instances "
|
||||
"would start multiple browser processes rather than "
|
||||
"opening a new window in the existing process. Aborting "
|
||||
"now to avoid profile corruption.";
|
||||
return chrome::RESULT_CODE_PROFILE_IN_USE;
|
||||
}
|
||||
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AlloyMainDelegate::AlloyMainDelegate(CefMainRunnerHandler* runner,
|
||||
@ -87,6 +135,35 @@ absl::optional<int> AlloyMainDelegate::PreBrowserMain() {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<int> AlloyMainDelegate::PostEarlyInitialization(
|
||||
InvokedIn invoked_in) {
|
||||
const auto* invoked_in_browser =
|
||||
absl::get_if<InvokedInBrowserProcess>(&invoked_in);
|
||||
if (!invoked_in_browser) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
// Based on ChromeMainDelegate::PostEarlyInitialization.
|
||||
// The User Data dir is guaranteed to be valid as per PreSandboxStartup.
|
||||
base::FilePath user_data_dir =
|
||||
base::PathService::CheckedGet(chrome::DIR_USER_DATA);
|
||||
|
||||
// On platforms that support the process rendezvous, acquire the process
|
||||
// singleton. In case of failure, it means there is already a running browser
|
||||
// instance that handled the command-line.
|
||||
if (auto process_singleton_result = AcquireProcessSingleton(user_data_dir);
|
||||
process_singleton_result.has_value()) {
|
||||
// To ensure that the histograms emitted in this process are reported in
|
||||
// case of early exit, report the metrics accumulated this session with a
|
||||
// future session's metrics.
|
||||
DeferBrowserMetrics(user_data_dir);
|
||||
|
||||
return process_singleton_result;
|
||||
}
|
||||
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<int> AlloyMainDelegate::BasicStartupComplete() {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
|
@ -47,6 +47,7 @@ class AlloyMainDelegate : public content::ContentMainDelegate,
|
||||
|
||||
// content::ContentMainDelegate overrides.
|
||||
absl::optional<int> PreBrowserMain() override;
|
||||
absl::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
|
||||
absl::optional<int> BasicStartupComplete() override;
|
||||
void PreSandboxStartup() override;
|
||||
absl::variant<int, content::MainFunctionParams> RunProcess(
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/notreached.h"
|
||||
#include "base/path_service.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
@ -89,6 +90,10 @@ base::FilePath GetUserDataPath(CefSettings* settings,
|
||||
}
|
||||
if (!root_cache_path.empty()) {
|
||||
return base::FilePath(root_cache_path);
|
||||
} else {
|
||||
LOG(WARNING) << "Please customize CefSettings.root_cache_path for your "
|
||||
"application. Use of the default value may lead to "
|
||||
"unintended process singleton behavior.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,10 @@ body {
|
||||
content: ':';
|
||||
}
|
||||
|
||||
.footnote {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#logo {
|
||||
float: right;
|
||||
margin-left: 40px;
|
||||
@ -109,9 +113,26 @@ body {
|
||||
<td class="value">$$MODULEPATH$$</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" valign="top">Cache Path</td>
|
||||
<td class="label" valign="top">Root Cache Path <sup>[1][2]</sup></td>
|
||||
<td class="value">$$ROOTCACHEPATH$$</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" valign="top">Cache Path <sup>[1]</sup></td>
|
||||
<td class="value">$$CACHEPATH$$</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="footnote">
|
||||
<br>[1] In <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md" target="_new">Chromium terminology</a>,
|
||||
"Root Cache Path" (<a href="https://cef-builds.spotifycdn.com/docs/beta.html?structcef__settings__t.html#a2e2be03f34ddd93de90e1cf196757a19" target="_new">CefSettings.root_cache_path</a>)
|
||||
is the "User Data Directory" and "Cache Path" (<a href="https://cef-builds.spotifycdn.com/docs/beta.html?structcef__settings__t.html#ad1644a7eb23cad969181db010f007710" target="_new">CefSettings.cache_path</a>)
|
||||
is the "Profile Path". An empty "Cache Path" value means that the browser is using an <a href="https://support.google.com/chrome/answer/9845881" target="_new">Incognito Profile</a>.
|
||||
Even in Incognito mode, some per-installation data will still be written to the "Root Cache Path" directory.
|
||||
<br/><br/>[2] Chromium's <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/process_singleton.h#35" target="_new">process singleton lock</a>
|
||||
protects against multiple app instances writing to the same "Root Cache Path" directory.
|
||||
Implement <a href="https://cef-builds.spotifycdn.com/docs/beta.html?classCefBrowserProcessHandler.html#a052a91639483467c0b546d57a05c2f06" target="_new">CefBrowserProcessHandler:: OnAlreadyRunningAppRelaunch</a>
|
||||
to handle the case of app relaunch with the same directory.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -68,6 +68,21 @@ class ClientBrowserDelegate : public ClientAppBrowser::Delegate {
|
||||
CefRefPtr<ClientAppBrowser> app,
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) override {
|
||||
// Add logging for some common switches that the user may attempt to use.
|
||||
static const char* kIgnoredSwitches[] = {
|
||||
switches::kEnableChromeRuntime,
|
||||
switches::kMultiThreadedMessageLoop,
|
||||
switches::kOffScreenRenderingEnabled,
|
||||
switches::kUseViews,
|
||||
};
|
||||
for (size_t i = 0;
|
||||
i < sizeof(kIgnoredSwitches) / sizeof(kIgnoredSwitches[0]); ++i) {
|
||||
if (command_line->HasSwitch(kIgnoredSwitches[i])) {
|
||||
LOG(WARNING) << "The --" << kIgnoredSwitches[i]
|
||||
<< " command-line switch is ignored on app relaunch.";
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new root window based on |command_line|.
|
||||
auto config = std::make_unique<RootWindowConfig>(command_line->Copy());
|
||||
|
||||
|
@ -36,9 +36,9 @@ enum class WindowType {
|
||||
|
||||
// Used to configure how a RootWindow is created.
|
||||
struct RootWindowConfig {
|
||||
// |command_line| will be non-nullptr when used for new window creation
|
||||
// via OnAlreadyRunningAppRelaunch (chrome runtime only). Otherwise, the
|
||||
// global command-line will be used.
|
||||
// |command_line| will be non-nullptr when used for new window creation via
|
||||
// OnAlreadyRunningAppRelaunch. Otherwise, the global command-line will be
|
||||
// used.
|
||||
RootWindowConfig(CefRefPtr<CefCommandLine> command_line = nullptr);
|
||||
|
||||
// Associated command-line.
|
||||
|
Reference in New Issue
Block a user