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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 436 |
437 void PrerenderManager::ProcessMergeResult( | 437 void PrerenderManager::ProcessMergeResult( |
438 PrerenderData* prerender_data, | 438 PrerenderData* prerender_data, |
439 bool timed_out, | 439 bool timed_out, |
440 content::SessionStorageNamespace::MergeResult result) { | 440 content::SessionStorageNamespace::MergeResult result) { |
441 PendingSwap* pending_swap = prerender_data->pending_swap(); | 441 PendingSwap* pending_swap = prerender_data->pending_swap(); |
442 DCHECK(pending_swap); | 442 DCHECK(pending_swap); |
443 // No pending_swap should never happen. If it does anyways (in a retail | 443 // No pending_swap should never happen. If it does anyways (in a retail |
444 // build), log this and bail. | 444 // build), log this and bail. |
445 if (!pending_swap) { | 445 if (!pending_swap) { |
446 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_NO_PENDING_SWAPIN); | 446 RecordEvent(prerender_data->contents(), |
| 447 PRERENDER_EVENT_MERGE_RESULT_NO_PENDING_SWAPIN); |
447 return; | 448 return; |
448 } | 449 } |
449 if (timed_out) { | 450 if (timed_out) { |
450 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMEOUT_CB); | 451 RecordEvent(prerender_data->contents(), |
| 452 PRERENDER_EVENT_MERGE_RESULT_TIMEOUT_CB); |
451 } else { | 453 } else { |
452 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_CB); | 454 RecordEvent(prerender_data->contents(), |
| 455 PRERENDER_EVENT_MERGE_RESULT_RESULT_CB); |
453 UMA_HISTOGRAM_TIMES("Prerender.SessionStorageNamespaceMergeTime", | 456 UMA_HISTOGRAM_TIMES("Prerender.SessionStorageNamespaceMergeTime", |
454 pending_swap->GetElapsedTime()); | 457 pending_swap->GetElapsedTime()); |
455 } | 458 } |
456 | 459 |
457 // Any return here must call ClearPendingSwap on |prerender_data| before | 460 // Any return here must call ClearPendingSwap on |prerender_data| before |
458 // returning, with one exception: when the prerender was ultimately swapped | 461 // returning, with one exception: when the prerender was ultimately swapped |
459 // in. In that case, SwapInternal will take care of deleting | 462 // in. In that case, SwapInternal will take care of deleting |
460 // |prerender_data| and sending the appropriate notifications to the tracker. | 463 // |prerender_data| and sending the appropriate notifications to the tracker. |
461 if (timed_out) { | 464 if (timed_out) { |
462 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | 465 RecordEvent(prerender_data->contents(), |
| 466 PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); |
463 prerender_data->ClearPendingSwap(); | 467 prerender_data->ClearPendingSwap(); |
464 return; | 468 return; |
465 } | 469 } |
466 | 470 |
467 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_DONE); | 471 RecordEvent(prerender_data->contents(), |
| 472 PRERENDER_EVENT_MERGE_RESULT_MERGE_DONE); |
468 | 473 |
469 // Log the exact merge result in a histogram. | 474 // Log the exact merge result in a histogram. |
470 switch (result) { | 475 switch (result) { |
471 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: | 476 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: |
472 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_FOUND); | 477 RecordEvent(prerender_data->contents(), |
| 478 PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_FOUND); |
473 break; | 479 break; |
474 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: | 480 case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: |
475 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_ALIAS); | 481 RecordEvent(prerender_data->contents(), |
| 482 PRERENDER_EVENT_MERGE_RESULT_RESULT_NAMESPACE_NOT_ALIAS); |
476 break; | 483 break; |
477 case content::SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: | 484 case content::SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: |
478 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_LOGGING); | 485 RecordEvent(prerender_data->contents(), |
| 486 PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_LOGGING); |
479 break; | 487 break; |
480 case content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: | 488 case content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: |
481 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NO_TRANSACTIONS); | 489 RecordEvent(prerender_data->contents(), |
| 490 PRERENDER_EVENT_MERGE_RESULT_RESULT_NO_TRANSACTIONS); |
482 break; | 491 break; |
483 case content::SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: | 492 case content::SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: |
484 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_TOO_MANY_TRANSACTIONS); | 493 RecordEvent(prerender_data->contents(), |
| 494 PRERENDER_EVENT_MERGE_RESULT_RESULT_TOO_MANY_TRANSACTIONS); |
485 break; | 495 break; |
486 case content::SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: | 496 case content::SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: |
487 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_MERGEABLE); | 497 RecordEvent(prerender_data->contents(), |
| 498 PRERENDER_EVENT_MERGE_RESULT_RESULT_NOT_MERGEABLE); |
488 break; | 499 break; |
489 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: | 500 case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: |
490 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_RESULT_MERGEABLE); | 501 RecordEvent(prerender_data->contents(), |
| 502 PRERENDER_EVENT_MERGE_RESULT_RESULT_MERGEABLE); |
491 break; | 503 break; |
492 default: | 504 default: |
493 NOTREACHED(); | 505 NOTREACHED(); |
494 } | 506 } |
495 | 507 |
496 if (result != content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE && | 508 if (result != content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE && |
497 result != | 509 result != |
498 content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS) { | 510 content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS) { |
499 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_MERGE_FAILED); | 511 RecordEvent(prerender_data->contents(), |
| 512 PRERENDER_EVENT_MERGE_RESULT_MERGE_FAILED); |
500 prerender_data->ClearPendingSwap(); | 513 prerender_data->ClearPendingSwap(); |
501 return; | 514 return; |
502 } | 515 } |
503 | 516 |
504 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); | 517 RecordEvent(prerender_data->contents(), |
| 518 PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); |
505 // Notice that SwapInInternal, on success, will delete |prerender_data| | 519 // Notice that SwapInInternal, on success, will delete |prerender_data| |
506 // and |pending_swap|. Therefore, we have to pass a new GURL object rather | 520 // and |pending_swap|. Therefore, we have to pass a new GURL object rather |
507 // than a reference to the one in |pending_swap|. | 521 // than a reference to the one in |pending_swap|. |
508 content::WebContents* new_web_contents = | 522 content::WebContents* new_web_contents = |
509 SwapInternal(GURL(pending_swap->url()), | 523 SwapInternal(GURL(pending_swap->url()), |
510 pending_swap->target_contents(), | 524 pending_swap->target_contents(), |
511 prerender_data); | 525 prerender_data); |
512 if (new_web_contents) { | 526 if (!new_web_contents) { |
513 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPIN_SUCCESSFUL); | 527 RecordEvent(prerender_data->contents(), |
514 } else { | 528 PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); |
515 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); | |
516 prerender_data->ClearPendingSwap(); | 529 prerender_data->ClearPendingSwap(); |
517 } | 530 } |
518 } | 531 } |
519 | 532 |
520 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, | 533 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, |
521 chrome::NavigateParams* params) { | 534 chrome::NavigateParams* params) { |
522 DCHECK(CalledOnValidThread()); | 535 DCHECK(CalledOnValidThread()); |
523 | 536 |
524 content::WebContents* web_contents = params->target_contents; | 537 content::WebContents* web_contents = params->target_contents; |
525 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | 538 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
(...skipping 20 matching lines...) Expand all Loading... |
546 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | 559 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
547 | 560 |
548 DeleteOldEntries(); | 561 DeleteOldEntries(); |
549 to_delete_prerenders_.clear(); | 562 to_delete_prerenders_.clear(); |
550 // TODO(ajwong): This doesn't handle isolated apps correctly. | 563 // TODO(ajwong): This doesn't handle isolated apps correctly. |
551 | 564 |
552 // Only if this WebContents is used in a tabstrip may be swap. | 565 // Only if this WebContents is used in a tabstrip may be swap. |
553 // We check this by examining whether its CoreTabHelper has a delegate. | 566 // We check this by examining whether its CoreTabHelper has a delegate. |
554 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); | 567 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); |
555 if (!core_tab_helper || !core_tab_helper->delegate()) { | 568 if (!core_tab_helper || !core_tab_helper->delegate()) { |
556 RecordEvent(PRERENDER_EVENT_SWAPIN_NO_DELEGATE); | 569 RecordEvent(NULL, PRERENDER_EVENT_SWAPIN_NO_DELEGATE); |
557 return NULL; | 570 return NULL; |
558 } | 571 } |
559 | 572 |
560 // First, try to find prerender data with the correct session storage | 573 // First, try to find prerender data with the correct session storage |
561 // namespace. | 574 // namespace. |
562 PrerenderData* prerender_data = FindPrerenderData( | 575 PrerenderData* prerender_data = FindPrerenderData( |
563 url, | 576 url, |
564 web_contents->GetController().GetDefaultSessionStorageNamespace()); | 577 web_contents->GetController().GetDefaultSessionStorageNamespace()); |
565 | 578 |
566 // If this failed, we may still find a prerender for the same URL, but a | 579 // If this failed, we may still find a prerender for the same URL, but a |
567 // different session storage namespace. If we do, we might have to perform | 580 // different session storage namespace. If we do, we might have to perform |
568 // a merge. | 581 // a merge. |
569 if (!prerender_data) { | 582 if (!prerender_data) { |
570 prerender_data = FindPrerenderData(url, NULL); | 583 prerender_data = FindPrerenderData(url, NULL); |
571 } else { | 584 } else { |
572 RecordEvent(PRERENDER_EVENT_SWAPIN_CANDIDATE_NAMESPACE_MATCHES); | 585 RecordEvent(prerender_data->contents(), |
| 586 PRERENDER_EVENT_SWAPIN_CANDIDATE_NAMESPACE_MATCHES); |
573 } | 587 } |
574 | 588 |
575 if (!prerender_data) | 589 if (!prerender_data) |
576 return NULL; | 590 return NULL; |
577 RecordEvent(PRERENDER_EVENT_SWAPIN_CANDIDATE); | 591 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_CANDIDATE); |
578 DCHECK(prerender_data->contents()); | 592 DCHECK(prerender_data->contents()); |
579 | 593 |
580 // If there is currently a merge pending for this prerender data, | 594 // If there is currently a merge pending for this prerender data, |
581 // or this webcontents, do not swap in, but give the merge a chance to | 595 // or this webcontents, do not swap in, but give the merge a chance to |
582 // finish and swap into the intended target webcontents. | 596 // finish and swap into the intended target webcontents. |
583 if (prerender_data != swap_candidate && prerender_data->pending_swap()) { | 597 if (prerender_data != swap_candidate && prerender_data->pending_swap()) { |
584 return NULL; | 598 return NULL; |
585 } | 599 } |
586 | 600 |
587 RecordEvent(PRERENDER_EVENT_SWAPIN_NO_MERGE_PENDING); | 601 RecordEvent(prerender_data->contents(), |
| 602 PRERENDER_EVENT_SWAPIN_NO_MERGE_PENDING); |
588 SessionStorageNamespace* target_namespace = | 603 SessionStorageNamespace* target_namespace = |
589 web_contents->GetController().GetDefaultSessionStorageNamespace(); | 604 web_contents->GetController().GetDefaultSessionStorageNamespace(); |
590 SessionStorageNamespace* prerender_namespace = | 605 SessionStorageNamespace* prerender_namespace = |
591 prerender_data->contents()->GetSessionStorageNamespace(); | 606 prerender_data->contents()->GetSessionStorageNamespace(); |
592 // Only when actually prerendering is session storage namespace merging an | 607 // Only when actually prerendering is session storage namespace merging an |
593 // issue. For the control group, it will be assumed that the merge succeeded. | 608 // issue. For the control group, it will be assumed that the merge succeeded. |
594 if (prerender_namespace && prerender_namespace != target_namespace && | 609 if (prerender_namespace && prerender_namespace != target_namespace && |
595 !prerender_namespace->IsAliasOf(target_namespace)) { | 610 !prerender_namespace->IsAliasOf(target_namespace)) { |
596 if (!ShouldMergeSessionStorageNamespaces()) { | 611 if (!ShouldMergeSessionStorageNamespaces()) { |
597 RecordEvent(PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); | 612 RecordEvent(prerender_data->contents(), |
| 613 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); |
598 return NULL; | 614 return NULL; |
599 } | 615 } |
600 RecordEvent(PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); | 616 RecordEvent(prerender_data->contents(), |
| 617 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); |
601 // There should never be a |pending_swap| if we get to here: | 618 // There should never be a |pending_swap| if we get to here: |
602 // Per check above, |pending_swap| may only be != NULL when | 619 // Per check above, |pending_swap| may only be != NULL when |
603 // processing a successful merge, as indicated by |swap_candidate| | 620 // processing a successful merge, as indicated by |swap_candidate| |
604 // != NULL. But in that case, there should be no need for yet another merge. | 621 // != NULL. But in that case, there should be no need for yet another merge. |
605 DCHECK(!prerender_data->pending_swap()); | 622 DCHECK(!prerender_data->pending_swap()); |
606 if (prerender_data->pending_swap()) { | 623 if (prerender_data->pending_swap()) { |
607 // In retail builds, log this error and bail. | 624 // In retail builds, log this error and bail. |
608 RecordEvent(PRERENDER_EVENT_MERGE_FOR_SWAPIN_CANDIDATE); | 625 RecordEvent(prerender_data->contents(), |
| 626 PRERENDER_EVENT_MERGE_FOR_SWAPIN_CANDIDATE); |
609 return NULL; | 627 return NULL; |
610 } | 628 } |
611 PendingSwap* pending_swap = new PendingSwap( | 629 PendingSwap* pending_swap = new PendingSwap( |
612 prerender_tracker_, | 630 prerender_tracker_, |
613 web_contents, | 631 web_contents, |
614 prerender_data, | 632 prerender_data, |
615 url, | 633 url, |
616 base::Bind(&PrerenderManager::ProcessMergeResult, | 634 base::Bind(&PrerenderManager::ProcessMergeResult, |
617 AsWeakPtr(), | 635 AsWeakPtr(), |
618 prerender_data, | 636 prerender_data, |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1916 if (logged_in_state_.get()) | 1934 if (logged_in_state_.get()) |
1917 logged_in_state_->erase(domain_key); | 1935 logged_in_state_->erase(domain_key); |
1918 } | 1936 } |
1919 | 1937 |
1920 void PrerenderManager::LoggedInPredictorDataReceived( | 1938 void PrerenderManager::LoggedInPredictorDataReceived( |
1921 scoped_ptr<LoggedInStateMap> new_map) { | 1939 scoped_ptr<LoggedInStateMap> new_map) { |
1922 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1940 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1923 logged_in_state_.swap(new_map); | 1941 logged_in_state_.swap(new_map); |
1924 } | 1942 } |
1925 | 1943 |
1926 void PrerenderManager::RecordEvent(PrerenderEvent event) const { | 1944 void PrerenderManager::RecordEvent(PrerenderContents* contents, |
1927 histograms_->RecordEvent(event); | 1945 PrerenderEvent event) const { |
| 1946 if (!contents) |
| 1947 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); |
| 1948 else |
| 1949 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), |
| 1950 event); |
1928 } | 1951 } |
1929 | 1952 |
1930 } // namespace prerender | 1953 } // namespace prerender |
OLD | NEW |