diff options
author | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 23:40:04 +0000 |
---|---|---|
committer | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-19 23:40:04 +0000 |
commit | 24c915e7d8204d061c62516da805416f21f88269 (patch) | |
tree | 29cb9640ae147d1ea85f7b4dd848ee02e1de958e /content | |
parent | 4a4512426f2c7224f3895d959e66ca1e8111a194 (diff) | |
download | chromium_src-24c915e7d8204d061c62516da805416f21f88269.zip chromium_src-24c915e7d8204d061c62516da805416f21f88269.tar.gz chromium_src-24c915e7d8204d061c62516da805416f21f88269.tar.bz2 |
DOMStorageContextImpl that's implemented in terms of the new dom_storage classes. Also compile out existing tests that no longer apply when ENABLE_NEW_DOM_STORAGE_BACKEND is defined.
BUG=106763
Review URL: https://chromiumcodereview.appspot.com/9695013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127573 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
9 files changed, 332 insertions, 28 deletions
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 8244ad6..7f7b556 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc @@ -34,6 +34,8 @@ static const char* kQuotaManagerKeyName = "content_quota_manager"; namespace content { +namespace { + void CreateQuotaManagerAndClients(BrowserContext* context) { if (context->GetUserData(kQuotaManagerKeyName)) { DCHECK(context->GetUserData(kDatabaseTrackerKeyName)); @@ -115,9 +117,7 @@ void SaveSessionStateOnIOThread(ResourceContext* resource_context) { } void SaveSessionStateOnWebkitThread( - scoped_refptr<DOMStorageContextImpl> dom_storage_context, scoped_refptr<IndexedDBContextImpl> indexed_db_context) { - dom_storage_context->SaveSessionState(); indexed_db_context->SaveSessionState(); } @@ -125,11 +125,13 @@ void PurgeMemoryOnIOThread(ResourceContext* resource_context) { ResourceContext::GetAppCacheService(resource_context)->PurgeMemory(); } -void PurgeMemoryOnWebkitThread( - scoped_refptr<DOMStorageContextImpl> dom_storage_context) { - dom_storage_context->PurgeMemory(); +DOMStorageContextImpl* GetDOMStorageContextImpl(BrowserContext* context) { + return static_cast<DOMStorageContextImpl*>( + BrowserContext::GetDOMStorageContext(context)); } +} // namespace + QuotaManager* BrowserContext::GetQuotaManager(BrowserContext* context) { CreateQuotaManagerAndClients(context); return UserDataAdapter<QuotaManager>::Get(context, kQuotaManagerKeyName); @@ -188,23 +190,20 @@ void BrowserContext::SaveSessionState(BrowserContext* browser_context) { browser_context->GetResourceContext())); } + GetDOMStorageContextImpl(browser_context)->SaveSessionState(); + if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { - DOMStorageContextImpl* dom_context = static_cast<DOMStorageContextImpl*>( - GetDOMStorageContext(browser_context)); IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>( GetIndexedDBContext(browser_context)); BrowserThread::PostTask( BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, base::Bind(&SaveSessionStateOnWebkitThread, - make_scoped_refptr(dom_context), make_scoped_refptr(indexed_db))); } } void BrowserContext::ClearLocalOnDestruction(BrowserContext* browser_context) { - DOMStorageContextImpl* dom_context = static_cast<DOMStorageContextImpl*>( - GetDOMStorageContext(browser_context)); - dom_context->set_clear_local_state_on_exit(true); + GetDOMStorageContextImpl(browser_context)->SetClearLocalState(true); IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>( GetIndexedDBContext(browser_context)); @@ -228,14 +227,7 @@ void BrowserContext::PurgeMemory(BrowserContext* browser_context) { browser_context->GetResourceContext())); } - if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { - DOMStorageContextImpl* dom_context = static_cast<DOMStorageContextImpl*>( - GetDOMStorageContext(browser_context)); - BrowserThread::PostTask( - BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, - base::Bind(&PurgeMemoryOnWebkitThread, - make_scoped_refptr(dom_context))); - } + GetDOMStorageContextImpl(browser_context)->PurgeMemory(); } BrowserContext::~BrowserContext() { @@ -248,6 +240,10 @@ BrowserContext::~BrowserContext() { GetDatabaseTracker(this))); } +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND + if (GetUserData(kDOMStorageContextKeyName)) + GetDOMStorageContextImpl(this)->Shutdown(); +#else if (GetUserData(kDOMStorageContextKeyName) && BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { DOMStorageContextImpl* dom_storage_context = @@ -256,6 +252,7 @@ BrowserContext::~BrowserContext() { BrowserThread::ReleaseSoon( BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, dom_storage_context); } +#endif } } // namespace content diff --git a/content/browser/dom_storage/dom_storage_context_impl_new.cc b/content/browser/dom_storage/dom_storage_context_impl_new.cc new file mode 100644 index 0000000..dec97e0 --- /dev/null +++ b/content/browser/dom_storage/dom_storage_context_impl_new.cc @@ -0,0 +1,174 @@ +// 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/dom_storage/dom_storage_context_impl_new.h" + +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/message_loop_proxy.h" +#include "content/public/browser/browser_thread.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "webkit/database/database_util.h" +#include "webkit/dom_storage/dom_storage_area.h" +#include "webkit/dom_storage/dom_storage_context.h" +#include "webkit/dom_storage/dom_storage_task_runner.h" +#include "webkit/glue/webkit_glue.h" + +using content::BrowserThread; +using content::DOMStorageContext; +using dom_storage::DomStorageArea; +using dom_storage::DomStorageContext; +using dom_storage::DomStorageWorkerPoolTaskRunner; +using webkit_database::DatabaseUtil; + +namespace { + +const char kLocalStorageDirectory[] = "Local Storage"; + +// TODO(michaeln): Fix the content layer api, FilePaths and +// string16 origin_ids are just wrong. Then get rid of +// this conversion non-sense. Most of the includes are just +// to support that non-sense. + +GURL OriginIdToGURL(const string16& origin_id) { + return DatabaseUtil::GetOriginFromIdentifier(origin_id); +} + +FilePath OriginToFullFilePath(const FilePath& directory, + const GURL& origin) { + return directory.Append(DomStorageArea::DatabaseFileNameFromOrigin(origin)); +} + +GURL FilePathToOrigin(const FilePath& path) { + DCHECK(path.MatchesExtension(DomStorageArea::kDatabaseFileExtension)); + return OriginIdToGURL( + webkit_glue::FilePathToWebString(path.BaseName().RemoveExtension())); +} + +void InvokeAllStorageFilesCallbackHelper( + const DOMStorageContext::GetAllStorageFilesCallback& callback, + const std::vector<FilePath>& file_paths) { + callback.Run(file_paths); +} + +void GetAllStorageFilesHelper( + base::MessageLoopProxy* reply_loop, + DomStorageContext* context, + const DOMStorageContext::GetAllStorageFilesCallback& callback) { + std::vector<DomStorageContext::UsageInfo> infos; + context->GetUsageInfo(&infos); + + std::vector<FilePath> paths; + for (size_t i = 0; i < infos.size(); ++i) { + paths.push_back( + OriginToFullFilePath(context->directory(), infos[i].origin)); + } + + reply_loop->PostTask( + FROM_HERE, + base::Bind(&InvokeAllStorageFilesCallbackHelper, + callback, paths)); +} + +} + +DOMStorageContextImpl::DOMStorageContextImpl( + const FilePath& data_path, + quota::SpecialStoragePolicy* special_storage_policy) { + base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); + context_ = new dom_storage::DomStorageContext( + data_path.empty() ? + data_path : data_path.AppendASCII(kLocalStorageDirectory), + special_storage_policy, + new DomStorageWorkerPoolTaskRunner( + worker_pool, + worker_pool->GetNamedSequenceToken("dom_storage"), + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))); +} + +DOMStorageContextImpl::~DOMStorageContextImpl() { +} + +void DOMStorageContextImpl::GetAllStorageFiles( + const GetAllStorageFilesCallback& callback) { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&GetAllStorageFilesHelper, + base::MessageLoopProxy::current(), + context_, callback)); +} + +FilePath DOMStorageContextImpl::GetFilePath(const string16& origin_id) const { + DCHECK(context_); + return OriginToFullFilePath(context_->directory(), OriginIdToGURL(origin_id)); +} + +void DOMStorageContextImpl::DeleteForOrigin(const string16& origin_id) { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::DeleteOrigin, context_, + OriginIdToGURL(origin_id))); +} + +void DOMStorageContextImpl::DeleteLocalStorageFile(const FilePath& file_path) { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::DeleteOrigin, context_, + FilePathToOrigin(file_path))); +} + +void DOMStorageContextImpl::DeleteDataModifiedSince(const base::Time& cutoff) { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::DeleteDataModifiedSince, context_, + cutoff)); +} + +void DOMStorageContextImpl::PurgeMemory() { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::PurgeMemory, context_)); +} + +void DOMStorageContextImpl::SetClearLocalState(bool clear_local_state) { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::SetClearLocalState, context_, + clear_local_state)); +} + +void DOMStorageContextImpl::SaveSessionState() { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::SaveSessionState, context_)); +} + +void DOMStorageContextImpl::Shutdown() { + DCHECK(context_); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::Shutdown, context_)); +} + +int64 DOMStorageContextImpl::LeakyCloneSessionStorage( + int64 existing_namespace_id) { + DCHECK(context_); + int64 clone_id = context_->AllocateSessionId(); + context_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&DomStorageContext::CloneSessionNamespace, context_, + existing_namespace_id, clone_id)); + return clone_id; +} + +#endif // ENABLE_NEW_DOM_STORAGE_BACKEND diff --git a/content/browser/dom_storage/dom_storage_context_impl_new.h b/content/browser/dom_storage/dom_storage_context_impl_new.h new file mode 100644 index 0000000..6f51f35 --- /dev/null +++ b/content/browser/dom_storage/dom_storage_context_impl_new.h @@ -0,0 +1,75 @@ +// 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_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_ +#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_ +#pragma once + +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/string16.h" +#include "base/time.h" +#include "content/public/browser/dom_storage_context.h" +#include "webkit/dom_storage/dom_storage_types.h" + +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND + +namespace dom_storage { +class DomStorageContext; +} + +namespace quota { +class SpecialStoragePolicy; +} + +// This is owned by BrowserContext (aka Profile) and encapsulates all +// per-profile dom storage state. +class CONTENT_EXPORT DOMStorageContextImpl : + NON_EXPORTED_BASE(public content::DOMStorageContext), + public base::RefCountedThreadSafe<DOMStorageContextImpl> { + public: + // If |data_path| is empty, nothing will be saved to disk. + DOMStorageContextImpl(const FilePath& data_path, + quota::SpecialStoragePolicy* special_storage_policy); + + // DOMStorageContext implementation. + virtual void GetAllStorageFiles( + const GetAllStorageFilesCallback& callback) OVERRIDE; + virtual FilePath GetFilePath(const string16& origin_id) const OVERRIDE; + virtual void DeleteForOrigin(const string16& origin_id) OVERRIDE; + virtual void DeleteLocalStorageFile(const FilePath& file_path) OVERRIDE; + virtual void DeleteDataModifiedSince(const base::Time& cutoff) OVERRIDE; + + // Called to free up memory that's not strictly needed. + void PurgeMemory(); + + // Used by content settings to alter the behavior around + // what data to keep and what data to discard at shutdown. + // The policy is not so straight forward to describe, see + // the implementation for details. + void SetClearLocalState(bool clear_local_state); + void SaveSessionState(); + + // Called when the BrowserContext/Profile is going away. + void Shutdown(); + + // See render_message_filter.cc for details. + // TODO(michaeln): Remove this method when that bug is fixed. + int64 LeakyCloneSessionStorage(int64 existing_namespace_id); + + private: + friend class DOMStorageMessageFilter; // for access to context() + friend class SessionStorageNamespaceImpl; // ditto + friend class base::RefCountedThreadSafe<DOMStorageContextImpl>; + + virtual ~DOMStorageContextImpl(); + dom_storage::DomStorageContext* context() const { return context_.get(); } + + scoped_refptr<dom_storage::DomStorageContext> context_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageContextImpl); +}; + +#endif // ENABLE_NEW_DOM_STORAGE_BACKEND +#endif // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_ diff --git a/content/browser/in_process_webkit/dom_storage_browsertest.cc b/content/browser/in_process_webkit/dom_storage_browsertest.cc index 9f335fc..7de3dff 100644 --- a/content/browser/in_process_webkit/dom_storage_browsertest.cc +++ b/content/browser/in_process_webkit/dom_storage_browsertest.cc @@ -12,8 +12,13 @@ #include "content/public/common/url_constants.h" #include "content/test/test_browser_context.h" #include "googleurl/src/gurl.h" +#include "webkit/dom_storage/dom_storage_types.h" #include "webkit/quota/special_storage_policy.h" +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND +// No longer applicable. +#else + using content::BrowserContext; using content::BrowserThread; @@ -85,7 +90,7 @@ IN_PROC_BROWSER_TEST_F(DOMStorageBrowserTest, MAYBE_ClearLocalState) { static_cast<DOMStorageContextImpl*>( BrowserContext::GetDOMStorageContext(&browser_context)); dom_storage_context->set_data_path_for_testing(temp_dir.path()); - dom_storage_context->set_clear_local_state_on_exit(true); + dom_storage_context->SetClearLocalState(true); } // Make sure we wait until the destructor has run. scoped_refptr<base::ThreadTestHelper> helper( @@ -99,3 +104,5 @@ IN_PROC_BROWSER_TEST_F(DOMStorageBrowserTest, MAYBE_ClearLocalState) { ASSERT_FALSE(file_util::PathExists(temp_file_path_1)); ASSERT_TRUE(file_util::PathExists(temp_file_path_2)); } + +#endif // ENABLE_NEW_DOM_STORAGE_BACKEND diff --git a/content/browser/in_process_webkit/dom_storage_context_impl.cc b/content/browser/in_process_webkit/dom_storage_context_impl.cc index 3a63bb2..30a2788 100644 --- a/content/browser/in_process_webkit/dom_storage_context_impl.cc +++ b/content/browser/in_process_webkit/dom_storage_context_impl.cc @@ -198,6 +198,13 @@ DOMStorageContextImpl::GetMessageFilterSet() const { } void DOMStorageContextImpl::PurgeMemory() { + if (!webkit_message_loop_->RunsTasksOnCurrentThread()) { + webkit_message_loop_->PostTask( + FROM_HERE, + base::Bind(&DOMStorageContextImpl::PurgeMemory, this)); + return; + } + // It is only safe to purge the memory from the LocalStorage namespace, // because it is backed by disk and can be reloaded later. If we purge a // SessionStorage namespace, its data will be gone forever, because it isn't @@ -277,6 +284,28 @@ void DOMStorageContextImpl::DeleteAllLocalStorageFiles() { } } +void DOMStorageContextImpl::SetClearLocalState(bool clear_local_state) { + if (!webkit_message_loop_->RunsTasksOnCurrentThread()) { + webkit_message_loop_->PostTask( + FROM_HERE, + base::Bind( + &DOMStorageContextImpl::SetClearLocalState, + this, clear_local_state)); + return; + } + clear_local_state_on_exit_ = clear_local_state; +} + +void DOMStorageContextImpl::SaveSessionState() { + if (!webkit_message_loop_->RunsTasksOnCurrentThread()) { + webkit_message_loop_->PostTask( + FROM_HERE, + base::Bind(&DOMStorageContextImpl::SaveSessionState, this)); + return; + } + save_session_state_ = true; +} + DOMStorageNamespace* DOMStorageContextImpl::CreateLocalStorage() { FilePath dir_path; if (!data_path_.empty()) @@ -316,6 +345,7 @@ void DOMStorageContextImpl::CompleteCloningSessionStorage( void DOMStorageContextImpl::GetAllStorageFiles( const GetAllStorageFilesCallback& callback) { if (!webkit_message_loop_->RunsTasksOnCurrentThread()) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); webkit_message_loop_->PostTask( FROM_HERE, base::Bind( @@ -352,4 +382,3 @@ FilePath DOMStorageContextImpl::GetFilePath(const string16& origin_id) const { } #endif // ENABLE_NEW_DOM_STORAGE_BACKEND - diff --git a/content/browser/in_process_webkit/dom_storage_context_impl.h b/content/browser/in_process_webkit/dom_storage_context_impl.h index 0a82015..d7fbc79 100644 --- a/content/browser/in_process_webkit/dom_storage_context_impl.h +++ b/content/browser/in_process_webkit/dom_storage_context_impl.h @@ -105,14 +105,10 @@ class CONTENT_EXPORT DOMStorageContextImpl : // The local storage file extension. static const FilePath::CharType kLocalStorageExtension[]; - void set_clear_local_state_on_exit(bool clear_local_state) { - clear_local_state_on_exit_ = clear_local_state; - } + void SetClearLocalState(bool clear_local_state); // Disables the exit-time deletion for all data (also session-only data). - void SaveSessionState() { - save_session_state_ = true; - } + void SaveSessionState(); void set_data_path_for_testing(const FilePath& data_path) { data_path_ = data_path; diff --git a/content/browser/in_process_webkit/dom_storage_uitest.cc b/content/browser/in_process_webkit/dom_storage_uitest.cc index 8928235..d1a338f 100644 --- a/content/browser/in_process_webkit/dom_storage_uitest.cc +++ b/content/browser/in_process_webkit/dom_storage_uitest.cc @@ -10,6 +10,11 @@ #include "chrome/test/ui/ui_layout_test.h" #include "content/public/common/content_switches.h" #include "net/base/net_util.h" +#include "webkit/dom_storage/dom_storage_types.h" + +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND +// No longer applicable. +#else static const char* kRootFiles[] = { "clear.html", @@ -210,3 +215,5 @@ TEST_F(DomStorageEmptyDatabaseTest, MAYBE_NonEmptyDirAfterSet) { QuitBrowser(); EXPECT_TRUE(StorageDirIsEmpty()); } + +#endif // ENABLE_NEW_DOM_STORAGE_BACKEND diff --git a/content/browser/in_process_webkit/dom_storage_unittest.cc b/content/browser/in_process_webkit/dom_storage_unittest.cc index 1b0f41f..d529d53 100644 --- a/content/browser/in_process_webkit/dom_storage_unittest.cc +++ b/content/browser/in_process_webkit/dom_storage_unittest.cc @@ -8,8 +8,13 @@ #include "content/browser/in_process_webkit/dom_storage_context_impl.h" #include "content/test/test_browser_context.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webkit/dom_storage/dom_storage_types.h" #include "webkit/quota/mock_special_storage_policy.h" +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND +// No longer applicable. +#else + using content::BrowserContext; using content::BrowserThread; using content::BrowserThreadImpl; @@ -108,7 +113,7 @@ TEST_F(DOMStorageTest, SaveSessionState) { BrowserContext::GetDOMStorageContext(browser_context.get())); dom_storage_context->special_storage_policy_ = special_storage_policy; - dom_storage_context->set_clear_local_state_on_exit(true); + dom_storage_context->SetClearLocalState(true); // Save session state. This should bypass the destruction-time deletion. dom_storage_context->SaveSessionState(); @@ -126,3 +131,5 @@ TEST_F(DOMStorageTest, SaveSessionState) { EXPECT_TRUE(file_util::PathExists(session_only_database_path)); EXPECT_TRUE(file_util::PathExists(permanent_database_path)); } + +#endif // ENABLE_NEW_DOM_STORAGE_BACKEND diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 2a5b2eb..a322366 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -411,9 +411,21 @@ void RenderMessageFilter::OnMsgCreateWindow( return; } +#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND + // TODO(michaeln): Fix this. + // This is a bug in the existing impl, session storage is effectively + // leaked when created thru this code path (window.open()) since there + // is no balancing DeleteSessionStorage() for this Clone() call anywhere + // in the codebase. I'm replicating the bug for now. + *cloned_session_storage_namespace_id = + dom_storage_context_->LeakyCloneSessionStorage( + params.session_storage_namespace_id); +#else *cloned_session_storage_namespace_id = dom_storage_context_->CloneSessionStorage( params.session_storage_namespace_id); +#endif + render_widget_helper_->CreateNewWindow(params, peer_handle(), route_id, |