13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Copyright 2013 The Chromium Authors. All rights reserved. 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Use of this source code is governed by a BSD-style license that can be 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// found in the LICENSE file. 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/files/file_path.h" 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/gtest_prod_util.h" 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/memory/ref_counted.h" 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/memory/scoped_ptr.h" 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/strings/nullable_string16.h" 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/strings/string16.h" 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/common/content_export.h" 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/common/dom_storage/dom_storage_types.h" 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "url/gurl.h" 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace content { 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DOMStorageDatabaseAdapter; 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DOMStorageMap; 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DOMStorageTaskRunner; 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SessionStorageDatabase; 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Container for a per-origin Map of key/value pairs potentially 2689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos// backed by storage on disk and lazily commits changes to disk. 2789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos// See class comments for DOMStorageContextImpl for a larger overview. 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CONTENT_EXPORT DOMStorageArea 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : public base::RefCountedThreadSafe<DOMStorageArea> { 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 3289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos static const base::FilePath::CharType kDatabaseFileExtension[]; 3389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos static base::FilePath DatabaseFileNameFromOrigin(const GURL& origin); 3489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos static GURL OriginFromDatabaseFileName(const base::FilePath& file_name); 3589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 3689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Local storage. Backed on disk if directory is nonempty. 3789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageArea(const GURL& origin, 3889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos const base::FilePath& directory, 3989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageTaskRunner* task_runner); 4089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 4189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Session storage. Backed on disk if |session_storage_backing| is not NULL. 4289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageArea(int64 namespace_id, 4389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos const std::string& persistent_namespace_id, 4489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos const GURL& origin, 4589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos SessionStorageDatabase* session_storage_backing, 4689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageTaskRunner* task_runner); 4789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 4889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos const GURL& origin() const { return origin_; } 4989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos int64 namespace_id() const { return namespace_id_; } 5089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 5189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Writes a copy of the current set of values in the area to the |map|. 5289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void ExtractValues(DOMStorageValuesMap* map); 5389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 5489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos unsigned Length(); 5589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos base::NullableString16 Key(unsigned index); 5689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos base::NullableString16 GetItem(const base::string16& key); 5789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool SetItem(const base::string16& key, const base::string16& value, 5889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos base::NullableString16* old_value); 5989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool RemoveItem(const base::string16& key, base::string16* old_value); 6089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool Clear(); 6189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void FastClear(); 6289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 6389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageArea* ShallowCopy( 6489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos int64 destination_namespace_id, 6589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos const std::string& destination_persistent_namespace_id); 6689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 6789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool HasUncommittedChanges() const; 6889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 6989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Similar to Clear() but more optimized for just deleting 7089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // without raising events. 7189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void DeleteOrigin(); 7289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 7389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Frees up memory when possible. Typically, this method returns 7489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // the object to its just constructed state, however if uncommitted 7589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // changes are pending, it does nothing. 7689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void PurgeMemory(); 7789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 7889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Schedules the commit of any unsaved changes and enters a 7989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // shutdown state such that the value getters and setters will 8089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // no longer do anything. 8189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void Shutdown(); 8289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 8389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Returns true if the data is loaded in memory. 8489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool IsLoadedInMemory() const { return is_initial_import_done_; } 8589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 8689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos private: 8789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos friend class DOMStorageAreaTest; 8889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, DOMStorageAreaBasics); 8989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, BackingDatabaseOpened); 9089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, TestDatabaseFilePath); 9189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, CommitTasks); 9289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, CommitChangesAtShutdown); 9389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, DeleteOrigin); 9489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, PurgeMemory); 9589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos FRIEND_TEST_ALL_PREFIXES(DOMStorageContextImplTest, PersistentIds); 9689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos friend class base::RefCountedThreadSafe<DOMStorageArea>; 9789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 9889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos struct CommitBatch { 9989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool clear_all_first; 10089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos DOMStorageValuesMap changed_values; 10189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos CommitBatch(); 10289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos ~CommitBatch(); 10389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos }; 10489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 10589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos ~DOMStorageArea(); 10689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 10789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // If we haven't done so already and this is a local storage area, 10889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // will attempt to read any values for this origin currently 10989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // stored on disk. 11089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void InitialImportIfNeeded(); 11189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 11289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // Post tasks to defer writing a batch of changed values to 11389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // disk on the commit sequence, and to call back on the primary 11489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos // task sequence when complete. 11589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos CommitBatch* CreateCommitBatchIfNeeded(); 11689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void OnCommitTimer(); 11789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void CommitChanges(const CommitBatch* commit_batch); 11889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void OnCommitComplete(); 11989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 12089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos void ShutdownInCommitSequence(); 12189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 12289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos int64 namespace_id_; 12389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos std::string persistent_namespace_id_; 12489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos GURL origin_; 12589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos base::FilePath directory_; 12689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos scoped_refptr<DOMStorageTaskRunner> task_runner_; 12789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos scoped_refptr<DOMStorageMap> map_; 12889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos scoped_ptr<DOMStorageDatabaseAdapter> backing_; 12989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos scoped_refptr<SessionStorageDatabase> session_storage_backing_; 13089659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool is_initial_import_done_; 13189659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos bool is_shutdown_; 13289659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos scoped_ptr<CommitBatch> commit_batch_; 13389659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos int commit_batches_in_flight_; 13489659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos}; 13589659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 13689659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos} // namespace content 13789659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos 13889659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos#endif // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 13989659d2685195bf9e34ff7a2e321e6ce471c8462Pyry Haulos