Move the frame/handler association to CefResourceContext (see issue #2622).
A CefBrowserHostImpl is created using a CefRequestContextImpl that may have a CefRequestContextHandler. Multiple CefRequestContextImpl may share the same underlying CefBrowserContext which owns a CefResourceContext. IO-thread callbacks from Chromium are often associated with a CefResourceContext and the target frame is identified using render_process_id/render_frame_id routing IDs. This change forwards frame create/delete notifications from CefBrowserHostImpl (or CefMimeHandlerViewGuestDelegate) to CefResourceContext so that it can properly resolve the association from routing ID to Handler when queried from CefPluginServiceFilter::IsPluginAvailable. To test: Verify that all ceftests pass with NetworkService disabled.
This commit is contained in:
parent
a23e845244
commit
ea27dff338
|
@ -287,8 +287,7 @@ void CefBrowserContext::Initialize() {
|
|||
|
||||
content::BrowserContext::Initialize(this, GetPath());
|
||||
|
||||
resource_context_.reset(
|
||||
new CefResourceContext(IsOffTheRecord(), GetHandler()));
|
||||
resource_context_.reset(new CefResourceContext(IsOffTheRecord()));
|
||||
|
||||
// This must be called before creating any services to avoid hitting
|
||||
// DependencyManager::AssertContextWasntDestroyed when creating/destroying
|
||||
|
@ -369,19 +368,6 @@ void CefBrowserContext::RemoveCefRequestContext(
|
|||
delete this;
|
||||
}
|
||||
|
||||
CefRequestContextImpl* CefBrowserContext::GetCefRequestContext(
|
||||
bool impl_only) const {
|
||||
CEF_REQUIRE_UIT();
|
||||
// First try to find a non-proxy RequestContext.
|
||||
for (CefRequestContextImpl* impl : request_context_set_) {
|
||||
if (!impl->GetHandler())
|
||||
return impl;
|
||||
}
|
||||
if (impl_only)
|
||||
return nullptr;
|
||||
return *request_context_set_.begin();
|
||||
}
|
||||
|
||||
// static
|
||||
CefBrowserContext* CefBrowserContext::GetForCachePath(
|
||||
const base::FilePath& cache_path) {
|
||||
|
@ -572,10 +558,6 @@ SimpleFactoryKey* CefBrowserContext::GetSimpleFactoryKey() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
CefRequestContextImpl* CefBrowserContext::GetCefRequestContext() const {
|
||||
return GetCefRequestContext(false);
|
||||
}
|
||||
|
||||
const CefRequestContextSettings& CefBrowserContext::GetSettings() const {
|
||||
return settings_;
|
||||
}
|
||||
|
@ -625,11 +607,44 @@ void CefBrowserContext::RebuildTable(
|
|||
enumerator->OnComplete(true);
|
||||
}
|
||||
|
||||
void CefBrowserContext::OnRenderFrameDeleted(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view) {
|
||||
void CefBrowserContext::OnRenderFrameCreated(
|
||||
CefRequestContextImpl* request_context,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view) {
|
||||
CEF_REQUIRE_UIT();
|
||||
CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
|
||||
if (handler && resource_context_) {
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
// 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::AddHandler,
|
||||
base::Unretained(resource_context_.get()),
|
||||
render_process_id, render_frame_id, handler));
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserContext::OnRenderFrameDeleted(
|
||||
CefRequestContextImpl* request_context,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view) {
|
||||
CEF_REQUIRE_UIT();
|
||||
CefRefPtr<CefRequestContextHandler> handler = request_context->GetHandler();
|
||||
if (handler && resource_context_) {
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
// 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::RemoveHandler,
|
||||
base::Unretained(resource_context_.get()),
|
||||
render_process_id, render_frame_id));
|
||||
}
|
||||
|
||||
if (resource_context_ && is_main_frame) {
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
// Using base::Unretained() is safe because both this callback and possible
|
||||
|
|
|
@ -134,7 +134,6 @@ class CefBrowserContext : public ChromeProfileStub,
|
|||
// itself when the count reaches zero.
|
||||
void AddCefRequestContext(CefRequestContextImpl* context);
|
||||
void RemoveCefRequestContext(CefRequestContextImpl* context);
|
||||
CefRequestContextImpl* GetCefRequestContext(bool impl_only) const;
|
||||
|
||||
// BrowserContext methods.
|
||||
content::ResourceContext* GetResourceContext() override;
|
||||
|
@ -185,10 +184,6 @@ class CefBrowserContext : public ChromeProfileStub,
|
|||
// visitedlink::VisitedLinkDelegate methods.
|
||||
void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
|
||||
|
||||
// Returns the first RequestContext without a handler, if one exists,
|
||||
// otherwise the first RequestContext.
|
||||
CefRequestContextImpl* GetCefRequestContext() const;
|
||||
|
||||
// Returns the settings associated with this object. Safe to call from any
|
||||
// thread.
|
||||
const CefRequestContextSettings& GetSettings() const;
|
||||
|
@ -204,10 +199,16 @@ class CefBrowserContext : public ChromeProfileStub,
|
|||
// visited links.
|
||||
void AddVisitedURLs(const std::vector<GURL>& urls);
|
||||
|
||||
// Called from CefBrowserHostImpl::RenderFrameDeleted or
|
||||
// CefMimeHandlerViewGuestDelegate::OnGuestDetached when a render frame is
|
||||
// deleted.
|
||||
void OnRenderFrameDeleted(int render_process_id,
|
||||
// Called from CefRequestContextImpl::OnRenderFrameCreated.
|
||||
void OnRenderFrameCreated(CefRequestContextImpl* request_context,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view);
|
||||
|
||||
// Called from CefRequestContextImpl::OnRenderFrameDeleted.
|
||||
void OnRenderFrameDeleted(CefRequestContextImpl* request_context,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view);
|
||||
|
|
|
@ -374,8 +374,8 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
|||
CefRefPtr<CefBrowserHostImpl> browser = CreateInternal(
|
||||
create_params.settings, create_params.client, web_contents.release(),
|
||||
true, info, create_params.devtools_opener, is_devtools_popup,
|
||||
create_params.request_context, std::move(platform_delegate),
|
||||
cef_extension);
|
||||
static_cast<CefRequestContextImpl*>(create_params.request_context.get()),
|
||||
std::move(platform_delegate), cef_extension);
|
||||
if (!browser)
|
||||
return nullptr;
|
||||
|
||||
|
@ -401,7 +401,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
|
|||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefRequestContextImpl> request_context,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
CefRefPtr<CefExtension> extension) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
@ -2565,17 +2565,15 @@ void CefBrowserHostImpl::WebContentsCreated(
|
|||
if (!opener.get())
|
||||
return;
|
||||
|
||||
// Popups must share the same BrowserContext as the parent.
|
||||
CefBrowserContext* browser_context =
|
||||
static_cast<CefBrowserContext*>(new_contents->GetBrowserContext());
|
||||
DCHECK(browser_context);
|
||||
// Popups must share the same RequestContext as the parent.
|
||||
CefRefPtr<CefRequestContextImpl> request_context = opener->request_context();
|
||||
DCHECK(request_context);
|
||||
|
||||
// We don't officially own |new_contents| until AddNewContents() is called.
|
||||
// However, we need to install observers/delegates here.
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CreateInternal(settings, client, new_contents, false, info, opener, false,
|
||||
browser_context->GetCefRequestContext(),
|
||||
std::move(platform_delegate), nullptr);
|
||||
request_context, std::move(platform_delegate), nullptr);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DidNavigateMainFramePostCommit(
|
||||
|
@ -2727,6 +2725,10 @@ void CefBrowserHostImpl::RenderFrameCreated(
|
|||
browser_info_->frame_tree_node_id_manager()->add_frame_tree_node_id(
|
||||
frame_tree_node_id);
|
||||
}
|
||||
|
||||
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
|
||||
request_context_->OnRenderFrameCreated(render_process_id, render_routing_id,
|
||||
is_main_frame, false);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::RenderFrameHostChanged(
|
||||
|
@ -2748,15 +2750,9 @@ void CefBrowserHostImpl::FrameDeleted(
|
|||
browser_info_->frame_tree_node_id_manager()->remove_frame_tree_node_id(
|
||||
frame_tree_node_id);
|
||||
|
||||
if (web_contents()) {
|
||||
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
|
||||
CefBrowserContext* context =
|
||||
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
|
||||
if (context) {
|
||||
context->OnRenderFrameDeleted(render_process_id, render_routing_id,
|
||||
is_main_frame, false);
|
||||
}
|
||||
}
|
||||
const bool is_main_frame = (render_frame_host->GetParent() == nullptr);
|
||||
request_context_->OnRenderFrameDeleted(render_process_id, render_routing_id,
|
||||
is_main_frame, false);
|
||||
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
|
@ -3250,7 +3246,7 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
|||
content::WebContents* web_contents,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefRequestContextImpl> request_context,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
CefRefPtr<CefExtension> extension)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libcef/browser/frame_host_impl.h"
|
||||
#include "libcef/browser/javascript_dialog_manager.h"
|
||||
#include "libcef/browser/menu_manager.h"
|
||||
#include "libcef/browser/request_context_impl.h"
|
||||
#include "libcef/common/response_manager.h"
|
||||
|
||||
#include "base/observer_list.h"
|
||||
|
@ -369,6 +370,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
CefRefPtr<CefClient> client() const { return client_; }
|
||||
scoped_refptr<CefBrowserInfo> browser_info() const { return browser_info_; }
|
||||
int browser_id() const;
|
||||
CefRefPtr<CefRequestContextImpl> request_context() const {
|
||||
return request_context_;
|
||||
}
|
||||
|
||||
// Accessors that must be called on the UI thread.
|
||||
content::BrowserContext* GetBrowserContext();
|
||||
|
@ -558,7 +562,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefRequestContextImpl> request_context,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
CefRefPtr<CefExtension> extension);
|
||||
|
||||
|
@ -588,7 +592,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
content::WebContents* web_contents,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefRequestContextImpl> request_context,
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
|
||||
CefRefPtr<CefExtension> extension);
|
||||
|
||||
|
@ -672,7 +676,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||
CefRefPtr<CefClient> client_;
|
||||
scoped_refptr<CefBrowserInfo> browser_info_;
|
||||
CefWindowHandle opener_;
|
||||
CefRefPtr<CefRequestContext> request_context_;
|
||||
CefRefPtr<CefRequestContextImpl> request_context_;
|
||||
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate_;
|
||||
const bool is_windowless_;
|
||||
const bool is_views_hosted_;
|
||||
|
|
|
@ -68,6 +68,10 @@ void CefMimeHandlerViewGuestDelegate::OnGuestAttached(
|
|||
const int frame_tree_node_id = main_frame_host->GetFrameTreeNodeId();
|
||||
info->frame_tree_node_id_manager()->add_frame_tree_node_id(
|
||||
frame_tree_node_id);
|
||||
|
||||
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
|
||||
owner_browser->request_context()->OnRenderFrameCreated(
|
||||
render_process_id, render_frame_id, is_main_frame, true);
|
||||
}
|
||||
|
||||
void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
|
||||
|
@ -90,13 +94,9 @@ void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
|
|||
info->frame_tree_node_id_manager()->remove_frame_tree_node_id(
|
||||
frame_tree_node_id);
|
||||
|
||||
CefBrowserContext* context =
|
||||
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
|
||||
if (context) {
|
||||
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
|
||||
context->OnRenderFrameDeleted(render_process_id, render_frame_id,
|
||||
is_main_frame, true);
|
||||
}
|
||||
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
|
||||
owner_browser->request_context()->OnRenderFrameDeleted(
|
||||
render_process_id, render_frame_id, is_main_frame, true);
|
||||
}
|
||||
|
||||
bool CefMimeHandlerViewGuestDelegate::HandleContextMenu(
|
||||
|
|
|
@ -94,7 +94,10 @@ bool CefPluginServiceFilter::IsPluginAvailable(
|
|||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContextHandler> handler = resource_context->GetHandler();
|
||||
// The |render_frame_id| value may not be valid, so allow matches with any
|
||||
// handler that shares the same |render_process_id| value.
|
||||
CefRefPtr<CefRequestContextHandler> handler =
|
||||
resource_context->GetHandler(render_process_id, render_frame_id, false);
|
||||
if (!handler) {
|
||||
// No handler so go with the default plugin load decision.
|
||||
return *status != chrome::mojom::PluginStatus::kDisabled;
|
||||
|
|
|
@ -543,6 +543,22 @@ CefRefPtr<CefExtension> CefRequestContextImpl::GetExtension(
|
|||
return GetBrowserContext()->extension_system()->GetExtension(extension_id);
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::OnRenderFrameCreated(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view) {
|
||||
browser_context_->OnRenderFrameCreated(
|
||||
this, render_process_id, render_frame_id, is_main_frame, is_guest_view);
|
||||
}
|
||||
|
||||
void CefRequestContextImpl::OnRenderFrameDeleted(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view) {
|
||||
browser_context_->OnRenderFrameDeleted(
|
||||
this, render_process_id, render_frame_id, is_main_frame, is_guest_view);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefRequestContextImpl>
|
||||
CefRequestContextImpl::GetOrCreateRequestContext(const Config& config) {
|
||||
|
|
|
@ -86,6 +86,22 @@ class CefRequestContextImpl : public CefRequestContext {
|
|||
|
||||
const CefRequestContextSettings& settings() const { return config_.settings; }
|
||||
|
||||
// Called from CefBrowserHostImpl::RenderFrameCreated or
|
||||
// CefMimeHandlerViewGuestDelegate::OnGuestAttached when a render frame is
|
||||
// created.
|
||||
void OnRenderFrameCreated(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view);
|
||||
|
||||
// Called from CefBrowserHostImpl::FrameDeleted or
|
||||
// CefMimeHandlerViewGuestDelegate::OnGuestDetached when a render frame is
|
||||
// deleted.
|
||||
void OnRenderFrameDeleted(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool is_main_frame,
|
||||
bool is_guest_view);
|
||||
|
||||
private:
|
||||
friend class CefRequestContext;
|
||||
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
#include "net/ssl/client_cert_store_mac.h"
|
||||
#endif
|
||||
|
||||
CefResourceContext::CefResourceContext(
|
||||
bool is_off_the_record,
|
||||
CefRefPtr<CefRequestContextHandler> handler)
|
||||
: is_off_the_record_(is_off_the_record), handler_(handler) {}
|
||||
CefResourceContext::CefResourceContext(bool is_off_the_record)
|
||||
: is_off_the_record_(is_off_the_record) {}
|
||||
|
||||
CefResourceContext::~CefResourceContext() {}
|
||||
|
||||
|
@ -55,6 +53,52 @@ void CefResourceContext::set_extensions_info_map(
|
|||
extension_info_map_ = extensions_info_map;
|
||||
}
|
||||
|
||||
void CefResourceContext::AddHandler(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
CefRefPtr<CefRequestContextHandler> handler) {
|
||||
CEF_REQUIRE_IOT();
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
DCHECK(handler);
|
||||
|
||||
handler_map_.insert(std::make_pair(
|
||||
std::make_pair(render_process_id, render_frame_id), handler));
|
||||
}
|
||||
|
||||
void CefResourceContext::RemoveHandler(int render_process_id,
|
||||
int render_frame_id) {
|
||||
CEF_REQUIRE_IOT();
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
|
||||
HandlerMap::iterator it =
|
||||
handler_map_.find(std::make_pair(render_process_id, render_frame_id));
|
||||
if (it != handler_map_.end())
|
||||
handler_map_.erase(it);
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContextHandler> CefResourceContext::GetHandler(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
bool require_frame_match) {
|
||||
CEF_REQUIRE_IOT();
|
||||
DCHECK_GE(render_process_id, 0);
|
||||
|
||||
HandlerMap::const_iterator it =
|
||||
handler_map_.find(std::make_pair(render_process_id, render_frame_id));
|
||||
if (it != handler_map_.end())
|
||||
return it->second;
|
||||
|
||||
if (!require_frame_match) {
|
||||
// Choose an arbitrary handler for the same process.
|
||||
for (auto& kv : handler_map_) {
|
||||
if (kv.first.first == render_process_id)
|
||||
return kv.second;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefResourceContext::AddPluginLoadDecision(
|
||||
int render_process_id,
|
||||
const base::FilePath& plugin_path,
|
||||
|
|
|
@ -28,14 +28,25 @@ class CefURLRequestContextGetter;
|
|||
// See browser_context.h for an object relationship diagram.
|
||||
class CefResourceContext : public content::ResourceContext {
|
||||
public:
|
||||
CefResourceContext(bool is_off_the_record,
|
||||
CefRefPtr<CefRequestContextHandler> handler);
|
||||
explicit CefResourceContext(bool is_off_the_record);
|
||||
~CefResourceContext() override;
|
||||
|
||||
std::unique_ptr<net::ClientCertStore> CreateClientCertStore();
|
||||
|
||||
void set_extensions_info_map(extensions::InfoMap* extensions_info_map);
|
||||
|
||||
// Keep track of handlers associated with specific frames. This information
|
||||
// originates from frame create/delete notifications in CefBrowserHostImpl or
|
||||
// CefMimeHandlerViewGuestDelegate which are forwarded via
|
||||
// CefRequestContextImpl and CefBrowserContext.
|
||||
void AddHandler(int render_process_id,
|
||||
int render_frame_id,
|
||||
CefRefPtr<CefRequestContextHandler> handler);
|
||||
void RemoveHandler(int render_process_id, int render_frame_id);
|
||||
CefRefPtr<CefRequestContextHandler> GetHandler(int render_process_id,
|
||||
int render_frame_id,
|
||||
bool require_frame_match);
|
||||
|
||||
// Remember the plugin load decision for plugin status requests that arrive
|
||||
// via CefPluginServiceFilter::IsPluginAvailable.
|
||||
void AddPluginLoadDecision(int render_process_id,
|
||||
|
@ -58,13 +69,16 @@ class CefResourceContext : public content::ResourceContext {
|
|||
const extensions::InfoMap* GetExtensionInfoMap() const {
|
||||
return extension_info_map_.get();
|
||||
}
|
||||
CefRefPtr<CefRequestContextHandler> GetHandler() const { return handler_; }
|
||||
|
||||
private:
|
||||
// Only accessed on the IO thread.
|
||||
bool is_off_the_record_;
|
||||
scoped_refptr<extensions::InfoMap> extension_info_map_;
|
||||
CefRefPtr<CefRequestContextHandler> handler_;
|
||||
|
||||
// Map of (render_process_id, render_frame_id) to handler.
|
||||
typedef std::map<std::pair<int, int>, CefRefPtr<CefRequestContextHandler>>
|
||||
HandlerMap;
|
||||
HandlerMap handler_map_;
|
||||
|
||||
// Map (render_process_id, plugin_path, is_main_frame, main_frame_origin) to
|
||||
// plugin load decision.
|
||||
|
|
Loading…
Reference in New Issue