| 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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // - The pending renderer sends a FrameNavigate message that invokes the | 154 // - The pending renderer sends a FrameNavigate message that invokes the |
| 155 // DidNavigate method. This replaces the current RVH with the | 155 // DidNavigate method. This replaces the current RVH with the |
| 156 // pending RVH. | 156 // pending RVH. |
| 157 // - The previous renderer is kept swapped out in RenderFrameHostManager in case | 157 // - The previous renderer is kept swapped out in RenderFrameHostManager in case |
| 158 // the user goes back. The process only stays live if another tab is using | 158 // the user goes back. The process only stays live if another tab is using |
| 159 // it, but if so, the existing frame relationships will be maintained. | 159 // it, but if so, the existing frame relationships will be maintained. |
| 160 | 160 |
| 161 namespace content { | 161 namespace content { |
| 162 namespace { | 162 namespace { |
| 163 | 163 |
| 164 const int kMinimumDelayBetweenLoadingUpdatesMS = 100; |
| 165 |
| 166 // This matches what Blink's ProgressTracker has traditionally used for a |
| 167 // minimum progress value. |
| 168 const double kMinimumLoadingProgress = 0.1; |
| 169 |
| 164 const char kDotGoogleDotCom[] = ".google.com"; | 170 const char kDotGoogleDotCom[] = ".google.com"; |
| 165 | 171 |
| 166 #if defined(OS_ANDROID) | 172 #if defined(OS_ANDROID) |
| 167 const char kWebContentsAndroidKey[] = "web_contents_android"; | 173 const char kWebContentsAndroidKey[] = "web_contents_android"; |
| 168 #endif // OS_ANDROID | 174 #endif // OS_ANDROID |
| 169 | 175 |
| 170 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > | 176 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > |
| 171 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; | 177 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; |
| 172 | 178 |
| 173 static int StartDownload(content::RenderFrameHost* rfh, | 179 static int StartDownload(content::RenderFrameHost* rfh, |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 #if defined(OS_WIN) | 331 #if defined(OS_WIN) |
| 326 accessible_parent_(NULL), | 332 accessible_parent_(NULL), |
| 327 #endif | 333 #endif |
| 328 frame_tree_(new NavigatorImpl(&controller_, this), | 334 frame_tree_(new NavigatorImpl(&controller_, this), |
| 329 this, this, this, this), | 335 this, this, this, this), |
| 330 is_loading_(false), | 336 is_loading_(false), |
| 331 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), | 337 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), |
| 332 crashed_error_code_(0), | 338 crashed_error_code_(0), |
| 333 waiting_for_response_(false), | 339 waiting_for_response_(false), |
| 334 load_state_(net::LOAD_STATE_IDLE, base::string16()), | 340 load_state_(net::LOAD_STATE_IDLE, base::string16()), |
| 341 loading_total_progress_(0.0), |
| 342 loading_weak_factory_(this), |
| 343 loading_frames_in_progress_(0), |
| 335 upload_size_(0), | 344 upload_size_(0), |
| 336 upload_position_(0), | 345 upload_position_(0), |
| 337 displayed_insecure_content_(false), | 346 displayed_insecure_content_(false), |
| 338 has_accessed_initial_document_(false), | 347 has_accessed_initial_document_(false), |
| 339 capturer_count_(0), | 348 capturer_count_(0), |
| 340 should_normally_be_visible_(true), | 349 should_normally_be_visible_(true), |
| 341 is_being_destroyed_(false), | 350 is_being_destroyed_(false), |
| 342 notify_disconnection_(false), | 351 notify_disconnection_(false), |
| 343 dialog_manager_(NULL), | 352 dialog_manager_(NULL), |
| 344 is_showing_before_unload_dialog_(false), | 353 is_showing_before_unload_dialog_(false), |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 bool handled = true; | 512 bool handled = true; |
| 504 bool message_is_ok = true; | 513 bool message_is_ok = true; |
| 505 IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok) | 514 IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok) |
| 506 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung) | 515 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung) |
| 507 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed) | 516 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed) |
| 508 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse, | 517 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse, |
| 509 OnDomOperationResponse) | 518 OnDomOperationResponse) |
| 510 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad, | 519 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad, |
| 511 OnDocumentLoadedInFrame) | 520 OnDocumentLoadedInFrame) |
| 512 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad) | 521 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad) |
| 522 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading) |
| 523 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) |
| 524 IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress, |
| 525 OnDidChangeLoadProgress) |
| 513 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser) | 526 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser) |
| 514 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser) | 527 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser) |
| 515 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser, | 528 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser, |
| 516 OnSetSelectedColorInColorChooser) | 529 OnSetSelectedColorInColorChooser) |
| 517 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification, | 530 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification, |
| 518 OnMediaPlayingNotification) | 531 OnMediaPlayingNotification) |
| 519 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification, | 532 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification, |
| 520 OnMediaPausedNotification) | 533 OnMediaPausedNotification) |
| 521 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, | 534 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, |
| 522 OnDidLoadResourceFromMemoryCache) | 535 OnDidLoadResourceFromMemoryCache) |
| (...skipping 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 delegate_->SetFocusToLocationBar(select_all); | 2332 delegate_->SetFocusToLocationBar(select_all); |
| 2320 } | 2333 } |
| 2321 | 2334 |
| 2322 void WebContentsImpl::DidStartProvisionalLoad( | 2335 void WebContentsImpl::DidStartProvisionalLoad( |
| 2323 RenderFrameHostImpl* render_frame_host, | 2336 RenderFrameHostImpl* render_frame_host, |
| 2324 int parent_routing_id, | 2337 int parent_routing_id, |
| 2325 const GURL& validated_url, | 2338 const GURL& validated_url, |
| 2326 bool is_error_page, | 2339 bool is_error_page, |
| 2327 bool is_iframe_srcdoc) { | 2340 bool is_iframe_srcdoc) { |
| 2328 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame(); | 2341 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame(); |
| 2329 if (is_main_frame) | |
| 2330 DidChangeLoadProgress(0); | |
| 2331 | 2342 |
| 2332 // Notify observers about the start of the provisional load. | 2343 // Notify observers about the start of the provisional load. |
| 2333 int render_frame_id = render_frame_host->GetRoutingID(); | 2344 int render_frame_id = render_frame_host->GetRoutingID(); |
| 2334 RenderViewHost* render_view_host = render_frame_host->render_view_host(); | 2345 RenderViewHost* render_view_host = render_frame_host->render_view_host(); |
| 2335 FOR_EACH_OBSERVER(WebContentsObserver, observers_, | 2346 FOR_EACH_OBSERVER(WebContentsObserver, observers_, |
| 2336 DidStartProvisionalLoadForFrame( | 2347 DidStartProvisionalLoadForFrame( |
| 2337 render_frame_id, parent_routing_id, is_main_frame, | 2348 render_frame_id, parent_routing_id, is_main_frame, |
| 2338 validated_url, is_error_page, is_iframe_srcdoc, | 2349 validated_url, is_error_page, is_iframe_srcdoc, |
| 2339 render_view_host)); | 2350 render_view_host)); |
| 2340 | 2351 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2625 RenderFrameHostImpl* rfh = | 2636 RenderFrameHostImpl* rfh = |
| 2626 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2637 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2627 int render_frame_id = rfh->GetRoutingID(); | 2638 int render_frame_id = rfh->GetRoutingID(); |
| 2628 RenderViewHost* render_view_host = rfh->render_view_host(); | 2639 RenderViewHost* render_view_host = rfh->render_view_host(); |
| 2629 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame(); | 2640 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame(); |
| 2630 FOR_EACH_OBSERVER(WebContentsObserver, observers_, | 2641 FOR_EACH_OBSERVER(WebContentsObserver, observers_, |
| 2631 DidFinishLoad(render_frame_id, validated_url, | 2642 DidFinishLoad(render_frame_id, validated_url, |
| 2632 is_main_frame, render_view_host)); | 2643 is_main_frame, render_view_host)); |
| 2633 } | 2644 } |
| 2634 | 2645 |
| 2646 void WebContentsImpl::OnDidStartLoading(bool to_different_document) { |
| 2647 RenderFrameHostImpl* rfh = |
| 2648 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2649 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); |
| 2650 |
| 2651 DCHECK_GE(loading_frames_in_progress_, 0); |
| 2652 if (loading_frames_in_progress_ == 0) |
| 2653 DidStartLoading(rfh, to_different_document); |
| 2654 ++loading_frames_in_progress_; |
| 2655 |
| 2656 loading_progresses_[render_frame_id] = kMinimumLoadingProgress; |
| 2657 SendLoadProgressChanged(); |
| 2658 } |
| 2659 |
| 2660 void WebContentsImpl::OnDidStopLoading() { |
| 2661 RenderFrameHostImpl* rfh = |
| 2662 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2663 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); |
| 2664 |
| 2665 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) { |
| 2666 // Load stopped while we were still tracking load. Make sure we update |
| 2667 // progress based on this frame's completion. |
| 2668 loading_progresses_[render_frame_id] = 1.0; |
| 2669 SendLoadProgressChanged(); |
| 2670 // Then we clean-up our states. |
| 2671 if (loading_total_progress_ == 1.0) |
| 2672 ResetLoadProgressState(); |
| 2673 } |
| 2674 |
| 2675 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes |
| 2676 // calls DidStopLoading() without a matching DidStartLoading(). |
| 2677 if (loading_frames_in_progress_ == 0) |
| 2678 return; |
| 2679 --loading_frames_in_progress_; |
| 2680 if (loading_frames_in_progress_ == 0) |
| 2681 DidStopLoading(rfh); |
| 2682 } |
| 2683 |
| 2684 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { |
| 2685 RenderFrameHostImpl* rfh = |
| 2686 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2687 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); |
| 2688 |
| 2689 loading_progresses_[render_frame_id] = load_progress; |
| 2690 |
| 2691 // We notify progress change immediately for the first and last updates. |
| 2692 // Also, since the message loop may be pretty busy when a page is loaded, it |
| 2693 // might not execute a posted task in a timely manner so we make sure to |
| 2694 // immediately send progress report if enough time has passed. |
| 2695 base::TimeDelta min_delay = |
| 2696 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); |
| 2697 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || |
| 2698 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { |
| 2699 // If there is a pending task to send progress, it is now obsolete. |
| 2700 loading_weak_factory_.InvalidateWeakPtrs(); |
| 2701 SendLoadProgressChanged(); |
| 2702 if (loading_total_progress_ == 1.0) |
| 2703 ResetLoadProgressState(); |
| 2704 return; |
| 2705 } |
| 2706 |
| 2707 if (loading_weak_factory_.HasWeakPtrs()) |
| 2708 return; |
| 2709 |
| 2710 base::MessageLoop::current()->PostDelayedTask( |
| 2711 FROM_HERE, |
| 2712 base::Bind(&WebContentsImpl::SendLoadProgressChanged, |
| 2713 loading_weak_factory_.GetWeakPtr()), |
| 2714 min_delay); |
| 2715 } |
| 2716 |
| 2635 void WebContentsImpl::OnGoToEntryAtOffset(int offset) { | 2717 void WebContentsImpl::OnGoToEntryAtOffset(int offset) { |
| 2636 if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) | 2718 if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) |
| 2637 controller_.GoToOffset(offset); | 2719 controller_.GoToOffset(offset); |
| 2638 } | 2720 } |
| 2639 | 2721 |
| 2640 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent, | 2722 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent, |
| 2641 int maximum_percent, | 2723 int maximum_percent, |
| 2642 bool remember) { | 2724 bool remember) { |
| 2643 minimum_zoom_percent_ = minimum_percent; | 2725 minimum_zoom_percent_ = minimum_percent; |
| 2644 maximum_zoom_percent_ = maximum_percent; | 2726 maximum_zoom_percent_ = maximum_percent; |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3016 std::pair<NavigationEntry*, bool> details = | 3098 std::pair<NavigationEntry*, bool> details = |
| 3017 std::make_pair(entry, explicit_set); | 3099 std::make_pair(entry, explicit_set); |
| 3018 NotificationService::current()->Notify( | 3100 NotificationService::current()->Notify( |
| 3019 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, | 3101 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, |
| 3020 Source<WebContents>(this), | 3102 Source<WebContents>(this), |
| 3021 Details<std::pair<NavigationEntry*, bool> >(&details)); | 3103 Details<std::pair<NavigationEntry*, bool> >(&details)); |
| 3022 | 3104 |
| 3023 return true; | 3105 return true; |
| 3024 } | 3106 } |
| 3025 | 3107 |
| 3108 void WebContentsImpl::SendLoadProgressChanged() { |
| 3109 loading_last_progress_update_ = base::TimeTicks::Now(); |
| 3110 double progress = 0.0; |
| 3111 int frame_count = 0; |
| 3112 |
| 3113 for (LoadingProgressMap::iterator it = loading_progresses_.begin(); |
| 3114 it != loading_progresses_.end(); |
| 3115 ++it) { |
| 3116 progress += it->second; |
| 3117 ++frame_count; |
| 3118 } |
| 3119 if (frame_count == 0) |
| 3120 return; |
| 3121 progress /= frame_count; |
| 3122 DCHECK(progress <= 1.0); |
| 3123 |
| 3124 if (progress <= loading_total_progress_) |
| 3125 return; |
| 3126 loading_total_progress_ = progress; |
| 3127 |
| 3128 if (delegate_) |
| 3129 delegate_->LoadProgressChanged(this, progress); |
| 3130 } |
| 3131 |
| 3132 void WebContentsImpl::ResetLoadProgressState() { |
| 3133 loading_progresses_.clear(); |
| 3134 loading_total_progress_ = 0.0; |
| 3135 loading_weak_factory_.InvalidateWeakPtrs(); |
| 3136 loading_last_progress_update_ = base::TimeTicks(); |
| 3137 } |
| 3138 |
| 3026 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host, | 3139 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host, |
| 3027 RenderViewHost* new_host) { | 3140 RenderViewHost* new_host) { |
| 3028 // After sending out a swap notification, we need to send a disconnect | 3141 // After sending out a swap notification, we need to send a disconnect |
| 3029 // notification so that clients that pick up a pointer to |this| can NULL the | 3142 // notification so that clients that pick up a pointer to |this| can NULL the |
| 3030 // pointer. See Bug 1230284. | 3143 // pointer. See Bug 1230284. |
| 3031 notify_disconnection_ = true; | 3144 notify_disconnection_ = true; |
| 3032 FOR_EACH_OBSERVER(WebContentsObserver, observers_, | 3145 FOR_EACH_OBSERVER(WebContentsObserver, observers_, |
| 3033 RenderViewHostChanged(old_host, new_host)); | 3146 RenderViewHostChanged(old_host, new_host)); |
| 3034 | 3147 |
| 3035 // TODO(avi): Remove. http://crbug.com/170921 | 3148 // TODO(avi): Remove. http://crbug.com/170921 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3449 details.get()); | 3562 details.get()); |
| 3450 } | 3563 } |
| 3451 | 3564 |
| 3452 void WebContentsImpl::DidCancelLoading() { | 3565 void WebContentsImpl::DidCancelLoading() { |
| 3453 controller_.DiscardNonCommittedEntries(); | 3566 controller_.DiscardNonCommittedEntries(); |
| 3454 | 3567 |
| 3455 // Update the URL display. | 3568 // Update the URL display. |
| 3456 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | 3569 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); |
| 3457 } | 3570 } |
| 3458 | 3571 |
| 3459 void WebContentsImpl::DidChangeLoadProgress(double progress) { | |
| 3460 if (delegate_) | |
| 3461 delegate_->LoadProgressChanged(this, progress); | |
| 3462 } | |
| 3463 | |
| 3464 void WebContentsImpl::DidAccessInitialDocument() { | 3572 void WebContentsImpl::DidAccessInitialDocument() { |
| 3465 has_accessed_initial_document_ = true; | 3573 has_accessed_initial_document_ = true; |
| 3466 | 3574 |
| 3467 // We may have left a failed browser-initiated navigation in the address bar | 3575 // We may have left a failed browser-initiated navigation in the address bar |
| 3468 // to let the user edit it and try again. Clear it now that content might | 3576 // to let the user edit it and try again. Clear it now that content might |
| 3469 // show up underneath it. | 3577 // show up underneath it. |
| 3470 if (!IsLoading() && controller_.GetPendingEntry()) | 3578 if (!IsLoading() && controller_.GetPendingEntry()) |
| 3471 controller_.DiscardPendingEntry(); | 3579 controller_.DiscardPendingEntry(); |
| 3472 | 3580 |
| 3473 // Update the URL display. | 3581 // Update the URL display. |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3987 | 4095 |
| 3988 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { | 4096 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { |
| 3989 if (!delegate_) | 4097 if (!delegate_) |
| 3990 return; | 4098 return; |
| 3991 const gfx::Size new_size = GetPreferredSize(); | 4099 const gfx::Size new_size = GetPreferredSize(); |
| 3992 if (new_size != old_size) | 4100 if (new_size != old_size) |
| 3993 delegate_->UpdatePreferredSize(this, new_size); | 4101 delegate_->UpdatePreferredSize(this, new_size); |
| 3994 } | 4102 } |
| 3995 | 4103 |
| 3996 } // namespace content | 4104 } // namespace content |
| OLD | NEW |