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

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 11028037: Fix prerender histograms for multiple prerender case. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... fix window logic Created 8 years, 2 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 "chrome/browser/prerender/prerender_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 bool PrerenderManager::is_prefetch_enabled_ = false; 158 bool PrerenderManager::is_prefetch_enabled_ = false;
159 159
160 // static 160 // static
161 int PrerenderManager::prerenders_per_session_count_ = 0; 161 int PrerenderManager::prerenders_per_session_count_ = 0;
162 162
163 // static 163 // static
164 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ = 164 PrerenderManager::PrerenderManagerMode PrerenderManager::mode_ =
165 PRERENDER_MODE_ENABLED; 165 PRERENDER_MODE_ENABLED;
166 166
167 struct PrerenderManager::NavigationRecord { 167 struct PrerenderManager::NavigationRecord {
168 GURL url_; 168 GURL url;
169 base::TimeTicks time_; 169 base::TimeTicks time;
170
170 NavigationRecord(const GURL& url, base::TimeTicks time) 171 NavigationRecord(const GURL& url, base::TimeTicks time)
171 : url_(url), 172 : url(url),
172 time_(time) { 173 time(time) {
173 } 174 }
174 }; 175 };
175 176
177 PrerenderManager::PrerenderedWebContentsData::
178 PrerenderedWebContentsData(Origin origin) : origin(origin) {
179 }
180
181 PrerenderManager::WouldBePrerenderedWebContentsData::
182 WouldBePrerenderedWebContentsData(Origin origin) : origin(origin),
183 state(INITIAL_STATE) {
184 }
185
176 PrerenderManager::PrerenderManager(Profile* profile, 186 PrerenderManager::PrerenderManager(Profile* profile,
177 PrerenderTracker* prerender_tracker) 187 PrerenderTracker* prerender_tracker)
178 : enabled_(true), 188 : enabled_(true),
179 profile_(profile), 189 profile_(profile),
180 prerender_tracker_(prerender_tracker), 190 prerender_tracker_(prerender_tracker),
181 prerender_contents_factory_(PrerenderContents::CreateFactory()), 191 prerender_contents_factory_(PrerenderContents::CreateFactory()),
182 last_prerender_start_time_(GetCurrentTimeTicks() - 192 last_prerender_start_time_(GetCurrentTimeTicks() -
183 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), 193 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)),
184 weak_factory_(this), 194 weak_factory_(this),
185 prerender_history_(new PrerenderHistory(kHistoryLength)), 195 prerender_history_(new PrerenderHistory(kHistoryLength)),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 FindPrerenderDataForChildAndRoute(process_id, route_id)) { 235 FindPrerenderDataForChildAndRoute(process_id, route_id)) {
226 // Instead of prerendering from inside of a running prerender, we will defer 236 // Instead of prerendering from inside of a running prerender, we will defer
227 // this request until its launcher is made visible. 237 // this request until its launcher is made visible.
228 if (PrerenderContents* contents = parent_prerender_data->contents_) { 238 if (PrerenderContents* contents = parent_prerender_data->contents_) {
229 pending_prerender_list_.push_back( 239 pending_prerender_list_.push_back(
230 linked_ptr<PrerenderData>(new PrerenderData(this))); 240 linked_ptr<PrerenderData>(new PrerenderData(this)));
231 PrerenderHandle* prerender_handle = 241 PrerenderHandle* prerender_handle =
232 new PrerenderHandle(pending_prerender_list_.back().get()); 242 new PrerenderHandle(pending_prerender_list_.back().get());
233 contents->AddPendingPrerender( 243 contents->AddPendingPrerender(
234 prerender_handle->weak_ptr_factory_.GetWeakPtr(), 244 prerender_handle->weak_ptr_factory_.GetWeakPtr(),
235 url, referrer, size); 245 ORIGIN_LINK_REL_PRERENDER, url, referrer, size);
236 return prerender_handle; 246 return prerender_handle;
237 } 247 }
238 } 248 }
239 249
240 // Unit tests pass in a process_id == -1. 250 // Unit tests pass in a process_id == -1.
241 SessionStorageNamespace* session_storage_namespace = NULL; 251 SessionStorageNamespace* session_storage_namespace = NULL;
242 if (process_id != -1) { 252 if (process_id != -1) {
243 RenderViewHost* source_render_view_host = 253 RenderViewHost* source_render_view_host =
244 RenderViewHost::FromID(process_id, route_id); 254 RenderViewHost::FromID(process_id, route_id);
245 if (!source_render_view_host) 255 if (!source_render_view_host)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 while (!active_prerender_list_.empty()) { 294 while (!active_prerender_list_.empty()) {
285 PrerenderContents* prerender_contents = 295 PrerenderContents* prerender_contents =
286 active_prerender_list_.front()->contents(); 296 active_prerender_list_.front()->contents();
287 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); 297 prerender_contents->Destroy(FINAL_STATUS_CANCELLED);
288 } 298 }
289 } 299 }
290 300
291 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, 301 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
292 const GURL& url) { 302 const GURL& url) {
293 DCHECK(CalledOnValidThread()); 303 DCHECK(CalledOnValidThread());
294 DCHECK(!IsWebContentsPrerendering(web_contents)); 304 DCHECK(!IsWebContentsPrerendering(web_contents, NULL));
295 305
296 DeleteOldEntries(); 306 DeleteOldEntries();
297 DeletePendingDeleteEntries(); 307 DeletePendingDeleteEntries();
298 // TODO(ajwong): This doesn't handle isolated apps correctly. 308 // TODO(ajwong): This doesn't handle isolated apps correctly.
299 PrerenderData* prerender_data = FindPrerenderData( 309 PrerenderData* prerender_data = FindPrerenderData(
300 url, 310 url,
301 web_contents->GetController().GetDefaultSessionStorageNamespace()); 311 web_contents->GetController().GetDefaultSessionStorageNamespace());
302 if (!prerender_data) 312 if (!prerender_data)
303 return false; 313 return false;
304 DCHECK(prerender_data->contents_); 314 DCHECK(prerender_data->contents_);
(...skipping 16 matching lines...) Expand all
321 // Do not use the prerendered version if there is an opener object. 331 // Do not use the prerendered version if there is an opener object.
322 if (web_contents->HasOpener()) { 332 if (web_contents->HasOpener()) {
323 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER); 333 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER);
324 return false; 334 return false;
325 } 335 }
326 336
327 // If we are just in the control group (which can be detected by noticing 337 // If we are just in the control group (which can be detected by noticing
328 // that prerendering hasn't even started yet), record that |web_contents| now 338 // that prerendering hasn't even started yet), record that |web_contents| now
329 // would be showing a prerendered contents, but otherwise, don't do anything. 339 // would be showing a prerendered contents, but otherwise, don't do anything.
330 if (!prerender_contents->prerendering_has_started()) { 340 if (!prerender_contents->prerendering_has_started()) {
331 MarkWebContentsAsWouldBePrerendered(web_contents); 341 MarkWebContentsAsWouldBePrerendered(web_contents,
342 prerender_contents->origin());
332 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 343 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
333 return false; 344 return false;
334 } 345 }
335 346
336 // Don't use prerendered pages if debugger is attached to the tab. 347 // Don't use prerendered pages if debugger is attached to the tab.
337 // See http://crbug.com/98541 348 // See http://crbug.com/98541
338 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { 349 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) {
339 DestroyAndMarkMatchCompleteAsUsed(prerender_contents.release(), 350 DestroyAndMarkMatchCompleteAsUsed(prerender_contents.release(),
340 FINAL_STATUS_DEVTOOLS_ATTACHED); 351 FINAL_STATUS_DEVTOOLS_ATTACHED);
341 return false; 352 return false;
342 } 353 }
343 354
344 // If the prerendered page is in the middle of a cross-site navigation, 355 // If the prerendered page is in the middle of a cross-site navigation,
345 // don't swap it in because there isn't a good way to merge histories. 356 // don't swap it in because there isn't a good way to merge histories.
346 if (prerender_contents->IsCrossSiteNavigationPending()) { 357 if (prerender_contents->IsCrossSiteNavigationPending()) {
347 DestroyAndMarkMatchCompleteAsUsed( 358 DestroyAndMarkMatchCompleteAsUsed(
348 prerender_contents.release(), 359 prerender_contents.release(),
349 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); 360 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
350 return false; 361 return false;
351 } 362 }
352 363
353 // For bookkeeping purposes, we need to mark this WebContents to 364 // For bookkeeping purposes, we need to mark this WebContents to
354 // reflect that it would have been prerendered. 365 // reflect that it would have been prerendered.
355 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { 366 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
356 MarkWebContentsAsWouldBePrerendered(web_contents); 367 MarkWebContentsAsWouldBePrerendered(web_contents,
368 prerender_contents->origin());
357 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 369 prerender_contents.release()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
358 return false; 370 return false;
359 } 371 }
360 372
361 int child_id, route_id; 373 int child_id, route_id;
362 CHECK(prerender_contents->GetChildId(&child_id)); 374 CHECK(prerender_contents->GetChildId(&child_id));
363 CHECK(prerender_contents->GetRouteId(&route_id)); 375 CHECK(prerender_contents->GetRouteId(&route_id));
364 376
365 // Try to set the prerendered page as used, so any subsequent attempts to 377 // Try to set the prerendered page as used, so any subsequent attempts to
366 // cancel on other threads will fail. If this fails because the prerender 378 // cancel on other threads will fail. If this fails because the prerender
367 // was already cancelled, possibly on another thread, fail. 379 // was already cancelled, possibly on another thread, fail.
368 if (!prerender_tracker_->TryUse(child_id, route_id)) 380 if (!prerender_tracker_->TryUse(child_id, route_id))
369 return false; 381 return false;
370 382
371 // At this point, we've determined that we will use the prerender. 383 // At this point, we've determined that we will use the prerender.
372 384
373 if (!prerender_contents->load_start_time().is_null()) { 385 if (!prerender_contents->load_start_time().is_null()) {
374 histograms_->RecordTimeUntilUsed( 386 histograms_->RecordTimeUntilUsed(
387 prerender_contents->origin(),
375 GetCurrentTimeTicks() - prerender_contents->load_start_time(), 388 GetCurrentTimeTicks() - prerender_contents->load_start_time(),
376 config_.time_to_live); 389 config_.time_to_live);
377 } 390 }
378 391
379 histograms_->RecordPerSessionCount(++prerenders_per_session_count_); 392 histograms_->RecordPerSessionCount(prerender_contents->origin(),
393 ++prerenders_per_session_count_);
380 histograms_->RecordUsedPrerender(prerender_contents->origin()); 394 histograms_->RecordUsedPrerender(prerender_contents->origin());
381 prerender_contents->set_final_status(FINAL_STATUS_USED); 395 prerender_contents->set_final_status(FINAL_STATUS_USED);
382 396
383 RenderViewHost* new_render_view_host = 397 RenderViewHost* new_render_view_host =
384 prerender_contents->prerender_contents()->web_contents()-> 398 prerender_contents->prerender_contents()->web_contents()->
385 GetRenderViewHost(); 399 GetRenderViewHost();
386 new_render_view_host->Send( 400 new_render_view_host->Send(
387 new PrerenderMsg_SetIsPrerendering(new_render_view_host->GetRoutingID(), 401 new PrerenderMsg_SetIsPrerendering(new_render_view_host->GetRoutingID(),
388 false)); 402 false));
389 403
390 // Start pending prerender requests from the PrerenderContents, if there are 404 // Start pending prerender requests from the PrerenderContents, if there are
391 // any. 405 // any.
392 prerender_contents->StartPendingPrerenders(); 406 prerender_contents->StartPendingPrerenders();
393 407
394 TabContents* new_tab_contents = 408 TabContents* new_tab_contents =
395 prerender_contents->ReleasePrerenderContents(); 409 prerender_contents->ReleasePrerenderContents();
396 TabContents* old_tab_contents = TabContents::FromWebContents(web_contents); 410 TabContents* old_tab_contents = TabContents::FromWebContents(web_contents);
397 DCHECK(new_tab_contents); 411 DCHECK(new_tab_contents);
398 DCHECK(old_tab_contents); 412 DCHECK(old_tab_contents);
399 413
400 MarkWebContentsAsPrerendered(new_tab_contents->web_contents()); 414 MarkWebContentsAsPrerendered(new_tab_contents->web_contents(),
415 prerender_contents->origin());
401 416
402 // Merge the browsing history. 417 // Merge the browsing history.
403 new_tab_contents->web_contents()->GetController().CopyStateFromAndPrune( 418 new_tab_contents->web_contents()->GetController().CopyStateFromAndPrune(
404 &old_tab_contents->web_contents()->GetController()); 419 &old_tab_contents->web_contents()->GetController());
405 CoreTabHelper::FromWebContents(old_tab_contents->web_contents())->delegate()-> 420 CoreTabHelper::FromWebContents(old_tab_contents->web_contents())->delegate()->
406 SwapTabContents(old_tab_contents->web_contents(), 421 SwapTabContents(old_tab_contents->web_contents(),
407 new_tab_contents->web_contents()); 422 new_tab_contents->web_contents());
408 prerender_contents->CommitHistory(new_tab_contents); 423 prerender_contents->CommitHistory(new_tab_contents);
409 424
410 GURL icon_url = prerender_contents->icon_url(); 425 GURL icon_url = prerender_contents->icon_url();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 WebContents* web_contents, 519 WebContents* web_contents,
505 const GURL& url) { 520 const GURL& url) {
506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
507 PrerenderManager* prerender_manager = 522 PrerenderManager* prerender_manager =
508 PrerenderManagerFactory::GetForProfile( 523 PrerenderManagerFactory::GetForProfile(
509 Profile::FromBrowserContext(web_contents->GetBrowserContext())); 524 Profile::FromBrowserContext(web_contents->GetBrowserContext()));
510 if (!prerender_manager) 525 if (!prerender_manager)
511 return; 526 return;
512 if (!prerender_manager->IsEnabled()) 527 if (!prerender_manager->IsEnabled())
513 return; 528 return;
529 Origin prerender_origin = ORIGIN_NONE;
514 bool was_prerender = 530 bool was_prerender =
515 prerender_manager->IsWebContentsPrerendered(web_contents); 531 prerender_manager->IsWebContentsPrerendered(web_contents,
532 &prerender_origin);
516 bool was_complete_prerender = was_prerender || 533 bool was_complete_prerender = was_prerender ||
517 prerender_manager->WouldWebContentsBePrerendered(web_contents); 534 prerender_manager->WouldWebContentsBePrerendered(web_contents,
518 if (prerender_manager->IsWebContentsPrerendering(web_contents)) { 535 &prerender_origin);
mmenke 2012/10/12 17:59:03 Couldn't these two bools be moved to the else case
gavinp 2012/10/13 13:48:09 Done.
536 if (prerender_manager->IsWebContentsPrerendering(web_contents,
537 &prerender_origin)) {
519 prerender_manager->histograms_->RecordPageLoadTimeNotSwappedIn( 538 prerender_manager->histograms_->RecordPageLoadTimeNotSwappedIn(
520 perceived_page_load_time, url); 539 prerender_origin, perceived_page_load_time, url);
mmenke 2012/10/12 17:59:03 optional: Could return early here, and get rid of
gavinp 2012/10/13 13:48:09 Done.
521 } else { 540 } else {
522 prerender_manager->histograms_->RecordPerceivedPageLoadTime( 541 prerender_manager->histograms_->RecordPerceivedPageLoadTime(
523 perceived_page_load_time, was_prerender, was_complete_prerender, url); 542 prerender_origin, perceived_page_load_time, was_prerender,
524 prerender_manager->histograms_->RecordPercentLoadDoneAtSwapin( 543 was_complete_prerender, url);
525 fraction_plt_elapsed_at_swap_in); 544 if (was_prerender) {
545 prerender_manager->histograms_->RecordPercentLoadDoneAtSwapin(
546 prerender_origin, fraction_plt_elapsed_at_swap_in);
547 }
526 if (prerender_manager->local_predictor_.get()) { 548 if (prerender_manager->local_predictor_.get()) {
527 prerender_manager->local_predictor_-> 549 prerender_manager->local_predictor_->
528 OnPLTEventForURL(url, perceived_page_load_time); 550 OnPLTEventForURL(url, perceived_page_load_time);
529 } 551 }
530 } 552 }
531 } 553 }
532 554
555 void PrerenderManager::RecordFractionPixelsFinalAtSwapin(
556 content::WebContents* web_contents,
557 double fraction) {
558 Origin origin = ORIGIN_NONE;
559 IsWebContentsPrerendered(web_contents, &origin);
560 histograms_->RecordFractionPixelsFinalAtSwapin(origin, fraction);
561 }
562
533 void PrerenderManager::set_enabled(bool enabled) { 563 void PrerenderManager::set_enabled(bool enabled) {
534 DCHECK(CalledOnValidThread()); 564 DCHECK(CalledOnValidThread());
535 enabled_ = enabled; 565 enabled_ = enabled;
536 } 566 }
537 567
538 // static 568 // static
539 bool PrerenderManager::IsPrefetchEnabled() { 569 bool PrerenderManager::IsPrefetchEnabled() {
540 return is_prefetch_enabled_; 570 return is_prefetch_enabled_;
541 } 571 }
542 572
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 bool PrerenderManager::IsControlGroup() { 623 bool PrerenderManager::IsControlGroup() {
594 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; 624 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP;
595 } 625 }
596 626
597 // static 627 // static
598 bool PrerenderManager::IsNoUseGroup() { 628 bool PrerenderManager::IsNoUseGroup() {
599 return GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; 629 return GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP;
600 } 630 }
601 631
602 bool PrerenderManager::IsWebContentsPrerendering( 632 bool PrerenderManager::IsWebContentsPrerendering(
603 WebContents* web_contents) const { 633 WebContents* web_contents,
634 Origin* origin) const {
604 DCHECK(CalledOnValidThread()); 635 DCHECK(CalledOnValidThread());
605 if (GetPrerenderContents(web_contents)) 636 if (PrerenderContents* prerender_contents =
637 GetPrerenderContents(web_contents)) {
638 if (origin)
639 *origin = prerender_contents->origin();
606 return true; 640 return true;
641 }
607 642
608 // Also look through the pending-deletion list. 643 // Also look through the pending-deletion list.
609 for (std::list<PrerenderContents*>::const_iterator it = 644 for (std::list<PrerenderContents*>::const_iterator it =
610 pending_delete_list_.begin(); 645 pending_delete_list_.begin();
611 it != pending_delete_list_.end(); 646 it != pending_delete_list_.end();
612 ++it) { 647 ++it) {
613 TabContents* prerender_tab_contents = (*it)->prerender_contents(); 648 TabContents* prerender_tab_contents = (*it)->prerender_contents();
614 if (prerender_tab_contents && 649 if (prerender_tab_contents &&
615 prerender_tab_contents->web_contents() == web_contents) 650 prerender_tab_contents->web_contents() == web_contents)
651 if (origin)
652 *origin = (*it)->origin();
616 return true; 653 return true;
617 } 654 }
618 655
619 return false; 656 return false;
620 } 657 }
621 658
622 PrerenderContents* PrerenderManager::GetPrerenderContents( 659 PrerenderContents* PrerenderManager::GetPrerenderContents(
623 content::WebContents* web_contents) const { 660 content::WebContents* web_contents) const {
624 DCHECK(CalledOnValidThread()); 661 DCHECK(CalledOnValidThread());
625 for (std::list<linked_ptr<PrerenderData> >::const_iterator it = 662 for (std::list<linked_ptr<PrerenderData> >::const_iterator it =
626 active_prerender_list_.begin(); 663 active_prerender_list_.begin();
627 it != active_prerender_list_.end(); 664 it != active_prerender_list_.end();
628 ++it) { 665 ++it) {
629 TabContents* prerender_tab_contents = 666 TabContents* prerender_tab_contents =
630 it->get()->contents_->prerender_contents(); 667 it->get()->contents_->prerender_contents();
631 if (prerender_tab_contents && 668 if (prerender_tab_contents &&
632 prerender_tab_contents->web_contents() == web_contents) { 669 prerender_tab_contents->web_contents() == web_contents) {
633 return it->get()->contents_; 670 return it->get()->contents_;
634 } 671 }
635 } 672 }
636 return NULL; 673 return NULL;
637 } 674 }
638 675
639 void PrerenderManager::MarkWebContentsAsPrerendered(WebContents* web_contents) { 676 void PrerenderManager::MarkWebContentsAsPrerendered(WebContents* web_contents,
677 Origin origin) {
640 DCHECK(CalledOnValidThread()); 678 DCHECK(CalledOnValidThread());
641 prerendered_tab_contents_set_.insert(web_contents); 679 prerendered_web_contents_data_.insert(
680 base::hash_map<content::WebContents*,
681 PrerenderedWebContentsData>::value_type(
682 web_contents, PrerenderedWebContentsData(origin)));
642 } 683 }
643 684
644 void PrerenderManager::MarkWebContentsAsWouldBePrerendered( 685 void PrerenderManager::MarkWebContentsAsWouldBePrerendered(
645 WebContents* web_contents) { 686 WebContents* web_contents,
687 Origin origin) {
646 DCHECK(CalledOnValidThread()); 688 DCHECK(CalledOnValidThread());
647 would_be_prerendered_map_[web_contents] = true; 689 would_be_prerendered_map_.insert(
690 base::hash_map<content::WebContents*,
691 WouldBePrerenderedWebContentsData>::value_type(
692 web_contents,
693 WouldBePrerenderedWebContentsData(origin)));
648 } 694 }
649 695
650 void PrerenderManager::MarkWebContentsAsNotPrerendered( 696 void PrerenderManager::MarkWebContentsAsNotPrerendered(
651 WebContents* web_contents) { 697 WebContents* web_contents) {
652 DCHECK(CalledOnValidThread()); 698 DCHECK(CalledOnValidThread());
653 prerendered_tab_contents_set_.erase(web_contents); 699 prerendered_web_contents_data_.erase(web_contents);
654 WouldBePrerenderedMap::iterator it = 700 base::hash_map<content::WebContents*, WouldBePrerenderedWebContentsData>::
655 would_be_prerendered_map_.find(web_contents); 701 iterator it = would_be_prerendered_map_.find(web_contents);
656 if (it != would_be_prerendered_map_.end()) { 702 if (it != would_be_prerendered_map_.end()) {
657 bool first_time = it->second; 703 if (it->second.state ==
658 if (first_time) { 704 WouldBePrerenderedWebContentsData::WAITING_FOR_PROVISIONAL_LOAD) {
659 it->second = false; 705 it->second.state =
706 WouldBePrerenderedWebContentsData::SEEN_PROVISIONAL_LOAD;
660 } else { 707 } else {
661 would_be_prerendered_map_.erase(it); 708 would_be_prerendered_map_.erase(it);
662 } 709 }
663 } 710 }
664 } 711 }
665 712
666 bool PrerenderManager::IsWebContentsPrerendered( 713 bool PrerenderManager::IsWebContentsPrerendered(
667 content::WebContents* web_contents) const { 714 content::WebContents* web_contents,
715 Origin* origin) const {
668 DCHECK(CalledOnValidThread()); 716 DCHECK(CalledOnValidThread());
669 return prerendered_tab_contents_set_.count(web_contents) > 0; 717 base::hash_map<content::WebContents*, PrerenderedWebContentsData>::
718 const_iterator it = prerendered_web_contents_data_.find(web_contents);
719 if (it == prerendered_web_contents_data_.end())
720 return false;
721 if (origin)
722 *origin = it->second.origin;
723 return true;
670 } 724 }
671 725
672 bool PrerenderManager::WouldWebContentsBePrerendered( 726 bool PrerenderManager::WouldWebContentsBePrerendered(
673 WebContents* web_contents) const { 727 WebContents* web_contents,
728 Origin* origin) const {
674 DCHECK(CalledOnValidThread()); 729 DCHECK(CalledOnValidThread());
675 return would_be_prerendered_map_.count(web_contents) > 0; 730 base::hash_map<content::WebContents*, WouldBePrerenderedWebContentsData>::
731 const_iterator it = would_be_prerendered_map_.find(web_contents);
732 if (it == would_be_prerendered_map_.end())
733 return false;
734 if (origin)
735 *origin = it->second.origin;
736 return true;
676 } 737 }
677 738
678 bool PrerenderManager::HasRecentlyBeenNavigatedTo(const GURL& url) { 739 bool PrerenderManager::HasRecentlyBeenNavigatedTo(Origin origin,
740 const GURL& url) {
679 DCHECK(CalledOnValidThread()); 741 DCHECK(CalledOnValidThread());
680 742
681 CleanUpOldNavigations(); 743 CleanUpOldNavigations();
682 std::list<NavigationRecord>::const_reverse_iterator end = navigations_.rend(); 744 std::list<NavigationRecord>::const_reverse_iterator end = navigations_.rend();
683 for (std::list<NavigationRecord>::const_reverse_iterator it = 745 for (std::list<NavigationRecord>::const_reverse_iterator it =
684 navigations_.rbegin(); 746 navigations_.rbegin();
685 it != end; 747 it != end;
686 ++it) { 748 ++it) {
687 if (it->url_ == url) { 749 if (it->url == url) {
688 base::TimeDelta delta = GetCurrentTimeTicks() - it->time_; 750 base::TimeDelta delta = GetCurrentTimeTicks() - it->time;
689 histograms_->RecordTimeSinceLastRecentVisit(delta); 751 histograms_->RecordTimeSinceLastRecentVisit(origin, delta);
690 return true; 752 return true;
691 } 753 }
692 } 754 }
693 755
694 return false; 756 return false;
695 } 757 }
696 758
697 // static 759 // static
698 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { 760 bool PrerenderManager::IsValidHttpMethod(const std::string& method) {
699 // method has been canonicalized to upper case at this point so we can just 761 // method has been canonicalized to upper case at this point so we can just
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 #if !defined(OS_ANDROID) 1023 #if !defined(OS_ANDROID)
962 if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost( 1024 if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost(
963 profile_, url) && 1025 profile_, url) &&
964 !content::RenderProcessHost::run_renderer_in_process()) { 1026 !content::RenderProcessHost::run_renderer_in_process()) {
965 RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES); 1027 RecordFinalStatus(origin, experiment, FINAL_STATUS_TOO_MANY_PROCESSES);
966 return NULL; 1028 return NULL;
967 } 1029 }
968 #endif 1030 #endif
969 1031
970 // Check if enough time has passed since the last prerender. 1032 // Check if enough time has passed since the last prerender.
971 if (!DoesRateLimitAllowPrerender()) { 1033 if (!DoesRateLimitAllowPrerender(origin)) {
972 // Cancel the prerender. We could add it to the pending prerender list but 1034 // Cancel the prerender. We could add it to the pending prerender list but
973 // this doesn't make sense as the next prerender request will be triggered 1035 // this doesn't make sense as the next prerender request will be triggered
974 // by a navigation and is unlikely to be the same site. 1036 // by a navigation and is unlikely to be the same site.
975 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 1037 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
976 return NULL; 1038 return NULL;
977 } 1039 }
978 1040
979 PrerenderContents* prerender_contents = CreatePrerenderContents( 1041 PrerenderContents* prerender_contents = CreatePrerenderContents(
980 url, referrer, origin, experiment); 1042 url, referrer, origin, experiment);
981 if (!prerender_contents || !prerender_contents->Init()) 1043 if (!prerender_contents || !prerender_contents->Init())
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 for (std::list<linked_ptr<PrerenderData> >::iterator 1226 for (std::list<linked_ptr<PrerenderData> >::iterator
1165 it = active_prerender_list_.begin(); 1227 it = active_prerender_list_.begin();
1166 it != active_prerender_list_.end(); 1228 it != active_prerender_list_.end();
1167 ++it) { 1229 ++it) {
1168 if (prerender_contents == it->get()->contents_) 1230 if (prerender_contents == it->get()->contents_)
1169 return it; 1231 return it;
1170 } 1232 }
1171 return active_prerender_list_.end(); 1233 return active_prerender_list_.end();
1172 } 1234 }
1173 1235
1174 bool PrerenderManager::DoesRateLimitAllowPrerender() const { 1236 bool PrerenderManager::DoesRateLimitAllowPrerender(Origin origin) const {
1175 DCHECK(CalledOnValidThread()); 1237 DCHECK(CalledOnValidThread());
1176 base::TimeDelta elapsed_time = 1238 base::TimeDelta elapsed_time =
1177 GetCurrentTimeTicks() - last_prerender_start_time_; 1239 GetCurrentTimeTicks() - last_prerender_start_time_;
1178 histograms_->RecordTimeBetweenPrerenderRequests(elapsed_time); 1240 histograms_->RecordTimeBetweenPrerenderRequests(origin, elapsed_time);
1179 if (!config_.rate_limit_enabled) 1241 if (!config_.rate_limit_enabled)
1180 return true; 1242 return true;
1181 return elapsed_time > 1243 return elapsed_time >
1182 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); 1244 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs);
1183 } 1245 }
1184 1246
1185 void PrerenderManager::DeleteOldTabContents() { 1247 void PrerenderManager::DeleteOldTabContents() {
1186 while (!old_tab_contents_list_.empty()) { 1248 while (!old_tab_contents_list_.empty()) {
1187 TabContents* tab_contents = old_tab_contents_list_.front(); 1249 TabContents* tab_contents = old_tab_contents_list_.front();
1188 old_tab_contents_list_.pop_front(); 1250 old_tab_contents_list_.pop_front();
1189 // TODO(dominich): should we use Instant Unload Handler here? 1251 // TODO(dominich): should we use Instant Unload Handler here?
1190 delete tab_contents; 1252 delete tab_contents;
1191 } 1253 }
1192 } 1254 }
1193 1255
1194 void PrerenderManager::CleanUpOldNavigations() { 1256 void PrerenderManager::CleanUpOldNavigations() {
1195 DCHECK(CalledOnValidThread()); 1257 DCHECK(CalledOnValidThread());
1196 1258
1197 // Cutoff. Navigations before this cutoff can be discarded. 1259 // Cutoff. Navigations before this cutoff can be discarded.
1198 base::TimeTicks cutoff = GetCurrentTimeTicks() - 1260 base::TimeTicks cutoff = GetCurrentTimeTicks() -
1199 base::TimeDelta::FromMilliseconds(kNavigationRecordWindowMs); 1261 base::TimeDelta::FromMilliseconds(kNavigationRecordWindowMs);
1200 while (!navigations_.empty()) { 1262 while (!navigations_.empty()) {
1201 if (navigations_.front().time_ > cutoff) 1263 if (navigations_.front().time > cutoff)
1202 break; 1264 break;
1203 navigations_.pop_front(); 1265 navigations_.pop_front();
1204 } 1266 }
1205 } 1267 }
1206 1268
1207 void PrerenderManager::ScheduleDeleteOldTabContents( 1269 void PrerenderManager::ScheduleDeleteOldTabContents(
1208 TabContents* tab, 1270 TabContents* tab,
1209 OnCloseTabContentsDeleter* deleter) { 1271 OnCloseTabContentsDeleter* deleter) {
1210 old_tab_contents_list_.push_back(tab); 1272 old_tab_contents_list_.push_back(tab);
1211 PostCleanupTask(); 1273 PostCleanupTask();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 if (!render_process_host || !render_process_host->GetBrowserContext()) 1358 if (!render_process_host || !render_process_host->GetBrowserContext())
1297 return NULL; 1359 return NULL;
1298 Profile* profile = Profile::FromBrowserContext( 1360 Profile* profile = Profile::FromBrowserContext(
1299 render_process_host->GetBrowserContext()); 1361 render_process_host->GetBrowserContext());
1300 if (!profile) 1362 if (!profile)
1301 return NULL; 1363 return NULL;
1302 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1364 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1303 } 1365 }
1304 1366
1305 } // namespace prerender 1367 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698