| 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_local_predictor.h" | 5 #include "chrome/browser/prerender/prerender_local_predictor.h" |
| 6 | 6 |
| 7 #include <ctype.h> | 7 #include <ctype.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 base::Time actual_start_time; | 299 base::Time actual_start_time; |
| 300 | 300 |
| 301 private: | 301 private: |
| 302 DISALLOW_IMPLICIT_CONSTRUCTORS(PrerenderProperties); | 302 DISALLOW_IMPLICIT_CONSTRUCTORS(PrerenderProperties); |
| 303 }; | 303 }; |
| 304 | 304 |
| 305 PrerenderLocalPredictor::PrerenderLocalPredictor( | 305 PrerenderLocalPredictor::PrerenderLocalPredictor( |
| 306 PrerenderManager* prerender_manager) | 306 PrerenderManager* prerender_manager) |
| 307 : prerender_manager_(prerender_manager), | 307 : prerender_manager_(prerender_manager), |
| 308 is_visit_database_observer_(false), | 308 is_visit_database_observer_(false), |
| 309 weak_factory_(this) { | 309 weak_factory_(this), |
| 310 current_prerender_would_have_matched_(false) { |
| 310 RecordEvent(EVENT_CONSTRUCTED); | 311 RecordEvent(EVENT_CONSTRUCTED); |
| 311 if (MessageLoop::current()) { | 312 if (MessageLoop::current()) { |
| 312 timer_.Start(FROM_HERE, | 313 timer_.Start(FROM_HERE, |
| 313 base::TimeDelta::FromMilliseconds(kInitDelayMs), | 314 base::TimeDelta::FromMilliseconds(kInitDelayMs), |
| 314 this, | 315 this, |
| 315 &PrerenderLocalPredictor::Init); | 316 &PrerenderLocalPredictor::Init); |
| 316 RecordEvent(EVENT_INIT_SCHEDULED); | 317 RecordEvent(EVENT_INIT_SCHEDULED); |
| 317 } | 318 } |
| 318 | 319 |
| 319 static const size_t kChecksumHashSize = 32; | 320 static const size_t kChecksumHashSize = 32; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 DCHECK_GE(static_cast<int>(info->candidate_urls_.size()), 1); | 467 DCHECK_GE(static_cast<int>(info->candidate_urls_.size()), 1); |
| 467 | 468 |
| 468 if (!info->source_url_.url_lookup_success) { | 469 if (!info->source_url_.url_lookup_success) { |
| 469 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED); | 470 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED); |
| 470 return; | 471 return; |
| 471 } | 472 } |
| 472 | 473 |
| 473 LogCandidateURLStats(info->candidate_urls_[0].url); | 474 LogCandidateURLStats(info->candidate_urls_[0].url); |
| 474 | 475 |
| 475 WebContents* source_web_contents = NULL; | 476 WebContents* source_web_contents = NULL; |
| 477 bool multiple_source_web_contents_candidates = false; |
| 476 | 478 |
| 477 #if !defined(OS_ANDROID) | 479 #if !defined(OS_ANDROID) |
| 478 // We need to figure out what tab launched the prerender. We do this by | 480 // We need to figure out what tab launched the prerender. We do this by |
| 479 // comparing URLs. This may not always work: the URL may occur in two | 481 // comparing URLs. This may not always work: the URL may occur in two |
| 480 // tabs, and we pick the wrong one, or the tab we should have picked | 482 // tabs, and we pick the wrong one, or the tab we should have picked |
| 481 // may have navigated elsewhere. Hopefully, this doesn't happen too often, | 483 // may have navigated elsewhere. Hopefully, this doesn't happen too often, |
| 482 // so we ignore these cases for now. | 484 // so we ignore these cases for now. |
| 483 // TODO(tburkard): Reconsider this, potentially measure it, and fix this | 485 // TODO(tburkard): Reconsider this, potentially measure it, and fix this |
| 484 // in the future. | 486 // in the future. |
| 485 for (TabContentsIterator it; !it.done(); it.Next()) { | 487 for (TabContentsIterator it; !it.done(); it.Next()) { |
| 486 if (it->GetURL() == info->source_url_.url) { | 488 if (it->GetURL() == info->source_url_.url) { |
| 487 source_web_contents = *it; | 489 if (!source_web_contents) |
| 488 break; | 490 source_web_contents = *it; |
| 491 else |
| 492 multiple_source_web_contents_candidates = true; |
| 489 } | 493 } |
| 490 } | 494 } |
| 491 #endif | 495 #endif |
| 492 | 496 |
| 493 if (!source_web_contents) { | 497 if (!source_web_contents) { |
| 494 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND); | 498 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND); |
| 495 return; | 499 return; |
| 496 } | 500 } |
| 497 | 501 |
| 502 if (multiple_source_web_contents_candidates) |
| 503 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_MULTIPLE_SOURCE_WEBCONTENTS_FOUND); |
| 504 |
| 505 |
| 498 scoped_refptr<SessionStorageNamespace> session_storage_namespace = | 506 scoped_refptr<SessionStorageNamespace> session_storage_namespace = |
| 499 source_web_contents->GetController().GetDefaultSessionStorageNamespace(); | 507 source_web_contents->GetController().GetDefaultSessionStorageNamespace(); |
| 500 | 508 |
| 501 gfx::Rect container_bounds; | 509 gfx::Rect container_bounds; |
| 502 source_web_contents->GetView()->GetContainerBounds(&container_bounds); | 510 source_web_contents->GetView()->GetContainerBounds(&container_bounds); |
| 503 scoped_ptr<gfx::Size> size(new gfx::Size(container_bounds.size())); | 511 scoped_ptr<gfx::Size> size(new gfx::Size(container_bounds.size())); |
| 504 | 512 |
| 505 scoped_refptr<LoggedInPredictorTable> logged_in_table = | 513 scoped_refptr<LoggedInPredictorTable> logged_in_table = |
| 506 prerender_manager_->logged_in_predictor_table(); | 514 prerender_manager_->logged_in_predictor_table(); |
| 507 | 515 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 const GURL& url = info->url; | 732 const GURL& url = info->url; |
| 725 double priority = info->priority; | 733 double priority = info->priority; |
| 726 base::Time current_time = GetCurrentTime(); | 734 base::Time current_time = GetCurrentTime(); |
| 727 RecordEvent(EVENT_ISSUING_PRERENDER); | 735 RecordEvent(EVENT_ISSUING_PRERENDER); |
| 728 | 736 |
| 729 current_prerender_priority_ = priority; | 737 current_prerender_priority_ = priority; |
| 730 scoped_ptr<prerender::PrerenderHandle> old_prerender_handle( | 738 scoped_ptr<prerender::PrerenderHandle> old_prerender_handle( |
| 731 prerender_handle_.release()); | 739 prerender_handle_.release()); |
| 732 prerender_handle_.reset(prerender_manager_->AddPrerenderFromLocalPredictor( | 740 prerender_handle_.reset(prerender_manager_->AddPrerenderFromLocalPredictor( |
| 733 url, session_storage_namespace.get(), *size)); | 741 url, session_storage_namespace.get(), *size)); |
| 742 current_prerender_would_have_matched_ = false; |
| 734 if (old_prerender_handle) | 743 if (old_prerender_handle) |
| 735 old_prerender_handle->OnCancel(); | 744 old_prerender_handle->OnCancel(); |
| 736 | 745 |
| 737 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); | 746 RecordEvent(EVENT_ADD_VISIT_PRERENDERING); |
| 738 if (current_prerender_.get() && current_prerender_->url_id == url_id) { | 747 if (current_prerender_.get() && current_prerender_->url_id == url_id) { |
| 739 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); | 748 RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); |
| 740 if (priority > current_prerender_->priority) | 749 if (priority > current_prerender_->priority) |
| 741 current_prerender_->priority = priority; | 750 current_prerender_->priority = priority; |
| 742 // If the prerender already existed, we want to extend it. However, | 751 // If the prerender already existed, we want to extend it. However, |
| 743 // we do not want to set its start_time to the current time to | 752 // we do not want to set its start_time to the current time to |
| 744 // disadvantage PLT computations when the prerender is swapped in. | 753 // disadvantage PLT computations when the prerender is swapped in. |
| 745 // So we set the new start time to current_time - 10s (since the vast | 754 // So we set the new start time to current_time - 10s (since the vast |
| 746 // majority of PLTs are < 10s), provided that is not before the actual | 755 // majority of PLTs are < 10s), provided that is not before the actual |
| 747 // time the prerender was started (so as to not artificially advantage | 756 // time the prerender was started (so as to not artificially advantage |
| 748 // the PLT computation). | 757 // the PLT computation). |
| 749 base::Time simulated_new_start_time = | 758 base::Time simulated_new_start_time = |
| 750 current_time - base::TimeDelta::FromSeconds(10); | 759 current_time - base::TimeDelta::FromSeconds(10); |
| 751 if (simulated_new_start_time > current_prerender_->start_time) | 760 if (simulated_new_start_time > current_prerender_->start_time) |
| 752 current_prerender_->start_time = simulated_new_start_time; | 761 current_prerender_->start_time = simulated_new_start_time; |
| 753 } else { | 762 } else { |
| 754 current_prerender_.reset( | 763 current_prerender_.reset( |
| 755 new PrerenderProperties(url_id, url, priority, current_time)); | 764 new PrerenderProperties(url_id, url, priority, current_time)); |
| 756 } | 765 } |
| 757 current_prerender_->actual_start_time = current_time; | 766 current_prerender_->actual_start_time = current_time; |
| 758 } | 767 } |
| 759 | 768 |
| 769 void PrerenderLocalPredictor::OnTabHelperURLSeen( |
| 770 const GURL& url, WebContents* web_contents) { |
| 771 RecordEvent(EVENT_TAB_HELPER_URL_SEEN); |
| 772 if (current_prerender_would_have_matched_ || |
| 773 !prerender_handle_.get() || |
| 774 !prerender_handle_->Matches(url, NULL)) { |
| 775 return; |
| 776 } |
| 777 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH); |
| 778 if (prerender_handle_->Matches( |
| 779 url, |
| 780 web_contents->GetController().GetDefaultSessionStorageNamespace())) { |
| 781 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH); |
| 782 } |
| 783 // If the namespace matches and the URL matches, we might be able to swap |
| 784 // in. However, the actual code initating the swapin is in the renderer |
| 785 // and is checking for other criteria (such as POSTs). There may |
| 786 // also be conditions when a swapin should happen but does not. By recording |
| 787 // the two previous events, we can keep an eye on the magnitude of the |
| 788 // discrepancy. |
| 789 current_prerender_would_have_matched_ = true; |
| 790 } |
| 791 |
| 760 } // namespace prerender | 792 } // namespace prerender |
| OLD | NEW |