OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |