| 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/logging.h" |
| 16 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 17 #include "base/prefs/pref_service.h" | 18 #include "base/prefs/pref_service.h" |
| 18 #include "base/prefs/scoped_user_pref_update.h" | 19 #include "base/prefs/scoped_user_pref_update.h" |
| 19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 20 #include "base/strings/string_split.h" | 21 #include "base/strings/string_split.h" |
| 21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 23 #include "base/synchronization/waitable_event.h" | 24 #include "base/synchronization/waitable_event.h" |
| 24 #include "base/threading/thread_restrictions.h" | 25 #include "base/threading/thread_restrictions.h" |
| 25 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| 26 #include "base/values.h" | 27 #include "base/values.h" |
| 27 #include "chrome/browser/io_thread.h" | 28 #include "chrome/browser/io_thread.h" |
| 28 #include "chrome/browser/net/preconnect.h" | 29 #include "chrome/browser/net/preconnect.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; |
| 236 if (!CanPredictNetworkActionsUI()) |
| 237 return; |
| 238 |
| 232 std::string host = url.HostNoBrackets(); | 239 std::string host = url.HostNoBrackets(); |
| 233 bool is_new_host_request = (host != last_omnibox_host_); | 240 bool is_new_host_request = (host != last_omnibox_host_); |
| 234 last_omnibox_host_ = host; | 241 last_omnibox_host_ = host; |
| 235 | 242 |
| 236 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); | 243 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); |
| 237 base::TimeTicks now = base::TimeTicks::Now(); | 244 base::TimeTicks now = base::TimeTicks::Now(); |
| 238 | 245 |
| 239 if (preconnect_enabled()) { | 246 if (preconnect_enabled_) { |
| 240 if (preconnectable && !is_new_host_request) { | 247 if (preconnectable && !is_new_host_request) { |
| 241 ++consecutive_omnibox_preconnect_count_; | 248 ++consecutive_omnibox_preconnect_count_; |
| 242 // The omnibox suggests a search URL (for which we can preconnect) after | 249 // 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 | 250 // 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 | 251 // 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 | 252 // preconnectable URL (search URL) before forming a preconnection, so as |
| 246 // to reduce the useless preconnect rate. | 253 // to reduce the useless preconnect rate. |
| 247 // Perchance this logic should be pushed back into the omnibox, where the | 254 // Perchance this logic should be pushed back into the omnibox, where the |
| 248 // actual characters typed, such as a space, can better forcast whether | 255 // 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 | 256 // 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, | 299 BrowserThread::IO, |
| 293 FROM_HERE, | 300 FROM_HERE, |
| 294 base::Bind(&Predictor::Resolve, base::Unretained(this), | 301 base::Bind(&Predictor::Resolve, base::Unretained(this), |
| 295 CanonicalizeUrl(url), motivation)); | 302 CanonicalizeUrl(url), motivation)); |
| 296 } | 303 } |
| 297 | 304 |
| 298 void Predictor::PreconnectUrlAndSubresources(const GURL& url, | 305 void Predictor::PreconnectUrlAndSubresources(const GURL& url, |
| 299 const GURL& first_party_for_cookies) { | 306 const GURL& first_party_for_cookies) { |
| 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 301 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 308 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 302 if (!predictor_enabled_ || !preconnect_enabled() || | 309 if (!predictor_enabled_ || !preconnect_enabled_ || |
| 303 !url.is_valid() || !url.has_host()) | 310 !url.is_valid() || !url.has_host()) |
| 304 return; | 311 return; |
| 305 | 312 |
| 313 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 314 if (!CanPredictNetworkActionsUI()) |
| 315 return; |
| 316 } else { |
| 317 if (!CanPredictNetworkActionsIO()) |
| 318 return; |
| 319 } |
| 320 |
| 306 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); | 321 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); |
| 307 const int kConnectionsNeeded = 1; | 322 const int kConnectionsNeeded = 1; |
| 308 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, | 323 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, |
| 309 motivation, kConnectionsNeeded); | 324 motivation, kConnectionsNeeded); |
| 310 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); | 325 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); |
| 311 } | 326 } |
| 312 | 327 |
| 313 UrlList Predictor::GetPredictedUrlListAtStartup( | 328 UrlList Predictor::GetPredictedUrlListAtStartup( |
| 314 PrefService* user_prefs, | 329 PrefService* user_prefs, |
| 315 PrefService* local_state) { | 330 PrefService* local_state) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 UrlInfo::ResolutionMotivation motivation) { | 466 UrlInfo::ResolutionMotivation motivation) { |
| 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 453 if (!url.has_host()) | 468 if (!url.has_host()) |
| 454 return; | 469 return; |
| 455 AppendToResolutionQueue(url, motivation); | 470 AppendToResolutionQueue(url, motivation); |
| 456 } | 471 } |
| 457 | 472 |
| 458 void Predictor::LearnFromNavigation(const GURL& referring_url, | 473 void Predictor::LearnFromNavigation(const GURL& referring_url, |
| 459 const GURL& target_url) { | 474 const GURL& target_url) { |
| 460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 461 if (!predictor_enabled_) | 476 if (!predictor_enabled_ || !CanPredictNetworkActionsIO()) |
| 462 return; | 477 return; |
| 463 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); | 478 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); |
| 464 DCHECK_NE(referring_url, GURL::EmptyGURL()); | 479 DCHECK_NE(referring_url, GURL::EmptyGURL()); |
| 465 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); | 480 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); |
| 466 DCHECK_NE(target_url, GURL::EmptyGURL()); | 481 DCHECK_NE(target_url, GURL::EmptyGURL()); |
| 467 | 482 |
| 468 referrers_[referring_url].SuggestHost(target_url); | 483 referrers_[referring_url].SuggestHost(target_url); |
| 469 // Possibly do some referrer trimming. | 484 // Possibly do some referrer trimming. |
| 470 TrimReferrers(); | 485 TrimReferrers(); |
| 471 } | 486 } |
| 472 | 487 |
| 473 //----------------------------------------------------------------------------- | 488 //----------------------------------------------------------------------------- |
| 474 // This section supports the about:dns page. | 489 // This section supports the about:dns page. |
| 475 | 490 |
| 476 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, | 491 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, |
| 477 std::string* output) { | 492 std::string* output) { |
| 478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 479 | 494 |
| 480 output->append("<html><head><title>About DNS</title>" | 495 output->append("<html><head><title>About DNS</title>" |
| 481 // We'd like the following no-cache... but it doesn't work. | 496 // We'd like the following no-cache... but it doesn't work. |
| 482 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" | 497 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" |
| 483 "</head><body>"); | 498 "</head><body>"); |
| 484 if (predictor && predictor->predictor_enabled()) { | 499 if (predictor && predictor->predictor_enabled() && |
| 500 predictor->CanPredictNetworkActionsIO()) { |
| 485 predictor->GetHtmlInfo(output); | 501 predictor->GetHtmlInfo(output); |
| 486 } else { | 502 } else { |
| 487 output->append("DNS pre-resolution and TCP pre-connection is disabled."); | 503 output->append("DNS pre-resolution and TCP pre-connection is disabled."); |
| 488 } | 504 } |
| 489 output->append("</body></html>"); | 505 output->append("</body></html>"); |
| 490 } | 506 } |
| 491 | 507 |
| 492 // Provide sort order so all .com's are together, etc. | 508 // Provide sort order so all .com's are together, etc. |
| 493 struct RightToLeftStringSorter { | 509 struct RightToLeftStringSorter { |
| 494 bool operator()(const GURL& left, const GURL& right) const { | 510 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() { | 687 void Predictor::DiscardInitialNavigationHistory() { |
| 672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 688 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 673 if (initial_observer_.get()) | 689 if (initial_observer_.get()) |
| 674 initial_observer_->DiscardInitialNavigationHistory(); | 690 initial_observer_->DiscardInitialNavigationHistory(); |
| 675 } | 691 } |
| 676 | 692 |
| 677 void Predictor::FinalizeInitializationOnIOThread( | 693 void Predictor::FinalizeInitializationOnIOThread( |
| 678 const UrlList& startup_urls, | 694 const UrlList& startup_urls, |
| 679 base::ListValue* referral_list, | 695 base::ListValue* referral_list, |
| 680 IOThread* io_thread, | 696 IOThread* io_thread, |
| 681 bool predictor_enabled) { | 697 ProfileIOData* profile_io_data) { |
| 682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 683 | 699 |
| 684 predictor_enabled_ = predictor_enabled; | 700 profile_io_data_ = profile_io_data; |
| 685 initial_observer_.reset(new InitialObserver()); | 701 initial_observer_.reset(new InitialObserver()); |
| 686 host_resolver_ = io_thread->globals()->host_resolver.get(); | 702 host_resolver_ = io_thread->globals()->host_resolver.get(); |
| 687 | 703 |
| 688 net::URLRequestContext* context = | 704 net::URLRequestContext* context = |
| 689 url_request_context_getter_->GetURLRequestContext(); | 705 url_request_context_getter_->GetURLRequestContext(); |
| 690 transport_security_state_ = context->transport_security_state(); | 706 transport_security_state_ = context->transport_security_state(); |
| 691 ssl_config_service_ = context->ssl_config_service(); | 707 ssl_config_service_ = context->ssl_config_service(); |
| 692 | 708 |
| 693 // base::WeakPtrFactory instances need to be created and destroyed | 709 // base::WeakPtrFactory instances need to be created and destroyed |
| 694 // on the same thread. The predictor lives on the IO thread and will die | 710 // on the same thread. The predictor lives on the IO thread and will die |
| 695 // from there so now that we're on the IO thread we need to properly | 711 // from there so now that we're on the IO thread we need to properly |
| 696 // initialize the base::WeakPtrFactory. | 712 // initialize the base::WeakPtrFactory. |
| 697 // TODO(groby): Check if WeakPtrFactory has the same constraint. | 713 // TODO(groby): Check if WeakPtrFactory has the same constraint. |
| 698 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); | 714 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| 699 | 715 |
| 700 // Prefetch these hostnames on startup. | 716 // Prefetch these hostnames on startup. |
| 701 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); | 717 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| 702 DeserializeReferrersThenDelete(referral_list); | 718 DeserializeReferrersThenDelete(referral_list); |
| 703 } | 719 } |
| 704 | 720 |
| 705 //----------------------------------------------------------------------------- | 721 //----------------------------------------------------------------------------- |
| 706 // This section intermingles prefetch results with actual browser HTTP | 722 // This section intermingles prefetch results with actual browser HTTP |
| 707 // network activity. It supports calculating of the benefit of a prefetch, as | 723 // network activity. It supports calculating of the benefit of a prefetch, as |
| 708 // well as recording what prefetched hostname resolutions might be potentially | 724 // well as recording what prefetched hostname resolutions might be potentially |
| 709 // helpful during the next chrome-startup. | 725 // helpful during the next chrome-startup. |
| 710 //----------------------------------------------------------------------------- | 726 //----------------------------------------------------------------------------- |
| 711 | 727 |
| 712 void Predictor::LearnAboutInitialNavigation(const GURL& url) { | 728 void Predictor::LearnAboutInitialNavigation(const GURL& url) { |
| 713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 714 if (!predictor_enabled_ || NULL == initial_observer_.get() ) | 730 if (!predictor_enabled_ || NULL == initial_observer_.get() || |
| 731 !CanPredictNetworkActionsIO()) |
| 715 return; | 732 return; |
| 716 initial_observer_->Append(url, this); | 733 initial_observer_->Append(url, this); |
| 717 } | 734 } |
| 718 | 735 |
| 719 // This API is only used in the browser process. | 736 // This API is only used in the browser process. |
| 720 // It is called from an IPC message originating in the renderer. It currently | 737 // It is called from an IPC message originating in the renderer. It currently |
| 721 // includes both Page-Scan, and Link-Hover prefetching. | 738 // includes both Page-Scan, and Link-Hover prefetching. |
| 722 // TODO(jar): Separate out link-hover prefetching, and page-scan results. | 739 // TODO(jar): Separate out link-hover prefetching, and page-scan results. |
| 723 void Predictor::DnsPrefetchList(const NameList& hostnames) { | 740 void Predictor::DnsPrefetchList(const NameList& hostnames) { |
| 724 // TODO(jar): Push GURL transport further back into renderer, but this will | 741 // TODO(jar): Push GURL transport further back into renderer, but this will |
| (...skipping 10 matching lines...) Expand all Loading... |
| 735 } | 752 } |
| 736 | 753 |
| 737 void Predictor::DnsPrefetchMotivatedList( | 754 void Predictor::DnsPrefetchMotivatedList( |
| 738 const UrlList& urls, | 755 const UrlList& urls, |
| 739 UrlInfo::ResolutionMotivation motivation) { | 756 UrlInfo::ResolutionMotivation motivation) { |
| 740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 741 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 758 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 742 if (!predictor_enabled_) | 759 if (!predictor_enabled_) |
| 743 return; | 760 return; |
| 744 | 761 |
| 762 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 763 if (!CanPredictNetworkActionsUI()) |
| 764 return; |
| 765 } else { |
| 766 if (!CanPredictNetworkActionsIO()) |
| 767 return; |
| 768 } |
| 769 |
| 745 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 770 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 746 ResolveList(urls, motivation); | 771 ResolveList(urls, motivation); |
| 747 } else { | 772 } else { |
| 748 BrowserThread::PostTask( | 773 BrowserThread::PostTask( |
| 749 BrowserThread::IO, | 774 BrowserThread::IO, |
| 750 FROM_HERE, | 775 FROM_HERE, |
| 751 base::Bind(&Predictor::ResolveList, base::Unretained(this), | 776 base::Bind(&Predictor::ResolveList, base::Unretained(this), |
| 752 urls, motivation)); | 777 urls, motivation)); |
| 753 } | 778 } |
| 754 } | 779 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 765 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 790 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 766 | 791 |
| 767 if (NULL == predictor) { | 792 if (NULL == predictor) { |
| 768 completion->Signal(); | 793 completion->Signal(); |
| 769 return; | 794 return; |
| 770 } | 795 } |
| 771 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( | 796 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( |
| 772 startup_list, referral_list, completion); | 797 startup_list, referral_list, completion); |
| 773 } | 798 } |
| 774 | 799 |
| 775 void Predictor::SaveStateForNextStartupAndTrim(PrefService* prefs) { | 800 void Predictor::SaveStateForNextStartupAndTrim() { |
| 776 if (!predictor_enabled_) | 801 if (!predictor_enabled_) |
| 777 return; | 802 return; |
| 778 | 803 |
| 804 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 805 if (!CanPredictNetworkActionsUI()) |
| 806 return; |
| 807 } else { |
| 808 if (!CanPredictNetworkActionsIO()) |
| 809 return; |
| 810 } |
| 811 |
| 779 base::WaitableEvent completion(true, false); | 812 base::WaitableEvent completion(true, false); |
| 780 | 813 |
| 781 ListPrefUpdate update_startup_list(prefs, prefs::kDnsPrefetchingStartupList); | 814 ListPrefUpdate update_startup_list(user_prefs_, |
| 782 ListPrefUpdate update_referral_list(prefs, | 815 prefs::kDnsPrefetchingStartupList); |
| 816 ListPrefUpdate update_referral_list(user_prefs_, |
| 783 prefs::kDnsPrefetchingHostReferralList); | 817 prefs::kDnsPrefetchingHostReferralList); |
| 784 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 818 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 785 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( | 819 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( |
| 786 update_startup_list.Get(), | 820 update_startup_list.Get(), |
| 787 update_referral_list.Get(), | 821 update_referral_list.Get(), |
| 788 &completion, | 822 &completion, |
| 789 this); | 823 this); |
| 790 } else { | 824 } else { |
| 791 bool posted = BrowserThread::PostTask( | 825 bool posted = BrowserThread::PostTask( |
| 792 BrowserThread::IO, | 826 BrowserThread::IO, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 818 initial_observer_->GetInitialDnsResolutionList(startup_list); | 852 initial_observer_->GetInitialDnsResolutionList(startup_list); |
| 819 | 853 |
| 820 // Do at least one trim at shutdown, in case the user wasn't running long | 854 // Do at least one trim at shutdown, in case the user wasn't running long |
| 821 // enough to do any regular trimming of referrers. | 855 // enough to do any regular trimming of referrers. |
| 822 TrimReferrersNow(); | 856 TrimReferrersNow(); |
| 823 SerializeReferrers(referral_list); | 857 SerializeReferrers(referral_list); |
| 824 | 858 |
| 825 completion->Signal(); | 859 completion->Signal(); |
| 826 } | 860 } |
| 827 | 861 |
| 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, | 862 void Predictor::PreconnectUrl(const GURL& url, |
| 849 const GURL& first_party_for_cookies, | 863 const GURL& first_party_for_cookies, |
| 850 UrlInfo::ResolutionMotivation motivation, | 864 UrlInfo::ResolutionMotivation motivation, |
| 851 int count) { | 865 int count) { |
| 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 866 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 853 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 867 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 854 | 868 |
| 855 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 869 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 856 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count); | 870 PreconnectUrlOnIOThread(url, first_party_for_cookies, motivation, count); |
| 857 } else { | 871 } else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 885 count, | 899 count, |
| 886 url_request_context_getter_.get()); | 900 url_request_context_getter_.get()); |
| 887 } | 901 } |
| 888 | 902 |
| 889 void Predictor::PredictFrameSubresources(const GURL& url, | 903 void Predictor::PredictFrameSubresources(const GURL& url, |
| 890 const GURL& first_party_for_cookies) { | 904 const GURL& first_party_for_cookies) { |
| 891 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 892 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 906 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 893 if (!predictor_enabled_) | 907 if (!predictor_enabled_) |
| 894 return; | 908 return; |
| 909 |
| 910 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 911 if (!CanPredictNetworkActionsUI()) |
| 912 return; |
| 913 } else { |
| 914 if (!CanPredictNetworkActionsIO()) |
| 915 return; |
| 916 } |
| 895 DCHECK_EQ(url.GetWithEmptyPath(), url); | 917 DCHECK_EQ(url.GetWithEmptyPath(), url); |
| 896 // Add one pass through the message loop to allow current navigation to | 918 // Add one pass through the message loop to allow current navigation to |
| 897 // proceed. | 919 // proceed. |
| 898 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 920 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 899 PrepareFrameSubresources(url, first_party_for_cookies); | 921 PrepareFrameSubresources(url, first_party_for_cookies); |
| 900 } else { | 922 } else { |
| 901 BrowserThread::PostTask( | 923 BrowserThread::PostTask( |
| 902 BrowserThread::IO, | 924 BrowserThread::IO, |
| 903 FROM_HERE, | 925 FROM_HERE, |
| 904 base::Bind(&Predictor::PrepareFrameSubresources, | 926 base::Bind(&Predictor::PrepareFrameSubresources, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 919 AdviseProxyOnIOThread(url, motivation, is_preconnect); | 941 AdviseProxyOnIOThread(url, motivation, is_preconnect); |
| 920 } else { | 942 } else { |
| 921 BrowserThread::PostTask( | 943 BrowserThread::PostTask( |
| 922 BrowserThread::IO, | 944 BrowserThread::IO, |
| 923 FROM_HERE, | 945 FROM_HERE, |
| 924 base::Bind(&Predictor::AdviseProxyOnIOThread, | 946 base::Bind(&Predictor::AdviseProxyOnIOThread, |
| 925 base::Unretained(this), url, motivation, is_preconnect)); | 947 base::Unretained(this), url, motivation, is_preconnect)); |
| 926 } | 948 } |
| 927 } | 949 } |
| 928 | 950 |
| 951 bool Predictor::CanPredictNetworkActionsUI() { |
| 952 return chrome_browser_net::CanPredictNetworkActionsUI(user_prefs_); |
| 953 } |
| 954 |
| 955 bool Predictor::CanPredictNetworkActionsIO() { |
| 956 return chrome_browser_net::CanPredictNetworkActionsIO(profile_io_data_); |
| 957 } |
| 958 |
| 929 enum SubresourceValue { | 959 enum SubresourceValue { |
| 930 PRECONNECTION, | 960 PRECONNECTION, |
| 931 PRERESOLUTION, | 961 PRERESOLUTION, |
| 932 TOO_NEW, | 962 TOO_NEW, |
| 933 SUBRESOURCE_VALUE_MAX | 963 SUBRESOURCE_VALUE_MAX |
| 934 }; | 964 }; |
| 935 | 965 |
| 936 void Predictor::PrepareFrameSubresources(const GURL& original_url, | 966 void Predictor::PrepareFrameSubresources(const GURL& original_url, |
| 937 const GURL& first_party_for_cookies) { | 967 const GURL& first_party_for_cookies) { |
| 938 // Apply HSTS redirect early so it is taken into account when looking up | 968 // Apply HSTS redirect early so it is taken into account when looking up |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 if (url.has_port()) | 1329 if (url.has_port()) |
| 1300 colon_plus_port = ":" + url.port(); | 1330 colon_plus_port = ":" + url.port(); |
| 1301 | 1331 |
| 1302 return GURL(scheme + "://" + url.host() + colon_plus_port); | 1332 return GURL(scheme + "://" + url.host() + colon_plus_port); |
| 1303 } | 1333 } |
| 1304 | 1334 |
| 1305 void SimplePredictor::InitNetworkPredictor( | 1335 void SimplePredictor::InitNetworkPredictor( |
| 1306 PrefService* user_prefs, | 1336 PrefService* user_prefs, |
| 1307 PrefService* local_state, | 1337 PrefService* local_state, |
| 1308 IOThread* io_thread, | 1338 IOThread* io_thread, |
| 1309 net::URLRequestContextGetter* getter) { | 1339 net::URLRequestContextGetter* getter, |
| 1340 ProfileIOData* profile_io_data) { |
| 1310 // Empty function for unittests. | 1341 // Empty function for unittests. |
| 1311 } | 1342 } |
| 1312 | 1343 |
| 1313 void SimplePredictor::ShutdownOnUIThread() { | 1344 void SimplePredictor::ShutdownOnUIThread() { |
| 1314 SetShutdown(true); | 1345 SetShutdown(true); |
| 1315 } | 1346 } |
| 1316 | 1347 |
| 1348 bool SimplePredictor::CanPredictNetworkActionsUI() { return true; } |
| 1349 bool SimplePredictor::CanPredictNetworkActionsIO() { return true; } |
| 1350 |
| 1317 } // namespace chrome_browser_net | 1351 } // namespace chrome_browser_net |
| OLD | NEW |