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

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

Issue 8392041: Prerendered tabs use the same SessionStorage namespace as the tab that triggered the prerender. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: string_ordinal_unittest Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 16 matching lines...) Expand all
27 #include "chrome/browser/prerender/prerender_tracker.h" 27 #include "chrome/browser/prerender/prerender_tracker.h"
28 #include "chrome/browser/prerender/prerender_util.h" 28 #include "chrome/browser/prerender/prerender_util.h"
29 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 30 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
31 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" 31 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
32 #include "chrome/common/chrome_notification_types.h" 32 #include "chrome/common/chrome_notification_types.h"
33 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/render_messages.h" 34 #include "chrome/common/render_messages.h"
35 #include "content/browser/cancelable_request.h" 35 #include "content/browser/cancelable_request.h"
36 #include "content/browser/debugger/render_view_devtools_agent_host.h" 36 #include "content/browser/debugger/render_view_devtools_agent_host.h"
37 #include "content/browser/in_process_webkit/session_storage_namespace.h"
37 #include "content/browser/renderer_host/render_process_host.h" 38 #include "content/browser/renderer_host/render_process_host.h"
38 #include "content/browser/renderer_host/render_view_host.h" 39 #include "content/browser/renderer_host/render_view_host.h"
39 #include "content/browser/renderer_host/resource_dispatcher_host.h" 40 #include "content/browser/renderer_host/resource_dispatcher_host.h"
40 #include "content/browser/tab_contents/render_view_host_manager.h" 41 #include "content/browser/tab_contents/render_view_host_manager.h"
41 #include "content/browser/tab_contents/tab_contents.h" 42 #include "content/browser/tab_contents/tab_contents.h"
42 #include "content/browser/tab_contents/tab_contents_delegate.h" 43 #include "content/browser/tab_contents/tab_contents_delegate.h"
43 #include "content/public/browser/browser_thread.h" 44 #include "content/public/browser/browser_thread.h"
44 #include "content/public/browser/notification_observer.h" 45 #include "content/public/browser/notification_observer.h"
45 #include "content/public/browser/notification_registrar.h" 46 #include "content/public/browser/notification_registrar.h"
46 #include "content/public/browser/notification_source.h" 47 #include "content/public/browser/notification_source.h"
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 266 }
266 267
267 bool PrerenderManager::AddPrerenderFromLinkRelPrerender(int process_id, 268 bool PrerenderManager::AddPrerenderFromLinkRelPrerender(int process_id,
268 int route_id, 269 int route_id,
269 const GURL& url, 270 const GURL& url,
270 const GURL& referrer) { 271 const GURL& referrer) {
271 std::pair<int, int> child_route_id_pair = std::make_pair(process_id, 272 std::pair<int, int> child_route_id_pair = std::make_pair(process_id,
272 route_id); 273 route_id);
273 274
274 return AddPrerender(ORIGIN_LINK_REL_PRERENDER, child_route_id_pair, 275 return AddPrerender(ORIGIN_LINK_REL_PRERENDER, child_route_id_pair,
275 url, referrer); 276 url, referrer, NULL);
276 } 277 }
277 278
278 bool PrerenderManager::AddPrerenderFromOmnibox(const GURL& url) { 279 bool PrerenderManager::AddPrerenderFromOmnibox(
280 const GURL& url,
281 SessionStorageNamespace* session_storage_namespace) {
282 DCHECK(session_storage_namespace);
279 if (!IsOmniboxEnabled(profile_)) 283 if (!IsOmniboxEnabled(profile_))
280 return false; 284 return false;
281 285
282 Origin origin = ORIGIN_MAX; 286 Origin origin = ORIGIN_MAX;
283 switch (GetOmniboxHeuristicToUse()) { 287 switch (GetOmniboxHeuristicToUse()) {
284 case OMNIBOX_HEURISTIC_ORIGINAL: 288 case OMNIBOX_HEURISTIC_ORIGINAL:
285 origin = ORIGIN_OMNIBOX_ORIGINAL; 289 origin = ORIGIN_OMNIBOX_ORIGINAL;
286 break; 290 break;
287 291
288 case OMNIBOX_HEURISTIC_CONSERVATIVE: 292 case OMNIBOX_HEURISTIC_CONSERVATIVE:
289 origin = ORIGIN_OMNIBOX_CONSERVATIVE; 293 origin = ORIGIN_OMNIBOX_CONSERVATIVE;
290 break; 294 break;
291 295
292 default: 296 default:
293 NOTREACHED(); 297 NOTREACHED();
294 break; 298 break;
295 }; 299 };
296 300
297 return AddPrerender(origin, std::make_pair(-1, -1), url, GURL()); 301 return AddPrerender(origin, std::make_pair(-1, -1), url, GURL(),
302 session_storage_namespace);
298 } 303 }
299 304
300 bool PrerenderManager::AddPrerender( 305 bool PrerenderManager::AddPrerender(
301 Origin origin, 306 Origin origin,
302 const std::pair<int, int>& child_route_id_pair, 307 const std::pair<int, int>& child_route_id_pair,
303 const GURL& url_arg, 308 const GURL& url_arg,
304 const GURL& referrer) { 309 const GURL& referrer,
310 SessionStorageNamespace* session_storage_namespace) {
305 DCHECK(CalledOnValidThread()); 311 DCHECK(CalledOnValidThread());
306 312
307 if (origin == ORIGIN_LINK_REL_PRERENDER && IsGoogleSearchResultURL(referrer)) 313 if (origin == ORIGIN_LINK_REL_PRERENDER && IsGoogleSearchResultURL(referrer))
308 origin = ORIGIN_GWS_PRERENDER; 314 origin = ORIGIN_GWS_PRERENDER;
309 315
310 histograms_->RecordPrerender(origin, url_arg); 316 histograms_->RecordPrerender(origin, url_arg);
311 317
312 // If the referring page is prerendering, defer the prerender. 318 // If the referring page is prerendering, defer the prerender.
313 std::list<PrerenderContentsData>::iterator source_prerender = 319 std::list<PrerenderContentsData>::iterator source_prerender =
314 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair); 320 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 // Check if enough time has passed since the last prerender. 355 // Check if enough time has passed since the last prerender.
350 if (!DoesRateLimitAllowPrerender()) { 356 if (!DoesRateLimitAllowPrerender()) {
351 // Cancel the prerender. We could add it to the pending prerender list but 357 // Cancel the prerender. We could add it to the pending prerender list but
352 // this doesn't make sense as the next prerender request will be triggered 358 // this doesn't make sense as the next prerender request will be triggered
353 // by a navigation and is unlikely to be the same site. 359 // by a navigation and is unlikely to be the same site.
354 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED); 360 RecordFinalStatus(origin, experiment, FINAL_STATUS_RATE_LIMIT_EXCEEDED);
355 return false; 361 return false;
356 } 362 }
357 363
358 RenderViewHost* source_render_view_host = NULL; 364 RenderViewHost* source_render_view_host = NULL;
359 // This test should fail only during unit tests.
360 if (child_route_id_pair.first != -1) { 365 if (child_route_id_pair.first != -1) {
361 source_render_view_host = 366 source_render_view_host =
362 RenderViewHost::FromID(child_route_id_pair.first, 367 RenderViewHost::FromID(child_route_id_pair.first,
363 child_route_id_pair.second); 368 child_route_id_pair.second);
364 // Don't prerender page if parent RenderViewHost no longer exists, or it has 369 // Don't prerender page if parent RenderViewHost no longer exists, or it has
365 // no view. The latter should only happen when the RenderView has closed. 370 // no view. The latter should only happen when the RenderView has closed.
366 if (!source_render_view_host || !source_render_view_host->view()) { 371 if (!source_render_view_host || !source_render_view_host->view()) {
367 RecordFinalStatus(origin, experiment, 372 RecordFinalStatus(origin, experiment,
368 FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED); 373 FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED);
369 return false; 374 return false;
370 } 375 }
371 } 376 }
372 377
373 PrerenderContents* prerender_contents = 378 if (!session_storage_namespace && source_render_view_host) {
374 CreatePrerenderContents(url, referrer, origin, experiment); 379 session_storage_namespace =
380 source_render_view_host->session_storage_namespace();
381 }
382
383 PrerenderContents* prerender_contents = CreatePrerenderContents(
384 url, referrer, origin, experiment);
375 if (!prerender_contents || !prerender_contents->Init()) 385 if (!prerender_contents || !prerender_contents->Init())
376 return false; 386 return false;
377 387
378 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 388 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
379 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 389 PrerenderContentsData data(prerender_contents, GetCurrentTime());
380 390
381 prerender_list_.push_back(data); 391 prerender_list_.push_back(data);
382 392
383 if (IsControlGroup()) { 393 if (IsControlGroup()) {
384 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); 394 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
385 } else { 395 } else {
386 last_prerender_start_time_ = GetCurrentTimeTicks(); 396 last_prerender_start_time_ = GetCurrentTimeTicks();
387 data.contents_->StartPrerendering(source_render_view_host); 397 data.contents_->StartPrerendering(source_render_view_host,
398 session_storage_namespace);
388 } 399 }
389 while (prerender_list_.size() > config_.max_elements) { 400 while (prerender_list_.size() > config_.max_elements) {
390 data = prerender_list_.front(); 401 data = prerender_list_.front();
391 prerender_list_.pop_front(); 402 prerender_list_.pop_front();
392 data.contents_->Destroy(FINAL_STATUS_EVICTED); 403 data.contents_->Destroy(FINAL_STATUS_EVICTED);
393 } 404 }
394 StartSchedulingPeriodicCleanups(); 405 StartSchedulingPeriodicCleanups();
395 return true; 406 return true;
396 } 407 }
397 408
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 } 539 }
529 540
530 // If the prerendered page is in the middle of a cross-site navigation, 541 // If the prerendered page is in the middle of a cross-site navigation,
531 // don't swap it in because there isn't a good way to merge histories. 542 // don't swap it in because there isn't a good way to merge histories.
532 if (prerender_contents->IsCrossSiteNavigationPending()) { 543 if (prerender_contents->IsCrossSiteNavigationPending()) {
533 prerender_contents.release()->Destroy( 544 prerender_contents.release()->Destroy(
534 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); 545 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
535 return false; 546 return false;
536 } 547 }
537 548
549 // If the sessionStorage namespaces don't match, don't swap the site in and
mmenke 2011/11/02 16:19:17 nit: "session storage namespaces" or "SessionStor
cbentzel 2011/11/02 17:13:49 Removed the "don't swap the site in" and just said
550 // cancel the prerender.
551 RenderViewHost* old_render_view_host = tab_contents->render_view_host();
mmenke 2011/11/02 16:19:17 What happens if the old tab has crashed? I think
cbentzel 2011/11/02 16:55:52 It's old_render_view_host->view() which could be N
mmenke 2011/11/02 17:44:07 You're right. As you say, I was getting the Rende
552 RenderViewHost* new_render_view_host =
553 prerender_contents->prerender_contents()->render_view_host();
554 DCHECK(old_render_view_host);
555 DCHECK(new_render_view_host);
556 if (old_render_view_host->session_storage_namespace() !=
557 new_render_view_host->session_storage_namespace()) {
558 prerender_contents.release()->Destroy(
559 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH);
560 return false;
561 }
562
538 int child_id, route_id; 563 int child_id, route_id;
539 CHECK(prerender_contents->GetChildId(&child_id)); 564 CHECK(prerender_contents->GetChildId(&child_id));
540 CHECK(prerender_contents->GetRouteId(&route_id)); 565 CHECK(prerender_contents->GetRouteId(&route_id));
541 566
542 // Try to set the prerendered page as used, so any subsequent attempts to 567 // Try to set the prerendered page as used, so any subsequent attempts to
543 // cancel on other threads will fail. If this fails because the prerender 568 // cancel on other threads will fail. If this fails because the prerender
544 // was already cancelled, possibly on another thread, fail. 569 // was already cancelled, possibly on another thread, fail.
545 if (!prerender_tracker_->TryUse(child_id, route_id)) 570 if (!prerender_tracker_->TryUse(child_id, route_id))
546 return false; 571 return false;
547 572
548 if (!prerender_contents->load_start_time().is_null()) { 573 if (!prerender_contents->load_start_time().is_null()) {
549 histograms_->RecordTimeUntilUsed(GetCurrentTimeTicks() - 574 histograms_->RecordTimeUntilUsed(GetCurrentTimeTicks() -
550 prerender_contents->load_start_time(), 575 prerender_contents->load_start_time(),
551 config_.max_age); 576 config_.max_age);
552 } 577 }
553 578
554 histograms_->RecordPerSessionCount(++prerenders_per_session_count_); 579 histograms_->RecordPerSessionCount(++prerenders_per_session_count_);
555 prerender_contents->set_final_status(FINAL_STATUS_USED); 580 prerender_contents->set_final_status(FINAL_STATUS_USED);
556 581
557 RenderViewHost* render_view_host = 582 new_render_view_host->Send(
558 prerender_contents->prerender_contents()->render_view_host(); 583 new ChromeViewMsg_SetIsPrerendering(new_render_view_host->routing_id(),
559 DCHECK(render_view_host);
560 render_view_host->Send(
561 new ChromeViewMsg_SetIsPrerendering(render_view_host->routing_id(),
562 false)); 584 false));
563 585
564 TabContentsWrapper* new_tab_contents = 586 TabContentsWrapper* new_tab_contents =
565 prerender_contents->ReleasePrerenderContents(); 587 prerender_contents->ReleasePrerenderContents();
566 TabContentsWrapper* old_tab_contents = 588 TabContentsWrapper* old_tab_contents =
567 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents); 589 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
568 DCHECK(new_tab_contents); 590 DCHECK(new_tab_contents);
569 DCHECK(old_tab_contents); 591 DCHECK(old_tab_contents);
570 592
571 MarkTabContentsAsPrerendered(new_tab_contents->tab_contents()); 593 MarkTabContentsAsPrerendered(new_tab_contents->tab_contents());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 return (now - start < config_.max_age); 669 return (now - start < config_.max_age);
648 } 670 }
649 671
650 PrerenderContents* PrerenderManager::CreatePrerenderContents( 672 PrerenderContents* PrerenderManager::CreatePrerenderContents(
651 const GURL& url, 673 const GURL& url,
652 const GURL& referrer, 674 const GURL& referrer,
653 Origin origin, 675 Origin origin,
654 uint8 experiment_id) { 676 uint8 experiment_id) {
655 DCHECK(CalledOnValidThread()); 677 DCHECK(CalledOnValidThread());
656 return prerender_contents_factory_->CreatePrerenderContents( 678 return prerender_contents_factory_->CreatePrerenderContents(
657 this, prerender_tracker_, profile_, url, referrer, origin, experiment_id); 679 this, prerender_tracker_, profile_, url,
680 referrer, origin, experiment_id);
658 } 681 }
659 682
660 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const { 683 bool PrerenderManager::IsPendingDelete(PrerenderContents* entry) const {
661 DCHECK(CalledOnValidThread()); 684 DCHECK(CalledOnValidThread());
662 for (std::list<PrerenderContents*>::const_iterator it = 685 for (std::list<PrerenderContents*>::const_iterator it =
663 pending_delete_list_.begin(); 686 pending_delete_list_.begin();
664 it != pending_delete_list_.end(); 687 it != pending_delete_list_.end();
665 ++it) { 688 ++it) {
666 if (*it == entry) 689 if (*it == entry)
667 return true; 690 return true;
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 if (!render_process_host || !render_process_host->browser_context()) 1034 if (!render_process_host || !render_process_host->browser_context())
1012 return NULL; 1035 return NULL;
1013 Profile* profile = Profile::FromBrowserContext( 1036 Profile* profile = Profile::FromBrowserContext(
1014 render_process_host->browser_context()); 1037 render_process_host->browser_context());
1015 if (!profile) 1038 if (!profile)
1016 return NULL; 1039 return NULL;
1017 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1040 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1018 } 1041 }
1019 1042
1020 } // namespace prerender 1043 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698