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

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: fixes 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 bool handled = true; 504 bool handled = true;
496 bool message_is_ok = true; 505 bool message_is_ok = true;
497 IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok) 506 IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok)
498 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung) 507 IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
499 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed) 508 IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
500 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse, 509 IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
501 OnDomOperationResponse) 510 OnDomOperationResponse)
502 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad, 511 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad,
503 OnDocumentLoadedInFrame) 512 OnDocumentLoadedInFrame)
504 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad) 513 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad)
514 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
515 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
516 IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
517 OnDidChangeLoadProgress)
505 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser) 518 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser)
506 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser) 519 IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
507 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser, 520 IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
508 OnSetSelectedColorInColorChooser) 521 OnSetSelectedColorInColorChooser)
509 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification, 522 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification,
510 OnMediaPlayingNotification) 523 OnMediaPlayingNotification)
511 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification, 524 IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
512 OnMediaPausedNotification) 525 OnMediaPausedNotification)
513 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, 526 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
514 OnDidLoadResourceFromMemoryCache) 527 OnDidLoadResourceFromMemoryCache)
(...skipping 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after
2311 delegate_->SetFocusToLocationBar(select_all); 2324 delegate_->SetFocusToLocationBar(select_all);
2312 } 2325 }
2313 2326
2314 void WebContentsImpl::DidStartProvisionalLoad( 2327 void WebContentsImpl::DidStartProvisionalLoad(
2315 RenderFrameHostImpl* render_frame_host, 2328 RenderFrameHostImpl* render_frame_host,
2316 int parent_routing_id, 2329 int parent_routing_id,
2317 const GURL& validated_url, 2330 const GURL& validated_url,
2318 bool is_error_page, 2331 bool is_error_page,
2319 bool is_iframe_srcdoc) { 2332 bool is_iframe_srcdoc) {
2320 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame(); 2333 bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
2321 if (is_main_frame)
2322 DidChangeLoadProgress(0);
2323 2334
2324 // Notify observers about the start of the provisional load. 2335 // Notify observers about the start of the provisional load.
2325 int render_frame_id = render_frame_host->GetRoutingID(); 2336 int render_frame_id = render_frame_host->GetRoutingID();
2326 RenderViewHost* render_view_host = render_frame_host->render_view_host(); 2337 RenderViewHost* render_view_host = render_frame_host->render_view_host();
2327 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 2338 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2328 DidStartProvisionalLoadForFrame( 2339 DidStartProvisionalLoadForFrame(
2329 render_frame_id, parent_routing_id, is_main_frame, 2340 render_frame_id, parent_routing_id, is_main_frame,
2330 validated_url, is_error_page, is_iframe_srcdoc, 2341 validated_url, is_error_page, is_iframe_srcdoc,
2331 render_view_host)); 2342 render_view_host));
2332 2343
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 RenderFrameHostImpl* rfh = 2628 RenderFrameHostImpl* rfh =
2618 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); 2629 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2619 int render_frame_id = rfh->GetRoutingID(); 2630 int render_frame_id = rfh->GetRoutingID();
2620 RenderViewHost* render_view_host = rfh->render_view_host(); 2631 RenderViewHost* render_view_host = rfh->render_view_host();
2621 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame(); 2632 bool is_main_frame = rfh->frame_tree_node()->IsMainFrame();
2622 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 2633 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2623 DidFinishLoad(render_frame_id, validated_url, 2634 DidFinishLoad(render_frame_id, validated_url,
2624 is_main_frame, render_view_host)); 2635 is_main_frame, render_view_host));
2625 } 2636 }
2626 2637
2638 void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
2639 RenderFrameHostImpl* rfh =
2640 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2641 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2642
2643 // It is possible for a frame to make multiple calls to OnDidStartLoading
nasko 2014/05/16 22:19:46 nit: It will be nice to qualify "frame" here to di
Avi (use Gerrit) 2014/05/16 23:29:59 Rewritten; please verify.
2644 // without calling OnDidStopLoading. (This happens when a RenderView gets
2645 // swapped out for a cross-process navigation, and it turns into a placeholder
2646 // for one being rendered in a different process.) TODO(avi): Once
2647 // "swappedout://" URLs go away and Camille moves navigation network requests
nasko 2014/05/16 22:19:46 nit: If a specific person is mentioned, shouldn't
Avi (use Gerrit) 2014/05/16 23:29:59 Done.
2648 // to the browser process, this should no longer happen; update this code to
2649 // not allow this case.
2650 DCHECK_GE(loading_frames_in_progress_, 0);
2651 if (loading_progresses_.find(render_frame_id) == loading_progresses_.end()) {
2652 if (loading_frames_in_progress_ == 0)
2653 DidStartLoading(rfh, to_different_document);
2654 ++loading_frames_in_progress_;
2655 }
2656
2657 loading_progresses_[render_frame_id] = kMinimumLoadingProgress;
2658 SendLoadProgressChanged();
2659 }
2660
2661 void WebContentsImpl::OnDidStopLoading() {
2662 RenderFrameHostImpl* rfh =
2663 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2664 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2665
2666 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) {
2667 // Load stopped while we were still tracking load. Make sure we update
2668 // progress based on this frame's completion.
2669 loading_progresses_[render_frame_id] = 1.0;
2670 SendLoadProgressChanged();
2671 // Then we clean-up our states.
2672 if (loading_total_progress_ == 1.0)
2673 ResetLoadProgressState();
2674 }
2675
2676 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
2677 // calls DidStopLoading() without a matching DidStartLoading().
2678 if (loading_frames_in_progress_ == 0)
2679 return;
2680 --loading_frames_in_progress_;
2681 if (loading_frames_in_progress_ == 0)
2682 DidStopLoading(rfh);
2683 }
2684
2685 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
2686 RenderFrameHostImpl* rfh =
2687 static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2688 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
2689
2690 loading_progresses_[render_frame_id] = load_progress;
2691
2692 // We notify progress change immediately for the first and last updates.
2693 // Also, since the message loop may be pretty busy when a page is loaded, it
2694 // might not execute a posted task in a timely manner so we make sure to
2695 // immediately send progress report if enough time has passed.
2696 base::TimeDelta min_delay =
2697 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
2698 if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
2699 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
2700 // If there is a pending task to send progress, it is now obsolete.
2701 loading_weak_factory_.InvalidateWeakPtrs();
2702 SendLoadProgressChanged();
2703 if (loading_total_progress_ == 1.0)
2704 ResetLoadProgressState();
2705 return;
2706 }
2707
2708 if (loading_weak_factory_.HasWeakPtrs())
2709 return;
2710
2711 base::MessageLoop::current()->PostDelayedTask(
2712 FROM_HERE,
2713 base::Bind(&WebContentsImpl::SendLoadProgressChanged,
2714 loading_weak_factory_.GetWeakPtr()),
2715 min_delay);
2716 }
2717
2627 void WebContentsImpl::OnGoToEntryAtOffset(int offset) { 2718 void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
2628 if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) 2719 if (!delegate_ || delegate_->OnGoToEntryOffset(offset))
2629 controller_.GoToOffset(offset); 2720 controller_.GoToOffset(offset);
2630 } 2721 }
2631 2722
2632 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent, 2723 void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
2633 int maximum_percent, 2724 int maximum_percent,
2634 bool remember) { 2725 bool remember) {
2635 minimum_zoom_percent_ = minimum_percent; 2726 minimum_zoom_percent_ = minimum_percent;
2636 maximum_zoom_percent_ = maximum_percent; 2727 maximum_zoom_percent_ = maximum_percent;
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
3002 std::pair<NavigationEntry*, bool> details = 3093 std::pair<NavigationEntry*, bool> details =
3003 std::make_pair(entry, explicit_set); 3094 std::make_pair(entry, explicit_set);
3004 NotificationService::current()->Notify( 3095 NotificationService::current()->Notify(
3005 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, 3096 NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
3006 Source<WebContents>(this), 3097 Source<WebContents>(this),
3007 Details<std::pair<NavigationEntry*, bool> >(&details)); 3098 Details<std::pair<NavigationEntry*, bool> >(&details));
3008 3099
3009 return true; 3100 return true;
3010 } 3101 }
3011 3102
3103 void WebContentsImpl::SendLoadProgressChanged() {
3104 loading_last_progress_update_ = base::TimeTicks::Now();
3105 double progress = 0.0;
3106 int frame_count = 0;
3107
3108 for (LoadingProgressMap::iterator it = loading_progresses_.begin();
3109 it != loading_progresses_.end();
3110 ++it) {
3111 progress += it->second;
3112 ++frame_count;
3113 }
3114 if (frame_count == 0)
3115 return;
3116 progress /= frame_count;
3117 DCHECK(progress <= 1.0);
3118
3119 if (progress <= loading_total_progress_)
3120 return;
3121 loading_total_progress_ = progress;
3122
3123 if (delegate_)
3124 delegate_->LoadProgressChanged(this, progress);
3125 }
3126
3127 void WebContentsImpl::ResetLoadProgressState() {
3128 loading_progresses_.clear();
3129 loading_total_progress_ = 0.0;
3130 loading_weak_factory_.InvalidateWeakPtrs();
3131 loading_last_progress_update_ = base::TimeTicks();
3132 }
3133
3012 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host, 3134 void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
3013 RenderViewHost* new_host) { 3135 RenderViewHost* new_host) {
3014 // After sending out a swap notification, we need to send a disconnect 3136 // After sending out a swap notification, we need to send a disconnect
3015 // notification so that clients that pick up a pointer to |this| can NULL the 3137 // notification so that clients that pick up a pointer to |this| can NULL the
3016 // pointer. See Bug 1230284. 3138 // pointer. See Bug 1230284.
3017 notify_disconnection_ = true; 3139 notify_disconnection_ = true;
3018 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3140 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3019 RenderViewHostChanged(old_host, new_host)); 3141 RenderViewHostChanged(old_host, new_host));
3020 3142
3021 // TODO(avi): Remove. http://crbug.com/170921 3143 // TODO(avi): Remove. http://crbug.com/170921
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 ToggleFullscreenMode(false); 3404 ToggleFullscreenMode(false);
3283 3405
3284 // Cancel any visible dialogs so they are not left dangling over the sad tab. 3406 // Cancel any visible dialogs so they are not left dangling over the sad tab.
3285 if (dialog_manager_) 3407 if (dialog_manager_)
3286 dialog_manager_->CancelActiveAndPendingDialogs(this); 3408 dialog_manager_->CancelActiveAndPendingDialogs(this);
3287 3409
3288 SetIsLoading(rvh, false, true, NULL); 3410 SetIsLoading(rvh, false, true, NULL);
3289 NotifyDisconnected(); 3411 NotifyDisconnected();
3290 SetIsCrashed(status, error_code); 3412 SetIsCrashed(status, error_code);
3291 3413
3414 // Reset the loading progress. TODO(avi): What does it mean to have a
Charlie Reis 2014/05/16 23:13:45 Yeah, leaving this as a TODO is fine for now, but
3415 // "renderer crash" when there is more than one renderer process serving a
3416 // webpage?
3417 ResetLoadProgressState();
3418 loading_frames_in_progress_ = 0;
3419
3292 #if defined(OS_ANDROID) 3420 #if defined(OS_ANDROID)
3293 if (GetRenderViewHostImpl()->media_player_manager()) 3421 if (GetRenderViewHostImpl()->media_player_manager())
3294 GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers(); 3422 GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers();
3295 #endif 3423 #endif
3296 3424
3297 FOR_EACH_OBSERVER(WebContentsObserver, 3425 FOR_EACH_OBSERVER(WebContentsObserver,
3298 observers_, 3426 observers_,
3299 RenderProcessGone(GetCrashedStatus())); 3427 RenderProcessGone(GetCrashedStatus()));
3300 } 3428 }
3301 3429
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 details.get()); 3529 details.get());
3402 } 3530 }
3403 3531
3404 void WebContentsImpl::DidCancelLoading() { 3532 void WebContentsImpl::DidCancelLoading() {
3405 controller_.DiscardNonCommittedEntries(); 3533 controller_.DiscardNonCommittedEntries();
3406 3534
3407 // Update the URL display. 3535 // Update the URL display.
3408 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); 3536 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
3409 } 3537 }
3410 3538
3411 void WebContentsImpl::DidChangeLoadProgress(double progress) {
3412 if (delegate_)
3413 delegate_->LoadProgressChanged(this, progress);
3414 }
3415
3416 void WebContentsImpl::DidAccessInitialDocument() { 3539 void WebContentsImpl::DidAccessInitialDocument() {
3417 has_accessed_initial_document_ = true; 3540 has_accessed_initial_document_ = true;
3418 3541
3419 // We may have left a failed browser-initiated navigation in the address bar 3542 // We may have left a failed browser-initiated navigation in the address bar
3420 // to let the user edit it and try again. Clear it now that content might 3543 // to let the user edit it and try again. Clear it now that content might
3421 // show up underneath it. 3544 // show up underneath it.
3422 if (!IsLoading() && controller_.GetPendingEntry()) 3545 if (!IsLoading() && controller_.GetPendingEntry())
3423 controller_.DiscardPendingEntry(); 3546 controller_.DiscardPendingEntry();
3424 3547
3425 // Update the URL display. 3548 // Update the URL display.
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
3965 4088
3966 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { 4089 void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
3967 if (!delegate_) 4090 if (!delegate_)
3968 return; 4091 return;
3969 const gfx::Size new_size = GetPreferredSize(); 4092 const gfx::Size new_size = GetPreferredSize();
3970 if (new_size != old_size) 4093 if (new_size != old_size)
3971 delegate_->UpdatePreferredSize(this, new_size); 4094 delegate_->UpdatePreferredSize(this, new_size);
3972 } 4095 }
3973 4096
3974 } // namespace content 4097 } // 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