Chromium Code Reviews| Index: chrome/browser/net/predictor.cc |
| diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc |
| index 0f7a3d159d9a702d32c5cd7c76df80220bb95aeb..d0901d8cbf40b4d51bc557b0755897f89ff04c98 100644 |
| --- a/chrome/browser/net/predictor.cc |
| +++ b/chrome/browser/net/predictor.cc |
| @@ -27,7 +27,9 @@ |
| #include "base/threading/thread_restrictions.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/time/time.h" |
| +#include "base/trace_event/trace_event.h" |
| #include "base/values.h" |
| +#include "build/build_config.h" |
| #include "chrome/browser/io_thread.h" |
| #include "chrome/browser/prefs/session_startup_pref.h" |
| #include "chrome/browser/profiles/profile_io_data.h" |
| @@ -60,8 +62,49 @@ namespace { |
| const base::Feature kNetworkPrediction{"NetworkPrediction", |
| base::FEATURE_ENABLED_BY_DEFAULT}; |
| +#if defined(OS_ANDROID) |
| +// Disabled on Android, as there are no "pinned tabs", meaning that a startup |
| +// is unlikely to request the same URL, and hence to resolve the same domains |
| +// as the previous one. |
| +constexpr bool kInitialDnsPrefetchListEnabled = false; |
| +#else |
| +constexpr bool kInitialDnsPrefetchListEnabled = true; |
| +#endif // defined(OS_ANDROID) |
| + |
| } // namespace |
| +// The InitialObserver monitors navigations made by the network stack. This |
| +// is only used to identify startup time resolutions (for re-resolution |
| +// during our next process startup). |
| +// TODO(jar): Consider preconnecting at startup, which may be faster than |
| +// waiting for render process to start and request a connection. |
| +class InitialObserver { |
| + public: |
| + InitialObserver(); |
| + ~InitialObserver(); |
| + // Recording of when we observed each navigation. |
| + typedef std::map<GURL, base::TimeTicks> FirstNavigations; |
| + |
| + // Potentially add a new URL to our startup list. |
| + void Append(const GURL& url, Predictor* predictor); |
| + |
| + // Get an HTML version of our current planned first_navigations_. |
| + void GetFirstResolutionsHtml(std::string* output); |
| + |
| + // Persist the current first_navigations_ for storage in a list. |
| + void GetInitialDnsResolutionList(base::ListValue* startup_list); |
| + |
| + // Discards all initial loading history. |
| + void DiscardInitialNavigationHistory() { first_navigations_.clear(); } |
| + |
| + private: |
| + // List of the first N URL resolutions observed in this run. |
| + FirstNavigations first_navigations_; |
| + |
| + // The number of URLs we'll save for pre-resolving at next startup. |
| + static const size_t kStartupResolutionCount = 10; |
| +}; |
| + |
| // static |
| const int Predictor::kPredictorReferrerVersion = 2; |
| const double Predictor::kPreconnectWorthyExpectedValue = 0.8; |
| @@ -506,7 +549,7 @@ void Predictor::GetHtmlReferrerLists(std::string* output) { |
| void Predictor::GetHtmlInfo(std::string* output) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (initial_observer_.get()) |
| + if (kInitialDnsPrefetchListEnabled && initial_observer_) |
| initial_observer_->GetFirstResolutionsHtml(output); |
| // Show list of subresource predictions and stats. |
| GetHtmlReferrerLists(output); |
| @@ -587,7 +630,7 @@ void Predictor::DeserializeReferrers(const base::ListValue& referral_list) { |
| void Predictor::DiscardInitialNavigationHistory() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (initial_observer_.get()) |
| + if (kInitialDnsPrefetchListEnabled && initial_observer_) |
| initial_observer_->DiscardInitialNavigationHistory(); |
| } |
| @@ -597,9 +640,11 @@ void Predictor::FinalizeInitializationOnIOThread( |
| IOThread* io_thread, |
| ProfileIOData* profile_io_data) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + TRACE_EVENT0("net", "Predictor::FinalizeInitializationOnIOThread"); |
| profile_io_data_ = profile_io_data; |
| - initial_observer_.reset(new InitialObserver()); |
| + if (kInitialDnsPrefetchListEnabled) |
| + initial_observer_ = base::MakeUnique<InitialObserver>(); |
| net::URLRequestContext* context = |
| url_request_context_getter_->GetURLRequestContext(); |
| @@ -612,7 +657,8 @@ void Predictor::FinalizeInitializationOnIOThread( |
| io_weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| // Prefetch these hostnames on startup. |
| - DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| + if (kInitialDnsPrefetchListEnabled) |
| + DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| DeserializeReferrers(*referral_list); |
| @@ -628,8 +674,8 @@ void Predictor::FinalizeInitializationOnIOThread( |
| void Predictor::LearnAboutInitialNavigation(const GURL& url) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (!PredictorEnabled() || nullptr == initial_observer_.get() || |
| - !CanPreresolveAndPreconnect()) { |
| + if (!PredictorEnabled() || !kInitialDnsPrefetchListEnabled || |
| + !initial_observer_ || !CanPreresolveAndPreconnect()) { |
| return; |
| } |
| initial_observer_->Append(url, this); |
| @@ -683,8 +729,8 @@ void Predictor::SaveStateForNextStartup() { |
| if (!CanPreresolveAndPreconnect()) |
| return; |
| - std::unique_ptr<base::ListValue> startup_list(new base::ListValue); |
| - std::unique_ptr<base::ListValue> referral_list(new base::ListValue); |
| + auto startup_list = base::MakeUnique<base::ListValue>(); |
| + auto referral_list = base::MakeUnique<base::ListValue>(); |
| // Get raw pointers to pass to the first task. Ownership of the unique_ptrs |
| // will be passed to the reply task. |
| @@ -708,13 +754,15 @@ void Predictor::UpdatePrefsOnUIThread( |
| std::unique_ptr<base::ListValue> referral_list) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| user_prefs_->Set(prefs::kDnsPrefetchingStartupList, *startup_list); |
| + // May be empty if kInitialDnsPrefetchListEnabled is false. Still update the |
|
jkarlin
2017/06/26 16:47:56
New line above this
Benoit L
2017/06/27 08:37:56
Done.
|
| + // prefs to clear the state. |
| user_prefs_->Set(prefs::kDnsPrefetchingHostReferralList, *referral_list); |
| } |
| void Predictor::WriteDnsPrefetchState(base::ListValue* startup_list, |
| base::ListValue* referral_list) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (initial_observer_.get()) |
| + if (kInitialDnsPrefetchListEnabled && initial_observer_) |
| initial_observer_->GetInitialDnsResolutionList(startup_list); |
| SerializeReferrers(referral_list); |
| @@ -1107,14 +1155,11 @@ GURL Predictor::HostNameQueue::Pop() { |
| //----------------------------------------------------------------------------- |
| // Member definitions for InitialObserver class. |
| -Predictor::InitialObserver::InitialObserver() { |
| -} |
| +InitialObserver::InitialObserver() = default; |
| -Predictor::InitialObserver::~InitialObserver() { |
| -} |
| +InitialObserver::~InitialObserver() = default; |
| -void Predictor::InitialObserver::Append(const GURL& url, |
| - Predictor* predictor) { |
| +void InitialObserver::Append(const GURL& url, Predictor* predictor) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (kStartupResolutionCount <= first_navigations_.size()) |
| @@ -1126,38 +1171,32 @@ void Predictor::InitialObserver::Append(const GURL& url, |
| first_navigations_[url] = base::TimeTicks::Now(); |
| } |
| -void Predictor::InitialObserver::GetInitialDnsResolutionList( |
| +void InitialObserver::GetInitialDnsResolutionList( |
| base::ListValue* startup_list) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(startup_list); |
| DCHECK(startup_list->empty()); |
| DCHECK_EQ(0u, startup_list->GetSize()); |
| startup_list->AppendInteger(kPredictorStartupFormatVersion); |
| - for (FirstNavigations::iterator it = first_navigations_.begin(); |
| - it != first_navigations_.end(); |
| - ++it) { |
| - DCHECK(it->first == Predictor::CanonicalizeUrl(it->first)); |
| - startup_list->AppendString(it->first.spec()); |
| + for (const auto& url_time : first_navigations_) { |
| + DCHECK(url_time.first == Predictor::CanonicalizeUrl(url_time.first)); |
| + startup_list->AppendString(url_time.first.spec()); |
| } |
| } |
| -void Predictor::InitialObserver::GetFirstResolutionsHtml( |
| - std::string* output) { |
| +void InitialObserver::GetFirstResolutionsHtml(std::string* output) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| UrlInfo::UrlInfoTable resolution_list; |
| - { |
| - for (FirstNavigations::iterator it(first_navigations_.begin()); |
| - it != first_navigations_.end(); |
| - it++) { |
| - UrlInfo info; |
| - info.SetUrl(it->first); |
| - info.set_time(it->second); |
| - resolution_list.push_back(info); |
| - } |
| + for (const auto& url_time : first_navigations_) { |
| + UrlInfo info; |
| + info.SetUrl(url_time.first); |
| + info.set_time(url_time.second); |
| + resolution_list.push_back(info); |
| } |
| UrlInfo::GetHtmlTable(resolution_list, |
| - "Future startups will prefetch DNS records for ", false, output); |
| + "Future startups will prefetch DNS records for ", false, |
| + output); |
| } |
| //----------------------------------------------------------------------------- |