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 <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #include "chrome/common/prerender_types.h" | 51 #include "chrome/common/prerender_types.h" |
52 #include "content/public/browser/browser_thread.h" | 52 #include "content/public/browser/browser_thread.h" |
53 #include "content/public/browser/devtools_agent_host.h" | 53 #include "content/public/browser/devtools_agent_host.h" |
54 #include "content/public/browser/navigation_controller.h" | 54 #include "content/public/browser/navigation_controller.h" |
55 #include "content/public/browser/notification_service.h" | 55 #include "content/public/browser/notification_service.h" |
56 #include "content/public/browser/notification_source.h" | 56 #include "content/public/browser/notification_source.h" |
57 #include "content/public/browser/render_frame_host.h" | 57 #include "content/public/browser/render_frame_host.h" |
58 #include "content/public/browser/render_process_host.h" | 58 #include "content/public/browser/render_process_host.h" |
59 #include "content/public/browser/render_view_host.h" | 59 #include "content/public/browser/render_view_host.h" |
60 #include "content/public/browser/session_storage_namespace.h" | 60 #include "content/public/browser/session_storage_namespace.h" |
| 61 #include "content/public/browser/storage_partition.h" |
61 #include "content/public/browser/web_contents.h" | 62 #include "content/public/browser/web_contents.h" |
62 #include "content/public/browser/web_contents_delegate.h" | 63 #include "content/public/browser/web_contents_delegate.h" |
63 #include "content/public/browser/web_contents_view.h" | 64 #include "content/public/browser/web_contents_view.h" |
64 #include "content/public/common/url_constants.h" | 65 #include "content/public/common/url_constants.h" |
65 #include "extensions/common/constants.h" | 66 #include "extensions/common/constants.h" |
66 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 67 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
67 #include "net/url_request/url_request_context.h" | 68 #include "net/url_request/url_request_context.h" |
68 #include "net/url_request/url_request_context_getter.h" | 69 #include "net/url_request/url_request_context_getter.h" |
69 | 70 |
70 using content::BrowserThread; | 71 using content::BrowserThread; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 : enabled_(profile && profile->GetPrefs() && | 240 : enabled_(profile && profile->GetPrefs() && |
240 profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)), | 241 profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)), |
241 profile_(profile), | 242 profile_(profile), |
242 prerender_tracker_(prerender_tracker), | 243 prerender_tracker_(prerender_tracker), |
243 prerender_contents_factory_(PrerenderContents::CreateFactory()), | 244 prerender_contents_factory_(PrerenderContents::CreateFactory()), |
244 last_prerender_start_time_(GetCurrentTimeTicks() - | 245 last_prerender_start_time_(GetCurrentTimeTicks() - |
245 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), | 246 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), |
246 prerender_history_(new PrerenderHistory(kHistoryLength)), | 247 prerender_history_(new PrerenderHistory(kHistoryLength)), |
247 histograms_(new PrerenderHistograms()), | 248 histograms_(new PrerenderHistograms()), |
248 profile_network_bytes_(0), | 249 profile_network_bytes_(0), |
249 last_recorded_profile_network_bytes_(0) { | 250 last_recorded_profile_network_bytes_(0), |
| 251 cookie_store_loaded_(false) { |
250 // There are some assumptions that the PrerenderManager is on the UI thread. | 252 // There are some assumptions that the PrerenderManager is on the UI thread. |
251 // Any other checks simply make sure that the PrerenderManager is accessed on | 253 // Any other checks simply make sure that the PrerenderManager is accessed on |
252 // the same thread that it was created on. | 254 // the same thread that it was created on. |
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
254 | 256 |
255 if (IsLocalPredictorEnabled()) | 257 if (IsLocalPredictorEnabled()) |
256 local_predictor_.reset(new PrerenderLocalPredictor(this)); | 258 local_predictor_.reset(new PrerenderLocalPredictor(this)); |
257 | 259 |
258 if (IsLoggedInPredictorEnabled() && !profile_->IsOffTheRecord()) { | 260 if (IsLoggedInPredictorEnabled() && !profile_->IsOffTheRecord()) { |
259 predictors::PredictorDatabase* predictor_db = | 261 predictors::PredictorDatabase* predictor_db = |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // For bookkeeping purposes, we need to mark this WebContents to | 573 // For bookkeeping purposes, we need to mark this WebContents to |
572 // reflect that it would have been prerendered. | 574 // reflect that it would have been prerendered. |
573 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { | 575 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { |
574 target_tab_helper->WouldHavePrerenderedNextLoad( | 576 target_tab_helper->WouldHavePrerenderedNextLoad( |
575 prerender_data->contents()->origin()); | 577 prerender_data->contents()->origin()); |
576 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); | 578 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); |
577 return NULL; | 579 return NULL; |
578 } | 580 } |
579 | 581 |
580 // At this point, we've determined that we will use the prerender. | 582 // At this point, we've determined that we will use the prerender. |
| 583 prerender_tracker()->OnPrerenderSwapped( |
| 584 prerender_data->contents()->GetRenderViewHost()->GetProcess()); |
581 if (!prerender_data->contents()->load_start_time().is_null()) { | 585 if (!prerender_data->contents()->load_start_time().is_null()) { |
582 histograms_->RecordTimeUntilUsed( | 586 histograms_->RecordTimeUntilUsed( |
583 prerender_data->contents()->origin(), | 587 prerender_data->contents()->origin(), |
584 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time()); | 588 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time()); |
585 } | 589 } |
586 histograms_->RecordAbandonTimeUntilUsed( | 590 histograms_->RecordAbandonTimeUntilUsed( |
587 prerender_data->contents()->origin(), | 591 prerender_data->contents()->origin(), |
588 prerender_data->abandon_time().is_null() ? | 592 prerender_data->abandon_time().is_null() ? |
589 base::TimeDelta() : | 593 base::TimeDelta() : |
590 GetCurrentTimeTicks() - prerender_data->abandon_time()); | 594 GetCurrentTimeTicks() - prerender_data->abandon_time()); |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 prerender_data); | 1215 prerender_data); |
1212 if (it == active_prerenders_.end()) | 1216 if (it == active_prerenders_.end()) |
1213 return; | 1217 return; |
1214 | 1218 |
1215 (*it)->set_expiry_time( | 1219 (*it)->set_expiry_time( |
1216 std::min((*it)->expiry_time(), | 1220 std::min((*it)->expiry_time(), |
1217 GetExpiryTimeForNavigatedAwayPrerender())); | 1221 GetExpiryTimeForNavigatedAwayPrerender())); |
1218 SortActivePrerenders(); | 1222 SortActivePrerenders(); |
1219 } | 1223 } |
1220 | 1224 |
| 1225 net::URLRequestContextGetter* PrerenderManager::GetURLRequestContext() { |
| 1226 return content::BrowserContext::GetDefaultStoragePartition(profile_)-> |
| 1227 GetURLRequestContext(); |
| 1228 } |
| 1229 |
| 1230 |
1221 // private | 1231 // private |
1222 PrerenderHandle* PrerenderManager::AddPrerender( | 1232 PrerenderHandle* PrerenderManager::AddPrerender( |
1223 Origin origin, | 1233 Origin origin, |
1224 int process_id, | 1234 int process_id, |
1225 const GURL& url_arg, | 1235 const GURL& url_arg, |
1226 const content::Referrer& referrer, | 1236 const content::Referrer& referrer, |
1227 const gfx::Size& size, | 1237 const gfx::Size& size, |
1228 SessionStorageNamespace* session_storage_namespace) { | 1238 SessionStorageNamespace* session_storage_namespace) { |
1229 DCHECK(CalledOnValidThread()); | 1239 DCHECK(CalledOnValidThread()); |
1230 | 1240 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 | 1285 |
1276 // Check if enough time has passed since the last prerender. | 1286 // Check if enough time has passed since the last prerender. |
1277 if (!DoesRateLimitAllowPrerender(origin)) { | 1287 if (!DoesRateLimitAllowPrerender(origin)) { |
1278 // Cancel the prerender. We could add it to the pending prerender list but | 1288 // Cancel the prerender. We could add it to the pending prerender list but |
1279 // this doesn't make sense as the next prerender request will be triggered | 1289 // this doesn't make sense as the next prerender request will be triggered |
1280 // by a navigation and is unlikely to be the same site. | 1290 // by a navigation and is unlikely to be the same site. |
1281 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); | 1291 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); |
1282 return NULL; | 1292 return NULL; |
1283 } | 1293 } |
1284 | 1294 |
| 1295 if (!cookie_store_loaded()) { |
| 1296 // Only prerender if the cookie store for this profile has been loaded. |
| 1297 // This is required by PrerenderCookieMonster. |
| 1298 RecordFinalStatus(origin, experiment, FINAL_STATUS_COOKIE_STORE_NOT_LOADED); |
| 1299 return NULL; |
| 1300 } |
| 1301 |
1285 PrerenderContents* prerender_contents = CreatePrerenderContents( | 1302 PrerenderContents* prerender_contents = CreatePrerenderContents( |
1286 url, referrer, origin, experiment); | 1303 url, referrer, origin, experiment); |
1287 DCHECK(prerender_contents); | 1304 DCHECK(prerender_contents); |
1288 active_prerenders_.push_back( | 1305 active_prerenders_.push_back( |
1289 new PrerenderData(this, prerender_contents, | 1306 new PrerenderData(this, prerender_contents, |
1290 GetExpiryTimeForNewPrerender(origin))); | 1307 GetExpiryTimeForNewPrerender(origin))); |
1291 if (!prerender_contents->Init()) { | 1308 if (!prerender_contents->Init()) { |
1292 DCHECK(active_prerenders_.end() == | 1309 DCHECK(active_prerenders_.end() == |
1293 FindIteratorForPrerenderContents(prerender_contents)); | 1310 FindIteratorForPrerenderContents(prerender_contents)); |
1294 return NULL; | 1311 return NULL; |
1295 } | 1312 } |
1296 | 1313 |
1297 histograms_->RecordPrerenderStarted(origin); | 1314 histograms_->RecordPrerenderStarted(origin); |
1298 DCHECK(!prerender_contents->prerendering_has_started()); | 1315 DCHECK(!prerender_contents->prerendering_has_started()); |
1299 | 1316 |
1300 PrerenderHandle* prerender_handle = | 1317 PrerenderHandle* prerender_handle = |
1301 new PrerenderHandle(active_prerenders_.back()); | 1318 new PrerenderHandle(active_prerenders_.back()); |
1302 SortActivePrerenders(); | 1319 SortActivePrerenders(); |
1303 | 1320 |
1304 last_prerender_start_time_ = GetCurrentTimeTicks(); | 1321 last_prerender_start_time_ = GetCurrentTimeTicks(); |
1305 | 1322 |
1306 gfx::Size contents_size = | 1323 gfx::Size contents_size = |
1307 size.IsEmpty() ? config_.default_tab_bounds.size() : size; | 1324 size.IsEmpty() ? config_.default_tab_bounds.size() : size; |
1308 | 1325 |
| 1326 net::URLRequestContextGetter* request_context = GetURLRequestContext(); |
| 1327 |
1309 prerender_contents->StartPrerendering(process_id, contents_size, | 1328 prerender_contents->StartPrerendering(process_id, contents_size, |
1310 session_storage_namespace); | 1329 session_storage_namespace, |
| 1330 request_context); |
1311 | 1331 |
1312 DCHECK(IsControlGroup(experiment) || | 1332 DCHECK(IsControlGroup(experiment) || |
1313 prerender_contents->prerendering_has_started()); | 1333 prerender_contents->prerendering_has_started() || |
| 1334 (origin == ORIGIN_LOCAL_PREDICTOR && |
| 1335 IsLocalPredictorPrerenderAlwaysControlEnabled())); |
1314 | 1336 |
1315 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP) | 1337 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP) |
1316 histograms_->RecordConcurrency(active_prerenders_.size()); | 1338 histograms_->RecordConcurrency(active_prerenders_.size()); |
1317 | 1339 |
1318 // Query the history to see if the URL being prerendered has ever been | 1340 // Query the history to see if the URL being prerendered has ever been |
1319 // visited before. | 1341 // visited before. |
1320 HistoryService* history_service = HistoryServiceFactory::GetForProfile( | 1342 HistoryService* history_service = HistoryServiceFactory::GetForProfile( |
1321 profile_, Profile::EXPLICIT_ACCESS); | 1343 profile_, Profile::EXPLICIT_ACCESS); |
1322 if (history_service) { | 1344 if (history_service) { |
1323 history_service->QueryURL( | 1345 history_service->QueryURL( |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 DCHECK_GE(recent_profile_bytes, 0); | 1843 DCHECK_GE(recent_profile_bytes, 0); |
1822 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes); | 1844 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes); |
1823 } | 1845 } |
1824 | 1846 |
1825 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) { | 1847 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) { |
1826 DCHECK_GE(bytes, 0); | 1848 DCHECK_GE(bytes, 0); |
1827 if (IsEnabled() && ActuallyPrerendering()) | 1849 if (IsEnabled() && ActuallyPrerendering()) |
1828 profile_network_bytes_ += bytes; | 1850 profile_network_bytes_ += bytes; |
1829 } | 1851 } |
1830 | 1852 |
| 1853 void PrerenderManager::OnCookieStoreLoaded() { |
| 1854 cookie_store_loaded_ = true; |
| 1855 if (!on_cookie_store_loaded_cb_.is_null()) |
| 1856 on_cookie_store_loaded_cb_.Run(); |
| 1857 } |
| 1858 |
1831 } // namespace prerender | 1859 } // namespace prerender |
OLD | NEW |