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 <set> | 9 #include <set> |
| 10 #include <sstream> | 10 #include <sstream> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/containers/mru_cache.h" | 15 #include "base/containers/mru_cache.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/prefs/pref_service.h" | 17 #include "base/prefs/pref_service.h" |
| 18 #include "base/prefs/scoped_user_pref_update.h" | 18 #include "base/prefs/scoped_user_pref_update.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/synchronization/waitable_event.h" | 23 #include "base/synchronization/waitable_event.h" |
| 24 #include "base/threading/thread_restrictions.h" | 24 #include "base/threading/thread_restrictions.h" |
| 25 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| 26 #include "base/values.h" | 26 #include "base/values.h" |
| 27 #include "chrome/browser/io_thread.h" | 27 #include "chrome/browser/io_thread.h" |
| 28 #include "chrome/browser/net/preconnect.h" | 28 #include "chrome/browser/net/preconnect.h" |
| 29 #include "chrome/browser/net/prediction_options.h" | |
| 29 #include "chrome/browser/net/spdyproxy/proxy_advisor.h" | 30 #include "chrome/browser/net/spdyproxy/proxy_advisor.h" |
| 30 #include "chrome/browser/prefs/session_startup_pref.h" | 31 #include "chrome/browser/prefs/session_startup_pref.h" |
| 32 #include "chrome/browser/profiles/profile_io_data.h" | |
| 31 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
| 32 #include "chrome/common/pref_names.h" | 34 #include "chrome/common/pref_names.h" |
| 33 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings. h" | 35 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings. h" |
| 34 #include "components/pref_registry/pref_registry_syncable.h" | 36 #include "components/pref_registry/pref_registry_syncable.h" |
| 35 #include "content/public/browser/browser_thread.h" | 37 #include "content/public/browser/browser_thread.h" |
| 36 #include "net/base/address_list.h" | 38 #include "net/base/address_list.h" |
| 37 #include "net/base/completion_callback.h" | 39 #include "net/base/completion_callback.h" |
| 38 #include "net/base/host_port_pair.h" | 40 #include "net/base/host_port_pair.h" |
| 39 #include "net/base/net_errors.h" | 41 #include "net/base/net_errors.h" |
| 40 #include "net/base/net_log.h" | 42 #include "net/base/net_log.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 | 128 |
| 127 Predictor* predictor_; // The predictor which started us. | 129 Predictor* predictor_; // The predictor which started us. |
| 128 | 130 |
| 129 const GURL url_; // Hostname to resolve. | 131 const GURL url_; // Hostname to resolve. |
| 130 net::SingleRequestHostResolver resolver_; | 132 net::SingleRequestHostResolver resolver_; |
| 131 net::AddressList addresses_; | 133 net::AddressList addresses_; |
| 132 | 134 |
| 133 DISALLOW_COPY_AND_ASSIGN(LookupRequest); | 135 DISALLOW_COPY_AND_ASSIGN(LookupRequest); |
| 134 }; | 136 }; |
| 135 | 137 |
| 136 Predictor::Predictor(bool preconnect_enabled) | 138 Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) |
| 137 : url_request_context_getter_(NULL), | 139 : url_request_context_getter_(NULL), |
| 138 predictor_enabled_(true), | 140 predictor_enabled_(predictor_enabled), |
| 141 user_prefs_(NULL), | |
| 142 profile_io_data_(NULL), | |
| 139 peak_pending_lookups_(0), | 143 peak_pending_lookups_(0), |
| 140 shutdown_(false), | 144 shutdown_(false), |
| 141 max_concurrent_dns_lookups_(g_max_parallel_resolves), | 145 max_concurrent_dns_lookups_(g_max_parallel_resolves), |
| 142 max_dns_queue_delay_( | 146 max_dns_queue_delay_( |
| 143 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), | 147 TimeDelta::FromMilliseconds(g_max_queueing_delay_ms)), |
| 144 host_resolver_(NULL), | 148 host_resolver_(NULL), |
| 145 transport_security_state_(NULL), | 149 transport_security_state_(NULL), |
| 146 ssl_config_service_(NULL), | 150 ssl_config_service_(NULL), |
| 147 preconnect_enabled_(preconnect_enabled), | 151 preconnect_enabled_(preconnect_enabled), |
| 148 consecutive_omnibox_preconnect_count_(0), | 152 consecutive_omnibox_preconnect_count_(0), |
| 149 next_trim_time_(base::TimeTicks::Now() + | 153 next_trim_time_(base::TimeTicks::Now() + |
| 150 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), | 154 TimeDelta::FromHours(kDurationBetweenTrimmingsHours)), |
| 151 observer_(NULL) { | 155 observer_(NULL) { |
| 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 153 } | 157 } |
| 154 | 158 |
| 155 Predictor::~Predictor() { | 159 Predictor::~Predictor() { |
| 156 // TODO(rlp): Add DCHECK for CurrentlyOn(BrowserThread::IO) when the | 160 // TODO(rlp): Add DCHECK for CurrentlyOn(BrowserThread::IO) when the |
| 157 // ProfileManagerTest has been updated with a mock profile. | 161 // ProfileManagerTest has been updated with a mock profile. |
| 158 DCHECK(shutdown_); | 162 DCHECK(shutdown_); |
| 159 } | 163 } |
| 160 | 164 |
| 161 // static | 165 // static |
| 162 Predictor* Predictor::CreatePredictor(bool preconnect_enabled, | 166 Predictor* Predictor::CreatePredictor(bool preconnect_enabled, |
| 167 bool predictor_enabled, | |
| 163 bool simple_shutdown) { | 168 bool simple_shutdown) { |
| 164 if (simple_shutdown) | 169 if (simple_shutdown) |
| 165 return new SimplePredictor(preconnect_enabled); | 170 return new SimplePredictor(preconnect_enabled, predictor_enabled); |
| 166 return new Predictor(preconnect_enabled); | 171 return new Predictor(preconnect_enabled, predictor_enabled); |
| 167 } | 172 } |
| 168 | 173 |
| 169 void Predictor::RegisterProfilePrefs( | 174 void Predictor::RegisterProfilePrefs( |
| 170 user_prefs::PrefRegistrySyncable* registry) { | 175 user_prefs::PrefRegistrySyncable* registry) { |
| 171 registry->RegisterListPref(prefs::kDnsPrefetchingStartupList, | 176 registry->RegisterListPref(prefs::kDnsPrefetchingStartupList, |
| 172 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 177 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 173 registry->RegisterListPref(prefs::kDnsPrefetchingHostReferralList, | 178 registry->RegisterListPref(prefs::kDnsPrefetchingHostReferralList, |
| 174 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 179 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 175 } | 180 } |
| 176 | 181 |
| 177 // --------------------- Start UI methods. ------------------------------------ | 182 // --------------------- Start UI methods. ------------------------------------ |
| 178 | 183 |
| 179 void Predictor::InitNetworkPredictor(PrefService* user_prefs, | 184 void Predictor::InitNetworkPredictor(PrefService* user_prefs, |
| 180 PrefService* local_state, | 185 PrefService* local_state, |
| 181 IOThread* io_thread, | 186 IOThread* io_thread, |
| 182 net::URLRequestContextGetter* getter) { | 187 net::URLRequestContextGetter* getter, |
| 188 ProfileIOData* profile_io_data) { | |
| 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 184 | 190 |
| 185 bool predictor_enabled = | 191 user_prefs_ = user_prefs; |
| 186 user_prefs->GetBoolean(prefs::kNetworkPredictionEnabled); | |
| 187 | |
| 188 url_request_context_getter_ = getter; | 192 url_request_context_getter_ = getter; |
| 189 | 193 |
| 190 // Gather the list of hostnames to prefetch on startup. | 194 // Gather the list of hostnames to prefetch on startup. |
| 191 UrlList urls = GetPredictedUrlListAtStartup(user_prefs, local_state); | 195 UrlList urls = GetPredictedUrlListAtStartup(user_prefs, local_state); |
| 192 | 196 |
| 193 base::ListValue* referral_list = | 197 base::ListValue* referral_list = |
| 194 static_cast<base::ListValue*>(user_prefs->GetList( | 198 static_cast<base::ListValue*>(user_prefs->GetList( |
| 195 prefs::kDnsPrefetchingHostReferralList)->DeepCopy()); | 199 prefs::kDnsPrefetchingHostReferralList)->DeepCopy()); |
| 196 | 200 |
| 197 // Now that we have the statistics in memory, wipe them from the Preferences | 201 // Now that we have the statistics in memory, wipe them from the Preferences |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 213 } | 217 } |
| 214 #endif | 218 #endif |
| 215 | 219 |
| 216 BrowserThread::PostTask( | 220 BrowserThread::PostTask( |
| 217 BrowserThread::IO, | 221 BrowserThread::IO, |
| 218 FROM_HERE, | 222 FROM_HERE, |
| 219 base::Bind( | 223 base::Bind( |
| 220 &Predictor::FinalizeInitializationOnIOThread, | 224 &Predictor::FinalizeInitializationOnIOThread, |
| 221 base::Unretained(this), | 225 base::Unretained(this), |
| 222 urls, referral_list, | 226 urls, referral_list, |
| 223 io_thread, predictor_enabled)); | 227 io_thread, profile_io_data)); |
| 224 } | 228 } |
| 225 | 229 |
| 226 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { | 230 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { |
| 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 228 if (!predictor_enabled_) | 232 if (!predictor_enabled_) |
| 229 return; | 233 return; |
| 230 if (!url.is_valid() || !url.has_host()) | 234 if (!url.is_valid() || !url.has_host()) |
| 231 return; | 235 return; |
| 232 std::string host = url.HostNoBrackets(); | 236 std::string host = url.HostNoBrackets(); |
| 233 bool is_new_host_request = (host != last_omnibox_host_); | 237 bool is_new_host_request = (host != last_omnibox_host_); |
| 234 last_omnibox_host_ = host; | 238 last_omnibox_host_ = host; |
| 235 | 239 |
| 236 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); | 240 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); |
| 237 base::TimeTicks now = base::TimeTicks::Now(); | 241 base::TimeTicks now = base::TimeTicks::Now(); |
| 238 | 242 |
| 239 if (preconnect_enabled()) { | 243 if (preconnect_enabled_ && |
| 244 chrome_browser_net::CanPredictNetworkActionsUI(user_prefs_)) { | |
| 240 if (preconnectable && !is_new_host_request) { | 245 if (preconnectable && !is_new_host_request) { |
| 241 ++consecutive_omnibox_preconnect_count_; | 246 ++consecutive_omnibox_preconnect_count_; |
| 242 // 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 |
| 243 // 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 |
| 244 // 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 |
| 245 // preconnectable URL (search URL) before forming a preconnection, so as | 250 // preconnectable URL (search URL) before forming a preconnection, so as |
| 246 // to reduce the useless preconnect rate. | 251 // to reduce the useless preconnect rate. |
| 247 // 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 |
| 248 // actual characters typed, such as a space, can better forcast whether | 253 // actual characters typed, such as a space, can better forcast whether |
| 249 // 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 BrowserThread::IO, | 297 BrowserThread::IO, |
| 293 FROM_HERE, | 298 FROM_HERE, |
| 294 base::Bind(&Predictor::Resolve, base::Unretained(this), | 299 base::Bind(&Predictor::Resolve, base::Unretained(this), |
| 295 CanonicalizeUrl(url), motivation)); | 300 CanonicalizeUrl(url), motivation)); |
| 296 } | 301 } |
| 297 | 302 |
| 298 void Predictor::PreconnectUrlAndSubresources(const GURL& url, | 303 void Predictor::PreconnectUrlAndSubresources(const GURL& url, |
| 299 const GURL& first_party_for_cookies) { | 304 const GURL& first_party_for_cookies) { |
| 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 305 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 301 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 306 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 302 if (!predictor_enabled_ || !preconnect_enabled() || | 307 if (!predictor_enabled_ || !preconnect_enabled_ || |
| 303 !url.is_valid() || !url.has_host()) | 308 !url.is_valid() || !url.has_host()) |
| 304 return; | 309 return; |
| 305 | 310 |
| 311 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 312 if (!chrome_browser_net::CanPredictNetworkActionsUI(user_prefs_)) | |
| 313 return; | |
| 314 } else { | |
| 315 if (!chrome_browser_net::CanPredictNetworkActionsIO(profile_io_data_)) | |
| 316 return; | |
| 317 } | |
| 318 | |
| 306 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); | 319 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); |
| 307 const int kConnectionsNeeded = 1; | 320 const int kConnectionsNeeded = 1; |
| 308 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, | 321 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, |
| 309 motivation, kConnectionsNeeded); | 322 motivation, kConnectionsNeeded); |
| 310 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); | 323 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); |
| 311 } | 324 } |
| 312 | 325 |
| 313 UrlList Predictor::GetPredictedUrlListAtStartup( | 326 UrlList Predictor::GetPredictedUrlListAtStartup( |
| 314 PrefService* user_prefs, | 327 PrefService* user_prefs, |
| 315 PrefService* local_state) { | 328 PrefService* local_state) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 // This section supports the about:dns page. | 487 // This section supports the about:dns page. |
| 475 | 488 |
| 476 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, | 489 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, |
| 477 std::string* output) { | 490 std::string* output) { |
| 478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 479 | 492 |
| 480 output->append("<html><head><title>About DNS</title>" | 493 output->append("<html><head><title>About DNS</title>" |
| 481 // We'd like the following no-cache... but it doesn't work. | 494 // We'd like the following no-cache... but it doesn't work. |
| 482 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" | 495 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" |
| 483 "</head><body>"); | 496 "</head><body>"); |
| 484 if (predictor && predictor->predictor_enabled()) { | 497 if (predictor && predictor->predictor_enabled() && |
| 498 chrome_browser_net::CanPredictNetworkActionsIO( | |
| 499 predictor->profile_io_data())) { | |
| 485 predictor->GetHtmlInfo(output); | 500 predictor->GetHtmlInfo(output); |
| 486 } else { | 501 } else { |
| 487 output->append("DNS pre-resolution and TCP pre-connection is disabled."); | 502 output->append("DNS pre-resolution and TCP pre-connection is disabled."); |
| 488 } | 503 } |
| 489 output->append("</body></html>"); | 504 output->append("</body></html>"); |
| 490 } | 505 } |
| 491 | 506 |
| 492 // Provide sort order so all .com's are together, etc. | 507 // Provide sort order so all .com's are together, etc. |
| 493 struct RightToLeftStringSorter { | 508 struct RightToLeftStringSorter { |
| 494 bool operator()(const GURL& left, const GURL& right) const { | 509 bool operator()(const GURL& left, const GURL& right) const { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 void Predictor::DiscardInitialNavigationHistory() { | 686 void Predictor::DiscardInitialNavigationHistory() { |
| 672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 673 if (initial_observer_.get()) | 688 if (initial_observer_.get()) |
| 674 initial_observer_->DiscardInitialNavigationHistory(); | 689 initial_observer_->DiscardInitialNavigationHistory(); |
| 675 } | 690 } |
| 676 | 691 |
| 677 void Predictor::FinalizeInitializationOnIOThread( | 692 void Predictor::FinalizeInitializationOnIOThread( |
| 678 const UrlList& startup_urls, | 693 const UrlList& startup_urls, |
| 679 base::ListValue* referral_list, | 694 base::ListValue* referral_list, |
| 680 IOThread* io_thread, | 695 IOThread* io_thread, |
| 681 bool predictor_enabled) { | 696 ProfileIOData* profile_io_data) { |
| 682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 683 | 698 |
| 684 predictor_enabled_ = predictor_enabled; | 699 profile_io_data_ = profile_io_data; |
| 685 initial_observer_.reset(new InitialObserver()); | 700 initial_observer_.reset(new InitialObserver()); |
| 686 host_resolver_ = io_thread->globals()->host_resolver.get(); | 701 host_resolver_ = io_thread->globals()->host_resolver.get(); |
| 687 | 702 |
| 688 net::URLRequestContext* context = | 703 net::URLRequestContext* context = |
| 689 url_request_context_getter_->GetURLRequestContext(); | 704 url_request_context_getter_->GetURLRequestContext(); |
| 690 transport_security_state_ = context->transport_security_state(); | 705 transport_security_state_ = context->transport_security_state(); |
| 691 ssl_config_service_ = context->ssl_config_service(); | 706 ssl_config_service_ = context->ssl_config_service(); |
| 692 | 707 |
| 693 // base::WeakPtrFactory instances need to be created and destroyed | 708 // base::WeakPtrFactory instances need to be created and destroyed |
| 694 // on the same thread. The predictor lives on the IO thread and will die | 709 // on the same thread. The predictor lives on the IO thread and will die |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 780 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 766 | 781 |
| 767 if (NULL == predictor) { | 782 if (NULL == predictor) { |
| 768 completion->Signal(); | 783 completion->Signal(); |
| 769 return; | 784 return; |
| 770 } | 785 } |
| 771 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( | 786 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( |
| 772 startup_list, referral_list, completion); | 787 startup_list, referral_list, completion); |
| 773 } | 788 } |
| 774 | 789 |
| 775 void Predictor::SaveStateForNextStartupAndTrim(PrefService* prefs) { | 790 void Predictor::SaveStateForNextStartupAndTrim() { |
| 776 if (!predictor_enabled_) | 791 if (!predictor_enabled_) |
| 777 return; | 792 return; |
| 778 | 793 |
| 779 base::WaitableEvent completion(true, false); | 794 base::WaitableEvent completion(true, false); |
| 780 | 795 |
| 781 ListPrefUpdate update_startup_list(prefs, prefs::kDnsPrefetchingStartupList); | 796 ListPrefUpdate update_startup_list(user_prefs_, |
| 782 ListPrefUpdate update_referral_list(prefs, | 797 prefs::kDnsPrefetchingStartupList); |
| 798 ListPrefUpdate update_referral_list(user_prefs_, | |
| 783 prefs::kDnsPrefetchingHostReferralList); | 799 prefs::kDnsPrefetchingHostReferralList); |
|
battre
2014/07/10 09:01:59
This is actually a pretty serious bug that existed
Bernhard Bauer
2014/07/10 09:59:02
I think in this particular case, we're okay. The o
| |
| 784 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 800 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 785 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( | 801 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( |
| 786 update_startup_list.Get(), | 802 update_startup_list.Get(), |
| 787 update_referral_list.Get(), | 803 update_referral_list.Get(), |
| 788 &completion, | 804 &completion, |
| 789 this); | 805 this); |
| 790 } else { | 806 } else { |
| 791 bool posted = BrowserThread::PostTask( | 807 bool posted = BrowserThread::PostTask( |
| 792 BrowserThread::IO, | 808 BrowserThread::IO, |
| 793 FROM_HERE, | 809 FROM_HERE, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 818 initial_observer_->GetInitialDnsResolutionList(startup_list); | 834 initial_observer_->GetInitialDnsResolutionList(startup_list); |
| 819 | 835 |
| 820 // Do at least one trim at shutdown, in case the user wasn't running long | 836 // Do at least one trim at shutdown, in case the user wasn't running long |
| 821 // enough to do any regular trimming of referrers. | 837 // enough to do any regular trimming of referrers. |
| 822 TrimReferrersNow(); | 838 TrimReferrersNow(); |
| 823 SerializeReferrers(referral_list); | 839 SerializeReferrers(referral_list); |
| 824 | 840 |
| 825 completion->Signal(); | 841 completion->Signal(); |
| 826 } | 842 } |
| 827 | 843 |
| 828 void Predictor::EnablePredictor(bool enable) { | |
| 829 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | |
| 830 BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 831 | |
| 832 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | |
| 833 EnablePredictorOnIOThread(enable); | |
| 834 } else { | |
| 835 BrowserThread::PostTask( | |
| 836 BrowserThread::IO, | |
| 837 FROM_HERE, | |
| 838 base::Bind(&Predictor::EnablePredictorOnIOThread, | |
| 839 base::Unretained(this), enable)); | |
| 840 } | |
| 841 } | |
| 842 | |
| 843 void Predictor::EnablePredictorOnIOThread(bool enable) { | |
| 844 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 845 predictor_enabled_ = enable; | |
| 846 } | |
| 847 | |
| 848 void Predictor::PreconnectUrl(const GURL& url, | 844 void Predictor::PreconnectUrl(const GURL& url, |
| 849 const GURL& first_party_for_cookies, | 845 const GURL& first_party_for_cookies, |
| 850 UrlInfo::ResolutionMotivation motivation, | 846 UrlInfo::ResolutionMotivation motivation, |
| 851 int count) { | 847 int count) { |
| 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 848 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 853 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 849 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 854 | 850 |
| 855 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 851 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 856 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count); | 852 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count); |
| 857 } else { | 853 } else { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 943 DCHECK_EQ(url.GetWithEmptyPath(), url); | 939 DCHECK_EQ(url.GetWithEmptyPath(), url); |
| 944 Referrers::iterator it = referrers_.find(url); | 940 Referrers::iterator it = referrers_.find(url); |
| 945 if (referrers_.end() == it) { | 941 if (referrers_.end() == it) { |
| 946 // Only when we don't know anything about this url, make 2 connections | 942 // Only when we don't know anything about this url, make 2 connections |
| 947 // available. We could do this completely via learning (by prepopulating | 943 // available. We could do this completely via learning (by prepopulating |
| 948 // the referrer_ list with this expected value), but it would swell the | 944 // the referrer_ list with this expected value), but it would swell the |
| 949 // size of the list with all the "Leaf" nodes in the tree (nodes that don't | 945 // size of the list with all the "Leaf" nodes in the tree (nodes that don't |
| 950 // load any subresources). If we learn about this resource, we will instead | 946 // load any subresources). If we learn about this resource, we will instead |
| 951 // provide a more carefully estimated preconnection count. | 947 // provide a more carefully estimated preconnection count. |
| 952 if (preconnect_enabled_) { | 948 if (preconnect_enabled_ && |
| 949 chrome_browser_net::CanPredictNetworkActionsIO(profile_io_data_)) { | |
| 953 PreconnectUrlOnIOThread(url, first_party_for_cookies, | 950 PreconnectUrlOnIOThread(url, first_party_for_cookies, |
| 954 UrlInfo::SELF_REFERAL_MOTIVATED, 2); | 951 UrlInfo::SELF_REFERAL_MOTIVATED, 2); |
| 955 } | 952 } |
| 956 return; | 953 return; |
| 957 } | 954 } |
| 958 | 955 |
| 959 Referrer* referrer = &(it->second); | 956 Referrer* referrer = &(it->second); |
| 960 referrer->IncrementUseCount(); | 957 referrer->IncrementUseCount(); |
| 961 const UrlInfo::ResolutionMotivation motivation = | 958 const UrlInfo::ResolutionMotivation motivation = |
| 962 UrlInfo::LEARNED_REFERAL_MOTIVATED; | 959 UrlInfo::LEARNED_REFERAL_MOTIVATED; |
| 963 for (Referrer::iterator future_url = referrer->begin(); | 960 for (Referrer::iterator future_url = referrer->begin(); |
| 964 future_url != referrer->end(); ++future_url) { | 961 future_url != referrer->end(); ++future_url) { |
| 965 SubresourceValue evalution(TOO_NEW); | 962 SubresourceValue evalution(TOO_NEW); |
| 966 double connection_expectation = future_url->second.subresource_use_rate(); | 963 double connection_expectation = future_url->second.subresource_use_rate(); |
| 967 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", | 964 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", |
| 968 static_cast<int>(connection_expectation * 100), | 965 static_cast<int>(connection_expectation * 100), |
| 969 10, 5000, 50); | 966 10, 5000, 50); |
| 970 future_url->second.ReferrerWasObserved(); | 967 future_url->second.ReferrerWasObserved(); |
| 971 if (preconnect_enabled_ && | 968 if (preconnect_enabled_ && |
| 969 chrome_browser_net::CanPredictNetworkActionsIO(profile_io_data_) && | |
| 972 connection_expectation > kPreconnectWorthyExpectedValue) { | 970 connection_expectation > kPreconnectWorthyExpectedValue) { |
| 973 evalution = PRECONNECTION; | 971 evalution = PRECONNECTION; |
| 974 future_url->second.IncrementPreconnectionCount(); | 972 future_url->second.IncrementPreconnectionCount(); |
| 975 int count = static_cast<int>(std::ceil(connection_expectation)); | 973 int count = static_cast<int>(std::ceil(connection_expectation)); |
| 976 if (url.host() == future_url->first.host()) | 974 if (url.host() == future_url->first.host()) |
| 977 ++count; | 975 ++count; |
| 978 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, | 976 PreconnectUrlOnIOThread(future_url->first, first_party_for_cookies, |
| 979 motivation, count); | 977 motivation, count); |
| 980 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { | 978 } else if (connection_expectation > kDNSPreresolutionWorthyExpectedValue) { |
| 981 evalution = PRERESOLUTION; | 979 evalution = PRERESOLUTION; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1299 if (url.has_port()) | 1297 if (url.has_port()) |
| 1300 colon_plus_port = ":" + url.port(); | 1298 colon_plus_port = ":" + url.port(); |
| 1301 | 1299 |
| 1302 return GURL(scheme + "://" + url.host() + colon_plus_port); | 1300 return GURL(scheme + "://" + url.host() + colon_plus_port); |
| 1303 } | 1301 } |
| 1304 | 1302 |
| 1305 void SimplePredictor::InitNetworkPredictor( | 1303 void SimplePredictor::InitNetworkPredictor( |
| 1306 PrefService* user_prefs, | 1304 PrefService* user_prefs, |
| 1307 PrefService* local_state, | 1305 PrefService* local_state, |
| 1308 IOThread* io_thread, | 1306 IOThread* io_thread, |
| 1309 net::URLRequestContextGetter* getter) { | 1307 net::URLRequestContextGetter* getter, |
| 1308 ProfileIOData* profile_io_data) { | |
| 1310 // Empty function for unittests. | 1309 // Empty function for unittests. |
| 1311 } | 1310 } |
| 1312 | 1311 |
| 1313 void SimplePredictor::ShutdownOnUIThread() { | 1312 void SimplePredictor::ShutdownOnUIThread() { |
| 1314 SetShutdown(true); | 1313 SetShutdown(true); |
| 1315 } | 1314 } |
| 1316 | 1315 |
| 1317 } // namespace chrome_browser_net | 1316 } // namespace chrome_browser_net |
| OLD | NEW |