mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
chrome: Support client-created request contexts (see issue #2969)
RequestContextTest and URLRequestTest suites now pass with the Chrome runtime enabled.
This commit is contained in:
@@ -12,11 +12,13 @@
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/features/runtime.h"
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -229,6 +231,25 @@ CefBrowserContext* CefBrowserContext::FromBrowserContext(
|
||||
return g_manager.Get().GetImplFromBrowserContext(context);
|
||||
}
|
||||
|
||||
// static
|
||||
CefBrowserContext* CefBrowserContext::FromProfile(const Profile* profile) {
|
||||
auto* cef_context = FromBrowserContext(profile);
|
||||
if (cef_context)
|
||||
return cef_context;
|
||||
|
||||
if (cef::IsChromeRuntimeEnabled()) {
|
||||
auto* original_profile = profile->GetOriginalProfile();
|
||||
if (original_profile != profile) {
|
||||
// With the Chrome runtime if the user launches an incognito window via
|
||||
// the UI we might be associated with the original Profile instead of the
|
||||
// (current) incognito profile.
|
||||
return FromBrowserContext(original_profile);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<CefBrowserContext*> CefBrowserContext::GetAll() {
|
||||
return g_manager.Get().GetAllImpl();
|
||||
|
@@ -103,6 +103,7 @@ class CefBrowserContext {
|
||||
// Returns the underlying CefBrowserContext if any.
|
||||
static CefBrowserContext* FromBrowserContext(
|
||||
const content::BrowserContext* context);
|
||||
static CefBrowserContext* FromProfile(const Profile* profile);
|
||||
|
||||
// Returns all existing CefBrowserContext.
|
||||
static std::vector<CefBrowserContext*> GetAll();
|
||||
|
@@ -6,11 +6,11 @@
|
||||
|
||||
#include "libcef/browser/prefs/browser_prefs.h"
|
||||
|
||||
#include "chrome/browser/profiles/profile_manager.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
|
||||
ChromeBrowserContext::ChromeBrowserContext(
|
||||
const CefRequestContextSettings& settings)
|
||||
: CefBrowserContext(settings) {}
|
||||
: CefBrowserContext(settings), weak_ptr_factory_(this) {}
|
||||
|
||||
ChromeBrowserContext::~ChromeBrowserContext() = default;
|
||||
|
||||
@@ -22,19 +22,73 @@ Profile* ChromeBrowserContext::AsProfile() {
|
||||
return profile_;
|
||||
}
|
||||
|
||||
void ChromeBrowserContext::Initialize() {
|
||||
void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) {
|
||||
initialized_cb_ = std::move(initialized_cb);
|
||||
|
||||
CefBrowserContext::Initialize();
|
||||
|
||||
// TODO(chrome-runtime): ProfileManager can create new profiles relative to
|
||||
// the user-data-dir, but it should be done asynchronously.
|
||||
// The global ProfileManager instance can be retrieved via
|
||||
// |g_browser_process->profile_manager()|.
|
||||
profile_ = ProfileManager::GetLastUsedProfileAllowedByPolicy();
|
||||
if (!cache_path_.empty()) {
|
||||
auto* profile_manager = g_browser_process->profile_manager();
|
||||
const auto& user_data_dir = profile_manager->user_data_dir();
|
||||
|
||||
browser_prefs::SetLanguagePrefs(profile_);
|
||||
if (cache_path_ == user_data_dir) {
|
||||
// Use the default disk-based profile.
|
||||
ProfileCreated(profile_manager->GetActiveUserProfile(),
|
||||
Profile::CreateStatus::CREATE_STATUS_INITIALIZED);
|
||||
return;
|
||||
} else if (cache_path_.DirName() == user_data_dir) {
|
||||
// Create or load a specific disk-based profile. May continue
|
||||
// synchronously or asynchronously.
|
||||
profile_manager->CreateProfileAsync(
|
||||
cache_path_,
|
||||
base::Bind(&ChromeBrowserContext::ProfileCreated,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
/*name=*/base::string16(), /*icon_url=*/std::string());
|
||||
return;
|
||||
} else {
|
||||
// All profile directories must be relative to |user_data_dir|.
|
||||
LOG(ERROR) << "Cannot create profile at path "
|
||||
<< cache_path_.AsUTF8Unsafe();
|
||||
}
|
||||
}
|
||||
|
||||
// Default to creating a new/unique OffTheRecord profile.
|
||||
ProfileCreated(nullptr, Profile::CreateStatus::CREATE_STATUS_CANCELED);
|
||||
}
|
||||
|
||||
void ChromeBrowserContext::Shutdown() {
|
||||
CefBrowserContext::Shutdown();
|
||||
// |g_browser_process| may be nullptr during shutdown.
|
||||
if (should_destroy_ && g_browser_process) {
|
||||
g_browser_process->profile_manager()
|
||||
->GetActiveUserProfile()
|
||||
->DestroyOffTheRecordProfile(profile_);
|
||||
}
|
||||
profile_ = nullptr;
|
||||
}
|
||||
|
||||
void ChromeBrowserContext::ProfileCreated(Profile* profile,
|
||||
Profile::CreateStatus status) {
|
||||
if (status != Profile::CreateStatus::CREATE_STATUS_CREATED &&
|
||||
status != Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
||||
DCHECK(!profile);
|
||||
|
||||
// Creation of a disk-based profile failed for some reason. Create a
|
||||
// new/unique OffTheRecord profile instead.
|
||||
const auto& profile_id = Profile::OTRProfileID::CreateUniqueForCEF();
|
||||
profile = g_browser_process->profile_manager()
|
||||
->GetActiveUserProfile()
|
||||
->GetOffTheRecordProfile(profile_id);
|
||||
status = Profile::CreateStatus::CREATE_STATUS_INITIALIZED;
|
||||
should_destroy_ = true;
|
||||
}
|
||||
|
||||
if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
||||
DCHECK(profile);
|
||||
DCHECK(!profile_);
|
||||
profile_ = profile;
|
||||
browser_prefs::SetLanguagePrefs(profile_);
|
||||
|
||||
std::move(initialized_cb_).Run();
|
||||
}
|
||||
}
|
||||
|
@@ -8,22 +8,32 @@
|
||||
|
||||
#include "libcef/browser/browser_context.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "chrome/browser/profiles/profile_manager.h"
|
||||
|
||||
// See CefBrowserContext documentation for usage. Only accessed on the UI thread
|
||||
// unless otherwise indicated.
|
||||
class ChromeBrowserContext : public CefBrowserContext {
|
||||
public:
|
||||
explicit ChromeBrowserContext(const CefRequestContextSettings& settings);
|
||||
|
||||
void InitializeAsync(base::OnceClosure initialized_cb);
|
||||
|
||||
// CefBrowserContext overrides.
|
||||
content::BrowserContext* AsBrowserContext() override;
|
||||
Profile* AsProfile() override;
|
||||
void Initialize() override;
|
||||
void Shutdown() override;
|
||||
|
||||
private:
|
||||
~ChromeBrowserContext() override;
|
||||
|
||||
void ProfileCreated(Profile* profile, Profile::CreateStatus status);
|
||||
|
||||
base::OnceClosure initialized_cb_;
|
||||
Profile* profile_ = nullptr;
|
||||
bool should_destroy_ = false;
|
||||
|
||||
base::WeakPtrFactory<ChromeBrowserContext> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserContext);
|
||||
};
|
||||
|
@@ -175,7 +175,7 @@ bool ChromeContentBrowserClientCef::WillCreateURLLoaderFactory(
|
||||
// For example, the User Manager profile created via
|
||||
// profiles::CreateSystemProfileForUserManager.
|
||||
auto profile = Profile::FromBrowserContext(browser_context);
|
||||
if (!CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile()))
|
||||
if (!CefBrowserContext::FromProfile(profile))
|
||||
return false;
|
||||
|
||||
auto request_handler = net_service::CreateInterceptedRequestHandler(
|
||||
|
@@ -262,8 +262,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
browser_context_ = browser_context;
|
||||
|
||||
auto profile = Profile::FromBrowserContext(browser_context);
|
||||
auto cef_browser_context =
|
||||
CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile());
|
||||
auto cef_browser_context = CefBrowserContext::FromProfile(profile);
|
||||
iothread_state_ = cef_browser_context->iothread_state();
|
||||
DCHECK(iothread_state_);
|
||||
cookieable_schemes_ = cef_browser_context->GetCookieableSchemes();
|
||||
|
@@ -612,7 +612,19 @@ CefRequestContextImpl::GetOrCreateRequestContext(const Config& config) {
|
||||
}
|
||||
|
||||
// The new context will be initialized later by EnsureBrowserContext().
|
||||
return new CefRequestContextImpl(config);
|
||||
CefRefPtr<CefRequestContextImpl> context = new CefRequestContextImpl(config);
|
||||
|
||||
if (config.handler) {
|
||||
// Keep the context alive until OnRequestContextInitialized is called.
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
context->Initialize();
|
||||
} else {
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT, base::BindOnce(&CefRequestContextImpl::Initialize, context));
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
CefRequestContextImpl::CefRequestContextImpl(
|
||||
@@ -645,16 +657,20 @@ void CefRequestContextImpl::Initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
auto initialized_cb =
|
||||
base::BindOnce(&CefRequestContextImpl::BrowserContextInitialized, this);
|
||||
|
||||
if (!browser_context_) {
|
||||
// Create a new CefBrowserContext instance. If the cache path is non-
|
||||
// empty then this new instance will become the globally registered
|
||||
// CefBrowserContext for that path. Otherwise, this new instance will
|
||||
// be a completely isolated "incognito mode" context.
|
||||
browser_context_ =
|
||||
CefAppManager::Get()->CreateNewBrowserContext(config_.settings);
|
||||
browser_context_ = CefAppManager::Get()->CreateNewBrowserContext(
|
||||
config_.settings, std::move(initialized_cb));
|
||||
} else {
|
||||
// Share the same settings as the existing context.
|
||||
config_.settings = browser_context_->settings();
|
||||
std::move(initialized_cb).Run();
|
||||
}
|
||||
|
||||
// We'll disassociate from |browser_context_| on destruction.
|
||||
@@ -666,9 +682,16 @@ void CefRequestContextImpl::Initialize() {
|
||||
// IsSharedWith().
|
||||
config_.other = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (config_.handler)
|
||||
config_.handler->OnRequestContextInitialized(this);
|
||||
void CefRequestContextImpl::BrowserContextInitialized() {
|
||||
if (config_.handler) {
|
||||
// Always execute asynchronously so the current call stack can unwind.
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT,
|
||||
base::BindOnce(&CefRequestContextHandler::OnRequestContextInitialized,
|
||||
config_.handler, CefRefPtr<CefRequestContext>(this)));
|
||||
}
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::EnsureBrowserContext() {
|
||||
|
@@ -128,6 +128,7 @@ class CefRequestContextImpl : public CefRequestContext {
|
||||
explicit CefRequestContextImpl(const Config& config);
|
||||
|
||||
void Initialize();
|
||||
void BrowserContextInitialized();
|
||||
|
||||
// Make sure the browser context exists. Only called on the UI thread.
|
||||
void EnsureBrowserContext();
|
||||
|
@@ -443,9 +443,11 @@ CefRefPtr<CefRequestContext> AlloyMainDelegate::GetGlobalRequestContext() {
|
||||
}
|
||||
|
||||
CefBrowserContext* AlloyMainDelegate::CreateNewBrowserContext(
|
||||
const CefRequestContextSettings& settings) {
|
||||
const CefRequestContextSettings& settings,
|
||||
base::OnceClosure initialized_cb) {
|
||||
auto context = new AlloyBrowserContext(settings);
|
||||
context->Initialize();
|
||||
std::move(initialized_cb).Run();
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@@ -62,7 +62,8 @@ class AlloyMainDelegate : public content::ContentMainDelegate,
|
||||
}
|
||||
CefRefPtr<CefRequestContext> GetGlobalRequestContext() override;
|
||||
CefBrowserContext* CreateNewBrowserContext(
|
||||
const CefRequestContextSettings& settings) override;
|
||||
const CefRequestContextSettings& settings,
|
||||
base::OnceClosure initialized_cb) override;
|
||||
|
||||
// CefTaskRunnerManager overrides.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_request_context.h"
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/macros.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
@@ -44,10 +45,12 @@ class CefAppManager {
|
||||
|
||||
// The following methods are only available in the main (browser) process.
|
||||
|
||||
// Called from CefRequestContextImpl.
|
||||
// Called from CefRequestContextImpl. |initialized_cb| may be executed
|
||||
// synchronously or asynchronously.
|
||||
virtual CefRefPtr<CefRequestContext> GetGlobalRequestContext() = 0;
|
||||
virtual CefBrowserContext* CreateNewBrowserContext(
|
||||
const CefRequestContextSettings& settings) = 0;
|
||||
const CefRequestContextSettings& settings,
|
||||
base::OnceClosure initialized_cb) = 0;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Returns the module name (usually libcef.dll).
|
||||
|
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "sandbox/policy/switches.h"
|
||||
|
||||
@@ -194,9 +195,10 @@ CefRefPtr<CefRequestContext> ChromeMainDelegateCef::GetGlobalRequestContext() {
|
||||
}
|
||||
|
||||
CefBrowserContext* ChromeMainDelegateCef::CreateNewBrowserContext(
|
||||
const CefRequestContextSettings& settings) {
|
||||
const CefRequestContextSettings& settings,
|
||||
base::OnceClosure initialized_cb) {
|
||||
auto context = new ChromeBrowserContext(settings);
|
||||
context->Initialize();
|
||||
context->InitializeAsync(std::move(initialized_cb));
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@@ -54,7 +54,8 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
|
||||
}
|
||||
CefRefPtr<CefRequestContext> GetGlobalRequestContext() override;
|
||||
CefBrowserContext* CreateNewBrowserContext(
|
||||
const CefRequestContextSettings& settings) override;
|
||||
const CefRequestContextSettings& settings,
|
||||
base::OnceClosure initialized_cb) override;
|
||||
|
||||
// CefTaskRunnerManager overrides.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "libcef/features/runtime.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
@@ -80,8 +82,21 @@ bool GetDefaultUserDataDirectory(base::FilePath* result) {
|
||||
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));
|
||||
if (settings) {
|
||||
// With the Chrome runtime Profile paths must always be relative to the
|
||||
// user data directory, so defaulting to |root_cache_path| first is
|
||||
// appropriate.
|
||||
CefString user_data_path;
|
||||
if (cef::IsChromeRuntimeEnabled() && settings->root_cache_path.length > 0) {
|
||||
user_data_path = CefString(&settings->root_cache_path);
|
||||
}
|
||||
if (user_data_path.empty() && settings->user_data_path.length > 0) {
|
||||
user_data_path = CefString(&settings->user_data_path);
|
||||
}
|
||||
if (!user_data_path.empty()) {
|
||||
return base::FilePath(user_data_path);
|
||||
}
|
||||
}
|
||||
|
||||
// This may be set for sub-processes.
|
||||
base::FilePath result =
|
||||
|
Reference in New Issue
Block a user