Improve timing of frame attach/detach (see #3664)

- Move frame attachment from RenderFrameCreated to
  DidCommitProvisionalLoad. This has a number of advantages:
  - Significantly reduces the frequency of disconnects by avoiding
    the GetInterface/DidCommitNavigation race condition.
  - Stops connecting temporary frames (created during cross-origin
    navigation), making callback behavior more consistent.
- Split frame detach and destruction notifications into separate
  callbacks. OnFrameDetached now reflects a potentially recoverable
  state. Add a new OnFrameDestroyed callback for the unrecoverable
  destruction state.
This commit is contained in:
Marshall Greenblatt
2024-11-27 17:08:42 -05:00
parent 7f253f83a2
commit 35fc888c72
16 changed files with 484 additions and 220 deletions

View File

@ -316,20 +316,23 @@ void CefFrameImpl::SendProcessMessage(CefProcessId target_process,
}
}
void CefFrameImpl::OnAttached() {
// Called indirectly from RenderFrameCreated.
ConnectBrowserFrame(ConnectReason::RENDER_FRAME_CREATED);
}
void CefFrameImpl::OnWasShown() {
if (browser_connection_state_ == ConnectionState::DISCONNECTED) {
// Reconnect a frame that has exited the bfcache.
if (browser_connection_state_ == ConnectionState::DISCONNECTED &&
did_commit_provisional_load_) {
// Reconnect a frame that has exited the bfcache. We ignore temporary
// frames that have never called DidCommitProvisionalLoad.
ConnectBrowserFrame(ConnectReason::WAS_SHOWN);
}
}
void CefFrameImpl::OnDidCommitProvisionalLoad() {
did_commit_provisional_load_ = true;
if (browser_connection_state_ == ConnectionState::DISCONNECTED) {
// Connect after RenderFrameImpl::DidCommitNavigation has potentially
// reset the BrowserInterfaceBroker in the browser process. See related
// comments in OnDisconnect.
ConnectBrowserFrame(ConnectReason::DID_COMMIT);
}
MaybeInitializeScriptContext();
}
@ -473,8 +476,8 @@ void CefFrameImpl::ConnectBrowserFrame(ConnectReason reason) {
if (VLOG_IS_ON(1)) {
std::string reason_str;
switch (reason) {
case ConnectReason::RENDER_FRAME_CREATED:
reason_str = "RENDER_FRAME_CREATED";
case ConnectReason::DID_COMMIT:
reason_str = "DID_COMMIT";
break;
case ConnectReason::WAS_SHOWN:
reason_str = "WAS_SHOWN";

View File

@ -81,7 +81,6 @@ class CefFrameImpl
CefRefPtr<CefProcessMessage> message) override;
// Forwarded from CefRenderFrameObserver.
void OnAttached();
void OnWasShown();
void OnDidCommitProvisionalLoad();
void OnDidFinishLoad();
@ -105,7 +104,7 @@ class CefFrameImpl
LocalFrameAction action);
enum class ConnectReason {
RENDER_FRAME_CREATED,
DID_COMMIT,
WAS_SHOWN,
RETRY,
};

View File

@ -199,7 +199,6 @@ void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) {
DCHECK(frame);
DCHECK(!frame_);
frame_ = frame;
frame_->OnAttached();
}
void CefRenderFrameObserver::OnLoadStart() {