| 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/prerender/prerender_manager.h" | 5 #include "chrome/browser/prerender/prerender_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <functional> | 10 #include <functional> |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 last_recorded_profile_network_bytes_(0), | 175 last_recorded_profile_network_bytes_(0), |
| 176 clock_(new base::DefaultClock()), | 176 clock_(new base::DefaultClock()), |
| 177 tick_clock_(new base::DefaultTickClock()), | 177 tick_clock_(new base::DefaultTickClock()), |
| 178 weak_factory_(this) { | 178 weak_factory_(this) { |
| 179 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 179 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 180 | 180 |
| 181 last_prerender_start_time_ = | 181 last_prerender_start_time_ = |
| 182 GetCurrentTimeTicks() - | 182 GetCurrentTimeTicks() - |
| 183 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); | 183 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); |
| 184 | 184 |
| 185 // Certain experiments override our default config_ values. | |
| 186 switch (PrerenderManager::GetMode()) { | |
| 187 case PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP: | |
| 188 config_.max_link_concurrency = 4; | |
| 189 config_.max_link_concurrency_per_launcher = 2; | |
| 190 break; | |
| 191 case PrerenderManager::PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP: | |
| 192 config_.time_to_live = base::TimeDelta::FromMinutes(15); | |
| 193 break; | |
| 194 default: | |
| 195 break; | |
| 196 } | |
| 197 | |
| 198 notification_registrar_.Add( | 185 notification_registrar_.Add( |
| 199 this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 186 this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 200 content::Source<Profile>(profile_)); | 187 content::Source<Profile>(profile_)); |
| 201 | 188 |
| 202 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); | 189 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); |
| 203 } | 190 } |
| 204 | 191 |
| 205 PrerenderManager::~PrerenderManager() { | 192 PrerenderManager::~PrerenderManager() { |
| 206 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); | 193 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); |
| 207 | 194 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // If the prerendered page is in the middle of a cross-site navigation, | 427 // If the prerendered page is in the middle of a cross-site navigation, |
| 441 // don't swap it in because there isn't a good way to merge histories. | 428 // don't swap it in because there isn't a good way to merge histories. |
| 442 if (prerender_data->contents()->IsCrossSiteNavigationPending()) { | 429 if (prerender_data->contents()->IsCrossSiteNavigationPending()) { |
| 443 histograms_->RecordFinalStatus(prerender_data->contents()->origin(), | 430 histograms_->RecordFinalStatus(prerender_data->contents()->origin(), |
| 444 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); | 431 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); |
| 445 prerender_data->contents()->Destroy( | 432 prerender_data->contents()->Destroy( |
| 446 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); | 433 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); |
| 447 return nullptr; | 434 return nullptr; |
| 448 } | 435 } |
| 449 | 436 |
| 450 // For bookkeeping purposes, we need to mark this WebContents to | |
| 451 // reflect that it would have been prerendered. | |
| 452 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { | |
| 453 target_tab_helper->WouldHavePrerenderedNextLoad( | |
| 454 prerender_data->contents()->origin()); | |
| 455 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); | |
| 456 return nullptr; | |
| 457 } | |
| 458 | |
| 459 // At this point, we've determined that we will use the prerender. | 437 // At this point, we've determined that we will use the prerender. |
| 460 content::RenderProcessHost* process_host = | 438 content::RenderProcessHost* process_host = |
| 461 prerender_data->contents()->GetRenderViewHost()->GetProcess(); | 439 prerender_data->contents()->GetRenderViewHost()->GetProcess(); |
| 462 process_host->RemoveObserver(this); | 440 process_host->RemoveObserver(this); |
| 463 prerender_process_hosts_.erase(process_host); | 441 prerender_process_hosts_.erase(process_host); |
| 464 if (!prerender_data->contents()->load_start_time().is_null()) { | 442 if (!prerender_data->contents()->load_start_time().is_null()) { |
| 465 histograms_->RecordTimeUntilUsed( | 443 histograms_->RecordTimeUntilUsed( |
| 466 prerender_data->contents()->origin(), | 444 prerender_data->contents()->origin(), |
| 467 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time()); | 445 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time()); |
| 468 } | 446 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 void PrerenderManager::SetMode(PrerenderManagerMode mode) { | 602 void PrerenderManager::SetMode(PrerenderManagerMode mode) { |
| 625 mode_ = mode; | 603 mode_ = mode; |
| 626 } | 604 } |
| 627 | 605 |
| 628 // static | 606 // static |
| 629 bool PrerenderManager::IsPrerenderingPossible() { | 607 bool PrerenderManager::IsPrerenderingPossible() { |
| 630 return GetMode() != PRERENDER_MODE_DISABLED; | 608 return GetMode() != PRERENDER_MODE_DISABLED; |
| 631 } | 609 } |
| 632 | 610 |
| 633 // static | 611 // static |
| 634 bool PrerenderManager::ActuallyPrerendering() { | |
| 635 return IsPrerenderingPossible() && !IsControlGroup(); | |
| 636 } | |
| 637 | |
| 638 // static | |
| 639 bool PrerenderManager::IsControlGroup() { | |
| 640 return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; | |
| 641 } | |
| 642 | |
| 643 // static | |
| 644 bool PrerenderManager::IsNoUseGroup() { | |
| 645 return GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP; | |
| 646 } | |
| 647 | |
| 648 // static | |
| 649 bool PrerenderManager::IsNoStatePrefetch() { | 612 bool PrerenderManager::IsNoStatePrefetch() { |
| 650 return GetMode() == PRERENDER_MODE_NOSTATE_PREFETCH; | 613 return GetMode() == PRERENDER_MODE_NOSTATE_PREFETCH; |
| 651 } | 614 } |
| 652 | 615 |
| 653 bool PrerenderManager::IsWebContentsPrerendering( | 616 bool PrerenderManager::IsWebContentsPrerendering( |
| 654 const WebContents* web_contents, | 617 const WebContents* web_contents, |
| 655 Origin* origin) const { | 618 Origin* origin) const { |
| 656 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 619 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 657 PrerenderContents* prerender_contents = GetPrerenderContents(web_contents); | 620 PrerenderContents* prerender_contents = GetPrerenderContents(web_contents); |
| 658 if (!prerender_contents) | 621 if (!prerender_contents) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 GetPredictionStatus() == NetworkPredictionStatus::ENABLED); | 752 GetPredictionStatus() == NetworkPredictionStatus::ENABLED); |
| 790 std::string disabled_note; | 753 std::string disabled_note; |
| 791 if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_ALWAYS) | 754 if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_ALWAYS) |
| 792 disabled_note = "Disabled by user setting"; | 755 disabled_note = "Disabled by user setting"; |
| 793 if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) | 756 if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) |
| 794 disabled_note = "Disabled on cellular connection by default"; | 757 disabled_note = "Disabled on cellular connection by default"; |
| 795 dict_value->SetString("disabled_note", disabled_note); | 758 dict_value->SetString("disabled_note", disabled_note); |
| 796 dict_value->SetBoolean("omnibox_enabled", IsOmniboxEnabled(profile_)); | 759 dict_value->SetBoolean("omnibox_enabled", IsOmniboxEnabled(profile_)); |
| 797 // If prerender is disabled via a flag this method is not even called. | 760 // If prerender is disabled via a flag this method is not even called. |
| 798 std::string enabled_note; | 761 std::string enabled_note; |
| 799 if (IsControlGroup()) | |
| 800 enabled_note += "(Control group: Not actually prerendering) "; | |
| 801 if (IsNoUseGroup()) | |
| 802 enabled_note += "(No-use group: Not swapping in prerendered pages) "; | |
| 803 if (GetMode() == PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP) { | |
| 804 enabled_note += | |
| 805 "(15 min TTL group: Extended prerender eviction to 15 mins) "; | |
| 806 } | |
| 807 dict_value->SetString("enabled_note", enabled_note); | 762 dict_value->SetString("enabled_note", enabled_note); |
| 808 return dict_value; | 763 return dict_value; |
| 809 } | 764 } |
| 810 | 765 |
| 811 void PrerenderManager::ClearData(int clear_flags) { | 766 void PrerenderManager::ClearData(int clear_flags) { |
| 812 DCHECK_GE(clear_flags, 0); | 767 DCHECK_GE(clear_flags, 0); |
| 813 DCHECK_LT(clear_flags, CLEAR_MAX); | 768 DCHECK_LT(clear_flags, CLEAR_MAX); |
| 814 if (clear_flags & CLEAR_PRERENDER_CONTENTS) | 769 if (clear_flags & CLEAR_PRERENDER_CONTENTS) |
| 815 DestroyAllContents(FINAL_STATUS_CACHE_OR_HISTORY_CLEARED); | 770 DestroyAllContents(FINAL_STATUS_CACHE_OR_HISTORY_CLEARED); |
| 816 // This has to be second, since destroying prerenders can add to the history. | 771 // This has to be second, since destroying prerenders can add to the history. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN) && | 876 origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN) && |
| 922 IsGoogleSearchResultURL(referrer.url)) { | 877 IsGoogleSearchResultURL(referrer.url)) { |
| 923 origin = ORIGIN_GWS_PRERENDER; | 878 origin = ORIGIN_GWS_PRERENDER; |
| 924 } | 879 } |
| 925 | 880 |
| 926 if (IsPrerenderSilenceExperiment(origin)) | 881 if (IsPrerenderSilenceExperiment(origin)) |
| 927 return nullptr; | 882 return nullptr; |
| 928 | 883 |
| 929 GURL url = url_arg; | 884 GURL url = url_arg; |
| 930 GURL alias_url; | 885 GURL alias_url; |
| 931 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) | |
| 932 url = alias_url; | |
| 933 | 886 |
| 934 // From here on, we will record a FinalStatus so we need to register with the | 887 // From here on, we will record a FinalStatus so we need to register with the |
| 935 // histogram tracking. | 888 // histogram tracking. |
| 936 histograms_->RecordPrerender(origin, url_arg); | 889 histograms_->RecordPrerender(origin, url_arg); |
| 937 | 890 |
| 938 if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies) && | 891 if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies) && |
| 939 origin != ORIGIN_OFFLINE) { | 892 origin != ORIGIN_OFFLINE) { |
| 940 RecordFinalStatusWithoutCreatingPrerenderContents( | 893 RecordFinalStatusWithoutCreatingPrerenderContents( |
| 941 url, origin, FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES); | 894 url, origin, FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES); |
| 942 return nullptr; | 895 return nullptr; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 SortActivePrerenders(); | 969 SortActivePrerenders(); |
| 1017 | 970 |
| 1018 last_prerender_start_time_ = GetCurrentTimeTicks(); | 971 last_prerender_start_time_ = GetCurrentTimeTicks(); |
| 1019 | 972 |
| 1020 gfx::Rect contents_bounds = | 973 gfx::Rect contents_bounds = |
| 1021 bounds.IsEmpty() ? config_.default_tab_bounds : bounds; | 974 bounds.IsEmpty() ? config_.default_tab_bounds : bounds; |
| 1022 | 975 |
| 1023 prerender_contents_ptr->StartPrerendering(contents_bounds, | 976 prerender_contents_ptr->StartPrerendering(contents_bounds, |
| 1024 session_storage_namespace); | 977 session_storage_namespace); |
| 1025 | 978 |
| 1026 DCHECK(IsControlGroup() || | 979 DCHECK(prerender_contents_ptr->prerendering_has_started()); |
| 1027 prerender_contents_ptr->prerendering_has_started()); | |
| 1028 | |
| 1029 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP) | |
| 1030 histograms_->RecordConcurrency(active_prerenders_.size()); | |
| 1031 | 980 |
| 1032 StartSchedulingPeriodicCleanups(); | 981 StartSchedulingPeriodicCleanups(); |
| 1033 return prerender_handle; | 982 return prerender_handle; |
| 1034 } | 983 } |
| 1035 | 984 |
| 1036 void PrerenderManager::StartSchedulingPeriodicCleanups() { | 985 void PrerenderManager::StartSchedulingPeriodicCleanups() { |
| 1037 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 986 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1038 if (repeating_timer_.IsRunning()) | 987 if (repeating_timer_.IsRunning()) |
| 1039 return; | 988 return; |
| 1040 repeating_timer_.Start(FROM_HERE, | 989 repeating_timer_.Start(FROM_HERE, |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 PrerenderContents* prerender_contents = GetPrerenderContents(tab); | 1231 PrerenderContents* prerender_contents = GetPrerenderContents(tab); |
| 1283 if (!prerender_contents) | 1232 if (!prerender_contents) |
| 1284 return; | 1233 return; |
| 1285 | 1234 |
| 1286 prerender_contents->Destroy(FINAL_STATUS_CREATING_AUDIO_STREAM); | 1235 prerender_contents->Destroy(FINAL_STATUS_CREATING_AUDIO_STREAM); |
| 1287 } | 1236 } |
| 1288 | 1237 |
| 1289 void PrerenderManager::RecordNetworkBytes(Origin origin, | 1238 void PrerenderManager::RecordNetworkBytes(Origin origin, |
| 1290 bool used, | 1239 bool used, |
| 1291 int64_t prerender_bytes) { | 1240 int64_t prerender_bytes) { |
| 1292 if (!ActuallyPrerendering()) | 1241 if (!IsPrerenderingPossible()) |
| 1293 return; | 1242 return; |
| 1294 int64_t recent_profile_bytes = | 1243 int64_t recent_profile_bytes = |
| 1295 profile_network_bytes_ - last_recorded_profile_network_bytes_; | 1244 profile_network_bytes_ - last_recorded_profile_network_bytes_; |
| 1296 last_recorded_profile_network_bytes_ = profile_network_bytes_; | 1245 last_recorded_profile_network_bytes_ = profile_network_bytes_; |
| 1297 DCHECK_GE(recent_profile_bytes, 0); | 1246 DCHECK_GE(recent_profile_bytes, 0); |
| 1298 histograms_->RecordNetworkBytes( | 1247 histograms_->RecordNetworkBytes( |
| 1299 origin, used, prerender_bytes, recent_profile_bytes); | 1248 origin, used, prerender_bytes, recent_profile_bytes); |
| 1300 } | 1249 } |
| 1301 | 1250 |
| 1302 bool PrerenderManager::IsPrerenderSilenceExperiment(Origin origin) const { | 1251 bool PrerenderManager::IsPrerenderSilenceExperiment(Origin origin) const { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR && | 1309 if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR && |
| 1361 prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) { | 1310 prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) { |
| 1362 return NetworkPredictionStatus::ENABLED; | 1311 return NetworkPredictionStatus::ENABLED; |
| 1363 } | 1312 } |
| 1364 return prediction_status; | 1313 return prediction_status; |
| 1365 } | 1314 } |
| 1366 | 1315 |
| 1367 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64_t bytes) { | 1316 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64_t bytes) { |
| 1368 DCHECK_GE(bytes, 0); | 1317 DCHECK_GE(bytes, 0); |
| 1369 if (GetPredictionStatus() == NetworkPredictionStatus::ENABLED && | 1318 if (GetPredictionStatus() == NetworkPredictionStatus::ENABLED && |
| 1370 ActuallyPrerendering()) | 1319 IsPrerenderingPossible()) |
| 1371 profile_network_bytes_ += bytes; | 1320 profile_network_bytes_ += bytes; |
| 1372 } | 1321 } |
| 1373 | 1322 |
| 1374 void PrerenderManager::AddPrerenderProcessHost( | 1323 void PrerenderManager::AddPrerenderProcessHost( |
| 1375 content::RenderProcessHost* process_host) { | 1324 content::RenderProcessHost* process_host) { |
| 1376 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1325 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1377 DCHECK(prerender_process_hosts_.find(process_host) == | 1326 DCHECK(prerender_process_hosts_.find(process_host) == |
| 1378 prerender_process_hosts_.end()); | 1327 prerender_process_hosts_.end()); |
| 1379 prerender_process_hosts_.insert(process_host); | 1328 prerender_process_hosts_.insert(process_host); |
| 1380 process_host->AddObserver(this); | 1329 process_host->AddObserver(this); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1400 return weak_factory_.GetWeakPtr(); | 1349 return weak_factory_.GetWeakPtr(); |
| 1401 } | 1350 } |
| 1402 | 1351 |
| 1403 void PrerenderManager::SetPrerenderContentsFactoryForTest( | 1352 void PrerenderManager::SetPrerenderContentsFactoryForTest( |
| 1404 PrerenderContents::Factory* prerender_contents_factory) { | 1353 PrerenderContents::Factory* prerender_contents_factory) { |
| 1405 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1354 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1406 prerender_contents_factory_.reset(prerender_contents_factory); | 1355 prerender_contents_factory_.reset(prerender_contents_factory); |
| 1407 } | 1356 } |
| 1408 | 1357 |
| 1409 } // namespace prerender | 1358 } // namespace prerender |
| OLD | NEW |