Move message routing from CefBrowser to CefFrame (see issue #2498).

This change moves the SendProcessMessage method from CefBrowser to CefFrame and
adds CefBrowser parameters to OnProcessMessageReceived and
OnDraggableRegionsChanged.

The internal implementation has changed as follows:
- Frame IDs are now a 64-bit combination of the 32-bit render_process_id and
  render_routing_id values that uniquely identify a RenderFrameHost (RFH).
- CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied
  to RFH expectations. Specifically, a CefFrameHostImpl object representing a
  sub-frame will be created when a RenderFrame is created in the renderer
  process and detached when the associated RenderFrame is deleted or the
  renderer process in which it runs has died.
- The CefFrameHostImpl object representing the main frame will always be valid
  but the underlying RFH (and associated frame ID) may change over time as a
  result of cross-origin navigations. Despite these changes calling LoadURL on
  the main frame object in the browser process will always navigate as expected.
- Speculative RFHs, which may be created as a result of a cross-origin
  navigation and discarded if that navigation is not committed, are now handled
  correctly (e.g. ignored in most cases until they're committed).
- It is less likely, but still possible, to receive a CefFrame object with an
  invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet
  been created for a sub-frame. For example, when OnBeforeBrowse is called
  before initiating navigation in a previously nonexisting sub-frame.

To test: All tests pass with NetworkService enabled and disabled.
This commit is contained in:
Marshall Greenblatt
2019-05-24 23:23:43 +03:00
parent 35295d2e27
commit 241941a44a
80 changed files with 2382 additions and 2378 deletions

View File

@@ -8,7 +8,7 @@
#include "include/cef_client.h"
#include <list>
#include <map>
#include <memory>
#include <vector>
@@ -80,7 +80,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
void GetCustomWebContentsView(
const GURL& target_url,
int opener_render_process_id,
int opener_render_frame_id,
int opener_render_routing_id,
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view);
@@ -89,7 +89,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
void WebContentsCreated(
const GURL& target_url,
int opener_render_process_id,
int opener_render_frame_id,
int opener_render_routing_id,
CefBrowserSettings& settings,
CefRefPtr<CefClient>& client,
std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
@@ -103,7 +103,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_frame_routing_id,
int render_routing_id,
IPC::Message* reply_msg);
// Called from CefBrowserHostImpl::DestroyBrowser() when a browser is
@@ -113,27 +113,30 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Called from CefContext::FinishShutdownOnUIThread() to destroy all browsers.
void DestroyAllBrowsers();
// 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::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> GetBrowserInfoForFrame(int render_process_id,
int render_routing_id,
bool* is_guest_view);
// Returns the CefBrowserInfo matching the specified IDs or nullptr if no
// match is found. It is allowed to add new callers of this method but
// consider using CefBrowserHostImpl::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);
// 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.
// 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 CefBrowserHostImpl::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);
int frame_tree_node_id,
bool* is_guest_view = nullptr);
// Retrieves all existing CefBrowserInfo objects.
// Returns all existing CefBrowserInfo objects.
typedef std::list<scoped_refptr<CefBrowserInfo>> BrowserInfoList;
void GetBrowserInfoList(BrowserInfoList& list);
BrowserInfoList GetBrowserInfoList();
private:
// RenderProcessHostObserver methods:
@@ -164,8 +167,8 @@ 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_process_id;
int opener_frame_id;
int opener_render_process_id;
int opener_render_routing_id;
GURL target_url;
std::string target_frame_name;
@@ -182,13 +185,13 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
void PushPendingPopup(std::unique_ptr<PendingPopup> popup);
std::unique_ptr<PendingPopup> PopPendingPopup(PendingPopup::Step step,
int opener_process_id,
int opener_frame_id,
int opener_routing_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_frame_process_id,
int render_frame_routing_id,
scoped_refptr<CefBrowserInfo> GetBrowserInfo(int render_process_id,
int render_routing_id,
bool* is_guest_view);
// Send the response for a pending OnGetNewBrowserInfo request.
@@ -201,7 +204,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Pending request for OnGetNewBrowserInfo.
struct PendingNewBrowserInfo {
int render_process_id;
int render_frame_routing_id;
int render_routing_id;
IPC::Message* reply_msg;
};
@@ -212,9 +215,10 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
BrowserInfoList browser_info_list_;
int next_browser_id_;
using PendingNewBrowserInfoList =
std::vector<std::unique_ptr<PendingNewBrowserInfo>>;
PendingNewBrowserInfoList pending_new_browser_info_list_;
// Map of frame ID to info.
using PendingNewBrowserInfoMap =
std::map<int64_t, std::unique_ptr<PendingNewBrowserInfo>>;
PendingNewBrowserInfoMap pending_new_browser_info_map_;
// Only accessed on the UI thread.
using PendingPopupList = std::vector<std::unique_ptr<PendingPopup>>;