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

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

Issue 98373010: Refactor prerender pending swap logic. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move cleanup code Created 7 years 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
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698