diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 42ae7b202..4e7aed9cb 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -477,50 +477,45 @@ CefRefPtr 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::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 { - // Use the thread-safe approach. - bool is_guest_view = false; - scoped_refptr info = - CefBrowserInfoManager::GetInstance()->GetBrowserInfoForView( - render_process_id, render_routing_id, &is_guest_view); - if (info.get() && !is_guest_view) { - CefRefPtr 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; - } - return browser; +CefRefPtr CefBrowserHostImpl::GetBrowserForFrameTreeNode( + int frame_tree_node_id) { + // Use the thread-safe approach. + scoped_refptr info = + CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameTreeNode( + frame_tree_node_id); + if (info.get()) { + CefRefPtr browser = info->browser(); + if (!browser.get()) { + LOG(WARNING) << "Found browser id " << info->browser_id() + << " but no browser object matching frame tree node id " + << frame_tree_node_id; } - return nullptr; + 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(); - browser_info_->render_id_manager()->add_render_frame_id(render_process_id, - render_routing_id); + 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(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. diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index b024dc701..b65c97c5a 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -153,9 +153,9 @@ class CefBrowserHostImpl : public CefBrowserHost, // Returns the browser associated with the specified URLRequest. static CefRefPtr GetBrowserForRequest( const net::URLRequest* request); - // Returns the browser associated with the specified view routing IDs. - static CefRefPtr GetBrowserForView(int render_process_id, - int render_routing_id); + // Returns the browser associated with the specified FrameTreeNode. + static CefRefPtr GetBrowserForFrameTreeNode( + int frame_tree_node_id); // Returns the browser associated with the specified frame routing IDs. static CefRefPtr 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; diff --git a/libcef/browser/browser_info.cc b/libcef/browser/browser_info.cc index 7c128f2d4..b9c465401 100644 --- a/libcef/browser/browser_info.cc +++ b/libcef/browser/browser_info.cc @@ -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); } diff --git a/libcef/browser/browser_info.h b/libcef/browser/browser_info.h index 0f1646c6c..7d52ecec1 100644 --- a/libcef/browser/browser_info.h +++ b/libcef/browser/browser_info.h @@ -28,50 +28,61 @@ class CefBrowserInfo : public base::RefCountedThreadSafe { 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> 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 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 { 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 browser() const; void set_browser(CefRefPtr browser); @@ -107,6 +123,8 @@ class CefBrowserInfo : public base::RefCountedThreadSafe { 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 browser_; diff --git a/libcef/browser/browser_info_manager.cc b/libcef/browser/browser_info_manager.cc index 70530ee9b..2b50180ac 100644 --- a/libcef/browser/browser_info_manager.cc +++ b/libcef/browser/browser_info_manager.cc @@ -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 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 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 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 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 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 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 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 +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& 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 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 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& 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)))) { + browser_info->guest_render_id_manager()->is_render_frame_id_match( + render_frame_process_id, render_frame_routing_id)) { if (is_guest_view) *is_guest_view = true; return browser_info; diff --git a/libcef/browser/browser_info_manager.h b/libcef/browser/browser_info_manager.h index 15a9ffc8f..aac162fca 100644 --- a/libcef/browser/browser_info_manager.h +++ b/libcef/browser/browser_info_manager.h @@ -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 GetBrowserInfoForView(int render_process_id, - int render_routing_id, - bool* is_guest_view); scoped_refptr 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 GetBrowserInfoForFrameTreeNode( + int frame_tree_node_id); + // Retrieves all existing CefBrowserInfo objects. typedef std::list> 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 GetBrowserInfo(int render_view_process_id, - int render_view_routing_id, - int render_frame_process_id, + scoped_refptr 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; }; diff --git a/libcef/browser/browser_message_filter.cc b/libcef/browser/browser_message_filter.cc index f738f93d2..853a0590f 100644 --- a/libcef/browser/browser_message_filter.cc +++ b/libcef/browser/browser_message_filter.cc @@ -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; } diff --git a/libcef/browser/browser_message_filter.h b/libcef/browser/browser_message_filter.h index 57cae8191..c4a28e435 100644 --- a/libcef/browser/browser_message_filter.h +++ b/libcef/browser/browser_message_filter.h @@ -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_; diff --git a/libcef/browser/extensions/mime_handler_view_guest_delegate.cc b/libcef/browser/extensions/mime_handler_view_guest_delegate.cc index 10c52a669..34cb6f369 100644 --- a/libcef/browser/extensions/mime_handler_view_guest_delegate.cc +++ b/libcef/browser/extensions/mime_handler_view_guest_delegate.cc @@ -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 owner_browser = GetOwnerBrowser(guest_); // Associate guest state information with the owner browser. scoped_refptr 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 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 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(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); } diff --git a/libcef/browser/net/url_request_interceptor.cc b/libcef/browser/net/url_request_interceptor.cc index 757e48ddf..034e33314 100644 --- a/libcef/browser/net/url_request_interceptor.cc +++ b/libcef/browser/net/url_request_interceptor.cc @@ -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 browser = CefBrowserHostImpl::GetBrowserForRequest(request); if (browser.get()) { diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h index 02ba89c0b..6c6502b89 100644 --- a/libcef/common/cef_messages.h +++ b/libcef/common/cef_messages.h @@ -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*/) diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index 23ce29715..618cedbb0 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -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(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 app = CefContentClient::Get()->application(); if (app.get()) { CefRefPtr handler = app->GetRenderProcessHandler(); @@ -689,9 +679,6 @@ void CefBrowserImpl::OnLoadingStateChange(bool isLoading) { } void CefBrowserImpl::OnLoadStart(blink::WebLocalFrame* frame) { - if (is_swapped_out()) - return; - CefRefPtr app = CefContentClient::Get()->application(); if (app.get()) { CefRefPtr 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 app = CefContentClient::Get()->application(); if (app.get()) { CefRefPtr 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 app = CefContentClient::Get()->application(); if (app.get()) { CefRefPtr handler = app->GetRenderProcessHandler(); diff --git a/libcef/renderer/browser_impl.h b/libcef/renderer/browser_impl.h index 9693ef519..b6ff9ae9a 100644 --- a/libcef/renderer/browser_impl.h +++ b/libcef/renderer/browser_impl.h @@ -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; diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 81abc15cb..310f71209 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -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(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, ¶ms)); + render_frame_routing_id, ¶ms)); if (params.browser_id == 0) { // The popup may have been canceled during creation. return; diff --git a/patch/patch.cfg b/patch/patch.cfg index b3ee60d8b..15cc069fa 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -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', diff --git a/patch/patches/render_view_host_impl_1392.patch b/patch/patches/render_view_host_impl_1392.patch deleted file mode 100644 index 1673e67f3..000000000 --- a/patch/patches/render_view_host_impl_1392.patch +++ /dev/null @@ -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_; }