• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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