Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: content/browser/dom_storage/dom_storage_context_impl_new.cc

Issue 9695013: DOMStorageContextImpl that's implemented in terms of the new dom_storage classes. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/in_process_webkit/dom_storage_context_impl.h" 5 #include "content/browser/dom_storage/dom_storage_context_impl_new.h"
6 6
7 #include <algorithm> 7 #ifdef ENABLE_NEW_DOM_STORAGE_BACKEND
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_path.h" 10 #include "base/bind_helpers.h"
11 #include "base/file_util.h" 11 #include "base/message_loop_proxy.h"
12 #include "base/string_util.h"
13 #include "content/browser/in_process_webkit/dom_storage_area.h"
14 #include "content/browser/in_process_webkit/dom_storage_namespace.h"
15 #include "content/common/dom_storage_common.h"
16 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
14 #include "webkit/database/database_util.h"
15 #include "webkit/dom_storage/dom_storage_area.h"
16 #include "webkit/dom_storage/dom_storage_context.h"
17 #include "webkit/dom_storage/dom_storage_task_runner.h"
19 #include "webkit/glue/webkit_glue.h" 18 #include "webkit/glue/webkit_glue.h"
20 #include "webkit/quota/special_storage_policy.h"
21 19
22 using content::BrowserThread; 20 using content::BrowserThread;
23 using content::DOMStorageContext; 21 using content::DOMStorageContext;
24 using WebKit::WebSecurityOrigin; 22 using dom_storage::DomStorageArea;
25 23 using dom_storage::DomStorageContext;
26 const FilePath::CharType DOMStorageContextImpl::kLocalStorageDirectory[] = 24 using dom_storage::DomStorageWorkerPoolTaskRunner;
27 FILE_PATH_LITERAL("Local Storage"); 25 using webkit_database::DatabaseUtil;
28
29 const FilePath::CharType DOMStorageContextImpl::kLocalStorageExtension[] =
30 FILE_PATH_LITERAL(".localstorage");
31 26
32 namespace { 27 namespace {
33 28
34 void ClearLocalState(const FilePath& domstorage_path, 29 // TODO(michaeln): Fix the content layer api, FilePaths and
35 quota::SpecialStoragePolicy* special_storage_policy, 30 // string16 origin_ids are just wrong. Then get rid of
36 bool clear_all_databases) { 31 // this conversion non-sense. Most of the includes are just
37 file_util::FileEnumerator file_enumerator( 32 // to support that non-sense.
38 domstorage_path, false, file_util::FileEnumerator::FILES); 33
39 for (FilePath file_path = file_enumerator.Next(); !file_path.empty(); 34 GURL OriginIdToGURL(const string16& origin_id) {
40 file_path = file_enumerator.Next()) { 35 return DatabaseUtil::GetOriginFromIdentifier(origin_id);
41 if (file_path.Extension() ==
42 DOMStorageContextImpl::kLocalStorageExtension) {
43 GURL origin(WebSecurityOrigin::createFromDatabaseIdentifier(
44 webkit_glue::FilePathToWebString(file_path.BaseName())).toString());
45 if (special_storage_policy &&
46 special_storage_policy->IsStorageProtected(origin))
47 continue;
48 if (!clear_all_databases &&
49 !special_storage_policy->IsStorageSessionOnly(origin)) {
50 continue;
51 }
52 file_util::Delete(file_path, false);
53 }
54 }
55 } 36 }
56 37
57 } // namespace 38 FilePath OriginToFullFilePath(const FilePath& directory,
39 const GURL& origin) {
40 return directory.Append(DomStorageArea::DatabaseFileNameFromOrigin(origin));
41 }
42
43 GURL FilePathToOrigin(const FilePath& path) {
44 return OriginIdToGURL(
45 webkit_glue::FilePathToWebString(path.BaseName().RemoveExtension()));
46 }
47
48 void InvokeAllStorageFilesCallbackHelper(
49 const DOMStorageContext::GetAllStorageFilesCallback& callback,
50 const std::vector<FilePath>& file_paths) {
51 callback.Run(file_paths);
52 }
53
54 void GetAllStorageFilesHelper(
55 base::MessageLoopProxy* reply_loop,
56 DomStorageContext* context,
57 const DOMStorageContext::GetAllStorageFilesCallback& callback) {
58 std::vector<DomStorageContext::UsageInfo> infos;
59 context->GetUsageInfo(&infos);
60
61 std::vector<FilePath> paths;
62 for (size_t i = 0; i < infos.size(); ++i) {
63 paths.push_back(
64 OriginToFullFilePath(context->directory(), infos[i].origin));
65 }
66
67 reply_loop->PostTask(
68 FROM_HERE,
69 base::Bind(&InvokeAllStorageFilesCallbackHelper,
70 callback, paths));
71 }
72
73 }
58 74
59 DOMStorageContextImpl::DOMStorageContextImpl( 75 DOMStorageContextImpl::DOMStorageContextImpl(
60 const FilePath& data_path, 76 const FilePath& data_path,
61 quota::SpecialStoragePolicy* special_storage_policy) 77 quota::SpecialStoragePolicy* special_storage_policy) {
62 : last_storage_area_id_(0), 78 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
63 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), 79 context_ = new dom_storage::DomStorageContext(
64 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), 80 data_path, special_storage_policy,
65 clear_local_state_on_exit_(false), 81 new DomStorageWorkerPoolTaskRunner(
66 save_session_state_(false), 82 worker_pool,
67 special_storage_policy_(special_storage_policy), 83 worker_pool->GetNamedSequenceToken("dom_storage"),
68 webkit_message_loop_( 84 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
69 BrowserThread::GetMessageLoopProxyForThread(
70 BrowserThread::WEBKIT_DEPRECATED)) {
71 data_path_ = data_path;
72 } 85 }
73 86
74 DOMStorageContextImpl::~DOMStorageContextImpl() { 87 DOMStorageContextImpl::~DOMStorageContextImpl() {
75 // This should not go away until all DOM Storage message filters have gone 88 context_->task_runner()->ReleaseSoon(
76 // away. And they remove themselves from this list. 89 FROM_HERE, context_.release());
77 DCHECK(message_filter_set_.empty());
78
79 for (StorageNamespaceMap::iterator iter(storage_namespace_map_.begin());
80 iter != storage_namespace_map_.end(); ++iter) {
81 delete iter->second;
82 }
83
84 if (save_session_state_)
85 return;
86
87 bool has_session_only_databases =
88 special_storage_policy_.get() &&
89 special_storage_policy_->HasSessionOnlyOrigins();
90
91 // Clearning only session-only databases, and there are none.
92 if (!clear_local_state_on_exit_ && !has_session_only_databases)
93 return;
94
95 // Not being on the WEBKIT thread here means we are running in a unit test
96 // where no clean up is needed.
97 if (BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)) {
98 ClearLocalState(data_path_.Append(kLocalStorageDirectory),
99 special_storage_policy_,
100 clear_local_state_on_exit_);
101 }
102 } 90 }
103 91
104 int64 DOMStorageContextImpl::AllocateStorageAreaId() { 92 void DOMStorageContextImpl::GetAllStorageFiles(
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 93 const GetAllStorageFilesCallback& callback) {
106 return ++last_storage_area_id_; 94 DCHECK(context_);
95 context_->task_runner()->PostTask(
96 FROM_HERE,
97 base::Bind(&GetAllStorageFilesHelper,
98 base::MessageLoopProxy::current(),
99 context_, callback));
107 } 100 }
108 101
109 int64 DOMStorageContextImpl::AllocateSessionStorageNamespaceId() { 102 FilePath DOMStorageContextImpl::GetFilePath(const string16& origin_id) const {
110 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) 103 DCHECK(context_);
111 return ++last_session_storage_namespace_id_on_ui_thread_; 104 return OriginToFullFilePath(context_->directory(), OriginIdToGURL(origin_id));
112 return --last_session_storage_namespace_id_on_io_thread_;
113 } 105 }
114 106
115 int64 DOMStorageContextImpl::CloneSessionStorage(int64 original_id) { 107 void DOMStorageContextImpl::DeleteForOrigin(const string16& origin_id) {
116 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 108 DCHECK(context_);
117 int64 clone_id = AllocateSessionStorageNamespaceId(); 109 context_->task_runner()->PostTask(
118 BrowserThread::PostTask( 110 FROM_HERE,
119 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, 111 base::Bind(&DomStorageContext::DeleteOrigin, context_,
120 base::Bind(&DOMStorageContextImpl::CompleteCloningSessionStorage, 112 OriginIdToGURL(origin_id)));
121 this, original_id, clone_id)); 113 }
114
115 void DOMStorageContextImpl::DeleteLocalStorageFile(const FilePath& file_path) {
116 DCHECK(context_);
117 context_->task_runner()->PostTask(
118 FROM_HERE,
119 base::Bind(&DomStorageContext::DeleteOrigin, context_,
120 FilePathToOrigin(file_path)));
121 }
122
123 void DOMStorageContextImpl::DeleteDataModifiedSince(const base::Time& cutoff) {
124 DCHECK(context_);
125 context_->task_runner()->PostTask(
126 FROM_HERE,
127 base::Bind(&DomStorageContext::DeleteDataModifiedSince, context_,
128 cutoff));
129 }
130
131 void DOMStorageContextImpl::PurgeMemory() {
132 DCHECK(context_);
133 context_->task_runner()->PostTask(
134 FROM_HERE,
135 base::Bind(&DomStorageContext::PurgeMemory, context_));
136 }
137
138 void DOMStorageContextImpl::SetClearLocalState(bool clear_local_state) {
139 DCHECK(context_);
140 context_->task_runner()->PostTask(
141 FROM_HERE,
142 base::Bind(&DomStorageContext::SetClearLocalState, context_,
143 clear_local_state));
144 }
145
146 void DOMStorageContextImpl::SaveSessionState() {
147 DCHECK(context_);
148 context_->task_runner()->PostTask(
149 FROM_HERE,
150 base::Bind(&DomStorageContext::SaveSessionState, context_));
151 }
152
153 void DOMStorageContextImpl::Shutdown() {
154 DCHECK(context_);
155 context_->task_runner()->PostTask(
156 FROM_HERE,
157 base::Bind(&DomStorageContext::Shutdown, context_));
158 }
159
160 int64 DOMStorageContextImpl::LeakyCloneSessionStorage(
161 int64 existing_namespace_id) {
162 DCHECK(context_);
163 int64 clone_id = context_->AllocateSessionId();
164 context_->task_runner()->PostTask(
165 FROM_HERE,
166 base::Bind(&DomStorageContext::CloneSessionNamespace, context_,
167 existing_namespace_id, clone_id));
122 return clone_id; 168 return clone_id;
123 } 169 }
124 170
125 void DOMStorageContextImpl::RegisterStorageArea(DOMStorageArea* storage_area) { 171 #endif // ENABLE_NEW_DOM_STORAGE_BACKEND
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
127 int64 id = storage_area->id();
128 DCHECK(!GetStorageArea(id));
129 storage_area_map_[id] = storage_area;
130 }
131
132 void DOMStorageContextImpl::UnregisterStorageArea(
133 DOMStorageArea* storage_area) {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
135 int64 id = storage_area->id();
136 DCHECK(GetStorageArea(id));
137 storage_area_map_.erase(id);
138 }
139
140 DOMStorageArea* DOMStorageContextImpl::GetStorageArea(int64 id) {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
142 StorageAreaMap::iterator iter = storage_area_map_.find(id);
143 if (iter == storage_area_map_.end())
144 return NULL;
145 return iter->second;
146 }
147
148 void DOMStorageContextImpl::DeleteSessionStorageNamespace(int64 namespace_id) {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED) ||
150 !BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED));
151 StorageNamespaceMap::iterator iter =
152 storage_namespace_map_.find(namespace_id);
153 if (iter == storage_namespace_map_.end())
154 return;
155 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
156 delete iter->second;
157 storage_namespace_map_.erase(iter);
158 }
159
160 DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
161 int64 id, bool allocation_allowed) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
163 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
164 if (iter != storage_namespace_map_.end())
165 return iter->second;
166 if (!allocation_allowed)
167 return NULL;
168 if (id == kLocalStorageNamespaceId)
169 return CreateLocalStorage();
170 return CreateSessionStorage(id);
171 }
172
173 void DOMStorageContextImpl::RegisterMessageFilter(
174 DOMStorageMessageFilter* message_filter) {
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
176 DCHECK(message_filter_set_.find(message_filter) ==
177 message_filter_set_.end());
178 message_filter_set_.insert(message_filter);
179 }
180
181 void DOMStorageContextImpl::UnregisterMessageFilter(
182 DOMStorageMessageFilter* message_filter) {
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
184 DCHECK(message_filter_set_.find(message_filter) !=
185 message_filter_set_.end());
186 message_filter_set_.erase(message_filter);
187 }
188
189 const DOMStorageContextImpl::MessageFilterSet*
190 DOMStorageContextImpl::GetMessageFilterSet() const {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
192 return &message_filter_set_;
193 }
194
195 void DOMStorageContextImpl::PurgeMemory() {
196 // It is only safe to purge the memory from the LocalStorage namespace,
197 // because it is backed by disk and can be reloaded later. If we purge a
198 // SessionStorage namespace, its data will be gone forever, because it isn't
199 // currently backed by disk.
200 DOMStorageNamespace* local_storage =
201 GetStorageNamespace(kLocalStorageNamespaceId, false);
202 if (local_storage)
203 local_storage->PurgeMemory();
204 }
205
206 void DOMStorageContextImpl::DeleteDataModifiedSince(const base::Time& cutoff) {
207 // Make sure that we don't delete a database that's currently being accessed
208 // by unloading all of the databases temporarily.
209 PurgeMemory();
210
211 file_util::FileEnumerator file_enumerator(
212 data_path_.Append(kLocalStorageDirectory), false,
213 file_util::FileEnumerator::FILES);
214 for (FilePath path = file_enumerator.Next(); !path.value().empty();
215 path = file_enumerator.Next()) {
216 GURL origin(WebSecurityOrigin::createFromDatabaseIdentifier(
217 webkit_glue::FilePathToWebString(path.BaseName())).toString());
218 if (special_storage_policy_->IsStorageProtected(origin))
219 continue;
220
221 file_util::FileEnumerator::FindInfo find_info;
222 file_enumerator.GetFindInfo(&find_info);
223 if (file_util::HasFileBeenModifiedSince(find_info, cutoff))
224 file_util::Delete(path, false);
225 }
226 }
227
228 void DOMStorageContextImpl::DeleteLocalStorageFile(const FilePath& file_path) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
230
231 // Make sure that we don't delete a database that's currently being accessed
232 // by unloading all of the databases temporarily.
233 // TODO(bulach): both this method and DeleteDataModifiedSince could purge
234 // only the memory used by the specific file instead of all memory at once.
235 // See http://crbug.com/32000
236 PurgeMemory();
237 file_util::Delete(file_path, false);
238 }
239
240 void DOMStorageContextImpl::DeleteForOrigin(const string16& origin_id) {
241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
242 DeleteLocalStorageFile(GetFilePath(origin_id));
243 }
244
245 void DOMStorageContextImpl::DeleteAllLocalStorageFiles() {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
247
248 // Make sure that we don't delete a database that's currently being accessed
249 // by unloading all of the databases temporarily.
250 PurgeMemory();
251
252 file_util::FileEnumerator file_enumerator(
253 data_path_.Append(kLocalStorageDirectory), false,
254 file_util::FileEnumerator::FILES);
255 for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
256 file_path = file_enumerator.Next()) {
257 if (file_path.Extension() == kLocalStorageExtension)
258 file_util::Delete(file_path, false);
259 }
260 }
261
262 DOMStorageNamespace* DOMStorageContextImpl::CreateLocalStorage() {
263 FilePath dir_path;
264 if (!data_path_.empty())
265 dir_path = data_path_.Append(kLocalStorageDirectory);
266 DOMStorageNamespace* new_namespace =
267 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
268 RegisterStorageNamespace(new_namespace);
269 return new_namespace;
270 }
271
272 DOMStorageNamespace* DOMStorageContextImpl::CreateSessionStorage(
273 int64 namespace_id) {
274 DOMStorageNamespace* new_namespace =
275 DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id);
276 RegisterStorageNamespace(new_namespace);
277 return new_namespace;
278 }
279
280 void DOMStorageContextImpl::RegisterStorageNamespace(
281 DOMStorageNamespace* storage_namespace) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
283 int64 id = storage_namespace->id();
284 DCHECK(!GetStorageNamespace(id, false));
285 storage_namespace_map_[id] = storage_namespace;
286 }
287
288 void DOMStorageContextImpl::CompleteCloningSessionStorage(
289 int64 existing_id, int64 clone_id) {
290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
291 DOMStorageNamespace* existing_namespace =
292 GetStorageNamespace(existing_id, false);
293 // If nothing exists, then there's nothing to clone.
294 if (existing_namespace)
295 RegisterStorageNamespace(existing_namespace->Copy(clone_id));
296 }
297
298 base::SequencedTaskRunner* DOMStorageContextImpl::task_runner() const {
299 return webkit_message_loop_;
300 }
301
302 std::vector<FilePath> DOMStorageContextImpl::GetAllStorageFiles() {
303 std::vector<FilePath> files;
304 file_util::FileEnumerator file_enumerator(
305 data_path_.Append(kLocalStorageDirectory), false,
306 file_util::FileEnumerator::FILES);
307 for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
308 file_path = file_enumerator.Next()) {
309 if (file_path.Extension() == kLocalStorageExtension)
310 files.push_back(file_path);
311 }
312 return files;
313 }
314
315 FilePath DOMStorageContextImpl::GetFilePath(const string16& origin_id) const {
316 FilePath storage_dir = data_path_.Append(kLocalStorageDirectory);
317 FilePath::StringType id = webkit_glue::WebStringToFilePathString(origin_id);
318 return storage_dir.Append(id.append(kLocalStorageExtension));
319 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698