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 |