diff options
34 files changed, 236 insertions, 96 deletions
diff --git a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc index 0b5ee0a..db573c1 100644 --- a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc +++ b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc @@ -95,7 +95,7 @@ IN_PROC_BROWSER_TEST_F(ActivityLogPrerenderTest, TestScriptInjected) { scoped_ptr<prerender::PrerenderHandle> prerender_handle( prerender_manager->AddPrerenderFromLocalPredictor( url, - web_contents->GetController().GetSessionStorageNamespace(), + web_contents->GetController().GetDefaultSessionStorageNamespace(), kSize)); page_observer.Wait(); diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc index 30b8d0a..4a7958e 100644 --- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc +++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc @@ -249,7 +249,7 @@ TEST_F(ActivityLogTest, LogPrerender) { scoped_ptr<prerender::PrerenderHandle> prerender_handle( prerender_manager->AddPrerenderFromLocalPredictor( url, - web_contents()->GetController().GetSessionStorageNamespace(), + web_contents()->GetController().GetDefaultSessionStorageNamespace(), kSize)); const std::vector<content::WebContents*> contentses = @@ -271,3 +271,4 @@ TEST_F(ActivityLogTest, LogPrerender) { } } // namespace extensions + diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc index 5a1e75b..2b9e732 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor.cc @@ -138,7 +138,7 @@ void AutocompleteActionPredictor::ClearTransitionalMatches() { void AutocompleteActionPredictor::StartPrerendering( const GURL& url, - content::SessionStorageNamespace* session_storage_namespace, + const content::SessionStorageNamespaceMap& session_storage_namespace_map, const gfx::Size& size) { // Only cancel the old prerender after starting the new one, so if the URLs // are the same, the underlying prerender will be reused. @@ -146,6 +146,11 @@ void AutocompleteActionPredictor::StartPrerendering( prerender_handle_.release()); if (prerender::PrerenderManager* prerender_manager = prerender::PrerenderManagerFactory::GetForProfile(profile_)) { + content::SessionStorageNamespace* session_storage_namespace = NULL; + content::SessionStorageNamespaceMap::const_iterator it = + session_storage_namespace_map.find(std::string()); + if (it != session_storage_namespace_map.end()) + session_storage_namespace = it->second.get(); prerender_handle_.reset(prerender_manager->AddPrerenderFromOmnibox( url, session_storage_namespace, size)); } diff --git a/chrome/browser/predictors/autocomplete_action_predictor.h b/chrome/browser/predictors/autocomplete_action_predictor.h index 762d31a..b1c4f97 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.h +++ b/chrome/browser/predictors/autocomplete_action_predictor.h @@ -98,7 +98,7 @@ class AutocompleteActionPredictor // prerenders (if any). void StartPrerendering( const GURL& url, - content::SessionStorageNamespace* session_storage_namespace, + const content::SessionStorageNamespaceMap& session_storage_namespace_map, const gfx::Size& size); // Return true if the suggestion type warrants a TCP/IP preconnection. diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 36e7375..d95a0ad 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -640,7 +640,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { current_browser()->tab_strip_model()->GetActiveWebContents(); if (!web_contents) return NULL; - return web_contents->GetController().GetSessionStorageNamespace(); + return web_contents->GetController().GetDefaultSessionStorageNamespace(); } virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index 6f7caf4..957809f 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc @@ -180,8 +180,9 @@ void PrerenderContents::PrepareForUse() { SessionStorageNamespace* session_storage_namespace = NULL; if (prerender_contents_) { + // TODO(ajwong): This does not correctly handle storage for isolated apps. session_storage_namespace = prerender_contents_-> - GetController().GetSessionStorageNamespace(); + GetController().GetDefaultSessionStorageNamespace(); } prerender_manager_->StartPendingPrerenders( child_id_, &pending_prerenders_, session_storage_namespace); @@ -473,8 +474,12 @@ size_t PrerenderContents::pending_prerender_count() const { WebContents* PrerenderContents::CreateWebContents( SessionStorageNamespace* session_storage_namespace) { + // TODO(ajwong): Remove the temporary map once prerendering is aware of + // multiple session storage namespaces per tab. + content::SessionStorageNamespaceMap session_storage_namespace_map; + session_storage_namespace_map[std::string()] = session_storage_namespace; return WebContents::CreateWithSessionStorage( - WebContents::CreateParams(profile_), session_storage_namespace); + WebContents::CreateParams(profile_), session_storage_namespace_map); } void PrerenderContents::NotifyPrerenderStart() { diff --git a/chrome/browser/prerender/prerender_local_predictor.cc b/chrome/browser/prerender/prerender_local_predictor.cc index 398a06f..93525f6 100644 --- a/chrome/browser/prerender/prerender_local_predictor.cc +++ b/chrome/browser/prerender/prerender_local_predictor.cc @@ -536,7 +536,7 @@ void PrerenderLocalPredictor::OnLookupURL( scoped_refptr<SessionStorageNamespace> session_storage_namespace = - source_web_contents->GetController().GetSessionStorageNamespace(); + source_web_contents->GetController().GetDefaultSessionStorageNamespace(); gfx::Rect container_bounds; source_web_contents->GetView()->GetContainerBounds(&container_bounds); @@ -883,7 +883,7 @@ void PrerenderLocalPredictor::OnTabHelperURLSeen( p->prerender_handle->Matches( url, web_contents->GetController(). - GetSessionStorageNamespace()); + GetDefaultSessionStorageNamespace()); } } if (best_matched_prerender) { diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index 9cdeff0..7089c60 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc @@ -328,8 +328,10 @@ PrerenderHandle* PrerenderManager::AddPrerenderFromLinkRelPrerender( return NULL; if (source_web_contents->GetURL().host() == url.host()) origin = ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN; + // TODO(ajwong): This does not correctly handle storage for isolated apps. session_storage_namespace = - source_web_contents->GetController().GetSessionStorageNamespace(); + source_web_contents->GetController() + .GetDefaultSessionStorageNamespace(); } // If the prerender request comes from a recently cancelled prerender that @@ -411,8 +413,10 @@ bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, DeleteOldEntries(); to_delete_prerenders_.clear(); + // TODO(ajwong): This doesn't handle isolated apps correctly. PrerenderData* prerender_data = FindPrerenderData( - url, web_contents->GetController().GetSessionStorageNamespace()); + url, + web_contents->GetController().GetDefaultSessionStorageNamespace()); if (!prerender_data) return false; DCHECK(prerender_data->contents()); diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 59945a7..6626bfe 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc @@ -1073,18 +1073,18 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) { ui_test_utils::NavigateToURL(browser(), url1_); content::NavigationController* controller = &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); - ASSERT_TRUE(controller->GetSessionStorageNamespace()); + ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace()); std::string session_storage_persistent_id = - controller->GetSessionStorageNamespace()->persistent_id(); + controller->GetDefaultSessionStorageNamespace()->persistent_id(); Browser* new_browser = QuitBrowserAndRestore(browser(), 1); ASSERT_EQ(1u, active_browser_list_->size()); ASSERT_EQ(url1_, new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); content::NavigationController* new_controller = &new_browser->tab_strip_model()->GetActiveWebContents()->GetController(); - ASSERT_TRUE(new_controller->GetSessionStorageNamespace()); + ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace()); std::string restored_session_storage_persistent_id = - new_controller->GetSessionStorageNamespace()->persistent_id(); + new_controller->GetDefaultSessionStorageNamespace()->persistent_id(); EXPECT_EQ(session_storage_persistent_id, restored_session_storage_persistent_id); } @@ -1095,12 +1095,15 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) { { content::NavigationController* controller = &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); - ASSERT_TRUE(controller->GetSessionStorageNamespace()); + ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace()); + content::SessionStorageNamespaceMap session_storage_namespace_map; + session_storage_namespace_map[std::string()] = + controller->GetDefaultSessionStorageNamespace(); scoped_ptr<content::WebContents> web_contents( content::WebContents::CreateWithSessionStorage( content::WebContents::CreateParams(browser()->profile()), - controller->GetSessionStorageNamespace())); + session_storage_namespace_map)); TabStripModel* tab_strip_model = browser()->tab_strip_model(); scoped_ptr<content::WebContents> old_web_contents( @@ -1115,7 +1118,7 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) { content::NavigationController* controller = &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); EXPECT_TRUE( - controller->GetSessionStorageNamespace()->should_persist()); + controller->GetDefaultSessionStorageNamespace()->should_persist()); // Quit and restore. Check that no extra tabs were created. Browser* new_browser = QuitBrowserAndRestore(browser(), 1); diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc index 05bf038..dd97f43 100644 --- a/chrome/browser/sessions/session_service.cc +++ b/chrome/browser/sessions/session_service.cc @@ -1334,7 +1334,7 @@ void SessionService::BuildCommandsForTab(const SessionID& window_id, // Record the association between the sessionStorage namespace and the tab. content::SessionStorageNamespace* session_storage_namespace = - tab->GetController().GetSessionStorageNamespace(); + tab->GetController().GetDefaultSessionStorageNamespace(); ScheduleCommand(CreateSessionStorageAssociatedCommand( session_tab_helper->session_id(), session_storage_namespace->persistent_id())); @@ -1736,8 +1736,12 @@ void SessionService::TabInserted(WebContents* contents) { // Record the association between the SessionStorageNamespace and the // tab. + // + // TODO(ajwong): This should be processing the whole map rather than + // just the default. This in particular will not work for tabs with only + // isolated apps which won't have a default partition. content::SessionStorageNamespace* session_storage_namespace = - contents->GetController().GetSessionStorageNamespace(); + contents->GetController().GetDefaultSessionStorageNamespace(); ScheduleCommand(CreateSessionStorageAssociatedCommand( session_tab_helper->session_id(), session_storage_namespace->persistent_id())); @@ -1748,7 +1752,7 @@ void SessionService::TabClosing(WebContents* contents) { // Allow the associated sessionStorage to get deleted; it won't be needed // in the session restore. content::SessionStorageNamespace* session_storage_namespace = - contents->GetController().GetSessionStorageNamespace(); + contents->GetController().GetDefaultSessionStorageNamespace(); session_storage_namespace->SetShouldPersist(false); SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(contents); diff --git a/chrome/browser/sessions/tab_restore_service_helper.cc b/chrome/browser/sessions/tab_restore_service_helper.cc index 2782b47..2b13861 100644 --- a/chrome/browser/sessions/tab_restore_service_helper.cc +++ b/chrome/browser/sessions/tab_restore_service_helper.cc @@ -419,7 +419,9 @@ void TabRestoreServiceHelper::PopulateTab( tab->user_agent_override = controller->GetWebContents()->GetUserAgentOverride(); - tab->session_storage_namespace = controller->GetSessionStorageNamespace(); + // TODO(ajwong): This does not correctly handle storage for isolated apps. + tab->session_storage_namespace = + controller->GetDefaultSessionStorageNamespace(); // Delegate may be NULL during unit tests. if (delegate) { diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc index eba4e94..f039ac3 100644 --- a/chrome/browser/sync/profile_sync_service_session_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc @@ -1295,7 +1295,7 @@ TEST_F(ProfileSyncServiceSessionTest, CheckPrerenderedWebContentsSwap) { // Create new WebContents, with the required tab helpers. WebContents* new_web_contents = WebContents::CreateWithSessionStorage( WebContents::CreateParams(profile()), - old_web_contents->GetController().GetSessionStorageNamespace()); + old_web_contents->GetController().GetSessionStorageNamespaceMap()); SessionTabHelper::CreateForWebContents(new_web_contents); TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents); new_web_contents->GetController() diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc index a949fc5..9bb737a 100644 --- a/chrome/browser/ui/browser_tabrestore.cc +++ b/chrome/browser/ui/browser_tabrestore.cc @@ -14,6 +14,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/session_storage_namespace.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" @@ -44,6 +45,13 @@ WebContents* CreateRestoredTab( content::SessionStorageNamespace* session_storage_namespace, const std::string& user_agent_override) { GURL restore_url = navigations.at(selected_navigation).virtual_url(); + // TODO(ajwong): Remove the temporary session_storage_namespace_map when + // we teach session restore to understand that one tab can have multiple + // SessionStorageNamespace objects. Also remove the + // session_storage_namespace.h include since we only need that to assign + // into the map. + content::SessionStorageNamespaceMap session_storage_namespace_map; + session_storage_namespace_map[std::string()] = session_storage_namespace; WebContents::CreateParams create_params( browser->profile(), tab_util::GetSiteInstanceForNewTab(browser->profile(), restore_url)); @@ -55,7 +63,7 @@ WebContents* CreateRestoredTab( } WebContents* web_contents = content::WebContents::CreateWithSessionStorage( create_params, - session_storage_namespace); + session_storage_namespace_map); extensions::TabHelper::CreateForWebContents(web_contents); extensions::TabHelper::FromWebContents(web_contents)-> SetExtensionAppById(extension_app_id); diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc index a50c59a..7868c8c 100644 --- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc +++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc @@ -93,6 +93,6 @@ void OmniboxCurrentPageDelegateImpl::DoPrerender( predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_)-> StartPrerendering( match.destination_url, - web_contents->GetController().GetSessionStorageNamespace(), + web_contents->GetController().GetSessionStorageNamespaceMap(), container_bounds.size()); } diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc index deb8741..9ac05b7 100644 --- a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc +++ b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc @@ -292,7 +292,8 @@ class CaptureTestRenderViewHostFactory : public RenderViewHostFactory { RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) OVERRIDE { + bool swapped_out, + SessionStorageNamespace* session_storage_namespace) OVERRIDE { return new CaptureTestRenderViewHost(instance, delegate, widget_delegate, routing_id, main_frame_routing_id, swapped_out, controller_); diff --git a/content/browser/renderer_host/render_view_host_delegate.cc b/content/browser/renderer_host/render_view_host_delegate.cc index 469afa7..f340a46 100644 --- a/content/browser/renderer_host/render_view_host_delegate.cc +++ b/content/browser/renderer_host/render_view_host_delegate.cc @@ -45,8 +45,4 @@ bool RenderViewHostDelegate::IsFullscreenForCurrentTab() const { return false; } -SessionStorageNamespace* RenderViewHostDelegate::GetSessionStorageNamespace() { - return NULL; -} - } // namespace content diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index a7f5cc9..f73b041 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h @@ -414,10 +414,6 @@ class CONTENT_EXPORT RenderViewHostDelegate { const MediaStreamRequest& request, const MediaResponseCallback& callback) {} - // Returns the SessionStorageNamespace the render view should use. Might - // create the SessionStorageNamespace on the fly. - virtual SessionStorageNamespace* GetSessionStorageNamespace(); - protected: virtual ~RenderViewHostDelegate() {} }; diff --git a/content/browser/renderer_host/render_view_host_factory.cc b/content/browser/renderer_host/render_view_host_factory.cc index 20d15d3..4f01d54 100644 --- a/content/browser/renderer_host/render_view_host_factory.cc +++ b/content/browser/renderer_host/render_view_host_factory.cc @@ -19,14 +19,17 @@ RenderViewHost* RenderViewHostFactory::Create( RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) { + bool swapped_out, + SessionStorageNamespace* session_storage_namespace) { if (factory_) { return factory_->CreateRenderViewHost(instance, delegate, widget_delegate, routing_id, main_frame_routing_id, - swapped_out); + swapped_out, + session_storage_namespace); } return new RenderViewHostImpl(instance, delegate, widget_delegate, routing_id, - main_frame_routing_id, swapped_out); + main_frame_routing_id, swapped_out, + session_storage_namespace); } // static diff --git a/content/browser/renderer_host/render_view_host_factory.h b/content/browser/renderer_host/render_view_host_factory.h index 6226187..df61552 100644 --- a/content/browser/renderer_host/render_view_host_factory.h +++ b/content/browser/renderer_host/render_view_host_factory.h @@ -29,7 +29,8 @@ class RenderViewHostFactory { RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out); + bool swapped_out, + SessionStorageNamespace* session_storage); // Returns true if there is currently a globally-registered factory. static bool has_factory() { @@ -48,7 +49,8 @@ class RenderViewHostFactory { RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) = 0; + bool swapped_out, + SessionStorageNamespace* session_storage_namespace) = 0; // Registers your factory to be called when new RenderViewHosts are created. // We have only one global factory, so there must be no factory registered diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index cc08df5..23ad584 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -153,7 +153,8 @@ RenderViewHostImpl::RenderViewHostImpl( RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) + bool swapped_out, + SessionStorageNamespace* session_storage) : RenderWidgetHostImpl(widget_delegate, instance->GetProcess(), routing_id), delegate_(delegate), instance_(static_cast<SiteInstanceImpl*>(instance)), @@ -172,7 +173,10 @@ RenderViewHostImpl::RenderViewHostImpl( unload_ack_is_for_cross_site_transition_(false), are_javascript_messages_suppressed_(false), sudden_termination_allowed_(false), + session_storage_namespace_( + static_cast<SessionStorageNamespaceImpl*>(session_storage)), render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) { + DCHECK(session_storage_namespace_.get()); DCHECK(instance_.get()); CHECK(delegate_); // http://crbug.com/82827 @@ -253,8 +257,7 @@ bool RenderViewHostImpl::CreateRenderView( params.view_id = GetRoutingID(); params.main_frame_routing_id = main_render_frame_host_->routing_id(); params.surface_id = surface_id(); - params.session_storage_namespace_id = - delegate_->GetSessionStorageNamespace()->id(); + params.session_storage_namespace_id = session_storage_namespace_->id(); params.frame_name = frame_name; // Ensure the RenderView sets its opener correctly. params.opener_route_id = opener_route_id; diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 3ab434f..7f63ba9 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -123,7 +123,8 @@ class CONTENT_EXPORT RenderViewHostImpl RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out); + bool swapped_out, + SessionStorageNamespace* session_storage_namespace); virtual ~RenderViewHostImpl(); // RenderViewHost implementation. @@ -687,6 +688,9 @@ class CONTENT_EXPORT RenderViewHostImpl // True if the render view can be shut down suddenly. bool sudden_termination_allowed_; + // The session storage namespace to be used by the associated render view. + scoped_refptr<SessionStorageNamespaceImpl> session_storage_namespace_; + // The termination status of the last render view that terminated. base::TerminationStatus render_view_termination_status_; diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index 7783e80..7641261 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -24,6 +24,17 @@ namespace content { namespace { +// Normally this is done by the NavigationController, but we'll fake it out +// here for testing. +SessionStorageNamespaceImpl* CreateSessionStorageNamespace( + SiteInstance* instance) { + RenderProcessHost* process_host = instance->GetProcess(); + DOMStorageContext* dom_storage_context = + BrowserContext::GetStoragePartition(process_host->GetBrowserContext(), + instance)->GetDOMStorageContext(); + return new SessionStorageNamespaceImpl( + static_cast<DOMStorageContextImpl*>(dom_storage_context)); +} const int64 kFrameId = 13UL; @@ -247,7 +258,8 @@ TestRenderViewHost::TestRenderViewHost( widget_delegate, routing_id, main_frame_routing_id, - swapped_out), + swapped_out, + CreateSessionStorageNamespace(instance)), render_view_created_(false), delete_counter_(NULL), simulate_fetch_via_proxy_(false), diff --git a/content/browser/web_contents/interstitial_page_impl.cc b/content/browser/web_contents/interstitial_page_impl.cc index 66d2181..4acea35 100644 --- a/content/browser/web_contents/interstitial_page_impl.cc +++ b/content/browser/web_contents/interstitial_page_impl.cc @@ -493,7 +493,7 @@ RenderViewHost* InterstitialPageImpl::CreateRenderViewHost() { DOMStorageContextImpl* dom_storage_context = static_cast<DOMStorageContextImpl*>(BrowserContext::GetStoragePartition( browser_context, site_instance.get())->GetDOMStorageContext()); - session_storage_namespace_ = + SessionStorageNamespaceImpl* session_storage_namespace_impl = new SessionStorageNamespaceImpl(dom_storage_context); RenderViewHostImpl* render_view_host = @@ -502,7 +502,8 @@ RenderViewHost* InterstitialPageImpl::CreateRenderViewHost() { this, MSG_ROUTING_NONE, MSG_ROUTING_NONE, - false); + false, + session_storage_namespace_impl); web_contents_->RenderViewForInterstitialPageCreated(render_view_host); return render_view_host; } @@ -703,10 +704,6 @@ void InterstitialPageImpl::ShowCreatedFullscreenWidget(int route_id) { << "InterstitialPage does not support showing full screen popups."; } -SessionStorageNamespace* InterstitialPageImpl::GetSessionStorageNamespace() { - return session_storage_namespace_.get(); -} - void InterstitialPageImpl::Disable() { enabled_ = false; } diff --git a/content/browser/web_contents/interstitial_page_impl.h b/content/browser/web_contents/interstitial_page_impl.h index 699d8e4..be4bd8c 100644 --- a/content/browser/web_contents/interstitial_page_impl.h +++ b/content/browser/web_contents/interstitial_page_impl.h @@ -129,8 +129,6 @@ class CONTENT_EXPORT InterstitialPageImpl const gfx::Rect& initial_pos) OVERRIDE; virtual void ShowCreatedFullscreenWidget(int route_id) OVERRIDE; - virtual SessionStorageNamespace* GetSessionStorageNamespace() OVERRIDE; - // RenderWidgetHostDelegate implementation: virtual void RenderWidgetDeleted( RenderWidgetHostImpl* render_widget_host) OVERRIDE; @@ -243,8 +241,6 @@ class CONTENT_EXPORT InterstitialPageImpl base::WeakPtrFactory<InterstitialPageImpl> weak_ptr_factory_; - scoped_refptr<SessionStorageNamespace> session_storage_namespace_; - DISALLOW_COPY_AND_ASSIGN(InterstitialPageImpl); }; diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index c13f3be..3f446be 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -1214,8 +1214,14 @@ void NavigationControllerImpl::CopyStateFrom( needs_reload_ = true; InsertEntriesFrom(source, source.GetEntryCount()); - session_storage_namespace_ = static_cast<SessionStorageNamespaceImpl*>( - source.session_storage_namespace_.get())->Clone(); + for (SessionStorageNamespaceMap::const_iterator it = + source.session_storage_namespace_map_.begin(); + it != source.session_storage_namespace_map_.end(); + ++it) { + SessionStorageNamespaceImpl* source_namespace = + static_cast<SessionStorageNamespaceImpl*>(it->second.get()); + session_storage_namespace_map_[it->first] = source_namespace->Clone(); + } FinishRestore(source.last_committed_entry_index_, RESTORE_CURRENT_SESSION); @@ -1337,6 +1343,7 @@ void NavigationControllerImpl::ClearAllScreenshots() { } void NavigationControllerImpl::SetSessionStorageNamespace( + const std::string& partition_id, SessionStorageNamespace* session_storage_namespace) { if (!session_storage_namespace) return; @@ -1344,8 +1351,12 @@ void NavigationControllerImpl::SetSessionStorageNamespace( // We can't overwrite an existing SessionStorage without violating spec. // Attempts to do so may give a tab access to another tab's session storage // so die hard on an error. - CHECK(!session_storage_namespace_.get()); - session_storage_namespace_ = session_storage_namespace; + bool successful_insert = session_storage_namespace_map_.insert( + make_pair(partition_id, + static_cast<SessionStorageNamespaceImpl*>( + session_storage_namespace))) + .second; + CHECK(successful_insert) << "Cannot replace existing SessionStorageNamespace"; } void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { @@ -1357,15 +1368,45 @@ int32 NavigationControllerImpl::GetMaxRestoredPageID() const { } SessionStorageNamespace* -NavigationControllerImpl::GetSessionStorageNamespace() { - if (session_storage_namespace_.get()) - return session_storage_namespace_.get(); - - session_storage_namespace_ = - new SessionStorageNamespaceImpl(static_cast<DOMStorageContextImpl*>( - BrowserContext::GetDefaultStoragePartition(browser_context_) - ->GetDOMStorageContext())); - return session_storage_namespace_.get(); +NavigationControllerImpl::GetSessionStorageNamespace(SiteInstance* instance) { + std::string partition_id; + if (instance) { + // TODO(ajwong): When GetDefaultSessionStorageNamespace() goes away, remove + // this if statement so |instance| must not be NULL. + partition_id = + GetContentClient()->browser()->GetStoragePartitionIdForSite( + browser_context_, instance->GetSiteURL()); + } + + SessionStorageNamespaceMap::const_iterator it = + session_storage_namespace_map_.find(partition_id); + if (it != session_storage_namespace_map_.end()) + return it->second.get(); + + // Create one if no one has accessed session storage for this partition yet. + // + // TODO(ajwong): Should this use the |partition_id| directly rather than + // re-lookup via |instance|? http://crbug.com/142685 + StoragePartition* partition = + BrowserContext::GetStoragePartition(browser_context_, instance); + SessionStorageNamespaceImpl* session_storage_namespace = + new SessionStorageNamespaceImpl( + static_cast<DOMStorageContextImpl*>( + partition->GetDOMStorageContext())); + session_storage_namespace_map_[partition_id] = session_storage_namespace; + + return session_storage_namespace; +} + +SessionStorageNamespace* +NavigationControllerImpl::GetDefaultSessionStorageNamespace() { + // TODO(ajwong): Remove if statement in GetSessionStorageNamespace(). + return GetSessionStorageNamespace(NULL); +} + +const SessionStorageNamespaceMap& +NavigationControllerImpl::GetSessionStorageNamespaceMap() const { + return session_storage_namespace_map_; } bool NavigationControllerImpl::NeedsReload() const { diff --git a/content/browser/web_contents/navigation_controller_impl.h b/content/browser/web_contents/navigation_controller_impl.h index 69a3a73..f0fd491 100644 --- a/content/browser/web_contents/navigation_controller_impl.h +++ b/content/browser/web_contents/navigation_controller_impl.h @@ -70,7 +70,10 @@ class CONTENT_EXPORT NavigationControllerImpl virtual void GoToIndex(int index) OVERRIDE; virtual void GoToOffset(int offset) OVERRIDE; virtual void RemoveEntryAtIndex(int index) OVERRIDE; - virtual SessionStorageNamespace* GetSessionStorageNamespace() OVERRIDE; + virtual const SessionStorageNamespaceMap& + GetSessionStorageNamespaceMap() const OVERRIDE; + virtual SessionStorageNamespace* + GetDefaultSessionStorageNamespace() OVERRIDE; virtual void SetMaxRestoredPageID(int32 max_id) OVERRIDE; virtual int32 GetMaxRestoredPageID() const OVERRIDE; virtual bool NeedsReload() const OVERRIDE; @@ -90,6 +93,11 @@ class CONTENT_EXPORT NavigationControllerImpl virtual void PruneAllButVisible() OVERRIDE; virtual void ClearAllScreenshots() OVERRIDE; + // The session storage namespace that all child RenderViews belonging to + // |instance| should use. + SessionStorageNamespace* GetSessionStorageNamespace( + SiteInstance* instance); + // Returns the index of the specified entry, or -1 if entry is not contained // in this NavigationController. int GetIndexOfEntry(const NavigationEntryImpl* entry) const; @@ -157,13 +165,16 @@ class CONTENT_EXPORT NavigationControllerImpl // origin isn't changing. bool IsURLInPageNavigation(const GURL& url, bool renderer_says_in_page) const; - // Sets the SessionStorageNamespace. This is used during initialization of a - // new NavigationController. Session restore, prerendering, and the - // implementaion of window.open() are the primary users of this API. + // Sets the SessionStorageNamespace for the given |partition_id|. This is + // used during initialization of a new NavigationController to allow + // pre-population of the SessionStorageNamespace objects. Session restore, + // prerendering, and the implementaion of window.open() are the primary users + // of this API. // // Calling this function when a SessionStorageNamespace has already been - // associated will CHECK() fail. + // associated with a |partition_id| will CHECK() fail. void SetSessionStorageNamespace( + const std::string& partition_id, SessionStorageNamespace* session_storage_namespace); // Random data --------------------------------------------------------------- @@ -359,7 +370,14 @@ class CONTENT_EXPORT NavigationControllerImpl // Becomes false when initial navigation commits. bool is_initial_navigation_; - scoped_refptr<SessionStorageNamespace> session_storage_namespace_; + // Used to find the appropriate SessionStorageNamespace for the storage + // partition of a NavigationEntry. + // + // A NavigationController may contain NavigationEntries that correspond to + // different StoragePartitions. Even though they are part of the same + // NavigationController, only entries in the same StoragePartition may + // share session storage state with one another. + SessionStorageNamespaceMap session_storage_namespace_map_; // The maximum number of entries that a navigation controller can store. static size_t max_entry_count_for_testing_; diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc index 603b20c..2c327f2 100644 --- a/content/browser/web_contents/navigation_controller_impl_unittest.cc +++ b/content/browser/web_contents/navigation_controller_impl_unittest.cc @@ -198,9 +198,6 @@ class NavigationControllerTest WebContents* web_contents = RenderViewHostImplTestHarness::web_contents(); ASSERT_TRUE(web_contents); // The WebContents should be created by now. WebContentsObserver::Observe(web_contents); - // Ensure that SessionStorageNamespace gets created in the test, too. In - // production code, it's created on demand when a RenderView is created. - controller().GetSessionStorageNamespace(); } // WebContentsObserver: @@ -2924,6 +2921,26 @@ TEST_F(NavigationControllerTest, CopyStateFrom) { SiteInstance* instance1 = GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)); EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); + + // Ensure the SessionStorageNamespaceMaps are the same size and have + // the same partitons loaded. + // + // TODO(ajwong): We should load a url from a different partition earlier + // to make sure this map has more than one entry. + const SessionStorageNamespaceMap& session_storage_namespace_map = + controller.GetSessionStorageNamespaceMap(); + const SessionStorageNamespaceMap& other_session_storage_namespace_map = + other_controller.GetSessionStorageNamespaceMap(); + EXPECT_EQ(session_storage_namespace_map.size(), + other_session_storage_namespace_map.size()); + for (SessionStorageNamespaceMap::const_iterator it = + session_storage_namespace_map.begin(); + it != session_storage_namespace_map.end(); + ++it) { + SessionStorageNamespaceMap::const_iterator other = + other_session_storage_namespace_map.find(it->first); + EXPECT_TRUE(other != other_session_storage_namespace_map.end()); + } } // Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest. diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc index 4201eb8..4c93537 100644 --- a/content/browser/web_contents/render_view_host_manager.cc +++ b/content/browser/web_contents/render_view_host_manager.cc @@ -83,7 +83,9 @@ void RenderViewHostManager::Init(BrowserContext* browser_context, render_view_host_ = static_cast<RenderViewHostImpl*>( RenderViewHostFactory::Create( site_instance, render_view_delegate_, render_widget_delegate_, - routing_id, main_frame_routing_id, false)); + routing_id, main_frame_routing_id, false, delegate_-> + GetControllerForRenderManager().GetSessionStorageNamespace( + site_instance))); // Keep track of renderer processes as they start to shut down or are // crashed/killed. @@ -659,11 +661,10 @@ int RenderViewHostManager::CreateRenderView( // Create a new RenderViewHost if we don't find an existing one. new_render_view_host = static_cast<RenderViewHostImpl*>( RenderViewHostFactory::Create(instance, - render_view_delegate_, - render_widget_delegate_, - MSG_ROUTING_NONE, - MSG_ROUTING_NONE, - swapped_out)); + render_view_delegate_, render_widget_delegate_, MSG_ROUTING_NONE, + MSG_ROUTING_NONE, swapped_out, delegate_-> + GetControllerForRenderManager().GetSessionStorageNamespace( + instance))); // If the new RVH is swapped out already, store it. Otherwise prevent the // process from exiting while we're trying to navigate in it. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 53fb4bc..068f7c9 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -272,11 +272,18 @@ WebContents* WebContents::Create(const WebContents::CreateParams& params) { WebContents* WebContents::CreateWithSessionStorage( const WebContents::CreateParams& params, - SessionStorageNamespace* session_storage_namespace) { + const SessionStorageNamespaceMap& session_storage_namespace_map) { WebContentsImpl* new_contents = new WebContentsImpl( params.browser_context, NULL); - new_contents->GetController() - .SetSessionStorageNamespace(session_storage_namespace); + + for (SessionStorageNamespaceMap::const_iterator it = + session_storage_namespace_map.begin(); + it != session_storage_namespace_map.end(); + ++it) { + new_contents->GetController() + .SetSessionStorageNamespace(it->first, it->second.get()); + } + new_contents->Init(params); return new_contents; } @@ -1460,6 +1467,10 @@ void WebContentsImpl::CreateNewWindow( // We must assign the SessionStorageNamespace before calling Init(). // // http://crbug.com/142685 + const std::string& partition_id = + GetContentClient()->browser()-> + GetStoragePartitionIdForSite(GetBrowserContext(), + site_instance->GetSiteURL()); StoragePartition* partition = BrowserContext::GetStoragePartition( GetBrowserContext(), site_instance.get()); DOMStorageContextImpl* dom_storage_context = @@ -1468,6 +1479,7 @@ void WebContentsImpl::CreateNewWindow( static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace); CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); new_contents->GetController().SetSessionStorageNamespace( + partition_id, session_storage_namespace); CreateParams create_params(GetBrowserContext(), site_instance.get()); create_params.routing_id = route_id; @@ -1687,10 +1699,6 @@ void WebContentsImpl::RequestMediaAccessPermission( callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); } -SessionStorageNamespace* WebContentsImpl::GetSessionStorageNamespace() { - return controller_.GetSessionStorageNamespace(); -} - void WebContentsImpl::DidSendScreenRects(RenderWidgetHostImpl* rwh) { if (browser_plugin_embedder_) browser_plugin_embedder_->DidSendScreenRects(); diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 6459236..b42748c 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -449,7 +449,6 @@ class CONTENT_EXPORT WebContentsImpl virtual void RequestMediaAccessPermission( const MediaStreamRequest& request, const MediaResponseCallback& callback) OVERRIDE; - virtual SessionStorageNamespace* GetSessionStorageNamespace() OVERRIDE; // RenderWidgetHostDelegate -------------------------------------------------- diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 3b93ef1..9770223 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h @@ -30,6 +30,11 @@ class NavigationEntry; class SessionStorageNamespace; class WebContents; +// Used to store the mapping of a StoragePartition id to +// SessionStorageNamespace. +typedef std::map<std::string, scoped_refptr<SessionStorageNamespace> > + SessionStorageNamespaceMap; + // A NavigationController maintains the back-forward list for a WebContents and // manages all navigation within that list. // @@ -340,7 +345,14 @@ class NavigationController { // Session storage depends on dom_storage that depends on WebKit::WebString, // which cannot be used on iOS. #if !defined(OS_IOS) - virtual SessionStorageNamespace* GetSessionStorageNamespace() = 0; + // Returns all the SessionStorageNamespace objects that this + // NavigationController knows about. + virtual const SessionStorageNamespaceMap& + GetSessionStorageNamespaceMap() const = 0; + + // TODO(ajwong): Remove this once prerendering, instant, and session restore + // are migrated. + virtual SessionStorageNamespace* GetDefaultSessionStorageNamespace() = 0; #endif // Sets the max restored page ID this NavigationController has seen, if it diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 47cd101..037fef84 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h @@ -91,8 +91,8 @@ class WebContents : public PageNavigator, // Creates a new WebContents. CONTENT_EXPORT static WebContents* Create(const CreateParams& params); - // Similar to Create() above but should be used when you need to set the - // the SessionStorageNamespace of the WebContents. This can happen if + // Similar to Create() above but should be used when you need to prepopulate + // the SessionStorageNamespaceMap of the WebContents. This can happen if // you duplicate a WebContents, try to reconstitute it from a saved state, // or when you create a new WebContents based on another one (eg., when // servicing a window.open() call). @@ -103,7 +103,7 @@ class WebContents : public PageNavigator, // can happen if you share the object. CONTENT_EXPORT static WebContents* CreateWithSessionStorage( const CreateParams& params, - SessionStorageNamespace* session_storage_namespace); + const SessionStorageNamespaceMap& session_storage_namespace_map); // Adds/removes a callback called on creation of each new WebContents. typedef base::Callback<void(WebContents*)> CreatedCallback; diff --git a/content/test/test_render_view_host_factory.cc b/content/test/test_render_view_host_factory.cc index ca86f09..47213aa 100644 --- a/content/test/test_render_view_host_factory.cc +++ b/content/test/test_render_view_host_factory.cc @@ -32,7 +32,8 @@ RenderViewHost* TestRenderViewHostFactory::CreateRenderViewHost( RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) { + bool swapped_out, + SessionStorageNamespace* session_storage) { return new TestRenderViewHost( instance, delegate, widget_delegate, routing_id, main_frame_routing_id, swapped_out); diff --git a/content/test/test_render_view_host_factory.h b/content/test/test_render_view_host_factory.h index e93762f..d194b2c 100644 --- a/content/test/test_render_view_host_factory.h +++ b/content/test/test_render_view_host_factory.h @@ -33,7 +33,8 @@ class TestRenderViewHostFactory : public RenderViewHostFactory { RenderWidgetHostDelegate* widget_delegate, int routing_id, int main_frame_routing_id, - bool swapped_out) OVERRIDE; + bool swapped_out, + SessionStorageNamespace* session_storage) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(TestRenderViewHostFactory); |