Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 1015243004: Move load progress tracking logic to the frame tree. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix tests Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } 158 }
159 159
160 // Helper function for retrieving all the sites in a frame tree. 160 // Helper function for retrieving all the sites in a frame tree.
161 bool CollectSites(BrowserContext* context, 161 bool CollectSites(BrowserContext* context,
162 std::set<GURL>* sites, 162 std::set<GURL>* sites,
163 FrameTreeNode* node) { 163 FrameTreeNode* node) {
164 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url())); 164 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url()));
165 return true; 165 return true;
166 } 166 }
167 167
168 // Helper function used with FrameTree::ForEach() for retrieving the total
169 // loading progress and number of frames in a frame tree.
170 bool CollectLoadProgress(double* progress,
171 int* frame_count,
172 FrameTreeNode* node) {
173 // Ignore the current frame if it has not started loading.
174 double frame_progress = node->GetLoadingProgress();
175 if (frame_progress == RenderFrameHostImpl::kLoadingProgressNotStarted)
176 return true;
177
178 // Collect progress.
179 *progress += node->GetLoadingProgress();
180 (*frame_count)++;
181 return true;
182 }
183
184 // Helper function used with FrameTree::ForEach() to check if at least one of
185 // the nodes is loading.
186 bool IsNodeLoading(bool* is_loading, FrameTreeNode* node) {
187 if (node->IsLoading()) {
188 // There is at least one node loading, so abort traversal.
189 *is_loading = true;
190 return false;
191 }
192 return true;
193 }
194
195 // Helper function used with FrameTree::ForEach() to reset the load progress.
196 bool ResetLoadProgress(FrameTreeNode* node) {
197 node->current_frame_host()->set_loading_progress(
198 RenderFrameHostImpl::kLoadingProgressNotStarted);
199 return true;
200 }
201
202 bool ForEachFrameInternal( 168 bool ForEachFrameInternal(
203 const base::Callback<void(RenderFrameHost*)>& on_frame, 169 const base::Callback<void(RenderFrameHost*)>& on_frame,
204 FrameTreeNode* node) { 170 FrameTreeNode* node) {
205 on_frame.Run(node->current_frame_host()); 171 on_frame.Run(node->current_frame_host());
206 return true; 172 return true;
207 } 173 }
208 174
209 bool ForEachPendingFrameInternal( 175 bool ForEachPendingFrameInternal(
210 const base::Callback<void(RenderFrameHost*)>& on_frame, 176 const base::Callback<void(RenderFrameHost*)>& on_frame,
211 FrameTreeNode* node) { 177 FrameTreeNode* node) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 // termination is not allowed for the current RenderFrameHost of 219 // termination is not allowed for the current RenderFrameHost of
254 // |frame_tree_node|. Used with FrameTree::ForEach. 220 // |frame_tree_node|. Used with FrameTree::ForEach.
255 bool SuddenTerminationAllowed(bool* sudden_termination_allowed, 221 bool SuddenTerminationAllowed(bool* sudden_termination_allowed,
256 FrameTreeNode* frame_tree_node) { 222 FrameTreeNode* frame_tree_node) {
257 if (frame_tree_node->current_frame_host()->SuddenTerminationAllowed()) 223 if (frame_tree_node->current_frame_host()->SuddenTerminationAllowed())
258 return true; 224 return true;
259 *sudden_termination_allowed = false; 225 *sudden_termination_allowed = false;
260 return false; 226 return false;
261 } 227 }
262 228
263 // Returns true if at least one of the nodes in the |frame_tree| is loading.
264 bool IsFrameTreeLoading(FrameTree& frame_tree) {
265 bool is_loading = false;
266 frame_tree.ForEach(base::Bind(&IsNodeLoading, &is_loading));
267 return is_loading;
268 }
269 229
270 } // namespace 230 } // namespace
271 231
272 WebContents* WebContents::Create(const WebContents::CreateParams& params) { 232 WebContents* WebContents::Create(const WebContents::CreateParams& params) {
273 return WebContentsImpl::CreateWithOpener( 233 return WebContentsImpl::CreateWithOpener(
274 params, static_cast<WebContentsImpl*>(params.opener)); 234 params, static_cast<WebContentsImpl*>(params.opener));
275 } 235 }
276 236
277 WebContents* WebContents::CreateWithSessionStorage( 237 WebContents* WebContents::CreateWithSessionStorage(
278 const WebContents::CreateParams& params, 238 const WebContents::CreateParams& params,
(...skipping 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 // This method should never be called when the frame is loading. 2915 // This method should never be called when the frame is loading.
2956 // Unfortunately, it can happen if a history navigation happens during a 2916 // Unfortunately, it can happen if a history navigation happens during a
2957 // BeforeUnload or Unload event. 2917 // BeforeUnload or Unload event.
2958 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been 2918 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been
2959 // refactored in Blink. See crbug.com/466089 2919 // refactored in Blink. See crbug.com/466089
2960 if (rfh->is_loading()) { 2920 if (rfh->is_loading()) {
2961 LOG(WARNING) << "OnDidStartLoading was called twice."; 2921 LOG(WARNING) << "OnDidStartLoading was called twice.";
2962 return; 2922 return;
2963 } 2923 }
2964 2924
2965 if (!IsFrameTreeLoading(frame_tree_)) 2925 if (!frame_tree_.IsLoading())
2966 DidStartLoading(rfh, to_different_document); 2926 DidStartLoading(rfh, to_different_document);
2967 2927
2968 rfh->set_is_loading(true); 2928 rfh->set_is_loading(true);
2969 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressMinimum); 2929
2930 FrameTreeNode* ftn = rfh->frame_tree_node();
2931 if (ftn->render_manager()->current_frame_host() == rfh)
clamy 2015/03/24 14:52:23 Should we reset the load progress even if its the
Fabrice (no longer in Chrome) 2015/03/24 16:28:50 We probably should reset but that is going to make
2932 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressMinimum);
2970 2933
2971 // Notify the RenderFrameHostManager of the event. 2934 // Notify the RenderFrameHostManager of the event.
2972 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); 2935 ftn->render_manager()->OnDidStartLoading();
2973 2936
2974 SendLoadProgressChanged(); 2937 SendLoadProgressChanged();
2975 } 2938 }
2976 2939
2977 void WebContentsImpl::OnDidStopLoading() { 2940 void WebContentsImpl::OnDidStopLoading() {
2978 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2941 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
2979 // fixed. 2942 // fixed.
2980 tracked_objects::ScopedTracker tracking_profile1( 2943 tracked_objects::ScopedTracker tracking_profile1(
2981 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2944 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2982 "465796 WebContentsImpl::OnDidStopLoading::Start")); 2945 "465796 WebContentsImpl::OnDidStopLoading::Start"));
2983 2946
2984 if (!HasValidFrameSource()) 2947 if (!HasValidFrameSource())
2985 return; 2948 return;
2986 2949
2987 RenderFrameHostImpl* rfh = 2950 RenderFrameHostImpl* rfh =
2988 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2951 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2989 2952
2990 // This method should never be called when the frame is not loading. 2953 // This method should never be called when the frame is not loading.
2991 // Unfortunately, it can happen if a history navigation happens during a 2954 // Unfortunately, it can happen if a history navigation happens during a
2992 // BeforeUnload or Unload event. 2955 // BeforeUnload or Unload event.
2993 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been 2956 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been
2994 // refactored in Blink. See crbug.com/466089 2957 // refactored in Blink. See crbug.com/466089
2995 if (!rfh->is_loading()) { 2958 if (!rfh->is_loading()) {
2996 LOG(WARNING) << "OnDidStopLoading was called twice."; 2959 LOG(WARNING) << "OnDidStopLoading was called twice.";
2997 return; 2960 return;
2998 } 2961 }
2999 2962
3000 rfh->set_is_loading(false); 2963 rfh->set_is_loading(false);
3001 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressDone); 2964
2965 FrameTreeNode* ftn = rfh->frame_tree_node();
2966 if (ftn->render_manager()->current_frame_host() == rfh)
clamy 2015/03/24 14:52:23 Can we get a DidStopLoading IPC from the pending R
Fabrice (no longer in Chrome) 2015/03/24 16:28:50 We can and we do. In fact, when we track the overa
nasko 2015/03/24 17:26:11 I'm not sure we can get a DidStopLoading from the
Fabrice (no longer in Chrome) 2015/03/25 13:25:12 I have found that DownloadContentTest.RemoveDownlo
2967 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressDone);
3002 2968
3003 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2969 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3004 // fixed. 2970 // fixed.
3005 tracked_objects::ScopedTracker tracking_profile2( 2971 tracked_objects::ScopedTracker tracking_profile2(
3006 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2972 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3007 "465796 " 2973 "465796 "
3008 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); 2974 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged"));
3009 2975
3010 // Update progress based on this frame's completion. 2976 // Update progress based on this frame's completion.
3011 SendLoadProgressChanged(); 2977 SendLoadProgressChanged();
3012 2978
3013 // Then clean-up the states. 2979 // Then clean-up the states.
3014 if (loading_total_progress_ == 1.0) 2980 if (loading_total_progress_ == 1.0)
3015 ResetLoadProgressState(); 2981 ResetLoadProgressState();
3016 2982
3017 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2983 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3018 // fixed. 2984 // fixed.
3019 tracked_objects::ScopedTracker tracking_profile3( 2985 tracked_objects::ScopedTracker tracking_profile3(
3020 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2986 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3021 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); 2987 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager"));
3022 // Notify the RenderFrameHostManager of the event. 2988 // Notify the RenderFrameHostManager of the event.
3023 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); 2989 ftn->render_manager()->OnDidStopLoading();
3024 2990
3025 if (!IsFrameTreeLoading(frame_tree_)) { 2991 if (!frame_tree_.IsLoading()) {
3026 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2992 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3027 // fixed. 2993 // fixed.
3028 tracked_objects::ScopedTracker tracking_profile4( 2994 tracked_objects::ScopedTracker tracking_profile4(
3029 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2995 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3030 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); 2996 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading"));
3031 DidStopLoading(); 2997 DidStopLoading();
3032 } 2998 }
3033 2999
3034 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 3000 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3035 // fixed. 3001 // fixed.
3036 tracked_objects::ScopedTracker tracking_profile4( 3002 tracked_objects::ScopedTracker tracking_profile4(
3037 FROM_HERE_WITH_EXPLICIT_FUNCTION( 3003 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3038 "465796 WebContentsImpl::OnDidStopLoading::End")); 3004 "465796 WebContentsImpl::OnDidStopLoading::End"));
3039 } 3005 }
3040 3006
3041 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { 3007 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
3042 if (!HasValidFrameSource()) 3008 if (!HasValidFrameSource())
3043 return; 3009 return;
3044 3010
3045 RenderFrameHostImpl* rfh = 3011 RenderFrameHostImpl* rfh =
3046 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 3012 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
3013 FrameTreeNode* ftn = rfh->frame_tree_node();
3047 3014
3048 rfh->set_loading_progress(load_progress); 3015 if (ftn->render_manager()->current_frame_host() != rfh)
clamy 2015/03/24 14:52:23 Same here. I don't think we should be getting this
Fabrice (no longer in Chrome) 2015/03/24 16:28:50 Same as above, we still get these events for pendi
nasko 2015/03/24 17:26:11 Really? Real progress cannot be made before we com
Fabrice (no longer in Chrome) 2015/03/25 13:25:12 I have found that the following tests send the eve
3016 return;
3017
3018 ftn->set_loading_progress(load_progress);
3049 3019
3050 // We notify progress change immediately for the first and last updates. 3020 // We notify progress change immediately for the first and last updates.
3051 // Also, since the message loop may be pretty busy when a page is loaded, it 3021 // Also, since the message loop may be pretty busy when a page is loaded, it
3052 // might not execute a posted task in a timely manner so we make sure to 3022 // might not execute a posted task in a timely manner so we make sure to
3053 // immediately send progress report if enough time has passed. 3023 // immediately send progress report if enough time has passed.
3054 base::TimeDelta min_delay = 3024 base::TimeDelta min_delay =
3055 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); 3025 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
3056 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || 3026 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
3057 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { 3027 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
3058 // If there is a pending task to send progress, it is now obsolete. 3028 // If there is a pending task to send progress, it is now obsolete.
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 NotificationService::current()->Notify( 3482 NotificationService::current()->Notify(
3513 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 3483 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
3514 Source<WebContents>(this), 3484 Source<WebContents>(this),
3515 Details<std::pair<NavigationEntry*, bool> >(&details)); 3485 Details<std::pair<NavigationEntry*, bool> >(&details));
3516 3486
3517 return true; 3487 return true;
3518 } 3488 }
3519 3489
3520 void WebContentsImpl::SendLoadProgressChanged() { 3490 void WebContentsImpl::SendLoadProgressChanged() {
3521 loading_last_progress_update_ = base::TimeTicks::Now(); 3491 loading_last_progress_update_ = base::TimeTicks::Now();
3522 double progress = 0.0; 3492 double progress = frame_tree_.GetLoadProgress();
3523 int frame_count = 0;
3524 3493
3525 frame_tree_.ForEach(
3526 base::Bind(&CollectLoadProgress, &progress, &frame_count));
3527 if (frame_count != 0)
3528 progress /= frame_count;
3529 DCHECK_LE(progress, 1.0); 3494 DCHECK_LE(progress, 1.0);
3530 3495
3531 if (progress <= loading_total_progress_) 3496 if (progress <= loading_total_progress_)
3532 return; 3497 return;
3533 loading_total_progress_ = progress; 3498 loading_total_progress_ = progress;
3534 3499
3535 if (delegate_) 3500 if (delegate_)
3536 delegate_->LoadProgressChanged(this, progress); 3501 delegate_->LoadProgressChanged(this, progress);
3537 } 3502 }
3538 3503
3539 void WebContentsImpl::ResetLoadProgressState() { 3504 void WebContentsImpl::ResetLoadProgressState() {
3540 frame_tree_.ForEach(base::Bind(&ResetLoadProgress)); 3505 frame_tree_.ResetLoadProgress();
3541 loading_total_progress_ = 0.0; 3506 loading_total_progress_ = 0.0;
3542 loading_weak_factory_.InvalidateWeakPtrs(); 3507 loading_weak_factory_.InvalidateWeakPtrs();
3543 loading_last_progress_update_ = base::TimeTicks(); 3508 loading_last_progress_update_ = base::TimeTicks();
3544 } 3509 }
3545 3510
3546 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, 3511 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
3547 RenderViewHost* new_host) { 3512 RenderViewHost* new_host) {
3548 // After sending out a swap notification, we need to send a disconnect 3513 // After sending out a swap notification, we need to send a disconnect
3549 // notification so that clients that pick up a pointer to |this| can NULL the 3514 // notification so that clients that pick up a pointer to |this| can NULL the
3550 // pointer. See Bug 1230284. 3515 // pointer. See Bug 1230284.
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 node->render_manager()->ResumeResponseDeferredAtStart(); 4613 node->render_manager()->ResumeResponseDeferredAtStart();
4649 } 4614 }
4650 4615
4651 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { 4616 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
4652 force_disable_overscroll_content_ = force_disable; 4617 force_disable_overscroll_content_ = force_disable;
4653 if (view_) 4618 if (view_)
4654 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4619 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4655 } 4620 }
4656 4621
4657 } // namespace content 4622 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698