| 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 <set> | 9 #include <set> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 if (!CanPreresolveAndPreconnect()) | 234 if (!CanPreresolveAndPreconnect()) |
| 235 return; | 235 return; |
| 236 | 236 |
| 237 std::string host = url.HostNoBrackets(); | 237 std::string host = url.HostNoBrackets(); |
| 238 bool is_new_host_request = (host != last_omnibox_host_); | 238 bool is_new_host_request = (host != last_omnibox_host_); |
| 239 last_omnibox_host_ = host; | 239 last_omnibox_host_ = host; |
| 240 | 240 |
| 241 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); | 241 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); |
| 242 base::TimeTicks now = base::TimeTicks::Now(); | 242 base::TimeTicks now = base::TimeTicks::Now(); |
| 243 | 243 |
| 244 if (preconnect_enabled_) { | 244 if (PreconnectEnabled()) { |
| 245 if (preconnectable && !is_new_host_request) { | 245 if (preconnectable && !is_new_host_request) { |
| 246 ++consecutive_omnibox_preconnect_count_; | 246 ++consecutive_omnibox_preconnect_count_; |
| 247 // The omnibox suggests a search URL (for which we can preconnect) after | 247 // The omnibox suggests a search URL (for which we can preconnect) after |
| 248 // one or two characters are typed, even though such typing often (1 in | 248 // one or two characters are typed, even though such typing often (1 in |
| 249 // 3?) becomes a real URL. This code waits till is has more evidence of a | 249 // 3?) becomes a real URL. This code waits till is has more evidence of a |
| 250 // preconnectable URL (search URL) before forming a preconnection, so as | 250 // preconnectable URL (search URL) before forming a preconnection, so as |
| 251 // to reduce the useless preconnect rate. | 251 // to reduce the useless preconnect rate. |
| 252 // Perchance this logic should be pushed back into the omnibox, where the | 252 // Perchance this logic should be pushed back into the omnibox, where the |
| 253 // actual characters typed, such as a space, can better forcast whether | 253 // actual characters typed, such as a space, can better forcast whether |
| 254 // we need to search/preconnect or not. By waiting for at least 4 | 254 // we need to search/preconnect or not. By waiting for at least 4 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 BrowserThread::IO, | 298 BrowserThread::IO, |
| 299 FROM_HERE, | 299 FROM_HERE, |
| 300 base::Bind(&Predictor::Resolve, base::Unretained(this), | 300 base::Bind(&Predictor::Resolve, base::Unretained(this), |
| 301 CanonicalizeUrl(url), motivation)); | 301 CanonicalizeUrl(url), motivation)); |
| 302 } | 302 } |
| 303 | 303 |
| 304 void Predictor::PreconnectUrlAndSubresources(const GURL& url, | 304 void Predictor::PreconnectUrlAndSubresources(const GURL& url, |
| 305 const GURL& first_party_for_cookies) { | 305 const GURL& first_party_for_cookies) { |
| 306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 307 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 307 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 308 if (!predictor_enabled_ || !preconnect_enabled_ || | 308 if (!predictor_enabled_ || !PreconnectEnabled() || !url.is_valid() || |
| 309 !url.is_valid() || !url.has_host()) | 309 !url.has_host()) |
| 310 return; | 310 return; |
| 311 if (!CanPreresolveAndPreconnect()) | 311 if (!CanPreresolveAndPreconnect()) |
| 312 return; | 312 return; |
| 313 | 313 |
| 314 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); | 314 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); |
| 315 const int kConnectionsNeeded = 1; | 315 const int kConnectionsNeeded = 1; |
| 316 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, motivation, | 316 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, motivation, |
| 317 kConnectionsNeeded, kAllowCredentialsOnPreconnectByDefault); | 317 kConnectionsNeeded, kAllowCredentialsOnPreconnectByDefault); |
| 318 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); | 318 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); |
| 319 } | 319 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 void Predictor::LearnFromNavigation(const GURL& referring_url, | 465 void Predictor::LearnFromNavigation(const GURL& referring_url, |
| 466 const GURL& target_url) { | 466 const GURL& target_url) { |
| 467 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 467 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 468 if (!predictor_enabled_ || !CanPreresolveAndPreconnect()) | 468 if (!predictor_enabled_ || !CanPreresolveAndPreconnect()) |
| 469 return; | 469 return; |
| 470 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); | 470 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); |
| 471 DCHECK_NE(referring_url, GURL::EmptyGURL()); | 471 DCHECK_NE(referring_url, GURL::EmptyGURL()); |
| 472 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); | 472 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); |
| 473 DCHECK_NE(target_url, GURL::EmptyGURL()); | 473 DCHECK_NE(target_url, GURL::EmptyGURL()); |
| 474 | 474 |
| 475 if (observer_) |
| 476 observer_->OnLearnFromNavigation(referring_url, target_url); |
| 475 referrers_[referring_url].SuggestHost(target_url); | 477 referrers_[referring_url].SuggestHost(target_url); |
| 476 // Possibly do some referrer trimming. | 478 // Possibly do some referrer trimming. |
| 477 TrimReferrers(); | 479 TrimReferrers(); |
| 478 } | 480 } |
| 479 | 481 |
| 480 //----------------------------------------------------------------------------- | 482 //----------------------------------------------------------------------------- |
| 481 // This section supports the about:dns page. | 483 // This section supports the about:dns page. |
| 482 | 484 |
| 483 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, | 485 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, |
| 484 std::string* output) { | 486 std::string* output) { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 973 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 972 DCHECK_EQ(url.GetWithEmptyPath(), url); | 974 DCHECK_EQ(url.GetWithEmptyPath(), url); |
| 973 Referrers::iterator it = referrers_.find(url); | 975 Referrers::iterator it = referrers_.find(url); |
| 974 if (referrers_.end() == it) { | 976 if (referrers_.end() == it) { |
| 975 // Only when we don't know anything about this url, make 2 connections | 977 // Only when we don't know anything about this url, make 2 connections |
| 976 // available. We could do this completely via learning (by prepopulating | 978 // available. We could do this completely via learning (by prepopulating |
| 977 // the referrer_ list with this expected value), but it would swell the | 979 // the referrer_ list with this expected value), but it would swell the |
| 978 // size of the list with all the "Leaf" nodes in the tree (nodes that don't | 980 // size of the list with all the "Leaf" nodes in the tree (nodes that don't |
| 979 // load any subresources). If we learn about this resource, we will instead | 981 // load any subresources). If we learn about this resource, we will instead |
| 980 // provide a more carefully estimated preconnection count. | 982 // provide a more carefully estimated preconnection count. |
| 981 if (preconnect_enabled_) { | 983 if (PreconnectEnabled()) { |
| 982 PreconnectUrlOnIOThread(url, first_party_for_cookies, | 984 PreconnectUrlOnIOThread(url, first_party_for_cookies, |
| 983 UrlInfo::SELF_REFERAL_MOTIVATED, | 985 UrlInfo::SELF_REFERAL_MOTIVATED, |
| 984 kAllowCredentialsOnPreconnectByDefault, 2); | 986 kAllowCredentialsOnPreconnectByDefault, 2); |
| 985 } | 987 } |
| 986 return; | 988 return; |
| 987 } | 989 } |
| 988 | 990 |
| 989 Referrer* referrer = &(it->second); | 991 Referrer* referrer = &(it->second); |
| 990 referrer->IncrementUseCount(); | 992 referrer->IncrementUseCount(); |
| 991 const UrlInfo::ResolutionMotivation motivation = | 993 const UrlInfo::ResolutionMotivation motivation = |
| 992 UrlInfo::LEARNED_REFERAL_MOTIVATED; | 994 UrlInfo::LEARNED_REFERAL_MOTIVATED; |
| 993 for (Referrer::iterator future_url = referrer->begin(); | 995 for (Referrer::iterator future_url = referrer->begin(); |
| 994 future_url != referrer->end(); ++future_url) { | 996 future_url != referrer->end(); ++future_url) { |
| 995 SubresourceValue evalution(TOO_NEW); | 997 SubresourceValue evalution(TOO_NEW); |
| 996 double connection_expectation = future_url->second.subresource_use_rate(); | 998 double connection_expectation = future_url->second.subresource_use_rate(); |
| 997 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", | 999 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", |
| 998 static_cast<int>(connection_expectation * 100), | 1000 static_cast<int>(connection_expectation * 100), |
| 999 10, 5000, 50); | 1001 10, 5000, 50); |
| 1000 future_url->second.ReferrerWasObserved(); | 1002 future_url->second.ReferrerWasObserved(); |
| 1001 if (preconnect_enabled_ && | 1003 if (PreconnectEnabled() && |
| 1002 connection_expectation > kPreconnectWorthyExpectedValue) { | 1004 connection_expectation > kPreconnectWorthyExpectedValue) { |
| 1003 evalution = PRECONNECTION; | 1005 evalution = PRECONNECTION; |
| 1004 future_url->second.IncrementPreconnectionCount(); | 1006 future_url->second.IncrementPreconnectionCount(); |
| 1005 int count = static_cast<int>(std::ceil(connection_expectation)); | 1007 int count = static_cast<int>(std::ceil(connection_expectation)); |
| 1006 if (url.host_piece() == future_url->first.host_piece()) | 1008 if (url.host_piece() == future_url->first.host_piece()) |
| 1007 ++count; | 1009 ++count; |
| 1008 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, | 1010 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, |
| 1009 motivation, | 1011 motivation, |
| 1010 kAllowCredentialsOnPreconnectByDefault, count); | 1012 kAllowCredentialsOnPreconnectByDefault, count); |
| 1011 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { | 1013 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 url::Replacements<char> replacements; | 1211 url::Replacements<char> replacements; |
| 1210 const char kNewScheme[] = "https"; | 1212 const char kNewScheme[] = "https"; |
| 1211 replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme))); | 1213 replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme))); |
| 1212 return url.ReplaceComponents(replacements); | 1214 return url.ReplaceComponents(replacements); |
| 1213 } | 1215 } |
| 1214 | 1216 |
| 1215 // ---------------------- End IO methods. ------------------------------------- | 1217 // ---------------------- End IO methods. ------------------------------------- |
| 1216 | 1218 |
| 1217 //----------------------------------------------------------------------------- | 1219 //----------------------------------------------------------------------------- |
| 1218 | 1220 |
| 1221 bool Predictor::PreconnectEnabled() const { |
| 1222 base::AutoLock lock(preconnect_enabled_lock_); |
| 1223 return preconnect_enabled_; |
| 1224 } |
| 1225 |
| 1226 void Predictor::SetPreconnectEnabledForTest(bool preconnect_enabled) { |
| 1227 base::AutoLock lock(preconnect_enabled_lock_); |
| 1228 preconnect_enabled_ = preconnect_enabled; |
| 1229 } |
| 1230 |
| 1219 Predictor::HostNameQueue::HostNameQueue() { | 1231 Predictor::HostNameQueue::HostNameQueue() { |
| 1220 } | 1232 } |
| 1221 | 1233 |
| 1222 Predictor::HostNameQueue::~HostNameQueue() { | 1234 Predictor::HostNameQueue::~HostNameQueue() { |
| 1223 } | 1235 } |
| 1224 | 1236 |
| 1225 void Predictor::HostNameQueue::Push(const GURL& url, | 1237 void Predictor::HostNameQueue::Push(const GURL& url, |
| 1226 UrlInfo::ResolutionMotivation motivation) { | 1238 UrlInfo::ResolutionMotivation motivation) { |
| 1227 switch (motivation) { | 1239 switch (motivation) { |
| 1228 case UrlInfo::STATIC_REFERAL_MOTIVATED: | 1240 case UrlInfo::STATIC_REFERAL_MOTIVATED: |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 } | 1359 } |
| 1348 | 1360 |
| 1349 void SimplePredictor::ShutdownOnUIThread() { | 1361 void SimplePredictor::ShutdownOnUIThread() { |
| 1350 SetShutdown(true); | 1362 SetShutdown(true); |
| 1351 } | 1363 } |
| 1352 | 1364 |
| 1353 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } | 1365 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
| 1354 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } | 1366 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
| 1355 | 1367 |
| 1356 } // namespace chrome_browser_net | 1368 } // namespace chrome_browser_net |
| OLD | NEW |