diff options
author | fdegans <fdegans@chromium.org> | 2015-04-16 18:57:59 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-17 01:59:20 +0000 |
commit | a696e5116f6b81f317758ad609e110db5ed3c284 (patch) | |
tree | d044b4861029bfcda66a95a194b5d12a63ee27c3 | |
parent | 18bad48c097ce68bccf2064daf41f6f6bb3649df (diff) | |
download | chromium_src-a696e5116f6b81f317758ad609e110db5ed3c284.zip chromium_src-a696e5116f6b81f317758ad609e110db5ed3c284.tar.gz chromium_src-a696e5116f6b81f317758ad609e110db5ed3c284.tar.bz2 |
Move DidStartLoading, DidStopLoading, DidChangeLoadProgress IPCs to RFHI.
This also adds a GetDelegate() method to the Navigator interface.
BUG=470082
Review URL: https://codereview.chromium.org/1080143003
Cr-Commit-Position: refs/heads/master@{#325579}
17 files changed, 258 insertions, 236 deletions
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index e7c814e..332524e 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc @@ -52,19 +52,18 @@ bool CollectLoadProgress(double* progress, int* frame_count, FrameTreeNode* node) { // Ignore the current frame if it has not started loading. - double frame_progress = node->loading_progress(); - if (frame_progress == FrameTreeNode::kLoadingProgressNotStarted) + if (!node->has_started_loading()) return true; // Collect progress. - *progress += frame_progress; + *progress += node->loading_progress(); (*frame_count)++; return true; } // Helper function used with FrameTree::ForEach() to reset the load progress. bool ResetNodeLoadProgress(FrameTreeNode* node) { - node->set_loading_progress(FrameTreeNode::kLoadingProgressNotStarted); + node->reset_loading_progress(); return true; } @@ -97,7 +96,8 @@ FrameTree::FrameTree(Navigator* navigator, render_widget_delegate, manager_delegate, std::string())), - focused_frame_tree_node_id_(-1) { + focused_frame_tree_node_id_(-1), + load_progress_(0.0) { } FrameTree::~FrameTree() { @@ -347,18 +347,25 @@ void FrameTree::FrameRemoved(FrameTreeNode* frame) { on_frame_removed_.Run(frame->current_frame_host()); } -double FrameTree::GetLoadProgress() { +void FrameTree::UpdateLoadProgress() { double progress = 0.0; int frame_count = 0; ForEach(base::Bind(&CollectLoadProgress, &progress, &frame_count)); if (frame_count != 0) progress /= frame_count; - return progress; + + if (progress <= load_progress_) + return; + load_progress_ = progress; + + // Notify the WebContents. + root_->navigator()->GetDelegate()->DidChangeLoadProgress(); } void FrameTree::ResetLoadProgress() { ForEach(base::Bind(&ResetNodeLoadProgress)); + load_progress_ = 0.0; } bool FrameTree::IsLoading() { diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h index 164c3c1..ce34bc2 100644 --- a/content/browser/frame_host/frame_tree.h +++ b/content/browser/frame_host/frame_tree.h @@ -130,8 +130,11 @@ class CONTENT_EXPORT FrameTree { // the listener installed by SetFrameRemoveListener. void FrameRemoved(FrameTreeNode* frame); + // Updates the overall load progress and notifies the WebContents. + void UpdateLoadProgress(); + // Returns this FrameTree's total load progress. - double GetLoadProgress(); + double load_progress() { return load_progress_; } // Resets the load progress on all nodes in this FrameTree. void ResetLoadProgress(); @@ -178,6 +181,9 @@ class CONTENT_EXPORT FrameTree { base::Callback<void(RenderFrameHost*)> on_frame_removed_; + // Overall load progress. + double load_progress_; + DISALLOW_COPY_AND_ASSIGN(FrameTree); }; diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 4a0db77..1567980 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc @@ -7,6 +7,7 @@ #include <queue> #include "base/command_line.h" +#include "base/profiler/scoped_tracker.h" #include "base/stl_util.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/navigation_request.h" @@ -27,11 +28,14 @@ typedef base::hash_map<int64, FrameTreeNode*> FrameTreeNodeIDMap; base::LazyInstance<FrameTreeNodeIDMap> g_frame_tree_node_id_map = LAZY_INSTANCE_INITIALIZER; -} // namespace +// These values indicate the loading progress status. The minimum progress +// value matches what Blink's ProgressTracker has traditionally used for a +// minimum progress value. +const double kLoadingProgressNotStarted = 0.0; +const double kLoadingProgressMinimum = 0.1; +const double kLoadingProgressDone = 1.0; -const double FrameTreeNode::kLoadingProgressNotStarted = 0.0; -const double FrameTreeNode::kLoadingProgressMinimum = 0.1; -const double FrameTreeNode::kLoadingProgressDone = 1.0; +} // namespace int64 FrameTreeNode::next_frame_tree_node_id_ = 1; @@ -194,4 +198,69 @@ void FrameTreeNode::ResetNavigationRequest(bool is_commit) { navigation_request_.reset(); } +bool FrameTreeNode::has_started_loading() const { + return loading_progress_ != kLoadingProgressNotStarted; +} + +void FrameTreeNode::reset_loading_progress() { + loading_progress_ = kLoadingProgressNotStarted; +} + +void FrameTreeNode::DidStartLoading(bool to_different_document) { + // Any main frame load to a new document should reset the load progress since + // it will replace the current page and any frames. The WebContents will + // be notified when DidChangeLoadProgress is called. + if (to_different_document && IsMainFrame()) + frame_tree_->ResetLoadProgress(); + + // Notify the WebContents. + if (!frame_tree_->IsLoading()) + navigator()->GetDelegate()->DidStartLoading(this, to_different_document); + + // Set initial load progress and update overall progress. This will notify + // the WebContents of the load progress change. + DidChangeLoadProgress(kLoadingProgressMinimum); + + // Notify the RenderFrameHostManager of the event. + render_manager()->OnDidStartLoading(); +} + +void FrameTreeNode::DidStopLoading() { + // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "465796 FrameTreeNode::DidStopLoading::Start")); + + // Set final load progress and update overall progress. This will notify + // the WebContents of the load progress change. + DidChangeLoadProgress(kLoadingProgressDone); + + // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "465796 FrameTreeNode::DidStopLoading::WCIDidStopLoading")); + + // Notify the WebContents. + if (!frame_tree_->IsLoading()) + navigator()->GetDelegate()->DidStopLoading(); + + // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "465796 FrameTreeNode::DidStopLoading::RFHMDidStopLoading")); + + // Notify the RenderFrameHostManager of the event. + render_manager()->OnDidStopLoading(); + + // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is fixed. + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "465796 FrameTreeNode::DidStopLoading::End")); +} + +void FrameTreeNode::DidChangeLoadProgress(double load_progress) { + loading_progress_ = load_progress; + frame_tree_->UpdateLoadProgress(); +} + } // namespace content diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index e321d3a..7e1add1 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h @@ -31,15 +31,6 @@ class RenderFrameHostImpl; // are frame-specific (as opposed to page-specific). class CONTENT_EXPORT FrameTreeNode { public: - // These values indicate the loading progress status. The minimum progress - // value matches what Blink's ProgressTracker has traditionally used for a - // minimum progress value. - // TODO(fdegans): Move these values to the implementation when the relevant - // IPCs are moved from WebContentsImpl to RenderFrameHost. - static const double kLoadingProgressNotStarted; - static const double kLoadingProgressMinimum; - static const double kLoadingProgressDone; - // Returns the FrameTreeNode with the given global |frame_tree_node_id|, // regardless of which FrameTree it is in. static FrameTreeNode* GloballyFindByID(int64 frame_tree_node_id); @@ -135,11 +126,6 @@ class CONTENT_EXPORT FrameTreeNode { // Returns true if this node is in a loading state. bool IsLoading() const; - // Sets this node's loading progress (from 0 to 1). - void set_loading_progress(double loading_progress) { - loading_progress_ = loading_progress; - } - // Returns this node's loading progress. double loading_progress() const { return loading_progress_; } @@ -157,6 +143,26 @@ class CONTENT_EXPORT FrameTreeNode { // due to the commit of the navigation. void ResetNavigationRequest(bool is_commit); + // Returns true if this node is in a state where the loading progress is being + // tracked. + bool has_started_loading() const; + + // Resets this node's loading progress. + void reset_loading_progress(); + + // A RenderFrameHost in this node started loading. + // |to_different_document| will be true unless the load is a fragment + // navigation, or triggered by history.pushState/replaceState. + void DidStartLoading(bool to_different_document); + + // A RenderFrameHost in this node stopped loading. + void DidStopLoading(); + + // The load progress for a RenderFrameHost in this node was updated to + // |load_progress|. This will notify the FrameTree which will in turn notify + // the WebContents. + void DidChangeLoadProgress(double load_progress); + private: void set_parent(FrameTreeNode* parent) { parent_ = parent; } diff --git a/content/browser/frame_host/interstitial_page_navigator_impl.cc b/content/browser/frame_host/interstitial_page_navigator_impl.cc index fc45950..8b1a3a6 100644 --- a/content/browser/frame_host/interstitial_page_navigator_impl.cc +++ b/content/browser/frame_host/interstitial_page_navigator_impl.cc @@ -17,6 +17,10 @@ InterstitialPageNavigatorImpl::InterstitialPageNavigatorImpl( : interstitial_(interstitial), controller_(navigation_controller) {} +NavigatorDelegate* InterstitialPageNavigatorImpl::GetDelegate() { + return interstitial_; +} + NavigationController* InterstitialPageNavigatorImpl::GetController() { return controller_; } diff --git a/content/browser/frame_host/interstitial_page_navigator_impl.h b/content/browser/frame_host/interstitial_page_navigator_impl.h index 2f96614..8a86219 100644 --- a/content/browser/frame_host/interstitial_page_navigator_impl.h +++ b/content/browser/frame_host/interstitial_page_navigator_impl.h @@ -22,6 +22,7 @@ class CONTENT_EXPORT InterstitialPageNavigatorImpl : public Navigator { InterstitialPageImpl* interstitial, NavigationControllerImpl* navigation_controller); + NavigatorDelegate* GetDelegate() override; NavigationController* GetController() override; void DidNavigate(RenderFrameHostImpl* render_frame_host, const FrameHostMsg_DidCommitProvisionalLoad_Params& diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index 00e193f..1ca9dfc 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc @@ -10,6 +10,10 @@ namespace content { +NavigatorDelegate* Navigator::GetDelegate() { + return nullptr; +} + NavigationController* Navigator::GetController() { return NULL; } diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index 981bd8a..8771dd2 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h @@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" +#include "content/browser/frame_host/navigator_delegate.h" #include "content/common/content_export.h" #include "content/public/browser/navigation_controller.h" #include "ui/base/window_open_disposition.h" @@ -26,7 +27,6 @@ class FrameTreeNode; class NavigationControllerImpl; class NavigationEntryImpl; class NavigationRequest; -class NavigatorDelegate; class RenderFrameHostImpl; class ResourceRequestBody; class StreamHandle; @@ -43,6 +43,9 @@ struct ResourceResponse; // from WebContentsImpl to this interface. class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> { public: + // Returns the delegate of this Navigator. + virtual NavigatorDelegate* GetDelegate(); + // Returns the NavigationController associated with this Navigator. virtual NavigationController* GetController(); @@ -88,7 +91,6 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> { FrameTreeNode* frame_tree_node, NavigationController::ReloadType reload_type); - // Navigation requests ------------------------------------------------------- virtual base::TimeTicks GetCurrentLoadStart(); diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h index 48501f4..75df9c4 100644 --- a/content/browser/frame_host/navigator_delegate.h +++ b/content/browser/frame_host/navigator_delegate.h @@ -17,6 +17,7 @@ struct FrameHostMsg_DidFailProvisionalLoadWithError_Params; namespace content { +class FrameTreeNode; class RenderFrameHostImpl; struct LoadCommittedDetails; struct OpenURLParams; @@ -99,6 +100,20 @@ class CONTENT_EXPORT NavigatorDelegate { // Returns whether URLs for aborted browser-initiated navigations should be // preserved in the omnibox. Defaults to false. virtual bool ShouldPreserveAbortedURLs(); + + // A RenderFrameHost in the specified |frame_tree_node| started loading a new + // document. This correponds to Blink's notion of the throbber starting. + // |to_different_document| will be true unless the load is a fragment + // navigation, or triggered by history.pushState/replaceState. + virtual void DidStartLoading(FrameTreeNode* frame_tree_node, + bool to_different_document) {} + + // A document stopped loading. This corresponds to Blink's notion of the + // throbber stopping. + virtual void DidStopLoading() {} + + // The load progress was changed. + virtual void DidChangeLoadProgress() {} }; } // namspace content diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 3097a54..0bbd2bd 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc @@ -106,6 +106,10 @@ NavigatorImpl::NavigatorImpl( NavigatorImpl::~NavigatorImpl() {} +NavigatorDelegate* NavigatorImpl::GetDelegate() { + return delegate_; +} + NavigationController* NavigatorImpl::GetController() { return controller_; } diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index 3c46500..7dd2a02 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h @@ -34,6 +34,7 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator { NavigatorDelegate* delegate); // Navigator implementation. + NavigatorDelegate* GetDelegate() override; NavigationController* GetController() override; void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host, const GURL& url, diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h index f0e9fbd..708e1c9 100644 --- a/content/browser/frame_host/render_frame_host_delegate.h +++ b/content/browser/frame_host/render_frame_host_delegate.h @@ -58,17 +58,6 @@ class CONTENT_EXPORT RenderFrameHostDelegate { // Informs the delegate whenever a RenderFrameHost is deleted. virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) {} - // The specified RenderFrame began loading a new page. This corresponds to - // Blink's notion of the throbber starting. - // |to_different_document| will be true unless the load is a fragment - // navigation, or triggered by history.pushState/replaceState. - virtual void DidStartLoading(RenderFrameHost* render_frame_host, - bool to_different_document) {} - - // The specified RenderFrame stopped loading a page. This corresponds to - // Blink's notion of the throbber stopping. - virtual void DidStopLoading() {} - // The RenderFrameHost has been swapped out. virtual void SwappedOut(RenderFrameHost* render_frame_host) {} diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 7f8aaf3..5df06c4 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -388,6 +388,10 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) { // The following message is synthetic and doesn't come from RenderFrame, but // from RenderProcessHost. IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress, + OnDidChangeLoadProgress) #if defined(OS_MACOSX) || defined(OS_ANDROID) IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup) IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup) @@ -847,11 +851,11 @@ void RenderFrameHostImpl::OnDidCommitProvisionalLoad(const IPC::Message& msg) { } void RenderFrameHostImpl::OnDidDropNavigation() { - // At the end of Navigate(), the delegate's DidStartLoading is called to force - // the spinner to start, even if the renderer didn't yet begin the load. If it - // turns out that the renderer dropped the navigation, we need to turn off the - // spinner. - delegate_->DidStopLoading(); + // At the end of Navigate(), the FrameTreeNode's DidStartLoading is called to + // force the spinner to start, even if the renderer didn't yet begin the load. + // If it turns out that the renderer dropped the navigation, the spinner needs + // to be turned off. + frame_tree_node_->DidStopLoading(); } RenderWidgetHostImpl* RenderFrameHostImpl::GetRenderWidgetHost() { @@ -1430,6 +1434,45 @@ void RenderFrameHostImpl::OnToggleFullscreen(bool enter_fullscreen) { render_view_host_->WasResized(); } +void RenderFrameHostImpl::OnDidStartLoading(bool to_different_document) { + // Any main frame load to a new document should reset the load since it will + // replace the current page and any frames. + if (to_different_document && !GetParent()) + is_loading_ = false; + + // This method should never be called when the frame is loading. + // Unfortunately, it can happen if a history navigation happens during a + // BeforeUnload or Unload event. + // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been + // refactored in Blink. See crbug.com/466089 + if (is_loading_) { + LOG(WARNING) << "OnDidStartLoading was called twice."; + return; + } + + frame_tree_node_->DidStartLoading(to_different_document); + is_loading_ = true; +} + +void RenderFrameHostImpl::OnDidStopLoading() { + // This method should never be called when the frame is not loading. + // Unfortunately, it can happen if a history navigation happens during a + // BeforeUnload or Unload event. + // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been + // refactored in Blink. See crbug.com/466089 + if (!is_loading_) { + LOG(WARNING) << "OnDidStopLoading was called twice."; + return; + } + + is_loading_ = false; + frame_tree_node_->DidStopLoading(); +} + +void RenderFrameHostImpl::OnDidChangeLoadProgress(double load_progress) { + frame_tree_node_->DidChangeLoadProgress(load_progress); +} + #if defined(OS_MACOSX) || defined(OS_ANDROID) void RenderFrameHostImpl::OnShowPopup( const FrameHostMsg_ShowPopup_Params& params) { @@ -1588,19 +1631,19 @@ void RenderFrameHostImpl::Navigate( request_params)); } - // Force the throbber to start. We do this because Blink's "started - // loading" message will be received asynchronously from the UI of the - // browser. But we want to keep the throbber in sync with what's happening - // in the UI. For example, we want to start throbbing immediately when the - // user navigates even if the renderer is delayed. There is also an issue - // with the throbber starting because the WebUI (which controls whether the - // favicon is displayed) happens synchronously. If the start loading - // messages was asynchronous, then the default favicon would flash in. + // Force the throbber to start. This is done because Blink's "started loading" + // message will be received asynchronously from the UI of the browser. But the + // throbber needs to be kept in sync with what's happening in the UI. For + // example, the throbber will start immediately when the user navigates even + // if the renderer is delayed. There is also an issue with the throbber + // starting because the WebUI (which controls whether the favicon is + // displayed) happens synchronously. If the start loading messages was + // asynchronous, then the default favicon would flash in. // - // Blink doesn't send throb notifications for JavaScript URLs, so we - // don't want to either. + // Blink doesn't send throb notifications for JavaScript URLs, so it is not + // done here either. if (!common_params.url.SchemeIs(url::kJavaScriptScheme)) - delegate_->DidStartLoading(this, true); + frame_tree_node_->DidStartLoading(true); } void RenderFrameHostImpl::NavigateToURL(const GURL& url) { diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 013df0a..2d1f702 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h @@ -203,11 +203,6 @@ class CONTENT_EXPORT RenderFrameHostImpl RenderFrameHostDelegate* delegate() { return delegate_; } FrameTreeNode* frame_tree_node() { return frame_tree_node_; } - // Sets this RenderFrameHost's loading state. - void set_is_loading(bool is_loading) { - is_loading_ = is_loading; - } - // Returns this RenderFrameHost's loading state. This method is only used by // FrameTreeNode. The proper way to check whether a frame is loading is to // call FrameTreeNode::IsLoading. @@ -529,6 +524,9 @@ class CONTENT_EXPORT RenderFrameHostImpl void OnAccessibilitySnapshotResponse(int callback_id, const ui::AXTreeUpdate& snapshot); void OnToggleFullscreen(bool enter_fullscreen); + void OnDidStartLoading(bool to_different_document); + void OnDidStopLoading(); + void OnDidChangeLoadProgress(double load_progress); #if defined(OS_MACOSX) || defined(OS_ANDROID) void OnShowPopup(const FrameHostMsg_ShowPopup_Params& params); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index ca9d608..c39eea8 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -202,7 +202,6 @@ void SetAccessibilityModeOnFrame(AccessibilityMode mode, static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode); } - } // namespace WebContents* WebContents::Create(const WebContents::CreateParams& params) { @@ -311,7 +310,6 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context, crashed_error_code_(0), waiting_for_response_(false), load_state_(net::LOAD_STATE_IDLE, base::string16()), - loading_total_progress_(0.0), upload_size_(0), upload_position_(0), displayed_insecure_content_(false), @@ -513,10 +511,6 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host, IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad, OnDocumentLoadedInFrame) IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad) - IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading) - IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) - IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress, - OnDidChangeLoadProgress) IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser) IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser) IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser, @@ -2862,146 +2856,6 @@ void WebContentsImpl::OnDidFinishLoad(const GURL& url) { WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url)); } -void WebContentsImpl::OnDidStartLoading(bool to_different_document) { - if (!HasValidFrameSource()) - return; - - RenderFrameHostImpl* rfh = - static_cast<RenderFrameHostImpl*>(render_frame_message_source_); - - // Any main frame load to a new document should reset the load progress, since - // it will replace the current page and any frames. - if (to_different_document && !rfh->GetParent()) { - ResetLoadProgressState(); - rfh->set_is_loading(false); - } - - // This method should never be called when the frame is loading. - // Unfortunately, it can happen if a history navigation happens during a - // BeforeUnload or Unload event. - // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been - // refactored in Blink. See crbug.com/466089 - if (rfh->is_loading()) { - LOG(WARNING) << "OnDidStartLoading was called twice."; - return; - } - - if (!frame_tree_.IsLoading()) - DidStartLoading(rfh, to_different_document); - - rfh->set_is_loading(true); - - FrameTreeNode* ftn = rfh->frame_tree_node(); - ftn->set_loading_progress(FrameTreeNode::kLoadingProgressMinimum); - - // Notify the RenderFrameHostManager of the event. - ftn->render_manager()->OnDidStartLoading(); - - SendLoadProgressChanged(); -} - -void WebContentsImpl::OnDidStopLoading() { - // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is - // fixed. - tracked_objects::ScopedTracker tracking_profile1( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "465796 WebContentsImpl::OnDidStopLoading::Start")); - - if (!HasValidFrameSource()) - return; - - RenderFrameHostImpl* rfh = - static_cast<RenderFrameHostImpl*>(render_frame_message_source_); - - // This method should never be called when the frame is not loading. - // Unfortunately, it can happen if a history navigation happens during a - // BeforeUnload or Unload event. - // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been - // refactored in Blink. See crbug.com/466089 - if (!rfh->is_loading()) { - LOG(WARNING) << "OnDidStopLoading was called twice."; - return; - } - - rfh->set_is_loading(false); - - FrameTreeNode* ftn = rfh->frame_tree_node(); - ftn->set_loading_progress(FrameTreeNode::kLoadingProgressDone); - - // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is - // fixed. - tracked_objects::ScopedTracker tracking_profile2( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "465796 " - "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); - - // Update progress based on this frame's completion. - SendLoadProgressChanged(); - - // Then clean-up the states. - if (loading_total_progress_ == 1.0) - ResetLoadProgressState(); - - // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is - // fixed. - tracked_objects::ScopedTracker tracking_profile3( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); - // Notify the RenderFrameHostManager of the event. - ftn->render_manager()->OnDidStopLoading(); - - if (!frame_tree_.IsLoading()) { - // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is - // fixed. - tracked_objects::ScopedTracker tracking_profile4( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); - DidStopLoading(); - } - - // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is - // fixed. - tracked_objects::ScopedTracker tracking_profile4( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "465796 WebContentsImpl::OnDidStopLoading::End")); -} - -void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { - if (!HasValidFrameSource()) - return; - - RenderFrameHostImpl* rfh = - static_cast<RenderFrameHostImpl*>(render_frame_message_source_); - FrameTreeNode* ftn = rfh->frame_tree_node(); - - ftn->set_loading_progress(load_progress); - - // We notify progress change immediately for the first and last updates. - // Also, since the message loop may be pretty busy when a page is loaded, it - // might not execute a posted task in a timely manner so we make sure to - // immediately send progress report if enough time has passed. - base::TimeDelta min_delay = - base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); - if (load_progress == 1.0 || loading_last_progress_update_.is_null() || - base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { - // If there is a pending task to send progress, it is now obsolete. - loading_weak_factory_.InvalidateWeakPtrs(); - SendLoadProgressChanged(); - if (loading_total_progress_ == 1.0) - ResetLoadProgressState(); - return; - } - - if (loading_weak_factory_.HasWeakPtrs()) - return; - - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&WebContentsImpl::SendLoadProgressChanged, - loading_weak_factory_.GetWeakPtr()), - min_delay); -} - void WebContentsImpl::OnGoToEntryAtOffset(int offset) { if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) controller_.GoToOffset(offset); @@ -3450,23 +3304,14 @@ bool WebContentsImpl::UpdateTitleForEntry(NavigationEntryImpl* entry, return true; } -void WebContentsImpl::SendLoadProgressChanged() { +void WebContentsImpl::SendChangeLoadProgress() { loading_last_progress_update_ = base::TimeTicks::Now(); - double progress = frame_tree_.GetLoadProgress(); - - DCHECK_LE(progress, 1.0); - - if (progress <= loading_total_progress_) - return; - loading_total_progress_ = progress; - if (delegate_) - delegate_->LoadProgressChanged(this, progress); + delegate_->LoadProgressChanged(this, frame_tree_.load_progress()); } void WebContentsImpl::ResetLoadProgressState() { frame_tree_.ResetLoadProgress(); - loading_total_progress_ = 0.0; loading_weak_factory_.InvalidateWeakPtrs(); loading_last_progress_update_ = base::TimeTicks(); } @@ -3867,7 +3712,7 @@ void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) { delegate_->MoveContents(this, new_bounds); } -void WebContentsImpl::DidStartLoading(RenderFrameHost* render_frame_host, +void WebContentsImpl::DidStartLoading(FrameTreeNode* frame_tree_node, bool to_different_document) { SetIsLoading(true, to_different_document, nullptr); @@ -3875,10 +3720,8 @@ void WebContentsImpl::DidStartLoading(RenderFrameHost* render_frame_host, // current document. // // TODO(dmazzoni): do this using a WebContentsObserver. - FrameTreeNode* ftn = static_cast<RenderFrameHostImpl*>(render_frame_host)-> - frame_tree_node(); BrowserAccessibilityManager* manager = - ftn->current_frame_host()->browser_accessibility_manager(); + frame_tree_node->current_frame_host()->browser_accessibility_manager(); if (manager) manager->UserIsNavigatingAway(); } @@ -3908,6 +3751,41 @@ void WebContentsImpl::DidStopLoading() { SetIsLoading(false, true, details.get()); } +void WebContentsImpl::DidChangeLoadProgress() { + double load_progress = frame_tree_.load_progress(); + + // The delegate is notified immediately for the first and last updates. Also, + // since the message loop may be pretty busy when a page is loaded, it might + // not execute a posted task in a timely manner so the progress report is sent + // immediately if enough time has passed. + base::TimeDelta min_delay = + base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); + bool delay_elapsed = loading_last_progress_update_.is_null() || + base::TimeTicks::Now() - loading_last_progress_update_ > min_delay; + + if (load_progress == 0.0 || load_progress == 1.0 || delay_elapsed) { + // If there is a pending task to send progress, it is now obsolete. + loading_weak_factory_.InvalidateWeakPtrs(); + + // Notify the load progress change. + SendChangeLoadProgress(); + + // Clean-up the states if needed. + if (load_progress == 1.0) + ResetLoadProgressState(); + return; + } + + if (loading_weak_factory_.HasWeakPtrs()) + return; + + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&WebContentsImpl::SendChangeLoadProgress, + loading_weak_factory_.GetWeakPtr()), + min_delay); +} + void WebContentsImpl::DidCancelLoading() { controller_.DiscardNonCommittedEntries(); diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index a1742d8..dc1eede 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -378,9 +378,6 @@ class CONTENT_EXPORT WebContentsImpl const GURL& GetMainFrameLastCommittedURL() const override; void RenderFrameCreated(RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; - void DidStartLoading(RenderFrameHost* render_frame_host, - bool to_different_document) override; - void DidStopLoading() override; void SwappedOut(RenderFrameHost* render_frame_host) override; void DidDeferAfterResponseStarted( const TransitionLayerData& transition_data) override; @@ -547,6 +544,10 @@ class CONTENT_EXPORT WebContentsImpl void RequestOpenURL(RenderFrameHostImpl* render_frame_host, const OpenURLParams& params) override; bool ShouldPreserveAbortedURLs() override; + void DidStartLoading(FrameTreeNode* frame_tree_node, + bool to_different_document) override; + void DidStopLoading() override; + void DidChangeLoadProgress() override; // RenderWidgetHostDelegate -------------------------------------------------- @@ -786,9 +787,6 @@ class CONTENT_EXPORT WebContentsImpl const GURL& target_url); void OnDocumentLoadedInFrame(); void OnDidFinishLoad(const GURL& url); - void OnDidStartLoading(bool to_different_document); - void OnDidStopLoading(); - void OnDidChangeLoadProgress(double load_progress); void OnGoToEntryAtOffset(int offset); void OnUpdateZoomLimits(int minimum_percent, int maximum_percent); @@ -919,11 +917,11 @@ class CONTENT_EXPORT WebContentsImpl // Tracking loading progress ------------------------------------------------- - // Resets the tracking state of the current load. + // Resets the tracking state of the current load progress. void ResetLoadProgressState(); - // Calculates the progress of the current load and notifies the delegate. - void SendLoadProgressChanged(); + // Notifies the delegate that the load progress was updated. + void SendChangeLoadProgress(); // Misc non-view stuff ------------------------------------------------------- @@ -1080,8 +1078,6 @@ class CONTENT_EXPORT WebContentsImpl net::LoadStateWithParam load_state_; base::string16 load_state_host_; - double loading_total_progress_; - base::TimeTicks loading_last_progress_update_; // Upload progress, for displaying in the status bar. diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index a40f741..51b78a7 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc @@ -581,16 +581,15 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, new LoadProgressDelegateAndObserver(shell())); RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame(); FrameHostMsg_DidStartLoading start_msg(main_frame->GetRoutingID(), true); - static_cast<WebContentsImpl*>(shell()->web_contents())->OnMessageReceived( - main_frame, start_msg); + static_cast<RenderFrameHostImpl*>(main_frame)->OnMessageReceived(start_msg); EXPECT_TRUE(delegate->did_start_loading); EXPECT_FALSE(delegate->did_stop_loading); // Also simulate a DidChangeLoadProgress, but not a DidStopLoading. FrameHostMsg_DidChangeLoadProgress progress_msg(main_frame->GetRoutingID(), 1.0); - static_cast<WebContentsImpl*>(shell()->web_contents())->OnMessageReceived( - main_frame, progress_msg); + static_cast<RenderFrameHostImpl*>(main_frame)->OnMessageReceived( + progress_msg); EXPECT_TRUE(delegate->did_start_loading); EXPECT_FALSE(delegate->did_stop_loading); |