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

Side by Side Diff: webkit/dom_storage/dom_storage_context.cc

Issue 9963107: Persist sessionStorage on disk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Draft: associate with session restore. Created 8 years, 7 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/dom_storage/dom_storage_context.h" 5 #include "webkit/dom_storage/dom_storage_context.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/time.h" 11 #include "base/time.h"
12 #include "webkit/dom_storage/dom_storage_area.h" 12 #include "webkit/dom_storage/dom_storage_area.h"
13 #include "webkit/dom_storage/dom_storage_database.h"
13 #include "webkit/dom_storage/dom_storage_namespace.h" 14 #include "webkit/dom_storage/dom_storage_namespace.h"
14 #include "webkit/dom_storage/dom_storage_task_runner.h" 15 #include "webkit/dom_storage/dom_storage_task_runner.h"
15 #include "webkit/dom_storage/dom_storage_types.h" 16 #include "webkit/dom_storage/dom_storage_types.h"
17 #include "webkit/dom_storage/session_storage_database.h"
16 #include "webkit/quota/special_storage_policy.h" 18 #include "webkit/quota/special_storage_policy.h"
17 19
18 using file_util::FileEnumerator; 20 using file_util::FileEnumerator;
19 21
20 namespace dom_storage { 22 namespace dom_storage {
21 23
22 DomStorageContext::UsageInfo::UsageInfo() : data_size(0) {} 24 DomStorageContext::UsageInfo::UsageInfo() : data_size(0) {}
23 DomStorageContext::UsageInfo::~UsageInfo() {} 25 DomStorageContext::UsageInfo::~UsageInfo() {}
24 26
25 DomStorageContext::DomStorageContext( 27 DomStorageContext::DomStorageContext(
26 const FilePath& localstorage_directory, 28 const FilePath& localstorage_directory,
27 const FilePath& sessionstorage_directory, 29 const FilePath& sessionstorage_directory,
28 quota::SpecialStoragePolicy* special_storage_policy, 30 quota::SpecialStoragePolicy* special_storage_policy,
29 DomStorageTaskRunner* task_runner) 31 DomStorageTaskRunner* task_runner)
30 : localstorage_directory_(localstorage_directory), 32 : localstorage_directory_(localstorage_directory),
31 sessionstorage_directory_(sessionstorage_directory), 33 sessionstorage_directory_(sessionstorage_directory),
32 task_runner_(task_runner), 34 task_runner_(task_runner),
33 is_shutdown_(false), 35 is_shutdown_(false),
34 clear_local_state_(false), 36 clear_local_state_(false),
35 save_session_state_(false), 37 save_session_state_(false),
36 special_storage_policy_(special_storage_policy) { 38 special_storage_policy_(special_storage_policy) {
37 // AtomicSequenceNum starts at 0 but we want to start session 39 // AtomicSequenceNum starts at 0 but we want to start session
38 // namespace ids at one since zero is reserved for the 40 // namespace ids at one since zero is reserved for the
39 // kLocalStorageNamespaceId. 41 // kLocalStorageNamespaceId.
40 session_id_sequence_.GetNext(); 42 session_id_sequence_.GetNext();
43 if (!sessionstorage_directory_.empty()) {
44 session_storage_database_ = new SessionStorageDatabase(
45 sessionstorage_directory_,
46 base::Bind(&DomStorageContext::NotifySessionStorageNamespaceAssociated,
47 this));
48 }
41 } 49 }
42 50
43 DomStorageContext::~DomStorageContext() { 51 DomStorageContext::~DomStorageContext() {
44 } 52 }
45 53
46 DomStorageNamespace* DomStorageContext::GetStorageNamespace( 54 DomStorageNamespace* DomStorageContext::GetStorageNamespace(
47 int64 namespace_id) { 55 int64 namespace_id) {
48 if (is_shutdown_) 56 if (is_shutdown_)
49 return NULL; 57 return NULL;
50 StorageNamespaceMap::iterator found = namespaces_.find(namespace_id); 58 StorageNamespaceMap::iterator found = namespaces_.find(namespace_id);
(...skipping 29 matching lines...) Expand all
80 info.origin = DomStorageArea::OriginFromDatabaseFileName(path); 88 info.origin = DomStorageArea::OriginFromDatabaseFileName(path);
81 if (include_file_info) { 89 if (include_file_info) {
82 FileEnumerator::FindInfo find_info; 90 FileEnumerator::FindInfo find_info;
83 enumerator.GetFindInfo(&find_info); 91 enumerator.GetFindInfo(&find_info);
84 info.data_size = FileEnumerator::GetFilesize(find_info); 92 info.data_size = FileEnumerator::GetFilesize(find_info);
85 info.last_modified = FileEnumerator::GetLastModifiedTime(find_info); 93 info.last_modified = FileEnumerator::GetLastModifiedTime(find_info);
86 } 94 }
87 infos->push_back(info); 95 infos->push_back(info);
88 } 96 }
89 } 97 }
98 // FIXME(marja): Get usage infos for sessionStorage (crbug.com/123599).
90 } 99 }
91 100
92 void DomStorageContext::DeleteOrigin(const GURL& origin) { 101 void DomStorageContext::DeleteOrigin(const GURL& origin) {
93 DCHECK(!is_shutdown_); 102 DCHECK(!is_shutdown_);
94 DomStorageNamespace* local = GetStorageNamespace(kLocalStorageNamespaceId); 103 DomStorageNamespace* local = GetStorageNamespace(kLocalStorageNamespaceId);
95 local->DeleteOrigin(origin); 104 local->DeleteOrigin(origin);
96 } 105 }
97 106
98 void DomStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { 107 void DomStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
99 std::vector<UsageInfo> infos; 108 std::vector<UsageInfo> infos;
(...skipping 17 matching lines...) Expand all
117 if (found != namespaces_.end()) 126 if (found != namespaces_.end())
118 found->second->PurgeMemory(); 127 found->second->PurgeMemory();
119 } 128 }
120 129
121 void DomStorageContext::Shutdown() { 130 void DomStorageContext::Shutdown() {
122 is_shutdown_ = true; 131 is_shutdown_ = true;
123 StorageNamespaceMap::const_iterator it = namespaces_.begin(); 132 StorageNamespaceMap::const_iterator it = namespaces_.begin();
124 for (; it != namespaces_.end(); ++it) 133 for (; it != namespaces_.end(); ++it)
125 it->second->Shutdown(); 134 it->second->Shutdown();
126 135
136 // Delete data from sessionStorage. If the previous exit was unclean, the
137 // session storage backing might contain leftover data. Delete it now.
138 if (session_storage_database_.get()) {
139 bool success = task_runner_->PostShutdownBlockingTask(
140 FROM_HERE,
141 DomStorageTaskRunner::COMMIT_SEQUENCE,
142 base::Bind(&DomStorageContext::DeleteLeftoverDataInCommitSequence,
143 this));
144 DCHECK(success);
145 }
146
147 // Delete data from localStorage.
127 if (localstorage_directory_.empty()) 148 if (localstorage_directory_.empty())
128 return; 149 return;
129 150
130 // Respect the content policy settings about what to 151 // Respect the content policy settings about what to
131 // keep and what to discard. 152 // keep and what to discard.
132 if (save_session_state_) 153 if (save_session_state_) // Keep everything.
133 return; // Keep everything. 154 return;
134 155
135 bool has_session_only_origins = 156 bool has_session_only_origins =
136 special_storage_policy_.get() && 157 special_storage_policy_.get() &&
137 special_storage_policy_->HasSessionOnlyOrigins(); 158 special_storage_policy_->HasSessionOnlyOrigins();
138 159
139 if (clear_local_state_ || has_session_only_origins) { 160 if (clear_local_state_ || has_session_only_origins) {
140 // We may have to delete something. We continue on the 161 // We may have to delete something. We continue on the
141 // commit sequence after area shutdown tasks have cycled 162 // commit sequence after area shutdown tasks have cycled
142 // thru that sequence (and closed their database files). 163 // thru that sequence (and closed their database files).
143 bool success = task_runner_->PostShutdownBlockingTask( 164 bool success = task_runner_->PostShutdownBlockingTask(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 199 }
179 200
180 void DomStorageContext::NotifyAreaCleared( 201 void DomStorageContext::NotifyAreaCleared(
181 const DomStorageArea* area, 202 const DomStorageArea* area,
182 const GURL& page_url) { 203 const GURL& page_url) {
183 FOR_EACH_OBSERVER( 204 FOR_EACH_OBSERVER(
184 EventObserver, event_observers_, 205 EventObserver, event_observers_,
185 OnDomStorageAreaCleared(area, page_url)); 206 OnDomStorageAreaCleared(area, page_url));
186 } 207 }
187 208
209 void DomStorageContext::AddSessionStorageObserver(
210 int64 namespace_id,
211 SessionStorageObserver* observer) {
212 session_storage_observers_[namespace_id] = observer;
213 }
214
215 void DomStorageContext::RemoveSessionStorageObserver(int64 namespace_id) {
216 session_storage_observers_.erase(namespace_id);
217 }
218
219 void DomStorageContext::NotifySessionStorageNamespaceAssociated(
220 int64 namespace_id,
221 int64 real_namespace_id) {
222 std::map<int64, SessionStorageObserver*>::const_iterator it =
223 session_storage_observers_.find(namespace_id);
224 if (it != session_storage_observers_.end())
225 it->second->OnSessionStorageNamespaceAssociated(real_namespace_id);
226 }
227
188 void DomStorageContext::CreateSessionNamespace( 228 void DomStorageContext::CreateSessionNamespace(
189 int64 namespace_id) { 229 int64 namespace_id) {
190 if (is_shutdown_) 230 if (is_shutdown_)
191 return; 231 return;
192 DCHECK(namespace_id != kLocalStorageNamespaceId); 232 DCHECK(namespace_id != kLocalStorageNamespaceId);
193 DCHECK(namespaces_.find(namespace_id) == namespaces_.end()); 233 DCHECK(namespaces_.find(namespace_id) == namespaces_.end());
194 namespaces_[namespace_id] = new DomStorageNamespace( 234 namespaces_[namespace_id] = new DomStorageNamespace(
195 namespace_id, task_runner_); 235 namespace_id, session_storage_database_.get(), task_runner_);
196 } 236 }
197 237
198 void DomStorageContext::DeleteSessionNamespace( 238 void DomStorageContext::DeleteSessionNamespace(
199 int64 namespace_id) { 239 int64 namespace_id) {
200 DCHECK_NE(kLocalStorageNamespaceId, namespace_id); 240 DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
201 namespaces_.erase(namespace_id); 241 namespaces_.erase(namespace_id);
242 // FIXME: protect from deletion
243 if (session_storage_database_.get()) {
244 bool success = task_runner_->PostShutdownBlockingTask(
245 FROM_HERE,
246 DomStorageTaskRunner::COMMIT_SEQUENCE,
247 base::Bind(&DomStorageContext::DeleteSessionNamespaceInCommitSequence,
248 this, namespace_id));
249 DCHECK(success);
250 }
202 } 251 }
203 252
204 void DomStorageContext::CloneSessionNamespace( 253 void DomStorageContext::CloneSessionNamespace(
205 int64 existing_id, int64 new_id) { 254 int64 existing_id, int64 new_id) {
206 if (is_shutdown_) 255 if (is_shutdown_)
207 return; 256 return;
208 DCHECK_NE(kLocalStorageNamespaceId, existing_id); 257 DCHECK_NE(kLocalStorageNamespaceId, existing_id);
209 DCHECK_NE(kLocalStorageNamespaceId, new_id); 258 DCHECK_NE(kLocalStorageNamespaceId, new_id);
210 StorageNamespaceMap::iterator found = namespaces_.find(existing_id); 259 StorageNamespaceMap::iterator found = namespaces_.find(existing_id);
211 if (found != namespaces_.end()) 260 if (found != namespaces_.end())
212 namespaces_[new_id] = found->second->Clone(new_id); 261 namespaces_[new_id] = found->second->Clone(new_id);
213 else 262 else
214 CreateSessionNamespace(new_id); 263 CreateSessionNamespace(new_id);
215 } 264 }
216 265
266 void DomStorageContext::AssociateSessionStorage(int64 namespace_id,
267 int64 real_id) {
268 if (!session_storage_database_.get())
269 return;
270 bool success = task_runner_->PostShutdownBlockingTask(
271 FROM_HERE,
272 DomStorageTaskRunner::COMMIT_SEQUENCE,
273 base::Bind(&SessionStorageDatabase::AssociateNamespaceId,
274 session_storage_database_.get(),
275 namespace_id, real_id));
276 DCHECK(success);
277 }
278
217 void DomStorageContext::ClearLocalStateInCommitSequence() { 279 void DomStorageContext::ClearLocalStateInCommitSequence() {
218 std::vector<UsageInfo> infos; 280 std::vector<UsageInfo> infos;
219 const bool kDontIncludeFileInfo = false; 281 const bool kDontIncludeFileInfo = false;
220 GetUsageInfo(&infos, kDontIncludeFileInfo); 282 GetUsageInfo(&infos, kDontIncludeFileInfo);
221 for (size_t i = 0; i < infos.size(); ++i) { 283 for (size_t i = 0; i < infos.size(); ++i) {
222 const GURL& origin = infos[i].origin; 284 const GURL& origin = infos[i].origin;
223 if (special_storage_policy_ && 285 if (special_storage_policy_ &&
224 special_storage_policy_->IsStorageProtected(origin)) 286 special_storage_policy_->IsStorageProtected(origin))
225 continue; 287 continue;
226 if (!clear_local_state_ && 288 if (!clear_local_state_ &&
227 !special_storage_policy_->IsStorageSessionOnly(origin)) 289 !special_storage_policy_->IsStorageSessionOnly(origin))
228 continue; 290 continue;
229 291
230 const bool kNotRecursive = false; 292 const bool kNotRecursive = false;
231 FilePath database_file_path = localstorage_directory_.Append( 293 FilePath database_file_path = localstorage_directory_.Append(
232 DomStorageArea::DatabaseFileNameFromOrigin(origin)); 294 DomStorageArea::DatabaseFileNameFromOrigin(origin));
233 file_util::Delete(database_file_path, kNotRecursive); 295 file_util::Delete(database_file_path, kNotRecursive);
234 file_util::Delete( 296 file_util::Delete(
235 DomStorageDatabase::GetJournalFilePath(database_file_path), 297 DomStorageDatabase::GetJournalFilePath(database_file_path),
236 kNotRecursive); 298 kNotRecursive);
237 } 299 }
238 } 300 }
239 301
302 void DomStorageContext::DeleteSessionNamespaceInCommitSequence(
303 int64 namespace_id) {
304 session_storage_database_->DeleteNamespace(namespace_id);
305 }
306
307 void DomStorageContext::DeleteLeftoverDataInCommitSequence() {
308 DCHECK(session_storage_database_.get());
309 // Delete all namespaces which don't have an associated DomStorageNamespace
310 // alive.
311 // FIXME: protect from deletion.
312 std::vector<int64> namespace_ids;
313 session_storage_database_->ReadNamespaceIds(&namespace_ids);
314 for (std::vector<int64>::const_iterator it = namespace_ids.begin();
315 it != namespace_ids.end(); ++it) {
316 if (namespaces_.find(*it) == namespaces_.end())
317 session_storage_database_->DeleteNamespace(*it);
318 }
319 }
320
240 } // namespace dom_storage 321 } // namespace dom_storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698