From 4c3a235850730f45ee734eef73e79fe386826950 Mon Sep 17 00:00:00 2001 From: "ajwong@chromium.org" Date: Sat, 18 Aug 2012 08:54:34 +0000 Subject: Move StoragePartition into content/public and remove BrowserContext::GetDOMStorageContext(). Eventually all the storage context accessors will be removed from BrowserContext. Instead, users should retrieve the storage context from the StoragePartition. This also changes RenderProcessHost to take in a StoragePartition removing the need for a re-lookup its storage contexts. BUG=85121,143486 Review URL: https://chromiumcodereview.appspot.com/10837230 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152251 0039d316-1c4b-4281-b951-d872f2087c98 --- content/browser/browser_context.cc | 182 ++++++++------------- .../browser/renderer_host/render_message_filter.cc | 7 +- .../browser/renderer_host/render_message_filter.h | 3 +- .../renderer_host/render_process_host_impl.cc | 18 +- .../renderer_host/render_process_host_impl.h | 13 +- .../browser/renderer_host/test_render_view_host.cc | 5 +- content/browser/site_instance_impl.cc | 32 ++-- content/browser/site_instance_impl_unittest.cc | 30 +++- content/browser/storage_partition.cc | 104 ------------ content/browser/storage_partition.h | 77 --------- content/browser/storage_partition_impl.cc | 126 ++++++++++++++ content/browser/storage_partition_impl.h | 57 +++++++ content/browser/storage_partition_impl_map.cc | 95 +++++++++++ content/browser/storage_partition_impl_map.h | 50 ++++++ content/browser/storage_partition_map.cc | 94 ----------- content/browser/storage_partition_map.h | 49 ------ .../browser/web_contents/interstitial_page_impl.cc | 9 +- .../web_contents/navigation_controller_impl.cc | 9 +- content/browser/web_contents/web_contents_impl.cc | 10 +- content/content_browser.gypi | 9 +- content/public/browser/browser_context.h | 25 ++- content/public/browser/resource_context.h | 1 + content/public/browser/storage_partition.h | 53 ++++++ 23 files changed, 569 insertions(+), 489 deletions(-) delete mode 100644 content/browser/storage_partition.cc delete mode 100644 content/browser/storage_partition.h create mode 100644 content/browser/storage_partition_impl.cc create mode 100644 content/browser/storage_partition_impl.h create mode 100644 content/browser/storage_partition_impl_map.cc create mode 100644 content/browser/storage_partition_impl_map.h delete mode 100644 content/browser/storage_partition_map.cc delete mode 100644 content/browser/storage_partition_map.h create mode 100644 content/public/browser/storage_partition.h (limited to 'content') diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 15735c9..527fe43 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc @@ -11,8 +11,8 @@ #include "content/browser/in_process_webkit/indexed_db_context_impl.h" #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" #include "content/public/browser/resource_context.h" -#include "content/browser/storage_partition.h" -#include "content/browser/storage_partition_map.h" +#include "content/browser/storage_partition_impl.h" +#include "content/browser/storage_partition_impl_map.h" #include "content/common/child_process_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -35,53 +35,22 @@ namespace { StoragePartition* GetStoragePartitionByPartitionId( BrowserContext* browser_context, const std::string& partition_id) { - StoragePartitionMap* partition_map = static_cast( - browser_context->GetUserData(kStorageParitionMapKeyName)); + StoragePartitionImplMap* partition_map = + static_cast( + browser_context->GetUserData(kStorageParitionMapKeyName)); if (!partition_map) { - partition_map = new StoragePartitionMap(browser_context); + partition_map = new StoragePartitionImplMap(browser_context); browser_context->SetUserData(kStorageParitionMapKeyName, partition_map); } return partition_map->Get(partition_id); } -StoragePartition* GetStoragePartition(BrowserContext* browser_context, - int renderer_child_id) { - const std::string& partition_id = - GetContentClient()->browser()->GetStoragePartitionIdForChildProcess( - browser_context, - renderer_child_id); - - return GetStoragePartitionByPartitionId(browser_context, partition_id); -} - -// Run |callback| on each storage partition in |browser_context|. -void ForEachStoragePartition( - BrowserContext* browser_context, - const base::Callback& callback) { - StoragePartitionMap* partition_map = static_cast( - browser_context->GetUserData(kStorageParitionMapKeyName)); - if (!partition_map) { - return; - } - - partition_map->ForEach(callback); -} - -// Used to convert a callback meant to take a DOMStorageContextImpl* into one -// that can take a StoragePartition*. -void ProcessDOMStorageContext( - const base::Callback& callback, - StoragePartition* partition) { - callback.Run(partition->dom_storage_context()); -} - // Run |callback| on each DOMStorageContextImpl in |browser_context|. -void ForEachDOMStorageContext( - BrowserContext* browser_context, - const base::Callback& callback) { - ForEachStoragePartition(browser_context, - base::Bind(&ProcessDOMStorageContext, callback)); +void PurgeDOMStorageContextInPartition(const std::string& id, + StoragePartition* storage_partition) { + static_cast(storage_partition)-> + GetDOMStorageContext()->PurgeMemory(); } void SaveSessionStateOnIOThread(ResourceContext* resource_context) { @@ -102,12 +71,6 @@ void PurgeMemoryOnIOThread(ResourceContext* resource_context) { ResourceContext::GetAppCacheService(resource_context)->PurgeMemory(); } -DOMStorageContextImpl* GetDefaultDOMStorageContextImpl( - BrowserContext* context) { - return static_cast( - BrowserContext::GetDefaultDOMStorageContext(context)); -} - } // namespace DownloadManager* BrowserContext::GetDownloadManager( @@ -134,87 +97,82 @@ DownloadManager* BrowserContext::GetDownloadManager( quota::QuotaManager* BrowserContext::GetQuotaManager( BrowserContext* browser_context) { - // TODO(ajwong): Change this API to require a process id instead of using - // kInvalidChildProcessId. - StoragePartition* partition = - GetStoragePartition(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); - return partition->quota_manager(); + // TODO(ajwong): Change this API to require a SiteInstance instead of + // using GetDefaultStoragePartition(). + return GetDefaultStoragePartition(browser_context)->GetQuotaManager(); } -DOMStorageContext* BrowserContext::GetDefaultDOMStorageContext( +IndexedDBContext* BrowserContext::GetIndexedDBContext( BrowserContext* browser_context) { - // TODO(ajwong): Force all users to know which process id they are performing - // actions on behalf of, migrate them to GetDOMStorageContext(), and then - // delete this function. - return GetDOMStorageContext(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); + // TODO(ajwong): Change this API to require a SiteInstance instead of + // using GetDefaultStoragePartition(). + return GetDefaultStoragePartition(browser_context)->GetIndexedDBContext(); } -DOMStorageContext* BrowserContext::GetDOMStorageContext( - BrowserContext* browser_context, - int render_child_id) { - StoragePartition* partition = - GetStoragePartition(browser_context, render_child_id); - return partition->dom_storage_context(); +webkit_database::DatabaseTracker* BrowserContext::GetDatabaseTracker( + BrowserContext* browser_context) { + // TODO(ajwong): Change this API to require a SiteInstance instead of + // using GetDefaultStoragePartition(). + return GetDefaultStoragePartition(browser_context)->GetDatabaseTracker(); } -DOMStorageContext* BrowserContext::GetDOMStorageContextByPartitionId( - BrowserContext* browser_context, - const std::string& partition_id) { - StoragePartition* partition = - GetStoragePartitionByPartitionId(browser_context, partition_id); - return partition->dom_storage_context(); +appcache::AppCacheService* BrowserContext::GetAppCacheService( + BrowserContext* browser_context) { + // TODO(ajwong): Change this API to require a SiteInstance instead of + // using GetDefaultStoragePartition(). + return GetDefaultStoragePartition(browser_context)->GetAppCacheService(); } -IndexedDBContext* BrowserContext::GetIndexedDBContext( +fileapi::FileSystemContext* BrowserContext::GetFileSystemContext( BrowserContext* browser_context) { - // TODO(ajwong): Change this API to require a process id instead of using - // kInvalidChildProcessId. - StoragePartition* partition = - GetStoragePartition(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); - return partition->indexed_db_context(); + // TODO(ajwong): Change this API to require a SiteInstance instead of + // using GetDefaultStoragePartition(). + return GetDefaultStoragePartition(browser_context)->GetFileSystemContext(); } -webkit_database::DatabaseTracker* BrowserContext::GetDatabaseTracker( - BrowserContext* browser_context) { - // TODO(ajwong): Change this API to require a process id instead of using - // kInvalidChildProcessId. - StoragePartition* partition = - GetStoragePartition(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); - return partition->database_tracker(); +StoragePartition* BrowserContext::GetStoragePartition( + BrowserContext* browser_context, + SiteInstance* site_instance) { + std::string partition_id; // Default to "" for NULL |site_instance|. + + // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of + // this conditional and require that |site_instance| is non-NULL. + if (site_instance) { + partition_id = GetContentClient()->browser()-> + GetStoragePartitionIdForSiteInstance(browser_context, + site_instance); + } + + return GetStoragePartitionByPartitionId(browser_context, partition_id); } -appcache::AppCacheService* BrowserContext::GetAppCacheService( - BrowserContext* browser_context) { - // TODO(ajwong): Change this API to require a process id instead of using - // kInvalidChildProcessId. - StoragePartition* partition = - GetStoragePartition(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); - return partition->appcache_service(); +void BrowserContext::ForEachStoragePartition( + BrowserContext* browser_context, + const StoragePartitionCallback& callback) { + StoragePartitionImplMap* partition_map = + static_cast( + browser_context->GetUserData(kStorageParitionMapKeyName)); + if (!partition_map) + return; + + partition_map->ForEach(callback); } -fileapi::FileSystemContext* BrowserContext::GetFileSystemContext( +StoragePartition* BrowserContext::GetDefaultStoragePartition( BrowserContext* browser_context) { - // TODO(ajwong): Change this API to require a process id instead of using - // kInvalidChildProcessId. - StoragePartition* partition = - GetStoragePartition(browser_context, - ChildProcessHostImpl::kInvalidChildProcessId); - return partition->filesystem_context(); + return GetStoragePartition(browser_context, NULL); } void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) { // This will be enough to tickle initialization of BrowserContext if // necessary, which initializes ResourceContext. The reason we don't call - // ResourceContext::InitializeResourceContext directly here is that if - // ResourceContext ends up initializing it will call back into BrowserContext - // and when that call returns it'll end rewriting its UserData map (with the - // same value) but this causes a race condition. See http://crbug.com/115678. - GetStoragePartition(context, ChildProcessHostImpl::kInvalidChildProcessId); + // ResourceContext::InitializeResourceContext() directly here is that + // ResourceContext initialization may call back into BrowserContext + // and when that call returns it'll end rewriting its UserData map. It will + // end up rewriting the same value but this still causes a race condition. + // + // See http://crbug.com/115678. + GetDefaultStoragePartition(context); } void BrowserContext::SaveSessionState(BrowserContext* browser_context) { @@ -227,10 +185,10 @@ void BrowserContext::SaveSessionState(BrowserContext* browser_context) { browser_context->GetResourceContext())); } - // TODO(ajwong): This is the only usage of GetDefaultDOMStorageContextImpl(). - // After we migrate this to support multiple DOMStorageContexts, don't forget - // to remove the GetDefaultDOMStorageContextImpl() function as well. - GetDefaultDOMStorageContextImpl(browser_context)->SetForceKeepSessionState(); + DOMStorageContextImpl* dom_storage_context_impl = + static_cast( + GetDefaultStoragePartition(browser_context)->GetDOMStorageContext()); + dom_storage_context_impl->SetForceKeepSessionState(); if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { IndexedDBContextImpl* indexed_db = static_cast( @@ -250,8 +208,8 @@ void BrowserContext::PurgeMemory(BrowserContext* browser_context) { browser_context->GetResourceContext())); } - ForEachDOMStorageContext(browser_context, - base::Bind(&DOMStorageContextImpl::PurgeMemory)); + ForEachStoragePartition(browser_context, + base::Bind(&PurgeDOMStorageContextInPartition)); } BrowserContext::~BrowserContext() { diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 55c37e9..11738b2 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -276,7 +276,8 @@ RenderMessageFilter::RenderMessageFilter( BrowserContext* browser_context, net::URLRequestContextGetter* request_context, RenderWidgetHelper* render_widget_helper, - MediaObserver* media_observer) + MediaObserver* media_observer, + DOMStorageContextImpl* dom_storage_context) : resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()), plugin_service_(plugin_service), profile_data_directory_(browser_context->GetPath()), @@ -284,9 +285,7 @@ RenderMessageFilter::RenderMessageFilter( resource_context_(browser_context->GetResourceContext()), render_widget_helper_(render_widget_helper), incognito_(browser_context->IsOffTheRecord()), - dom_storage_context_(static_cast( - BrowserContext::GetDOMStorageContext(browser_context, - render_process_id))), + dom_storage_context_(dom_storage_context), render_process_id_(render_process_id), cpu_usage_(0), media_observer_(media_observer) { diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 10d2b92..0ab0135 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -78,7 +78,8 @@ class RenderMessageFilter : public BrowserMessageFilter { BrowserContext* browser_context, net::URLRequestContextGetter* request_context, RenderWidgetHelper* render_widget_helper, - MediaObserver* media_observer); + MediaObserver* media_observer, + DOMStorageContextImpl* dom_storage_context); // IPC::ChannelProxy::MessageFilter methods: virtual void OnChannelClosing() OVERRIDE; diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 77a9d61..69ba4f5 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -81,6 +81,7 @@ #include "content/browser/renderer_host/socket_stream_dispatcher_host.h" #include "content/browser/renderer_host/text_input_client_message_filter.h" #include "content/browser/resolve_proxy_msg_helper.h" +#include "content/browser/storage_partition_impl.h" #include "content/browser/speech/input_tag_speech_dispatcher_host.h" #include "content/browser/speech/speech_recognition_dispatcher_host.h" #include "content/browser/trace_message_filter.h" @@ -321,7 +322,9 @@ void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { } RenderProcessHostImpl::RenderProcessHostImpl( - BrowserContext* browser_context, bool is_guest) + BrowserContext* browser_context, + StoragePartitionImpl* storage_partition_impl, + bool is_guest) : fast_shutdown_started_(false), deleting_soon_(false), pending_views_(0), @@ -333,6 +336,7 @@ RenderProcessHostImpl::RenderProcessHostImpl( is_initialized_(false), id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), browser_context_(browser_context), + storage_partition_impl_(storage_partition_impl), sudden_termination_allowed_(true), ignore_input_events_(false), is_guest_(is_guest) { @@ -512,7 +516,8 @@ void RenderProcessHostImpl::CreateMessageFilters() { GetBrowserContext(), GetBrowserContext()->GetRequestContextForRenderProcess(GetID()), widget_helper_, - media_observer)); + media_observer, + storage_partition_impl_->GetDOMStorageContext())); channel_->AddFilter(render_message_filter); BrowserContext* browser_context = GetBrowserContext(); ResourceContext* resource_context = browser_context->GetResourceContext(); @@ -534,9 +539,10 @@ void RenderProcessHostImpl::CreateMessageFilters() { BrowserContext::GetAppCacheService(browser_context)), GetID())); channel_->AddFilter(new ClipboardMessageFilter()); - channel_->AddFilter(new DOMStorageMessageFilter(GetID(), - static_cast( - BrowserContext::GetDOMStorageContext(browser_context, GetID())))); + channel_->AddFilter( + new DOMStorageMessageFilter( + GetID(), + storage_partition_impl_->GetDOMStorageContext())); channel_->AddFilter(new IndexedDBDispatcherHost(GetID(), static_cast( BrowserContext::GetIndexedDBContext(browser_context)))); @@ -596,7 +602,7 @@ void RenderProcessHostImpl::CreateMessageFilters() { browser_context->GetRequestContextForRenderProcess(GetID()))); channel_->AddFilter(new QuotaDispatcherHost( GetID(), - BrowserContext::GetQuotaManager(browser_context), + storage_partition_impl_->GetQuotaManager(), GetContentClient()->browser()->CreateQuotaPermissionContext())); channel_->AddFilter(new GamepadBrowserMessageFilter(this)); channel_->AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER)); diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 1d568ad..3876b8a 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -26,6 +26,7 @@ class RendererMainThread; class RenderWidgetHelper; class RenderWidgetHost; class RenderWidgetHostImpl; +class StoragePartitionImpl; // Implements a concrete RenderProcessHost for the browser process for talking // to actual renderer processes (as opposed to mocks). @@ -41,11 +42,18 @@ class RenderWidgetHostImpl; // keeps a list of RenderView (renderer) and WebContentsImpl (browser) which // are correlated with IDs. This way, the Views and the corresponding ViewHosts // communicate through the two process objects. +// +// A RenderProcessHost is also associated with one and only one +// StoragePartition. This allows us to implement strong storage isolation +// because all the IPCs from the RenderViews (renderer) will only ever be able +// to access the partition they are assigned to. class CONTENT_EXPORT RenderProcessHostImpl : public RenderProcessHost, public ChildProcessLauncher::Client { public: - RenderProcessHostImpl(BrowserContext* browser_context, bool is_guest); + RenderProcessHostImpl(BrowserContext* browser_context, + StoragePartitionImpl* storage_partition_impl, + bool is_guest); virtual ~RenderProcessHostImpl(); // RenderProcessHost implementation (public portion). @@ -259,6 +267,9 @@ class CONTENT_EXPORT RenderProcessHostImpl BrowserContext* browser_context_; + // Owned by |browser_context_|. + StoragePartitionImpl* storage_partition_impl_; + // True if the process can be shut down suddenly. If this is true, then we're // sure that all the RenderViews in the process can be shutdown suddenly. If // it's false, then specific RenderViews might still be allowed to be shutdown diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index 53564b3..58796ea 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -12,6 +12,7 @@ #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_controller.h" +#include "content/public/browser/storage_partition.h" #include "content/public/common/content_client.h" #include "ui/gfx/rect.h" #include "webkit/dom_storage/dom_storage_types.h" @@ -31,8 +32,8 @@ SessionStorageNamespaceImpl* CreateSessionStorageNamespace( SiteInstance* instance) { RenderProcessHost* process_host = instance->GetProcess(); DOMStorageContext* dom_storage_context = - BrowserContext::GetDOMStorageContext(process_host->GetBrowserContext(), - process_host->GetID()); + BrowserContext::GetStoragePartition(process_host->GetBrowserContext(), + instance)->GetDOMStorageContext(); return new SessionStorageNamespaceImpl( static_cast(dom_storage_context)); } diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index bded902..d8fcd0e 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc @@ -8,6 +8,7 @@ #include "content/browser/browsing_instance.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/storage_partition_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -17,9 +18,11 @@ #include "content/public/common/url_constants.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +using content::BrowserContext; using content::RenderProcessHost; using content::RenderProcessHostImpl; using content::SiteInstance; +using content::StoragePartitionImpl; using content::WebUIControllerFactory; static bool IsURLSameAsAnySiteInstance(const GURL& url) { @@ -93,8 +96,7 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() { // Create a new process if ours went away or was reused. if (!process_) { - content::BrowserContext* browser_context = - browsing_instance_->browser_context(); + BrowserContext* browser_context = browsing_instance_->browser_context(); // If we should use process-per-site mode (either in general or for the // given site), then look for an existing RenderProcessHost for the site. @@ -118,8 +120,11 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() { process_ = render_process_host_factory_->CreateRenderProcessHost( browser_context); } else { + StoragePartitionImpl* partition = + static_cast( + BrowserContext::GetStoragePartition(browser_context, this)); process_ = - new RenderProcessHostImpl(browser_context, + new RenderProcessHostImpl(browser_context, partition, site_.SchemeIs(chrome::kGuestScheme)); } } @@ -154,8 +159,7 @@ void SiteInstanceImpl::SetSite(const GURL& url) { // Remember that this SiteInstance has been used to load a URL, even if the // URL is invalid. has_site_ = true; - content::BrowserContext* browser_context = - browsing_instance_->browser_context(); + BrowserContext* browser_context = browsing_instance_->browser_context(); site_ = GetSiteForURL(browser_context, url); // Now that we have a site, register it with the BrowsingInstance. This @@ -214,18 +218,18 @@ bool SiteInstanceImpl::HasWrongProcessForURL(const GURL& url) const { process_, browsing_instance_->browser_context(), site_url); } -content::BrowserContext* SiteInstanceImpl::GetBrowserContext() const { +BrowserContext* SiteInstanceImpl::GetBrowserContext() const { return browsing_instance_->browser_context(); } /*static*/ -SiteInstance* SiteInstance::Create(content::BrowserContext* browser_context) { +SiteInstance* SiteInstance::Create(BrowserContext* browser_context) { return new SiteInstanceImpl(new BrowsingInstance(browser_context)); } /*static*/ -SiteInstance* SiteInstance::CreateForURL( - content::BrowserContext* browser_context, const GURL& url) { +SiteInstance* SiteInstance::CreateForURL(BrowserContext* browser_context, + const GURL& url) { // This BrowsingInstance may be deleted if it returns an existing // SiteInstance. scoped_refptr instance( @@ -234,7 +238,7 @@ SiteInstance* SiteInstance::CreateForURL( } /*static*/ -GURL SiteInstanceImpl::GetSiteForURL(content::BrowserContext* browser_context, +GURL SiteInstanceImpl::GetSiteForURL(BrowserContext* browser_context, const GURL& real_url) { // TODO(fsamuel, creis): For some reason appID is not recognized as a host. if (real_url.SchemeIs(chrome::kGuestScheme)) @@ -274,7 +278,7 @@ GURL SiteInstanceImpl::GetSiteForURL(content::BrowserContext* browser_context, } /*static*/ -bool SiteInstance::IsSameWebSite(content::BrowserContext* browser_context, +bool SiteInstance::IsSameWebSite(BrowserContext* browser_context, const GURL& real_url1, const GURL& real_url2) { GURL url1 = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url1); @@ -303,9 +307,8 @@ bool SiteInstance::IsSameWebSite(content::BrowserContext* browser_context, } /*static*/ -GURL SiteInstanceImpl::GetEffectiveURL( - content::BrowserContext* browser_context, - const GURL& url) { +GURL SiteInstanceImpl::GetEffectiveURL(BrowserContext* browser_context, + const GURL& url) { return content::GetContentClient()->browser()-> GetEffectiveURL(browser_context, url); } @@ -327,4 +330,3 @@ void SiteInstanceImpl::LockToOrigin() { policy->LockToOrigin(process_->GetID(), site_); } } - diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index bd7997d..45d1600 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc @@ -135,14 +135,20 @@ class SiteInstanceTest : public testing::Test { content::GetContentClient()->set_browser_for_testing(old_browser_client_); content::SetContentClient(old_client_); - MessageLoop::current()->RunAllPending(); - message_loop_.RunAllPending(); } void set_privileged_process_id(int process_id) { browser_client_.set_privileged_process_id(process_id); } + void DrainMessageLoops() { + // We don't just do this in TearDown() because we create TestBrowserContext + // objects in each test, which will be destructed before + // TearDown() is called. + MessageLoop::current()->RunAllPending(); + message_loop_.RunAllPending(); + } + private: MessageLoopForUI message_loop_; content::TestBrowserThread ui_thread_; @@ -258,7 +264,7 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) { // Make sure that we flush any messages related to the above WebContentsImpl // destruction. - MessageLoop::current()->RunAllPending(); + DrainMessageLoops(); EXPECT_EQ(2, site_delete_counter); EXPECT_EQ(2, browsing_delete_counter); @@ -303,6 +309,8 @@ TEST_F(SiteInstanceTest, CloneNavigationEntry) { // Both BrowsingInstances are also now deleted EXPECT_EQ(2, browsing_delete_counter); + + DrainMessageLoops(); } // Test to ensure GetProcess returns and creates processes correctly. @@ -322,6 +330,8 @@ TEST_F(SiteInstanceTest, GetProcess) { scoped_ptr host2(instance2->GetProcess()); EXPECT_TRUE(host2.get() != NULL); EXPECT_NE(host1.get(), host2.get()); + + DrainMessageLoops(); } // Test to ensure SetSite and site() work properly. @@ -335,6 +345,8 @@ TEST_F(SiteInstanceTest, SetSite) { EXPECT_EQ(GURL("http://google.com"), instance->GetSite()); EXPECT_TRUE(instance->HasSite()); + + DrainMessageLoops(); } // Test to ensure GetSiteForURL properly returns sites for URLs. @@ -368,6 +380,8 @@ TEST_F(SiteInstanceTest, GetSiteForURL) { // "file://home/" as the site, which seems broken. // test_url = GURL("file://home/"); // EXPECT_EQ(GURL(), SiteInstanceImpl::GetSiteForURL(NULL, test_url)); + + DrainMessageLoops(); } // Test of distinguishing URLs from different sites. Most of this logic is @@ -394,6 +408,8 @@ TEST_F(SiteInstanceTest, IsSameWebSite) { EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo)); EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo_https)); EXPECT_TRUE(SiteInstance::IsSameWebSite(NULL, url_javascript, url_foo_port)); + + DrainMessageLoops(); } // Test to ensure that there is only one SiteInstance per site in a given @@ -468,6 +484,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSite) { // browsing_instances will be deleted when their SiteInstances are deleted. // The processes will be unregistered when the RPH scoped_ptrs go away. + + DrainMessageLoops(); } // Test to ensure that there is only one RenderProcessHost per site for an @@ -553,6 +571,8 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) { // browsing_instances will be deleted when their SiteInstances are deleted. // The processes will be unregistered when the RPH scoped_ptrs go away. + + DrainMessageLoops(); } static SiteInstanceImpl* CreateSiteInstance( @@ -618,6 +638,8 @@ TEST_F(SiteInstanceTest, ProcessSharingByType) { } STLDeleteContainerPointers(hosts.begin(), hosts.end()); + + DrainMessageLoops(); } // Test to ensure that HasWrongProcessForURL behaves properly for different @@ -650,4 +672,6 @@ TEST_F(SiteInstanceTest, HasWrongProcessForURL) { GURL("javascript:alert(document.location.href);"))); EXPECT_TRUE(instance->HasWrongProcessForURL(GURL("chrome://settings"))); + + DrainMessageLoops(); } diff --git a/content/browser/storage_partition.cc b/content/browser/storage_partition.cc deleted file mode 100644 index b6ed8c2..0000000 --- a/content/browser/storage_partition.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/storage_partition.h" - -#include "content/browser/appcache/chrome_appcache_service.h" -#include "content/browser/dom_storage/dom_storage_context_impl.h" -#include "content/browser/fileapi/browser_file_system_helper.h" -#include "content/browser/in_process_webkit/indexed_db_context_impl.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "webkit/database/database_tracker.h" -#include "webkit/quota/quota_manager.h" - -namespace content { - -StoragePartition::StoragePartition( - const FilePath& partition_path, - quota::QuotaManager* quota_manager, - ChromeAppCacheService* appcache_service, - fileapi::FileSystemContext* filesystem_context, - webkit_database::DatabaseTracker* database_tracker, - DOMStorageContextImpl* dom_storage_context, - IndexedDBContext* indexed_db_context) - : partition_path_(partition_path), - quota_manager_(quota_manager), - appcache_service_(appcache_service), - filesystem_context_(filesystem_context), - database_tracker_(database_tracker), - dom_storage_context_(dom_storage_context), - indexed_db_context_(indexed_db_context) { -} - -StoragePartition::~StoragePartition() { - // These message loop checks are just to avoid leaks in unittests. - if (database_tracker() && - BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) { - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&webkit_database::DatabaseTracker::Shutdown, - database_tracker())); - } - - if (dom_storage_context()) - dom_storage_context()->Shutdown(); -} - -// TODO(ajwong): Break the direct dependency on |context|. We only -// need 3 pieces of info from it. -StoragePartition* StoragePartition::Create(BrowserContext* context, - const FilePath& partition_path) { - // Ensure that these methods are called on the UI thread, except for - // unittests where a UI thread might not have been created. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || - !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); - - // All of the clients have to be created and registered with the - // QuotaManager prior to the QuotaManger being used. We do them - // all together here prior to handing out a reference to anything - // that utilizes the QuotaManager. - scoped_refptr quota_manager = - new quota::QuotaManager( - context->IsOffTheRecord(), partition_path, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), - context->GetSpecialStoragePolicy()); - - // Each consumer is responsible for registering its QuotaClient during - // its construction. - scoped_refptr filesystem_context = - CreateFileSystemContext(partition_path, context->IsOffTheRecord(), - context->GetSpecialStoragePolicy(), - quota_manager->proxy()); - - scoped_refptr database_tracker = - new webkit_database::DatabaseTracker( - partition_path, context->IsOffTheRecord(), - context->GetSpecialStoragePolicy(), quota_manager->proxy(), - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); - - FilePath path = context->IsOffTheRecord() ? FilePath() : partition_path; - scoped_refptr dom_storage_context = - new DOMStorageContextImpl(path, context->GetSpecialStoragePolicy()); - - scoped_refptr indexed_db_context = - new IndexedDBContextImpl(path, context->GetSpecialStoragePolicy(), - quota_manager->proxy(), - BrowserThread::GetMessageLoopProxyForThread( - BrowserThread::WEBKIT_DEPRECATED)); - - scoped_refptr appcache_service = - new ChromeAppCacheService(quota_manager->proxy()); - - return new StoragePartition(partition_path, - quota_manager, - appcache_service, - filesystem_context, - database_tracker, - dom_storage_context, - indexed_db_context); -} - -} // namespace content diff --git a/content/browser/storage_partition.h b/content/browser/storage_partition.h deleted file mode 100644 index ee6885e..0000000 --- a/content/browser/storage_partition.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_STORAGE_PARTITION_H_ -#define CONTENT_BROWSER_STORAGE_PARTITION_H_ - -#include "base/file_path.h" -#include "base/memory/ref_counted.h" - -namespace fileapi { -class FileSystemContext; -} - -namespace quota { -class QuotaManager; -} - -namespace webkit_database { -class DatabaseTracker; -} - -class ChromeAppCacheService; -class DOMStorageContextImpl; - -namespace content { - -class BrowserContext; -class IndexedDBContext; - -// Defines the what persistent state a child process can access. -// -// The StoragePartition defines the view each child process has of the -// persistent state inside the BrowserContext. This is used to implement -// isolated storage where a renderer with isolated storage cannot see -// the cookies, localStorage, etc., that normal web renderers have access to. -class StoragePartition { - public: - ~StoragePartition(); - - // TODO(ajwong): Break the direct dependency on |context|. We only - // need 3 pieces of info from it. - static StoragePartition* Create(BrowserContext* context, - const FilePath& partition_path); - - quota::QuotaManager* quota_manager() { return quota_manager_; } - ChromeAppCacheService* appcache_service() { return appcache_service_; } - fileapi::FileSystemContext* filesystem_context() { - return filesystem_context_; - } - webkit_database::DatabaseTracker* database_tracker() { - return database_tracker_; - } - DOMStorageContextImpl* dom_storage_context() { return dom_storage_context_; } - IndexedDBContext* indexed_db_context() { return indexed_db_context_; } - - private: - StoragePartition(const FilePath& partition_path, - quota::QuotaManager* quota_manager, - ChromeAppCacheService* appcache_service, - fileapi::FileSystemContext* filesystem_context, - webkit_database::DatabaseTracker* database_tracker, - DOMStorageContextImpl* dom_storage_context, - IndexedDBContext* indexed_db_context); - - FilePath partition_path_; - scoped_refptr quota_manager_; - scoped_refptr appcache_service_; - scoped_refptr filesystem_context_; - scoped_refptr database_tracker_; - scoped_refptr dom_storage_context_; - scoped_refptr indexed_db_context_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_STORAGE_PARTITION_H_ diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc new file mode 100644 index 0000000..e906a6a --- /dev/null +++ b/content/browser/storage_partition_impl.cc @@ -0,0 +1,126 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/storage_partition_impl.h" + +#include "content/browser/fileapi/browser_file_system_helper.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "webkit/database/database_tracker.h" +#include "webkit/quota/quota_manager.h" + +namespace content { + +StoragePartitionImpl::StoragePartitionImpl( + const FilePath& partition_path, + quota::QuotaManager* quota_manager, + ChromeAppCacheService* appcache_service, + fileapi::FileSystemContext* filesystem_context, + webkit_database::DatabaseTracker* database_tracker, + DOMStorageContextImpl* dom_storage_context, + IndexedDBContextImpl* indexed_db_context) + : partition_path_(partition_path), + quota_manager_(quota_manager), + appcache_service_(appcache_service), + filesystem_context_(filesystem_context), + database_tracker_(database_tracker), + dom_storage_context_(dom_storage_context), + indexed_db_context_(indexed_db_context) { +} + +StoragePartitionImpl::~StoragePartitionImpl() { + // These message loop checks are just to avoid leaks in unittests. + if (GetDatabaseTracker() && + BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) { + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + base::Bind(&webkit_database::DatabaseTracker::Shutdown, + GetDatabaseTracker())); + } + + if (GetDOMStorageContext()) + GetDOMStorageContext()->Shutdown(); +} + +// TODO(ajwong): Break the direct dependency on |context|. We only +// need 3 pieces of info from it. +StoragePartitionImpl* StoragePartitionImpl::Create( + BrowserContext* context, + const FilePath& partition_path) { + // Ensure that these methods are called on the UI thread, except for + // unittests where a UI thread might not have been created. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); + + // All of the clients have to be created and registered with the + // QuotaManager prior to the QuotaManger being used. We do them + // all together here prior to handing out a reference to anything + // that utilizes the QuotaManager. + scoped_refptr quota_manager = + new quota::QuotaManager( + context->IsOffTheRecord(), partition_path, + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), + context->GetSpecialStoragePolicy()); + + // Each consumer is responsible for registering its QuotaClient during + // its construction. + scoped_refptr filesystem_context = + CreateFileSystemContext(partition_path, context->IsOffTheRecord(), + context->GetSpecialStoragePolicy(), + quota_manager->proxy()); + + scoped_refptr database_tracker = + new webkit_database::DatabaseTracker( + partition_path, context->IsOffTheRecord(), + context->GetSpecialStoragePolicy(), quota_manager->proxy(), + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); + + FilePath path = context->IsOffTheRecord() ? FilePath() : partition_path; + scoped_refptr dom_storage_context = + new DOMStorageContextImpl(path, context->GetSpecialStoragePolicy()); + + scoped_refptr indexed_db_context = + new IndexedDBContextImpl(path, context->GetSpecialStoragePolicy(), + quota_manager->proxy(), + BrowserThread::GetMessageLoopProxyForThread( + BrowserThread::WEBKIT_DEPRECATED)); + + scoped_refptr appcache_service = + new ChromeAppCacheService(quota_manager->proxy()); + + return new StoragePartitionImpl(partition_path, + quota_manager, + appcache_service, + filesystem_context, + database_tracker, + dom_storage_context, + indexed_db_context); +} + +quota::QuotaManager* StoragePartitionImpl::GetQuotaManager() { + return quota_manager_; +} + +ChromeAppCacheService* StoragePartitionImpl::GetAppCacheService() { + return appcache_service_; +} + +fileapi::FileSystemContext* StoragePartitionImpl::GetFileSystemContext() { + return filesystem_context_; +} + +webkit_database::DatabaseTracker* StoragePartitionImpl::GetDatabaseTracker() { + return database_tracker_; +} + +DOMStorageContextImpl* StoragePartitionImpl::GetDOMStorageContext() { + return dom_storage_context_; +} + +IndexedDBContextImpl* StoragePartitionImpl::GetIndexedDBContext() { + return indexed_db_context_; +} + +} // namespace content diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h new file mode 100644 index 0000000..9ab7fc3 --- /dev/null +++ b/content/browser/storage_partition_impl.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_ +#define CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_ + +#include "base/compiler_specific.h" +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/dom_storage/dom_storage_context_impl.h" +#include "content/browser/in_process_webkit/indexed_db_context_impl.h" +#include "content/public/browser/storage_partition.h" + +namespace content { + +class StoragePartitionImpl : public StoragePartition { + public: + virtual ~StoragePartitionImpl(); + + // TODO(ajwong): Break the direct dependency on |context|. We only + // need 3 pieces of info from it. + static StoragePartitionImpl* Create(BrowserContext* context, + const FilePath& partition_path); + + // StoragePartition interface. + virtual quota::QuotaManager* GetQuotaManager() OVERRIDE; + virtual ChromeAppCacheService* GetAppCacheService() OVERRIDE; + virtual fileapi::FileSystemContext* GetFileSystemContext() OVERRIDE; + virtual webkit_database::DatabaseTracker* GetDatabaseTracker() OVERRIDE; + virtual DOMStorageContextImpl* GetDOMStorageContext() OVERRIDE; + virtual IndexedDBContextImpl* GetIndexedDBContext() OVERRIDE; + + private: + StoragePartitionImpl(const FilePath& partition_path, + quota::QuotaManager* quota_manager, + ChromeAppCacheService* appcache_service, + fileapi::FileSystemContext* filesystem_context, + webkit_database::DatabaseTracker* database_tracker, + DOMStorageContextImpl* dom_storage_context, + IndexedDBContextImpl* indexed_db_context); + + FilePath partition_path_; + scoped_refptr quota_manager_; + scoped_refptr appcache_service_; + scoped_refptr filesystem_context_; + scoped_refptr database_tracker_; + scoped_refptr dom_storage_context_; + scoped_refptr indexed_db_context_; + + DISALLOW_COPY_AND_ASSIGN(StoragePartitionImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_STORAGE_PARTITION_IMPL_H_ diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc new file mode 100644 index 0000000..fd62c98 --- /dev/null +++ b/content/browser/storage_partition_impl_map.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/storage_partition_impl_map.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/file_path.h" +#include "base/stl_util.h" +#include "base/string_util.h" +#include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/resource_context_impl.h" +#include "content/browser/storage_partition_impl.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_constants.h" + +namespace content { + +// Dirname for storing persistent data for renderers with isolated storage. +const FilePath::CharType kStoragePartitionDirName[] = + FILE_PATH_LITERAL("Storage Partitions"); + +StoragePartitionImplMap::StoragePartitionImplMap( + BrowserContext* browser_context) + : browser_context_(browser_context) { +} + +StoragePartitionImplMap::~StoragePartitionImplMap() { + STLDeleteContainerPairSecondPointers(partitions_.begin(), + partitions_.end()); +} + +StoragePartitionImpl* StoragePartitionImplMap::Get( + const std::string& partition_id) { + // Find the previously created partition if it's available. + std::map::const_iterator it = + partitions_.find(partition_id); + if (it != partitions_.end()) + return it->second; + + // There was no previous partition, so let's make a new one. + FilePath partition_path = browser_context_->GetPath(); + if (!partition_id.empty()) { + // TODO(ajwong): This should check the path is valid? + CHECK(IsStringASCII(partition_id)); + partition_path = partition_path.Append(kStoragePartitionDirName) + .AppendASCII(partition_id); + } + + StoragePartitionImpl* storage_partition = + StoragePartitionImpl::Create(browser_context_, partition_path); + partitions_[partition_id] = storage_partition; + + PostCreateInitialization(storage_partition, partition_path); + + // TODO(ajwong): We need to remove this conditional by making + // InitializeResourceContext() understand having different partition data + // based on the renderer_id. + if (partition_id.empty()) { + InitializeResourceContext(browser_context_); + } + + return storage_partition; +} + +void StoragePartitionImplMap::ForEach( + const BrowserContext::StoragePartitionCallback& callback) { + for (std::map::const_iterator it = + partitions_.begin(); + it != partitions_.end(); + ++it) { + callback.Run(it->first, it->second); + } +} + +void StoragePartitionImplMap::PostCreateInitialization( + StoragePartitionImpl* partition, + const FilePath& partition_path) { + // Check first to avoid memory leak in unittests. + if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ChromeAppCacheService::InitializeOnIOThread, + partition->GetAppCacheService(), + browser_context_->IsOffTheRecord() ? FilePath() : + partition_path.Append(kAppCacheDirname), + browser_context_->GetResourceContext(), + make_scoped_refptr( + browser_context_->GetSpecialStoragePolicy()))); + } +} + +} // namespace content diff --git a/content/browser/storage_partition_impl_map.h b/content/browser/storage_partition_impl_map.h new file mode 100644 index 0000000..d4a66e7 --- /dev/null +++ b/content/browser/storage_partition_impl_map.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ +#define CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ + +#include +#include + +#include "base/callback_forward.h" +#include "base/supports_user_data.h" +#include "content/public/browser/browser_context.h" + +class FilePath; + +namespace content { + +class BrowserContext; +class StoragePartitionImpl; + +// A std::string to StoragePartition map for use with SupportsUserData APIs. +class StoragePartitionImplMap : public base::SupportsUserData::Data { + public: + explicit StoragePartitionImplMap(BrowserContext* browser_context); + + virtual ~StoragePartitionImplMap(); + + // This map retains ownership of the returned StoragePartition objects. + StoragePartitionImpl* Get(const std::string& partition_id); + + void ForEach(const BrowserContext::StoragePartitionCallback& callback); + + private: + // This must always be called *after* |partition| has been added to the + // partitions_. + // + // TODO(ajwong): Is there a way to make it so that Get()'s implementation + // doesn't need to be aware of this ordering? Revisit when refactoring + // ResourceContext and AppCache to respect storage partitions. + void PostCreateInitialization(StoragePartitionImpl* partition, + const FilePath& partition_path); + + BrowserContext* browser_context_; // Not Owned. + std::map partitions_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ diff --git a/content/browser/storage_partition_map.cc b/content/browser/storage_partition_map.cc deleted file mode 100644 index 2611370..0000000 --- a/content/browser/storage_partition_map.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/storage_partition_map.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/file_path.h" -#include "base/stl_util.h" -#include "base/string_util.h" -#include "content/browser/appcache/chrome_appcache_service.h" -#include "content/browser/resource_context_impl.h" -#include "content/browser/storage_partition.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/common/content_constants.h" - -namespace content { - -// Dirname for storing persistent data for renderers with isolated storage. -const FilePath::CharType kStoragePartitionDirName[] = - FILE_PATH_LITERAL("Storage Partitions"); - -StoragePartitionMap::StoragePartitionMap( - BrowserContext* browser_context) - : browser_context_(browser_context) { -} - -StoragePartitionMap::~StoragePartitionMap() { - STLDeleteContainerPairSecondPointers(partitions_.begin(), - partitions_.end()); -} - -StoragePartition* StoragePartitionMap::Get(const std::string& partition_id) { - // Find the previously created partition if it's available. - std::map::const_iterator it = - partitions_.find(partition_id); - if (it != partitions_.end()) - return it->second; - - // There was no previous partition, so let's make a new one. - FilePath partition_path = browser_context_->GetPath(); - if (!partition_id.empty()) { - // TODO(ajwong): This should check the pth is valid? - CHECK(IsStringASCII(partition_id)); - partition_path = partition_path.Append(kStoragePartitionDirName) - .AppendASCII(partition_id); - } - - StoragePartition* storage_partition = - StoragePartition::Create(browser_context_, partition_path); - partitions_[partition_id] = storage_partition; - - PostCreateInitialization(storage_partition, partition_path); - - // TODO(ajwong): We need to remove this conditional by making - // InitializeResourceContext() understand having different partition data - // based on the renderer_id. - if (partition_id.empty()) { - InitializeResourceContext(browser_context_); - } - - return storage_partition; -} - -void StoragePartitionMap::ForEach( - const base::Callback& callback) { - for (std::map::const_iterator it = - partitions_.begin(); - it != partitions_.end(); - ++it) { - callback.Run(it->second); - } -} - -void StoragePartitionMap::PostCreateInitialization( - StoragePartition* partition, - const FilePath& partition_path) { - // Check first to avoid memory leak in unittests. - if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&ChromeAppCacheService::InitializeOnIOThread, - partition->appcache_service(), - browser_context_->IsOffTheRecord() ? FilePath() : - partition_path.Append(kAppCacheDirname), - browser_context_->GetResourceContext(), - make_scoped_refptr( - browser_context_->GetSpecialStoragePolicy()))); - } -} - -} // namespace content diff --git a/content/browser/storage_partition_map.h b/content/browser/storage_partition_map.h deleted file mode 100644 index bcebac1..0000000 --- a/content/browser/storage_partition_map.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ -#define CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ - -#include -#include - -#include "base/callback_forward.h" -#include "base/supports_user_data.h" - -class FilePath; - -namespace content { - -class BrowserContext; -class StoragePartition; - -// A std::string to StoragePartition map for use with SupportsUserData APIs. -class StoragePartitionMap : public base::SupportsUserData::Data { - public: - explicit StoragePartitionMap(BrowserContext* browser_context); - - virtual ~StoragePartitionMap(); - - // This map retains ownership of the returned StoragePartition objects. - StoragePartition* Get(const std::string& partition_id); - - void ForEach(const base::Callback& callback); - - private: - // This must always be called *after* |partition| has been added to the - // partitions_. - // - // TODO(ajwong): Is there a way to make it so that Get()'s implementation - // doesn't need to be aware of this ordering? Revisit when refactoring - // ResourceContext and AppCache to respect storage partitions. - void PostCreateInitialization(StoragePartition* partition, - const FilePath& partition_path); - - BrowserContext* browser_context_; // Not Owned. - std::map partitions_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_ diff --git a/content/browser/web_contents/interstitial_page_impl.cc b/content/browser/web_contents/interstitial_page_impl.cc index 1d53cb1..f2ac72e 100644 --- a/content/browser/web_contents/interstitial_page_impl.cc +++ b/content/browser/web_contents/interstitial_page_impl.cc @@ -32,6 +32,7 @@ #include "content/public/browser/invalidate_type.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents_view.h" #include "content/public/common/bindings_policy.h" #include "content/public/common/page_transition_types.h" @@ -487,14 +488,10 @@ RenderViewHost* InterstitialPageImpl::CreateRenderViewHost() { BrowserContext* browser_context = web_contents()->GetBrowserContext(); scoped_refptr site_instance = SiteInstance::Create(browser_context); - const std::string& partition_id = - content::GetContentClient()->browser()-> - GetStoragePartitionIdForSiteInstance(browser_context, - site_instance); DOMStorageContextImpl* dom_storage_context = static_cast( - BrowserContext::GetDOMStorageContextByPartitionId(browser_context, - partition_id)); + BrowserContext::GetStoragePartition( + browser_context, site_instance)->GetDOMStorageContext()); SessionStorageNamespaceImpl* session_storage_namespace_impl = new SessionStorageNamespaceImpl(dom_storage_context); diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index 28ad4a4..877a446 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -27,6 +27,7 @@ #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/content_client.h" @@ -1269,11 +1270,15 @@ NavigationControllerImpl::GetSessionStorageNamespace( 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 + content::StoragePartition* partition = + BrowserContext::GetStoragePartition(browser_context_, instance); SessionStorageNamespaceImpl* session_storage_namespace = new SessionStorageNamespaceImpl( static_cast( - BrowserContext::GetDOMStorageContextByPartitionId( - browser_context_, partition_id))); + partition->GetDOMStorageContext())); session_storage_namespace_map_[partition_id] = session_storage_namespace; return session_storage_namespace; diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index d4c3dafb..61d98d8 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -54,6 +54,7 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/resource_request_details.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" @@ -1247,14 +1248,17 @@ void WebContentsImpl::CreateNewWindow( params.opener_suppressed ? NULL : this); // We must assign the SessionStorageNamespace before calling Init(). + // + // http://crbug.com/142685 const std::string& partition_id = content::GetContentClient()->browser()-> GetStoragePartitionIdForSiteInstance(GetBrowserContext(), site_instance); + content::StoragePartition* partition = + BrowserContext::GetStoragePartition(GetBrowserContext(), + site_instance); DOMStorageContextImpl* dom_storage_context = - static_cast( - BrowserContext::GetDOMStorageContextByPartitionId( - GetBrowserContext(), partition_id)); + static_cast(partition->GetDOMStorageContext()); SessionStorageNamespaceImpl* session_storage_namespace_impl = static_cast(session_storage_namespace); CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 23178e3..3fcf64d 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -152,6 +152,7 @@ 'public/browser/speech_recognition_session_config.h', 'public/browser/speech_recognition_session_context.cc', 'public/browser/speech_recognition_session_context.h', + 'public/browser/storage_partition.h', 'public/browser/trace_controller.h', 'public/browser/trace_subscriber.h', 'public/browser/user_metrics.h', @@ -749,12 +750,12 @@ 'browser/ssl/ssl_policy_backend.h', 'browser/ssl/ssl_policy.cc', 'browser/ssl/ssl_policy.h', - 'browser/storage_partition.cc', - 'browser/storage_partition.h', - 'browser/storage_partition_map.cc', - 'browser/storage_partition_map.h', 'browser/ssl/ssl_request_info.cc', 'browser/ssl/ssl_request_info.h', + 'browser/storage_partition_impl.cc', + 'browser/storage_partition_impl.h', + 'browser/storage_partition_impl_map.cc', + 'browser/storage_partition_impl_map.h', 'browser/system_message_window_win.cc', 'browser/system_message_window_win.h', 'browser/tcmalloc_internals_request_job.cc', diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h index cfe4d53..2acf400 100644 --- a/content/public/browser/browser_context.h +++ b/content/public/browser/browser_context.h @@ -5,6 +5,7 @@ #ifndef CONTENT_PUBLIC_BROWSER_BROWSER_CONTEXT_H_ #define CONTENT_PUBLIC_BROWSER_BROWSER_CONTEXT_H_ +#include "base/callback_forward.h" #include "base/hash_tables.h" #include "base/supports_user_data.h" #include "content/common/content_export.h" @@ -40,21 +41,22 @@ class DownloadManagerDelegate; class GeolocationPermissionContext; class IndexedDBContext; class ResourceContext; +class SiteInstance; class SpeechRecognitionPreferences; +class StoragePartition; // This class holds the context needed for a browsing session. // It lives on the UI thread. All these methods must only be called on the UI // thread. class CONTENT_EXPORT BrowserContext : public base::SupportsUserData { public: + // Used in ForEachStoragePartition(). The first argument is the partition id. + // The second argument is the StoragePartition object for that partition id. + typedef base::Callback + StoragePartitionCallback; + static DownloadManager* GetDownloadManager(BrowserContext* browser_context); static quota::QuotaManager* GetQuotaManager(BrowserContext* browser_context); - static DOMStorageContext* GetDefaultDOMStorageContext( - BrowserContext* browser_context); - static DOMStorageContext* GetDOMStorageContext( - BrowserContext* browser_context, int renderer_child_id); - static content::DOMStorageContext* GetDOMStorageContextByPartitionId( - BrowserContext* browser_context, const std::string& partition_id); static IndexedDBContext* GetIndexedDBContext(BrowserContext* browser_context); static webkit_database::DatabaseTracker* GetDatabaseTracker( BrowserContext* browser_context); @@ -63,6 +65,17 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData { static fileapi::FileSystemContext* GetFileSystemContext( BrowserContext* browser_context); + static content::StoragePartition* GetStoragePartition( + BrowserContext* browser_context, SiteInstance* site_instance); + static void ForEachStoragePartition( + BrowserContext* browser_context, + const StoragePartitionCallback& callback); + + // DON'T USE THIS. GetDefaultStoragePartition() is going away. + // Use GetStoragePartition() instead. Ask ajwong@ if you have problems. + static content::StoragePartition* GetDefaultStoragePartition( + BrowserContext* browser_context); + // Ensures that the corresponding ResourceContext is initialized. Normally the // BrowserContext initializs the corresponding getters when its objects are // created, but if the embedder wants to pass the ResourceContext to another diff --git a/content/public/browser/resource_context.h b/content/public/browser/resource_context.h index 0bdcff8..8304159 100644 --- a/content/public/browser/resource_context.h +++ b/content/public/browser/resource_context.h @@ -5,6 +5,7 @@ #ifndef CONTENT_PUBLIC_BROWSER_RESOURCE_CONTEXT_H_ #define CONTENT_PUBLIC_BROWSER_RESOURCE_CONTEXT_H_ +#include "base/basictypes.h" #include "base/supports_user_data.h" #include "content/common/content_export.h" diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h new file mode 100644 index 0000000..d7c1363 --- /dev/null +++ b/content/public/browser/storage_partition.h @@ -0,0 +1,53 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_STORAGE_PARTITION_H_ +#define CONTENT_PUBLIC_BROWSER_STORAGE_PARTITION_H_ + +#include "base/basictypes.h" + +namespace appcache { +class AppCacheService; +} + +namespace fileapi { +class FileSystemContext; +} + +namespace quota { +class QuotaManager; +} + +namespace webkit_database { +class DatabaseTracker; +} + +namespace content { + +class BrowserContext; +class IndexedDBContext; +class DOMStorageContext; + +// Defines what persistent state a child process can access. +// +// The StoragePartition defines the view each child process has of the +// persistent state inside the BrowserContext. This is used to implement +// isolated storage where a renderer with isolated storage cannot see +// the cookies, localStorage, etc., that normal web renderers have access to. +class StoragePartition { + public: + virtual quota::QuotaManager* GetQuotaManager() = 0; + virtual appcache::AppCacheService* GetAppCacheService() = 0; + virtual fileapi::FileSystemContext* GetFileSystemContext() = 0; + virtual webkit_database::DatabaseTracker* GetDatabaseTracker() = 0; + virtual DOMStorageContext* GetDOMStorageContext() = 0; + virtual IndexedDBContext* GetIndexedDBContext() = 0; + + protected: + virtual ~StoragePartition() {} +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_STORAGE_PARTITION_H_ -- cgit v1.1