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

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 278403003: Only commit cookie changes in prerenders after a prerender is shown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix test issue Created 6 years, 7 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) 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
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/common/url_constants.h" 64 #include "content/public/common/url_constants.h"
64 #include "extensions/common/constants.h" 65 #include "extensions/common/constants.h"
65 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 66 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
66 #include "net/url_request/url_request_context.h" 67 #include "net/url_request/url_request_context.h"
67 #include "net/url_request/url_request_context_getter.h" 68 #include "net/url_request/url_request_context_getter.h"
68 69
69 using content::BrowserThread; 70 using content::BrowserThread;
70 using content::RenderViewHost; 71 using content::RenderViewHost;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 : enabled_(profile && profile->GetPrefs() && 239 : enabled_(profile && profile->GetPrefs() &&
239 profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)), 240 profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)),
240 profile_(profile), 241 profile_(profile),
241 prerender_tracker_(prerender_tracker), 242 prerender_tracker_(prerender_tracker),
242 prerender_contents_factory_(PrerenderContents::CreateFactory()), 243 prerender_contents_factory_(PrerenderContents::CreateFactory()),
243 last_prerender_start_time_(GetCurrentTimeTicks() - 244 last_prerender_start_time_(GetCurrentTimeTicks() -
244 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)), 245 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs)),
245 prerender_history_(new PrerenderHistory(kHistoryLength)), 246 prerender_history_(new PrerenderHistory(kHistoryLength)),
246 histograms_(new PrerenderHistograms()), 247 histograms_(new PrerenderHistograms()),
247 profile_network_bytes_(0), 248 profile_network_bytes_(0),
248 last_recorded_profile_network_bytes_(0) { 249 last_recorded_profile_network_bytes_(0),
250 cookie_store_loaded_(false) {
249 // There are some assumptions that the PrerenderManager is on the UI thread. 251 // There are some assumptions that the PrerenderManager is on the UI thread.
250 // Any other checks simply make sure that the PrerenderManager is accessed on 252 // Any other checks simply make sure that the PrerenderManager is accessed on
251 // the same thread that it was created on. 253 // the same thread that it was created on.
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
253 255
254 if (IsLocalPredictorEnabled()) 256 if (IsLocalPredictorEnabled())
255 local_predictor_.reset(new PrerenderLocalPredictor(this)); 257 local_predictor_.reset(new PrerenderLocalPredictor(this));
256 258
257 if (IsLoggedInPredictorEnabled() && !profile_->IsOffTheRecord()) { 259 if (IsLoggedInPredictorEnabled() && !profile_->IsOffTheRecord()) {
258 predictors::PredictorDatabase* predictor_db = 260 predictors::PredictorDatabase* predictor_db =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); 298 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
297 } 299 }
298 300
299 PrerenderManager::~PrerenderManager() { 301 PrerenderManager::~PrerenderManager() {
300 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); 302 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
301 303
302 // The earlier call to KeyedService::Shutdown() should have 304 // The earlier call to KeyedService::Shutdown() should have
303 // emptied these vectors already. 305 // emptied these vectors already.
304 DCHECK(active_prerenders_.empty()); 306 DCHECK(active_prerenders_.empty());
305 DCHECK(to_delete_prerenders_.empty()); 307 DCHECK(to_delete_prerenders_.empty());
308
309 for (PrerenderProcessSet::const_iterator it =
310 prerender_process_hosts_.begin();
311 it != prerender_process_hosts_.end();
312 ++it) {
313 (*it)->RemoveObserver(this);
314 }
306 } 315 }
307 316
308 void PrerenderManager::Shutdown() { 317 void PrerenderManager::Shutdown() {
309 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); 318 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN);
310 STLDeleteElements(&prerender_conditions_); 319 STLDeleteElements(&prerender_conditions_);
311 on_close_web_contents_deleters_.clear(); 320 on_close_web_contents_deleters_.clear();
312 // Must happen before |profile_| is set to NULL as 321 // Must happen before |profile_| is set to NULL as
313 // |local_predictor_| accesses it. 322 // |local_predictor_| accesses it.
314 if (local_predictor_) 323 if (local_predictor_)
315 local_predictor_->Shutdown(); 324 local_predictor_->Shutdown();
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 // For bookkeeping purposes, we need to mark this WebContents to 579 // For bookkeeping purposes, we need to mark this WebContents to
571 // reflect that it would have been prerendered. 580 // reflect that it would have been prerendered.
572 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { 581 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
573 target_tab_helper->WouldHavePrerenderedNextLoad( 582 target_tab_helper->WouldHavePrerenderedNextLoad(
574 prerender_data->contents()->origin()); 583 prerender_data->contents()->origin());
575 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); 584 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
576 return NULL; 585 return NULL;
577 } 586 }
578 587
579 // At this point, we've determined that we will use the prerender. 588 // At this point, we've determined that we will use the prerender.
589 content::RenderProcessHost* process_host =
590 prerender_data->contents()->GetRenderViewHost()->GetProcess();
591 prerender_process_hosts_.erase(process_host);
592 BrowserThread::PostTask(
593 BrowserThread::IO, FROM_HERE,
594 base::Bind(&PrerenderTracker::RemovePrerenderCookieStoreOnIOThread,
595 base::Unretained(prerender_tracker()), process_host->GetID(),
596 true));
580 if (!prerender_data->contents()->load_start_time().is_null()) { 597 if (!prerender_data->contents()->load_start_time().is_null()) {
581 histograms_->RecordTimeUntilUsed( 598 histograms_->RecordTimeUntilUsed(
582 prerender_data->contents()->origin(), 599 prerender_data->contents()->origin(),
583 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time()); 600 GetCurrentTimeTicks() - prerender_data->contents()->load_start_time());
584 } 601 }
585 histograms_->RecordAbandonTimeUntilUsed( 602 histograms_->RecordAbandonTimeUntilUsed(
586 prerender_data->contents()->origin(), 603 prerender_data->contents()->origin(),
587 prerender_data->abandon_time().is_null() ? 604 prerender_data->abandon_time().is_null() ?
588 base::TimeDelta() : 605 base::TimeDelta() :
589 GetCurrentTimeTicks() - prerender_data->abandon_time()); 606 GetCurrentTimeTicks() - prerender_data->abandon_time());
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 case PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP: 758 case PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP:
742 return "_Multi"; 759 return "_Multi";
743 case PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP: 760 case PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP:
744 return "_15MinTTL"; 761 return "_15MinTTL";
745 case PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP: 762 case PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP:
746 return "_NoUse"; 763 return "_NoUse";
747 case PRERENDER_MODE_MAX: 764 case PRERENDER_MODE_MAX:
748 default: 765 default:
749 NOTREACHED() << "Invalid PrerenderManager mode."; 766 NOTREACHED() << "Invalid PrerenderManager mode.";
750 break; 767 break;
751 }; 768 }
752 return ""; 769 return "";
753 } 770 }
754 771
755 // static 772 // static
756 bool PrerenderManager::IsPrerenderingPossible() { 773 bool PrerenderManager::IsPrerenderingPossible() {
757 return GetMode() != PRERENDER_MODE_DISABLED; 774 return GetMode() != PRERENDER_MODE_DISABLED;
758 } 775 }
759 776
760 // static 777 // static
761 bool PrerenderManager::ActuallyPrerendering() { 778 bool PrerenderManager::ActuallyPrerendering() {
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 prerender_data); 1226 prerender_data);
1210 if (it == active_prerenders_.end()) 1227 if (it == active_prerenders_.end())
1211 return; 1228 return;
1212 1229
1213 (*it)->set_expiry_time( 1230 (*it)->set_expiry_time(
1214 std::min((*it)->expiry_time(), 1231 std::min((*it)->expiry_time(),
1215 GetExpiryTimeForNavigatedAwayPrerender())); 1232 GetExpiryTimeForNavigatedAwayPrerender()));
1216 SortActivePrerenders(); 1233 SortActivePrerenders();
1217 } 1234 }
1218 1235
1236 net::URLRequestContextGetter* PrerenderManager::GetURLRequestContext() {
1237 return content::BrowserContext::GetDefaultStoragePartition(profile_)->
1238 GetURLRequestContext();
1239 }
1240
1241
1219 // private 1242 // private
1220 PrerenderHandle* PrerenderManager::AddPrerender( 1243 PrerenderHandle* PrerenderManager::AddPrerender(
1221 Origin origin, 1244 Origin origin,
1222 int process_id, 1245 int process_id,
1223 const GURL& url_arg, 1246 const GURL& url_arg,
1224 const content::Referrer& referrer, 1247 const content::Referrer& referrer,
1225 const gfx::Size& size, 1248 const gfx::Size& size,
1226 SessionStorageNamespace* session_storage_namespace) { 1249 SessionStorageNamespace* session_storage_namespace) {
1227 DCHECK(CalledOnValidThread()); 1250 DCHECK(CalledOnValidThread());
1228 1251
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 1296
1274 // Check if enough time has passed since the last prerender. 1297 // Check if enough time has passed since the last prerender.
1275 if (!DoesRateLimitAllowPrerender(origin)) { 1298 if (!DoesRateLimitAllowPrerender(origin)) {
1276 // Cancel the prerender. We could add it to the pending prerender list but 1299 // Cancel the prerender. We could add it to the pending prerender list but
1277 // this doesn't make sense as the next prerender request will be triggered 1300 // this doesn't make sense as the next prerender request will be triggered
1278 // by a navigation and is unlikely to be the same site. 1301 // by a navigation and is unlikely to be the same site.
1279 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 1302 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
1280 return NULL; 1303 return NULL;
1281 } 1304 }
1282 1305
1306 if (!cookie_store_loaded()) {
1307 // Only prerender if the cookie store for this profile has been loaded.
1308 // This is required by PrerenderCookieMonster.
1309 RecordFinalStatus(origin, experiment, FINAL_STATUS_COOKIE_STORE_NOT_LOADED);
1310 return NULL;
1311 }
1312
1283 PrerenderContents* prerender_contents = CreatePrerenderContents( 1313 PrerenderContents* prerender_contents = CreatePrerenderContents(
1284 url, referrer, origin, experiment); 1314 url, referrer, origin, experiment);
1285 DCHECK(prerender_contents); 1315 DCHECK(prerender_contents);
1286 active_prerenders_.push_back( 1316 active_prerenders_.push_back(
1287 new PrerenderData(this, prerender_contents, 1317 new PrerenderData(this, prerender_contents,
1288 GetExpiryTimeForNewPrerender(origin))); 1318 GetExpiryTimeForNewPrerender(origin)));
1289 if (!prerender_contents->Init()) { 1319 if (!prerender_contents->Init()) {
1290 DCHECK(active_prerenders_.end() == 1320 DCHECK(active_prerenders_.end() ==
1291 FindIteratorForPrerenderContents(prerender_contents)); 1321 FindIteratorForPrerenderContents(prerender_contents));
1292 return NULL; 1322 return NULL;
1293 } 1323 }
1294 1324
1295 histograms_->RecordPrerenderStarted(origin); 1325 histograms_->RecordPrerenderStarted(origin);
1296 DCHECK(!prerender_contents->prerendering_has_started()); 1326 DCHECK(!prerender_contents->prerendering_has_started());
1297 1327
1298 PrerenderHandle* prerender_handle = 1328 PrerenderHandle* prerender_handle =
1299 new PrerenderHandle(active_prerenders_.back()); 1329 new PrerenderHandle(active_prerenders_.back());
1300 SortActivePrerenders(); 1330 SortActivePrerenders();
1301 1331
1302 last_prerender_start_time_ = GetCurrentTimeTicks(); 1332 last_prerender_start_time_ = GetCurrentTimeTicks();
1303 1333
1304 gfx::Size contents_size = 1334 gfx::Size contents_size =
1305 size.IsEmpty() ? config_.default_tab_bounds.size() : size; 1335 size.IsEmpty() ? config_.default_tab_bounds.size() : size;
1306 1336
1337 net::URLRequestContextGetter* request_context = GetURLRequestContext();
1338
1307 prerender_contents->StartPrerendering(process_id, contents_size, 1339 prerender_contents->StartPrerendering(process_id, contents_size,
1308 session_storage_namespace); 1340 session_storage_namespace,
1341 request_context);
1309 1342
1310 DCHECK(IsControlGroup(experiment) || 1343 DCHECK(IsControlGroup(experiment) ||
1311 prerender_contents->prerendering_has_started()); 1344 prerender_contents->prerendering_has_started() ||
1345 (origin == ORIGIN_LOCAL_PREDICTOR &&
1346 IsLocalPredictorPrerenderAlwaysControlEnabled()));
1312 1347
1313 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP) 1348 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP)
1314 histograms_->RecordConcurrency(active_prerenders_.size()); 1349 histograms_->RecordConcurrency(active_prerenders_.size());
1315 1350
1316 // Query the history to see if the URL being prerendered has ever been 1351 // Query the history to see if the URL being prerendered has ever been
1317 // visited before. 1352 // visited before.
1318 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 1353 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
1319 profile_, Profile::EXPLICIT_ACCESS); 1354 profile_, Profile::EXPLICIT_ACCESS);
1320 if (history_service) { 1355 if (history_service) {
1321 history_service->QueryURL( 1356 history_service->QueryURL(
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 DCHECK_GE(recent_profile_bytes, 0); 1854 DCHECK_GE(recent_profile_bytes, 0);
1820 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes); 1855 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes);
1821 } 1856 }
1822 1857
1823 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) { 1858 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) {
1824 DCHECK_GE(bytes, 0); 1859 DCHECK_GE(bytes, 0);
1825 if (IsEnabled() && ActuallyPrerendering()) 1860 if (IsEnabled() && ActuallyPrerendering())
1826 profile_network_bytes_ += bytes; 1861 profile_network_bytes_ += bytes;
1827 } 1862 }
1828 1863
1864 void PrerenderManager::OnCookieStoreLoaded() {
1865 cookie_store_loaded_ = true;
1866 if (!on_cookie_store_loaded_cb_for_testing_.is_null())
1867 on_cookie_store_loaded_cb_for_testing_.Run();
1868 }
1869
1870 void PrerenderManager::AddPrerenderProcessHost(
1871 content::RenderProcessHost* process_host) {
1872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1873 DCHECK(prerender_process_hosts_.find(process_host) ==
1874 prerender_process_hosts_.end());
1875 prerender_process_hosts_.insert(process_host);
1876 process_host->AddObserver(this);
1877 }
1878
1879 bool PrerenderManager::IsProcessPrerendering(
1880 content::RenderProcessHost* process_host) {
1881 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1882 return (prerender_process_hosts_.find(process_host) !=
1883 prerender_process_hosts_.end());
1884 }
1885
1886 void PrerenderManager::RenderProcessHostDestroyed(
1887 content::RenderProcessHost* host) {
1888 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1889 prerender_process_hosts_.erase(host);
1890 BrowserThread::PostTask(
1891 BrowserThread::IO, FROM_HERE,
1892 base::Bind(&PrerenderTracker::RemovePrerenderCookieStoreOnIOThread,
1893 base::Unretained(prerender_tracker()), host->GetID(), false));
1894 }
1895
1829 } // namespace prerender 1896 } // namespace prerender
OLDNEW
« no previous file with comments | « chrome/browser/prerender/prerender_manager.h ('k') | chrome/browser/prerender/prerender_tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698