Index: webkit/browser/dom_storage/dom_storage_context.cc |
diff --git a/webkit/browser/dom_storage/dom_storage_context.cc b/webkit/browser/dom_storage/dom_storage_context.cc |
deleted file mode 100644 |
index 5d7229d51ad5b0b28447ccabf814fcf217dd0023..0000000000000000000000000000000000000000 |
--- a/webkit/browser/dom_storage/dom_storage_context.cc |
+++ /dev/null |
@@ -1,418 +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 "webkit/browser/dom_storage/dom_storage_context.h" |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/file_util.h" |
-#include "base/files/file_enumerator.h" |
-#include "base/guid.h" |
-#include "base/location.h" |
-#include "base/time/time.h" |
-#include "webkit/browser/dom_storage/dom_storage_area.h" |
-#include "webkit/browser/dom_storage/dom_storage_database.h" |
-#include "webkit/browser/dom_storage/dom_storage_namespace.h" |
-#include "webkit/browser/dom_storage/dom_storage_task_runner.h" |
-#include "webkit/browser/dom_storage/session_storage_database.h" |
-#include "webkit/browser/quota/special_storage_policy.h" |
-#include "webkit/common/dom_storage/dom_storage_types.h" |
- |
-namespace dom_storage { |
- |
-static const int kSessionStoraceScavengingSeconds = 60; |
- |
-DomStorageContext::DomStorageContext( |
- const base::FilePath& localstorage_directory, |
- const base::FilePath& sessionstorage_directory, |
- quota::SpecialStoragePolicy* special_storage_policy, |
- DomStorageTaskRunner* task_runner) |
- : localstorage_directory_(localstorage_directory), |
- sessionstorage_directory_(sessionstorage_directory), |
- task_runner_(task_runner), |
- is_shutdown_(false), |
- force_keep_session_state_(false), |
- special_storage_policy_(special_storage_policy), |
- scavenging_started_(false) { |
- // AtomicSequenceNum starts at 0 but we want to start session |
- // namespace ids at one since zero is reserved for the |
- // kLocalStorageNamespaceId. |
- session_id_sequence_.GetNext(); |
-} |
- |
-DomStorageContext::~DomStorageContext() { |
- if (session_storage_database_.get()) { |
- // SessionStorageDatabase shouldn't be deleted right away: deleting it will |
- // potentially involve waiting in leveldb::DBImpl::~DBImpl, and waiting |
- // shouldn't happen on this thread. |
- SessionStorageDatabase* to_release = session_storage_database_.get(); |
- to_release->AddRef(); |
- session_storage_database_ = NULL; |
- task_runner_->PostShutdownBlockingTask( |
- FROM_HERE, |
- DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind(&SessionStorageDatabase::Release, |
- base::Unretained(to_release))); |
- } |
-} |
- |
-DomStorageNamespace* DomStorageContext::GetStorageNamespace( |
- int64 namespace_id) { |
- if (is_shutdown_) |
- return NULL; |
- StorageNamespaceMap::iterator found = namespaces_.find(namespace_id); |
- if (found == namespaces_.end()) { |
- if (namespace_id == kLocalStorageNamespaceId) { |
- if (!localstorage_directory_.empty()) { |
- if (!file_util::CreateDirectory(localstorage_directory_)) { |
- LOG(ERROR) << "Failed to create 'Local Storage' directory," |
- " falling back to in-memory only."; |
- localstorage_directory_ = base::FilePath(); |
- } |
- } |
- DomStorageNamespace* local = |
- new DomStorageNamespace(localstorage_directory_, task_runner_.get()); |
- namespaces_[kLocalStorageNamespaceId] = local; |
- return local; |
- } |
- return NULL; |
- } |
- return found->second.get(); |
-} |
- |
-void DomStorageContext::GetLocalStorageUsage( |
- std::vector<LocalStorageUsageInfo>* infos, |
- bool include_file_info) { |
- if (localstorage_directory_.empty()) |
- return; |
- base::FileEnumerator enumerator(localstorage_directory_, false, |
- base::FileEnumerator::FILES); |
- for (base::FilePath path = enumerator.Next(); !path.empty(); |
- path = enumerator.Next()) { |
- if (path.MatchesExtension(DomStorageArea::kDatabaseFileExtension)) { |
- LocalStorageUsageInfo info; |
- info.origin = DomStorageArea::OriginFromDatabaseFileName(path); |
- if (include_file_info) { |
- base::FileEnumerator::FileInfo find_info = enumerator.GetInfo(); |
- info.data_size = find_info.GetSize(); |
- info.last_modified = find_info.GetLastModifiedTime(); |
- } |
- infos->push_back(info); |
- } |
- } |
-} |
- |
-void DomStorageContext::GetSessionStorageUsage( |
- std::vector<SessionStorageUsageInfo>* infos) { |
- if (!session_storage_database_.get()) |
- return; |
- std::map<std::string, std::vector<GURL> > namespaces_and_origins; |
- session_storage_database_->ReadNamespacesAndOrigins( |
- &namespaces_and_origins); |
- for (std::map<std::string, std::vector<GURL> >::const_iterator it = |
- namespaces_and_origins.begin(); |
- it != namespaces_and_origins.end(); ++it) { |
- for (std::vector<GURL>::const_iterator origin_it = it->second.begin(); |
- origin_it != it->second.end(); ++origin_it) { |
- SessionStorageUsageInfo info; |
- info.persistent_namespace_id = it->first; |
- info.origin = *origin_it; |
- infos->push_back(info); |
- } |
- } |
-} |
- |
-void DomStorageContext::DeleteLocalStorage(const GURL& origin) { |
- DCHECK(!is_shutdown_); |
- DomStorageNamespace* local = GetStorageNamespace(kLocalStorageNamespaceId); |
- local->DeleteLocalStorageOrigin(origin); |
- // Synthesize a 'cleared' event if the area is open so CachedAreas in |
- // renderers get emptied out too. |
- DomStorageArea* area = local->GetOpenStorageArea(origin); |
- if (area) |
- NotifyAreaCleared(area, origin); |
-} |
- |
-void DomStorageContext::DeleteSessionStorage( |
- const SessionStorageUsageInfo& usage_info) { |
- DCHECK(!is_shutdown_); |
- DomStorageNamespace* dom_storage_namespace = NULL; |
- std::map<std::string, int64>::const_iterator it = |
- persistent_namespace_id_to_namespace_id_.find( |
- usage_info.persistent_namespace_id); |
- if (it != persistent_namespace_id_to_namespace_id_.end()) { |
- dom_storage_namespace = GetStorageNamespace(it->second); |
- } else { |
- int64 namespace_id = AllocateSessionId(); |
- CreateSessionNamespace(namespace_id, usage_info.persistent_namespace_id); |
- dom_storage_namespace = GetStorageNamespace(namespace_id); |
- } |
- dom_storage_namespace->DeleteSessionStorageOrigin(usage_info.origin); |
- // Synthesize a 'cleared' event if the area is open so CachedAreas in |
- // renderers get emptied out too. |
- DomStorageArea* area = |
- dom_storage_namespace->GetOpenStorageArea(usage_info.origin); |
- if (area) |
- NotifyAreaCleared(area, usage_info.origin); |
-} |
- |
-void DomStorageContext::PurgeMemory() { |
- // We can only purge memory from the local storage namespace |
- // which is backed by disk. |
- // TODO(marja): Purge sessionStorage, too. (Requires changes to the FastClear |
- // functionality.) |
- StorageNamespaceMap::iterator found = |
- namespaces_.find(kLocalStorageNamespaceId); |
- if (found != namespaces_.end()) |
- found->second->PurgeMemory(DomStorageNamespace::PURGE_AGGRESSIVE); |
-} |
- |
-void DomStorageContext::Shutdown() { |
- is_shutdown_ = true; |
- StorageNamespaceMap::const_iterator it = namespaces_.begin(); |
- for (; it != namespaces_.end(); ++it) |
- it->second->Shutdown(); |
- |
- if (localstorage_directory_.empty() && !session_storage_database_.get()) |
- return; |
- |
- // Respect the content policy settings about what to |
- // keep and what to discard. |
- if (force_keep_session_state_) |
- return; // Keep everything. |
- |
- bool has_session_only_origins = |
- special_storage_policy_.get() && |
- special_storage_policy_->HasSessionOnlyOrigins(); |
- |
- if (has_session_only_origins) { |
- // We may have to delete something. We continue on the |
- // commit sequence after area shutdown tasks have cycled |
- // thru that sequence (and closed their database files). |
- bool success = task_runner_->PostShutdownBlockingTask( |
- FROM_HERE, |
- DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind(&DomStorageContext::ClearSessionOnlyOrigins, this)); |
- DCHECK(success); |
- } |
-} |
- |
-void DomStorageContext::AddEventObserver(EventObserver* observer) { |
- event_observers_.AddObserver(observer); |
-} |
- |
-void DomStorageContext::RemoveEventObserver(EventObserver* observer) { |
- event_observers_.RemoveObserver(observer); |
-} |
- |
-void DomStorageContext::NotifyItemSet( |
- const DomStorageArea* area, |
- const base::string16& key, |
- const base::string16& new_value, |
- const base::NullableString16& old_value, |
- const GURL& page_url) { |
- FOR_EACH_OBSERVER( |
- EventObserver, event_observers_, |
- OnDomStorageItemSet(area, key, new_value, old_value, page_url)); |
-} |
- |
-void DomStorageContext::NotifyItemRemoved( |
- const DomStorageArea* area, |
- const base::string16& key, |
- const base::string16& old_value, |
- const GURL& page_url) { |
- FOR_EACH_OBSERVER( |
- EventObserver, event_observers_, |
- OnDomStorageItemRemoved(area, key, old_value, page_url)); |
-} |
- |
-void DomStorageContext::NotifyAreaCleared( |
- const DomStorageArea* area, |
- const GURL& page_url) { |
- FOR_EACH_OBSERVER( |
- EventObserver, event_observers_, |
- OnDomStorageAreaCleared(area, page_url)); |
-} |
- |
-std::string DomStorageContext::AllocatePersistentSessionId() { |
- std::string guid = base::GenerateGUID(); |
- std::replace(guid.begin(), guid.end(), '-', '_'); |
- return guid; |
-} |
- |
-void DomStorageContext::CreateSessionNamespace( |
- int64 namespace_id, |
- const std::string& persistent_namespace_id) { |
- if (is_shutdown_) |
- return; |
- DCHECK(namespace_id != kLocalStorageNamespaceId); |
- DCHECK(namespaces_.find(namespace_id) == namespaces_.end()); |
- namespaces_[namespace_id] = new DomStorageNamespace( |
- namespace_id, persistent_namespace_id, session_storage_database_.get(), |
- task_runner_.get()); |
- persistent_namespace_id_to_namespace_id_[persistent_namespace_id] = |
- namespace_id; |
-} |
- |
-void DomStorageContext::DeleteSessionNamespace( |
- int64 namespace_id, bool should_persist_data) { |
- DCHECK_NE(kLocalStorageNamespaceId, namespace_id); |
- StorageNamespaceMap::const_iterator it = namespaces_.find(namespace_id); |
- if (it == namespaces_.end()) |
- return; |
- std::string persistent_namespace_id = it->second->persistent_namespace_id(); |
- if (session_storage_database_.get()) { |
- if (!should_persist_data) { |
- task_runner_->PostShutdownBlockingTask( |
- FROM_HERE, |
- DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind( |
- base::IgnoreResult(&SessionStorageDatabase::DeleteNamespace), |
- session_storage_database_, |
- persistent_namespace_id)); |
- } else { |
- // Ensure that the data gets committed before we shut down. |
- it->second->Shutdown(); |
- if (!scavenging_started_) { |
- // Protect the persistent namespace ID from scavenging. |
- protected_persistent_session_ids_.insert(persistent_namespace_id); |
- } |
- } |
- } |
- persistent_namespace_id_to_namespace_id_.erase(persistent_namespace_id); |
- namespaces_.erase(namespace_id); |
-} |
- |
-void DomStorageContext::CloneSessionNamespace( |
- int64 existing_id, int64 new_id, |
- const std::string& new_persistent_id) { |
- if (is_shutdown_) |
- return; |
- DCHECK_NE(kLocalStorageNamespaceId, existing_id); |
- DCHECK_NE(kLocalStorageNamespaceId, new_id); |
- StorageNamespaceMap::iterator found = namespaces_.find(existing_id); |
- if (found != namespaces_.end()) |
- namespaces_[new_id] = found->second->Clone(new_id, new_persistent_id); |
- else |
- CreateSessionNamespace(new_id, new_persistent_id); |
-} |
- |
-void DomStorageContext::ClearSessionOnlyOrigins() { |
- if (!localstorage_directory_.empty()) { |
- std::vector<LocalStorageUsageInfo> infos; |
- const bool kDontIncludeFileInfo = false; |
- GetLocalStorageUsage(&infos, kDontIncludeFileInfo); |
- for (size_t i = 0; i < infos.size(); ++i) { |
- const GURL& origin = infos[i].origin; |
- if (special_storage_policy_->IsStorageProtected(origin)) |
- continue; |
- if (!special_storage_policy_->IsStorageSessionOnly(origin)) |
- continue; |
- |
- base::FilePath database_file_path = localstorage_directory_.Append( |
- DomStorageArea::DatabaseFileNameFromOrigin(origin)); |
- sql::Connection::Delete(database_file_path); |
- } |
- } |
- if (session_storage_database_.get()) { |
- std::vector<SessionStorageUsageInfo> infos; |
- GetSessionStorageUsage(&infos); |
- for (size_t i = 0; i < infos.size(); ++i) { |
- const GURL& origin = infos[i].origin; |
- if (special_storage_policy_->IsStorageProtected(origin)) |
- continue; |
- if (!special_storage_policy_->IsStorageSessionOnly(origin)) |
- continue; |
- session_storage_database_->DeleteArea(infos[i].persistent_namespace_id, |
- origin); |
- } |
- } |
-} |
- |
-void DomStorageContext::SetSaveSessionStorageOnDisk() { |
- DCHECK(namespaces_.empty()); |
- if (!sessionstorage_directory_.empty()) { |
- session_storage_database_ = new SessionStorageDatabase( |
- sessionstorage_directory_); |
- } |
-} |
- |
-void DomStorageContext::StartScavengingUnusedSessionStorage() { |
- if (session_storage_database_.get()) { |
- task_runner_->PostDelayedTask( |
- FROM_HERE, base::Bind(&DomStorageContext::FindUnusedNamespaces, this), |
- base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
- } |
-} |
- |
-void DomStorageContext::FindUnusedNamespaces() { |
- DCHECK(session_storage_database_.get()); |
- if (scavenging_started_) |
- return; |
- scavenging_started_ = true; |
- std::set<std::string> namespace_ids_in_use; |
- for (StorageNamespaceMap::const_iterator it = namespaces_.begin(); |
- it != namespaces_.end(); ++it) |
- namespace_ids_in_use.insert(it->second->persistent_namespace_id()); |
- std::set<std::string> protected_persistent_session_ids; |
- protected_persistent_session_ids.swap(protected_persistent_session_ids_); |
- task_runner_->PostShutdownBlockingTask( |
- FROM_HERE, DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind( |
- &DomStorageContext::FindUnusedNamespacesInCommitSequence, |
- this, namespace_ids_in_use, protected_persistent_session_ids)); |
-} |
- |
-void DomStorageContext::FindUnusedNamespacesInCommitSequence( |
- const std::set<std::string>& namespace_ids_in_use, |
- const std::set<std::string>& protected_persistent_session_ids) { |
- DCHECK(session_storage_database_.get()); |
- // Delete all namespaces which don't have an associated DomStorageNamespace |
- // alive. |
- std::map<std::string, std::vector<GURL> > namespaces_and_origins; |
- session_storage_database_->ReadNamespacesAndOrigins(&namespaces_and_origins); |
- for (std::map<std::string, std::vector<GURL> >::const_iterator it = |
- namespaces_and_origins.begin(); |
- it != namespaces_and_origins.end(); ++it) { |
- if (namespace_ids_in_use.find(it->first) == namespace_ids_in_use.end() && |
- protected_persistent_session_ids.find(it->first) == |
- protected_persistent_session_ids.end()) { |
- deletable_persistent_namespace_ids_.push_back(it->first); |
- } |
- } |
- if (!deletable_persistent_namespace_ids_.empty()) { |
- task_runner_->PostDelayedTask( |
- FROM_HERE, base::Bind( |
- &DomStorageContext::DeleteNextUnusedNamespace, |
- this), |
- base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
- } |
-} |
- |
-void DomStorageContext::DeleteNextUnusedNamespace() { |
- if (is_shutdown_) |
- return; |
- task_runner_->PostShutdownBlockingTask( |
- FROM_HERE, DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind( |
- &DomStorageContext::DeleteNextUnusedNamespaceInCommitSequence, |
- this)); |
-} |
- |
-void DomStorageContext::DeleteNextUnusedNamespaceInCommitSequence() { |
- if (deletable_persistent_namespace_ids_.empty()) |
- return; |
- const std::string& persistent_id = deletable_persistent_namespace_ids_.back(); |
- session_storage_database_->DeleteNamespace(persistent_id); |
- deletable_persistent_namespace_ids_.pop_back(); |
- if (!deletable_persistent_namespace_ids_.empty()) { |
- task_runner_->PostDelayedTask( |
- FROM_HERE, base::Bind( |
- &DomStorageContext::DeleteNextUnusedNamespace, |
- this), |
- base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
- } |
-} |
- |
-} // namespace dom_storage |