Chromium Code Reviews| 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/net/predictor.h" | 5 #include "chrome/browser/net/predictor.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <iterator> | 9 #include <iterator> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <sstream> | 11 #include <sstream> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/compiler_specific.h" | 16 #include "base/compiler_specific.h" |
| 17 #include "base/containers/mru_cache.h" | 17 #include "base/containers/mru_cache.h" |
| 18 #include "base/feature_list.h" | 18 #include "base/feature_list.h" |
| 19 #include "base/location.h" | 19 #include "base/location.h" |
| 20 #include "base/logging.h" | 20 #include "base/logging.h" |
| 21 #include "base/macros.h" | 21 #include "base/macros.h" |
| 22 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" |
| 23 #include "base/metrics/histogram_macros.h" | 23 #include "base/metrics/histogram_macros.h" |
| 24 #include "base/single_thread_task_runner.h" | 24 #include "base/single_thread_task_runner.h" |
| 25 #include "base/stl_util.h" | 25 #include "base/stl_util.h" |
| 26 #include "base/strings/stringprintf.h" | 26 #include "base/strings/stringprintf.h" |
| 27 #include "base/threading/thread_restrictions.h" | 27 #include "base/threading/thread_restrictions.h" |
| 28 #include "base/threading/thread_task_runner_handle.h" | 28 #include "base/threading/thread_task_runner_handle.h" |
| 29 #include "base/time/time.h" | 29 #include "base/time/time.h" |
| 30 #include "base/trace_event/trace_event.h" | |
|
Charlie Harrison
2017/06/20 13:24:29
Is it used?
Benoit L
2017/06/20 13:30:17
Yes, there is a TRACE_EVENT0() added below.
Charlie Harrison
2017/06/20 13:32:22
Ahh sorry. It's early :)
| |
| 30 #include "base/values.h" | 31 #include "base/values.h" |
| 32 #include "build/build_config.h" | |
| 31 #include "chrome/browser/io_thread.h" | 33 #include "chrome/browser/io_thread.h" |
| 32 #include "chrome/browser/prefs/session_startup_pref.h" | 34 #include "chrome/browser/prefs/session_startup_pref.h" |
| 33 #include "chrome/browser/profiles/profile_io_data.h" | 35 #include "chrome/browser/profiles/profile_io_data.h" |
| 34 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 35 #include "chrome/common/pref_names.h" | 37 #include "chrome/common/pref_names.h" |
| 36 #include "components/pref_registry/pref_registry_syncable.h" | 38 #include "components/pref_registry/pref_registry_syncable.h" |
| 37 #include "components/prefs/pref_service.h" | 39 #include "components/prefs/pref_service.h" |
| 38 #include "components/prefs/scoped_user_pref_update.h" | 40 #include "components/prefs/scoped_user_pref_update.h" |
| 39 #include "content/public/browser/browser_thread.h" | 41 #include "content/public/browser/browser_thread.h" |
| 40 #include "content/public/browser/resource_hints.h" | 42 #include "content/public/browser/resource_hints.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 53 using base::TimeDelta; | 55 using base::TimeDelta; |
| 54 using content::BrowserThread; | 56 using content::BrowserThread; |
| 55 | 57 |
| 56 namespace chrome_browser_net { | 58 namespace chrome_browser_net { |
| 57 | 59 |
| 58 namespace { | 60 namespace { |
| 59 | 61 |
| 60 const base::Feature kNetworkPrediction{"NetworkPrediction", | 62 const base::Feature kNetworkPrediction{"NetworkPrediction", |
| 61 base::FEATURE_ENABLED_BY_DEFAULT}; | 63 base::FEATURE_ENABLED_BY_DEFAULT}; |
| 62 | 64 |
| 65 #if defined(OS_ANDROID) | |
| 66 // Disabled on Android, as there are no "pinned tabs", meaning that a startup | |
| 67 // is unlikely to request the same URL, and hence to resolve the same domains | |
| 68 // as the previous one. | |
| 69 constexpr bool kInitialDnsPrefetchListEnabled = false; | |
| 70 #else | |
| 71 constexpr bool kInitialDnsPrefetchListEnabled = true; | |
| 72 #endif // defined(OS_ANDROID) | |
| 73 | |
| 63 } // namespace | 74 } // namespace |
| 64 | 75 |
| 65 // static | 76 // static |
| 66 const int Predictor::kPredictorReferrerVersion = 2; | 77 const int Predictor::kPredictorReferrerVersion = 2; |
| 67 const double Predictor::kPreconnectWorthyExpectedValue = 0.8; | 78 const double Predictor::kPreconnectWorthyExpectedValue = 0.8; |
| 68 const double Predictor::kDNSPreresolutionWorthyExpectedValue = 0.1; | 79 const double Predictor::kDNSPreresolutionWorthyExpectedValue = 0.1; |
| 69 const double Predictor::kDiscardableExpectedValue = 0.05; | 80 const double Predictor::kDiscardableExpectedValue = 0.05; |
| 70 const size_t Predictor::kMaxSpeculativeParallelResolves = 3; | 81 const size_t Predictor::kMaxSpeculativeParallelResolves = 3; |
| 71 const int Predictor::kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10; | 82 const int Predictor::kMaxUnusedSocketLifetimeSecondsWithoutAGet = 10; |
| 72 | 83 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 static_cast<int>(future_url->second.preresolution_count()), | 510 static_cast<int>(future_url->second.preresolution_count()), |
| 500 static_cast<double>(future_url->second.subresource_use_rate()), | 511 static_cast<double>(future_url->second.subresource_use_rate()), |
| 501 future_url->first.spec().c_str()); | 512 future_url->first.spec().c_str()); |
| 502 } | 513 } |
| 503 } | 514 } |
| 504 output->append("</table>"); | 515 output->append("</table>"); |
| 505 } | 516 } |
| 506 | 517 |
| 507 void Predictor::GetHtmlInfo(std::string* output) { | 518 void Predictor::GetHtmlInfo(std::string* output) { |
| 508 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 519 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 509 if (initial_observer_.get()) | 520 if (initial_observer_) |
| 510 initial_observer_->GetFirstResolutionsHtml(output); | 521 initial_observer_->GetFirstResolutionsHtml(output); |
| 511 // Show list of subresource predictions and stats. | 522 // Show list of subresource predictions and stats. |
| 512 GetHtmlReferrerLists(output); | 523 GetHtmlReferrerLists(output); |
| 513 | 524 |
| 514 // Local lists for calling UrlInfo | 525 // Local lists for calling UrlInfo |
| 515 UrlInfo::UrlInfoTable name_not_found; | 526 UrlInfo::UrlInfoTable name_not_found; |
| 516 UrlInfo::UrlInfoTable name_preresolved; | 527 UrlInfo::UrlInfoTable name_preresolved; |
| 517 | 528 |
| 518 // UrlInfo supports value semantics, so we can do a shallow copy. | 529 // UrlInfo supports value semantics, so we can do a shallow copy. |
| 519 for (Results::iterator it(results_.begin()); it != results_.end(); it++) { | 530 for (Results::iterator it(results_.begin()); it != results_.end(); it++) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 } | 591 } |
| 581 | 592 |
| 582 referrers_.Put(GURL(motivating_url_spec), Referrer()) | 593 referrers_.Put(GURL(motivating_url_spec), Referrer()) |
| 583 ->second.Deserialize(*subresource_list); | 594 ->second.Deserialize(*subresource_list); |
| 584 } | 595 } |
| 585 } | 596 } |
| 586 } | 597 } |
| 587 | 598 |
| 588 void Predictor::DiscardInitialNavigationHistory() { | 599 void Predictor::DiscardInitialNavigationHistory() { |
| 589 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 600 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 590 if (initial_observer_.get()) | 601 if (initial_observer_) |
| 591 initial_observer_->DiscardInitialNavigationHistory(); | 602 initial_observer_->DiscardInitialNavigationHistory(); |
| 592 } | 603 } |
| 593 | 604 |
| 594 void Predictor::FinalizeInitializationOnIOThread( | 605 void Predictor::FinalizeInitializationOnIOThread( |
| 595 const std::vector<GURL>& startup_urls, | 606 const std::vector<GURL>& startup_urls, |
| 596 std::unique_ptr<base::ListValue> referral_list, | 607 std::unique_ptr<base::ListValue> referral_list, |
| 597 IOThread* io_thread, | 608 IOThread* io_thread, |
| 598 ProfileIOData* profile_io_data) { | 609 ProfileIOData* profile_io_data) { |
| 599 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 610 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 611 TRACE_EVENT0("net", "Predictor::FinalizeInitializationOnIOThread"); | |
| 600 | 612 |
| 601 profile_io_data_ = profile_io_data; | 613 profile_io_data_ = profile_io_data; |
| 602 initial_observer_.reset(new InitialObserver()); | 614 if (kInitialDnsPrefetchListEnabled) |
| 615 initial_observer_ = base::MakeUnique<InitialObserver>(); | |
| 603 | 616 |
| 604 net::URLRequestContext* context = | 617 net::URLRequestContext* context = |
| 605 url_request_context_getter_->GetURLRequestContext(); | 618 url_request_context_getter_->GetURLRequestContext(); |
| 606 transport_security_state_ = context->transport_security_state(); | 619 transport_security_state_ = context->transport_security_state(); |
| 607 ssl_config_service_ = context->ssl_config_service(); | 620 ssl_config_service_ = context->ssl_config_service(); |
| 608 proxy_service_ = context->proxy_service(); | 621 proxy_service_ = context->proxy_service(); |
| 609 | 622 |
| 610 // base::WeakPtrFactory instances need to be created and destroyed | 623 // base::WeakPtrFactory instances need to be created and destroyed |
| 611 // on the same thread. Initialize the IO thread weak factory now. | 624 // on the same thread. Initialize the IO thread weak factory now. |
| 612 io_weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); | 625 io_weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| 613 | 626 |
| 614 // Prefetch these hostnames on startup. | 627 // Prefetch these hostnames on startup. |
| 615 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); | 628 if (kInitialDnsPrefetchListEnabled) |
| 629 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); | |
| 616 | 630 |
| 617 DeserializeReferrers(*referral_list); | 631 DeserializeReferrers(*referral_list); |
| 618 | 632 |
| 619 LogStartupMetrics(); | 633 LogStartupMetrics(); |
| 620 } | 634 } |
| 621 | 635 |
| 622 //----------------------------------------------------------------------------- | 636 //----------------------------------------------------------------------------- |
| 623 // This section intermingles prefetch results with actual browser HTTP | 637 // This section intermingles prefetch results with actual browser HTTP |
| 624 // network activity. It supports calculating of the benefit of a prefetch, as | 638 // network activity. It supports calculating of the benefit of a prefetch, as |
| 625 // well as recording what prefetched hostname resolutions might be potentially | 639 // well as recording what prefetched hostname resolutions might be potentially |
| 626 // helpful during the next chrome-startup. | 640 // helpful during the next chrome-startup. |
| 627 //----------------------------------------------------------------------------- | 641 //----------------------------------------------------------------------------- |
| 628 | 642 |
| 629 void Predictor::LearnAboutInitialNavigation(const GURL& url) { | 643 void Predictor::LearnAboutInitialNavigation(const GURL& url) { |
| 630 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 644 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 631 if (!PredictorEnabled() || nullptr == initial_observer_.get() || | 645 if (!PredictorEnabled() || !kInitialDnsPrefetchListEnabled || |
| 632 !CanPreresolveAndPreconnect()) { | 646 !initial_observer_ || !CanPreresolveAndPreconnect()) { |
| 633 return; | 647 return; |
| 634 } | 648 } |
| 635 initial_observer_->Append(url, this); | 649 initial_observer_->Append(url, this); |
| 636 } | 650 } |
| 637 | 651 |
| 638 // This API is only used in the browser process. | 652 // This API is only used in the browser process. |
| 639 // It is called from an IPC message originating in the renderer. It currently | 653 // It is called from an IPC message originating in the renderer. It currently |
| 640 // includes both Page-Scan, and Link-Hover prefetching. | 654 // includes both Page-Scan, and Link-Hover prefetching. |
| 641 // TODO(jar): Separate out link-hover prefetching, and page-scan results. | 655 // TODO(jar): Separate out link-hover prefetching, and page-scan results. |
| 642 void Predictor::DnsPrefetchList(const std::vector<std::string>& hostnames) { | 656 void Predictor::DnsPrefetchList(const std::vector<std::string>& hostnames) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 // Functions to handle saving of hostnames from one session to the next, to | 690 // Functions to handle saving of hostnames from one session to the next, to |
| 677 // expedite startup times. | 691 // expedite startup times. |
| 678 | 692 |
| 679 void Predictor::SaveStateForNextStartup() { | 693 void Predictor::SaveStateForNextStartup() { |
| 680 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 694 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 681 if (!PredictorEnabled()) | 695 if (!PredictorEnabled()) |
| 682 return; | 696 return; |
| 683 if (!CanPreresolveAndPreconnect()) | 697 if (!CanPreresolveAndPreconnect()) |
| 684 return; | 698 return; |
| 685 | 699 |
| 686 std::unique_ptr<base::ListValue> startup_list(new base::ListValue); | 700 auto startup_list = base::MakeUnique<base::ListValue>(); |
| 687 std::unique_ptr<base::ListValue> referral_list(new base::ListValue); | 701 auto referral_list = base::MakeUnique<base::ListValue>(); |
| 688 | 702 |
| 689 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs | 703 // Get raw pointers to pass to the first task. Ownership of the unique_ptrs |
| 690 // will be passed to the reply task. | 704 // will be passed to the reply task. |
| 691 base::ListValue* startup_list_raw = startup_list.get(); | 705 base::ListValue* startup_list_raw = startup_list.get(); |
| 692 base::ListValue* referral_list_raw = referral_list.get(); | 706 base::ListValue* referral_list_raw = referral_list.get(); |
| 693 | 707 |
| 694 // The first post task here is guaranteed to execute before the post task in | 708 // The first post task here is guaranteed to execute before the post task in |
| 695 // ShutdownOnUIThread, because the caller has a valid profile. | 709 // ShutdownOnUIThread, because the caller has a valid profile. |
| 696 BrowserThread::PostTaskAndReply( | 710 BrowserThread::PostTaskAndReply( |
| 697 BrowserThread::IO, FROM_HERE, | 711 BrowserThread::IO, FROM_HERE, |
| 698 base::BindOnce(&Predictor::WriteDnsPrefetchState, base::Unretained(this), | 712 base::BindOnce(&Predictor::WriteDnsPrefetchState, base::Unretained(this), |
| 699 startup_list_raw, referral_list_raw), | 713 startup_list_raw, referral_list_raw), |
| 700 base::BindOnce(&Predictor::UpdatePrefsOnUIThread, | 714 base::BindOnce(&Predictor::UpdatePrefsOnUIThread, |
| 701 ui_weak_factory_->GetWeakPtr(), | 715 ui_weak_factory_->GetWeakPtr(), |
| 702 base::Passed(std::move(startup_list)), | 716 base::Passed(std::move(startup_list)), |
| 703 base::Passed(std::move(referral_list)))); | 717 base::Passed(std::move(referral_list)))); |
| 704 } | 718 } |
| 705 | 719 |
| 706 void Predictor::UpdatePrefsOnUIThread( | 720 void Predictor::UpdatePrefsOnUIThread( |
| 707 std::unique_ptr<base::ListValue> startup_list, | 721 std::unique_ptr<base::ListValue> startup_list, |
| 708 std::unique_ptr<base::ListValue> referral_list) { | 722 std::unique_ptr<base::ListValue> referral_list) { |
| 709 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 723 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 710 user_prefs_->Set(prefs::kDnsPrefetchingStartupList, *startup_list); | 724 user_prefs_->Set(prefs::kDnsPrefetchingStartupList, *startup_list); |
| 725 // May be empty if kInitialDnsPrefetchListEnabled is false. Still update the | |
| 726 // prefs to clear the state. | |
| 711 user_prefs_->Set(prefs::kDnsPrefetchingHostReferralList, *referral_list); | 727 user_prefs_->Set(prefs::kDnsPrefetchingHostReferralList, *referral_list); |
| 712 } | 728 } |
| 713 | 729 |
| 714 void Predictor::WriteDnsPrefetchState(base::ListValue* startup_list, | 730 void Predictor::WriteDnsPrefetchState(base::ListValue* startup_list, |
| 715 base::ListValue* referral_list) { | 731 base::ListValue* referral_list) { |
| 716 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 732 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 717 if (initial_observer_.get()) | 733 if (initial_observer_) |
| 718 initial_observer_->GetInitialDnsResolutionList(startup_list); | 734 initial_observer_->GetInitialDnsResolutionList(startup_list); |
| 719 | 735 |
| 720 SerializeReferrers(referral_list); | 736 SerializeReferrers(referral_list); |
| 721 } | 737 } |
| 722 | 738 |
| 723 void Predictor::PreconnectUrl(const GURL& url, | 739 void Predictor::PreconnectUrl(const GURL& url, |
| 724 const GURL& first_party_for_cookies, | 740 const GURL& first_party_for_cookies, |
| 725 UrlInfo::ResolutionMotivation motivation, | 741 UrlInfo::ResolutionMotivation motivation, |
| 726 bool allow_credentials, | 742 bool allow_credentials, |
| 727 int count) { | 743 int count) { |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1197 } | 1213 } |
| 1198 | 1214 |
| 1199 void SimplePredictor::ShutdownOnUIThread() { | 1215 void SimplePredictor::ShutdownOnUIThread() { |
| 1200 SetShutdown(true); | 1216 SetShutdown(true); |
| 1201 } | 1217 } |
| 1202 | 1218 |
| 1203 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } | 1219 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
| 1204 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } | 1220 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
| 1205 | 1221 |
| 1206 } // namespace chrome_browser_net | 1222 } // namespace chrome_browser_net |
| OLD | NEW |