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

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

Issue 925623002: Refactor the loading tracking logic in WebContentsImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 for retrieving the total loading progress
Charlie Reis 2015/02/13 01:01:51 nit: Please try to wrap lines closer to 80 chars f
carlosk 2015/02/13 15:05:41 Note: git cl format does *not* do a good job when
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 Done.
169 // and number of frames in a frame tree.
170 bool CollectProgress(double* progress, int* frame_count, FrameTreeNode* node) {
Charlie Reis 2015/02/13 01:01:51 nit: This name is a bit ambiguous. Maybe CollectL
Fabrice (no longer in Chrome) 2015/02/13 18:04:24 Done.
171 *progress += node->get_loading_progress();
172 (*frame_count)++;
173 return true;
174 }
175
176 // Helper function to check if a node is loading.
carlosk 2015/02/13 15:05:41 I'd suggest: Used with FrameTree::ForEach() to che
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 That's exactly what is being done. These are the f
carlosk 2015/02/16 11:40:21 I was suggesting a new way to phrase your comment.
Fabrice (no longer in Chrome) 2015/02/20 12:58:58 Done.
177 bool IsNodeLoading(bool* is_loading, FrameTreeNode* node) {
178 if (node->is_loading()) {
179 *is_loading = true;
180 return false;
Charlie Reis 2015/02/13 01:01:51 nit: Put a comment here saying that this aborts th
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 Done.
181 }
182 return true;
183 }
184
168 bool ForEachFrameInternal( 185 bool ForEachFrameInternal(
169 const base::Callback<void(RenderFrameHost*)>& on_frame, 186 const base::Callback<void(RenderFrameHost*)>& on_frame,
170 FrameTreeNode* node) { 187 FrameTreeNode* node) {
171 on_frame.Run(node->current_frame_host()); 188 on_frame.Run(node->current_frame_host());
172 return true; 189 return true;
173 } 190 }
174 191
175 bool ForEachPendingFrameInternal( 192 bool ForEachPendingFrameInternal(
176 const base::Callback<void(RenderFrameHost*)>& on_frame, 193 const base::Callback<void(RenderFrameHost*)>& on_frame,
177 FrameTreeNode* node) { 194 FrameTreeNode* node) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 this, 345 this,
329 this, 346 this,
330 this), 347 this),
331 is_loading_(false), 348 is_loading_(false),
332 is_load_to_different_document_(false), 349 is_load_to_different_document_(false),
333 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), 350 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
334 crashed_error_code_(0), 351 crashed_error_code_(0),
335 waiting_for_response_(false), 352 waiting_for_response_(false),
336 load_state_(net::LOAD_STATE_IDLE, base::string16()), 353 load_state_(net::LOAD_STATE_IDLE, base::string16()),
337 loading_total_progress_(0.0), 354 loading_total_progress_(0.0),
338 loading_frames_in_progress_(0),
339 upload_size_(0), 355 upload_size_(0),
340 upload_position_(0), 356 upload_position_(0),
341 displayed_insecure_content_(false), 357 displayed_insecure_content_(false),
342 has_accessed_initial_document_(false), 358 has_accessed_initial_document_(false),
343 capturer_count_(0), 359 capturer_count_(0),
344 should_normally_be_visible_(true), 360 should_normally_be_visible_(true),
345 is_being_destroyed_(false), 361 is_being_destroyed_(false),
346 notify_disconnection_(false), 362 notify_disconnection_(false),
347 dialog_manager_(NULL), 363 dialog_manager_(NULL),
348 is_showing_before_unload_dialog_(false), 364 is_showing_before_unload_dialog_(false),
(...skipping 2473 matching lines...) Expand 10 before | Expand all | Expand 10 after
2822 FOR_EACH_OBSERVER( 2838 FOR_EACH_OBSERVER(
2823 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url)); 2839 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url));
2824 } 2840 }
2825 2841
2826 void WebContentsImpl::OnDidStartLoading(bool to_different_document) { 2842 void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
2827 if (!HasValidFrameSource()) 2843 if (!HasValidFrameSource())
2828 return; 2844 return;
2829 2845
2830 RenderFrameHostImpl* rfh = 2846 RenderFrameHostImpl* rfh =
2831 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2847 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2832 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2833 2848
2834 // Any main frame load to a new document should reset the load progress, since 2849 // Any main frame load to a new document should reset the load progress, since
2835 // it will replace the current page and any frames. 2850 // it will replace the current page and any frames.
2836 if (to_different_document && !rfh->GetParent()) { 2851 if (to_different_document && !rfh->GetParent()) {
2837 ResetLoadProgressState(); 2852 ResetLoadProgressState();
2838 loading_frames_in_progress_ = 0;
2839 rfh->frame_tree_node()->set_is_loading(false); 2853 rfh->frame_tree_node()->set_is_loading(false);
2840 } 2854 }
2841 2855
2842 // It is possible to get multiple calls to OnDidStartLoading that don't have 2856 // It is possible to get multiple calls to OnDidStartLoading that don't have
2843 // corresponding calls to OnDidStopLoading: 2857 // corresponding calls to OnDidStopLoading:
2844 // - With "swappedout://" URLs, this happens when a RenderView gets swapped 2858 // - With "swappedout://" URLs, this happens when a RenderView gets swapped
2845 // out for a cross-process navigation, and it turns into a placeholder for 2859 // out for a cross-process navigation, and it turns into a placeholder for
2846 // one being rendered in a different process. 2860 // one being rendered in a different process.
2847 // - Also, there might be more than one RenderFrameHost sharing the same 2861 // - Also, there might be more than one RenderFrameHost sharing the same
2848 // FrameTreeNode (and thus sharing its ID) each sending a start. 2862 // FrameTreeNode (and thus sharing its ID) each sending a start.
2849 // - But in the future, once clamy@ moves navigation network requests to the 2863 // - But in the future, once clamy@ moves navigation network requests to the
2850 // browser process, there's a good chance that callbacks about starting and 2864 // browser process, there's a good chance that callbacks about starting and
2851 // stopping will all be handled by the browser. When that happens, there 2865 // stopping will all be handled by the browser. When that happens, there
2852 // should no longer be a start/stop call imbalance. TODO(avi): When this 2866 // should no longer be a start/stop call imbalance. TODO(avi): When this
2853 // future arrives, update this code to not allow this case. 2867 // future arrives, update this code to not allow this case.
2854 if (rfh->frame_tree_node()->is_loading()) 2868 if (rfh->frame_tree_node()->is_loading())
2855 return; 2869 return;
2856 2870
2857 DCHECK_GE(loading_frames_in_progress_, 0); 2871 if (!IsTreeLoading())
2858 if (loading_frames_in_progress_ == 0)
2859 DidStartLoading(rfh, to_different_document); 2872 DidStartLoading(rfh, to_different_document);
2860 2873
2861 ++loading_frames_in_progress_;
2862 rfh->frame_tree_node()->set_is_loading(true); 2874 rfh->frame_tree_node()->set_is_loading(true);
2863 2875
2864 // Notify the RenderFrameHostManager of the event. 2876 // Notify the RenderFrameHostManager of the event.
2865 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); 2877 rfh->frame_tree_node()->render_manager()->OnDidStartLoading();
2866 2878
2867 loading_progresses_[render_frame_id] = kMinimumLoadingProgress; 2879 rfh->frame_tree_node()->set_loading_progress(kMinimumLoadingProgress);
2868 SendLoadProgressChanged(); 2880 SendLoadProgressChanged();
2869 } 2881 }
2870 2882
2871 void WebContentsImpl::OnDidStopLoading() { 2883 void WebContentsImpl::OnDidStopLoading() {
2872 if (!HasValidFrameSource()) 2884 if (!HasValidFrameSource())
2873 return; 2885 return;
2874 2886
2875 RenderFrameHostImpl* rfh = 2887 RenderFrameHostImpl* rfh =
2876 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2888 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2877 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2878 rfh->frame_tree_node()->set_is_loading(false);
2879 2889
2880 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) { 2890 // Load stopped while the load was still being tracked.
Charlie Reis 2015/02/13 01:01:51 This comment doesn't make sense if it's not within
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 My understanding of this test is that it really sh
2881 // Load stopped while we were still tracking load. Make sure we update 2891 // Make sure the progress is updated based on this frame's completion.
2882 // progress based on this frame's completion. 2892 rfh->frame_tree_node()->set_loading_progress(1.0);
2883 loading_progresses_[render_frame_id] = 1.0; 2893 SendLoadProgressChanged();
2884 SendLoadProgressChanged(); 2894 // Then clean-up the states.
2885 // Then we clean-up our states. 2895 if (loading_total_progress_ == 1.0)
2886 if (loading_total_progress_ == 1.0) 2896 ResetLoadProgressState();
2887 ResetLoadProgressState();
2888 }
2889 2897
2890 // Notify the RenderFrameHostManager of the event. 2898 // Notify the RenderFrameHostManager of the event.
2891 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); 2899 rfh->frame_tree_node()->render_manager()->OnDidStopLoading();
2892 2900
2893 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes 2901 // TODO(japhet): This test should not exist, but the pdf plugin sometimes
nasko 2015/02/13 00:16:29 nit: s/test/check/
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 Done.
2894 // calls DidStopLoading() without a matching DidStartLoading(). 2902 // calls DidStopLoading() without a matching DidStartLoading().
2895 if (loading_frames_in_progress_ == 0) 2903 if (!IsTreeLoading())
2896 return; 2904 return;
2897 --loading_frames_in_progress_; 2905
2898 if (loading_frames_in_progress_ == 0) 2906 rfh->frame_tree_node()->set_is_loading(false);
2907 if (!IsTreeLoading())
carlosk 2015/02/13 15:05:41 Suggestion: IsTreeLoading could return the number
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 This is no longer necessary since I am removing th
2899 DidStopLoading(rfh); 2908 DidStopLoading(rfh);
2900 } 2909 }
2901 2910
2902 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { 2911 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
2903 if (!HasValidFrameSource()) 2912 if (!HasValidFrameSource())
2904 return; 2913 return;
2905 2914
2906 RenderFrameHostImpl* rfh = 2915 RenderFrameHostImpl* rfh =
2907 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2916 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2908 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2909 2917
2910 loading_progresses_[render_frame_id] = load_progress; 2918 rfh->frame_tree_node()->set_loading_progress(load_progress);
2911 2919
2912 // We notify progress change immediately for the first and last updates. 2920 // We notify progress change immediately for the first and last updates.
2913 // Also, since the message loop may be pretty busy when a page is loaded, it 2921 // Also, since the message loop may be pretty busy when a page is loaded, it
2914 // might not execute a posted task in a timely manner so we make sure to 2922 // might not execute a posted task in a timely manner so we make sure to
2915 // immediately send progress report if enough time has passed. 2923 // immediately send progress report if enough time has passed.
2916 base::TimeDelta min_delay = 2924 base::TimeDelta min_delay =
2917 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); 2925 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
2918 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || 2926 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
2919 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { 2927 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
2920 // If there is a pending task to send progress, it is now obsolete.
2921 loading_weak_factory_.InvalidateWeakPtrs();
Charlie Reis 2015/02/13 01:01:51 Why is this safe to remove? Is the factory still
Fabrice (no longer in Chrome) 2015/02/13 18:04:25 Because I fail to merge my local branches. Fixed,
2922 SendLoadProgressChanged(); 2928 SendLoadProgressChanged();
2923 if (loading_total_progress_ == 1.0) 2929 if (loading_total_progress_ == 1.0)
2924 ResetLoadProgressState(); 2930 ResetLoadProgressState();
2925 return; 2931 return;
2926 } 2932 }
2927 2933
2928 if (loading_weak_factory_.HasWeakPtrs())
2929 return;
2930
2931 base::MessageLoop::current()->PostDelayedTask( 2934 base::MessageLoop::current()->PostDelayedTask(
2932 FROM_HERE, 2935 FROM_HERE,
2933 base::Bind(&WebContentsImpl::SendLoadProgressChanged, 2936 base::Bind(&WebContentsImpl::SendLoadProgressChanged,
2934 loading_weak_factory_.GetWeakPtr()), 2937 loading_weak_factory_.GetWeakPtr()),
2935 min_delay); 2938 min_delay);
2936 } 2939 }
2937 2940
2938 void WebContentsImpl::OnGoToEntryAtOffset(int offset) { 2941 void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
2939 if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) 2942 if (!delegate_ || delegate_->OnGoToEntryOffset(offset))
2940 controller_.GoToOffset(offset); 2943 controller_.GoToOffset(offset);
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
3381 Details<std::pair<NavigationEntry*, bool> >(&details)); 3384 Details<std::pair<NavigationEntry*, bool> >(&details));
3382 3385
3383 return true; 3386 return true;
3384 } 3387 }
3385 3388
3386 void WebContentsImpl::SendLoadProgressChanged() { 3389 void WebContentsImpl::SendLoadProgressChanged() {
3387 loading_last_progress_update_ = base::TimeTicks::Now(); 3390 loading_last_progress_update_ = base::TimeTicks::Now();
3388 double progress = 0.0; 3391 double progress = 0.0;
3389 int frame_count = 0; 3392 int frame_count = 0;
3390 3393
3391 for (LoadingProgressMap::iterator it = loading_progresses_.begin(); 3394 frame_tree_.ForEach(base::Bind(&CollectProgress, &progress, &frame_count));
3392 it != loading_progresses_.end();
3393 ++it) {
3394 progress += it->second;
3395 ++frame_count;
3396 }
3397 if (frame_count == 0) 3395 if (frame_count == 0)
carlosk 2015/02/13 15:05:41 With your implementation it seems that this if wou
Fabrice (no longer in Chrome) 2015/02/20 12:58:58 Done. But will need to double-check if we're doing
3398 return; 3396 return;
3399 progress /= frame_count; 3397 progress /= frame_count;
3400 DCHECK(progress <= 1.0); 3398 DCHECK(progress <= 1.0);
3401 3399
3402 if (progress <= loading_total_progress_) 3400 if (progress <= loading_total_progress_)
3403 return; 3401 return;
3404 loading_total_progress_ = progress; 3402 loading_total_progress_ = progress;
3405 3403
3406 if (delegate_) 3404 if (delegate_)
3407 delegate_->LoadProgressChanged(this, progress); 3405 delegate_->LoadProgressChanged(this, progress);
3408 } 3406 }
3409 3407
3410 void WebContentsImpl::ResetLoadProgressState() { 3408 void WebContentsImpl::ResetLoadProgressState() {
3411 loading_progresses_.clear();
clamy 2015/02/13 12:13:43 Is it okay to not reset the loading progress of ea
Fabrice (no longer in Chrome) 2015/02/24 13:14:46 Answered in patch set 4.
3412 loading_total_progress_ = 0.0; 3409 loading_total_progress_ = 0.0;
3413 loading_weak_factory_.InvalidateWeakPtrs();
3414 loading_last_progress_update_ = base::TimeTicks(); 3410 loading_last_progress_update_ = base::TimeTicks();
3415 } 3411 }
3416 3412
3417 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, 3413 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
3418 RenderViewHost* new_host) { 3414 RenderViewHost* new_host) {
3419 // After sending out a swap notification, we need to send a disconnect 3415 // After sending out a swap notification, we need to send a disconnect
3420 // notification so that clients that pick up a pointer to |this| can NULL the 3416 // notification so that clients that pick up a pointer to |this| can NULL the
3421 // pointer. See Bug 1230284. 3417 // pointer. See Bug 1230284.
3422 notify_disconnection_ = true; 3418 notify_disconnection_ = true;
3423 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3419 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 3714
3719 SetIsLoading(rvh, false, true, NULL); 3715 SetIsLoading(rvh, false, true, NULL);
3720 NotifyDisconnected(); 3716 NotifyDisconnected();
3721 SetIsCrashed(status, error_code); 3717 SetIsCrashed(status, error_code);
3722 3718
3723 // Reset the loading progress. TODO(avi): What does it mean to have a 3719 // Reset the loading progress. TODO(avi): What does it mean to have a
3724 // "renderer crash" when there is more than one renderer process serving a 3720 // "renderer crash" when there is more than one renderer process serving a
3725 // webpage? Once this function is called at a more granular frame level, we 3721 // webpage? Once this function is called at a more granular frame level, we
3726 // probably will need to more granularly reset the state here. 3722 // probably will need to more granularly reset the state here.
3727 ResetLoadProgressState(); 3723 ResetLoadProgressState();
3728 loading_frames_in_progress_ = 0;
3729 3724
3730 FOR_EACH_OBSERVER(WebContentsObserver, 3725 FOR_EACH_OBSERVER(WebContentsObserver,
3731 observers_, 3726 observers_,
3732 RenderProcessGone(GetCrashedStatus())); 3727 RenderProcessGone(GetCrashedStatus()));
3733 } 3728 }
3734 3729
3735 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { 3730 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
3736 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh)); 3731 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
3737 } 3732 }
3738 3733
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
4513 FrameTreeNode* node = frame_tree_.root(); 4508 FrameTreeNode* node = frame_tree_.root();
4514 node->render_manager()->ResumeResponseDeferredAtStart(); 4509 node->render_manager()->ResumeResponseDeferredAtStart();
4515 } 4510 }
4516 4511
4517 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { 4512 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
4518 force_disable_overscroll_content_ = force_disable; 4513 force_disable_overscroll_content_ = force_disable;
4519 if (view_) 4514 if (view_)
4520 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4515 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4521 } 4516 }
4522 4517
4518 bool WebContentsImpl::IsTreeLoading() {
4519 bool is_loading = false;
4520 frame_tree_.ForEach(base::Bind(&IsNodeLoading, &is_loading));
4521 return is_loading;
4522 }
4523
4523 } // namespace content 4524 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698