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> |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 urls, referral_list, | 226 urls, referral_list, |
227 io_thread, profile_io_data)); | 227 io_thread, profile_io_data)); |
228 } | 228 } |
229 | 229 |
230 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { | 230 void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { |
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
232 if (!predictor_enabled_) | 232 if (!predictor_enabled_) |
233 return; | 233 return; |
234 if (!url.is_valid() || !url.has_host()) | 234 if (!url.is_valid() || !url.has_host()) |
235 return; | 235 return; |
236 if (!CanPredictNetworkActionsUI()) | 236 if (!CanPreresolveAndPreconnect()) |
237 return; | 237 return; |
238 | 238 |
239 std::string host = url.HostNoBrackets(); | 239 std::string host = url.HostNoBrackets(); |
240 bool is_new_host_request = (host != last_omnibox_host_); | 240 bool is_new_host_request = (host != last_omnibox_host_); |
241 last_omnibox_host_ = host; | 241 last_omnibox_host_ = host; |
242 | 242 |
243 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); | 243 UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); |
244 base::TimeTicks now = base::TimeTicks::Now(); | 244 base::TimeTicks now = base::TimeTicks::Now(); |
245 | 245 |
246 if (preconnect_enabled_) { | 246 if (preconnect_enabled_) { |
(...skipping 16 matching lines...) Expand all Loading... |
263 // TODO(jar): Use an A/B test to optimize this. | 263 // TODO(jar): Use an A/B test to optimize this. |
264 const int kMinConsecutiveRequests = 8; | 264 const int kMinConsecutiveRequests = 8; |
265 if (consecutive_omnibox_preconnect_count_ >= kMinConsecutiveRequests) { | 265 if (consecutive_omnibox_preconnect_count_ >= kMinConsecutiveRequests) { |
266 // TODO(jar): Perhaps we should do a GET to leave the socket open in the | 266 // TODO(jar): Perhaps we should do a GET to leave the socket open in the |
267 // pool. Currently, we just do a connect, which MAY be reset if we | 267 // pool. Currently, we just do a connect, which MAY be reset if we |
268 // don't use it in 10 secondes!!! As a result, we may do more | 268 // don't use it in 10 secondes!!! As a result, we may do more |
269 // connections, and actually cost the server more than if we did a real | 269 // connections, and actually cost the server more than if we did a real |
270 // get with a fake request (/gen_204 might be the good path on Google). | 270 // get with a fake request (/gen_204 might be the good path on Google). |
271 const int kMaxSearchKeepaliveSeconds(10); | 271 const int kMaxSearchKeepaliveSeconds(10); |
272 if ((now - last_omnibox_preconnect_).InSeconds() < | 272 if ((now - last_omnibox_preconnect_).InSeconds() < |
273 kMaxSearchKeepaliveSeconds) | 273 kMaxSearchKeepaliveSeconds) |
274 return; // We've done a preconnect recently. | 274 return; // We've done a preconnect recently. |
275 last_omnibox_preconnect_ = now; | 275 last_omnibox_preconnect_ = now; |
276 const int kConnectionsNeeded = 1; | 276 const int kConnectionsNeeded = 1; |
277 PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation, | 277 PreconnectUrl( |
278 kConnectionsNeeded); | 278 CanonicalizeUrl(url), GURL(), motivation, kConnectionsNeeded); |
279 return; // Skip pre-resolution, since we'll open a connection. | 279 return; // Skip pre-resolution, since we'll open a connection. |
280 } | 280 } |
281 } else { | 281 } else { |
282 consecutive_omnibox_preconnect_count_ = 0; | 282 consecutive_omnibox_preconnect_count_ = 0; |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 // Fall through and consider pre-resolution. | 286 // Fall through and consider pre-resolution. |
287 | 287 |
288 // Omnibox tends to call in pairs (just a few milliseconds apart), and we | 288 // Omnibox tends to call in pairs (just a few milliseconds apart), and we |
(...skipping 13 matching lines...) Expand all Loading... |
302 CanonicalizeUrl(url), motivation)); | 302 CanonicalizeUrl(url), motivation)); |
303 } | 303 } |
304 | 304 |
305 void Predictor::PreconnectUrlAndSubresources(const GURL& url, | 305 void Predictor::PreconnectUrlAndSubresources(const GURL& url, |
306 const GURL& first_party_for_cookies) { | 306 const GURL& first_party_for_cookies) { |
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
308 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 308 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
309 if (!predictor_enabled_ || !preconnect_enabled_ || | 309 if (!predictor_enabled_ || !preconnect_enabled_ || |
310 !url.is_valid() || !url.has_host()) | 310 !url.is_valid() || !url.has_host()) |
311 return; | 311 return; |
312 | 312 if (!CanPreresolveAndPreconnect()) |
313 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 313 return; |
314 if (!CanPredictNetworkActionsUI()) | |
315 return; | |
316 } else { | |
317 if (!CanPredictNetworkActionsIO()) | |
318 return; | |
319 } | |
320 | 314 |
321 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); | 315 UrlInfo::ResolutionMotivation motivation(UrlInfo::EARLY_LOAD_MOTIVATED); |
322 const int kConnectionsNeeded = 1; | 316 const int kConnectionsNeeded = 1; |
323 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, | 317 PreconnectUrl(CanonicalizeUrl(url), first_party_for_cookies, |
324 motivation, kConnectionsNeeded); | 318 motivation, kConnectionsNeeded); |
325 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); | 319 PredictFrameSubresources(url.GetWithEmptyPath(), first_party_for_cookies); |
326 } | 320 } |
327 | 321 |
328 UrlList Predictor::GetPredictedUrlListAtStartup( | 322 UrlList Predictor::GetPredictedUrlListAtStartup( |
329 PrefService* user_prefs, | 323 PrefService* user_prefs, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 UrlInfo::ResolutionMotivation motivation) { | 460 UrlInfo::ResolutionMotivation motivation) { |
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
468 if (!url.has_host()) | 462 if (!url.has_host()) |
469 return; | 463 return; |
470 AppendToResolutionQueue(url, motivation); | 464 AppendToResolutionQueue(url, motivation); |
471 } | 465 } |
472 | 466 |
473 void Predictor::LearnFromNavigation(const GURL& referring_url, | 467 void Predictor::LearnFromNavigation(const GURL& referring_url, |
474 const GURL& target_url) { | 468 const GURL& target_url) { |
475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
476 if (!predictor_enabled_ || !CanPredictNetworkActionsIO()) | 470 if (!predictor_enabled_ || !CanPrefetchAndPrerender()) |
477 return; | 471 return; |
478 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); | 472 DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); |
479 DCHECK_NE(referring_url, GURL::EmptyGURL()); | 473 DCHECK_NE(referring_url, GURL::EmptyGURL()); |
480 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); | 474 DCHECK_EQ(target_url, Predictor::CanonicalizeUrl(target_url)); |
481 DCHECK_NE(target_url, GURL::EmptyGURL()); | 475 DCHECK_NE(target_url, GURL::EmptyGURL()); |
482 | 476 |
483 referrers_[referring_url].SuggestHost(target_url); | 477 referrers_[referring_url].SuggestHost(target_url); |
484 // Possibly do some referrer trimming. | 478 // Possibly do some referrer trimming. |
485 TrimReferrers(); | 479 TrimReferrers(); |
486 } | 480 } |
487 | 481 |
488 //----------------------------------------------------------------------------- | 482 //----------------------------------------------------------------------------- |
489 // This section supports the about:dns page. | 483 // This section supports the about:dns page. |
490 | 484 |
491 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, | 485 void Predictor::PredictorGetHtmlInfo(Predictor* predictor, |
492 std::string* output) { | 486 std::string* output) { |
493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
494 | 488 |
495 output->append("<html><head><title>About DNS</title>" | 489 output->append("<html><head><title>About DNS</title>" |
496 // We'd like the following no-cache... but it doesn't work. | 490 // We'd like the following no-cache... but it doesn't work. |
497 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" | 491 // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" |
498 "</head><body>"); | 492 "</head><body>"); |
499 if (predictor && predictor->predictor_enabled() && | 493 if (predictor && predictor->predictor_enabled() && |
500 predictor->CanPredictNetworkActionsIO()) { | 494 predictor->CanPrefetchAndPrerender()) { |
501 predictor->GetHtmlInfo(output); | 495 predictor->GetHtmlInfo(output); |
502 } else { | 496 } else { |
503 output->append("DNS pre-resolution and TCP pre-connection is disabled."); | 497 output->append("DNS pre-resolution and TCP pre-connection is disabled."); |
504 } | 498 } |
505 output->append("</body></html>"); | 499 output->append("</body></html>"); |
506 } | 500 } |
507 | 501 |
508 // Provide sort order so all .com's are together, etc. | 502 // Provide sort order so all .com's are together, etc. |
509 struct RightToLeftStringSorter { | 503 struct RightToLeftStringSorter { |
510 bool operator()(const GURL& left, const GURL& right) const { | 504 bool operator()(const GURL& left, const GURL& right) const { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 //----------------------------------------------------------------------------- | 715 //----------------------------------------------------------------------------- |
722 // This section intermingles prefetch results with actual browser HTTP | 716 // This section intermingles prefetch results with actual browser HTTP |
723 // network activity. It supports calculating of the benefit of a prefetch, as | 717 // network activity. It supports calculating of the benefit of a prefetch, as |
724 // well as recording what prefetched hostname resolutions might be potentially | 718 // well as recording what prefetched hostname resolutions might be potentially |
725 // helpful during the next chrome-startup. | 719 // helpful during the next chrome-startup. |
726 //----------------------------------------------------------------------------- | 720 //----------------------------------------------------------------------------- |
727 | 721 |
728 void Predictor::LearnAboutInitialNavigation(const GURL& url) { | 722 void Predictor::LearnAboutInitialNavigation(const GURL& url) { |
729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
730 if (!predictor_enabled_ || NULL == initial_observer_.get() || | 724 if (!predictor_enabled_ || NULL == initial_observer_.get() || |
731 !CanPredictNetworkActionsIO()) | 725 !CanPrefetchAndPrerender()) { |
732 return; | 726 return; |
| 727 } |
733 initial_observer_->Append(url, this); | 728 initial_observer_->Append(url, this); |
734 } | 729 } |
735 | 730 |
736 // This API is only used in the browser process. | 731 // This API is only used in the browser process. |
737 // It is called from an IPC message originating in the renderer. It currently | 732 // It is called from an IPC message originating in the renderer. It currently |
738 // includes both Page-Scan, and Link-Hover prefetching. | 733 // includes both Page-Scan, and Link-Hover prefetching. |
739 // TODO(jar): Separate out link-hover prefetching, and page-scan results. | 734 // TODO(jar): Separate out link-hover prefetching, and page-scan results. |
740 void Predictor::DnsPrefetchList(const NameList& hostnames) { | 735 void Predictor::DnsPrefetchList(const NameList& hostnames) { |
741 // TODO(jar): Push GURL transport further back into renderer, but this will | 736 // TODO(jar): Push GURL transport further back into renderer, but this will |
742 // require a Webkit change in the observer :-/. | 737 // require a Webkit change in the observer :-/. |
743 UrlList urls; | 738 UrlList urls; |
744 for (NameList::const_iterator it = hostnames.begin(); | 739 for (NameList::const_iterator it = hostnames.begin(); |
745 it < hostnames.end(); | 740 it < hostnames.end(); |
746 ++it) { | 741 ++it) { |
747 urls.push_back(GURL("http://" + *it + ":80")); | 742 urls.push_back(GURL("http://" + *it + ":80")); |
748 } | 743 } |
749 | 744 |
750 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
751 DnsPrefetchMotivatedList(urls, UrlInfo::PAGE_SCAN_MOTIVATED); | 746 DnsPrefetchMotivatedList(urls, UrlInfo::PAGE_SCAN_MOTIVATED); |
752 } | 747 } |
753 | 748 |
754 void Predictor::DnsPrefetchMotivatedList( | 749 void Predictor::DnsPrefetchMotivatedList( |
755 const UrlList& urls, | 750 const UrlList& urls, |
756 UrlInfo::ResolutionMotivation motivation) { | 751 UrlInfo::ResolutionMotivation motivation) { |
757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
758 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 753 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
759 if (!predictor_enabled_) | 754 if (!predictor_enabled_) |
760 return; | 755 return; |
761 | 756 if (!CanPrefetchAndPrerender()) |
762 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 757 return; |
763 if (!CanPredictNetworkActionsUI()) | |
764 return; | |
765 } else { | |
766 if (!CanPredictNetworkActionsIO()) | |
767 return; | |
768 } | |
769 | 758 |
770 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 759 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
771 ResolveList(urls, motivation); | 760 ResolveList(urls, motivation); |
772 } else { | 761 } else { |
773 BrowserThread::PostTask( | 762 BrowserThread::PostTask( |
774 BrowserThread::IO, | 763 BrowserThread::IO, |
775 FROM_HERE, | 764 FROM_HERE, |
776 base::Bind(&Predictor::ResolveList, base::Unretained(this), | 765 base::Bind(&Predictor::ResolveList, base::Unretained(this), |
777 urls, motivation)); | 766 urls, motivation)); |
778 } | 767 } |
(...skipping 14 matching lines...) Expand all Loading... |
793 completion->Signal(); | 782 completion->Signal(); |
794 return; | 783 return; |
795 } | 784 } |
796 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( | 785 predictor->SaveDnsPrefetchStateForNextStartupAndTrim( |
797 startup_list, referral_list, completion); | 786 startup_list, referral_list, completion); |
798 } | 787 } |
799 | 788 |
800 void Predictor::SaveStateForNextStartupAndTrim() { | 789 void Predictor::SaveStateForNextStartupAndTrim() { |
801 if (!predictor_enabled_) | 790 if (!predictor_enabled_) |
802 return; | 791 return; |
803 | 792 if (!CanPrefetchAndPrerender()) |
804 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 793 return; |
805 if (!CanPredictNetworkActionsUI()) | |
806 return; | |
807 } else { | |
808 if (!CanPredictNetworkActionsIO()) | |
809 return; | |
810 } | |
811 | 794 |
812 base::WaitableEvent completion(true, false); | 795 base::WaitableEvent completion(true, false); |
813 | 796 |
814 ListPrefUpdate update_startup_list(user_prefs_, | 797 ListPrefUpdate update_startup_list(user_prefs_, |
815 prefs::kDnsPrefetchingStartupList); | 798 prefs::kDnsPrefetchingStartupList); |
816 ListPrefUpdate update_referral_list(user_prefs_, | 799 ListPrefUpdate update_referral_list(user_prefs_, |
817 prefs::kDnsPrefetchingHostReferralList); | 800 prefs::kDnsPrefetchingHostReferralList); |
818 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 801 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
819 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( | 802 SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread( |
820 update_startup_list.Get(), | 803 update_startup_list.Get(), |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 count, | 882 count, |
900 url_request_context_getter_.get()); | 883 url_request_context_getter_.get()); |
901 } | 884 } |
902 | 885 |
903 void Predictor::PredictFrameSubresources(const GURL& url, | 886 void Predictor::PredictFrameSubresources(const GURL& url, |
904 const GURL& first_party_for_cookies) { | 887 const GURL& first_party_for_cookies) { |
905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 888 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
906 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 889 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
907 if (!predictor_enabled_) | 890 if (!predictor_enabled_) |
908 return; | 891 return; |
909 | 892 if (!CanPrefetchAndPrerender()) |
910 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 893 return; |
911 if (!CanPredictNetworkActionsUI()) | |
912 return; | |
913 } else { | |
914 if (!CanPredictNetworkActionsIO()) | |
915 return; | |
916 } | |
917 DCHECK_EQ(url.GetWithEmptyPath(), url); | 894 DCHECK_EQ(url.GetWithEmptyPath(), url); |
918 // Add one pass through the message loop to allow current navigation to | 895 // Add one pass through the message loop to allow current navigation to |
919 // proceed. | 896 // proceed. |
920 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 897 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
921 PrepareFrameSubresources(url, first_party_for_cookies); | 898 PrepareFrameSubresources(url, first_party_for_cookies); |
922 } else { | 899 } else { |
923 BrowserThread::PostTask( | 900 BrowserThread::PostTask( |
924 BrowserThread::IO, | 901 BrowserThread::IO, |
925 FROM_HERE, | 902 FROM_HERE, |
926 base::Bind(&Predictor::PrepareFrameSubresources, | 903 base::Bind(&Predictor::PrepareFrameSubresources, |
(...skipping 14 matching lines...) Expand all Loading... |
941 AdviseProxyOnIOThread(url, motivation, is_preconnect); | 918 AdviseProxyOnIOThread(url, motivation, is_preconnect); |
942 } else { | 919 } else { |
943 BrowserThread::PostTask( | 920 BrowserThread::PostTask( |
944 BrowserThread::IO, | 921 BrowserThread::IO, |
945 FROM_HERE, | 922 FROM_HERE, |
946 base::Bind(&Predictor::AdviseProxyOnIOThread, | 923 base::Bind(&Predictor::AdviseProxyOnIOThread, |
947 base::Unretained(this), url, motivation, is_preconnect)); | 924 base::Unretained(this), url, motivation, is_preconnect)); |
948 } | 925 } |
949 } | 926 } |
950 | 927 |
951 bool Predictor::CanPredictNetworkActionsUI() { | 928 bool Predictor::CanPrefetchAndPrerender() const { |
952 return chrome_browser_net::CanPredictNetworkActionsUI(user_prefs_); | 929 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 930 return chrome_browser_net::CanPrefetchAndPrerenderUI(user_prefs_); |
| 931 } else { |
| 932 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 933 return chrome_browser_net::CanPrefetchAndPrerenderIO(profile_io_data_); |
| 934 } |
953 } | 935 } |
954 | 936 |
955 bool Predictor::CanPredictNetworkActionsIO() { | 937 bool Predictor::CanPreresolveAndPreconnect() const { |
956 return chrome_browser_net::CanPredictNetworkActionsIO(profile_io_data_); | 938 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 939 return chrome_browser_net::CanPreresolveAndPreconnectUI(user_prefs_); |
| 940 } else { |
| 941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 942 return chrome_browser_net::CanPreresolveAndPreconnectIO(profile_io_data_); |
| 943 } |
957 } | 944 } |
958 | 945 |
959 enum SubresourceValue { | 946 enum SubresourceValue { |
960 PRECONNECTION, | 947 PRECONNECTION, |
961 PRERESOLUTION, | 948 PRERESOLUTION, |
962 TOO_NEW, | 949 TOO_NEW, |
963 SUBRESOURCE_VALUE_MAX | 950 SUBRESOURCE_VALUE_MAX |
964 }; | 951 }; |
965 | 952 |
966 void Predictor::PrepareFrameSubresources(const GURL& original_url, | 953 void Predictor::PrepareFrameSubresources(const GURL& original_url, |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 IOThread* io_thread, | 1325 IOThread* io_thread, |
1339 net::URLRequestContextGetter* getter, | 1326 net::URLRequestContextGetter* getter, |
1340 ProfileIOData* profile_io_data) { | 1327 ProfileIOData* profile_io_data) { |
1341 // Empty function for unittests. | 1328 // Empty function for unittests. |
1342 } | 1329 } |
1343 | 1330 |
1344 void SimplePredictor::ShutdownOnUIThread() { | 1331 void SimplePredictor::ShutdownOnUIThread() { |
1345 SetShutdown(true); | 1332 SetShutdown(true); |
1346 } | 1333 } |
1347 | 1334 |
1348 bool SimplePredictor::CanPredictNetworkActionsUI() { return true; } | 1335 bool SimplePredictor::CanPrefetchAndPrerender() const { return true; } |
1349 bool SimplePredictor::CanPredictNetworkActionsIO() { return true; } | 1336 bool SimplePredictor::CanPreresolveAndPreconnect() const { return true; } |
1350 | 1337 |
1351 } // namespace chrome_browser_net | 1338 } // namespace chrome_browser_net |
OLD | NEW |