Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: chrome/browser/net/predictor.cc

Issue 7467012: Modifying prefetch to account for multi-profile. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/synchronization/waitable_event.h"
15 #include "base/time.h" 16 #include "base/time.h"
16 #include "base/values.h" 17 #include "base/values.h"
17 #include "chrome/browser/net/preconnect.h" 18 #include "chrome/browser/net/preconnect.h"
19 #include "chrome/browser/prefs/pref_service.h"
20 #include "chrome/browser/prefs/scoped_user_pref_update.h"
21 #include "chrome/browser/prefs/session_startup_pref.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/common/pref_names.h"
18 #include "content/browser/browser_thread.h" 24 #include "content/browser/browser_thread.h"
19 #include "net/base/address_list.h" 25 #include "net/base/address_list.h"
20 #include "net/base/completion_callback.h" 26 #include "net/base/completion_callback.h"
21 #include "net/base/host_port_pair.h" 27 #include "net/base/host_port_pair.h"
22 #include "net/base/host_resolver.h" 28 #include "net/base/host_resolver.h"
23 #include "net/base/net_errors.h" 29 #include "net/base/net_errors.h"
24 #include "net/base/net_log.h" 30 #include "net/base/net_log.h"
25 #include "net/base/single_request_host_resolver.h" 31 #include "net/base/single_request_host_resolver.h"
26 32
27 using base::TimeDelta; 33 using base::TimeDelta;
28 34
29 namespace chrome_browser_net { 35 namespace chrome_browser_net {
30 36
37 static void DnsPrefetchMotivatedList(const UrlList& urls,
38 UrlInfo::ResolutionMotivation motivation);
31 // static 39 // static
32 const double Predictor::kPreconnectWorthyExpectedValue = 0.8; 40 const double Predictor::kPreconnectWorthyExpectedValue = 0.8;
33 // static 41 // static
34 const double Predictor::kDNSPreresolutionWorthyExpectedValue = 0.1; 42 const double Predictor::kDNSPreresolutionWorthyExpectedValue = 0.1;
35 // static 43 // static
36 const double Predictor::kDiscardableExpectedValue = 0.05; 44 const double Predictor::kDiscardableExpectedValue = 0.05;
37 // The goal is of trimming is to to reduce the importance (number of expected 45 // The goal is of trimming is to to reduce the importance (number of expected
38 // subresources needed) by a factor of 2 after about 24 hours of uptime. We will 46 // subresources needed) by a factor of 2 after about 24 hours of uptime. We will
39 // trim roughly once-an-hour of uptime. The ratio to use in each trim operation 47 // trim roughly once-an-hour of uptime. The ratio to use in each trim operation
40 // is then the 24th root of 0.5. If a user only surfs for 4 hours a day, then 48 // is then the 24th root of 0.5. If a user only surfs for 4 hours a day, then
41 // after about 6 days they will have halved all their estimates of subresource 49 // after about 6 days they will have halved all their estimates of subresource
42 // connections. Once this falls below kDiscardableExpectedValue the referrer 50 // connections. Once this falls below kDiscardableExpectedValue the referrer
43 // will be discarded. 51 // will be discarded.
44 // TODO(jar): Measure size of referrer lists in the field. Consider an adaptive 52 // TODO(jar): Measure size of referrer lists in the field. Consider an adaptive
45 // system that uses a higher trim ratio when the list is large. 53 // system that uses a higher trim ratio when the list is large.
46 // static 54 // static
47 const double Predictor::kReferrerTrimRatio = 0.97153; 55 const double Predictor::kReferrerTrimRatio = 0.97153;
48 56
49 // static 57 // static
50 const TimeDelta Predictor::kDurationBetweenTrimmings = TimeDelta::FromHours(1); 58 const TimeDelta Predictor::kDurationBetweenTrimmings = TimeDelta::FromHours(1);
51 // static 59 // static
52 const TimeDelta Predictor::kDurationBetweenTrimmingIncrements = 60 const TimeDelta Predictor::kDurationBetweenTrimmingIncrements =
53 TimeDelta::FromSeconds(15); 61 TimeDelta::FromSeconds(15);
54 // static 62 // static
55 const size_t Predictor::kUrlsTrimmedPerIncrement = 5u; 63 const size_t Predictor::kUrlsTrimmedPerIncrement = 5u;
56 64
65 // A version number for prefs that are saved. This should be incremented when
66 // we change the format so that we discard old data.
67 static const int kPredictorStartupFormatVersion = 1;
68
57 class Predictor::LookupRequest { 69 class Predictor::LookupRequest {
58 public: 70 public:
59 LookupRequest(Predictor* predictor, 71 LookupRequest(Predictor* predictor,
60 net::HostResolver* host_resolver, 72 net::HostResolver* host_resolver,
61 const GURL& url) 73 const GURL& url)
62 : ALLOW_THIS_IN_INITIALIZER_LIST( 74 : ALLOW_THIS_IN_INITIALIZER_LIST(
63 net_callback_(this, &LookupRequest::OnLookupFinished)), 75 net_callback_(this, &LookupRequest::OnLookupFinished)),
64 predictor_(predictor), 76 predictor_(predictor),
65 url_(url), 77 url_(url),
66 resolver_(host_resolver) { 78 resolver_(host_resolver) {
(...skipping 28 matching lines...) Expand all
95 const GURL url_; // Hostname to resolve. 107 const GURL url_; // Hostname to resolve.
96 net::SingleRequestHostResolver resolver_; 108 net::SingleRequestHostResolver resolver_;
97 net::AddressList addresses_; 109 net::AddressList addresses_;
98 110
99 DISALLOW_COPY_AND_ASSIGN(LookupRequest); 111 DISALLOW_COPY_AND_ASSIGN(LookupRequest);
100 }; 112 };
101 113
102 Predictor::Predictor(net::HostResolver* host_resolver, 114 Predictor::Predictor(net::HostResolver* host_resolver,
103 TimeDelta max_dns_queue_delay, 115 TimeDelta max_dns_queue_delay,
104 size_t max_concurrent, 116 size_t max_concurrent,
105 bool preconnect_enabled) 117 bool preconnect_enabled,
106 : peak_pending_lookups_(0), 118 bool predictor_enabled)
119 : predictor_enabled_(true),
120 off_the_record_windows_count_(0),
121 on_the_record_(true),
122 peak_pending_lookups_(0),
107 shutdown_(false), 123 shutdown_(false),
108 max_concurrent_dns_lookups_(max_concurrent), 124 max_concurrent_dns_lookups_(max_concurrent),
109 max_dns_queue_delay_(max_dns_queue_delay), 125 max_dns_queue_delay_(max_dns_queue_delay),
110 host_resolver_(host_resolver), 126 host_resolver_(host_resolver),
111 preconnect_enabled_(preconnect_enabled), 127 preconnect_enabled_(preconnect_enabled),
112 consecutive_omnibox_preconnect_count_(0), 128 consecutive_omnibox_preconnect_count_(0),
113 next_trim_time_(base::TimeTicks::Now() + kDurationBetweenTrimmings), 129 next_trim_time_(base::TimeTicks::Now() + kDurationBetweenTrimmings),
114 ALLOW_THIS_IN_INITIALIZER_LIST(trim_task_factory_(this)) { 130 ALLOW_THIS_IN_INITIALIZER_LIST(trim_task_factory_(this)) {
131 initial_observer_.reset(new InitialObserver());
115 } 132 }
116 133
117 Predictor::~Predictor() { 134 Predictor::~Predictor() {
118 DCHECK(shutdown_); 135 DCHECK(shutdown_);
119 } 136 }
120 137
121 void Predictor::Shutdown() { 138 void Predictor::Shutdown() {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
123 DCHECK(!shutdown_); 140 DCHECK(!shutdown_);
124 shutdown_ = true; 141 shutdown_ = true;
(...skipping 19 matching lines...) Expand all
144 UrlInfo::ResolutionMotivation motivation) { 161 UrlInfo::ResolutionMotivation motivation) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
146 if (!url.has_host()) 163 if (!url.has_host())
147 return; 164 return;
148 AppendToResolutionQueue(url, motivation); 165 AppendToResolutionQueue(url, motivation);
149 } 166 }
150 167
151 void Predictor::LearnFromNavigation(const GURL& referring_url, 168 void Predictor::LearnFromNavigation(const GURL& referring_url,
152 const GURL& target_url) { 169 const GURL& target_url) {
153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
171 if (!predictor_enabled_)
172 return;
154 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); 173 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url));
155 DCHECK_NE(referring_url, GURL::EmptyGURL()); 174 DCHECK_NE(referring_url, GURL::EmptyGURL());
156 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); 175 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url));
157 DCHECK_NE(target_url, GURL::EmptyGURL()); 176 DCHECK_NE(target_url, GURL::EmptyGURL());
158 177
159 referrers_[referring_url].SuggestHost(target_url); 178 referrers_[referring_url].SuggestHost(target_url);
160 // Possibly do some referrer trimming. 179 // Possibly do some referrer trimming.
161 TrimReferrers(); 180 TrimReferrers();
162 } 181 }
163 182
164 enum SubresourceValue { 183 enum SubresourceValue {
165 PRECONNECTION, 184 PRECONNECTION,
166 PRERESOLUTION, 185 PRERESOLUTION,
167 TOO_NEW, 186 TOO_NEW,
168 SUBRESOURCE_VALUE_MAX 187 SUBRESOURCE_VALUE_MAX
169 }; 188 };
170 189
171 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { 190 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
192 if (!predictor_enabled_)
193 return;
194 if (!url.is_valid() || !url.has_host())
195 return;
172 std::string host = url.HostNoBrackets(); 196 std::string host = url.HostNoBrackets();
173 bool is_new_host_request = (host != last_omnibox_host_); 197 bool is_new_host_request = (host != last_omnibox_host_);
174 last_omnibox_host_ = host; 198 last_omnibox_host_ = host;
175 199
176 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); 200 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED);
177 base::TimeTicks now = base::TimeTicks::Now(); 201 base::TimeTicks now = base::TimeTicks::Now();
178 202
179 if (preconnect_enabled()) { 203 if (preconnect_enabled()) {
180 if (preconnectable && !is_new_host_request) { 204 if (preconnectable && !is_new_host_request) {
181 ++consecutive_omnibox_preconnect_count_; 205 ++consecutive_omnibox_preconnect_count_;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 254
231 // Perform at least DNS pre-resolution. 255 // Perform at least DNS pre-resolution.
232 BrowserThread::PostTask( 256 BrowserThread::PostTask(
233 BrowserThread::IO, 257 BrowserThread::IO,
234 FROM_HERE, 258 FROM_HERE,
235 NewRunnableMethod(this, &Predictor::Resolve, CanonicalizeUrl(url), 259 NewRunnableMethod(this, &Predictor::Resolve, CanonicalizeUrl(url),
236 motivation)); 260 motivation));
237 } 261 }
238 262
239 void Predictor::PreconnectUrlAndSubresources(const GURL& url) { 263 void Predictor::PreconnectUrlAndSubresources(const GURL& url) {
264 if (!predictor_enabled_)
265 return;
266 if (!url.is_valid() || !url.has_host())
267 return;
240 if (preconnect_enabled()) { 268 if (preconnect_enabled()) {
241 std::string host = url.HostNoBrackets(); 269 std::string host = url.HostNoBrackets();
242 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); 270 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED);
243 const int kConnectionsNeeded = 1; 271 const int kConnectionsNeeded = 1;
244 PreconnectOnUIThread(CanonicalizeUrl(url), motivation, 272 PreconnectOnUIThread(CanonicalizeUrl(url), motivation,
245 kConnectionsNeeded); 273 kConnectionsNeeded);
246 PredictFrameSubresources(url.GetWithEmptyPath()); 274 PredictFrameSubresources(url.GetWithEmptyPath());
247 } 275 }
248 } 276 }
249 277
250 void Predictor::PredictFrameSubresources(const GURL& url) { 278 void Predictor::PredictFrameSubresources(const GURL& url) {
279 if (!predictor_enabled_)
280 return;
251 DCHECK_EQ(url.GetWithEmptyPath(), url); 281 DCHECK_EQ(url.GetWithEmptyPath(), url);
252 // Add one pass through the message loop to allow current navigation to 282 // Add one pass through the message loop to allow current navigation to
253 // proceed. 283 // proceed.
254 BrowserThread::PostTask( 284 BrowserThread::PostTask(
255 BrowserThread::IO, 285 BrowserThread::IO,
256 FROM_HERE, 286 FROM_HERE,
257 NewRunnableMethod(this, &Predictor::PrepareFrameSubresources, url)); 287 NewRunnableMethod(this, &Predictor::PrepareFrameSubresources, url));
258 } 288 }
259 289
260 void Predictor::PrepareFrameSubresources(const GURL& url) { 290 void Predictor::PrepareFrameSubresources(const GURL& url) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 static_cast<int>(future_url->second.preresolution_count()), 446 static_cast<int>(future_url->second.preresolution_count()),
417 static_cast<double>(future_url->second.subresource_use_rate()), 447 static_cast<double>(future_url->second.subresource_use_rate()),
418 future_url->first.spec().c_str()); 448 future_url->first.spec().c_str());
419 } 449 }
420 } 450 }
421 output->append("</table>"); 451 output->append("</table>");
422 } 452 }
423 453
424 void Predictor::GetHtmlInfo(std::string* output) { 454 void Predictor::GetHtmlInfo(std::string* output) {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
456 if (initial_observer_.get())
457 initial_observer_->GetFirstResolutionsHtml(output);
458 // Show list of subresource predictions and stats.
459 GetHtmlReferrerLists(output);
460
426 // Local lists for calling UrlInfo 461 // Local lists for calling UrlInfo
427 UrlInfo::UrlInfoTable name_not_found; 462 UrlInfo::UrlInfoTable name_not_found;
428 UrlInfo::UrlInfoTable name_preresolved; 463 UrlInfo::UrlInfoTable name_preresolved;
429 464
430 // Get copies of all useful data. 465 // Get copies of all useful data.
431 typedef std::map<GURL, UrlInfo, RightToLeftStringSorter> SortedUrlInfo; 466 typedef std::map<GURL, UrlInfo, RightToLeftStringSorter> SortedUrlInfo;
432 SortedUrlInfo snapshot; 467 SortedUrlInfo snapshot;
433 // UrlInfo supports value semantics, so we can do a shallow copy. 468 // UrlInfo supports value semantics, so we can do a shallow copy.
434 for (Results::iterator it(results_.begin()); it != results_.end(); it++) 469 for (Results::iterator it(results_.begin()); it != results_.end(); it++)
435 snapshot[it->first] = it->second; 470 snapshot[it->first] = it->second;
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 Referrers::iterator it = referrers_.find(urls_being_trimmed_.back()); 731 Referrers::iterator it = referrers_.find(urls_being_trimmed_.back());
697 urls_being_trimmed_.pop_back(); 732 urls_being_trimmed_.pop_back();
698 if (it == referrers_.end()) 733 if (it == referrers_.end())
699 continue; // Defensive code: It got trimmed away already. 734 continue; // Defensive code: It got trimmed away already.
700 if (!it->second.Trim(kReferrerTrimRatio, kDiscardableExpectedValue)) 735 if (!it->second.Trim(kReferrerTrimRatio, kDiscardableExpectedValue))
701 referrers_.erase(it); 736 referrers_.erase(it);
702 } 737 }
703 PostIncrementalTrimTask(); 738 PostIncrementalTrimTask();
704 } 739 }
705 740
741 void Predictor::DiscardInitialNavigationHistory() {
742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
743 if (initial_observer_.get())
744 initial_observer_->DiscardInitialNavigationHistory();
745 }
746
747 void Predictor::FinalizeInitialization(
748 const UrlList& startup_urls,
749 ListValue* referral_list) {
750 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
751
752 // Prefetch these hostnames on startup.
753 DnsPrefetchMotivatedList(startup_urls, UrlInfo::STARTUP_LIST_MOTIVATED);
754 DeserializeReferrersThenDelete(referral_list);
755 }
756
757 //------------------------------------------------------------------------------
758 // This section intermingles prefetch results with actual browser HTTP
759 // network activity. It supports calculating of the benefit of a prefetch, as
760 // well as recording what prefetched hostname resolutions might be potentially
761 // helpful during the next chrome-startup.
762 //------------------------------------------------------------------------------
763
764 void Predictor::LearnAboutInitialNavigation(const GURL& url) {
765 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
766 if (!predictor_enabled_ || NULL == initial_observer_.get() )
767 return;
768 initial_observer_->Append(url, this);
769 }
770
771 // This API is only used in the browser process.
772 // It is called from an IPC message originating in the renderer. It currently
773 // includes both Page-Scan, and Link-Hover prefetching.
774 // TODO(jar): Separate out link-hover prefetching, and page-scan results.
775 void Predictor::DnsPrefetchList(const NameList& hostnames) {
776 // TODO(jar): Push GURL transport further back into renderer, but this will
777 // require a Webkit change in the observer :-/.
778 UrlList urls;
779 for (NameList::const_iterator it = hostnames.begin();
780 it < hostnames.end();
781 ++it) {
782 urls.push_back(GURL("http://" + *it + ":80"));
783 }
784
785 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
786 DnsPrefetchMotivatedList(urls, UrlInfo::PAGE_SCAN_MOTIVATED);
787 }
788
789 void Predictor::DnsPrefetchMotivatedList(
790 const UrlList& urls,
791 UrlInfo::ResolutionMotivation motivation) {
792 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
793 BrowserThread::CurrentlyOn(BrowserThread::IO));
794 if (!predictor_enabled_)
795 return;
796
797 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
798 ResolveList(urls, motivation);
799 } else {
800 BrowserThread::PostTask(
801 BrowserThread::IO,
802 FROM_HERE,
803 NewRunnableMethod(this, &Predictor::ResolveList, urls, motivation));
804 }
805 }
806
807 //------------------------------------------------------------------------------
808 // Functions to handle saving of hostnames from one session to the next, to
809 // expedite startup times.
810
811 static void SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
812 ListValue* startup_list,
813 ListValue* referral_list,
814 base::WaitableEvent* completion,
815 Profile* profile) {
816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
817
818 if (NULL == profile->GetPredictor()) {
819 completion->Signal();
820 return;
821 }
822 profile->GetPredictor()->SaveDnsPrefetchStateForNextStartupAndTrim(
823 startup_list, referral_list, completion);
824 }
825
826 void Predictor::SaveDnsPrefetchStateForNextStartupAndTrim(
827 ListValue* startup_list,
828 ListValue* referral_list,
829 base::WaitableEvent* completion) {
830 if (initial_observer_.get())
831 initial_observer_->GetInitialDnsResolutionList(startup_list);
832
833 // Do at least one trim at shutdown, in case the user wasn't running long
834 // enough to do any regular trimming of referrers.
835 TrimReferrersNow();
836 SerializeReferrers(referral_list);
837
838 completion->Signal();
839 }
840
841 void Predictor::SaveStateForNextStartupAndTrim(PrefService* prefs,
842 Profile* profile) {
843 if (!predictor_enabled_)
844 return;
845
846 base::WaitableEvent completion(true, false);
847
848 ListPrefUpdate update_startup_list(prefs, prefs::kDnsPrefetchingStartupList);
849 ListPrefUpdate update_referral_list(prefs,
850 prefs::kDnsPrefetchingHostReferralList);
851 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
852 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread(
853 update_startup_list.Get(),
854 update_referral_list.Get(),
855 &completion,
856 profile);
857 } else {
858 bool posted = BrowserThread::PostTask(
859 BrowserThread::IO,
860 FROM_HERE,
861 NewRunnableFunction(
862 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread,
863 update_startup_list.Get(),
864 update_referral_list.Get(),
865 &completion,
866 profile));
867
868 // TODO(jar): Synchronous waiting for the IO thread is a potential source
869 // to deadlocks and should be investigated. See http://crbug.com/78451.
870 DCHECK(posted);
871 if (posted)
872 completion.Wait();
873 }
874 }
875
876 UrlList Predictor::GetPredictedUrlListAtStartup(
877 PrefService* user_prefs,
878 PrefService* local_state) {
879 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
880 UrlList urls;
881 // Recall list of URLs we learned about during last session.
882 // This may catch secondary hostnames, pulled in by the homepages. It will
883 // also catch more of the "primary" home pages, since that was (presumably)
884 // rendered first (and will be rendered first this time too).
885 const ListValue* startup_list =
886 user_prefs->GetList(prefs::kDnsPrefetchingStartupList);
887
888 if (startup_list) {
889 ListValue::const_iterator it = startup_list->begin();
890 int format_version = -1;
891 if (it != startup_list->end() &&
892 (*it)->GetAsInteger(&format_version) &&
893 format_version == kPredictorStartupFormatVersion) {
894 ++it;
895 for (; it != startup_list->end(); ++it) {
896 std::string url_spec;
897 if (!(*it)->GetAsString(&url_spec)) {
898 LOG(DFATAL);
899 break; // Format incompatibility.
900 }
901 GURL url(url_spec);
902 if (!url.has_host() || !url.has_scheme()) {
903 LOG(DFATAL);
904 break; // Format incompatibility.
905 }
906
907 urls.push_back(url);
908 }
909 }
910 }
911
912 // Prepare for any static home page(s) the user has in prefs. The user may
913 // have a LOT of tab's specified, so we may as well try to warm them all.
914 SessionStartupPref tab_start_pref =
915 SessionStartupPref::GetStartupPref(user_prefs);
916 if (SessionStartupPref::URLS == tab_start_pref.type) {
917 for (size_t i = 0; i < tab_start_pref.urls.size(); i++) {
918 GURL gurl = tab_start_pref.urls[i];
919 if (!gurl.is_valid() || gurl.SchemeIsFile() || gurl.host().empty())
920 continue;
921 if (gurl.SchemeIs("http") || gurl.SchemeIs("https"))
922 urls.push_back(gurl.GetWithEmptyPath());
923 }
924 }
925
926 if (urls.empty())
927 urls.push_back(GURL("http://www.google.com:80"));
928
929 return urls;
930 }
931
932 bool Predictor::HandleIncognitoBrowserClosed() {
933 DCHECK_LT(0, off_the_record_windows_count_);
934 if (0 >= off_the_record_windows_count_) // Defensive coding.
935 return false;
936 if (--off_the_record_windows_count_)
937 return false; // Still some windows are incognito.
938 return true;
939 }
940
941 void Predictor::HandleIncognitoBrowserOpened() {
942 off_the_record_windows_count_++;
943 }
944
706 //------------------------------------------------------------------------------ 945 //------------------------------------------------------------------------------
707 946
708 Predictor::HostNameQueue::HostNameQueue() { 947 Predictor::HostNameQueue::HostNameQueue() {
709 } 948 }
710 949
711 Predictor::HostNameQueue::~HostNameQueue() { 950 Predictor::HostNameQueue::~HostNameQueue() {
712 } 951 }
713 952
714 void Predictor::HostNameQueue::Push(const GURL& url, 953 void Predictor::HostNameQueue::Push(const GURL& url,
715 UrlInfo::ResolutionMotivation motivation) { 954 UrlInfo::ResolutionMotivation motivation) {
(...skipping 21 matching lines...) Expand all
737 GURL url(queue->front()); 976 GURL url(queue->front());
738 queue->pop(); 977 queue->pop();
739 return url; 978 return url;
740 } 979 }
741 980
742 void Predictor::DeserializeReferrersThenDelete(ListValue* referral_list) { 981 void Predictor::DeserializeReferrersThenDelete(ListValue* referral_list) {
743 DeserializeReferrers(*referral_list); 982 DeserializeReferrers(*referral_list);
744 delete referral_list; 983 delete referral_list;
745 } 984 }
746 985
986 //------------------------------------------------------------------------------
987 // Member definitions for InitialObserver class.
988
989 void Predictor::InitialObserver::Append(const GURL& url,
990 Predictor* predictor) {
991 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
992
993 // TODO(rlp): Do we really need the predictor check here?
994 if (!predictor->on_the_record() || NULL == predictor)
995 return;
996 if (kStartupResolutionCount <= first_navigations_.size())
997 return;
998
999 DCHECK(url.SchemeIs("http") || url.SchemeIs("https"));
1000 DCHECK_EQ(url, Predictor::CanonicalizeUrl(url));
1001 if (first_navigations_.find(url) == first_navigations_.end())
1002 first_navigations_[url] = base::TimeTicks::Now();
1003 }
1004
1005 void Predictor::InitialObserver::GetInitialDnsResolutionList(
1006 ListValue* startup_list) {
1007 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1008 DCHECK(startup_list);
1009 startup_list->Clear();
1010 DCHECK_EQ(0u, startup_list->GetSize());
1011 startup_list->Append(new FundamentalValue(kPredictorStartupFormatVersion));
1012 for (FirstNavigations::iterator it = first_navigations_.begin();
1013 it != first_navigations_.end();
1014 ++it) {
1015 DCHECK(it->first == Predictor::CanonicalizeUrl(it->first));
1016 startup_list->Append(new StringValue(it->first.spec()));
1017 }
1018 }
1019
1020 void Predictor::InitialObserver::GetFirstResolutionsHtml(
1021 std::string* output) {
1022 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1023
1024 UrlInfo::UrlInfoTable resolution_list;
1025 {
1026 for (FirstNavigations::iterator it(first_navigations_.begin());
1027 it != first_navigations_.end();
1028 it++) {
1029 UrlInfo info;
1030 info.SetUrl(it->first);
1031 info.set_time(it->second);
1032 resolution_list.push_back(info);
1033 }
1034 }
1035 UrlInfo::GetHtmlTable(resolution_list,
1036 "Future startups will prefetch DNS records for ", false, output);
1037 }
747 1038
748 //------------------------------------------------------------------------------ 1039 //------------------------------------------------------------------------------
749 // Helper functions 1040 // Helper functions
750 //------------------------------------------------------------------------------ 1041 //------------------------------------------------------------------------------
751 1042
752 // static 1043 // static
753 GURL Predictor::CanonicalizeUrl(const GURL& url) { 1044 GURL Predictor::CanonicalizeUrl(const GURL& url) {
754 if (!url.has_host()) 1045 if (!url.has_host())
755 return GURL::EmptyGURL(); 1046 return GURL::EmptyGURL();
756 1047
(...skipping 11 matching lines...) Expand all
768 // If we omit a port, it will default to 80 or 443 as appropriate. 1059 // If we omit a port, it will default to 80 or 443 as appropriate.
769 std::string colon_plus_port; 1060 std::string colon_plus_port;
770 if (url.has_port()) 1061 if (url.has_port())
771 colon_plus_port = ":" + url.port(); 1062 colon_plus_port = ":" + url.port();
772 1063
773 return GURL(scheme + "://" + url.host() + colon_plus_port); 1064 return GURL(scheme + "://" + url.host() + colon_plus_port);
774 } 1065 }
775 1066
776 1067
777 } // namespace chrome_browser_net 1068 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698