Chromium Code Reviews| 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 "chrome/browser/prerender/prerender_manager.h" | 5 #include "chrome/browser/prerender/prerender_manager.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 if (!prerender_contents || !prerender_contents->Init()) | 430 if (!prerender_contents || !prerender_contents->Init()) |
| 431 return false; | 431 return false; |
| 432 | 432 |
| 433 histograms_->RecordPrerenderStarted(origin); | 433 histograms_->RecordPrerenderStarted(origin); |
| 434 | 434 |
| 435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? | 435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? |
| 436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); | 436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); |
| 437 | 437 |
| 438 prerender_list_.push_back(data); | 438 prerender_list_.push_back(data); |
| 439 | 439 |
| 440 if (IsControlGroup()) { | 440 if (!IsControlGroup()) { |
| 441 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); | |
| 442 } else { | |
| 443 last_prerender_start_time_ = GetCurrentTimeTicks(); | 441 last_prerender_start_time_ = GetCurrentTimeTicks(); |
| 444 data.contents_->StartPrerendering(source_render_view_host, | 442 data.contents_->StartPrerendering(source_render_view_host, |
| 445 session_storage_namespace); | 443 session_storage_namespace); |
| 446 } | 444 } |
| 447 while (prerender_list_.size() > config_.max_elements) { | 445 while (prerender_list_.size() > config_.max_elements) { |
| 448 data = prerender_list_.front(); | 446 data = prerender_list_.front(); |
| 449 prerender_list_.pop_front(); | 447 prerender_list_.pop_front(); |
| 450 data.contents_->Destroy(FINAL_STATUS_EVICTED); | 448 data.contents_->Destroy(FINAL_STATUS_EVICTED); |
| 451 } | 449 } |
| 452 StartSchedulingPeriodicCleanups(); | 450 StartSchedulingPeriodicCleanups(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 bool url_matches = prerender_contents->MatchesURL(url, &matching_url); | 558 bool url_matches = prerender_contents->MatchesURL(url, &matching_url); |
| 561 DCHECK(url_matches); | 559 DCHECK(url_matches); |
| 562 if (url_matches && url.ref() != matching_url.ref()) { | 560 if (url_matches && url.ref() != matching_url.ref()) { |
| 563 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH); | 561 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH); |
| 564 return false; | 562 return false; |
| 565 } | 563 } |
| 566 | 564 |
| 567 // If we are just in the control group (which can be detected by noticing | 565 // If we are just in the control group (which can be detected by noticing |
| 568 // that prerendering hasn't even started yet), record that |web_contents| now | 566 // that prerendering hasn't even started yet), record that |web_contents| now |
| 569 // would be showing a prerendered contents, but otherwise, don't do anything. | 567 // would be showing a prerendered contents, but otherwise, don't do anything. |
| 570 if (!prerender_contents->prerendering_has_started()) { | 568 if (!prerender_contents->prerendering_has_started()) { |
|
dominich
2012/01/20 21:17:08
I'm a bit puzzled why this is a different check to
tburkard
2012/01/20 21:57:54
This is necessary to also cover e.g. the case of a
| |
| 571 MarkWebContentsAsWouldBePrerendered(web_contents); | 569 MarkWebContentsAsWouldBePrerendered(web_contents); |
| 570 prerender_contents.release()->Destroy(FINAL_STATUS_USED); | |
| 572 return false; | 571 return false; |
| 573 } | 572 } |
| 574 | 573 |
| 575 // Don't use prerendered pages if debugger is attached to the tab. | 574 // Don't use prerendered pages if debugger is attached to the tab. |
| 576 // See http://crbug.com/98541 | 575 // See http://crbug.com/98541 |
| 577 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { | 576 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { |
| 578 prerender_contents.release()->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED); | 577 prerender_contents.release()->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED); |
| 578 // TODO: record MatchComplete status correctly. | |
|
dominich
2012/01/20 21:17:08
If the current addition of the mc_status doesn't a
tburkard
2012/01/20 21:57:54
It does suffice.. All that's needed is exercising
| |
| 579 return false; | 579 return false; |
| 580 } | 580 } |
| 581 | 581 |
| 582 // If the prerendered page is in the middle of a cross-site navigation, | 582 // If the prerendered page is in the middle of a cross-site navigation, |
| 583 // don't swap it in because there isn't a good way to merge histories. | 583 // don't swap it in because there isn't a good way to merge histories. |
| 584 if (prerender_contents->IsCrossSiteNavigationPending()) { | 584 if (prerender_contents->IsCrossSiteNavigationPending()) { |
| 585 prerender_contents.release()->Destroy( | 585 prerender_contents.release()->Destroy( |
| 586 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); | 586 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); |
| 587 // TODO: record MatchComplete status correctly. | |
| 587 return false; | 588 return false; |
| 588 } | 589 } |
| 589 | 590 |
| 590 // If the session storage namespaces don't match, cancel the prerender. | 591 // If the session storage namespaces don't match, cancel the prerender. |
| 591 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost(); | 592 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost(); |
| 592 RenderViewHost* new_render_view_host = | 593 RenderViewHost* new_render_view_host = |
| 593 prerender_contents->prerender_contents()->web_contents()-> | 594 prerender_contents->prerender_contents()->web_contents()-> |
| 594 GetRenderViewHost(); | 595 GetRenderViewHost(); |
| 595 DCHECK(old_render_view_host); | 596 DCHECK(old_render_view_host); |
| 596 DCHECK(new_render_view_host); | 597 DCHECK(new_render_view_host); |
| 597 if (old_render_view_host->session_storage_namespace() != | 598 if (old_render_view_host->session_storage_namespace() != |
| 598 new_render_view_host->session_storage_namespace()) { | 599 new_render_view_host->session_storage_namespace()) { |
| 599 prerender_contents.release()->Destroy( | 600 prerender_contents.release()->Destroy( |
| 600 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH); | 601 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH); |
| 602 // TODO: record MatchComplete status correctly. | |
| 601 return false; | 603 return false; |
| 602 } | 604 } |
| 603 | 605 |
| 604 // If we don't want to use prerenders at all, we are done. | 606 // If we don't want to use prerenders at all, we are done. |
| 605 // For bookkeeping purposes, we need to mark this TabContents to | 607 // For bookkeeping purposes, we need to mark this TabContents to |
| 606 // reflect that it would have been prerendered. | 608 // reflect that it would have been prerendered. |
| 607 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { | 609 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { |
| 608 MarkWebContentsAsWouldBePrerendered(web_contents); | 610 MarkWebContentsAsWouldBePrerendered(web_contents); |
| 609 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP); | 611 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP); |
| 610 return false; | 612 return false; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 698 it != prerender_list_.end(); | 700 it != prerender_list_.end(); |
| 699 ++it) { | 701 ++it) { |
| 700 if (it->contents_ == entry) { | 702 if (it->contents_ == entry) { |
| 701 bool swapped_in_dummy_replacement = false; | 703 bool swapped_in_dummy_replacement = false; |
| 702 | 704 |
| 703 // If this PrerenderContents is being deleted due to a cancellation, | 705 // If this PrerenderContents is being deleted due to a cancellation, |
| 704 // we need to create a dummy replacement for PPLT accounting purposes | 706 // we need to create a dummy replacement for PPLT accounting purposes |
| 705 // for the Match Complete group. | 707 // for the Match Complete group. |
| 706 // This is the case if the cancellation is for any reason that would not | 708 // This is the case if the cancellation is for any reason that would not |
| 707 // occur in the control group case. | 709 // occur in the control group case. |
| 708 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { | 710 if (entry->mc_status() == PrerenderContents::MC_DEFAULT && |
| 711 NeedMatchCompleteDummyForFinalStatus(final_status)) { | |
| 709 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. | 712 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. |
| 710 // However, what if new conditions are added and | 713 // However, what if new conditions are added and |
| 711 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure | 714 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure |
| 712 // what's the best thing to do here. For now, I will just check whether | 715 // what's the best thing to do here. For now, I will just check whether |
| 713 // we are actually prerendering. | 716 // we are actually prerendering. |
| 714 if (ActuallyPrerendering()) { | 717 if (ActuallyPrerendering()) { |
| 718 entry->set_mc_status(PrerenderContents::MC_REPLACED); | |
| 715 PrerenderContents* dummy_replacement_prerender_contents = | 719 PrerenderContents* dummy_replacement_prerender_contents = |
| 716 CreatePrerenderContents( | 720 CreatePrerenderContents( |
| 717 entry->prerender_url(), | 721 entry->prerender_url(), |
| 718 entry->referrer(), | 722 entry->referrer(), |
| 719 entry->origin(), | 723 entry->origin(), |
| 720 entry->experiment_id()); | 724 entry->experiment_id()); |
| 721 if (dummy_replacement_prerender_contents && | 725 if (dummy_replacement_prerender_contents && |
| 722 dummy_replacement_prerender_contents->Init()) { | 726 dummy_replacement_prerender_contents->Init()) { |
| 723 dummy_replacement_prerender_contents-> | 727 dummy_replacement_prerender_contents-> |
| 724 AddAliasURLsFromOtherPrerenderContents(entry); | 728 AddAliasURLsFromOtherPrerenderContents(entry); |
| 729 dummy_replacement_prerender_contents->set_mc_status( | |
| 730 PrerenderContents::MC_REPLACEMENT); | |
| 725 it->contents_ = dummy_replacement_prerender_contents; | 731 it->contents_ = dummy_replacement_prerender_contents; |
| 726 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY); | |
| 727 swapped_in_dummy_replacement = true; | 732 swapped_in_dummy_replacement = true; |
| 728 } | 733 } |
| 729 } | 734 } |
| 730 } | 735 } |
| 731 if (!swapped_in_dummy_replacement) | 736 if (!swapped_in_dummy_replacement) |
| 732 prerender_list_.erase(it); | 737 prerender_list_.erase(it); |
| 733 break; | 738 break; |
| 734 } | 739 } |
| 735 } | 740 } |
| 736 AddToHistory(entry); | 741 AddToHistory(entry); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { | 1097 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { |
| 1093 DeleteOldTabContents(); | 1098 DeleteOldTabContents(); |
| 1094 while (!prerender_list_.empty()) { | 1099 while (!prerender_list_.empty()) { |
| 1095 PrerenderContentsData data = prerender_list_.front(); | 1100 PrerenderContentsData data = prerender_list_.front(); |
| 1096 prerender_list_.pop_front(); | 1101 prerender_list_.pop_front(); |
| 1097 data.contents_->Destroy(final_status); | 1102 data.contents_->Destroy(final_status); |
| 1098 } | 1103 } |
| 1099 DeletePendingDeleteEntries(); | 1104 DeletePendingDeleteEntries(); |
| 1100 } | 1105 } |
| 1101 | 1106 |
| 1107 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus( | |
| 1108 Origin origin, | |
| 1109 uint8 experiment_id, | |
| 1110 PrerenderContents::MatchCompleteStatus mc_status, | |
| 1111 FinalStatus final_status) const { | |
|
dominich
2012/01/20 21:17:08
if mc_status is MC_DEFAULT this will be recorded i
tburkard
2012/01/20 21:57:54
Yes. There will be 2 histograms for the Prerender
| |
| 1112 if (mc_status != PrerenderContents::MC_REPLACEMENT) | |
| 1113 histograms_->RecordFinalStatus(origin, experiment_id, final_status); | |
| 1114 if (mc_status != PrerenderContents::MC_REPLACED) { | |
| 1115 histograms_->RecordMatchCompleteFinalStatus(origin, experiment_id, | |
| 1116 final_status); | |
| 1117 } | |
| 1118 } | |
| 1119 | |
| 1102 void PrerenderManager::RecordFinalStatus(Origin origin, | 1120 void PrerenderManager::RecordFinalStatus(Origin origin, |
| 1103 uint8 experiment_id, | 1121 uint8 experiment_id, |
| 1104 FinalStatus final_status) const { | 1122 FinalStatus final_status) const { |
| 1105 histograms_->RecordFinalStatus(origin, experiment_id, final_status); | 1123 RecordFinalStatusWithMatchCompleteStatus(origin, experiment_id, |
| 1124 PrerenderContents::MC_DEFAULT, | |
| 1125 final_status); | |
| 1106 } | 1126 } |
| 1107 | 1127 |
| 1128 | |
| 1108 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( | 1129 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( |
| 1109 int render_process_id) { | 1130 int render_process_id) { |
| 1110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1111 content::RenderProcessHost* render_process_host = | 1132 content::RenderProcessHost* render_process_host = |
| 1112 content::RenderProcessHost::FromID(render_process_id); | 1133 content::RenderProcessHost::FromID(render_process_id); |
| 1113 // Each render process is guaranteed to only hold RenderViews owned by the | 1134 // Each render process is guaranteed to only hold RenderViews owned by the |
| 1114 // same BrowserContext. This is enforced by | 1135 // same BrowserContext. This is enforced by |
| 1115 // RenderProcessHost::GetExistingProcessHost. | 1136 // RenderProcessHost::GetExistingProcessHost. |
| 1116 if (!render_process_host || !render_process_host->GetBrowserContext()) | 1137 if (!render_process_host || !render_process_host->GetBrowserContext()) |
| 1117 return NULL; | 1138 return NULL; |
| 1118 Profile* profile = Profile::FromBrowserContext( | 1139 Profile* profile = Profile::FromBrowserContext( |
| 1119 render_process_host->GetBrowserContext()); | 1140 render_process_host->GetBrowserContext()); |
| 1120 if (!profile) | 1141 if (!profile) |
| 1121 return NULL; | 1142 return NULL; |
| 1122 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); | 1143 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); |
| 1123 } | 1144 } |
| 1124 | 1145 |
| 1125 } // namespace prerender | 1146 } // namespace prerender |
| OLD | NEW |