| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/prerender/prerender_manager.h" | 5 #include "chrome/browser/prerender/prerender_manager.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 123 |
| 124 // static | 124 // static |
| 125 bool PrerenderManager::IsPrerenderingPossible() { | 125 bool PrerenderManager::IsPrerenderingPossible() { |
| 126 return GetMode() == PRERENDER_MODE_ENABLED || | 126 return GetMode() == PRERENDER_MODE_ENABLED || |
| 127 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || | 127 GetMode() == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP || |
| 128 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP || | 128 GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP || |
| 129 GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; | 129 GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; |
| 130 } | 130 } |
| 131 | 131 |
| 132 // static | 132 // static |
| 133 bool PrerenderManager::ActuallyPrerendering() { |
| 134 return IsPrerenderingPossible() && !IsControlGroup(); |
| 135 } |
| 136 |
| 137 // static |
| 133 bool PrerenderManager::IsControlGroup() { | 138 bool PrerenderManager::IsControlGroup() { |
| 134 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; | 139 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; |
| 135 } | 140 } |
| 136 | 141 |
| 137 // static | 142 // static |
| 138 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { | 143 bool PrerenderManager::IsValidHttpMethod(const std::string& method) { |
| 139 // method has been canonicalized to upper case at this point so we can just | 144 // method has been canonicalized to upper case at this point so we can just |
| 140 // compare them. | 145 // compare them. |
| 141 DCHECK_EQ(method, StringToUpperASCII(method)); | 146 DCHECK_EQ(method, StringToUpperASCII(method)); |
| 142 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { | 147 for (size_t i = 0; i < arraysize(kValidHttpMethods); ++i) { |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 } | 383 } |
| 379 } | 384 } |
| 380 | 385 |
| 381 if (!session_storage_namespace && source_render_view_host) { | 386 if (!session_storage_namespace && source_render_view_host) { |
| 382 session_storage_namespace = | 387 session_storage_namespace = |
| 383 source_render_view_host->session_storage_namespace(); | 388 source_render_view_host->session_storage_namespace(); |
| 384 } | 389 } |
| 385 | 390 |
| 386 PrerenderContents* prerender_contents = CreatePrerenderContents( | 391 PrerenderContents* prerender_contents = CreatePrerenderContents( |
| 387 url, referrer, origin, experiment); | 392 url, referrer, origin, experiment); |
| 388 if (!prerender_contents || !prerender_contents->Init()) | 393 if (!prerender_contents || !prerender_contents->Init()) { |
| 394 if (prerender_contents) |
| 395 delete prerender_contents; |
| 389 return false; | 396 return false; |
| 397 } |
| 390 | 398 |
| 391 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? | 399 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? |
| 392 PrerenderContentsData data(prerender_contents, GetCurrentTime()); | 400 PrerenderContentsData data(prerender_contents, GetCurrentTime()); |
| 393 | 401 |
| 394 prerender_list_.push_back(data); | 402 prerender_list_.push_back(data); |
| 395 | 403 |
| 396 if (IsControlGroup()) { | 404 if (IsControlGroup()) { |
| 397 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); | 405 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); |
| 398 } else { | 406 } else { |
| 399 last_prerender_start_time_ = GetCurrentTimeTicks(); | 407 last_prerender_start_time_ = GetCurrentTimeTicks(); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 // No unload handler to run, so delete asap. | 648 // No unload handler to run, so delete asap. |
| 641 ScheduleDeleteOldTabContents(old_tab_contents, NULL); | 649 ScheduleDeleteOldTabContents(old_tab_contents, NULL); |
| 642 } | 650 } |
| 643 | 651 |
| 644 // TODO(cbentzel): Should prerender_contents move to the pending delete | 652 // TODO(cbentzel): Should prerender_contents move to the pending delete |
| 645 // list, instead of deleting directly here? | 653 // list, instead of deleting directly here? |
| 646 AddToHistory(prerender_contents.get()); | 654 AddToHistory(prerender_contents.get()); |
| 647 return true; | 655 return true; |
| 648 } | 656 } |
| 649 | 657 |
| 650 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { | 658 bool PrerenderManager::NeedMatchCompleteDummyForFinalStatus( |
| 659 FinalStatus final_status) const { |
| 660 return final_status != FINAL_STATUS_USED && |
| 661 final_status != FINAL_STATUS_TIMED_OUT && |
| 662 final_status != FINAL_STATUS_EVICTED && |
| 663 final_status != FINAL_STATUS_MANAGER_SHUTDOWN && |
| 664 final_status != FINAL_STATUS_WINDOW_OPENER && |
| 665 final_status != FINAL_STATUS_FRAGMENT_MISMATCH && |
| 666 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && |
| 667 final_status != FINAL_STATUS_CANCELLED && |
| 668 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; |
| 669 } |
| 670 |
| 671 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry, |
| 672 FinalStatus final_status) { |
| 651 DCHECK(CalledOnValidThread()); | 673 DCHECK(CalledOnValidThread()); |
| 674 DCHECK(entry); |
| 652 DCHECK(!IsPendingDelete(entry)); | 675 DCHECK(!IsPendingDelete(entry)); |
| 676 |
| 677 // If this PrerenderContents is being deleted due to a cancellation, we need |
| 678 // to create a dummy replacement for PPLT accounting purposes for the |
| 679 // Match Complete group. |
| 680 // This is the case if the cancellation is for any reason that would not occur |
| 681 // in the control group case. |
| 682 PrerenderContents* dummy_replacement_prerender_contents = NULL; |
| 683 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { |
| 684 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. |
| 685 // However, what if new conditions are added and |
| 686 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure |
| 687 // what's the best thing to do here. For now, I will just check whether |
| 688 // we are actually prerendering. |
| 689 if (ActuallyPrerendering()) { |
| 690 dummy_replacement_prerender_contents = CreatePrerenderContents( |
| 691 entry->prerender_url(), |
| 692 entry->referrer(), |
| 693 entry->origin(), |
| 694 entry->experiment_id()); |
| 695 if (dummy_replacement_prerender_contents) { |
| 696 if (!dummy_replacement_prerender_contents->Init()) { |
| 697 delete dummy_replacement_prerender_contents; |
| 698 dummy_replacement_prerender_contents = NULL; |
| 699 } |
| 700 } |
| 701 } |
| 702 } |
| 703 |
| 653 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); | 704 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); |
| 654 it != prerender_list_.end(); | 705 it != prerender_list_.end(); |
| 655 ++it) { | 706 ++it) { |
| 656 if (it->contents_ == entry) { | 707 if (it->contents_ == entry) { |
| 657 prerender_list_.erase(it); | 708 if (dummy_replacement_prerender_contents) { |
| 709 it->contents_ = dummy_replacement_prerender_contents; |
| 710 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY); |
| 711 } else { |
| 712 prerender_list_.erase(it); |
| 713 } |
| 658 break; | 714 break; |
| 659 } | 715 } |
| 660 } | 716 } |
| 661 AddToHistory(entry); | 717 AddToHistory(entry); |
| 662 pending_delete_list_.push_back(entry); | 718 pending_delete_list_.push_back(entry); |
| 663 | 719 |
| 664 // Destroy the old TabContents relatively promptly to reduce resource usage, | 720 // Destroy the old TabContents relatively promptly to reduce resource usage, |
| 665 // and in the case of HTML5 media, reduce the change of playing any sound. | 721 // and in the case of HTML5 media, reduce the change of playing any sound. |
| 666 PostCleanupTask(); | 722 PostCleanupTask(); |
| 667 } | 723 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 const GURL& url) { | 775 const GURL& url) { |
| 720 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 721 PrerenderManager* prerender_manager = | 777 PrerenderManager* prerender_manager = |
| 722 PrerenderManagerFactory::GetForProfile( | 778 PrerenderManagerFactory::GetForProfile( |
| 723 Profile::FromBrowserContext(tab_contents->browser_context())); | 779 Profile::FromBrowserContext(tab_contents->browser_context())); |
| 724 if (!prerender_manager) | 780 if (!prerender_manager) |
| 725 return; | 781 return; |
| 726 if (!prerender_manager->is_enabled()) | 782 if (!prerender_manager->is_enabled()) |
| 727 return; | 783 return; |
| 728 bool was_prerender = | 784 bool was_prerender = |
| 729 ((mode_ == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP && | 785 prerender_manager->IsTabContentsPrerendered(tab_contents); |
| 730 prerender_manager->WouldTabContentsBePrerendered(tab_contents)) || | 786 bool was_complete_prerender = was_prerender || |
| 731 (mode_ == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP && | 787 prerender_manager->WouldTabContentsBePrerendered(tab_contents); |
| 732 prerender_manager->IsTabContentsPrerendered(tab_contents))); | |
| 733 prerender_manager->histograms_->RecordPerceivedPageLoadTime( | 788 prerender_manager->histograms_->RecordPerceivedPageLoadTime( |
| 734 perceived_page_load_time, was_prerender, url); | 789 perceived_page_load_time, was_prerender, was_complete_prerender, url); |
| 735 } | 790 } |
| 736 | 791 |
| 737 bool PrerenderManager::is_enabled() const { | 792 bool PrerenderManager::is_enabled() const { |
| 738 DCHECK(CalledOnValidThread()); | 793 DCHECK(CalledOnValidThread()); |
| 739 if (!enabled_) | 794 if (!enabled_) |
| 740 return false; | 795 return false; |
| 741 for (std::list<const PrerenderCondition*>::const_iterator it = | 796 for (std::list<const PrerenderCondition*>::const_iterator it = |
| 742 prerender_conditions_.begin(); | 797 prerender_conditions_.begin(); |
| 743 it != prerender_conditions_.end(); | 798 it != prerender_conditions_.end(); |
| 744 ++it) { | 799 ++it) { |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 if (!render_process_host || !render_process_host->browser_context()) | 1100 if (!render_process_host || !render_process_host->browser_context()) |
| 1046 return NULL; | 1101 return NULL; |
| 1047 Profile* profile = Profile::FromBrowserContext( | 1102 Profile* profile = Profile::FromBrowserContext( |
| 1048 render_process_host->browser_context()); | 1103 render_process_host->browser_context()); |
| 1049 if (!profile) | 1104 if (!profile) |
| 1050 return NULL; | 1105 return NULL; |
| 1051 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); | 1106 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); |
| 1052 } | 1107 } |
| 1053 | 1108 |
| 1054 } // namespace prerender | 1109 } // namespace prerender |
| OLD | NEW |