Frame identifiers have changed from int64_t to string type. This is due
to https://crbug.com/1502660 which removes access to frame routing IDs
in the renderer process. New cross-process frame identifiers are 160-bit
values (32-bit child process ID + 128-bit local frame token) and most
easily represented as strings. All other frame-related expectations and
behaviors remain the same.
Write access to the shared memory region is required because JavaScript lacks
the capability to create read-only ArrayBuffers. When a user attempts to modify
an ArrayBuffer that utilizes a ReadOnlySharedMemoryRegion as its BackingStore
it triggers an access violation.
Note that this pull request may be reverted in the future if JavaScript adds
read-only ArrayBuffer support.
Run with "--vmodule=frame_*=1 --enable-logging=stderr --no-sandbox" on the
command-line to see these log messages from both the browser and renderer
processes.
CefSharedProcessMessageBuilder supports creation of a CefProcessMessage
backed by a CefSharedMemoryRegion.
Performance tests comparing the existing ArgumentList approach and the new
SharedMemoryRegion approach have been added to cefclient at
http://tests/ipc_performance.
CefMessageRouter has been updated to use SharedMemoryRegion as transport
for larger message payloads. The threshold is configurable via
|CefMessageRouterConfig.message_size_threshold|.
To test:
run `ceftests --gtest_filter=SendSharedProcessMessageTest.*:SharedProcessMessageTest.*:MessageRouterTest.Threshold*`
The mojo channel used for frame communication may disconnect for a variety of
reasons including frame navigation, frame destruction, or insertion into the
BackForwardCache (when the browser-side frame representation is destroyed and
closes the connection). When disconnect occurs we now evaluate the situation
and reconnect if appropriate.
Connections are now initiated solely from the renderer process and the
RenderFrame is passed as an argument to FrameAttached() instead of being
retrieved independently. Messages are queued while the frame is disconnected
and sent only after FrameAttachedAck() is received from the browser process.
The renderer process will be crashed intentionally with a "connection retry
failure" message if the reconnect fails 3 times in a row.
When BackForwardCache is enabled and the user navigates the main frame
back/forward a new RFH may be created for an existing main frame GlobalId value
and CefFrameHostImpl (e.g. an object that was previously Detach()ed after main
frame navigation called SetMainFrame, but for which RenderFrameDeleted was not
subsequently called due to insertion in the BackForwardCache). In this case we
can re-attach the new RFH to the existing main frame CefFrameHostImpl in
RenderFrameHostStateChanged and resume processing of messages.
Swapping back/forward to an existing (already loaded) renderer does not trigger
new notifications for draggable regions (e.g. RenderFrameObserver::
DraggableRegionsChanged is not called by default). We therefore explicitly
request an update of draggable regions by sending the DidStopLoading message to
the renderer.
A new |reattached| parameter is added to CefFrameHandler::OnFrameAttached to
support identification of BackForwardCache usage by the client.
To test with unit tests:
Run `ceftests --gtest_filter=DraggableRegionsTest.DraggableRegionsCrossOrigin
--enable-features=BackForwardCache`
To test manually:
1. Run `cefclient --enable-features=BackForwardCache --use-views
--url=http://tests/draggable`, note that draggable regions work.
2. Load https://www.google.com via the address bar, note that draggable regions
are removed.
3. Go back to http://tests/draggable, note that draggable regions work.
4. Go forward to https://www.google.com, note that draggable regions are
removed.
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.
When BackForwardCache is enabled the old RFH tree may be cached instead of being
immediately deleted as a result of main frame navigation. If a RFH is cached
then delivery of the CefFrameHandler::OnFrameDetached callback will be delayed
until the the RFH is ejected from the cache (possibly not occurring until the
browser is destroyed). This change in OnFrameDetached timing was causing
FrameHandlerTest.OrderSubCrossOrigin* to fail, and the inclusion of cached
frames in CefBrowserInfo::GetAllFrames was causing
FrameTest.NestedIframesDiffOrigin to fail.
BackForwardCache is currently being tested via field trials (see
https://crbug.com/1171298) and can be explicitly disabled using the
`--disable-back-forward-cache` or `--disable-features=BackForwardCache`
command-line flags.
See the new cef_frame_handler.h for complete usage documentation.
This change includes the following related enhancements:
- The newly added CefBrowser::IsValid method will return false (in the browser
process) after CefLifeSpanHandler::OnBeforeClose is called.
- CefBrowser::GetMainFrame will return a valid object (in the browser process)
until after CefLifeSpanHandler::OnBeforeClose is called.
- The main frame object will change during cross-origin navigation or
re-navigation after renderer process termination. During that time,
GetMainFrame will return the new/pending frame (in the browser process) and
any messages that arrive for the new/pending frame will be correctly
attributed in OnProcessMessageReceived.
- Commands to be executed in the renderer process that may fail during early
frame initialization (ExecuteJavaScript, LoadRequest, etc.) will now be
queued until after the JavaScript context for the frame has been created.
- Logging has been added for any commands that are dropped because they arrived
after frame detachment.
When navigating cross-origin a speculative RenderFrameHost (RFH) and
CefFrameHostImpl is created in the browser process for the new frame object
created in a new renderer process. The FrameAttached message then arrives for
the speculative RFH, and as a consequence interfaces are bound between the new
CefFrameHostImpl and the speculative RFH. If the pending navigation commits
then the existing RFH will be replaced with the previously speculative RFH.
Since interfaces are already bound we must keep the new CefFrameHostImpl. This
means that frame objects (including for the main frame) will now always change
after cross-origin navigation, and the old frame object will be invalidated.
This change introduces a few minor CEF API behavior changes:
- A CefProcessMessage object cannot be reused after being passed to
SendProcessMessage.
- The |extra_info| argument to CefRenderProcessHandler::OnBrowserCreated may
now be NULL.
Where appropriate, we now utilize the default UTF string encoding format and
shared memory to reduce copies and conversions for the cross-process
transfer of arbitrary-length strings. For example, CefFrame::GetSource/GetText
now involves zero UTF conversions and zero copies in the browser process for
the CefString delivered to CefStringVisitor::Visit().
The Browser object represents the top-level Chrome browser window. One or more
tabs (WebContents) are then owned by the Browser object via TabStripModel. A
new Browser object can be created programmatically using "new Browser" or
Browser::Create, or as a result of user action such as dragging a tab out of an
existing window. New or existing tabs can also be added to an already existing
Browser object.
The Browser object acts as the WebContentsDelegate for all attached tabs. CEF
integration requires WebContentsDelegate callbacks and notification of tab
attach/detach. To support this integration we add a cef::BrowserDelegate
(ChromeBrowserDelegate) member that is created in the Browser constructor and
receives delegation for the Browser callbacks. ChromeBrowserDelegate creates a
new ChromeBrowserHostImpl when a tab is added to a Browser for the first time,
and that ChromeBrowserHostImpl continues to exist until the tab's WebContents
is destroyed. The associated WebContents object does not change, but the
Browser object will change when the tab is dragged between windows.
CEF callback logic is shared between the chrome and alloy runtimes where
possible. This shared logic has been extracted from CefBrowserHostImpl to
create new CefBrowserHostBase and CefBrowserContentsDelegate classes. The
CefBrowserHostImpl class is now only used with the alloy runtime and will be
renamed to AlloyBrowserHostImpl in a future commit.
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.
Requests created using CefURLRequest::Create are not associated with a
browser/frame. When originating from the render process these requests cannot be
intercepted and consequently only http(s) and blob requests are supported. To
work around this limitation a new CefFrame::CreateURLRequest method has been
added that allows the request to be associated with that browser/frame for
interception purposes.
This change also fixes an issue with the NetworkService implementation where
redirected requests could result in two parallel requests being sent to the
target server.
To test: URLRequestTest.* tests pass with NetworkService enabled.
- Add about:tracing UI support (issue #711).
- Avoid unnecessary string type conversions for values and process messages.
- Add support for a 'note' attribute in patch.cfg.
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@865 5089003a-bbd8-11dd-ad1f-f1f9622dbc98