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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 | 427 |
428 void PrerenderManager::CancelAllPrerenders() { | 428 void PrerenderManager::CancelAllPrerenders() { |
429 DCHECK(CalledOnValidThread()); | 429 DCHECK(CalledOnValidThread()); |
430 while (!active_prerenders_.empty()) { | 430 while (!active_prerenders_.empty()) { |
431 PrerenderContents* prerender_contents = | 431 PrerenderContents* prerender_contents = |
432 active_prerenders_.front()->contents(); | 432 active_prerenders_.front()->contents(); |
433 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); | 433 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
437 void PrerenderManager::ProcessMergeResult( | |
438 PrerenderData* prerender_data, | |
439 bool timed_out, | |
440 content::SessionStorageNamespace::MergeResult result) { | |
441 PendingSwap* pending_swap = prerender_data->pending_swap(); | |
442 DCHECK(pending_swap); | |
443 // No pending_swap should never happen. If it does anyways (in a retail | |
444 // build), log this and bail. | |
445 if (!pending_swap) { | |
446 RecordEvent(prerender_data->contents(), | |
447 PRERENDER_EVENT_MERGE_RESULT_NO_PENDING_SWAPIN); | |
448 return; | |
449 } | |
450 if (timed_out) { | |
451 RecordEvent(prerender_data->contents(), | |
452 PRERENDER_EVENT_MERGE_RESULT_TIMEOUT_CB); | |
453 } else { | |
454 RecordEvent(prerender_data->contents(), | |
455 PRERENDER_EVENT_MERGE_RESULT_RESULT_CB); | |
456 UMA_HISTOGRAM_TIMES("Prerender.SessionStorageNamespaceMergeTime", | |
457 pending_swap->GetElapsedTime()); | |
458 } | |
459 | |
460 // Any return here must call ClearPendingSwap on |prerender_data| before | |
461 // returning, with one exception: when the prerender was ultimately swapped | |
462 // in. In that case, SwapInternal will take care of deleting | |
463 // |prerender_data| and sending the appropriate notifications to the tracker. | |
464 if (timed_out) { | |
465 RecordEvent(prerender_data->contents(), | |
466 PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | |
467 prerender_data->ClearPendingSwap(); | |
468 return; | |
469 } | |
470 | |
471 RecordEvent(prerender_data->contents(), | |
472 PRERENDER_EVENT_MERGE_RESULT_MERGE_DONE); | |
473 | |
474 // Log the exact merge result in a histogram. | |
475 switch (result) { | |
476 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: | |
477 RecordEvent(prerender_data->contents(), | |
478 PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_FOUND); | |
479 break; | |
480 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: | |
481 RecordEvent(prerender_data->contents(), | |
482 PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_ALIAS); | |
483 break; | |
484 case content::SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: | |
485 RecordEvent(prerender_data->contents(), | |
486 PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_LOGGING); | |
487 break; | |
488 case content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: | |
489 RecordEvent(prerender_data->contents(), | |
490 PRERENDER_EVENT_MERGE_RESULT_RESULT_NO_TRANSACTIONS); | |
491 break; | |
492 case content::SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: | |
493 RecordEvent(prerender_data->contents(), | |
494 PRERENDER_EVENT_MERGE_RESULT_RESULT_TOO_MANY_TRANSACTIONS); | |
495 break; | |
496 case content::SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: | |
497 RecordEvent(prerender_data->contents(), | |
498 PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_MERGEABLE); | |
499 break; | |
500 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | |
501 RecordEvent(prerender_data->contents(), | |
502 PRERENDER_EVENT_MERGE_RESULT_RESULT_MERGEABLE); | |
503 break; | |
504 default: | |
505 NOTREACHED(); | |
506 } | |
507 | |
508 if (result != content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE && | |
509 result != | |
510 content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS) { | |
511 RecordEvent(prerender_data->contents(), | |
512 PRERENDER_EVENT_MERGE_RESULT_MERGE_FAILED); | |
513 prerender_data->ClearPendingSwap(); | |
514 return; | |
515 } | |
516 | |
517 RecordEvent(prerender_data->contents(), | |
518 PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); | |
519 // Notice that SwapInInternal, on success, will delete |prerender_data| | |
520 // and |pending_swap|. Therefore, we have to pass a new GURL object rather | |
521 // than a reference to the one in |pending_swap|. | |
522 content::WebContents* new_web_contents = | |
523 SwapInternal(GURL(pending_swap->url()), | |
524 pending_swap->target_contents(), | |
525 prerender_data); | |
526 if (!new_web_contents) { | |
527 RecordEvent(prerender_data->contents(), | |
528 PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); | |
529 prerender_data->ClearPendingSwap(); | |
530 } | |
531 } | |
532 | |
533 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, | 437 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, |
534 chrome::NavigateParams* params) { | 438 chrome::NavigateParams* params) { |
535 DCHECK(CalledOnValidThread()); | 439 DCHECK(CalledOnValidThread()); |
536 | 440 |
537 content::WebContents* web_contents = params->target_contents; | 441 content::WebContents* web_contents = params->target_contents; |
538 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | 442 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
539 | 443 |
540 // Don't prerender if the navigation involves some special parameters. | 444 // Don't prerender if the navigation involves some special parameters. |
541 if (params->uses_post || !params->extra_headers.empty()) | 445 if (params->uses_post || !params->extra_headers.empty()) |
542 return false; | 446 return false; |
543 | 447 |
544 content::WebContents* new_web_contents = SwapInternal(url, web_contents, | |
545 NULL); | |
546 if (!new_web_contents) | |
547 return false; | |
548 | |
549 // Record the new target_contents for the callers. | |
550 params->target_contents = new_web_contents; | |
551 return true; | |
552 } | |
553 | |
554 content::WebContents* PrerenderManager::SwapInternal( | |
555 const GURL& url, | |
556 content::WebContents* web_contents, | |
557 PrerenderData* swap_candidate) { | |
558 DCHECK(CalledOnValidThread()); | |
559 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | |
560 | |
561 DeleteOldEntries(); | 448 DeleteOldEntries(); |
562 to_delete_prerenders_.clear(); | 449 to_delete_prerenders_.clear(); |
563 // TODO(ajwong): This doesn't handle isolated apps correctly. | |
564 | |
565 // Only if this WebContents is used in a tabstrip may be swap. | |
566 // We check this by examining whether its CoreTabHelper has a delegate. | |
567 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); | |
568 if (!core_tab_helper || !core_tab_helper->delegate()) { | |
569 RecordEvent(NULL, PRERENDER_EVENT_SWAPIN_NO_DELEGATE); | |
570 return NULL; | |
571 } | |
572 | 450 |
573 // First, try to find prerender data with the correct session storage | 451 // First, try to find prerender data with the correct session storage |
574 // namespace. | 452 // namespace. |
453 // TODO(ajwong): This doesn't handle isolated apps correctly. | |
575 PrerenderData* prerender_data = FindPrerenderData( | 454 PrerenderData* prerender_data = FindPrerenderData( |
576 url, | 455 url, |
577 web_contents->GetController().GetDefaultSessionStorageNamespace()); | 456 web_contents->GetController().GetDefaultSessionStorageNamespace()); |
578 | 457 |
579 // If this failed, we may still find a prerender for the same URL, but a | 458 // If this failed, we may still find a prerender for the same URL, but a |
580 // different session storage namespace. If we do, we might have to perform | 459 // different session storage namespace. If we do, we might have to perform |
581 // a merge. | 460 // a merge. |
582 if (!prerender_data) { | 461 if (!prerender_data) { |
583 prerender_data = FindPrerenderData(url, NULL); | 462 prerender_data = FindPrerenderData(url, NULL); |
584 } else { | 463 } else { |
585 RecordEvent(prerender_data->contents(), | 464 RecordEvent(prerender_data->contents(), |
586 PRERENDER_EVENT_SWAPIN_CANDIDATE_NAMESPACE_MATCHES); | 465 PRERENDER_EVENT_SWAPIN_CANDIDATE_NAMESPACE_MATCHES); |
587 } | 466 } |
588 | 467 |
589 if (!prerender_data) | 468 if (!prerender_data) |
590 return NULL; | 469 return false; |
591 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_CANDIDATE); | 470 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_CANDIDATE); |
592 DCHECK(prerender_data->contents()); | 471 DCHECK(prerender_data->contents()); |
593 | 472 |
594 // If there is currently a merge pending for this prerender data, | 473 // If there is currently a merge pending for this prerender data, |
595 // or this webcontents, do not swap in, but give the merge a chance to | 474 // or this webcontents, do not swap in, but give the merge a chance to |
596 // finish and swap into the intended target webcontents. | 475 // finish and swap into the intended target webcontents. |
597 if (prerender_data != swap_candidate && prerender_data->pending_swap()) { | 476 if (prerender_data->pending_swap()) |
598 return NULL; | 477 return false; |
mmenke
2013/12/09 21:04:44
Random comment: We could still theoretically have
| |
599 } | |
600 | 478 |
601 RecordEvent(prerender_data->contents(), | 479 RecordEvent(prerender_data->contents(), |
602 PRERENDER_EVENT_SWAPIN_NO_MERGE_PENDING); | 480 PRERENDER_EVENT_SWAPIN_NO_MERGE_PENDING); |
603 SessionStorageNamespace* target_namespace = | 481 SessionStorageNamespace* target_namespace = |
604 web_contents->GetController().GetDefaultSessionStorageNamespace(); | 482 web_contents->GetController().GetDefaultSessionStorageNamespace(); |
605 SessionStorageNamespace* prerender_namespace = | 483 SessionStorageNamespace* prerender_namespace = |
606 prerender_data->contents()->GetSessionStorageNamespace(); | 484 prerender_data->contents()->GetSessionStorageNamespace(); |
607 // Only when actually prerendering is session storage namespace merging an | 485 // Only when actually prerendering is session storage namespace merging an |
608 // issue. For the control group, it will be assumed that the merge succeeded. | 486 // issue. For the control group, it will be assumed that the merge succeeded. |
609 if (prerender_namespace && prerender_namespace != target_namespace && | 487 if (prerender_namespace && prerender_namespace != target_namespace && |
610 !prerender_namespace->IsAliasOf(target_namespace)) { | 488 !prerender_namespace->IsAliasOf(target_namespace)) { |
611 if (!ShouldMergeSessionStorageNamespaces()) { | 489 if (!ShouldMergeSessionStorageNamespaces()) { |
612 RecordEvent(prerender_data->contents(), | 490 RecordEvent(prerender_data->contents(), |
613 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); | 491 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); |
614 return NULL; | 492 return false; |
615 } | 493 } |
616 RecordEvent(prerender_data->contents(), | 494 RecordEvent(prerender_data->contents(), |
617 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); | 495 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); |
618 // There should never be a |pending_swap| if we get to here: | 496 prerender_data->set_pending_swap(new PendingSwap( |
619 // Per check above, |pending_swap| may only be != NULL when | 497 this, web_contents, prerender_data, url)); |
620 // processing a successful merge, as indicated by |swap_candidate| | 498 prerender_data->pending_swap()->BeginSwap(); |
621 // != NULL. But in that case, there should be no need for yet another merge. | 499 return false; |
mmenke
2013/12/09 21:04:44
optional: Suggest a comment that we'll defer the
davidben
2013/12/09 23:08:55
Done.
| |
622 DCHECK(!prerender_data->pending_swap()); | 500 } |
623 if (prerender_data->pending_swap()) { | 501 |
624 // In retail builds, log this error and bail. | 502 // No need to merge; swap synchronously. |
625 RecordEvent(prerender_data->contents(), | 503 WebContents* new_web_contents = SwapInternal(url, web_contents, |
626 PRERENDER_EVENT_MERGE_FOR_SWAPIN_CANDIDATE); | 504 prerender_data); |
627 return NULL; | 505 if (!new_web_contents) |
628 } | 506 return false; |
629 PendingSwap* pending_swap = new PendingSwap( | 507 |
630 prerender_tracker_, | 508 // Record the new target_contents for the callers. |
631 web_contents, | 509 params->target_contents = new_web_contents; |
632 prerender_data, | 510 return true; |
633 url, | 511 } |
634 base::Bind(&PrerenderManager::ProcessMergeResult, | 512 |
635 AsWeakPtr(), | 513 WebContents* PrerenderManager::SwapInternal( |
636 prerender_data, | 514 const GURL& url, |
637 true, | 515 WebContents* web_contents, |
638 SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE), | 516 PrerenderData* prerender_data) { |
639 base::Bind(&PrerenderManager::ProcessMergeResult, | 517 DCHECK(CalledOnValidThread()); |
640 AsWeakPtr(), | 518 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
641 prerender_data, | 519 |
642 false)); | 520 // Only if this WebContents is used in a tabstrip may be swap. |
mmenke
2013/12/09 21:04:44
nit: Know this was an old comment, but could you
davidben
2013/12/09 23:08:55
Done.
| |
643 prerender_data->set_pending_swap(pending_swap); | 521 // We check this by examining whether its CoreTabHelper has a delegate. |
644 prerender_namespace->Merge( | 522 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); |
645 true, | 523 if (!core_tab_helper || !core_tab_helper->delegate()) { |
646 prerender_data->contents()->child_id(), | 524 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_NO_DELEGATE); |
647 target_namespace, | |
648 pending_swap->GetMergeResultCallback()); | |
649 base::MessageLoop::current()->PostDelayedTask( | |
650 FROM_HERE, | |
651 pending_swap->GetTimeoutCallback(), | |
652 base::TimeDelta::FromMilliseconds( | |
653 kSessionStorageNamespaceMergeTimeoutMs)); | |
654 return NULL; | 525 return NULL; |
655 } | 526 } |
656 | 527 |
657 if (IsNoSwapInExperiment(prerender_data->contents()->experiment_id())) | 528 if (IsNoSwapInExperiment(prerender_data->contents()->experiment_id())) |
658 return NULL; | 529 return NULL; |
659 | 530 |
660 if (WebContents* new_web_contents = | 531 if (WebContents* new_web_contents = |
661 prerender_data->contents()->prerender_contents()) { | 532 prerender_data->contents()->prerender_contents()) { |
662 if (web_contents == new_web_contents) | 533 if (web_contents == new_web_contents) |
663 return NULL; // Do not swap in to ourself. | 534 return NULL; // Do not swap in to ourself. |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
844 NeedMatchCompleteDummyForFinalStatus(final_status) && | 715 NeedMatchCompleteDummyForFinalStatus(final_status) && |
845 ActuallyPrerendering()) { | 716 ActuallyPrerendering()) { |
846 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. | 717 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. |
847 // However, what if new conditions are added and | 718 // However, what if new conditions are added and |
848 // NeedMatchCompleteDummyForFinalStatus is not being updated. Not sure | 719 // NeedMatchCompleteDummyForFinalStatus is not being updated. Not sure |
849 // what's the best thing to do here. For now, I will just check whether | 720 // what's the best thing to do here. For now, I will just check whether |
850 // we are actually prerendering. | 721 // we are actually prerendering. |
851 (*it)->MakeIntoMatchCompleteReplacement(); | 722 (*it)->MakeIntoMatchCompleteReplacement(); |
852 } else { | 723 } else { |
853 to_delete_prerenders_.push_back(*it); | 724 to_delete_prerenders_.push_back(*it); |
854 (*it)->ClearPendingSwap(); | |
855 active_prerenders_.weak_erase(it); | 725 active_prerenders_.weak_erase(it); |
856 } | 726 } |
857 | 727 |
858 // Destroy the old WebContents relatively promptly to reduce resource usage. | 728 // Destroy the old WebContents relatively promptly to reduce resource usage. |
859 PostCleanupTask(); | 729 PostCleanupTask(); |
860 } | 730 } |
861 | 731 |
862 // static | 732 // static |
863 void PrerenderManager::RecordPerceivedPageLoadTime( | 733 void PrerenderManager::RecordPerceivedPageLoadTime( |
864 base::TimeDelta perceived_page_load_time, | 734 base::TimeDelta perceived_page_load_time, |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 | 1145 |
1276 void PrerenderManager::PrerenderData::ClearPendingSwap() { | 1146 void PrerenderManager::PrerenderData::ClearPendingSwap() { |
1277 pending_swap_.reset(NULL); | 1147 pending_swap_.reset(NULL); |
1278 } | 1148 } |
1279 | 1149 |
1280 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { | 1150 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { |
1281 return contents_.release(); | 1151 return contents_.release(); |
1282 } | 1152 } |
1283 | 1153 |
1284 PrerenderManager::PendingSwap::PendingSwap( | 1154 PrerenderManager::PendingSwap::PendingSwap( |
1285 PrerenderTracker* prerender_tracker, | 1155 PrerenderManager* manager, |
1286 content::WebContents* target_contents, | 1156 content::WebContents* target_contents, |
1287 PrerenderData* prerender_data, | 1157 PrerenderData* prerender_data, |
1288 const GURL& url, | 1158 const GURL& url) |
1289 const base::Closure& timeout_cb, | |
1290 const SessionStorageNamespace::MergeResultCallback& merge_result_cb) | |
1291 : content::WebContentsObserver(target_contents), | 1159 : content::WebContentsObserver(target_contents), |
1292 prerender_tracker_(prerender_tracker), | 1160 manager_(manager), |
1293 target_contents_(target_contents), | 1161 target_contents_(target_contents), |
1294 prerender_data_(prerender_data), | 1162 prerender_data_(prerender_data), |
1295 url_(url), | 1163 url_(url), |
1296 timeout_cb_(timeout_cb), | 1164 start_time_(base::TimeTicks::Now()), |
1297 merge_result_cb_(merge_result_cb), | 1165 weak_factory_(this) { |
1298 start_time_(base::TimeTicks::Now()) { | |
1299 RenderViewCreated(target_contents->GetRenderViewHost()); | 1166 RenderViewCreated(target_contents->GetRenderViewHost()); |
1300 } | 1167 } |
1301 | 1168 |
1302 PrerenderManager::PendingSwap::~PendingSwap() { | 1169 PrerenderManager::PendingSwap::~PendingSwap() { |
1303 timeout_cb_.Cancel(); | 1170 for (size_t i = 0; i < rvh_ids_.size(); i++) { |
1304 merge_result_cb_.Cancel(); | 1171 manager_->prerender_tracker()->RemovePrerenderPendingSwap( |
1305 for (size_t i = 0; i < rvh_ids_.size(); i++) { | 1172 rvh_ids_[i], false); |
1306 prerender_tracker_->RemovePrerenderPendingSwap(rvh_ids_[i], false); | 1173 } |
1307 } | |
1308 } | 1174 } |
1309 | 1175 |
1310 const base::Closure& PrerenderManager::PendingSwap::GetTimeoutCallback() { | 1176 void PrerenderManager::PendingSwap::BeginSwap() { |
1311 return timeout_cb_.callback(); | 1177 SessionStorageNamespace* target_namespace = |
1312 } | 1178 target_contents_->GetController().GetDefaultSessionStorageNamespace(); |
1179 SessionStorageNamespace* prerender_namespace = | |
1180 prerender_data_->contents()->GetSessionStorageNamespace(); | |
1313 | 1181 |
1314 void PrerenderManager::PendingSwap::SwapSuccessful() { | 1182 prerender_namespace->Merge( |
1315 for (size_t i = 0; i < rvh_ids_.size(); i++) { | 1183 true, prerender_data_->contents()->child_id(), |
1316 prerender_tracker_->RemovePrerenderPendingSwap(rvh_ids_[i], true); | 1184 target_namespace, |
1317 } | 1185 base::Bind(&PrerenderManager::PendingSwap::OnMergeCompleted, |
1318 rvh_ids_.clear(); | 1186 weak_factory_.GetWeakPtr())); |
1319 } | |
1320 | 1187 |
1321 const SessionStorageNamespace::MergeResultCallback& | 1188 merge_timeout_.Start( |
1322 PrerenderManager::PendingSwap::GetMergeResultCallback() { | 1189 FROM_HERE, |
1323 return merge_result_cb_.callback(); | 1190 base::TimeDelta::FromMilliseconds( |
1191 kSessionStorageNamespaceMergeTimeoutMs), | |
1192 this, &PrerenderManager::PendingSwap::OnMergeTimeout); | |
1324 } | 1193 } |
1325 | 1194 |
1326 void PrerenderManager::PendingSwap::ProvisionalChangeToMainFrameUrl( | 1195 void PrerenderManager::PendingSwap::ProvisionalChangeToMainFrameUrl( |
1327 const GURL& url, | 1196 const GURL& url, |
1328 content::RenderViewHost* render_view_host) { | 1197 content::RenderViewHost* render_view_host) { |
1329 // We must only cancel the pending swap if the |url| navigated to is not | 1198 // We must only cancel the pending swap if the |url| navigated to is not |
1330 // the URL being attempted to be swapped in. That's because in the normal | 1199 // the URL being attempted to be swapped in. That's because in the normal |
1331 // flow, a ProvisionalChangeToMainFrameUrl will happen for the URL attempted | 1200 // flow, a ProvisionalChangeToMainFrameUrl will happen for the URL attempted |
1332 // to be swapped in immediately after the pending swap has issued its merge. | 1201 // to be swapped in immediately after the pending swap has issued its merge. |
1333 if (url != url_) | 1202 if (url != url_) |
1334 prerender_data_->ClearPendingSwap(); | 1203 prerender_data_->ClearPendingSwap(); |
1335 } | 1204 } |
1336 | 1205 |
1337 void PrerenderManager::PendingSwap::DidCommitProvisionalLoadForFrame( | 1206 void PrerenderManager::PendingSwap::DidCommitProvisionalLoadForFrame( |
1338 int64 frame_id, | 1207 int64 frame_id, |
1339 const string16& frame_unique_name, | 1208 const string16& frame_unique_name, |
1340 bool is_main_frame, | 1209 bool is_main_frame, |
1341 const GURL& validated_url, | 1210 const GURL& validated_url, |
1342 content::PageTransition transition_type, | 1211 content::PageTransition transition_type, |
1343 content::RenderViewHost* render_view_host){ | 1212 content::RenderViewHost* render_view_host){ |
1344 if (!is_main_frame) | 1213 if (!is_main_frame) |
1345 return; | 1214 return; |
1346 if (validated_url != url_) | 1215 prerender_data_->ClearPendingSwap(); |
1347 prerender_data_->ClearPendingSwap(); | |
1348 } | 1216 } |
1349 | 1217 |
1350 void PrerenderManager::PendingSwap::RenderViewCreated( | 1218 void PrerenderManager::PendingSwap::RenderViewCreated( |
1351 content::RenderViewHost* render_view_host) { | 1219 content::RenderViewHost* render_view_host) { |
1220 // Record the RVH id in the tracker to install throttles on MAIN_FRAME | |
1221 // requests from that route. | |
1352 int child_id = render_view_host->GetProcess()->GetID(); | 1222 int child_id = render_view_host->GetProcess()->GetID(); |
1353 int route_id = render_view_host->GetRoutingID(); | 1223 int route_id = render_view_host->GetRoutingID(); |
1354 PrerenderTracker::ChildRouteIdPair child_route_id_pair(child_id, route_id); | 1224 PrerenderTracker::ChildRouteIdPair child_route_id_pair(child_id, route_id); |
1355 rvh_ids_.push_back(child_route_id_pair); | 1225 rvh_ids_.push_back(child_route_id_pair); |
1356 prerender_tracker_->AddPrerenderPendingSwap(child_route_id_pair, url_); | 1226 manager_->prerender_tracker()->AddPrerenderPendingSwap( |
1227 child_route_id_pair, url_); | |
1357 } | 1228 } |
1358 | 1229 |
1359 void PrerenderManager::PendingSwap::DidFailProvisionalLoad( | 1230 void PrerenderManager::PendingSwap::DidFailProvisionalLoad( |
1360 int64 frame_id, | 1231 int64 frame_id, |
1361 const string16& frame_unique_name, | 1232 const string16& frame_unique_name, |
1362 bool is_main_frame, | 1233 bool is_main_frame, |
1363 const GURL& validated_url, | 1234 const GURL& validated_url, |
1364 int error_code, | 1235 int error_code, |
1365 const string16& error_description, | 1236 const string16& error_description, |
1366 content::RenderViewHost* render_view_host) { | 1237 content::RenderViewHost* render_view_host) { |
1238 if (!is_main_frame) | |
1239 return; | |
1367 prerender_data_->ClearPendingSwap(); | 1240 prerender_data_->ClearPendingSwap(); |
1368 } | 1241 } |
1369 | 1242 |
1370 void PrerenderManager::PendingSwap::WebContentsDestroyed( | 1243 void PrerenderManager::PendingSwap::WebContentsDestroyed( |
1371 content::WebContents* web_contents) { | 1244 content::WebContents* web_contents) { |
1372 prerender_data_->ClearPendingSwap(); | 1245 prerender_data_->ClearPendingSwap(); |
1373 } | 1246 } |
1374 | 1247 |
1375 base::TimeDelta PrerenderManager::PendingSwap::GetElapsedTime() { | 1248 void PrerenderManager::PendingSwap::SwapSuccessful() { |
mmenke
2013/12/09 21:04:44
Can we just delete the swap object and get rid of
davidben
2013/12/09 23:08:55
There's the parameter for whether the swap succeed
| |
1376 return base::TimeTicks::Now() - start_time_; | 1249 for (size_t i = 0; i < rvh_ids_.size(); i++) { |
1250 manager_->prerender_tracker()->RemovePrerenderPendingSwap( | |
1251 rvh_ids_[i], true); | |
1252 } | |
1253 rvh_ids_.clear(); | |
1254 } | |
1255 | |
1256 void PrerenderManager::PendingSwap::RecordEvent(PrerenderEvent event) const { | |
1257 manager_->RecordEvent(prerender_data_->contents(), event); | |
1258 } | |
1259 | |
1260 void PrerenderManager::PendingSwap::OnMergeCompleted( | |
1261 SessionStorageNamespace::MergeResult result) { | |
1262 UMA_HISTOGRAM_TIMES("Prerender.SessionStorageNamespaceMergeTime", | |
1263 base::TimeTicks::Now() - start_time_); | |
1264 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_DONE); | |
1265 | |
1266 // Log the exact merge result in a histogram. | |
1267 switch (result) { | |
1268 case SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: | |
1269 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_FOUND); | |
1270 break; | |
1271 case SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: | |
1272 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_ALIAS); | |
1273 break; | |
1274 case SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: | |
1275 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_LOGGING); | |
1276 break; | |
1277 case SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: | |
1278 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NO_TRANSACTIONS); | |
1279 break; | |
1280 case SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: | |
1281 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_TOO_MANY_TRANSACTIONS); | |
1282 break; | |
1283 case SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: | |
1284 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_MERGEABLE); | |
1285 break; | |
1286 case SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | |
1287 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_MERGEABLE); | |
1288 break; | |
1289 default: | |
1290 NOTREACHED(); | |
1291 } | |
1292 | |
1293 if (result != SessionStorageNamespace::MERGE_RESULT_MERGEABLE && | |
1294 result != SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS) { | |
1295 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_FAILED); | |
1296 prerender_data_->ClearPendingSwap(); | |
1297 return; | |
1298 } | |
1299 | |
1300 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); | |
1301 // Note that SwapInternal, on success, will delete |prerender_data_| and | |
1302 // |this|. Pass in a new GURL object rather than a reference to |url_|. | |
1303 WebContents* new_web_contents = | |
1304 manager_->SwapInternal(GURL(url_), target_contents_, prerender_data_); | |
1305 if (!new_web_contents) { | |
1306 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); | |
1307 prerender_data_->ClearPendingSwap(); | |
1308 } | |
1309 } | |
1310 | |
1311 void PrerenderManager::PendingSwap::OnMergeTimeout() { | |
1312 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | |
1313 prerender_data_->ClearPendingSwap(); | |
1377 } | 1314 } |
1378 | 1315 |
1379 void PrerenderManager::SetPrerenderContentsFactory( | 1316 void PrerenderManager::SetPrerenderContentsFactory( |
1380 PrerenderContents::Factory* prerender_contents_factory) { | 1317 PrerenderContents::Factory* prerender_contents_factory) { |
1381 DCHECK(CalledOnValidThread()); | 1318 DCHECK(CalledOnValidThread()); |
1382 prerender_contents_factory_.reset(prerender_contents_factory); | 1319 prerender_contents_factory_.reset(prerender_contents_factory); |
1383 } | 1320 } |
1384 | 1321 |
1385 | 1322 |
1386 void PrerenderManager::StartPendingPrerenders( | 1323 void PrerenderManager::StartPendingPrerenders( |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1944 void PrerenderManager::RecordEvent(PrerenderContents* contents, | 1881 void PrerenderManager::RecordEvent(PrerenderContents* contents, |
1945 PrerenderEvent event) const { | 1882 PrerenderEvent event) const { |
1946 if (!contents) | 1883 if (!contents) |
1947 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); | 1884 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); |
1948 else | 1885 else |
1949 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), | 1886 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), |
1950 event); | 1887 event); |
1951 } | 1888 } |
1952 | 1889 |
1953 } // namespace prerender | 1890 } // namespace prerender |
OLD | NEW |