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

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

Issue 983973002: Revert of Refactor the loading tracking logic in WebContentsImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed patch conflict 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 #endif 114 #endif
115 115
116 #if defined(OS_MACOSX) 116 #if defined(OS_MACOSX)
117 #include "base/mac/foundation_util.h" 117 #include "base/mac/foundation_util.h"
118 #endif 118 #endif
119 119
120 namespace content { 120 namespace content {
121 namespace { 121 namespace {
122 122
123 const int kMinimumDelayBetweenLoadingUpdatesMS = 100; 123 const int kMinimumDelayBetweenLoadingUpdatesMS = 100;
124
125 // This matches what Blink's ProgressTracker has traditionally used for a
126 // minimum progress value.
127 const double kMinimumLoadingProgress = 0.1;
128
124 const char kDotGoogleDotCom[] = ".google.com"; 129 const char kDotGoogleDotCom[] = ".google.com";
125 130
126 #if defined(OS_ANDROID) 131 #if defined(OS_ANDROID)
127 const char kWebContentsAndroidKey[] = "web_contents_android"; 132 const char kWebContentsAndroidKey[] = "web_contents_android";
128 #endif // OS_ANDROID 133 #endif // OS_ANDROID
129 134
130 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > 135 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
131 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; 136 g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
132 137
133 static int StartDownload(RenderFrameHost* rfh, 138 static int StartDownload(RenderFrameHost* rfh,
(...skipping 20 matching lines...) Expand all
154 } 159 }
155 160
156 // Helper function for retrieving all the sites in a frame tree. 161 // Helper function for retrieving all the sites in a frame tree.
157 bool CollectSites(BrowserContext* context, 162 bool CollectSites(BrowserContext* context,
158 std::set<GURL>* sites, 163 std::set<GURL>* sites,
159 FrameTreeNode* node) { 164 FrameTreeNode* node) {
160 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url())); 165 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url()));
161 return true; 166 return true;
162 } 167 }
163 168
164 // Helper function used with FrameTree::ForEach() for retrieving the total
165 // loading progress and number of frames in a frame tree.
166 bool CollectLoadProgress(double* progress,
167 int* frame_count,
168 FrameTreeNode* node) {
169 // Ignore the current frame if it has not started loading.
170 double frame_progress = node->GetLoadingProgress();
171 if (frame_progress == RenderFrameHostImpl::kLoadingProgressNotStarted)
172 return true;
173
174 // Collect progress.
175 *progress += node->GetLoadingProgress();
176 (*frame_count)++;
177 return true;
178 }
179
180 // Helper function used with FrameTree::ForEach() to check if at least one of
181 // the nodes is loading.
182 bool IsNodeLoading(bool* is_loading, FrameTreeNode* node) {
183 if (node->IsLoading()) {
184 // There is at least one node loading, so abort traversal.
185 *is_loading = true;
186 return false;
187 }
188 return true;
189 }
190
191 // Helper function used with FrameTree::ForEach() to reset the load progress.
192 bool ResetLoadProgress(FrameTreeNode* node) {
193 node->current_frame_host()->set_loading_progress(
194 RenderFrameHostImpl::kLoadingProgressNotStarted);
195 return true;
196 }
197
198 bool ForEachFrameInternal( 169 bool ForEachFrameInternal(
199 const base::Callback<void(RenderFrameHost*)>& on_frame, 170 const base::Callback<void(RenderFrameHost*)>& on_frame,
200 FrameTreeNode* node) { 171 FrameTreeNode* node) {
201 on_frame.Run(node->current_frame_host()); 172 on_frame.Run(node->current_frame_host());
202 return true; 173 return true;
203 } 174 }
204 175
205 bool ForEachPendingFrameInternal( 176 bool ForEachPendingFrameInternal(
206 const base::Callback<void(RenderFrameHost*)>& on_frame, 177 const base::Callback<void(RenderFrameHost*)>& on_frame,
207 FrameTreeNode* node) { 178 FrameTreeNode* node) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // termination is not allowed for the current RenderFrameHost of 220 // termination is not allowed for the current RenderFrameHost of
250 // |frame_tree_node|. Used with FrameTree::ForEach. 221 // |frame_tree_node|. Used with FrameTree::ForEach.
251 bool SuddenTerminationAllowed(bool* sudden_termination_allowed, 222 bool SuddenTerminationAllowed(bool* sudden_termination_allowed,
252 FrameTreeNode* frame_tree_node) { 223 FrameTreeNode* frame_tree_node) {
253 if (frame_tree_node->current_frame_host()->SuddenTerminationAllowed()) 224 if (frame_tree_node->current_frame_host()->SuddenTerminationAllowed())
254 return true; 225 return true;
255 *sudden_termination_allowed = false; 226 *sudden_termination_allowed = false;
256 return false; 227 return false;
257 } 228 }
258 229
259 // Returns true if at least one of the nodes in the |frame_tree| is loading.
260 bool IsFrameTreeLoading(FrameTree& frame_tree) {
261 bool is_loading = false;
262 frame_tree.ForEach(base::Bind(&IsNodeLoading, &is_loading));
263 return is_loading;
264 }
265
266 } // namespace 230 } // namespace
267 231
268 WebContents* WebContents::Create(const WebContents::CreateParams& params) { 232 WebContents* WebContents::Create(const WebContents::CreateParams& params) {
269 return WebContentsImpl::CreateWithOpener( 233 return WebContentsImpl::CreateWithOpener(
270 params, static_cast<WebContentsImpl*>(params.opener)); 234 params, static_cast<WebContentsImpl*>(params.opener));
271 } 235 }
272 236
273 WebContents* WebContents::CreateWithSessionStorage( 237 WebContents* WebContents::CreateWithSessionStorage(
274 const WebContents::CreateParams& params, 238 const WebContents::CreateParams& params,
275 const SessionStorageNamespaceMap& session_storage_namespace_map) { 239 const SessionStorageNamespaceMap& session_storage_namespace_map) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 this, 329 this,
366 this, 330 this,
367 this), 331 this),
368 is_loading_(false), 332 is_loading_(false),
369 is_load_to_different_document_(false), 333 is_load_to_different_document_(false),
370 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), 334 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
371 crashed_error_code_(0), 335 crashed_error_code_(0),
372 waiting_for_response_(false), 336 waiting_for_response_(false),
373 load_state_(net::LOAD_STATE_IDLE, base::string16()), 337 load_state_(net::LOAD_STATE_IDLE, base::string16()),
374 loading_total_progress_(0.0), 338 loading_total_progress_(0.0),
339 loading_frames_in_progress_(0),
375 upload_size_(0), 340 upload_size_(0),
376 upload_position_(0), 341 upload_position_(0),
377 displayed_insecure_content_(false), 342 displayed_insecure_content_(false),
378 has_accessed_initial_document_(false), 343 has_accessed_initial_document_(false),
379 theme_color_(SK_ColorTRANSPARENT), 344 theme_color_(SK_ColorTRANSPARENT),
380 last_sent_theme_color_(SK_ColorTRANSPARENT), 345 last_sent_theme_color_(SK_ColorTRANSPARENT),
381 capturer_count_(0), 346 capturer_count_(0),
382 should_normally_be_visible_(true), 347 should_normally_be_visible_(true),
383 is_being_destroyed_(false), 348 is_being_destroyed_(false),
384 notify_disconnection_(false), 349 notify_disconnection_(false),
(...skipping 2519 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 FOR_EACH_OBSERVER( 2869 FOR_EACH_OBSERVER(
2905 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url)); 2870 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url));
2906 } 2871 }
2907 2872
2908 void WebContentsImpl::OnDidStartLoading(bool to_different_document) { 2873 void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
2909 if (!HasValidFrameSource()) 2874 if (!HasValidFrameSource())
2910 return; 2875 return;
2911 2876
2912 RenderFrameHostImpl* rfh = 2877 RenderFrameHostImpl* rfh =
2913 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2878 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2879 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2914 2880
2915 // Any main frame load to a new document should reset the load progress, since 2881 // Any main frame load to a new document should reset the load progress, since
2916 // it will replace the current page and any frames. 2882 // it will replace the current page and any frames.
2917 if (to_different_document && !rfh->GetParent()) { 2883 if (to_different_document && !rfh->GetParent()) {
2918 ResetLoadProgressState(); 2884 ResetLoadProgressState();
2919 rfh->set_is_loading(false); 2885 loading_frames_in_progress_ = 0;
2886 rfh->frame_tree_node()->set_is_loading(false);
2920 } 2887 }
2921 2888
2922 // This method should never be called when the frame is loading. 2889 // It is possible to get multiple calls to OnDidStartLoading that don't have
2923 DCHECK(!rfh->is_loading()); 2890 // corresponding calls to OnDidStopLoading:
2891 // - With "swappedout://" URLs, this happens when a RenderView gets swapped
2892 // out for a cross-process navigation, and it turns into a placeholder for
2893 // one being rendered in a different process.
2894 // - Also, there might be more than one RenderFrameHost sharing the same
2895 // FrameTreeNode (and thus sharing its ID) each sending a start.
2896 // - But in the future, once clamy@ moves navigation network requests to the
2897 // browser process, there's a good chance that callbacks about starting and
2898 // stopping will all be handled by the browser. When that happens, there
2899 // should no longer be a start/stop call imbalance. TODO(avi): When this
2900 // future arrives, update this code to not allow this case.
2901 if (rfh->frame_tree_node()->is_loading())
2902 return;
2924 2903
2925 if (!IsFrameTreeLoading(frame_tree_)) 2904 DCHECK_GE(loading_frames_in_progress_, 0);
2905 if (loading_frames_in_progress_ == 0)
2926 DidStartLoading(rfh, to_different_document); 2906 DidStartLoading(rfh, to_different_document);
2927 2907
2928 rfh->set_is_loading(true); 2908 ++loading_frames_in_progress_;
2929 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressMinimum); 2909 rfh->frame_tree_node()->set_is_loading(true);
2930 2910
2931 // Notify the RenderFrameHostManager of the event. 2911 // Notify the RenderFrameHostManager of the event.
2932 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); 2912 rfh->frame_tree_node()->render_manager()->OnDidStartLoading();
2933 2913
2914 loading_progresses_[render_frame_id] = kMinimumLoadingProgress;
2934 SendLoadProgressChanged(); 2915 SendLoadProgressChanged();
2935 } 2916 }
2936 2917
2937 void WebContentsImpl::OnDidStopLoading() { 2918 void WebContentsImpl::OnDidStopLoading() {
2938 if (!HasValidFrameSource()) 2919 if (!HasValidFrameSource())
2939 return; 2920 return;
2940 2921
2941 RenderFrameHostImpl* rfh = 2922 RenderFrameHostImpl* rfh =
2942 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2923 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2924 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2925 rfh->frame_tree_node()->set_is_loading(false);
2943 2926
2944 // This method should never be called when the frame is not loading. 2927 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) {
2945 DCHECK(rfh->is_loading()); 2928 // Load stopped while we were still tracking load. Make sure we update
2946 rfh->set_is_loading(false); 2929 // progress based on this frame's completion.
2947 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressDone); 2930 loading_progresses_[render_frame_id] = 1.0;
2948 2931 SendLoadProgressChanged();
2949 // Update progress based on this frame's completion. 2932 // Then we clean-up our states.
2950 SendLoadProgressChanged(); 2933 if (loading_total_progress_ == 1.0)
2951 2934 ResetLoadProgressState();
2952 // Then clean-up the states. 2935 }
2953 if (loading_total_progress_ == 1.0)
2954 ResetLoadProgressState();
2955 2936
2956 // Notify the RenderFrameHostManager of the event. 2937 // Notify the RenderFrameHostManager of the event.
2957 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); 2938 rfh->frame_tree_node()->render_manager()->OnDidStopLoading();
2958 2939
2959 if (!IsFrameTreeLoading(frame_tree_)) 2940 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
2941 // calls DidStopLoading() without a matching DidStartLoading().
2942 if (loading_frames_in_progress_ == 0)
2943 return;
2944 --loading_frames_in_progress_;
2945 if (loading_frames_in_progress_ == 0)
2960 DidStopLoading(rfh); 2946 DidStopLoading(rfh);
2961 } 2947 }
2962 2948
2963 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { 2949 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
2964 if (!HasValidFrameSource()) 2950 if (!HasValidFrameSource())
2965 return; 2951 return;
2966 2952
2967 RenderFrameHostImpl* rfh = 2953 RenderFrameHostImpl* rfh =
2968 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2954 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2955 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2969 2956
2970 rfh->set_loading_progress(load_progress); 2957 loading_progresses_[render_frame_id] = load_progress;
2971 2958
2972 // We notify progress change immediately for the first and last updates. 2959 // We notify progress change immediately for the first and last updates.
2973 // Also, since the message loop may be pretty busy when a page is loaded, it 2960 // Also, since the message loop may be pretty busy when a page is loaded, it
2974 // might not execute a posted task in a timely manner so we make sure to 2961 // might not execute a posted task in a timely manner so we make sure to
2975 // immediately send progress report if enough time has passed. 2962 // immediately send progress report if enough time has passed.
2976 base::TimeDelta min_delay = 2963 base::TimeDelta min_delay =
2977 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); 2964 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
2978 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || 2965 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
2979 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { 2966 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
2980 // If there is a pending task to send progress, it is now obsolete. 2967 // If there is a pending task to send progress, it is now obsolete.
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
3445 Details<std::pair<NavigationEntry*, bool> >(&details)); 3432 Details<std::pair<NavigationEntry*, bool> >(&details));
3446 3433
3447 return true; 3434 return true;
3448 } 3435 }
3449 3436
3450 void WebContentsImpl::SendLoadProgressChanged() { 3437 void WebContentsImpl::SendLoadProgressChanged() {
3451 loading_last_progress_update_ = base::TimeTicks::Now(); 3438 loading_last_progress_update_ = base::TimeTicks::Now();
3452 double progress = 0.0; 3439 double progress = 0.0;
3453 int frame_count = 0; 3440 int frame_count = 0;
3454 3441
3455 frame_tree_.ForEach( 3442 for (LoadingProgressMap::iterator it = loading_progresses_.begin();
3456 base::Bind(&CollectLoadProgress, &progress, &frame_count)); 3443 it != loading_progresses_.end();
3457 if (frame_count != 0) 3444 ++it) {
3458 progress /= frame_count; 3445 progress += it->second;
3459 DCHECK_LE(progress, 1.0); 3446 ++frame_count;
3447 }
3448 if (frame_count == 0)
3449 return;
3450 progress /= frame_count;
3451 DCHECK(progress <= 1.0);
3460 3452
3461 if (progress <= loading_total_progress_) 3453 if (progress <= loading_total_progress_)
3462 return; 3454 return;
3463 loading_total_progress_ = progress; 3455 loading_total_progress_ = progress;
3464 3456
3465 if (delegate_) 3457 if (delegate_)
3466 delegate_->LoadProgressChanged(this, progress); 3458 delegate_->LoadProgressChanged(this, progress);
3467 } 3459 }
3468 3460
3469 void WebContentsImpl::ResetLoadProgressState() { 3461 void WebContentsImpl::ResetLoadProgressState() {
3470 frame_tree_.ForEach(base::Bind(&ResetLoadProgress)); 3462 loading_progresses_.clear();
3471 loading_total_progress_ = 0.0; 3463 loading_total_progress_ = 0.0;
3472 loading_weak_factory_.InvalidateWeakPtrs(); 3464 loading_weak_factory_.InvalidateWeakPtrs();
3473 loading_last_progress_update_ = base::TimeTicks(); 3465 loading_last_progress_update_ = base::TimeTicks();
3474 } 3466 }
3475 3467
3476 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, 3468 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
3477 RenderViewHost* new_host) { 3469 RenderViewHost* new_host) {
3478 // After sending out a swap notification, we need to send a disconnect 3470 // After sending out a swap notification, we need to send a disconnect
3479 // notification so that clients that pick up a pointer to |this| can NULL the 3471 // notification so that clients that pick up a pointer to |this| can NULL the
3480 // pointer. See Bug 1230284. 3472 // pointer. See Bug 1230284.
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
3765 3757
3766 SetIsLoading(rvh, false, true, NULL); 3758 SetIsLoading(rvh, false, true, NULL);
3767 NotifyDisconnected(); 3759 NotifyDisconnected();
3768 SetIsCrashed(status, error_code); 3760 SetIsCrashed(status, error_code);
3769 3761
3770 // Reset the loading progress. TODO(avi): What does it mean to have a 3762 // Reset the loading progress. TODO(avi): What does it mean to have a
3771 // "renderer crash" when there is more than one renderer process serving a 3763 // "renderer crash" when there is more than one renderer process serving a
3772 // webpage? Once this function is called at a more granular frame level, we 3764 // webpage? Once this function is called at a more granular frame level, we
3773 // probably will need to more granularly reset the state here. 3765 // probably will need to more granularly reset the state here.
3774 ResetLoadProgressState(); 3766 ResetLoadProgressState();
3767 loading_frames_in_progress_ = 0;
3775 3768
3776 FOR_EACH_OBSERVER(WebContentsObserver, 3769 FOR_EACH_OBSERVER(WebContentsObserver,
3777 observers_, 3770 observers_,
3778 RenderProcessGone(GetCrashedStatus())); 3771 RenderProcessGone(GetCrashedStatus()));
3779 } 3772 }
3780 3773
3781 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { 3774 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
3782 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh)); 3775 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
3783 } 3776 }
3784 3777
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
4563 node->render_manager()->ResumeResponseDeferredAtStart(); 4556 node->render_manager()->ResumeResponseDeferredAtStart();
4564 } 4557 }
4565 4558
4566 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { 4559 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
4567 force_disable_overscroll_content_ = force_disable; 4560 force_disable_overscroll_content_ = force_disable;
4568 if (view_) 4561 if (view_)
4569 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4562 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4570 } 4563 }
4571 4564
4572 } // namespace content 4565 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/browser/web_contents/web_contents_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698