Simplify ownership of CefBrowserContext objects (issue #2083)

This commit is contained in:
Marshall Greenblatt 2017-02-14 17:27:19 -05:00
parent 43001c0a94
commit 897c0f01ed
21 changed files with 351 additions and 307 deletions

View File

@ -15,25 +15,14 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#if DCHECK_IS_ON()
base::AtomicRefCount CefBrowserContext::DebugObjCt = 0;
#endif
CefBrowserContext::CefBrowserContext(bool is_proxy)
: is_proxy_(is_proxy),
extension_system_(NULL) {
#if DCHECK_IS_ON()
base::AtomicRefCountInc(&DebugObjCt);
#endif
}
CefBrowserContext::~CefBrowserContext() {
// Should be cleared in Shutdown().
DCHECK(!resource_context_.get());
#if DCHECK_IS_ON()
base::AtomicRefCountDec(&DebugObjCt);
#endif
}
void CefBrowserContext::Initialize() {
@ -129,28 +118,27 @@ void CefBrowserContext::OnRenderFrameDeleted(int render_process_id,
int render_frame_id,
bool is_main_frame,
bool is_guest_view) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefBrowserContext::RenderFrameDeletedOnIOThread, this,
render_process_id, render_frame_id, is_main_frame,
is_guest_view));
}
void CefBrowserContext::OnPurgePluginListCache() {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefBrowserContext::PurgePluginListCacheOnIOThread, this));
}
void CefBrowserContext::RenderFrameDeletedOnIOThread(int render_process_id,
int render_frame_id,
bool is_main_frame,
bool is_guest_view) {
CEF_REQUIRE_UIT();
if (resource_context_ && is_main_frame) {
DCHECK_GE(render_process_id, 0);
resource_context_->ClearPluginLoadDecision(render_process_id);
// Using base::Unretained() is safe because both this callback and possible
// deletion of |resource_context_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceContext::ClearPluginLoadDecision,
base::Unretained(resource_context_.get()),
render_process_id));
}
}
void CefBrowserContext::PurgePluginListCacheOnIOThread() {
if (resource_context_)
resource_context_->ClearPluginLoadDecision(-1);
void CefBrowserContext::OnPurgePluginListCache() {
CEF_REQUIRE_UIT();
if (resource_context_) {
// Using base::Unretained() is safe because both this callback and possible
// deletion of |resource_context_| will execute on the IO thread, and this
// callback will be executed first.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceContext::ClearPluginLoadDecision,
base::Unretained(resource_context_.get()), -1));
}
}

View File

@ -33,12 +33,12 @@
//
// BCI = CefBrowserContextImpl
// Entry point from WC when using an isolated RCI. Owns the RC and creates the
// SPI indirectly. Life span controlled by RCI and (for the global context)
// CefBrowserMainParts.
// SPI indirectly. Owned by CefBrowserMainParts for the global context or RCI
// for non-global contexts.
//
// BCP = CefBrowserContextProxy
// Entry point from WC when using a custom RCI. Owns the RC and creates the
// URCGP and SPP. Life span controlled by RCI.
// URCGP and SPP. Owned by RCI.
//
// SPI = content::StoragePartitionImpl
// Owns storage-related objects like Quota, IndexedDB, Cache, etc. Created by
@ -83,29 +83,29 @@
//
// Relationship diagram:
// ref = reference (CefRefPtr/scoped_refptr)
// own = ownership (scoped_ptr)
// own = ownership (std::unique_ptr)
// ptr = raw pointer
//
// CefBrowserMainParts----\ isolated cookie manager, etc.
// | \ ^
// ref ref ref/own
// own ref ref/own
// v v |
// /---> BCI -own-> SPI -ref-> URCGI --own-> URCI <-ptr-- CSP
// / ^ ^ ^ ^
// ptr ref ptr ref /
// ptr ptr ptr ref /
// / | | | /
// BHI -own-> WC -ptr-> BCP -own-> SPP -ref-> URCGP -own-> URCP --ref-/
//
// BHI -ref-> RCI -ref-> BCI/BCP -own-> RC -ref-> URCGI/URCGP
// BHI -ref-> RCI -own-> BCI/BCP -own-> RC -ref-> URCGI/URCGP
//
//
// How shutdown works:
// 1. CefBrowserHostImpl is destroyed on any thread due to browser close,
// ref release, etc.
// 2. CefRequestContextImpl is destroyed on any thread due to
// CefBrowserHostImpl destruction, ref release, etc.
// 2. CefRequestContextImpl is destroyed (possibly asynchronously) on the UI
// thread due to CefBrowserHostImpl destruction, ref release, etc.
// 3. CefBrowserContext* is destroyed on the UI thread due to
// CefRequestContextImpl destruction (*Impl, *Proxy) or ref release in
// CefRequestContextImpl destruction (*Impl, *Proxy) or deletion in
// CefBrowserMainParts::PostMainMessageLoopRun() (*Impl).
// 4. CefResourceContext is destroyed asynchronously on the IO thread due to
// CefBrowserContext* destruction. This cancels/destroys any pending
@ -128,10 +128,7 @@ class CefExtensionSystem;
// Main entry point for configuring behavior on a per-browser basis. An instance
// of this class is passed to WebContents::Create in CefBrowserHostImpl::
// CreateInternal. Only accessed on the UI thread unless otherwise indicated.
class CefBrowserContext
: public ChromeProfileStub,
public base::RefCountedThreadSafe<
CefBrowserContext, content::BrowserThread::DeleteOnUIThread> {
class CefBrowserContext : public ChromeProfileStub {
public:
explicit CefBrowserContext(bool is_proxy);
@ -183,10 +180,9 @@ class CefBrowserContext
return extension_system_;
}
#if DCHECK_IS_ON()
// Simple tracking of allocated objects.
static base::AtomicRefCount DebugObjCt; // NOLINT(runtime/int)
#endif
bool is_proxy() const {
return is_proxy_;
}
protected:
~CefBrowserContext() override;
@ -195,17 +191,6 @@ class CefBrowserContext
void Shutdown();
private:
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContext>;
void RenderFrameDeletedOnIOThread(int render_process_id,
int render_frame_id,
bool is_main_frame,
bool is_guest_view);
void PurgePluginListCacheOnIOThread();
// True if this CefBrowserContext is a CefBrowserContextProxy.
const bool is_proxy_;

View File

@ -8,6 +8,7 @@
#include <utility>
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/extensions/extension_system.h"
@ -85,9 +86,19 @@ class ImplManager {
const content::BrowserContext* context) {
CEF_REQUIRE_UIT();
const CefBrowserContext* cef_context =
static_cast<const CefBrowserContext*>(context);
const CefBrowserContextImpl* cef_context_impl = nullptr;
if (cef_context->is_proxy()) {
cef_context_impl =
static_cast<const CefBrowserContextProxy*>(cef_context)->parent();
} else {
cef_context_impl = static_cast<const CefBrowserContextImpl*>(cef_context);
}
Vector::iterator it = all_.begin();
for (; it != all_.end(); ++it) {
if (*it == context || (*it)->HasProxy(context))
if (*it == cef_context_impl)
return *it;
}
return NULL;
@ -139,6 +150,7 @@ base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER;
class CefVisitedLinkListener : public visitedlink::VisitedLinkMaster::Listener {
public:
CefVisitedLinkListener() {
DCHECK(listener_map_.empty());
}
void CreateListenerForContext(const CefBrowserContext* context) {
@ -196,11 +208,18 @@ CefBrowserContextImpl::CefBrowserContextImpl(
}
CefBrowserContextImpl::~CefBrowserContextImpl() {
CEF_REQUIRE_UIT();
// No CefRequestContextImpl should be referencing this object any longer.
DCHECK_EQ(request_context_count_, 0);
// Unregister the context first to avoid re-entrancy during shutdown.
g_manager.Get().RemoveImpl(this, cache_path_);
Shutdown();
visitedlink_listener_->RemoveListenerForContext(this);
// The FontFamilyCache references the ProxyService so delete it before the
// ProxyService is deleted.
SetUserData(&kFontFamilyCacheKey, NULL);
@ -281,48 +300,39 @@ void CefBrowserContextImpl::Initialize() {
void CefBrowserContextImpl::AddProxy(const CefBrowserContextProxy* proxy) {
CEF_REQUIRE_UIT();
DCHECK(!HasProxy(proxy));
proxy_list_.push_back(proxy);
visitedlink_listener_->CreateListenerForContext(proxy);
}
void CefBrowserContextImpl::RemoveProxy(const CefBrowserContextProxy* proxy) {
CEF_REQUIRE_UIT();
visitedlink_listener_->RemoveListenerForContext(proxy);
bool found = false;
ProxyList::iterator it = proxy_list_.begin();
for (; it != proxy_list_.end(); ++it) {
if (*it == proxy) {
proxy_list_.erase(it);
found = true;
break;
}
}
DCHECK(found);
}
bool CefBrowserContextImpl::HasProxy(
const content::BrowserContext* context) const {
void CefBrowserContextImpl::AddRequestContext() {
CEF_REQUIRE_UIT();
ProxyList::const_iterator it = proxy_list_.begin();
for (; it != proxy_list_.end(); ++it) {
if (*it == context)
return true;
request_context_count_++;
}
void CefBrowserContextImpl::RemoveRequestContext() {
CEF_REQUIRE_UIT();
request_context_count_--;
DCHECK_GE(request_context_count_, 0);
// Delete non-global contexts when the reference count reaches zero.
if (request_context_count_ == 0 &&
this != CefContentBrowserClient::Get()->browser_context()) {
delete this;
}
return false;
}
// static
scoped_refptr<CefBrowserContextImpl> CefBrowserContextImpl::GetForCachePath(
CefBrowserContextImpl* CefBrowserContextImpl::GetForCachePath(
const base::FilePath& cache_path) {
return g_manager.Get().GetImplForPath(cache_path);
}
// static
CefRefPtr<CefBrowserContextImpl> CefBrowserContextImpl::GetForContext(
CefBrowserContextImpl* CefBrowserContextImpl::GetForContext(
content::BrowserContext* context) {
return g_manager.Get().GetImplForContext(context);
}

View File

@ -25,9 +25,9 @@ class VisitedLinkMaster;
}
// Isolated BrowserContext implementation. Life span is controlled by
// CefRequestContextImpl and (for the main context) CefBrowserMainParts. Only
// accessed on the UI thread unless otherwise indicated. See browser_context.h
// for an object relationship diagram.
// CefBrowserMainParts for the global context and CefRequestContextImpl
// for non-global contexts. Only accessed on the UI thread unless otherwise
// indicated. See browser_context.h for an object relationship diagram.
class CefBrowserContextImpl : public CefBrowserContext,
public visitedlink::VisitedLinkDelegate {
public:
@ -35,11 +35,11 @@ class CefBrowserContextImpl : public CefBrowserContext,
// Returns the existing instance, if any, associated with the specified
// |cache_path|.
static scoped_refptr<CefBrowserContextImpl> GetForCachePath(
static CefBrowserContextImpl* GetForCachePath(
const base::FilePath& cache_path);
// Returns the underlying CefBrowserContextImpl if any.
static CefRefPtr<CefBrowserContextImpl> GetForContext(
static CefBrowserContextImpl* GetForContext(
content::BrowserContext* context);
// Returns all existing CefBrowserContextImpl.
@ -48,10 +48,14 @@ class CefBrowserContextImpl : public CefBrowserContext,
// Must be called immediately after this object is created.
void Initialize() override;
// Track associated proxy objects.
// Track associated CefBrowserContextProxy objects.
void AddProxy(const CefBrowserContextProxy* proxy);
void RemoveProxy(const CefBrowserContextProxy* proxy);
bool HasProxy(const content::BrowserContext* context) const;
// Track associated CefRequestContextImpl objects. If this object is a non-
// global context then it will delete itself when the count reaches zero.
void AddRequestContext();
void RemoveRequestContext();
// BrowserContext methods.
base::FilePath GetPath() const override;
@ -98,10 +102,8 @@ class CefBrowserContextImpl : public CefBrowserContext,
}
private:
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContextImpl>;
// Allow deletion via std::unique_ptr().
friend std::default_delete<CefBrowserContextImpl>;
~CefBrowserContextImpl() override;
@ -109,9 +111,8 @@ class CefBrowserContextImpl : public CefBrowserContext,
CefRequestContextSettings settings_;
base::FilePath cache_path_;
// Not owned by this class.
typedef std::vector<const CefBrowserContextProxy*> ProxyList;
ProxyList proxy_list_;
// Number of CefRequestContextImpl objects referencing this object.
int request_context_count_ = 0;
std::unique_ptr<PrefService> pref_service_;
std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;

View File

@ -59,16 +59,18 @@ bool ShouldProxyUserData(const void* key) {
CefBrowserContextProxy::CefBrowserContextProxy(
CefRefPtr<CefRequestContextHandler> handler,
scoped_refptr<CefBrowserContextImpl> parent)
CefBrowserContextImpl* parent)
: CefBrowserContext(true),
handler_(handler),
parent_(parent) {
DCHECK(handler_.get());
DCHECK(parent_.get());
DCHECK(parent_);
parent_->AddProxy(this);
}
CefBrowserContextProxy::~CefBrowserContextProxy() {
CEF_REQUIRE_UIT();
Shutdown();
parent_->RemoveProxy(this);

View File

@ -21,7 +21,7 @@ class CefStoragePartitionProxy;
class CefBrowserContextProxy : public CefBrowserContext {
public:
CefBrowserContextProxy(CefRefPtr<CefRequestContextHandler> handler,
scoped_refptr<CefBrowserContextImpl> parent);
CefBrowserContextImpl* parent);
// Must be called immediately after this object is created.
void Initialize() override;
@ -67,21 +67,19 @@ class CefBrowserContextProxy : public CefBrowserContext {
content::StoragePartition* GetOrCreateStoragePartitionProxy(
content::StoragePartition* partition_impl);
scoped_refptr<CefBrowserContextImpl> parent() const {
CefBrowserContextImpl* parent() const {
return parent_;
}
private:
// Only allow deletion via scoped_refptr().
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<CefBrowserContextProxy>;
// Allow deletion via std::unique_ptr() only.
friend std::default_delete<CefBrowserContextProxy>;
~CefBrowserContextProxy() override;
// Members initialized during construction are safe to access from any thread.
CefRefPtr<CefRequestContextHandler> handler_;
scoped_refptr<CefBrowserContextImpl> parent_;
CefBrowserContextImpl* parent_; // Guaranteed to outlive this object.
std::unique_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<CefStoragePartitionProxy> storage_partition_proxy_;

View File

@ -281,10 +281,10 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetForRequestContext(
CefRequestContextImpl::GetOrCreateForRequestContext(
create_params.request_context);
DCHECK(request_context_impl);
scoped_refptr<CefBrowserContext> browser_context =
CefBrowserContext* browser_context =
request_context_impl->GetBrowserContext();
DCHECK(browser_context);
@ -298,8 +298,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
create_params.request_context = request_context_impl.get();
}
content::WebContents::CreateParams wc_create_params(
browser_context.get());
content::WebContents::CreateParams wc_create_params(browser_context);
if (platform_delegate->IsWindowless()) {
// Create the OSR view for the WebContents.
@ -692,13 +691,13 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) {
if (!web_contents())
return;
scoped_refptr<CefBrowserContext> context =
CefBrowserContext* context =
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
if (!context.get())
if (!context)
return;
content::DownloadManager* manager =
content::BrowserContext::GetDownloadManager(context.get());
content::BrowserContext::GetDownloadManager(context);
if (!manager)
return;
@ -2272,11 +2271,11 @@ void CefBrowserHostImpl::WebContentsCreated(
CefRefPtr<CefBrowserHostImpl> opener = GetBrowserForContents(source_contents);
DCHECK(opener.get());
scoped_refptr<CefBrowserContext> browser_context =
CefBrowserContext* browser_context =
static_cast<CefBrowserContext*>(new_contents->GetBrowserContext());
DCHECK(browser_context.get());
DCHECK(browser_context);
CefRefPtr<CefRequestContext> request_context =
CefRequestContextImpl::GetForBrowserContext(browser_context).get();
CefRequestContextImpl::CreateForBrowserContext(browser_context).get();
DCHECK(request_context.get());
CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::CreateInternal(
@ -2406,7 +2405,7 @@ void CefBrowserHostImpl::RenderFrameDeleted(
if (web_contents()) {
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
scoped_refptr<CefBrowserContext> context =
CefBrowserContext* context =
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
if (context) {
context->OnRenderFrameDeleted(render_process_id, render_routing_id,
@ -2578,9 +2577,9 @@ void CefBrowserHostImpl::DidNavigateAnyFrame(
if (!web_contents())
return;
scoped_refptr<CefBrowserContext> context =
CefBrowserContext* context =
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
if (!context.get())
if (!context)
return;
context->AddVisitedURLs(params.redirects);

View File

@ -193,7 +193,7 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
CefContext::Get()->PopulateRequestContextSettings(&settings);
// Create the global BrowserContext.
global_browser_context_ = new CefBrowserContextImpl(settings);
global_browser_context_.reset(new CefBrowserContextImpl(settings));
global_browser_context_->Initialize();
CefDevToolsManagerDelegate::StartHttpHandler(global_browser_context_.get());
@ -212,7 +212,7 @@ void CefBrowserMainParts::PostMainMessageLoopRun() {
// NOTE: Destroy objects in reverse order of creation.
CefDevToolsManagerDelegate::StopHttpHandler();
global_browser_context_ = NULL;
global_browser_context_.reset(nullptr);
if (extensions::ExtensionsEnabled()) {
extensions::ExtensionsBrowserClient::Set(NULL);

View File

@ -6,7 +6,6 @@
#define CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_
#pragma once
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/net/url_request_context_getter_impl.h"
#include "base/macros.h"
@ -31,6 +30,7 @@ class ExtensionsBrowserClient;
class ExtensionsClient;
}
class CefBrowserContextImpl;
class CefDevToolsDelegate;
class CefBrowserMainParts : public content::BrowserMainParts {
@ -47,8 +47,8 @@ class CefBrowserMainParts : public content::BrowserMainParts {
void PostMainMessageLoopRun() override;
void PostDestroyThreads() override;
scoped_refptr<CefBrowserContextImpl> browser_context() const {
return global_browser_context_;
CefBrowserContextImpl* browser_context() const {
return global_browser_context_.get();
}
CefDevToolsDelegate* devtools_delegate() const {
return devtools_delegate_;
@ -59,7 +59,7 @@ class CefBrowserMainParts : public content::BrowserMainParts {
void PlatformInitialize();
#endif // defined(OS_WIN)
scoped_refptr<CefBrowserContextImpl> global_browser_context_;
std::unique_ptr<CefBrowserContextImpl> global_browser_context_;
CefDevToolsDelegate* devtools_delegate_; // Deletes itself.
std::unique_ptr<base::MessageLoop> message_loop_;

View File

@ -190,11 +190,11 @@ class CefBrowserURLRequest::Context
// Get or create the request context and browser context.
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetForRequestContext(request_context_);
CefRequestContextImpl::GetOrCreateForRequestContext(request_context_);
DCHECK(request_context_impl.get());
scoped_refptr<CefBrowserContext> browser_context =
CefBrowserContext* browser_context =
request_context_impl->GetBrowserContext();
DCHECK(browser_context.get());
DCHECK(browser_context);
if (!request_context_.get())
request_context_ = request_context_impl.get();

View File

@ -360,7 +360,7 @@ ChromeBrowserProcessStub::GetPhysicalWebDataSource() {
content::BrowserContext*
ChromeBrowserProcessStub::GetBrowserContextRedirectedInIncognito(
content::BrowserContext* context) {
return CefBrowserContextImpl::GetForContext(context).get();
return CefBrowserContextImpl::GetForContext(context);
}
content::BrowserContext*

View File

@ -21,7 +21,7 @@ namespace {
// Return the main context for now since we don't currently have a good way to
// determine that.
CefBrowserContextImpl* GetActiveBrowserContext() {
return CefContentBrowserClient::Get()->browser_context().get();
return CefContentBrowserClient::Get()->browser_context();
}
} // namespace
@ -35,7 +35,7 @@ ChromeProfileManagerStub::~ChromeProfileManagerStub() {
Profile* ChromeProfileManagerStub::GetProfile(
const base::FilePath& profile_dir) {
scoped_refptr<CefBrowserContextImpl> browser_context =
CefBrowserContextImpl* browser_context =
CefBrowserContextImpl::GetForCachePath(profile_dir);
if (!browser_context) {
// ProfileManager makes assumptions about profile directory paths that do
@ -46,7 +46,7 @@ Profile* ChromeProfileManagerStub::GetProfile(
// asking for.
browser_context = GetActiveBrowserContext();
}
return browser_context.get();
return browser_context;
}
bool ChromeProfileManagerStub::IsValidProfile(const void* profile) {
@ -54,7 +54,7 @@ bool ChromeProfileManagerStub::IsValidProfile(const void* profile) {
return false;
return !!CefBrowserContextImpl::GetForContext(
reinterpret_cast<content::BrowserContext*>(
const_cast<void*>(profile))).get();
const_cast<void*>(profile)));
}
Profile* ChromeProfileManagerStub::GetLastUsedProfile(

View File

@ -7,6 +7,7 @@
#include <algorithm>
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_host_impl.h"
@ -42,6 +43,7 @@
#include "base/json/json_reader.h"
#include "base/path_service.h"
#include "cef/grit/cef_resources.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_message_filter.h"
#include "chrome/common/chrome_switches.h"
#include "components/navigation_interception/intercept_navigation_throttle.h"
@ -979,8 +981,7 @@ void CefContentBrowserClient::RegisterCustomScheme(const std::string& scheme) {
policy->RegisterWebSafeScheme(scheme);
}
scoped_refptr<CefBrowserContextImpl>
CefContentBrowserClient::browser_context() const {
CefBrowserContextImpl* CefContentBrowserClient::browser_context() const {
return browser_main_parts_->browser_context();
}

View File

@ -10,7 +10,6 @@
#include <utility>
#include "include/cef_request_context_handler.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/net/url_request_context_getter_impl.h"
#include "base/macros.h"
@ -20,6 +19,7 @@
#include "third_party/skia/include/core/SkColor.h"
class CefBrowserMainParts;
class CefBrowserContextImpl;
class CefDevToolsDelegate;
class CefResourceDispatcherHostDelegate;
@ -28,6 +28,10 @@ class PluginServiceFilter;
class SiteInstance;
}
namespace extensions {
class Extension;
}
class CefContentBrowserClient : public content::ContentBrowserClient {
public:
CefContentBrowserClient();
@ -113,7 +117,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
// Perform browser process registration for the custom scheme.
void RegisterCustomScheme(const std::string& scheme);
scoped_refptr<CefBrowserContextImpl> browser_context() const;
CefBrowserContextImpl* browser_context() const;
CefDevToolsDelegate* devtools_delegate() const;
private:

View File

@ -57,10 +57,10 @@ bool GetTabById(int tab_id,
if (!request_context)
continue;
CefRefPtr<CefRequestContextImpl> request_context_impl =
CefRequestContextImpl::GetForRequestContext(request_context);
CefRequestContextImpl::GetOrCreateForRequestContext(request_context);
if (!request_context_impl)
continue;
scoped_refptr<CefBrowserContext> browser_context =
CefBrowserContext* browser_context =
request_context_impl->GetBrowserContext();
if (!browser_context)
continue;

View File

@ -44,7 +44,7 @@ CefExtensionsAPIClient::CreateGuestViewManagerDelegate(
// *Proxy object that has already been deleted.
return base::WrapUnique(
new extensions::ExtensionsGuestViewManagerDelegate(
CefBrowserContextImpl::GetForContext(context).get()));
CefBrowserContextImpl::GetForContext(context)));
}
std::unique_ptr<MimeHandlerViewGuestDelegate>

View File

@ -64,8 +64,8 @@ bool CefExtensionsBrowserClient::IsSameContext(BrowserContext* first,
BrowserContext* second) {
// Returns true if |first| and |second| share the same underlying
// CefBrowserContextImpl.
return CefBrowserContextImpl::GetForContext(first).get() ==
CefBrowserContextImpl::GetForContext(second).get();
return CefBrowserContextImpl::GetForContext(first) ==
CefBrowserContextImpl::GetForContext(second);
}
bool CefExtensionsBrowserClient::HasOffTheRecordContext(

View File

@ -5,6 +5,7 @@
#include "libcef/browser/extensions/mime_handler_view_guest_delegate.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/content_browser_client.h"
@ -91,7 +92,7 @@ void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
info->guest_render_id_manager()->remove_render_frame_id(
render_process_id, render_frame_id);
scoped_refptr<CefBrowserContext> context =
CefBrowserContext* context =
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
if (context) {
context->OnRenderFrameDeleted(render_process_id, render_frame_id,

View File

@ -64,7 +64,7 @@ struct ResolveHostHelper {
resolved_ips.push_back(iter->ToStringWithoutPort());
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefResolveCallback::OnResolveCompleted, callback_.get(),
base::Bind(&CefResolveCallback::OnResolveCompleted, callback_,
static_cast<cef_errorcode_t>(result), resolved_ips));
delete this;
@ -88,8 +88,9 @@ CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() {
return NULL;
}
return CefRequestContextImpl::GetForBrowserContext(
CefContentBrowserClient::Get()->browser_context());
CefRequestContextImpl::Config config;
config.is_global = true;
return new CefRequestContextImpl(config);
}
// static
@ -102,7 +103,11 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
return NULL;
}
return new CefRequestContextImpl(settings, handler);
CefRequestContextImpl::Config config;
config.settings = settings;
config.handler = handler;
config.unique_id = g_next_id.GetNext();
return new CefRequestContextImpl(config);
}
// static
@ -118,18 +123,31 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext(
if (!other.get())
return NULL;
return new CefRequestContextImpl(
static_cast<CefRequestContextImpl*>(other.get()), handler);
CefRequestContextImpl::Config config;
config.other = static_cast<CefRequestContextImpl*>(other.get());
config.handler = handler;
config.unique_id = g_next_id.GetNext();
return new CefRequestContextImpl(config);
}
// CefBrowserContextImpl
// CefRequestContextImpl
CefRequestContextImpl::~CefRequestContextImpl() {
// Delete the proxy first because it also references |browser_context_impl_|.
if (browser_context_proxy_)
browser_context_proxy_.reset(nullptr);
if (browser_context_impl_) {
// May result in |browser_context_impl_| being deleted if it's not the
// global context and no other CefRequestContextImpl are referencing it.
browser_context_impl_->RemoveRequestContext();
}
}
// static
CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForRequestContext(
CefRefPtr<CefRequestContextImpl>
CefRequestContextImpl::GetOrCreateForRequestContext(
CefRefPtr<CefRequestContext> request_context) {
if (request_context.get()) {
// Use the context from the provided CefRequestContext.
@ -137,87 +155,27 @@ CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForRequestContext(
}
// Use the global context.
scoped_refptr<CefBrowserContext> browser_context =
CefContentBrowserClient::Get()->browser_context();
return GetForBrowserContext(browser_context);
CefRequestContextImpl::Config config;
config.is_global = true;
return new CefRequestContextImpl(config);
}
// static
CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForBrowserContext(
scoped_refptr<CefBrowserContext> browser_context) {
DCHECK(browser_context.get());
return new CefRequestContextImpl(browser_context);
CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::CreateForBrowserContext(
CefBrowserContext* browser_context) {
DCHECK(browser_context);
CefRequestContextImpl::Config config;
config.handler = browser_context->GetHandler();
CefRefPtr<CefRequestContextImpl> impl = new CefRequestContextImpl(config);
// Force immediate initialization because it's not safe to keep a raw pointer
// to |browser_context|.
impl->Initialize(browser_context);
return impl;
}
scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() {
CEF_REQUIRE_UIT();
if (!browser_context_) {
scoped_refptr<CefBrowserContextImpl> parent;
if (other_.get()) {
// Share storage with |other_|.
parent = CefBrowserContextImpl::GetForContext(
other_->GetBrowserContext().get());
}
if (!parent.get()) {
const base::FilePath& cache_path =
base::FilePath(CefString(&settings_.cache_path));
if (!cache_path.empty()) {
// Check if a CefBrowserContextImpl is already globally registered for
// the specified cache path. If so then use it.
parent = CefBrowserContextImpl::GetForCachePath(cache_path);
}
}
if (!parent.get()) {
// Create a new CefBrowserContextImpl instance. If the cache path is non-
// empty then this new instance will become the globally registered
// CefBrowserContextImpl for that path. Otherwise, this new instance will
// be a completely isolated "incongento mode" context.
parent = new CefBrowserContextImpl(settings_);
parent->Initialize();
}
// The parent's settings may be different. Force our settings to match the
// parent.
settings_ = parent->GetSettings();
if (handler_.get()) {
// Use a proxy that will execute handler callbacks where appropriate and
// otherwise forward all requests to the parent implementation.
browser_context_ = new CefBrowserContextProxy(handler_, parent);
browser_context_->Initialize();
} else {
// Use the parent implementation directly.
browser_context_ = parent;
}
request_context_impl_ = parent->request_context().get();
DCHECK(request_context_impl_);
if (handler_.get()) {
// Keep the handler alive until the associated request context is
// destroyed.
request_context_impl_->AddHandler(handler_);
}
}
if (!request_context_impl_) {
request_context_impl_ =
CefBrowserContextImpl::GetForContext(browser_context_.get())->
request_context().get();
DCHECK(request_context_impl_);
}
if (other_.get()) {
// Clear the reference to |other_| after setting |request_context_impl_|.
// This is the reverse order of checks in IsSharedWith().
other_ = NULL;
}
return browser_context_;
CefBrowserContext* CefRequestContextImpl::GetBrowserContext() {
EnsureBrowserContext();
return browser_context();
}
void CefRequestContextImpl::GetBrowserContext(
@ -235,8 +193,8 @@ void CefRequestContextImpl::GetRequestContextImpl(
task_runner = base::MessageLoop::current()->task_runner();
if (request_context_impl_) {
// The browser context already exists.
DCHECK(browser_context_.get());
GetRequestContextImplOnIOThread(task_runner, callback, browser_context_);
DCHECK(browser_context());
GetRequestContextImplOnIOThread(task_runner, callback, browser_context());
} else {
// Need to initialize the browser context first.
GetBrowserContextOnUIThread(
@ -252,14 +210,28 @@ bool CefRequestContextImpl::IsSame(CefRefPtr<CefRequestContext> other) {
if (!other_impl)
return false;
// Compare whether both are the global context.
if (config_.is_global && other_impl->config_.is_global)
return true;
// Compare CefBrowserContext pointers if one has been associated.
if (browser_context_ && other_impl->browser_context_)
return (browser_context_ == other_impl->browser_context_);
else if (browser_context_ || other_impl->browser_context_)
if (browser_context() && other_impl->browser_context()) {
if (browser_context()->is_proxy() &&
other_impl->browser_context()->is_proxy()) {
CefBrowserContextProxy* proxy =
static_cast<CefBrowserContextProxy*>(browser_context());
CefBrowserContextProxy* other_proxy =
static_cast<CefBrowserContextProxy*>(other_impl->browser_context());
return (proxy->parent() == other_proxy->parent() &&
proxy->GetHandler() == other_proxy->GetHandler());
}
return (browser_context() == other_impl->browser_context());
} else if (browser_context() || other_impl->browser_context()) {
return false;
}
// Otherwise compare unique IDs.
return (unique_id_ == other_impl->unique_id_);
return (config_.unique_id == other_impl->config_.unique_id);
}
bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) {
@ -271,14 +243,14 @@ bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) {
if (IsSame(other))
return true;
CefRefPtr<CefRequestContext> pending_other = other_;
CefRefPtr<CefRequestContext> pending_other = config_.other;
if (pending_other.get()) {
// This object is not initialized but we know what context this object will
// share with. Compare to that other context instead.
return pending_other->IsSharingWith(other);
}
pending_other = other_impl->other_;
pending_other = other_impl->config_.other;
if (pending_other.get()) {
// The other object is not initialized but we know what context that object
// will share with. Compare to that other context instead.
@ -292,26 +264,26 @@ bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) {
// This or the other object is not initialized. Compare the cache path values.
// If both are non-empty and the same then they'll share the same storage.
if (settings_.cache_path.length > 0 &&
other_impl->settings_.cache_path.length > 0) {
return (base::FilePath(CefString(&settings_.cache_path)) ==
base::FilePath(CefString(&other_impl->settings_.cache_path)));
if (config_.settings.cache_path.length > 0 &&
other_impl->config_.settings.cache_path.length > 0) {
return (base::FilePath(CefString(&config_.settings.cache_path)) ==
base::FilePath(
CefString(&other_impl->config_.settings.cache_path)));
}
return false;
}
bool CefRequestContextImpl::IsGlobal() {
return (browser_context_ ==
CefContentBrowserClient::Get()->browser_context());
return config_.is_global;
}
CefRefPtr<CefRequestContextHandler> CefRequestContextImpl::GetHandler() {
return handler_;
return config_.handler;
}
CefString CefRequestContextImpl::GetCachePath() {
return CefString(&settings_.cache_path);
return CefString(&config_.settings.cache_path);
}
CefRefPtr<CefCookieManager> CefRequestContextImpl::GetDefaultCookieManager(
@ -357,7 +329,7 @@ bool CefRequestContextImpl::HasPreference(const CefString& name) {
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context_->GetPrefs();
PrefService* pref_service = browser_context()->GetPrefs();
return (pref_service->FindPreference(name) != NULL);
}
@ -372,7 +344,7 @@ CefRefPtr<CefValue> CefRequestContextImpl::GetPreference(
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context_->GetPrefs();
PrefService* pref_service = browser_context()->GetPrefs();
const PrefService::Preference* pref = pref_service->FindPreference(name);
if (!pref)
return NULL;
@ -390,7 +362,7 @@ CefRefPtr<CefDictionaryValue> CefRequestContextImpl::GetAllPreferences(
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context_->GetPrefs();
PrefService* pref_service = browser_context()->GetPrefs();
std::unique_ptr<base::DictionaryValue> values;
if (include_defaults)
@ -412,7 +384,7 @@ bool CefRequestContextImpl::CanSetPreference(const CefString& name) {
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context_->GetPrefs();
PrefService* pref_service = browser_context()->GetPrefs();
const PrefService::Preference* pref = pref_service->FindPreference(name);
return (pref && pref->IsUserModifiable());
}
@ -429,7 +401,7 @@ bool CefRequestContextImpl::SetPreference(const CefString& name,
// Make sure the browser context exists.
EnsureBrowserContext();
PrefService* pref_service = browser_context_->GetPrefs();
PrefService* pref_service = browser_context()->GetPrefs();
// The below validation logic should match PrefService::SetUserPrefValue.
@ -530,35 +502,91 @@ cef_errorcode_t CefRequestContextImpl::ResolveHostCached(
}
CefRequestContextImpl::CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context)
: browser_context_(browser_context),
settings_(browser_context->GetSettings()),
handler_(browser_context->GetHandler()),
unique_id_(0),
request_context_impl_(NULL) {
const CefRequestContextImpl::Config& config)
: config_(config) {
}
CefRequestContextImpl::CefRequestContextImpl(
const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler)
: settings_(settings),
handler_(handler),
unique_id_(g_next_id.GetNext()),
request_context_impl_(NULL) {
void CefRequestContextImpl::Initialize() {
CefBrowserContext* other_browser_context = nullptr;
if (config_.is_global)
other_browser_context = CefContentBrowserClient::Get()->browser_context();
else if (config_.other.get())
other_browser_context = config_.other->GetBrowserContext();
Initialize(other_browser_context);
if (config_.other.get()) {
// Clear the reference to |other_| after setting |request_context_impl_|.
// This is the reverse order of checks in IsSharedWith().
config_.other = NULL;
}
}
CefRequestContextImpl::CefRequestContextImpl(
CefRefPtr<CefRequestContextImpl> other,
CefRefPtr<CefRequestContextHandler> handler)
: other_(other),
handler_(handler),
unique_id_(g_next_id.GetNext()),
request_context_impl_(NULL) {
void CefRequestContextImpl::Initialize(
CefBrowserContext* other_browser_context) {
CEF_REQUIRE_UIT();
DCHECK(!browser_context_impl_);
DCHECK(!request_context_impl_);
if (other_browser_context) {
// Share storage with |other_browser_context|.
browser_context_impl_ = CefBrowserContextImpl::GetForContext(
other_browser_context);
}
if (!browser_context_impl_) {
const base::FilePath& cache_path =
base::FilePath(CefString(&config_.settings.cache_path));
if (!cache_path.empty()) {
// Check if a CefBrowserContextImpl is already globally registered for
// the specified cache path. If so then use it.
browser_context_impl_ =
CefBrowserContextImpl::GetForCachePath(cache_path);
}
}
if (!browser_context_impl_) {
// Create a new CefBrowserContextImpl instance. If the cache path is non-
// empty then this new instance will become the globally registered
// CefBrowserContextImpl for that path. Otherwise, this new instance will
// be a completely isolated "incongento mode" context.
browser_context_impl_ = new CefBrowserContextImpl(config_.settings);
browser_context_impl_->Initialize();
}
// We'll disassociate from |browser_context_impl_| on destruction.
browser_context_impl_->AddRequestContext();
// Force our settings to match |browser_context_impl_|.
config_.settings = browser_context_impl_->GetSettings();
if (config_.handler.get()) {
// Use a proxy that will execute handler callbacks where appropriate and
// otherwise forward all requests to |browser_context_impl_|.
browser_context_proxy_.reset(
new CefBrowserContextProxy(config_.handler, browser_context_impl_));
browser_context_proxy_->Initialize();
DCHECK(!config_.is_global);
} else {
config_.is_global = (browser_context_impl_ ==
CefContentBrowserClient::Get()->browser_context());
}
request_context_impl_ = browser_context_impl_->request_context().get();
DCHECK(request_context_impl_);
if (config_.handler.get()) {
// Keep the handler alive until the associated request context is
// destroyed.
request_context_impl_->AddHandler(config_.handler);
}
}
void CefRequestContextImpl::EnsureBrowserContext() {
GetBrowserContext();
DCHECK(browser_context_.get());
if (!browser_context())
Initialize();
DCHECK(browser_context());
DCHECK(request_context_impl_);
}
@ -577,17 +605,17 @@ void CefRequestContextImpl::GetBrowserContextOnUIThread(
if (task_runner->BelongsToCurrentThread()) {
// Execute the callback immediately.
callback.Run(browser_context_);
callback.Run(browser_context());
} else {
// Execute the callback on the target thread.
task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context_));
task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context()));
}
}
void CefRequestContextImpl::GetRequestContextImplOnIOThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback,
scoped_refptr<CefBrowserContext> browser_context) {
CefBrowserContext* browser_context) {
if (!CEF_CURRENTLY_ON_IOT()) {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefRequestContextImpl::GetRequestContextImplOnIOThread,
@ -628,16 +656,16 @@ void CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal(
void CefRequestContextImpl::PurgePluginListCacheInternal(
bool reload_pages,
scoped_refptr<CefBrowserContext> browser_context) {
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
browser_context->OnPurgePluginListCache();
content::PluginService::GetInstance()->PurgePluginListCache(
browser_context.get(), false);
browser_context, false);
}
void CefRequestContextImpl::ClearCertificateExceptionsInternal(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefBrowserContext> browser_context) {
CefBrowserContext* browser_context) {
CEF_REQUIRE_UIT();
content::SSLHostStateDelegate* ssl_delegate =
@ -647,7 +675,7 @@ void CefRequestContextImpl::ClearCertificateExceptionsInternal(
if (callback) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
base::Bind(&CefCompletionCallback::OnComplete, callback));
}
}
@ -669,7 +697,7 @@ void CefRequestContextImpl::CloseAllConnectionsInternal(
if (callback) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
base::Bind(&CefCompletionCallback::OnComplete, callback));
}
}
@ -702,3 +730,10 @@ void CefRequestContextImpl::ResolveHostInternal(
helper->OnResolveCompleted(retval);
}
CefBrowserContext* CefRequestContextImpl::browser_context() const {
if (browser_context_proxy_)
return browser_context_proxy_.get();
return browser_context_impl_;
}

View File

@ -8,32 +8,35 @@
#include "include/cef_request_context.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/thread_util.h"
class CefBrowserContextImpl;
class CefBrowserContextProxy;
// Implementation of the CefRequestContext interface. All methods are thread-
// safe unless otherwise indicated.
// safe unless otherwise indicated. Will be deleted on the UI thread.
class CefRequestContextImpl : public CefRequestContext {
public:
~CefRequestContextImpl() override;
// Returns a CefRequestContextImpl for the specified |request_context|.
// Will return the global context if |request_context| is NULL.
static CefRefPtr<CefRequestContextImpl> GetForRequestContext(
static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext(
CefRefPtr<CefRequestContext> request_context);
// Returns a CefRequestContextImpl for the specified |browser_context|.
// |browser_context| must be non-NULL.
static CefRefPtr<CefRequestContextImpl> GetForBrowserContext(
scoped_refptr<CefBrowserContext> browser_context);
static CefRefPtr<CefRequestContextImpl> CreateForBrowserContext(
CefBrowserContext* browser_context);
// Returns the browser context object. Can only be called on the UI thread.
scoped_refptr<CefBrowserContext> GetBrowserContext();
CefBrowserContext* GetBrowserContext();
// Executes |callback| either synchronously or asynchronously with the browser
// context object when it's available. If |task_runner| is NULL the callback
// will be executed on the originating thread. The resulting context object
// can only be accessed on the UI thread.
typedef base::Callback<void(scoped_refptr<CefBrowserContext>)>
BrowserContextCallback;
typedef base::Callback<void(CefBrowserContext*)> BrowserContextCallback;
void GetBrowserContext(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const BrowserContextCallback& callback);
@ -79,17 +82,36 @@ class CefRequestContextImpl : public CefRequestContext {
const CefString& origin,
std::vector<CefString>& resolved_ips) override;
const CefRequestContextSettings& settings() const { return settings_; }
const CefRequestContextSettings& settings() const { return config_.settings; }
private:
friend class CefRequestContext;
explicit CefRequestContextImpl(
scoped_refptr<CefBrowserContext> browser_context);
CefRequestContextImpl(const CefRequestContextSettings& settings,
CefRefPtr<CefRequestContextHandler> handler);
CefRequestContextImpl(CefRefPtr<CefRequestContextImpl> other,
CefRefPtr<CefRequestContextHandler> handler);
struct Config {
// True if wrapping the global context.
bool is_global = false;
// |settings| or |other| will be set when creating a new CefRequestContext
// via the API. When wrapping an existing CefBrowserContext* both will be
// empty and Initialize(CefBrowserContext*) will be called immediately after
// CefRequestContextImpl construction.
CefRequestContextSettings settings;
CefRefPtr<CefRequestContextImpl> other;
// Optionally use this handler, in which case a CefBrowserContextProxy will
// be created.
CefRefPtr<CefRequestContextHandler> handler;
// Used to uniquely identify CefRequestContext objects before an associated
// CefBrowserContext has been created. Should be set when a new
// CefRequestContext via the API.
int unique_id = -1;
};
explicit CefRequestContextImpl(const Config& config);
void Initialize();
void Initialize(CefBrowserContext* other_browser_context);
// Make sure the browser context exists. Only called on the UI thread.
void EnsureBrowserContext();
@ -100,7 +122,7 @@ class CefRequestContextImpl : public CefRequestContext {
void GetRequestContextImplOnIOThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const RequestContextCallback& callback,
scoped_refptr<CefBrowserContext> browser_context);
CefBrowserContext* browser_context);
void RegisterSchemeHandlerFactoryInternal(
const CefString& scheme_name,
@ -111,10 +133,10 @@ class CefRequestContextImpl : public CefRequestContext {
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
void PurgePluginListCacheInternal(
bool reload_pages,
scoped_refptr<CefBrowserContext> browser_context);
CefBrowserContext* browser_context);
void ClearCertificateExceptionsInternal(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefBrowserContext> browser_context);
CefBrowserContext* browser_context);
void CloseAllConnectionsInternal(
CefRefPtr<CefCompletionCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
@ -123,19 +145,19 @@ class CefRequestContextImpl : public CefRequestContext {
CefRefPtr<CefResolveCallback> callback,
scoped_refptr<CefURLRequestContextGetterImpl> request_context);
scoped_refptr<CefBrowserContext> browser_context_;
CefRequestContextSettings settings_;
CefRefPtr<CefRequestContextImpl> other_;
CefRefPtr<CefRequestContextHandler> handler_;
CefBrowserContext* browser_context() const;
// Used to uniquely identify CefRequestContext objects before an associated
// CefBrowserContext has been created.
int unique_id_;
// If *Impl then we must disassociate from it on destruction.
CefBrowserContextImpl* browser_context_impl_ = nullptr;
// If *Proxy then we own it.
std::unique_ptr<CefBrowserContextProxy> browser_context_proxy_;
Config config_;
// Owned by the CefBrowserContext.
CefURLRequestContextGetterImpl* request_context_impl_;
CefURLRequestContextGetterImpl* request_context_impl_ = nullptr;
IMPLEMENT_REFCOUNTING(CefRequestContextImpl);
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefRequestContextImpl);
DISALLOW_COPY_AND_ASSIGN(CefRequestContextImpl);
};

View File

@ -671,8 +671,6 @@ class MethodTestHandler : public TestHandler {
}
~CompletionCallback() override {
EXPECT_UI_THREAD();
// OnComplete should be executed.
EXPECT_FALSE(test_handler_);
}