| 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 <iterator> | 9 #include <iterator> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <sstream> | 11 #include <sstream> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/containers/mru_cache.h" | 16 #include "base/containers/mru_cache.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" |
| 20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
| 21 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
| 22 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
| 23 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
| 24 #include "base/synchronization/waitable_event.h" | 25 #include "base/synchronization/waitable_event.h" |
| 25 #include "base/threading/thread_restrictions.h" | 26 #include "base/threading/thread_restrictions.h" |
| 26 #include "base/threading/thread_task_runner_handle.h" | 27 #include "base/threading/thread_task_runner_handle.h" |
| 27 #include "base/time/time.h" | 28 #include "base/time/time.h" |
| 28 #include "base/values.h" | 29 #include "base/values.h" |
| 29 #include "chrome/browser/io_thread.h" | 30 #include "chrome/browser/io_thread.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 net::URLRequestContextGetter* getter, | 140 net::URLRequestContextGetter* getter, |
| 140 ProfileIOData* profile_io_data) { | 141 ProfileIOData* profile_io_data) { |
| 141 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 142 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 142 | 143 |
| 143 user_prefs_ = user_prefs; | 144 user_prefs_ = user_prefs; |
| 144 url_request_context_getter_ = getter; | 145 url_request_context_getter_ = getter; |
| 145 | 146 |
| 146 // Gather the list of hostnames to prefetch on startup. | 147 // Gather the list of hostnames to prefetch on startup. |
| 147 std::vector<GURL> urls = GetPredictedUrlListAtStartup(user_prefs); | 148 std::vector<GURL> urls = GetPredictedUrlListAtStartup(user_prefs); |
| 148 | 149 |
| 149 base::ListValue* referral_list = | 150 std::unique_ptr<base::ListValue> referral_list = base::WrapUnique( |
| 150 static_cast<base::ListValue*>(user_prefs->GetList( | 151 user_prefs->GetList(prefs::kDnsPrefetchingHostReferralList)->DeepCopy()); |
| 151 prefs::kDnsPrefetchingHostReferralList)->DeepCopy()); | |
| 152 | |
| 153 // Now that we have the statistics in memory, wipe them from the Preferences | |
| 154 // file. They will be serialized back on a clean shutdown. This way we only | |
| 155 // have to worry about clearing our in-memory state when Clearing Browsing | |
| 156 // Data. | |
| 157 user_prefs->ClearPref(prefs::kDnsPrefetchingStartupList); | |
| 158 user_prefs->ClearPref(prefs::kDnsPrefetchingHostReferralList); | |
| 159 | 152 |
| 160 BrowserThread::PostTask( | 153 BrowserThread::PostTask( |
| 161 BrowserThread::IO, | 154 BrowserThread::IO, FROM_HERE, |
| 162 FROM_HERE, | 155 base::Bind(&Predictor::FinalizeInitializationOnIOThread, |
| 163 base::Bind( | 156 base::Unretained(this), urls, |
| 164 &Predictor::FinalizeInitializationOnIOThread, | 157 base::Passed(std::move(referral_list)), io_thread, |
| 165 base::Unretained(this), | 158 profile_io_data)); |
| 166 urls, referral_list, | |
| 167 io_thread, profile_io_data)); | |
| 168 } | 159 } |
| 169 | 160 |
| 170 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { | 161 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { |
| 171 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 162 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 172 if (!predictor_enabled_) | 163 if (!predictor_enabled_) |
| 173 return; | 164 return; |
| 174 if (!url.is_valid() || !url.has_host()) | 165 if (!url.is_valid() || !url.has_host()) |
| 175 return; | 166 return; |
| 176 if (!CanPreresolveAndPreconnect()) | 167 if (!CanPreresolveAndPreconnect()) |
| 177 return; | 168 return; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 urls.push_back(gurl.GetWithEmptyPath()); | 299 urls.push_back(gurl.GetWithEmptyPath()); |
| 309 } | 300 } |
| 310 } | 301 } |
| 311 | 302 |
| 312 if (urls.empty()) | 303 if (urls.empty()) |
| 313 urls.push_back(GURL("http://www.google.com:80")); | 304 urls.push_back(GURL("http://www.google.com:80")); |
| 314 | 305 |
| 315 return urls; | 306 return urls; |
| 316 } | 307 } |
| 317 | 308 |
| 309 void Predictor::DiscardAllResultsAndClearPrefsOnUIThread() { |
| 310 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 311 BrowserThread::PostTask( |
| 312 BrowserThread::IO, FROM_HERE, |
| 313 base::Bind(&Predictor::DiscardAllResults, weak_factory_->GetWeakPtr())); |
| 314 ClearPrefsOnUIThread(); |
| 315 } |
| 316 |
| 317 void Predictor::ClearPrefsOnUIThread() { |
| 318 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 319 user_prefs_->ClearPref(prefs::kDnsPrefetchingStartupList); |
| 320 user_prefs_->ClearPref(prefs::kDnsPrefetchingHostReferralList); |
| 321 } |
| 322 |
| 318 void Predictor::set_max_queueing_delay(int max_queueing_delay_ms) { | 323 void Predictor::set_max_queueing_delay(int max_queueing_delay_ms) { |
| 319 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 324 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 320 g_max_queueing_delay_ms = max_queueing_delay_ms; | 325 g_max_queueing_delay_ms = max_queueing_delay_ms; |
| 321 } | 326 } |
| 322 | 327 |
| 323 void Predictor::set_max_parallel_resolves(size_t max_parallel_resolves) { | 328 void Predictor::set_max_parallel_resolves(size_t max_parallel_resolves) { |
| 324 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 329 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 325 g_max_parallel_resolves = max_parallel_resolves; | 330 g_max_parallel_resolves = max_parallel_resolves; |
| 326 } | 331 } |
| 327 | 332 |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 NOTREACHED(); | 572 NOTREACHED(); |
| 568 return; | 573 return; |
| 569 } | 574 } |
| 570 | 575 |
| 571 referrers_.Put(GURL(motivating_url_spec), Referrer()) | 576 referrers_.Put(GURL(motivating_url_spec), Referrer()) |
| 572 ->second.Deserialize(*subresource_list); | 577 ->second.Deserialize(*subresource_list); |
| 573 } | 578 } |
| 574 } | 579 } |
| 575 } | 580 } |
| 576 | 581 |
| 577 void Predictor::DeserializeReferrersThenDelete( | |
| 578 base::ListValue* referral_list) { | |
| 579 DeserializeReferrers(*referral_list); | |
| 580 delete referral_list; | |
| 581 } | |
| 582 | |
| 583 void Predictor::DiscardInitialNavigationHistory() { | 582 void Predictor::DiscardInitialNavigationHistory() { |
| 584 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 583 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 585 if (initial_observer_.get()) | 584 if (initial_observer_.get()) |
| 586 initial_observer_->DiscardInitialNavigationHistory(); | 585 initial_observer_->DiscardInitialNavigationHistory(); |
| 587 } | 586 } |
| 588 | 587 |
| 589 void Predictor::FinalizeInitializationOnIOThread( | 588 void Predictor::FinalizeInitializationOnIOThread( |
| 590 const std::vector<GURL>& startup_urls, | 589 const std::vector<GURL>& startup_urls, |
| 591 base::ListValue* referral_list, | 590 std::unique_ptr<base::ListValue> referral_list, |
| 592 IOThread* io_thread, | 591 IOThread* io_thread, |
| 593 ProfileIOData* profile_io_data) { | 592 ProfileIOData* profile_io_data) { |
| 594 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 593 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 595 | 594 |
| 596 profile_io_data_ = profile_io_data; | 595 profile_io_data_ = profile_io_data; |
| 597 initial_observer_.reset(new InitialObserver()); | 596 initial_observer_.reset(new InitialObserver()); |
| 598 | 597 |
| 599 net::URLRequestContext* context = | 598 net::URLRequestContext* context = |
| 600 url_request_context_getter_->GetURLRequestContext(); | 599 url_request_context_getter_->GetURLRequestContext(); |
| 601 transport_security_state_ = context->transport_security_state(); | 600 transport_security_state_ = context->transport_security_state(); |
| 602 ssl_config_service_ = context->ssl_config_service(); | 601 ssl_config_service_ = context->ssl_config_service(); |
| 603 proxy_service_ = context->proxy_service(); | 602 proxy_service_ = context->proxy_service(); |
| 604 | 603 |
| 605 // base::WeakPtrFactory instances need to be created and destroyed | 604 // base::WeakPtrFactory instances need to be created and destroyed |
| 606 // on the same thread. The predictor lives on the IO thread and will die | 605 // on the same thread. The predictor lives on the IO thread and will die |
| 607 // from there so now that we're on the IO thread we need to properly | 606 // from there so now that we're on the IO thread we need to properly |
| 608 // initialize the base::WeakPtrFactory. | 607 // initialize the base::WeakPtrFactory. |
| 609 // TODO(groby): Check if WeakPtrFactory has the same constraint. | 608 // TODO(groby): Check if WeakPtrFactory has the same constraint. |
| 610 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); | 609 weak_factory_.reset(new base::WeakPtrFactory<Predictor>(this)); |
| 611 | 610 |
| 612 // Prefetch these hostnames on startup. | 611 // Prefetch these hostnames on startup. |
| 613 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); | 612 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED); |
| 614 | 613 |
| 615 DeserializeReferrersThenDelete(referral_list); | 614 DeserializeReferrers(*referral_list); |
| 616 | 615 |
| 617 LogStartupMetrics(); | 616 LogStartupMetrics(); |
| 618 } | 617 } |
| 619 | 618 |
| 620 //----------------------------------------------------------------------------- | 619 //----------------------------------------------------------------------------- |
| 621 // This section intermingles prefetch results with actual browser HTTP | 620 // This section intermingles prefetch results with actual browser HTTP |
| 622 // network activity. It supports calculating of the benefit of a prefetch, as | 621 // network activity. It supports calculating of the benefit of a prefetch, as |
| 623 // well as recording what prefetched hostname resolutions might be potentially | 622 // well as recording what prefetched hostname resolutions might be potentially |
| 624 // helpful during the next chrome-startup. | 623 // helpful during the next chrome-startup. |
| 625 //----------------------------------------------------------------------------- | 624 //----------------------------------------------------------------------------- |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 } | 1225 } |
| 1227 | 1226 |
| 1228 void SimplePredictor::ShutdownOnUIThread() { | 1227 void SimplePredictor::ShutdownOnUIThread() { |
| 1229 SetShutdown(true); | 1228 SetShutdown(true); |
| 1230 } | 1229 } |
| 1231 | 1230 |
| 1232 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } | 1231 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
| 1233 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } | 1232 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
| 1234 | 1233 |
| 1235 } // namespace chrome_browser_net | 1234 } // namespace chrome_browser_net |
| OLD | NEW |