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 |