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

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: Readding TODO Created 5 years, 8 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
« no previous file with comments | « content/browser/frame_host/render_frame_host_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 17 matching lines...) Expand all
229 ->render_manager() 195 ->render_manager()
230 ->GetRenderWidgetHostView(); 196 ->GetRenderWidgetHostView();
231 set->insert(rwhv); 197 set->insert(rwhv);
232 } 198 }
233 199
234 void SetAccessibilityModeOnFrame(AccessibilityMode mode, 200 void SetAccessibilityModeOnFrame(AccessibilityMode mode,
235 RenderFrameHost* frame_host) { 201 RenderFrameHost* frame_host) {
236 static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode); 202 static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode);
237 } 203 }
238 204
239 // Returns true if at least one of the nodes in the |frame_tree| is loading.
240 bool IsFrameTreeLoading(FrameTree& frame_tree) {
241 bool is_loading = false;
242 frame_tree.ForEach(base::Bind(&IsNodeLoading, &is_loading));
243 return is_loading;
244 }
245 205
246 } // namespace 206 } // namespace
247 207
248 WebContents* WebContents::Create(const WebContents::CreateParams& params) { 208 WebContents* WebContents::Create(const WebContents::CreateParams& params) {
249 return WebContentsImpl::CreateWithOpener( 209 return WebContentsImpl::CreateWithOpener(
250 params, static_cast<WebContentsImpl*>(params.opener)); 210 params, static_cast<WebContentsImpl*>(params.opener));
251 } 211 }
252 212
253 WebContents* WebContents::CreateWithSessionStorage( 213 WebContents* WebContents::CreateWithSessionStorage(
254 const WebContents::CreateParams& params, 214 const WebContents::CreateParams& params,
(...skipping 2675 matching lines...) Expand 10 before | Expand all | Expand 10 after
2930 // This method should never be called when the frame is loading. 2890 // This method should never be called when the frame is loading.
2931 // Unfortunately, it can happen if a history navigation happens during a 2891 // Unfortunately, it can happen if a history navigation happens during a
2932 // BeforeUnload or Unload event. 2892 // BeforeUnload or Unload event.
2933 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been 2893 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been
2934 // refactored in Blink. See crbug.com/466089 2894 // refactored in Blink. See crbug.com/466089
2935 if (rfh->is_loading()) { 2895 if (rfh->is_loading()) {
2936 LOG(WARNING) << "OnDidStartLoading was called twice."; 2896 LOG(WARNING) << "OnDidStartLoading was called twice.";
2937 return; 2897 return;
2938 } 2898 }
2939 2899
2940 if (!IsFrameTreeLoading(frame_tree_)) 2900 if (!frame_tree_.IsLoading())
2941 DidStartLoading(rfh, to_different_document); 2901 DidStartLoading(rfh, to_different_document);
2942 2902
2943 rfh->set_is_loading(true); 2903 rfh->set_is_loading(true);
2944 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressMinimum); 2904
2905 FrameTreeNode* ftn = rfh->frame_tree_node();
2906 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressMinimum);
2945 2907
2946 // Notify the RenderFrameHostManager of the event. 2908 // Notify the RenderFrameHostManager of the event.
2947 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); 2909 ftn->render_manager()->OnDidStartLoading();
2948 2910
2949 SendLoadProgressChanged(); 2911 SendLoadProgressChanged();
2950 } 2912 }
2951 2913
2952 void WebContentsImpl::OnDidStopLoading() { 2914 void WebContentsImpl::OnDidStopLoading() {
2953 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2915 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
2954 // fixed. 2916 // fixed.
2955 tracked_objects::ScopedTracker tracking_profile1( 2917 tracked_objects::ScopedTracker tracking_profile1(
2956 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2918 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2957 "465796 WebContentsImpl::OnDidStopLoading::Start")); 2919 "465796 WebContentsImpl::OnDidStopLoading::Start"));
2958 2920
2959 if (!HasValidFrameSource()) 2921 if (!HasValidFrameSource())
2960 return; 2922 return;
2961 2923
2962 RenderFrameHostImpl* rfh = 2924 RenderFrameHostImpl* rfh =
2963 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2925 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2964 2926
2965 // This method should never be called when the frame is not loading. 2927 // This method should never be called when the frame is not loading.
2966 // Unfortunately, it can happen if a history navigation happens during a 2928 // Unfortunately, it can happen if a history navigation happens during a
2967 // BeforeUnload or Unload event. 2929 // BeforeUnload or Unload event.
2968 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been 2930 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been
2969 // refactored in Blink. See crbug.com/466089 2931 // refactored in Blink. See crbug.com/466089
2970 if (!rfh->is_loading()) { 2932 if (!rfh->is_loading()) {
2971 LOG(WARNING) << "OnDidStopLoading was called twice."; 2933 LOG(WARNING) << "OnDidStopLoading was called twice.";
2972 return; 2934 return;
2973 } 2935 }
2974 2936
2975 rfh->set_is_loading(false); 2937 rfh->set_is_loading(false);
2976 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressDone); 2938
2939 FrameTreeNode* ftn = rfh->frame_tree_node();
2940 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressDone);
2977 2941
2978 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2942 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
2979 // fixed. 2943 // fixed.
2980 tracked_objects::ScopedTracker tracking_profile2( 2944 tracked_objects::ScopedTracker tracking_profile2(
2981 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2945 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2982 "465796 " 2946 "465796 "
2983 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); 2947 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged"));
2984 2948
2985 // Update progress based on this frame's completion. 2949 // Update progress based on this frame's completion.
2986 SendLoadProgressChanged(); 2950 SendLoadProgressChanged();
2987 2951
2988 // Then clean-up the states. 2952 // Then clean-up the states.
2989 if (loading_total_progress_ == 1.0) 2953 if (loading_total_progress_ == 1.0)
2990 ResetLoadProgressState(); 2954 ResetLoadProgressState();
2991 2955
2992 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2956 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
2993 // fixed. 2957 // fixed.
2994 tracked_objects::ScopedTracker tracking_profile3( 2958 tracked_objects::ScopedTracker tracking_profile3(
2995 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2959 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2996 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); 2960 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager"));
2997 // Notify the RenderFrameHostManager of the event. 2961 // Notify the RenderFrameHostManager of the event.
2998 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); 2962 ftn->render_manager()->OnDidStopLoading();
2999 2963
3000 if (!IsFrameTreeLoading(frame_tree_)) { 2964 if (!frame_tree_.IsLoading()) {
3001 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2965 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3002 // fixed. 2966 // fixed.
3003 tracked_objects::ScopedTracker tracking_profile4( 2967 tracked_objects::ScopedTracker tracking_profile4(
3004 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2968 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3005 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); 2969 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading"));
3006 DidStopLoading(); 2970 DidStopLoading();
3007 } 2971 }
3008 2972
3009 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is 2973 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is
3010 // fixed. 2974 // fixed.
3011 tracked_objects::ScopedTracker tracking_profile4( 2975 tracked_objects::ScopedTracker tracking_profile4(
3012 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2976 FROM_HERE_WITH_EXPLICIT_FUNCTION(
3013 "465796 WebContentsImpl::OnDidStopLoading::End")); 2977 "465796 WebContentsImpl::OnDidStopLoading::End"));
3014 } 2978 }
3015 2979
3016 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { 2980 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
3017 if (!HasValidFrameSource()) 2981 if (!HasValidFrameSource())
3018 return; 2982 return;
3019 2983
3020 RenderFrameHostImpl* rfh = 2984 RenderFrameHostImpl* rfh =
3021 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2985 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2986 FrameTreeNode* ftn = rfh->frame_tree_node();
3022 2987
3023 rfh->set_loading_progress(load_progress); 2988 ftn->set_loading_progress(load_progress);
3024 2989
3025 // We notify progress change immediately for the first and last updates. 2990 // We notify progress change immediately for the first and last updates.
3026 // Also, since the message loop may be pretty busy when a page is loaded, it 2991 // Also, since the message loop may be pretty busy when a page is loaded, it
3027 // might not execute a posted task in a timely manner so we make sure to 2992 // might not execute a posted task in a timely manner so we make sure to
3028 // immediately send progress report if enough time has passed. 2993 // immediately send progress report if enough time has passed.
3029 base::TimeDelta min_delay = 2994 base::TimeDelta min_delay =
3030 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); 2995 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
3031 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || 2996 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
3032 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { 2997 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
3033 // If there is a pending task to send progress, it is now obsolete. 2998 // 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
3487 NotificationService::current()->Notify( 3452 NotificationService::current()->Notify(
3488 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 3453 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
3489 Source<WebContents>(this), 3454 Source<WebContents>(this),
3490 Details<std::pair<NavigationEntry*, bool> >(&details)); 3455 Details<std::pair<NavigationEntry*, bool> >(&details));
3491 3456
3492 return true; 3457 return true;
3493 } 3458 }
3494 3459
3495 void WebContentsImpl::SendLoadProgressChanged() { 3460 void WebContentsImpl::SendLoadProgressChanged() {
3496 loading_last_progress_update_ = base::TimeTicks::Now(); 3461 loading_last_progress_update_ = base::TimeTicks::Now();
3497 double progress = 0.0; 3462 double progress = frame_tree_.GetLoadProgress();
3498 int frame_count = 0;
3499 3463
3500 frame_tree_.ForEach(
3501 base::Bind(&CollectLoadProgress, &progress, &frame_count));
3502 if (frame_count != 0)
3503 progress /= frame_count;
3504 DCHECK_LE(progress, 1.0); 3464 DCHECK_LE(progress, 1.0);
3505 3465
3506 if (progress <= loading_total_progress_) 3466 if (progress <= loading_total_progress_)
3507 return; 3467 return;
3508 loading_total_progress_ = progress; 3468 loading_total_progress_ = progress;
3509 3469
3510 if (delegate_) 3470 if (delegate_)
3511 delegate_->LoadProgressChanged(this, progress); 3471 delegate_->LoadProgressChanged(this, progress);
3512 } 3472 }
3513 3473
3514 void WebContentsImpl::ResetLoadProgressState() { 3474 void WebContentsImpl::ResetLoadProgressState() {
3515 frame_tree_.ForEach(base::Bind(&ResetLoadProgress)); 3475 frame_tree_.ResetLoadProgress();
3516 loading_total_progress_ = 0.0; 3476 loading_total_progress_ = 0.0;
3517 loading_weak_factory_.InvalidateWeakPtrs(); 3477 loading_weak_factory_.InvalidateWeakPtrs();
3518 loading_last_progress_update_ = base::TimeTicks(); 3478 loading_last_progress_update_ = base::TimeTicks();
3519 } 3479 }
3520 3480
3521 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, 3481 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
3522 RenderViewHost* new_host) { 3482 RenderViewHost* new_host) {
3523 // After sending out a swap notification, we need to send a disconnect 3483 // After sending out a swap notification, we need to send a disconnect
3524 // notification so that clients that pick up a pointer to |this| can NULL the 3484 // notification so that clients that pick up a pointer to |this| can NULL the
3525 // pointer. See Bug 1230284. 3485 // pointer. See Bug 1230284.
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after
4622 node->render_manager()->ResumeResponseDeferredAtStart(); 4582 node->render_manager()->ResumeResponseDeferredAtStart();
4623 } 4583 }
4624 4584
4625 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { 4585 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
4626 force_disable_overscroll_content_ = force_disable; 4586 force_disable_overscroll_content_ = force_disable;
4627 if (view_) 4587 if (view_)
4628 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4588 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4629 } 4589 }
4630 4590
4631 } // namespace content 4591 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698