Resolve request mapping issues with swapped out frames and browser-side navigation (issue #2290)

This commit is contained in:
Marshall Greenblatt 2017-10-26 14:17:00 -04:00
parent 2733a561e4
commit 4787b45db2
16 changed files with 245 additions and 286 deletions

View File

@ -477,50 +477,45 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForRequest(
const net::URLRequest* request) {
DCHECK(request);
CEF_REQUIRE_IOT();
// When navigating the main frame a new (pre-commit) URLRequest will be
// created before the RenderFrameHost. Consequently we can't rely on
// ResourceRequestInfo::GetRenderFrameForRequest returning a valid frame
// ID. See https://crbug.com/776884 for background.
int render_process_id = -1;
int render_frame_id = MSG_ROUTING_NONE;
if (!content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id) ||
render_process_id == -1 || render_frame_id == MSG_ROUTING_NONE) {
return nullptr;
if (content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id) &&
render_process_id >= 0 && render_frame_id >= 0) {
return GetBrowserForFrame(render_process_id, render_frame_id);
}
return GetBrowserForFrame(render_process_id, render_frame_id);
const content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(request);
if (request_info)
return GetBrowserForFrameTreeNode(request_info->GetFrameTreeNodeId());
return nullptr;
}
// static
CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForView(
int render_process_id,
int render_routing_id) {
if (render_process_id == -1 || render_routing_id == MSG_ROUTING_NONE)
return nullptr;
if (CEF_CURRENTLY_ON_UIT()) {
// Use the non-thread-safe but potentially faster approach.
content::RenderViewHost* render_view_host =
content::RenderViewHost::FromID(render_process_id, render_routing_id);
if (!render_view_host)
return nullptr;
return GetBrowserForHost(render_view_host);
} else {
CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForFrameTreeNode(
int frame_tree_node_id) {
// Use the thread-safe approach.
bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->GetBrowserInfoForView(
render_process_id, render_routing_id, &is_guest_view);
if (info.get() && !is_guest_view) {
CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameTreeNode(
frame_tree_node_id);
if (info.get()) {
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id()
<< " but no browser object matching view process id "
<< render_process_id << " and routing id "
<< render_routing_id;
<< " but no browser object matching frame tree node id "
<< frame_tree_node_id;
}
return browser;
}
return nullptr;
}
}
// static
@ -2591,17 +2586,39 @@ void CefBrowserHostImpl::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
const int render_process_id = render_frame_host->GetProcess()->GetID();
const int render_routing_id = render_frame_host->GetRoutingID();
if (!browser_info_->render_id_manager()->is_render_frame_id_match(
render_process_id, render_routing_id)) {
browser_info_->render_id_manager()->add_render_frame_id(render_process_id,
render_routing_id);
}
const int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId();
if (!browser_info_->frame_tree_node_id_manager()->is_frame_tree_node_id_match(
frame_tree_node_id)) {
browser_info_->frame_tree_node_id_manager()->add_frame_tree_node_id(
frame_tree_node_id);
}
}
void CefBrowserHostImpl::RenderFrameDeleted(
void CefBrowserHostImpl::RenderFrameHostChanged(
content::RenderFrameHost* old_host,
content::RenderFrameHost* new_host) {
// Just in case RenderFrameCreated wasn't called for some reason.
RenderFrameCreated(new_host);
}
void CefBrowserHostImpl::FrameDeleted(
content::RenderFrameHost* render_frame_host) {
// The ID entries should currently exist.
const int render_process_id = render_frame_host->GetProcess()->GetID();
const int render_routing_id = render_frame_host->GetRoutingID();
browser_info_->render_id_manager()->remove_render_frame_id(render_process_id,
render_routing_id);
const int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId();
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 =
@ -2611,18 +2628,24 @@ void CefBrowserHostImpl::RenderFrameDeleted(
is_main_frame, false);
}
}
base::AutoLock lock_scope(state_lock_);
const int64 frame_id = render_frame_host->GetRoutingID();
FrameMap::iterator it = frames_.find(frame_id);
if (it != frames_.end()) {
it->second->Detach();
frames_.erase(it);
}
if (main_frame_id_ == frame_id)
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
if (focused_frame_id_ == frame_id)
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
}
void CefBrowserHostImpl::RenderViewCreated(
content::RenderViewHost* render_view_host) {
// As of https://crrev.com/27caae83 this notification will be sent for RVHs
// created for provisional main frame navigations.
const int render_process_id = render_view_host->GetProcess()->GetID();
const int render_routing_id = render_view_host->GetRoutingID();
browser_info_->render_id_manager()->add_render_view_id(render_process_id,
render_routing_id);
// May be already registered if the renderer crashed previously.
if (!registrar_->IsRegistered(
this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
@ -2636,11 +2659,6 @@ void CefBrowserHostImpl::RenderViewCreated(
void CefBrowserHostImpl::RenderViewDeleted(
content::RenderViewHost* render_view_host) {
const int render_process_id = render_view_host->GetProcess()->GetID();
const int render_routing_id = render_view_host->GetRoutingID();
browser_info_->render_id_manager()->remove_render_view_id(render_process_id,
render_routing_id);
if (registrar_->IsRegistered(
this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
content::Source<content::RenderViewHost>(render_view_host))) {
@ -2757,23 +2775,6 @@ void CefBrowserHostImpl::DidFailLoad(
OnLoadEnd(frame, validated_url, error_code);
}
void CefBrowserHostImpl::FrameDeleted(
content::RenderFrameHost* render_frame_host) {
base::AutoLock lock_scope(state_lock_);
const int64 frame_id = render_frame_host->GetRoutingID();
FrameMap::iterator it = frames_.find(frame_id);
if (it != frames_.end()) {
it->second->Detach();
frames_.erase(it);
}
if (main_frame_id_ == frame_id)
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
if (focused_frame_id_ == frame_id)
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
}
void CefBrowserHostImpl::TitleWasSet(content::NavigationEntry* entry) {
// |entry| may be NULL if a popup is created via window.open and never
// navigated.

View File

@ -153,9 +153,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Returns the browser associated with the specified URLRequest.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForRequest(
const net::URLRequest* request);
// Returns the browser associated with the specified view routing IDs.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForView(int render_process_id,
int render_routing_id);
// Returns the browser associated with the specified FrameTreeNode.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForFrameTreeNode(
int frame_tree_node_id);
// Returns the browser associated with the specified frame routing IDs.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForFrame(
int render_process_id,
@ -485,7 +485,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
using content::WebContentsObserver::BeforeUnloadFired;
using content::WebContentsObserver::WasHidden;
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void RenderFrameHostChanged(content::RenderFrameHost* old_host,
content::RenderFrameHost* new_host) override;
void FrameDeleted(content::RenderFrameHost* render_frame_host) override;
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void RenderViewDeleted(content::RenderViewHost* render_view_host) override;
void RenderViewReady() override;
@ -497,7 +499,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
void FrameDeleted(content::RenderFrameHost* render_frame_host) override;
void TitleWasSet(content::NavigationEntry* entry) override;
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override;

View File

@ -16,91 +16,104 @@ CefBrowserInfo::RenderIDManager::RenderIDManager(base::Lock* lock)
DCHECK(lock);
}
void CefBrowserInfo::RenderIDManager::add_render_view_id(
int render_process_id,
int render_routing_id) {
add_render_id(&render_view_id_set_, render_process_id, render_routing_id);
}
void CefBrowserInfo::RenderIDManager::add_render_frame_id(
int render_process_id,
int render_routing_id) {
add_render_id(&render_frame_id_set_, render_process_id, render_routing_id);
}
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
void CefBrowserInfo::RenderIDManager::remove_render_view_id(
int render_process_id,
int render_routing_id) {
remove_render_id(&render_view_id_set_, render_process_id, render_routing_id);
base::AutoLock lock_scope(*lock_);
if (!render_frame_id_set_.empty()) {
RenderIdSet::const_iterator it = render_frame_id_set_.find(
std::make_pair(render_process_id, render_routing_id));
DCHECK(it == render_frame_id_set_.end());
if (it != render_frame_id_set_.end())
return;
}
render_frame_id_set_.insert(
std::make_pair(render_process_id, render_routing_id));
}
void CefBrowserInfo::RenderIDManager::remove_render_frame_id(
int render_process_id,
int render_routing_id) {
remove_render_id(&render_frame_id_set_, render_process_id, render_routing_id);
}
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
bool CefBrowserInfo::RenderIDManager::is_render_view_id_match(
int render_process_id,
int render_routing_id) const {
return is_render_id_match(&render_view_id_set_, render_process_id,
render_routing_id);
base::AutoLock lock_scope(*lock_);
DCHECK(!render_frame_id_set_.empty());
if (render_frame_id_set_.empty())
return;
bool erased = render_frame_id_set_.erase(
std::make_pair(render_process_id, render_routing_id)) != 0;
DCHECK(erased);
}
bool CefBrowserInfo::RenderIDManager::is_render_frame_id_match(
int render_process_id,
int render_routing_id) const {
return is_render_id_match(&render_frame_id_set_, render_process_id,
render_routing_id);
base::AutoLock lock_scope(*lock_);
if (render_frame_id_set_.empty())
return false;
RenderIdSet::const_iterator it = render_frame_id_set_.find(
std::make_pair(render_process_id, render_routing_id));
return (it != render_frame_id_set_.end());
}
void CefBrowserInfo::RenderIDManager::add_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id) {
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
// CefBrowserInfo::FrameTreeNodeIDManager
CefBrowserInfo::FrameTreeNodeIDManager::FrameTreeNodeIDManager(base::Lock* lock)
: lock_(lock) {
DCHECK(lock);
}
void CefBrowserInfo::FrameTreeNodeIDManager::add_frame_tree_node_id(
int frame_tree_node_id) {
DCHECK_GE(frame_tree_node_id, 0);
base::AutoLock lock_scope(*lock_);
if (!id_set->empty()) {
RenderIdSet::const_iterator it =
id_set->find(std::make_pair(render_process_id, render_routing_id));
if (it != id_set->end())
if (!frame_tree_node_id_set_.empty()) {
FrameTreeNodeIdSet::const_iterator it =
frame_tree_node_id_set_.find(frame_tree_node_id);
DCHECK(it == frame_tree_node_id_set_.end());
if (it != frame_tree_node_id_set_.end())
return;
}
id_set->insert(std::make_pair(render_process_id, render_routing_id));
frame_tree_node_id_set_.insert(frame_tree_node_id);
}
void CefBrowserInfo::RenderIDManager::remove_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id) {
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
void CefBrowserInfo::FrameTreeNodeIDManager::remove_frame_tree_node_id(
int frame_tree_node_id) {
DCHECK_GE(frame_tree_node_id, 0);
base::AutoLock lock_scope(*lock_);
DCHECK(!id_set->empty());
if (id_set->empty())
DCHECK(!frame_tree_node_id_set_.empty());
if (frame_tree_node_id_set_.empty())
return;
bool erased =
id_set->erase(std::make_pair(render_process_id, render_routing_id)) != 0;
bool erased = frame_tree_node_id_set_.erase(frame_tree_node_id) != 0;
DCHECK(erased);
}
bool CefBrowserInfo::RenderIDManager::is_render_id_match(
const RenderIdSet* id_set,
int render_process_id,
int render_routing_id) const {
bool CefBrowserInfo::FrameTreeNodeIDManager::is_frame_tree_node_id_match(
int frame_tree_node_id) const {
base::AutoLock lock_scope(*lock_);
if (id_set->empty())
if (frame_tree_node_id_set_.empty())
return false;
RenderIdSet::const_iterator it =
id_set->find(std::make_pair(render_process_id, render_routing_id));
return (it != id_set->end());
FrameTreeNodeIdSet::const_iterator it =
frame_tree_node_id_set_.find(frame_tree_node_id);
return (it != frame_tree_node_id_set_.end());
}
// CefBrowserInfo
@ -110,7 +123,8 @@ CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
is_popup_(is_popup),
is_windowless_(false),
render_id_manager_(&lock_),
guest_render_id_manager_(&lock_) {
guest_render_id_manager_(&lock_),
frame_tree_node_id_manager_(&lock_) {
DCHECK_GT(browser_id, 0);
}

View File

@ -28,50 +28,61 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
explicit RenderIDManager(base::Lock* lock);
// Adds an ID pair if it doesn't already exist.
void add_render_view_id(int render_process_id, int render_routing_id);
void add_render_frame_id(int render_process_id, int render_routing_id);
// Remove an ID pair if it exists.
void remove_render_view_id(int render_process_id, int render_routing_id);
void remove_render_frame_id(int render_process_id, int render_routing_id);
// Returns true if this browser matches the specified ID pair.
bool is_render_view_id_match(int render_process_id,
int render_routing_id) const;
bool is_render_frame_id_match(int render_process_id,
int render_routing_id) const;
private:
typedef std::set<std::pair<int, int>> RenderIdSet;
void add_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id);
void remove_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id);
bool is_render_id_match(const RenderIdSet* id_set,
int render_process_id,
int render_routing_id) const;
// Access to |render_frame_id_set_| must be protected by |lock_|.
mutable base::Lock* lock_;
// The below members must be protected by |lock_|.
// Set of mapped (process_id, routing_id) pairs. Keeping this set is
// necessary for the following reasons:
// 1. When navigating cross-origin the new (pending) RenderViewHost will be
// created before the old (current) RenderViewHost is destroyed.
// 1. When navigating cross-origin the new (pending) RenderFrameHost will be
// created before the old (current) RenderFrameHost is destroyed.
// 2. When canceling and asynchronously continuing navigation of the same
// URL a new RenderViewHost may be created for the first (canceled)
// URL a new RenderFrameHost may be created for the first (canceled)
// navigation and then destroyed as a result of the second (allowed)
// navigation.
// 3. Out-of-process iframes have their own render IDs which must also be
// associated with the host browser.
RenderIdSet render_view_id_set_;
RenderIdSet render_frame_id_set_;
};
class FrameTreeNodeIDManager {
public:
explicit FrameTreeNodeIDManager(base::Lock* lock);
// Adds an ID if it doesn't already exist.
void add_frame_tree_node_id(int frame_tree_node_id);
// Remove an ID if it exists.
void remove_frame_tree_node_id(int frame_tree_node_id);
// Returns true if this browser matches the specified ID.
bool is_frame_tree_node_id_match(int frame_tree_node_id) const;
private:
typedef std::set<int> FrameTreeNodeIdSet;
// Access to |request_id_set_| must be protected by |lock_|.
mutable base::Lock* lock_;
// Set of mapped frame_tree_node_id values. Keeping this set is necessary
// because, when navigating the main frame, a new (pre-commit) URLRequest
// will be created before the RenderFrameHost. Consequently we can't rely
// on ResourceRequestInfo::GetRenderFrameForRequest returning a valid frame
// ID. See https://crbug.com/776884 for background.
FrameTreeNodeIdSet frame_tree_node_id_set_;
};
CefBrowserInfo(int browser_id, bool is_popup);
int browser_id() const { return browser_id_; };
@ -88,6 +99,11 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
return &guest_render_id_manager_;
}
// Returns the frame tree node ID manager for this browser.
FrameTreeNodeIDManager* frame_tree_node_id_manager() {
return &frame_tree_node_id_manager_;
}
CefRefPtr<CefBrowserHostImpl> browser() const;
void set_browser(CefRefPtr<CefBrowserHostImpl> browser);
@ -107,6 +123,8 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
RenderIDManager render_id_manager_;
RenderIDManager guest_render_id_manager_;
FrameTreeNodeIDManager frame_tree_node_id_manager_;
// May be NULL if the browser has not yet been created or if the browser has
// been destroyed.
CefRefPtr<CefBrowserHostImpl> browser_;

View File

@ -17,7 +17,6 @@
#include "content/common/view_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"
@ -79,23 +78,12 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
bool is_windowless) {
base::AutoLock lock_scope(browser_info_lock_);
content::RenderViewHost* view_host = new_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = new_contents->GetMainFrame();
content::RenderProcessHost* host = view_host->GetProcess();
// The host processes may be different in the future with OOP iframes. When
// that happens re-visit the implementation of this class.
DCHECK_EQ(host, main_frame_host->GetProcess());
const int render_process_id = host->GetID();
const int render_view_routing_id = view_host->GetRoutingID();
const int render_frame_routing_id = main_frame_host->GetRoutingID();
content::RenderFrameHost* frame_host = new_contents->GetMainFrame();
const int render_process_id = frame_host->GetProcess()->GetID();
const int render_frame_routing_id = frame_host->GetRoutingID();
scoped_refptr<CefBrowserInfo> browser_info =
new CefBrowserInfo(++next_browser_id_, true);
browser_info->render_id_manager()->add_render_view_id(render_process_id,
render_view_routing_id);
browser_info->render_id_manager()->add_render_frame_id(
render_process_id, render_frame_routing_id);
browser_info_list_.push_back(browser_info);
@ -109,7 +97,6 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
for (; it != pending_new_browser_info_list_.end(); ++it) {
PendingNewBrowserInfo* info = it->get();
if (info->render_process_id == render_process_id &&
info->render_view_routing_id == render_view_routing_id &&
info->render_frame_routing_id == render_frame_routing_id) {
SendNewBrowserInfoResponse(render_process_id, browser_info, false,
info->reply_msg);
@ -281,11 +268,9 @@ void CefBrowserInfoManager::WebContentsCreated(
}
void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id,
int render_view_routing_id,
int render_frame_routing_id,
IPC::Message* reply_msg) {
DCHECK_NE(render_process_id, content::ChildProcessHost::kInvalidUniqueID);
DCHECK_GT(render_view_routing_id, 0);
DCHECK_GT(render_frame_routing_id, 0);
DCHECK(reply_msg);
@ -294,8 +279,7 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id,
bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> browser_info = GetBrowserInfo(
render_process_id, render_view_routing_id, render_process_id,
render_frame_routing_id, &is_guest_view);
render_process_id, render_frame_routing_id, &is_guest_view);
if (browser_info.get()) {
// Send the response immediately.
@ -312,7 +296,6 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id,
for (; it != pending_new_browser_info_list_.end(); ++it) {
PendingNewBrowserInfo* info = it->get();
if (info->render_process_id == render_process_id &&
info->render_view_routing_id == render_view_routing_id &&
info->render_frame_routing_id == render_frame_routing_id) {
NOTREACHED();
}
@ -323,7 +306,6 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id,
// Queue the request.
std::unique_ptr<PendingNewBrowserInfo> pending(new PendingNewBrowserInfo());
pending->render_process_id = render_process_id;
pending->render_view_routing_id = render_view_routing_id;
pending->render_frame_routing_id = render_frame_routing_id;
pending->reply_msg = reply_msg;
pending_new_browser_info_list_.push_back(std::move(pending));
@ -374,22 +356,31 @@ void CefBrowserInfoManager::DestroyAllBrowsers() {
#endif
}
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfoForView(
int render_process_id,
int render_routing_id,
bool* is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
return GetBrowserInfo(render_process_id, render_routing_id, 0, 0,
is_guest_view);
}
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfoForFrame(
int render_process_id,
int render_routing_id,
bool* is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
return GetBrowserInfo(0, 0, render_process_id, render_routing_id,
is_guest_view);
return GetBrowserInfo(render_process_id, render_routing_id, is_guest_view);
}
scoped_refptr<CefBrowserInfo>
CefBrowserInfoManager::GetBrowserInfoForFrameTreeNode(int frame_tree_node_id) {
if (frame_tree_node_id < 0)
return nullptr;
base::AutoLock lock_scope(browser_info_lock_);
BrowserInfoList::const_iterator it = browser_info_list_.begin();
for (; it != browser_info_list_.end(); ++it) {
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
if (browser_info->frame_tree_node_id_manager()->is_frame_tree_node_id_match(
frame_tree_node_id)) {
return browser_info;
}
}
return nullptr;
}
void CefBrowserInfoManager::GetBrowserInfoList(BrowserInfoList& list) {
@ -465,8 +456,6 @@ CefBrowserInfoManager::PopPendingPopup(PendingPopup::Step step,
}
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfo(
int render_view_process_id,
int render_view_routing_id,
int render_frame_process_id,
int render_frame_routing_id,
bool* is_guest_view) {
@ -475,41 +464,19 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfo(
if (is_guest_view)
*is_guest_view = false;
const bool valid_view_ids =
render_view_process_id > 0 && render_view_routing_id > 0;
const bool valid_frame_ids =
render_frame_process_id > 0 && render_frame_routing_id > 0;
if (render_frame_process_id < 0 || render_frame_routing_id < 0)
return nullptr;
BrowserInfoList::const_iterator it = browser_info_list_.begin();
for (; it != browser_info_list_.end(); ++it) {
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
if (valid_view_ids &&
browser_info->render_id_manager()->is_render_view_id_match(
render_view_process_id, render_view_routing_id)) {
if (valid_frame_ids) {
// Make sure the frame id is also registered.
browser_info->render_id_manager()->add_render_frame_id(
render_frame_process_id, render_frame_routing_id);
}
return browser_info;
}
if (valid_frame_ids &&
browser_info->render_id_manager()->is_render_frame_id_match(
if (browser_info->render_id_manager()->is_render_frame_id_match(
render_frame_process_id, render_frame_routing_id)) {
if (valid_view_ids) {
// Make sure the view id is also registered.
browser_info->render_id_manager()->add_render_view_id(
render_view_process_id, render_view_routing_id);
}
return browser_info;
}
if (extensions::ExtensionsEnabled() &&
((valid_view_ids &&
browser_info->guest_render_id_manager()->is_render_view_id_match(
render_view_process_id, render_view_routing_id)) ||
(valid_frame_ids &&
browser_info->guest_render_id_manager()->is_render_frame_id_match(
render_frame_process_id, render_frame_routing_id)))) {
render_frame_process_id, render_frame_routing_id)) {
if (is_guest_view)
*is_guest_view = true;
return browser_info;

View File

@ -99,7 +99,6 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// already exist for traditional popup browsers depending on timing. See
// comments on PendingPopup for more information.
void OnGetNewBrowserInfo(int render_process_id,
int render_view_routing_id,
int render_frame_routing_id,
IPC::Message* reply_msg);
@ -112,17 +111,22 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Retrieves the CefBrowserInfo matching the specified IDs or an empty
// pointer if no match is found. It is allowed to add new callers of this
// method but consider using CefBrowserHostImpl::GetBrowserFor[View|Frame]()
// method but consider using CefBrowserHostImpl::GetBrowserForFrame()
// or extensions::GetOwnerBrowserForFrame() instead.
// |is_guest_view| will be set to true if the IDs match a guest view
// associated with the returned browser info instead of the browser itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfoForView(int render_process_id,
int render_routing_id,
bool* is_guest_view);
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrame(int render_process_id,
int render_routing_id,
bool* is_guest_view);
// Retrieves the CefBrowserInfo matching the specified ID or an empty
// pointer if no match is found. It is allowed to add new callers of this
// method but consider using CefBrowserHostImpl::GetBrowserForRequest()
// instead since we generally use this mapping for URLRequests on the IO
// thread.
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrameTreeNode(
int frame_tree_node_id);
// Retrieves all existing CefBrowserInfo objects.
typedef std::list<scoped_refptr<CefBrowserInfo>> BrowserInfoList;
void GetBrowserInfoList(BrowserInfoList& list);
@ -178,9 +182,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Retrieves the BrowserInfo matching the specified IDs. If both sets are
// valid then this method makes sure both sets have been registered.
scoped_refptr<CefBrowserInfo> GetBrowserInfo(int render_view_process_id,
int render_view_routing_id,
int render_frame_process_id,
scoped_refptr<CefBrowserInfo> GetBrowserInfo(int render_frame_process_id,
int render_frame_routing_id,
bool* is_guest_view);
@ -194,7 +196,6 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Pending request for OnGetNewBrowserInfo.
struct PendingNewBrowserInfo {
int render_process_id;
int render_view_routing_id;
int render_frame_routing_id;
IPC::Message* reply_msg;
};

View File

@ -56,13 +56,11 @@ void CefBrowserMessageFilter::OnGetNewRenderThreadInfo(
}
}
void CefBrowserMessageFilter::OnGetNewBrowserInfo(int render_view_routing_id,
int render_frame_routing_id,
void CefBrowserMessageFilter::OnGetNewBrowserInfo(int render_frame_routing_id,
IPC::Message* reply_msg) {
if (render_process_id_ != content::ChildProcessHost::kInvalidUniqueID) {
CefBrowserInfoManager::GetInstance()->OnGetNewBrowserInfo(
render_process_id_, render_view_routing_id, render_frame_routing_id,
reply_msg);
render_process_id_, render_frame_routing_id, reply_msg);
} else {
delete reply_msg;
}

View File

@ -29,8 +29,7 @@ class CefBrowserMessageFilter : public content::BrowserMessageFilter {
// Message handlers.
void OnGetNewRenderThreadInfo(
CefProcessHostMsg_GetNewRenderThreadInfo_Params* params);
void OnGetNewBrowserInfo(int render_view_routing_id,
int render_frame_routing_id,
void OnGetNewBrowserInfo(int render_frame_routing_id,
IPC::Message* reply_msg);
int render_process_id_;

View File

@ -54,17 +54,20 @@ void CefMimeHandlerViewGuestDelegate::OnGuestAttached(
content::WebContents* web_contents = guest_->web_contents();
DCHECK(web_contents);
content::RenderViewHost* view_host = web_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
// Associate guest state information with the owner browser.
scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info();
info->guest_render_id_manager()->add_render_view_id(
view_host->GetProcess()->GetID(), view_host->GetRoutingID());
info->guest_render_id_manager()->add_render_frame_id(
main_frame_host->GetProcess()->GetID(), main_frame_host->GetRoutingID());
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
const int render_process_id = main_frame_host->GetProcess()->GetID();
const int render_frame_id = main_frame_host->GetRoutingID();
info->guest_render_id_manager()->add_render_frame_id(render_process_id,
render_frame_id);
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);
}
void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
@ -72,25 +75,25 @@ void CefMimeHandlerViewGuestDelegate::OnGuestDetached(
content::WebContents* web_contents = guest_->web_contents();
DCHECK(web_contents);
content::RenderViewHost* view_host = web_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
const int render_process_id = main_frame_host->GetProcess()->GetID();
const int render_frame_id = main_frame_host->GetRoutingID();
const bool is_main_frame = (main_frame_host->GetParent() == nullptr);
// Disassociate guest state information with the owner browser.
scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info();
info->guest_render_id_manager()->remove_render_view_id(
view_host->GetProcess()->GetID(), view_host->GetRoutingID());
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
const int render_process_id = main_frame_host->GetProcess()->GetID();
const int render_frame_id = main_frame_host->GetRoutingID();
info->guest_render_id_manager()->remove_render_frame_id(render_process_id,
render_frame_id);
const int frame_tree_node_id = main_frame_host->GetFrameTreeNodeId();
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);
}

View File

@ -29,6 +29,12 @@ CefRequestInterceptor::~CefRequestInterceptor() {
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
// With PlzNavigate we now receive blob URLs here.
// Ignore these URLs. See https://crbug.com/776884 for details.
if (request->url().SchemeIs(url::kBlobScheme)) {
return nullptr;
}
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {

View File

@ -202,9 +202,8 @@ IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
IPC_STRUCT_END()
// Retrieve information about a newly created browser.
IPC_SYNC_MESSAGE_CONTROL2_1(
IPC_SYNC_MESSAGE_CONTROL1_1(
CefProcessHostMsg_GetNewBrowserInfo,
int /* render_view_routing_id */,
int /* render_frame_routing_id */,
CefProcessHostMsg_GetNewBrowserInfo_Params /* params*/)

View File

@ -26,7 +26,6 @@
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
@ -413,12 +412,6 @@ void CefBrowserImpl::AddFrameObject(int64_t frame_id,
manager->Add(tracked_object);
}
bool CefBrowserImpl::is_swapped_out() const {
content::RenderViewImpl* render_view_impl =
static_cast<content::RenderViewImpl*>(render_view());
return (!render_view_impl || render_view_impl->is_swapped_out());
}
// RenderViewObserver methods.
// -----------------------------------------------------------------------------
@ -668,9 +661,6 @@ void CefBrowserImpl::OnResponseAck(int request_id) {
}
void CefBrowserImpl::OnLoadingStateChange(bool isLoading) {
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
@ -689,9 +679,6 @@ void CefBrowserImpl::OnLoadingStateChange(bool isLoading) {
}
void CefBrowserImpl::OnLoadStart(blink::WebLocalFrame* frame) {
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
@ -706,9 +693,6 @@ void CefBrowserImpl::OnLoadStart(blink::WebLocalFrame* frame) {
}
void CefBrowserImpl::OnLoadEnd(blink::WebLocalFrame* frame) {
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
@ -726,9 +710,6 @@ void CefBrowserImpl::OnLoadEnd(blink::WebLocalFrame* frame) {
void CefBrowserImpl::OnLoadError(blink::WebLocalFrame* frame,
const blink::WebURLError& error) {
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();

View File

@ -105,8 +105,6 @@ class CefBrowserImpl : public CefBrowser, public content::RenderViewObserver {
return content::RenderViewObserver::render_view();
}
bool is_swapped_out() const;
// RenderViewObserver methods.
void OnDestruct() override;
void DidStartLoading() override;

View File

@ -73,7 +73,6 @@
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
#include "extensions/common/switches.h"
#include "extensions/renderer/renderer_extension_registry.h"
@ -837,27 +836,18 @@ void CefContentRendererClient::BrowserCreated(
if (!render_view || !render_frame)
return;
// Swapped out RenderWidgets will be created in the parent/owner process for
// frames that are hosted in a separate process (e.g. guest views or OOP
// frames). Don't create any CEF objects for swapped out RenderWidgets.
content::RenderFrameImpl* render_frame_impl =
static_cast<content::RenderFrameImpl*>(render_frame);
if (render_frame_impl->GetRenderWidget()->is_swapped_out())
return;
// Don't create another browser or guest view object if one already exists for
// the view.
if (GetBrowserForView(render_view).get() || HasGuestViewForView(render_view))
return;
const int render_view_routing_id = render_view->GetRoutingID();
const int render_frame_routing_id = render_frame->GetRoutingID();
// Retrieve the browser information synchronously. This will also register
// the routing ids with the browser info object in the browser process.
CefProcessHostMsg_GetNewBrowserInfo_Params params;
content::RenderThread::Get()->Send(new CefProcessHostMsg_GetNewBrowserInfo(
render_view_routing_id, render_frame_routing_id, &params));
render_frame_routing_id, &params));
if (params.browser_id == 0) {
// The popup may have been canceled during creation.
return;

View File

@ -215,11 +215,6 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2102
'name': 'views_1749_2102',
},
{
# Expose RenderViewHostImpl swapped-out state.
# https://bitbucket.org/chromiumembedded/cef/issues/1392
'name': 'render_view_host_impl_1392',
},
{
# Expose ui::Compositor via BrowserCompositorMac for OSR.
'name': 'browser_compositor_mac',

View File

@ -1,12 +0,0 @@
diff --git content/browser/renderer_host/render_view_host_impl.h content/browser/renderer_host/render_view_host_impl.h
index 071ed012bada..0957d5dda328 100644
--- content/browser/renderer_host/render_view_host_impl.h
+++ content/browser/renderer_host/render_view_host_impl.h
@@ -158,6 +158,7 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
void set_is_swapped_out(bool is_swapped_out) {
is_swapped_out_ = is_swapped_out;
}
+ bool is_swapped_out() const { return is_swapped_out_; }
// TODO(creis): Remove as part of http://crbug.com/418265.
bool is_waiting_for_close_ack() const { return is_waiting_for_close_ack_; }