1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 6 #define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 7 8 #include "base/files/file_path.h" 9 #include "base/gtest_prod_util.h" 10 #include "base/memory/ref_counted.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/strings/nullable_string16.h" 13 #include "base/strings/string16.h" 14 #include "content/common/content_export.h" 15 #include "content/common/dom_storage/dom_storage_types.h" 16 #include "url/gurl.h" 17 18 namespace content { 19 20 class DOMStorageDatabaseAdapter; 21 class DOMStorageMap; 22 class DOMStorageTaskRunner; 23 class SessionStorageDatabase; 24 25 // Container for a per-origin Map of key/value pairs potentially 26 // backed by storage on disk and lazily commits changes to disk. 27 // See class comments for DOMStorageContextImpl for a larger overview. 28 class CONTENT_EXPORT DOMStorageArea 29 : public base::RefCountedThreadSafe<DOMStorageArea> { 30 31 public: 32 static const base::FilePath::CharType kDatabaseFileExtension[]; 33 static base::FilePath DatabaseFileNameFromOrigin(const GURL& origin); 34 static GURL OriginFromDatabaseFileName(const base::FilePath& file_name); 35 36 // Local storage. Backed on disk if directory is nonempty. 37 DOMStorageArea(const GURL& origin, 38 const base::FilePath& directory, 39 DOMStorageTaskRunner* task_runner); 40 41 // Session storage. Backed on disk if |session_storage_backing| is not NULL. 42 DOMStorageArea(int64 namespace_id, 43 const std::string& persistent_namespace_id, 44 const GURL& origin, 45 SessionStorageDatabase* session_storage_backing, 46 DOMStorageTaskRunner* task_runner); 47 48 const GURL& origin() const { return origin_; } 49 int64 namespace_id() const { return namespace_id_; } 50 51 // Writes a copy of the current set of values in the area to the |map|. 52 void ExtractValues(DOMStorageValuesMap* map); 53 54 unsigned Length(); 55 base::NullableString16 Key(unsigned index); 56 base::NullableString16 GetItem(const base::string16& key); 57 bool SetItem(const base::string16& key, const base::string16& value, 58 base::NullableString16* old_value); 59 bool RemoveItem(const base::string16& key, base::string16* old_value); 60 bool Clear(); 61 void FastClear(); 62 63 DOMStorageArea* ShallowCopy( 64 int64 destination_namespace_id, 65 const std::string& destination_persistent_namespace_id); 66 67 bool HasUncommittedChanges() const; 68 69 // Similar to Clear() but more optimized for just deleting 70 // without raising events. 71 void DeleteOrigin(); 72 73 // Frees up memory when possible. Typically, this method returns 74 // the object to its just constructed state, however if uncommitted 75 // changes are pending, it does nothing. 76 void PurgeMemory(); 77 78 // Schedules the commit of any unsaved changes and enters a 79 // shutdown state such that the value getters and setters will 80 // no longer do anything. 81 void Shutdown(); 82 83 // Returns true if the data is loaded in memory. 84 bool IsLoadedInMemory() const { return is_initial_import_done_; } 85 86 private: 87 friend class DOMStorageAreaTest; 88 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, DOMStorageAreaBasics); 89 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, BackingDatabaseOpened); 90 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, TestDatabaseFilePath); 91 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, CommitTasks); 92 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, CommitChangesAtShutdown); 93 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, DeleteOrigin); 94 FRIEND_TEST_ALL_PREFIXES(DOMStorageAreaTest, PurgeMemory); 95 FRIEND_TEST_ALL_PREFIXES(DOMStorageContextImplTest, PersistentIds); 96 friend class base::RefCountedThreadSafe<DOMStorageArea>; 97 98 struct CommitBatch { 99 bool clear_all_first; 100 DOMStorageValuesMap changed_values; 101 CommitBatch(); 102 ~CommitBatch(); 103 }; 104 105 ~DOMStorageArea(); 106 107 // If we haven't done so already and this is a local storage area, 108 // will attempt to read any values for this origin currently 109 // stored on disk. 110 void InitialImportIfNeeded(); 111 112 // Post tasks to defer writing a batch of changed values to 113 // disk on the commit sequence, and to call back on the primary 114 // task sequence when complete. 115 CommitBatch* CreateCommitBatchIfNeeded(); 116 void OnCommitTimer(); 117 void CommitChanges(const CommitBatch* commit_batch); 118 void OnCommitComplete(); 119 120 void ShutdownInCommitSequence(); 121 122 int64 namespace_id_; 123 std::string persistent_namespace_id_; 124 GURL origin_; 125 base::FilePath directory_; 126 scoped_refptr<DOMStorageTaskRunner> task_runner_; 127 scoped_refptr<DOMStorageMap> map_; 128 scoped_ptr<DOMStorageDatabaseAdapter> backing_; 129 scoped_refptr<SessionStorageDatabase> session_storage_backing_; 130 bool is_initial_import_done_; 131 bool is_shutdown_; 132 scoped_ptr<CommitBatch> commit_batch_; 133 int commit_batches_in_flight_; 134 }; 135 136 } // namespace content 137 138 #endif // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_AREA_H_ 139