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_NAMESPACE_H_ 6 #define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/files/file_path.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/strings/nullable_string16.h" 15 #include "content/common/content_export.h" 16 #include "content/public/browser/session_storage_namespace.h" 17 #include "url/gurl.h" 18 19 namespace content { 20 21 class DOMStorageArea; 22 class DOMStorageContextImpl; 23 class DOMStorageTaskRunner; 24 class SessionStorageDatabase; 25 26 // Container for the set of per-origin Areas. 27 // See class comments for DOMStorageContextImpl for a larger overview. 28 class CONTENT_EXPORT DOMStorageNamespace 29 : public base::RefCountedThreadSafe<DOMStorageNamespace> { 30 public: 31 // Option for PurgeMemory. 32 enum PurgeOption { 33 // Purge unopened areas only. 34 PURGE_UNOPENED, 35 36 // Purge aggressively, i.e. discard cache even for areas that have 37 // non-zero open count. 38 PURGE_AGGRESSIVE, 39 }; 40 41 // Constructor for a LocalStorage namespace with id of 0 42 // and an optional backing directory on disk. 43 DOMStorageNamespace(const base::FilePath& directory, // may be empty 44 DOMStorageTaskRunner* task_runner); 45 46 // Constructor for a SessionStorage namespace with a non-zero id and an 47 // optional backing on disk via |session_storage_database| (may be NULL). 48 DOMStorageNamespace(int64 namespace_id, 49 const std::string& persistent_namespace_id, 50 SessionStorageDatabase* session_storage_database, 51 DOMStorageTaskRunner* task_runner); 52 namespace_id()53 int64 namespace_id() const { return namespace_id_; } persistent_namespace_id()54 const std::string& persistent_namespace_id() const { 55 return persistent_namespace_id_; 56 } 57 58 // Returns the storage area for the given origin, 59 // creating instance if needed. Each call to open 60 // must be balanced with a call to CloseStorageArea. 61 DOMStorageArea* OpenStorageArea(const GURL& origin); 62 void CloseStorageArea(DOMStorageArea* area); 63 64 // Returns the area for |origin| if it's open, otherwise NULL. 65 DOMStorageArea* GetOpenStorageArea(const GURL& origin); 66 67 // Creates a clone of |this| namespace including 68 // shallow copies of all contained areas. 69 // Should only be called for session storage namespaces. 70 DOMStorageNamespace* Clone(int64 clone_namespace_id, 71 const std::string& clone_persistent_namespace_id); 72 73 // Creates an alias of |this| namespace. 74 // Should only be called for session storage namespaces. 75 DOMStorageNamespace* CreateAlias(int64 alias_namespace_id); 76 77 void DeleteLocalStorageOrigin(const GURL& origin); 78 void DeleteSessionStorageOrigin(const GURL& origin); 79 void PurgeMemory(PurgeOption purge); 80 void Shutdown(); 81 82 unsigned int CountInMemoryAreas() const; 83 84 void AddTransactionLogProcessId(int process_id); 85 void RemoveTransactionLogProcessId(int process_id); 86 SessionStorageNamespace::MergeResult Merge( 87 bool actually_merge, 88 int process_id, 89 DOMStorageNamespace* other, 90 DOMStorageContextImpl* context); alias_master_namespace()91 DOMStorageNamespace* alias_master_namespace() { 92 return alias_master_namespace_.get(); 93 } num_aliases()94 int num_aliases() const { return num_aliases_; } ready_for_deletion_pending_aliases()95 bool ready_for_deletion_pending_aliases() const { 96 return ready_for_deletion_pending_aliases_; } set_ready_for_deletion_pending_aliases(bool value)97 void set_ready_for_deletion_pending_aliases(bool value) { 98 ready_for_deletion_pending_aliases_ = value; 99 } must_persist_at_shutdown()100 bool must_persist_at_shutdown() const { return must_persist_at_shutdown_; } set_must_persist_at_shutdown(bool value)101 void set_must_persist_at_shutdown(bool value) { 102 must_persist_at_shutdown_ = value; 103 } 104 105 enum LogType { 106 TRANSACTION_READ, 107 TRANSACTION_WRITE, 108 TRANSACTION_REMOVE, 109 TRANSACTION_CLEAR 110 }; 111 112 struct CONTENT_EXPORT TransactionRecord { 113 LogType transaction_type; 114 GURL origin; 115 GURL page_url; 116 base::string16 key; 117 base::NullableString16 value; 118 TransactionRecord(); 119 ~TransactionRecord(); 120 }; 121 122 void AddTransaction(int process_id, const TransactionRecord& transaction); 123 bool IsLoggingRenderer(int process_id); 124 // Decrements the count of aliases owned by the master, and returns true 125 // if the new count is 0. 126 bool DecrementMasterAliasCount(); 127 128 private: 129 friend class base::RefCountedThreadSafe<DOMStorageNamespace>; 130 131 // Struct to hold references to our contained areas and 132 // to keep track of how many tabs have a given area open. 133 struct AreaHolder { 134 scoped_refptr<DOMStorageArea> area_; 135 int open_count_; 136 AreaHolder(); 137 AreaHolder(DOMStorageArea* area, int count); 138 ~AreaHolder(); 139 }; 140 typedef std::map<GURL, AreaHolder> AreaMap; 141 142 struct TransactionData { 143 bool max_log_size_exceeded; 144 std::vector<TransactionRecord> log; 145 TransactionData(); 146 ~TransactionData(); 147 }; 148 149 ~DOMStorageNamespace(); 150 151 // Returns a pointer to the area holder in our map or NULL. 152 AreaHolder* GetAreaHolder(const GURL& origin); 153 154 // Switches the current alias DOM storage namespace to a new alias master. 155 void SwitchToNewAliasMaster(DOMStorageNamespace* new_master, 156 DOMStorageContextImpl* context); 157 158 int64 namespace_id_; 159 std::string persistent_namespace_id_; 160 base::FilePath directory_; 161 AreaMap areas_; 162 scoped_refptr<DOMStorageTaskRunner> task_runner_; 163 scoped_refptr<SessionStorageDatabase> session_storage_database_; 164 std::map<int, TransactionData*> transactions_; 165 int num_aliases_; 166 scoped_refptr<DOMStorageNamespace> alias_master_namespace_; 167 DOMStorageNamespace* old_master_for_close_area_; 168 // Indicates whether we have already decremented |num_aliases_| for this 169 // namespace in its alias master. We may only decrement it once, and around 170 // deletion, this instance will stick around a bit longer until its refcount 171 // drops to 0. Therefore, we want to make sure we don't decrement the master's 172 // alias count a second time. 173 bool master_alias_count_decremented_; 174 // This indicates, for an alias master, that the master itself is ready 175 // for deletion, but there are aliases outstanding that we have to wait for 176 // before we can start cleaning up the master. 177 bool ready_for_deletion_pending_aliases_; 178 bool must_persist_at_shutdown_; 179 }; 180 181 } // namespace content 182 183 184 #endif // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_ 185