Chromium Code Reviews| 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 |