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

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

Issue 280403002: Only commit cookie changes in prerenders after a prerender is shown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix sync related bug 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 // Check if enough time has passed since the last prerender. 1299 // Check if enough time has passed since the last prerender.
1277 if (!DoesRateLimitAllowPrerender(origin)) { 1300 if (!DoesRateLimitAllowPrerender(origin)) {
1278 // Cancel the prerender. We could add it to the pending prerender list but 1301 // 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 1302 // 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. 1303 // by a navigation and is unlikely to be the same site.
1281 RecordFinalStatusWithoutCreatingPrerenderContents( 1304 RecordFinalStatusWithoutCreatingPrerenderContents(
1282 url, origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 1305 url, origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
1283 return NULL; 1306 return NULL;
1284 } 1307 }
1285 1308
1309 if (!cookie_store_loaded()) {
1310 // Only prerender if the cookie store for this profile has been loaded.
1311 // This is required by PrerenderCookieMonster.
1312 RecordFinalStatusWithoutCreatingPrerenderContents(
1313 url, origin, experiment, FINAL_STATUS_COOKIE_STORE_NOT_LOADED);
1314 return NULL;
1315 }
1316
1286 PrerenderContents* prerender_contents = CreatePrerenderContents( 1317 PrerenderContents* prerender_contents = CreatePrerenderContents(
1287 url, referrer, origin, experiment); 1318 url, referrer, origin, experiment);
1288 DCHECK(prerender_contents); 1319 DCHECK(prerender_contents);
1289 active_prerenders_.push_back( 1320 active_prerenders_.push_back(
1290 new PrerenderData(this, prerender_contents, 1321 new PrerenderData(this, prerender_contents,
1291 GetExpiryTimeForNewPrerender(origin))); 1322 GetExpiryTimeForNewPrerender(origin)));
1292 if (!prerender_contents->Init()) { 1323 if (!prerender_contents->Init()) {
1293 DCHECK(active_prerenders_.end() == 1324 DCHECK(active_prerenders_.end() ==
1294 FindIteratorForPrerenderContents(prerender_contents)); 1325 FindIteratorForPrerenderContents(prerender_contents));
1295 return NULL; 1326 return NULL;
1296 } 1327 }
1297 1328
1298 histograms_->RecordPrerenderStarted(origin); 1329 histograms_->RecordPrerenderStarted(origin);
1299 DCHECK(!prerender_contents->prerendering_has_started()); 1330 DCHECK(!prerender_contents->prerendering_has_started());
1300 1331
1301 PrerenderHandle* prerender_handle = 1332 PrerenderHandle* prerender_handle =
1302 new PrerenderHandle(active_prerenders_.back()); 1333 new PrerenderHandle(active_prerenders_.back());
1303 SortActivePrerenders(); 1334 SortActivePrerenders();
1304 1335
1305 last_prerender_start_time_ = GetCurrentTimeTicks(); 1336 last_prerender_start_time_ = GetCurrentTimeTicks();
1306 1337
1307 gfx::Size contents_size = 1338 gfx::Size contents_size =
1308 size.IsEmpty() ? config_.default_tab_bounds.size() : size; 1339 size.IsEmpty() ? config_.default_tab_bounds.size() : size;
1309 1340
1341 net::URLRequestContextGetter* request_context = GetURLRequestContext();
1342
1310 prerender_contents->StartPrerendering(process_id, contents_size, 1343 prerender_contents->StartPrerendering(process_id, contents_size,
1311 session_storage_namespace); 1344 session_storage_namespace,
1345 request_context);
1312 1346
1313 DCHECK(IsControlGroup(experiment) || 1347 DCHECK(IsControlGroup(experiment) ||
1314 prerender_contents->prerendering_has_started()); 1348 prerender_contents->prerendering_has_started() ||
1349 (origin == ORIGIN_LOCAL_PREDICTOR &&
1350 IsLocalPredictorPrerenderAlwaysControlEnabled()));
1315 1351
1316 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP) 1352 if (GetMode() == PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP)
1317 histograms_->RecordConcurrency(active_prerenders_.size()); 1353 histograms_->RecordConcurrency(active_prerenders_.size());
1318 1354
1319 // Query the history to see if the URL being prerendered has ever been 1355 // Query the history to see if the URL being prerendered has ever been
1320 // visited before. 1356 // visited before.
1321 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 1357 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
1322 profile_, Profile::EXPLICIT_ACCESS); 1358 profile_, Profile::EXPLICIT_ACCESS);
1323 if (history_service) { 1359 if (history_service) {
1324 history_service->QueryURL( 1360 history_service->QueryURL(
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 DCHECK_GE(recent_profile_bytes, 0); 1860 DCHECK_GE(recent_profile_bytes, 0);
1825 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes); 1861 histograms_->RecordNetworkBytes(used, prerender_bytes, recent_profile_bytes);
1826 } 1862 }
1827 1863
1828 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) { 1864 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) {
1829 DCHECK_GE(bytes, 0); 1865 DCHECK_GE(bytes, 0);
1830 if (IsEnabled() && ActuallyPrerendering()) 1866 if (IsEnabled() && ActuallyPrerendering())
1831 profile_network_bytes_ += bytes; 1867 profile_network_bytes_ += bytes;
1832 } 1868 }
1833 1869
1870 void PrerenderManager::OnCookieStoreLoaded() {
1871 cookie_store_loaded_ = true;
1872 if (!on_cookie_store_loaded_cb_for_testing_.is_null())
1873 on_cookie_store_loaded_cb_for_testing_.Run();
1874 }
1875
1876 void PrerenderManager::AddPrerenderProcessHost(
1877 content::RenderProcessHost* process_host) {
1878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1879 DCHECK(prerender_process_hosts_.find(process_host) ==
1880 prerender_process_hosts_.end());
1881 prerender_process_hosts_.insert(process_host);
1882 process_host->AddObserver(this);
1883 }
1884
1885 bool PrerenderManager::IsProcessPrerendering(
1886 content::RenderProcessHost* process_host) {
1887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1888 return (prerender_process_hosts_.find(process_host) !=
1889 prerender_process_hosts_.end());
1890 }
1891
1892 void PrerenderManager::RenderProcessHostDestroyed(
1893 content::RenderProcessHost* host) {
1894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1895 prerender_process_hosts_.erase(host);
1896 BrowserThread::PostTask(
1897 BrowserThread::IO, FROM_HERE,
1898 base::Bind(&PrerenderTracker::RemovePrerenderCookieStoreOnIOThread,
1899 base::Unretained(prerender_tracker()), host->GetID(), false));
1900 }
1901
1834 } // namespace prerender 1902 } // 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