Remove usage of FrameTreeNode IDs (see issue #2421)

With the introduction of prerendering in Chromium it is now possible for
RenderFrameHosts (RFH) to move between FrameTrees. As a consequence we can no
longer rely on FrameTreeNode IDs to uniquely identify a RFH over its lifespan.
We must now switch to using GlobalRenderFrameHostId (child_id, frame_routing_id)
instead for that purpose. Additionally, we simplify existing code by using the
GlobalRenderFrameHostId struct in all places that previously used a
(render_process_id, render_frame_id) pair, since these concepts are equivalent.

See https://crbug.com/1179502#c8 for additional background.
This commit is contained in:
Marshall Greenblatt
2021-08-19 17:07:44 -04:00
parent cfdec92624
commit 955097ea77
33 changed files with 506 additions and 781 deletions

View File

@ -17,6 +17,7 @@
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "cef/libcef/common/mojom/cef.mojom.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_process_host_observer.h"
#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
#include "ui/base/window_open_disposition.h"
@ -79,8 +80,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// only). See comments on PendingPopup for more information.
void GetCustomWebContentsView(
const GURL& target_url,
int opener_render_process_id,
int opener_render_routing_id,
const content::GlobalRenderFrameHostId& opener_global_id,
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view);
@ -88,8 +88,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// PendingPopup for more information.
void WebContentsCreated(
const GURL& target_url,
int opener_render_process_id,
int opener_render_routing_id,
const content::GlobalRenderFrameHostId& opener_global_id,
CefBrowserSettings& settings,
CefRefPtr<CefClient>& client,
std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
@ -103,8 +102,7 @@ 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_routing_id,
const content::GlobalRenderFrameHostId& global_id,
cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback);
// Called from CefBrowserHostBase::DestroyBrowser() when a browser is
@ -114,25 +112,14 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Called from CefContext::FinishShutdownOnUIThread() to destroy all browsers.
void DestroyAllBrowsers();
// Returns the CefBrowserInfo matching the specified IDs or nullptr if no
// Returns the CefBrowserInfo matching the specified ID or nullptr if no
// match is found. It is allowed to add new callers of this method but
// consider using CefBrowserHostBase::GetBrowserForFrameRoute() or
// extensions::GetOwnerBrowserForFrameRoute() instead. If |is_guest_view| is
// non-nullptr it 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> GetBrowserInfoForFrameRoute(
int render_process_id,
int render_routing_id,
bool* is_guest_view = nullptr);
// Returns the CefBrowserInfo matching the specified ID or nullptr if no match
// is found. It is allowed to add new callers of this method but consider
// using CefBrowserHostBase::GetBrowserForFrameTreeNode() instead. If
// |is_guest_view| is non-nullptr it 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> GetBrowserInfoForFrameTreeNode(
int frame_tree_node_id,
// consider using CefBrowserHostBase::GetBrowserForGlobalId() or
// extensions::GetOwnerBrowserForGlobalId() instead. If |is_guest_view| is
// non-nullptr it will be set to true if the ID matches a guest view
// associated with the returned browser info instead of the browser itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfo(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view = nullptr);
// Returns all existing CefBrowserInfo objects.
@ -176,8 +163,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Initial state from ViewHostMsg_CreateWindow.
// |target_url| will be empty if a popup is created via window.open() and
// never navigated. For example: javascript:window.open();
int opener_render_process_id;
int opener_render_routing_id;
content::GlobalRenderFrameHostId opener_global_id;
GURL target_url;
std::string target_frame_name;
@ -192,20 +178,18 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Manage pending popups. Only called on the UI thread.
void PushPendingPopup(std::unique_ptr<PendingPopup> popup);
std::unique_ptr<PendingPopup> PopPendingPopup(PendingPopup::Step step,
int opener_process_id,
int opener_routing_id,
const GURL& target_url);
std::unique_ptr<PendingPopup> PopPendingPopup(
PendingPopup::Step step,
const content::GlobalRenderFrameHostId& opener_global_id,
const GURL& target_url);
// 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_process_id,
int render_routing_id,
bool* is_guest_view);
// Retrieves the BrowserInfo matching the specified ID.
scoped_refptr<CefBrowserInfo> GetBrowserInfoInternal(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view);
// Send the response for a pending OnGetNewBrowserInfo request.
static void SendNewBrowserInfoResponse(
int render_process_id,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_guest_view,
cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback,
@ -213,8 +197,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Pending request for OnGetNewBrowserInfo.
struct PendingNewBrowserInfo {
int render_process_id;
int render_routing_id;
content::GlobalRenderFrameHostId global_id;
int timeout_id;
cef::mojom::BrowserManager::GetNewBrowserInfoCallback callback;
scoped_refptr<base::SequencedTaskRunner> callback_runner;
@ -224,7 +207,9 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
static void CancelNewBrowserInfoResponse(PendingNewBrowserInfo* pending_info);
// Time out a response if it's still pending.
static void TimeoutNewBrowserInfoResponse(int64_t frame_id, int timeout_id);
static void TimeoutNewBrowserInfoResponse(
const content::GlobalRenderFrameHostId& global_id,
int timeout_id);
mutable base::Lock browser_info_lock_;
@ -233,9 +218,12 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
BrowserInfoList browser_info_list_;
int next_browser_id_ = 0;
// Map of frame ID to info.
// Map of global ID to info. These IDs are guaranteed to uniquely
// identify a RFH for its complete lifespan. See documentation on
// RenderFrameHost::GetFrameTreeNodeId() for background.
using PendingNewBrowserInfoMap =
std::map<int64_t, std::unique_ptr<PendingNewBrowserInfo>>;
std::map<content::GlobalRenderFrameHostId,
std::unique_ptr<PendingNewBrowserInfo>>;
PendingNewBrowserInfoMap pending_new_browser_info_map_;
// Only accessed on the UI thread.