Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 263973003: Move LoadProgressTracker to the browser process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: recomment Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // - The pending renderer sends a FrameNavigate message that invokes the 153 // - The pending renderer sends a FrameNavigate message that invokes the
154 // DidNavigate method. This replaces the current RVH with the 154 // DidNavigate method. This replaces the current RVH with the
155 // pending RVH. 155 // pending RVH.
156 // - The previous renderer is kept swapped out in RenderFrameHostManager in case 156 // - The previous renderer is kept swapped out in RenderFrameHostManager in case
157 // the user goes back. The process only stays live if another tab is using 157 // the user goes back. The process only stays live if another tab is using
158 // it, but if so, the existing frame relationships will be maintained. 158 // it, but if so, the existing frame relationships will be maintained.
159 159
160 namespace content { 160 namespace content {
161 namespace { 161 namespace {
162 162
163 const int kMinimumDelayBetweenLoadingUpdatesMS = 100;
164
165 // This matches what Blink's ProgressTracker has traditionally used for a
166 // minimum progress value.
167 const double kMinimumLoadingProgress = 0.1;
168
163 const char kDotGoogleDotCom[] = ".google.com"; 169 const char kDotGoogleDotCom[] = ".google.com";
164 170
165 #if defined(OS_ANDROID) 171 #if defined(OS_ANDROID)
166 const char kWebContentsAndroidKey[] = "web_contents_android"; 172 const char kWebContentsAndroidKey[] = "web_contents_android";
167 #endif // OS_ANDROID 173 #endif // OS_ANDROID
168 174
169 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > 175 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
170 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; 176 g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
171 177
172 static int StartDownload(content::RenderFrameHost* rfh, 178 static int StartDownload(content::RenderFrameHost* rfh,
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 503
495 bool handled = true; 504 bool handled = true;
496 IPC_BEGIN_MESSAGE_MAP(WebContentsImpl, message) 505 IPC_BEGIN_MESSAGE_MAP(WebContentsImpl, message)
497 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung) 506 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
498 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed) 507 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
499 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse, 508 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
500 OnDomOperationResponse) 509 OnDomOperationResponse)
501 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad, 510 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad,
502 OnDocumentLoadedInFrame) 511 OnDocumentLoadedInFrame)
503 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad) 512 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad)
513 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
514 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
515 IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
516 OnDidChangeLoadProgress)
504 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser) 517 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser)
505 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser) 518 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
506 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser, 519 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
507 OnSetSelectedColorInColorChooser) 520 OnSetSelectedColorInColorChooser)
508 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification, 521 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification,
509 OnMediaPlayingNotification) 522 OnMediaPlayingNotification)
510 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification, 523 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
511 OnMediaPausedNotification) 524 OnMediaPausedNotification)
512 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, 525 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
513 OnDidLoadResourceFromMemoryCache) 526 OnDidLoadResourceFromMemoryCache)
(...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 delegate_->SetFocusToLocationBar(select_all); 2316 delegate_->SetFocusToLocationBar(select_all);
2304 } 2317 }
2305 2318
2306 void WebContentsImpl::DidStartProvisionalLoad( 2319 void WebContentsImpl::DidStartProvisionalLoad(
2307 RenderFrameHostImpl* render_frame_host, 2320 RenderFrameHostImpl* render_frame_host,
2308 int parent_routing_id, 2321 int parent_routing_id,
2309 const GURL& validated_url, 2322 const GURL& validated_url,
2310 bool is_error_page, 2323 bool is_error_page,
2311 bool is_iframe_srcdoc) { 2324 bool is_iframe_srcdoc) {
2312 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame(); 2325 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
2313 if (is_main_frame)
2314 DidChangeLoadProgress(0);
2315 2326
2316 // Notify observers about the start of the provisional load. 2327 // Notify observers about the start of the provisional load.
2317 int render_frame_id = render_frame_host->GetRoutingID(); 2328 int render_frame_id = render_frame_host->GetRoutingID();
2318 RenderViewHost* render_view_host = render_frame_host->render_view_host(); 2329 RenderViewHost* render_view_host = render_frame_host->render_view_host();
2319 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 2330 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2320 DidStartProvisionalLoadForFrame( 2331 DidStartProvisionalLoadForFrame(
2321 render_frame_id, parent_routing_id, is_main_frame, 2332 render_frame_id, parent_routing_id, is_main_frame,
2322 validated_url, is_error_page, is_iframe_srcdoc, 2333 validated_url, is_error_page, is_iframe_srcdoc,
2323 render_view_host)); 2334 render_view_host));
2324 2335
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 RenderFrameHostImpl* rfh = 2620 RenderFrameHostImpl* rfh =
2610 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2621 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2611 int render_frame_id = rfh->GetRoutingID(); 2622 int render_frame_id = rfh->GetRoutingID();
2612 RenderViewHost* render_view_host = rfh->render_view_host(); 2623 RenderViewHost* render_view_host = rfh->render_view_host();
2613 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame(); 2624 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame();
2614 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 2625 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2615 DidFinishLoad(render_frame_id, validated_url, 2626 DidFinishLoad(render_frame_id, validated_url,
2616 is_main_frame, render_view_host)); 2627 is_main_frame, render_view_host));
2617 } 2628 }
2618 2629
2630 void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
2631 RenderFrameHostImpl* rfh =
2632 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2633 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2634
2635 // It is possible to get multiple calls to OnDidStartLoading that don't have
2636 // corresponding calls to OnDidStopLoading:
2637 // - Today, with "swappedout://" URLs, this happens when a RenderView gets
2638 // swapped out for a cross-process navigation, and it turns into a
2639 // placeholder for one being rendered in a different process.
2640 // - Tomorrow, there might be more than one RenderFrameHost sharing the same
nasko 2014/05/16 23:45:58 This is true even today.
2641 // FrameTreeNode (and thus sharing its ID) each sending a start.
2642 // - But in the future, once clamy@ moves navigation network requests to the
2643 // browser process, there's a good chance that callbacks about starting and
2644 // stopping will all be handled by the browser. When that happens, there
2645 // should no longer be a start/stop call imbalance. TODO(avi): When this
2646 // future arrives, update this code to not allow this case.
2647 DCHECK_GE(loading_frames_in_progress_, 0);
2648 if (loading_progresses_.find(render_frame_id) == loading_progresses_.end()) {
2649 if (loading_frames_in_progress_ == 0)
2650 DidStartLoading(rfh, to_different_document);
2651 ++loading_frames_in_progress_;
2652 }
2653
2654 loading_progresses_[render_frame_id] = kMinimumLoadingProgress;
2655 SendLoadProgressChanged();
2656 }
2657
2658 void WebContentsImpl::OnDidStopLoading() {
2659 RenderFrameHostImpl* rfh =
2660 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2661 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2662
2663 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) {
2664 // Load stopped while we were still tracking load. Make sure we update
2665 // progress based on this frame's completion.
2666 loading_progresses_[render_frame_id] = 1.0;
2667 SendLoadProgressChanged();
2668 // Then we clean-up our states.
2669 if (loading_total_progress_ == 1.0)
2670 ResetLoadProgressState();
2671 }
2672
2673 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
2674 // calls DidStopLoading() without a matching DidStartLoading().
2675 if (loading_frames_in_progress_ == 0)
2676 return;
2677 --loading_frames_in_progress_;
2678 if (loading_frames_in_progress_ == 0)
2679 DidStopLoading(rfh);
2680 }
2681
2682 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
2683 RenderFrameHostImpl* rfh =
2684 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2685 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2686
2687 loading_progresses_[render_frame_id] = load_progress;
2688
2689 // We notify progress change immediately for the first and last updates.
2690 // Also, since the message loop may be pretty busy when a page is loaded, it
2691 // might not execute a posted task in a timely manner so we make sure to
2692 // immediately send progress report if enough time has passed.
2693 base::TimeDelta min_delay =
2694 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
2695 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
2696 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
2697 // If there is a pending task to send progress, it is now obsolete.
2698 loading_weak_factory_.InvalidateWeakPtrs();
2699 SendLoadProgressChanged();
2700 if (loading_total_progress_ == 1.0)
2701 ResetLoadProgressState();
2702 return;
2703 }
2704
2705 if (loading_weak_factory_.HasWeakPtrs())
2706 return;
2707
2708 base::MessageLoop::current()->PostDelayedTask(
2709 FROM_HERE,
2710 base::Bind(&WebContentsImpl::SendLoadProgressChanged,
2711 loading_weak_factory_.GetWeakPtr()),
2712 min_delay);
2713 }
2714
2619 void WebContentsImpl::OnGoToEntryAtOffset(int offset) { 2715 void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
2620 if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) 2716 if (!delegate_ || delegate_->OnGoToEntryOffset(offset))
2621 controller_.GoToOffset(offset); 2717 controller_.GoToOffset(offset);
2622 } 2718 }
2623 2719
2624 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent, 2720 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
2625 int maximum_percent, 2721 int maximum_percent,
2626 bool remember) { 2722 bool remember) {
2627 minimum_zoom_percent_ = minimum_percent; 2723 minimum_zoom_percent_ = minimum_percent;
2628 maximum_zoom_percent_ = maximum_percent; 2724 maximum_zoom_percent_ = maximum_percent;
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 std::pair<NavigationEntry*, bool> details = 3090 std::pair<NavigationEntry*, bool> details =
2995 std::make_pair(entry, explicit_set); 3091 std::make_pair(entry, explicit_set);
2996 NotificationService::current()->Notify( 3092 NotificationService::current()->Notify(
2997 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 3093 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
2998 Source<WebContents>(this), 3094 Source<WebContents>(this),
2999 Details<std::pair<NavigationEntry*, bool> >(&details)); 3095 Details<std::pair<NavigationEntry*, bool> >(&details));
3000 3096
3001 return true; 3097 return true;
3002 } 3098 }
3003 3099
3100 void WebContentsImpl::SendLoadProgressChanged() {
3101 loading_last_progress_update_ = base::TimeTicks::Now();
3102 double progress = 0.0;
3103 int frame_count = 0;
3104
3105 for (LoadingProgressMap::iterator it = loading_progresses_.begin();
3106 it != loading_progresses_.end();
3107 ++it) {
3108 progress += it->second;
3109 ++frame_count;
3110 }
3111 if (frame_count == 0)
3112 return;
3113 progress /= frame_count;
3114 DCHECK(progress <= 1.0);
3115
3116 if (progress <= loading_total_progress_)
3117 return;
3118 loading_total_progress_ = progress;
3119
3120 if (delegate_)
3121 delegate_->LoadProgressChanged(this, progress);
3122 }
3123
3124 void WebContentsImpl::ResetLoadProgressState() {
3125 loading_progresses_.clear();
3126 loading_total_progress_ = 0.0;
3127 loading_weak_factory_.InvalidateWeakPtrs();
3128 loading_last_progress_update_ = base::TimeTicks();
3129 }
3130
3004 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host, 3131 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
3005 RenderViewHost* new_host) { 3132 RenderViewHost* new_host) {
3006 // After sending out a swap notification, we need to send a disconnect 3133 // After sending out a swap notification, we need to send a disconnect
3007 // notification so that clients that pick up a pointer to |this| can NULL the 3134 // notification so that clients that pick up a pointer to |this| can NULL the
3008 // pointer. See Bug 1230284. 3135 // pointer. See Bug 1230284.
3009 notify_disconnection_ = true; 3136 notify_disconnection_ = true;
3010 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3137 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3011 RenderViewHostChanged(old_host, new_host)); 3138 RenderViewHostChanged(old_host, new_host));
3012 3139
3013 // TODO(avi): Remove. http://crbug.com/170921 3140 // TODO(avi): Remove. http://crbug.com/170921
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
3274 ToggleFullscreenMode(false); 3401 ToggleFullscreenMode(false);
3275 3402
3276 // Cancel any visible dialogs so they are not left dangling over the sad tab. 3403 // Cancel any visible dialogs so they are not left dangling over the sad tab.
3277 if (dialog_manager_) 3404 if (dialog_manager_)
3278 dialog_manager_->CancelActiveAndPendingDialogs(this); 3405 dialog_manager_->CancelActiveAndPendingDialogs(this);
3279 3406
3280 SetIsLoading(rvh, false, true, NULL); 3407 SetIsLoading(rvh, false, true, NULL);
3281 NotifyDisconnected(); 3408 NotifyDisconnected();
3282 SetIsCrashed(status, error_code); 3409 SetIsCrashed(status, error_code);
3283 3410
3411 // Reset the loading progress. TODO(avi): What does it mean to have a
3412 // "renderer crash" when there is more than one renderer process serving a
3413 // webpage? Once this function is called at a more granular frame level, we
3414 // probably will need to more granularly reset the state here.
3415 ResetLoadProgressState();
3416 loading_frames_in_progress_ = 0;
3417
3284 #if defined(OS_ANDROID) 3418 #if defined(OS_ANDROID)
3285 if (GetRenderViewHostImpl()->media_player_manager()) 3419 if (GetRenderViewHostImpl()->media_player_manager())
3286 GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers(); 3420 GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers();
3287 #endif 3421 #endif
3288 3422
3289 FOR_EACH_OBSERVER(WebContentsObserver, 3423 FOR_EACH_OBSERVER(WebContentsObserver,
3290 observers_, 3424 observers_,
3291 RenderProcessGone(GetCrashedStatus())); 3425 RenderProcessGone(GetCrashedStatus()));
3292 } 3426 }
3293 3427
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 details.get()); 3527 details.get());
3394 } 3528 }
3395 3529
3396 void WebContentsImpl::DidCancelLoading() { 3530 void WebContentsImpl::DidCancelLoading() {
3397 controller_.DiscardNonCommittedEntries(); 3531 controller_.DiscardNonCommittedEntries();
3398 3532
3399 // Update the URL display. 3533 // Update the URL display.
3400 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); 3534 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
3401 } 3535 }
3402 3536
3403 void WebContentsImpl::DidChangeLoadProgress(double progress) {
3404 if (delegate_)
3405 delegate_->LoadProgressChanged(this, progress);
3406 }
3407
3408 void WebContentsImpl::DidAccessInitialDocument() { 3537 void WebContentsImpl::DidAccessInitialDocument() {
3409 has_accessed_initial_document_ = true; 3538 has_accessed_initial_document_ = true;
3410 3539
3411 // We may have left a failed browser-initiated navigation in the address bar 3540 // We may have left a failed browser-initiated navigation in the address bar
3412 // to let the user edit it and try again. Clear it now that content might 3541 // to let the user edit it and try again. Clear it now that content might
3413 // show up underneath it. 3542 // show up underneath it.
3414 if (!IsLoading() && controller_.GetPendingEntry()) 3543 if (!IsLoading() && controller_.GetPendingEntry())
3415 controller_.DiscardPendingEntry(); 3544 controller_.DiscardPendingEntry();
3416 3545
3417 // Update the URL display. 3546 // Update the URL display.
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
3957 4086
3958 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { 4087 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
3959 if (!delegate_) 4088 if (!delegate_)
3960 return; 4089 return;
3961 const gfx::Size new_size = GetPreferredSize(); 4090 const gfx::Size new_size = GetPreferredSize();
3962 if (new_size != old_size) 4091 if (new_size != old_size)
3963 delegate_->UpdatePreferredSize(this, new_size); 4092 delegate_->UpdatePreferredSize(this, new_size);
3964 } 4093 }
3965 4094
3966 } // namespace content 4095 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/browser/web_contents/web_contents_impl_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698