| Index: chrome/browser/net/predictor.cc
|
| diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
|
| index 0f7a3d159d9a702d32c5cd7c76df80220bb95aeb..c1dc2d127114969c75a96a62f468d019149115fe 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,16 @@ 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
|
| + // 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 +1156,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 +1172,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);
|
| }
|
|
|
| //-----------------------------------------------------------------------------
|
|
|