| 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 17 matching lines...) Expand all Loading... |
| 229 ->render_manager() | 195 ->render_manager() |
| 230 ->GetRenderWidgetHostView(); | 196 ->GetRenderWidgetHostView(); |
| 231 set->insert(rwhv); | 197 set->insert(rwhv); |
| 232 } | 198 } |
| 233 | 199 |
| 234 void SetAccessibilityModeOnFrame(AccessibilityMode mode, | 200 void SetAccessibilityModeOnFrame(AccessibilityMode mode, |
| 235 RenderFrameHost* frame_host) { | 201 RenderFrameHost* frame_host) { |
| 236 static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode); | 202 static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode); |
| 237 } | 203 } |
| 238 | 204 |
| 239 // Returns true if at least one of the nodes in the |frame_tree| is loading. | |
| 240 bool IsFrameTreeLoading(FrameTree& frame_tree) { | |
| 241 bool is_loading = false; | |
| 242 frame_tree.ForEach(base::Bind(&IsNodeLoading, &is_loading)); | |
| 243 return is_loading; | |
| 244 } | |
| 245 | 205 |
| 246 } // namespace | 206 } // namespace |
| 247 | 207 |
| 248 WebContents* WebContents::Create(const WebContents::CreateParams& params) { | 208 WebContents* WebContents::Create(const WebContents::CreateParams& params) { |
| 249 return WebContentsImpl::CreateWithOpener( | 209 return WebContentsImpl::CreateWithOpener( |
| 250 params, static_cast<WebContentsImpl*>(params.opener)); | 210 params, static_cast<WebContentsImpl*>(params.opener)); |
| 251 } | 211 } |
| 252 | 212 |
| 253 WebContents* WebContents::CreateWithSessionStorage( | 213 WebContents* WebContents::CreateWithSessionStorage( |
| 254 const WebContents::CreateParams& params, | 214 const WebContents::CreateParams& params, |
| (...skipping 2675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2930 // This method should never be called when the frame is loading. | 2890 // This method should never be called when the frame is loading. |
| 2931 // Unfortunately, it can happen if a history navigation happens during a | 2891 // Unfortunately, it can happen if a history navigation happens during a |
| 2932 // BeforeUnload or Unload event. | 2892 // BeforeUnload or Unload event. |
| 2933 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been | 2893 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been |
| 2934 // refactored in Blink. See crbug.com/466089 | 2894 // refactored in Blink. See crbug.com/466089 |
| 2935 if (rfh->is_loading()) { | 2895 if (rfh->is_loading()) { |
| 2936 LOG(WARNING) << "OnDidStartLoading was called twice."; | 2896 LOG(WARNING) << "OnDidStartLoading was called twice."; |
| 2937 return; | 2897 return; |
| 2938 } | 2898 } |
| 2939 | 2899 |
| 2940 if (!IsFrameTreeLoading(frame_tree_)) | 2900 if (!frame_tree_.IsLoading()) |
| 2941 DidStartLoading(rfh, to_different_document); | 2901 DidStartLoading(rfh, to_different_document); |
| 2942 | 2902 |
| 2943 rfh->set_is_loading(true); | 2903 rfh->set_is_loading(true); |
| 2944 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressMinimum); | 2904 |
| 2905 FrameTreeNode* ftn = rfh->frame_tree_node(); |
| 2906 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressMinimum); |
| 2945 | 2907 |
| 2946 // Notify the RenderFrameHostManager of the event. | 2908 // Notify the RenderFrameHostManager of the event. |
| 2947 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); | 2909 ftn->render_manager()->OnDidStartLoading(); |
| 2948 | 2910 |
| 2949 SendLoadProgressChanged(); | 2911 SendLoadProgressChanged(); |
| 2950 } | 2912 } |
| 2951 | 2913 |
| 2952 void WebContentsImpl::OnDidStopLoading() { | 2914 void WebContentsImpl::OnDidStopLoading() { |
| 2953 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2915 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
| 2954 // fixed. | 2916 // fixed. |
| 2955 tracked_objects::ScopedTracker tracking_profile1( | 2917 tracked_objects::ScopedTracker tracking_profile1( |
| 2956 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2918 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2957 "465796 WebContentsImpl::OnDidStopLoading::Start")); | 2919 "465796 WebContentsImpl::OnDidStopLoading::Start")); |
| 2958 | 2920 |
| 2959 if (!HasValidFrameSource()) | 2921 if (!HasValidFrameSource()) |
| 2960 return; | 2922 return; |
| 2961 | 2923 |
| 2962 RenderFrameHostImpl* rfh = | 2924 RenderFrameHostImpl* rfh = |
| 2963 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2925 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2964 | 2926 |
| 2965 // This method should never be called when the frame is not loading. | 2927 // This method should never be called when the frame is not loading. |
| 2966 // Unfortunately, it can happen if a history navigation happens during a | 2928 // Unfortunately, it can happen if a history navigation happens during a |
| 2967 // BeforeUnload or Unload event. | 2929 // BeforeUnload or Unload event. |
| 2968 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been | 2930 // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been |
| 2969 // refactored in Blink. See crbug.com/466089 | 2931 // refactored in Blink. See crbug.com/466089 |
| 2970 if (!rfh->is_loading()) { | 2932 if (!rfh->is_loading()) { |
| 2971 LOG(WARNING) << "OnDidStopLoading was called twice."; | 2933 LOG(WARNING) << "OnDidStopLoading was called twice."; |
| 2972 return; | 2934 return; |
| 2973 } | 2935 } |
| 2974 | 2936 |
| 2975 rfh->set_is_loading(false); | 2937 rfh->set_is_loading(false); |
| 2976 rfh->set_loading_progress(RenderFrameHostImpl::kLoadingProgressDone); | 2938 |
| 2939 FrameTreeNode* ftn = rfh->frame_tree_node(); |
| 2940 ftn->set_loading_progress(FrameTreeNode::kLoadingProgressDone); |
| 2977 | 2941 |
| 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_profile2( | 2944 tracked_objects::ScopedTracker tracking_profile2( |
| 2981 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2945 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2982 "465796 " | 2946 "465796 " |
| 2983 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); | 2947 "WebContentsImpl::OnDidStopLoading::SendLoadProgressChanged")); |
| 2984 | 2948 |
| 2985 // Update progress based on this frame's completion. | 2949 // Update progress based on this frame's completion. |
| 2986 SendLoadProgressChanged(); | 2950 SendLoadProgressChanged(); |
| 2987 | 2951 |
| 2988 // Then clean-up the states. | 2952 // Then clean-up the states. |
| 2989 if (loading_total_progress_ == 1.0) | 2953 if (loading_total_progress_ == 1.0) |
| 2990 ResetLoadProgressState(); | 2954 ResetLoadProgressState(); |
| 2991 | 2955 |
| 2992 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2956 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
| 2993 // fixed. | 2957 // fixed. |
| 2994 tracked_objects::ScopedTracker tracking_profile3( | 2958 tracked_objects::ScopedTracker tracking_profile3( |
| 2995 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2959 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2996 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); | 2960 "465796 WebContentsImpl::OnDidStopLoading::NotifyRenderManager")); |
| 2997 // Notify the RenderFrameHostManager of the event. | 2961 // Notify the RenderFrameHostManager of the event. |
| 2998 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); | 2962 ftn->render_manager()->OnDidStopLoading(); |
| 2999 | 2963 |
| 3000 if (!IsFrameTreeLoading(frame_tree_)) { | 2964 if (!frame_tree_.IsLoading()) { |
| 3001 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2965 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
| 3002 // fixed. | 2966 // fixed. |
| 3003 tracked_objects::ScopedTracker tracking_profile4( | 2967 tracked_objects::ScopedTracker tracking_profile4( |
| 3004 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2968 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 3005 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); | 2969 "465796 WebContentsImpl::OnDidStopLoading::WCIDidStopLoading")); |
| 3006 DidStopLoading(); | 2970 DidStopLoading(); |
| 3007 } | 2971 } |
| 3008 | 2972 |
| 3009 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is | 2973 // TODO(erikchen): Remove ScopedTracker below once crbug.com/465796 is |
| 3010 // fixed. | 2974 // fixed. |
| 3011 tracked_objects::ScopedTracker tracking_profile4( | 2975 tracked_objects::ScopedTracker tracking_profile4( |
| 3012 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2976 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 3013 "465796 WebContentsImpl::OnDidStopLoading::End")); | 2977 "465796 WebContentsImpl::OnDidStopLoading::End")); |
| 3014 } | 2978 } |
| 3015 | 2979 |
| 3016 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { | 2980 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { |
| 3017 if (!HasValidFrameSource()) | 2981 if (!HasValidFrameSource()) |
| 3018 return; | 2982 return; |
| 3019 | 2983 |
| 3020 RenderFrameHostImpl* rfh = | 2984 RenderFrameHostImpl* rfh = |
| 3021 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2985 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2986 FrameTreeNode* ftn = rfh->frame_tree_node(); |
| 3022 | 2987 |
| 3023 rfh->set_loading_progress(load_progress); | 2988 ftn->set_loading_progress(load_progress); |
| 3024 | 2989 |
| 3025 // We notify progress change immediately for the first and last updates. | 2990 // We notify progress change immediately for the first and last updates. |
| 3026 // Also, since the message loop may be pretty busy when a page is loaded, it | 2991 // Also, since the message loop may be pretty busy when a page is loaded, it |
| 3027 // might not execute a posted task in a timely manner so we make sure to | 2992 // might not execute a posted task in a timely manner so we make sure to |
| 3028 // immediately send progress report if enough time has passed. | 2993 // immediately send progress report if enough time has passed. |
| 3029 base::TimeDelta min_delay = | 2994 base::TimeDelta min_delay = |
| 3030 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); | 2995 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); |
| 3031 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || | 2996 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || |
| 3032 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { | 2997 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { |
| 3033 // If there is a pending task to send progress, it is now obsolete. | 2998 // 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... |
| 3487 NotificationService::current()->Notify( | 3452 NotificationService::current()->Notify( |
| 3488 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, | 3453 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
| 3489 Source<WebContents>(this), | 3454 Source<WebContents>(this), |
| 3490 Details<std::pair<NavigationEntry*, bool> >(&details)); | 3455 Details<std::pair<NavigationEntry*, bool> >(&details)); |
| 3491 | 3456 |
| 3492 return true; | 3457 return true; |
| 3493 } | 3458 } |
| 3494 | 3459 |
| 3495 void WebContentsImpl::SendLoadProgressChanged() { | 3460 void WebContentsImpl::SendLoadProgressChanged() { |
| 3496 loading_last_progress_update_ = base::TimeTicks::Now(); | 3461 loading_last_progress_update_ = base::TimeTicks::Now(); |
| 3497 double progress = 0.0; | 3462 double progress = frame_tree_.GetLoadProgress(); |
| 3498 int frame_count = 0; | |
| 3499 | 3463 |
| 3500 frame_tree_.ForEach( | |
| 3501 base::Bind(&CollectLoadProgress, &progress, &frame_count)); | |
| 3502 if (frame_count != 0) | |
| 3503 progress /= frame_count; | |
| 3504 DCHECK_LE(progress, 1.0); | 3464 DCHECK_LE(progress, 1.0); |
| 3505 | 3465 |
| 3506 if (progress <= loading_total_progress_) | 3466 if (progress <= loading_total_progress_) |
| 3507 return; | 3467 return; |
| 3508 loading_total_progress_ = progress; | 3468 loading_total_progress_ = progress; |
| 3509 | 3469 |
| 3510 if (delegate_) | 3470 if (delegate_) |
| 3511 delegate_->LoadProgressChanged(this, progress); | 3471 delegate_->LoadProgressChanged(this, progress); |
| 3512 } | 3472 } |
| 3513 | 3473 |
| 3514 void WebContentsImpl::ResetLoadProgressState() { | 3474 void WebContentsImpl::ResetLoadProgressState() { |
| 3515 frame_tree_.ForEach(base::Bind(&ResetLoadProgress)); | 3475 frame_tree_.ResetLoadProgress(); |
| 3516 loading_total_progress_ = 0.0; | 3476 loading_total_progress_ = 0.0; |
| 3517 loading_weak_factory_.InvalidateWeakPtrs(); | 3477 loading_weak_factory_.InvalidateWeakPtrs(); |
| 3518 loading_last_progress_update_ = base::TimeTicks(); | 3478 loading_last_progress_update_ = base::TimeTicks(); |
| 3519 } | 3479 } |
| 3520 | 3480 |
| 3521 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, | 3481 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, |
| 3522 RenderViewHost* new_host) { | 3482 RenderViewHost* new_host) { |
| 3523 // After sending out a swap notification, we need to send a disconnect | 3483 // After sending out a swap notification, we need to send a disconnect |
| 3524 // notification so that clients that pick up a pointer to |this| can NULL the | 3484 // notification so that clients that pick up a pointer to |this| can NULL the |
| 3525 // pointer. See Bug 1230284. | 3485 // pointer. See Bug 1230284. |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4622 node->render_manager()->ResumeResponseDeferredAtStart(); | 4582 node->render_manager()->ResumeResponseDeferredAtStart(); |
| 4623 } | 4583 } |
| 4624 | 4584 |
| 4625 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { | 4585 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { |
| 4626 force_disable_overscroll_content_ = force_disable; | 4586 force_disable_overscroll_content_ = force_disable; |
| 4627 if (view_) | 4587 if (view_) |
| 4628 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4588 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4629 } | 4589 } |
| 4630 | 4590 |
| 4631 } // namespace content | 4591 } // namespace content |
| OLD | NEW |