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 <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 "GET", | 85 "GET", |
86 "HEAD", | 86 "HEAD", |
87 "OPTIONS", | 87 "OPTIONS", |
88 "POST", | 88 "POST", |
89 "TRACE", | 89 "TRACE", |
90 }; | 90 }; |
91 | 91 |
92 // Length of prerender history, for display in chrome://net-internals | 92 // Length of prerender history, for display in chrome://net-internals |
93 const int kHistoryLength = 100; | 93 const int kHistoryLength = 100; |
94 | 94 |
95 // Timeout, in ms, for a session storage namespace merge. | |
96 const int kSessionStorageNamespaceMergeTimeoutMs = 500; | |
97 | |
98 // If true, all session storage merges hang indefinitely. | |
99 bool g_hang_session_storage_merges_for_testing = false; | |
100 | |
101 // Indicates whether a Prerender has been cancelled such that we need | 95 // Indicates whether a Prerender has been cancelled such that we need |
102 // a dummy replacement for the purpose of recording the correct PPLT for | 96 // a dummy replacement for the purpose of recording the correct PPLT for |
103 // the Match Complete case. | 97 // the Match Complete case. |
104 // Traditionally, "Match" means that a prerendered page was actually visited & | 98 // Traditionally, "Match" means that a prerendered page was actually visited & |
105 // the prerender was used. Our goal is to have "Match" cases line up in the | 99 // the prerender was used. Our goal is to have "Match" cases line up in the |
106 // control group & the experiment group, so that we can make meaningful | 100 // control group & the experiment group, so that we can make meaningful |
107 // comparisons of improvements. However, in the control group, since we don't | 101 // comparisons of improvements. However, in the control group, since we don't |
108 // actually perform prerenders, many of the cancellation reasons cannot be | 102 // actually perform prerenders, many of the cancellation reasons cannot be |
109 // detected. Therefore, in the Prerender group, when we cancel for one of these | 103 // detected. Therefore, in the Prerender group, when we cancel for one of these |
110 // reasons, we keep track of a dummy Prerender representing what we would | 104 // reasons, we keep track of a dummy Prerender representing what we would |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 | 411 |
418 DeleteOldEntries(); | 412 DeleteOldEntries(); |
419 to_delete_prerenders_.clear(); | 413 to_delete_prerenders_.clear(); |
420 | 414 |
421 // First, try to find prerender data with the correct session storage | 415 // First, try to find prerender data with the correct session storage |
422 // namespace. | 416 // namespace. |
423 // TODO(ajwong): This doesn't handle isolated apps correctly. | 417 // TODO(ajwong): This doesn't handle isolated apps correctly. |
424 PrerenderData* prerender_data = FindPrerenderData( | 418 PrerenderData* prerender_data = FindPrerenderData( |
425 url, | 419 url, |
426 web_contents->GetController().GetDefaultSessionStorageNamespace()); | 420 web_contents->GetController().GetDefaultSessionStorageNamespace()); |
427 | |
428 // If this failed, we may still find a prerender for the same URL, but a | |
429 // different session storage namespace. If we do, we might have to perform | |
430 // a merge. | |
431 if (!prerender_data) { | |
432 prerender_data = FindPrerenderData(url, NULL); | |
433 } else { | |
434 RecordEvent(prerender_data->contents(), | |
435 PRERENDER_EVENT_SWAPIN_CANDIDATE_NAMESPACE_MATCHES); | |
436 } | |
437 | |
438 if (!prerender_data) | 421 if (!prerender_data) |
439 return false; | 422 return false; |
440 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_CANDIDATE); | 423 |
441 DCHECK(prerender_data->contents()); | 424 DCHECK(prerender_data->contents()); |
442 | 425 |
443 // If there is currently a merge pending for this prerender data, don't swap. | |
444 if (prerender_data->pending_swap()) | |
445 return false; | |
446 | |
447 // Abort any existing pending swap on the target contents. | |
448 PrerenderData* pending_swap = | |
449 FindPrerenderDataForTargetContents(web_contents); | |
450 if (pending_swap) { | |
451 pending_swap->ClearPendingSwap(); | |
452 DCHECK(FindPrerenderDataForTargetContents(web_contents) == NULL); | |
453 } | |
454 | |
455 RecordEvent(prerender_data->contents(), | |
456 PRERENDER_EVENT_SWAPIN_NO_MERGE_PENDING); | |
457 SessionStorageNamespace* target_namespace = | |
458 web_contents->GetController().GetDefaultSessionStorageNamespace(); | |
459 SessionStorageNamespace* prerender_namespace = | |
460 prerender_data->contents()->GetSessionStorageNamespace(); | |
461 // Only when actually prerendering is session storage namespace merging an | |
462 // issue. For the control group, it will be assumed that the merge succeeded. | |
463 if (prerender_namespace && prerender_namespace != target_namespace && | |
464 !prerender_namespace->IsAliasOf(target_namespace)) { | |
465 if (!ShouldMergeSessionStorageNamespaces()) { | |
466 RecordEvent(prerender_data->contents(), | |
467 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); | |
468 return false; | |
469 } | |
470 RecordEvent(prerender_data->contents(), | |
471 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); | |
472 prerender_data->set_pending_swap(new PendingSwap( | |
473 this, web_contents, prerender_data, url, | |
474 params->should_replace_current_entry)); | |
475 prerender_data->pending_swap()->BeginSwap(); | |
476 // Although this returns false, creating a PendingSwap registers with | |
477 // PrerenderTracker to throttle MAIN_FRAME navigations while the swap is | |
478 // pending. | |
479 return false; | |
480 } | |
481 | |
482 // No need to merge; swap synchronously. | 426 // No need to merge; swap synchronously. |
483 WebContents* new_web_contents = SwapInternal( | 427 WebContents* new_web_contents = SwapInternal( |
484 url, web_contents, prerender_data, | 428 url, web_contents, prerender_data, |
485 params->should_replace_current_entry); | 429 params->should_replace_current_entry); |
486 if (!new_web_contents) | 430 if (!new_web_contents) |
487 return false; | 431 return false; |
488 | 432 |
489 // Record the new target_contents for the callers. | 433 // Record the new target_contents for the callers. |
490 params->target_contents = new_web_contents; | 434 params->target_contents = new_web_contents; |
491 return true; | 435 return true; |
492 } | 436 } |
493 | 437 |
494 WebContents* PrerenderManager::SwapInternal( | 438 WebContents* PrerenderManager::SwapInternal( |
495 const GURL& url, | 439 const GURL& url, |
496 WebContents* web_contents, | 440 WebContents* web_contents, |
497 PrerenderData* prerender_data, | 441 PrerenderData* prerender_data, |
498 bool should_replace_current_entry) { | 442 bool should_replace_current_entry) { |
499 DCHECK(CalledOnValidThread()); | 443 DCHECK(CalledOnValidThread()); |
500 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | 444 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
501 | 445 |
502 // Only swap if the target WebContents has a CoreTabHelper delegate to swap | 446 // Only swap if the target WebContents has a CoreTabHelper delegate to swap |
503 // out of it. For a normal WebContents, this is if it is in a TabStripModel. | 447 // out of it. For a normal WebContents, this is if it is in a TabStripModel. |
504 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); | 448 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); |
505 if (!core_tab_helper || !core_tab_helper->delegate()) { | 449 if (!core_tab_helper || !core_tab_helper->delegate()) { |
506 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_NO_DELEGATE); | |
507 return NULL; | 450 return NULL; |
508 } | 451 } |
509 | 452 |
510 PrerenderTabHelper* target_tab_helper = | 453 PrerenderTabHelper* target_tab_helper = |
511 PrerenderTabHelper::FromWebContents(web_contents); | 454 PrerenderTabHelper::FromWebContents(web_contents); |
512 if (!target_tab_helper) { | 455 if (!target_tab_helper) { |
513 NOTREACHED(); | 456 NOTREACHED(); |
514 return NULL; | 457 return NULL; |
515 } | 458 } |
516 | 459 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 histograms_->RecordAbandonTimeUntilUsed( | 552 histograms_->RecordAbandonTimeUntilUsed( |
610 prerender_data->contents()->origin(), | 553 prerender_data->contents()->origin(), |
611 prerender_data->abandon_time().is_null() ? | 554 prerender_data->abandon_time().is_null() ? |
612 base::TimeDelta() : | 555 base::TimeDelta() : |
613 GetCurrentTimeTicks() - prerender_data->abandon_time()); | 556 GetCurrentTimeTicks() - prerender_data->abandon_time()); |
614 | 557 |
615 histograms_->RecordPerSessionCount(prerender_data->contents()->origin(), | 558 histograms_->RecordPerSessionCount(prerender_data->contents()->origin(), |
616 ++prerenders_per_session_count_); | 559 ++prerenders_per_session_count_); |
617 histograms_->RecordUsedPrerender(prerender_data->contents()->origin()); | 560 histograms_->RecordUsedPrerender(prerender_data->contents()->origin()); |
618 | 561 |
619 if (prerender_data->pending_swap()) | |
620 prerender_data->pending_swap()->set_swap_successful(true); | |
621 ScopedVector<PrerenderData>::iterator to_erase = | 562 ScopedVector<PrerenderData>::iterator to_erase = |
622 FindIteratorForPrerenderContents(prerender_data->contents()); | 563 FindIteratorForPrerenderContents(prerender_data->contents()); |
623 DCHECK(active_prerenders_.end() != to_erase); | 564 DCHECK(active_prerenders_.end() != to_erase); |
624 DCHECK_EQ(prerender_data, *to_erase); | 565 DCHECK_EQ(prerender_data, *to_erase); |
625 scoped_ptr<PrerenderContents> | 566 scoped_ptr<PrerenderContents> |
626 prerender_contents(prerender_data->ReleaseContents()); | 567 prerender_contents(prerender_data->ReleaseContents()); |
627 active_prerenders_.erase(to_erase); | 568 active_prerenders_.erase(to_erase); |
628 | 569 |
629 // Mark prerender as used. | 570 // Mark prerender as used. |
630 prerender_contents->PrepareForUse(); | 571 prerender_contents->PrepareForUse(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 ActuallyPrerendering() && | 634 ActuallyPrerendering() && |
694 GetMode() == PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP) { | 635 GetMode() == PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP) { |
695 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. | 636 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. |
696 // However, what if new conditions are added and | 637 // However, what if new conditions are added and |
697 // NeedMatchCompleteDummyForFinalStatus is not being updated. Not sure | 638 // NeedMatchCompleteDummyForFinalStatus is not being updated. Not sure |
698 // what's the best thing to do here. For now, I will just check whether | 639 // what's the best thing to do here. For now, I will just check whether |
699 // we are actually prerendering. | 640 // we are actually prerendering. |
700 (*it)->MakeIntoMatchCompleteReplacement(); | 641 (*it)->MakeIntoMatchCompleteReplacement(); |
701 } else { | 642 } else { |
702 to_delete_prerenders_.push_back(*it); | 643 to_delete_prerenders_.push_back(*it); |
703 (*it)->ClearPendingSwap(); | |
704 active_prerenders_.weak_erase(it); | 644 active_prerenders_.weak_erase(it); |
705 } | 645 } |
706 | 646 |
707 // Destroy the old WebContents relatively promptly to reduce resource usage. | 647 // Destroy the old WebContents relatively promptly to reduce resource usage. |
708 PostCleanupTask(); | 648 PostCleanupTask(); |
709 } | 649 } |
710 | 650 |
711 void PrerenderManager::RecordPageLoadTimeNotSwappedIn( | 651 void PrerenderManager::RecordPageLoadTimeNotSwappedIn( |
712 Origin origin, | 652 Origin origin, |
713 base::TimeDelta page_load_time, | 653 base::TimeDelta page_load_time, |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 PrerenderHandle* handle) { | 961 PrerenderHandle* handle) { |
1022 DCHECK_LT(0, handle_count_); | 962 DCHECK_LT(0, handle_count_); |
1023 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); | 963 DCHECK_NE(static_cast<PrerenderContents*>(NULL), contents_); |
1024 | 964 |
1025 if (--handle_count_ == 0) { | 965 if (--handle_count_ == 0) { |
1026 // This will eventually remove this object from active_prerenders_. | 966 // This will eventually remove this object from active_prerenders_. |
1027 contents_->Destroy(FINAL_STATUS_CANCELLED); | 967 contents_->Destroy(FINAL_STATUS_CANCELLED); |
1028 } | 968 } |
1029 } | 969 } |
1030 | 970 |
1031 void PrerenderManager::PrerenderData::ClearPendingSwap() { | |
1032 pending_swap_.reset(NULL); | |
1033 } | |
1034 | |
1035 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { | 971 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { |
1036 return contents_.release(); | 972 return contents_.release(); |
1037 } | 973 } |
1038 | 974 |
1039 PrerenderManager::PendingSwap::PendingSwap( | |
1040 PrerenderManager* manager, | |
1041 content::WebContents* target_contents, | |
1042 PrerenderData* prerender_data, | |
1043 const GURL& url, | |
1044 bool should_replace_current_entry) | |
1045 : content::WebContentsObserver(target_contents), | |
1046 manager_(manager), | |
1047 prerender_data_(prerender_data), | |
1048 url_(url), | |
1049 should_replace_current_entry_(should_replace_current_entry), | |
1050 start_time_(base::TimeTicks::Now()), | |
1051 seen_target_route_id_(false), | |
1052 swap_successful_(false), | |
1053 weak_factory_(this) { | |
1054 } | |
1055 | |
1056 PrerenderManager::PendingSwap::~PendingSwap() { | |
1057 manager_->prerender_tracker()->RemovePrerenderPendingSwap( | |
1058 target_route_id_, swap_successful_); | |
1059 } | |
1060 | |
1061 void PrerenderManager::PendingSwap::BeginSwap() { | |
1062 if (g_hang_session_storage_merges_for_testing) | |
1063 return; | |
1064 | |
1065 SessionStorageNamespace* target_namespace = | |
1066 web_contents()->GetController().GetDefaultSessionStorageNamespace(); | |
1067 SessionStorageNamespace* prerender_namespace = | |
1068 prerender_data_->contents()->GetSessionStorageNamespace(); | |
1069 | |
1070 prerender_namespace->Merge( | |
1071 true, prerender_data_->contents()->child_id(), | |
1072 target_namespace, | |
1073 base::Bind(&PrerenderManager::PendingSwap::OnMergeCompleted, | |
1074 weak_factory_.GetWeakPtr())); | |
1075 | |
1076 merge_timeout_.Start( | |
1077 FROM_HERE, | |
1078 base::TimeDelta::FromMilliseconds( | |
1079 kSessionStorageNamespaceMergeTimeoutMs), | |
1080 this, &PrerenderManager::PendingSwap::OnMergeTimeout); | |
1081 } | |
1082 | |
1083 void PrerenderManager::PendingSwap::AboutToNavigateRenderFrame( | |
1084 RenderFrameHost* render_frame_host) { | |
1085 // TODO(davidben): Update prerendering for --site-per-process. | |
1086 if (render_frame_host->GetParent()) | |
1087 return; | |
1088 | |
1089 if (seen_target_route_id_) { | |
1090 // A second navigation began browser-side. | |
1091 prerender_data_->ClearPendingSwap(); | |
1092 return; | |
1093 } | |
1094 | |
1095 seen_target_route_id_ = true; | |
1096 target_route_id_ = PrerenderTracker::ChildRouteIdPair( | |
1097 render_frame_host->GetProcess()->GetID(), | |
1098 render_frame_host->GetRoutingID()); | |
1099 manager_->prerender_tracker()->AddPrerenderPendingSwap( | |
1100 target_route_id_, url_); | |
1101 } | |
1102 | |
1103 void PrerenderManager::PendingSwap::DidStartProvisionalLoadForFrame( | |
1104 content::RenderFrameHost* render_frame_host, | |
1105 const GURL& validated_url, | |
1106 bool is_error_page, | |
1107 bool is_iframe_srcdoc) { | |
1108 if (render_frame_host->GetParent()) | |
1109 return; | |
1110 | |
1111 // We must only cancel the pending swap if the url navigated to is not | |
1112 // the URL being attempted to be swapped in. That's because in the normal | |
1113 // flow, a ProvisionalChangeToMainFrameUrl will happen for the URL attempted | |
1114 // to be swapped in immediately after the pending swap has issued its merge. | |
1115 if (validated_url != url_) | |
1116 prerender_data_->ClearPendingSwap(); | |
1117 } | |
1118 | |
1119 void PrerenderManager::PendingSwap::DidCommitProvisionalLoadForFrame( | |
1120 content::RenderFrameHost* render_frame_host, | |
1121 const GURL& validated_url, | |
1122 ui::PageTransition transition_type) { | |
1123 if (render_frame_host->GetParent()) | |
1124 return; | |
1125 prerender_data_->ClearPendingSwap(); | |
1126 } | |
1127 | |
1128 void PrerenderManager::PendingSwap::DidFailProvisionalLoad( | |
1129 content::RenderFrameHost* render_frame_host, | |
1130 const GURL& validated_url, | |
1131 int error_code, | |
1132 const base::string16& error_description) { | |
1133 if (render_frame_host->GetParent()) | |
1134 return; | |
1135 prerender_data_->ClearPendingSwap(); | |
1136 } | |
1137 | |
1138 void PrerenderManager::PendingSwap::WebContentsDestroyed() { | |
1139 prerender_data_->ClearPendingSwap(); | |
1140 } | |
1141 | |
1142 void PrerenderManager::PendingSwap::RecordEvent(PrerenderEvent event) const { | |
1143 manager_->RecordEvent(prerender_data_->contents(), event); | |
1144 } | |
1145 | |
1146 void PrerenderManager::PendingSwap::OnMergeCompleted( | |
1147 SessionStorageNamespace::MergeResult result) { | |
1148 UMA_HISTOGRAM_TIMES("Prerender.SessionStorageNamespaceMergeTime", | |
1149 base::TimeTicks::Now() - start_time_); | |
1150 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_DONE); | |
1151 | |
1152 // Log the exact merge result in a histogram. | |
1153 switch (result) { | |
1154 case SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: | |
1155 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_FOUND); | |
1156 break; | |
1157 case SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: | |
1158 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_ALIAS); | |
1159 break; | |
1160 case SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: | |
1161 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_LOGGING); | |
1162 break; | |
1163 case SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: | |
1164 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NO_TRANSACTIONS); | |
1165 break; | |
1166 case SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: | |
1167 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_TOO_MANY_TRANSACTIONS); | |
1168 break; | |
1169 case SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: | |
1170 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_MERGEABLE); | |
1171 break; | |
1172 case SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | |
1173 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_MERGEABLE); | |
1174 break; | |
1175 default: | |
1176 NOTREACHED(); | |
1177 } | |
1178 | |
1179 if (result != SessionStorageNamespace::MERGE_RESULT_MERGEABLE && | |
1180 result != SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS) { | |
1181 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_FAILED); | |
1182 prerender_data_->ClearPendingSwap(); | |
1183 return; | |
1184 } | |
1185 | |
1186 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); | |
1187 | |
1188 // Note that SwapInternal will, on success, delete |prerender_data_| and | |
1189 // |this|. It will also delete |this| in some failure cases. Pass in a new | |
1190 // GURL object rather than a reference to |url_|. Also hold on to |manager_| | |
1191 // and |prerender_data_|. | |
1192 // | |
1193 // TODO(davidben): Can we make this less fragile? | |
1194 PrerenderManager* manager = manager_; | |
1195 PrerenderData* prerender_data = prerender_data_; | |
1196 WebContents* new_web_contents = | |
1197 manager_->SwapInternal(GURL(url_), | |
1198 web_contents(), | |
1199 prerender_data_, | |
1200 should_replace_current_entry_); | |
1201 if (!new_web_contents) { | |
1202 manager->RecordEvent(prerender_data->contents(), | |
1203 PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); | |
1204 // Depending on whether SwapInternal called Destroy() or simply failed to | |
1205 // swap, |this| may or may not be deleted. Either way, if the swap failed, | |
1206 // |prerender_data| is deleted asynchronously, so this call is a no-op if | |
1207 // |this| is already gone. | |
1208 prerender_data->ClearPendingSwap(); | |
1209 } | |
1210 } | |
1211 | |
1212 void PrerenderManager::PendingSwap::OnMergeTimeout() { | |
1213 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | |
1214 prerender_data_->ClearPendingSwap(); | |
1215 } | |
1216 | |
1217 void PrerenderManager::SetPrerenderContentsFactory( | 975 void PrerenderManager::SetPrerenderContentsFactory( |
1218 PrerenderContents::Factory* prerender_contents_factory) { | 976 PrerenderContents::Factory* prerender_contents_factory) { |
1219 DCHECK(CalledOnValidThread()); | 977 DCHECK(CalledOnValidThread()); |
1220 prerender_contents_factory_.reset(prerender_contents_factory); | 978 prerender_contents_factory_.reset(prerender_contents_factory); |
1221 } | 979 } |
1222 | 980 |
1223 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { | 981 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { |
1224 // The expiry time of our prerender data will likely change because of | 982 // The expiry time of our prerender data will likely change because of |
1225 // this navigation. This requires a resort of active_prerenders_. | 983 // this navigation. This requires a resort of active_prerenders_. |
1226 ScopedVector<PrerenderData>::iterator it = | 984 ScopedVector<PrerenderData>::iterator it = |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 const GURL& url, | 1243 const GURL& url, |
1486 const SessionStorageNamespace* session_storage_namespace) { | 1244 const SessionStorageNamespace* session_storage_namespace) { |
1487 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1245 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
1488 it != active_prerenders_.end(); ++it) { | 1246 it != active_prerenders_.end(); ++it) { |
1489 if ((*it)->contents()->Matches(url, session_storage_namespace)) | 1247 if ((*it)->contents()->Matches(url, session_storage_namespace)) |
1490 return *it; | 1248 return *it; |
1491 } | 1249 } |
1492 return NULL; | 1250 return NULL; |
1493 } | 1251 } |
1494 | 1252 |
1495 PrerenderManager::PrerenderData* | |
1496 PrerenderManager::FindPrerenderDataForTargetContents( | |
1497 WebContents* target_contents) { | |
1498 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | |
1499 it != active_prerenders_.end(); ++it) { | |
1500 if ((*it)->pending_swap() && | |
1501 (*it)->pending_swap()->web_contents() == target_contents) | |
1502 return *it; | |
1503 } | |
1504 return NULL; | |
1505 } | |
1506 | |
1507 ScopedVector<PrerenderManager::PrerenderData>::iterator | 1253 ScopedVector<PrerenderManager::PrerenderData>::iterator |
1508 PrerenderManager::FindIteratorForPrerenderContents( | 1254 PrerenderManager::FindIteratorForPrerenderContents( |
1509 PrerenderContents* prerender_contents) { | 1255 PrerenderContents* prerender_contents) { |
1510 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1256 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
1511 it != active_prerenders_.end(); ++it) { | 1257 it != active_prerenders_.end(); ++it) { |
1512 if (prerender_contents == (*it)->contents()) | 1258 if (prerender_contents == (*it)->contents()) |
1513 return it; | 1259 return it; |
1514 } | 1260 } |
1515 return active_prerenders_.end(); | 1261 return active_prerenders_.end(); |
1516 } | 1262 } |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 if (logged_in_state_.get()) | 1499 if (logged_in_state_.get()) |
1754 logged_in_state_->erase(domain_key); | 1500 logged_in_state_->erase(domain_key); |
1755 } | 1501 } |
1756 | 1502 |
1757 void PrerenderManager::LoggedInPredictorDataReceived( | 1503 void PrerenderManager::LoggedInPredictorDataReceived( |
1758 scoped_ptr<LoggedInStateMap> new_map) { | 1504 scoped_ptr<LoggedInStateMap> new_map) { |
1759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1760 logged_in_state_.swap(new_map); | 1506 logged_in_state_.swap(new_map); |
1761 } | 1507 } |
1762 | 1508 |
1763 void PrerenderManager::RecordEvent(PrerenderContents* contents, | |
1764 PrerenderEvent event) const { | |
1765 if (!contents) | |
1766 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); | |
1767 else | |
1768 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), | |
1769 event); | |
1770 } | |
1771 | |
1772 // static | 1509 // static |
1773 void PrerenderManager::RecordCookieEvent(int process_id, | 1510 void PrerenderManager::RecordCookieEvent(int process_id, |
1774 int frame_id, | 1511 int frame_id, |
1775 const GURL& url, | 1512 const GURL& url, |
1776 const GURL& frame_url, | 1513 const GURL& frame_url, |
1777 bool is_for_blocking_resource, | 1514 bool is_for_blocking_resource, |
1778 PrerenderContents::CookieEvent event, | 1515 PrerenderContents::CookieEvent event, |
1779 const net::CookieList* cookie_list) { | 1516 const net::CookieList* cookie_list) { |
1780 RenderFrameHost* rfh = RenderFrameHost::FromID(process_id, frame_id); | 1517 RenderFrameHost* rfh = RenderFrameHost::FromID(process_id, frame_id); |
1781 WebContents* web_contents = WebContents::FromRenderFrameHost(rfh); | 1518 WebContents* web_contents = WebContents::FromRenderFrameHost(rfh); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 | 1566 |
1830 void PrerenderManager::OnHistoryServiceDidQueryURL( | 1567 void PrerenderManager::OnHistoryServiceDidQueryURL( |
1831 Origin origin, | 1568 Origin origin, |
1832 uint8 experiment_id, | 1569 uint8 experiment_id, |
1833 bool success, | 1570 bool success, |
1834 const history::URLRow& url_row, | 1571 const history::URLRow& url_row, |
1835 const history::VisitVector& /*visits*/) { | 1572 const history::VisitVector& /*visits*/) { |
1836 histograms_->RecordPrerenderPageVisitedStatus(origin, experiment_id, success); | 1573 histograms_->RecordPrerenderPageVisitedStatus(origin, experiment_id, success); |
1837 } | 1574 } |
1838 | 1575 |
1839 // static | |
1840 void PrerenderManager::HangSessionStorageMergesForTesting() { | |
1841 g_hang_session_storage_merges_for_testing = true; | |
1842 } | |
1843 | |
1844 void PrerenderManager::RecordNetworkBytes(Origin origin, | 1576 void PrerenderManager::RecordNetworkBytes(Origin origin, |
1845 bool used, | 1577 bool used, |
1846 int64 prerender_bytes) { | 1578 int64 prerender_bytes) { |
1847 if (!ActuallyPrerendering()) | 1579 if (!ActuallyPrerendering()) |
1848 return; | 1580 return; |
1849 int64 recent_profile_bytes = | 1581 int64 recent_profile_bytes = |
1850 profile_network_bytes_ - last_recorded_profile_network_bytes_; | 1582 profile_network_bytes_ - last_recorded_profile_network_bytes_; |
1851 last_recorded_profile_network_bytes_ = profile_network_bytes_; | 1583 last_recorded_profile_network_bytes_ = profile_network_bytes_; |
1852 DCHECK_GE(recent_profile_bytes, 0); | 1584 DCHECK_GE(recent_profile_bytes, 0); |
1853 histograms_->RecordNetworkBytes( | 1585 histograms_->RecordNetworkBytes( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 content::RenderProcessHost* host) { | 1628 content::RenderProcessHost* host) { |
1897 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1898 prerender_process_hosts_.erase(host); | 1630 prerender_process_hosts_.erase(host); |
1899 BrowserThread::PostTask( | 1631 BrowserThread::PostTask( |
1900 BrowserThread::IO, FROM_HERE, | 1632 BrowserThread::IO, FROM_HERE, |
1901 base::Bind(&PrerenderTracker::RemovePrerenderCookieStoreOnIOThread, | 1633 base::Bind(&PrerenderTracker::RemovePrerenderCookieStoreOnIOThread, |
1902 base::Unretained(prerender_tracker()), host->GetID(), false)); | 1634 base::Unretained(prerender_tracker()), host->GetID(), false)); |
1903 } | 1635 } |
1904 | 1636 |
1905 } // namespace prerender | 1637 } // namespace prerender |
OLD | NEW |