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 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 Loading... | |
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 Loading... | |
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 // The loading progress is only reset when the current RFH starts navigating. | |
2931 FrameTreeNode* ftn = rfh->frame_tree_node(); | |
2932 if (ftn->render_manager()->current_frame_host() == rfh) | |
nasko
2015/03/24 17:26:11
I think this check might be problematic. In browse
Fabrice (no longer in Chrome)
2015/03/25 17:35:01
Following our offline conversation, I removed the
| |
2933 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressMinimum); | |
2970 | 2934 |
2971 // Notify the RenderFrameHostManager of the event. | 2935 // Notify the RenderFrameHostManager of the event. |
2972 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); | 2936 ftn->render_manager()->OnDidStartLoading(); |
2973 | 2937 |
2974 SendLoadProgressChanged(); | 2938 SendLoadProgressChanged(); |
2975 } | 2939 } |
2976 | 2940 |
2977 void WebContentsImpl::OnDidStopLoading() { | 2941 void WebContentsImpl::OnDidStopLoading() { |
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_profile1( | 2944 tracked_objects::ScopedTracker tracking_profile1( |
2981 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2945 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2982 "465796 WebContentsImpl::OnDidStopLoading::Start")); | 2946 "465796 WebContentsImpl::OnDidStopLoading::Start")); |
2983 | 2947 |
2984 if (!HasValidFrameSource()) | 2948 if (!HasValidFrameSource()) |
2985 return; | 2949 return; |
2986 | 2950 |
2987 RenderFrameHostImpl* rfh = | 2951 RenderFrameHostImpl* rfh = |
2988 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2952 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
2989 | 2953 |
2990 // This method should never be called when the frame is not loading. | 2954 // This method should never be called when the frame is not loading. |
2991 // Unfortunately, it can happen if a history navigation happens during a | 2955 // Unfortunately, it can happen if a history navigation happens during a |
2992 // BeforeUnload or Unload event. | 2956 // BeforeUnload or Unload event. |
2993 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been | 2957 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been |
2994 // refactored in Blink. See crbug.com/466089 | 2958 // refactored in Blink. See crbug.com/466089 |
2995 if (!rfh->is_loading()) { | 2959 if (!rfh->is_loading()) { |
2996 LOG(WARNING) << "OnDidStopLoading was called twice."; | 2960 LOG(WARNING) << "OnDidStopLoading was called twice."; |
2997 return; | 2961 return; |
2998 } | 2962 } |
2999 | 2963 |
3000 rfh->set_is_loading(false); | 2964 rfh->set_is_loading(false); |
3001 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressDone); | 2965 |
2966 FrameTreeNode* ftn = rfh->frame_tree_node(); | |
2967 if (ftn->render_manager()->current_frame_host() == rfh) | |
2968 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressDone); | |
3002 | 2969 |
3003 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2970 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
3004 // fixed. | 2971 // fixed. |
3005 tracked_objects::ScopedTracker tracking_profile2( | 2972 tracked_objects::ScopedTracker tracking_profile2( |
3006 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2973 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
3007 "465796 " | 2974 "465796 " |
3008 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); | 2975 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); |
3009 | 2976 |
3010 // Update progress based on this frame's completion. | 2977 // Update progress based on this frame's completion. |
3011 SendLoadProgressChanged(); | 2978 SendLoadProgressChanged(); |
3012 | 2979 |
3013 // Then clean-up the states. | 2980 // Then clean-up the states. |
3014 if (loading_total_progress_ == 1.0) | 2981 if (loading_total_progress_ == 1.0) |
3015 ResetLoadProgressState(); | 2982 ResetLoadProgressState(); |
3016 | 2983 |
3017 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2984 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
3018 // fixed. | 2985 // fixed. |
3019 tracked_objects::ScopedTracker tracking_profile3( | 2986 tracked_objects::ScopedTracker tracking_profile3( |
3020 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2987 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
3021 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); | 2988 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); |
3022 // Notify the RenderFrameHostManager of the event. | 2989 // Notify the RenderFrameHostManager of the event. |
3023 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); | 2990 ftn->render_manager()->OnDidStopLoading(); |
3024 | 2991 |
3025 if (!IsFrameTreeLoading(frame_tree_)) { | 2992 if (!frame_tree_.IsLoading()) { |
3026 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2993 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
3027 // fixed. | 2994 // fixed. |
3028 tracked_objects::ScopedTracker tracking_profile4( | 2995 tracked_objects::ScopedTracker tracking_profile4( |
3029 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2996 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
3030 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); | 2997 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); |
3031 DidStopLoading(); | 2998 DidStopLoading(); |
3032 } | 2999 } |
3033 | 3000 |
3034 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 3001 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
3035 // fixed. | 3002 // fixed. |
3036 tracked_objects::ScopedTracker tracking_profile4( | 3003 tracked_objects::ScopedTracker tracking_profile4( |
3037 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 3004 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
3038 "465796 WebContentsImpl::OnDidStopLoading::End")); | 3005 "465796 WebContentsImpl::OnDidStopLoading::End")); |
3039 } | 3006 } |
3040 | 3007 |
3041 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { | 3008 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { |
3042 if (!HasValidFrameSource()) | 3009 if (!HasValidFrameSource()) |
3043 return; | 3010 return; |
3044 | 3011 |
3045 RenderFrameHostImpl* rfh = | 3012 RenderFrameHostImpl* rfh = |
3046 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 3013 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
3014 FrameTreeNode* ftn = rfh->frame_tree_node(); | |
3047 | 3015 |
3048 rfh->set_loading_progress(load_progress); | 3016 if (ftn->render_manager()->current_frame_host() != rfh) |
3017 return; | |
3018 | |
3019 ftn->set_loading_progress(load_progress); | |
3049 | 3020 |
3050 // We notify progress change immediately for the first and last updates. | 3021 // 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 | 3022 // 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 | 3023 // 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. | 3024 // immediately send progress report if enough time has passed. |
3054 base::TimeDelta min_delay = | 3025 base::TimeDelta min_delay = |
3055 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); | 3026 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); |
3056 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || | 3027 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || |
3057 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { | 3028 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { |
3058 // If there is a pending task to send progress, it is now obsolete. | 3029 // 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 Loading... | |
3512 NotificationService::current()->Notify( | 3483 NotificationService::current()->Notify( |
3513 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, | 3484 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
3514 Source<WebContents>(this), | 3485 Source<WebContents>(this), |
3515 Details<std::pair<NavigationEntry*, bool> >(&details)); | 3486 Details<std::pair<NavigationEntry*, bool> >(&details)); |
3516 | 3487 |
3517 return true; | 3488 return true; |
3518 } | 3489 } |
3519 | 3490 |
3520 void WebContentsImpl::SendLoadProgressChanged() { | 3491 void WebContentsImpl::SendLoadProgressChanged() { |
3521 loading_last_progress_update_ = base::TimeTicks::Now(); | 3492 loading_last_progress_update_ = base::TimeTicks::Now(); |
3522 double progress = 0.0; | 3493 double progress = frame_tree_.GetLoadProgress(); |
3523 int frame_count = 0; | |
3524 | 3494 |
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); | 3495 DCHECK_LE(progress, 1.0); |
3530 | 3496 |
3531 if (progress <= loading_total_progress_) | 3497 if (progress <= loading_total_progress_) |
3532 return; | 3498 return; |
3533 loading_total_progress_ = progress; | 3499 loading_total_progress_ = progress; |
3534 | 3500 |
3535 if (delegate_) | 3501 if (delegate_) |
3536 delegate_->LoadProgressChanged(this, progress); | 3502 delegate_->LoadProgressChanged(this, progress); |
3537 } | 3503 } |
3538 | 3504 |
3539 void WebContentsImpl::ResetLoadProgressState() { | 3505 void WebContentsImpl::ResetLoadProgressState() { |
3540 frame_tree_.ForEach(base::Bind(&ResetLoadProgress)); | 3506 frame_tree_.ResetLoadProgress(); |
3541 loading_total_progress_ = 0.0; | 3507 loading_total_progress_ = 0.0; |
3542 loading_weak_factory_.InvalidateWeakPtrs(); | 3508 loading_weak_factory_.InvalidateWeakPtrs(); |
3543 loading_last_progress_update_ = base::TimeTicks(); | 3509 loading_last_progress_update_ = base::TimeTicks(); |
3544 } | 3510 } |
3545 | 3511 |
3546 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, | 3512 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, |
3547 RenderViewHost* new_host) { | 3513 RenderViewHost* new_host) { |
3548 // After sending out a swap notification, we need to send a disconnect | 3514 // 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 | 3515 // notification so that clients that pick up a pointer to |this| can NULL the |
3550 // pointer. See Bug 1230284. | 3516 // pointer. See Bug 1230284. |
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4648 node->render_manager()->ResumeResponseDeferredAtStart(); | 4614 node->render_manager()->ResumeResponseDeferredAtStart(); |
4649 } | 4615 } |
4650 | 4616 |
4651 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { | 4617 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { |
4652 force_disable_overscroll_content_ = force_disable; | 4618 force_disable_overscroll_content_ = force_disable; |
4653 if (view_) | 4619 if (view_) |
4654 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4620 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
4655 } | 4621 } |
4656 | 4622 |
4657 } // namespace content | 4623 } // namespace content |
OLD | NEW |