• 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_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 
origin()48   const GURL& origin() const { return origin_; }
namespace_id()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.
IsLoadedInMemory()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