OLD | NEW |
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/guid.h" | 10 #include "base/guid.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 force_keep_session_state_(false), | 36 force_keep_session_state_(false), |
37 special_storage_policy_(special_storage_policy), | 37 special_storage_policy_(special_storage_policy), |
38 scavenging_started_(false) { | 38 scavenging_started_(false) { |
39 // AtomicSequenceNum starts at 0 but we want to start session | 39 // AtomicSequenceNum starts at 0 but we want to start session |
40 // namespace ids at one since zero is reserved for the | 40 // namespace ids at one since zero is reserved for the |
41 // kLocalStorageNamespaceId. | 41 // kLocalStorageNamespaceId. |
42 session_id_sequence_.GetNext(); | 42 session_id_sequence_.GetNext(); |
43 } | 43 } |
44 | 44 |
45 DomStorageContext::~DomStorageContext() { | 45 DomStorageContext::~DomStorageContext() { |
46 if (session_storage_database_) { | 46 if (session_storage_database_.get()) { |
47 // SessionStorageDatabase shouldn't be deleted right away: deleting it will | 47 // SessionStorageDatabase shouldn't be deleted right away: deleting it will |
48 // potentially involve waiting in leveldb::DBImpl::~DBImpl, and waiting | 48 // potentially involve waiting in leveldb::DBImpl::~DBImpl, and waiting |
49 // shouldn't happen on this thread. | 49 // shouldn't happen on this thread. |
50 SessionStorageDatabase* to_release = session_storage_database_.get(); | 50 SessionStorageDatabase* to_release = session_storage_database_.get(); |
51 to_release->AddRef(); | 51 to_release->AddRef(); |
52 session_storage_database_ = NULL; | 52 session_storage_database_ = NULL; |
53 task_runner_->PostShutdownBlockingTask( | 53 task_runner_->PostShutdownBlockingTask( |
54 FROM_HERE, | 54 FROM_HERE, |
55 DomStorageTaskRunner::COMMIT_SEQUENCE, | 55 DomStorageTaskRunner::COMMIT_SEQUENCE, |
56 base::Bind(&SessionStorageDatabase::Release, | 56 base::Bind(&SessionStorageDatabase::Release, |
57 base::Unretained(to_release))); | 57 base::Unretained(to_release))); |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 DomStorageNamespace* DomStorageContext::GetStorageNamespace( | 61 DomStorageNamespace* DomStorageContext::GetStorageNamespace( |
62 int64 namespace_id) { | 62 int64 namespace_id) { |
63 if (is_shutdown_) | 63 if (is_shutdown_) |
64 return NULL; | 64 return NULL; |
65 StorageNamespaceMap::iterator found = namespaces_.find(namespace_id); | 65 StorageNamespaceMap::iterator found = namespaces_.find(namespace_id); |
66 if (found == namespaces_.end()) { | 66 if (found == namespaces_.end()) { |
67 if (namespace_id == kLocalStorageNamespaceId) { | 67 if (namespace_id == kLocalStorageNamespaceId) { |
68 if (!localstorage_directory_.empty()) { | 68 if (!localstorage_directory_.empty()) { |
69 if (!file_util::CreateDirectory(localstorage_directory_)) { | 69 if (!file_util::CreateDirectory(localstorage_directory_)) { |
70 LOG(ERROR) << "Failed to create 'Local Storage' directory," | 70 LOG(ERROR) << "Failed to create 'Local Storage' directory," |
71 " falling back to in-memory only."; | 71 " falling back to in-memory only."; |
72 localstorage_directory_ = base::FilePath(); | 72 localstorage_directory_ = base::FilePath(); |
73 } | 73 } |
74 } | 74 } |
75 DomStorageNamespace* local = | 75 DomStorageNamespace* local = |
76 new DomStorageNamespace(localstorage_directory_, task_runner_); | 76 new DomStorageNamespace(localstorage_directory_, task_runner_.get()); |
77 namespaces_[kLocalStorageNamespaceId] = local; | 77 namespaces_[kLocalStorageNamespaceId] = local; |
78 return local; | 78 return local; |
79 } | 79 } |
80 return NULL; | 80 return NULL; |
81 } | 81 } |
82 return found->second; | 82 return found->second.get(); |
83 } | 83 } |
84 | 84 |
85 void DomStorageContext::GetLocalStorageUsage( | 85 void DomStorageContext::GetLocalStorageUsage( |
86 std::vector<LocalStorageUsageInfo>* infos, | 86 std::vector<LocalStorageUsageInfo>* infos, |
87 bool include_file_info) { | 87 bool include_file_info) { |
88 if (localstorage_directory_.empty()) | 88 if (localstorage_directory_.empty()) |
89 return; | 89 return; |
90 FileEnumerator enumerator(localstorage_directory_, false, | 90 FileEnumerator enumerator(localstorage_directory_, false, |
91 FileEnumerator::FILES); | 91 FileEnumerator::FILES); |
92 for (base::FilePath path = enumerator.Next(); !path.empty(); | 92 for (base::FilePath path = enumerator.Next(); !path.empty(); |
93 path = enumerator.Next()) { | 93 path = enumerator.Next()) { |
94 if (path.MatchesExtension(DomStorageArea::kDatabaseFileExtension)) { | 94 if (path.MatchesExtension(DomStorageArea::kDatabaseFileExtension)) { |
95 LocalStorageUsageInfo info; | 95 LocalStorageUsageInfo info; |
96 info.origin = DomStorageArea::OriginFromDatabaseFileName(path); | 96 info.origin = DomStorageArea::OriginFromDatabaseFileName(path); |
97 if (include_file_info) { | 97 if (include_file_info) { |
98 FileEnumerator::FindInfo find_info; | 98 FileEnumerator::FindInfo find_info; |
99 enumerator.GetFindInfo(&find_info); | 99 enumerator.GetFindInfo(&find_info); |
100 info.data_size = FileEnumerator::GetFilesize(find_info); | 100 info.data_size = FileEnumerator::GetFilesize(find_info); |
101 info.last_modified = FileEnumerator::GetLastModifiedTime(find_info); | 101 info.last_modified = FileEnumerator::GetLastModifiedTime(find_info); |
102 } | 102 } |
103 infos->push_back(info); | 103 infos->push_back(info); |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 void DomStorageContext::GetSessionStorageUsage( | 108 void DomStorageContext::GetSessionStorageUsage( |
109 std::vector<SessionStorageUsageInfo>* infos) { | 109 std::vector<SessionStorageUsageInfo>* infos) { |
110 if (!session_storage_database_) | 110 if (!session_storage_database_.get()) |
111 return; | 111 return; |
112 std::map<std::string, std::vector<GURL> > namespaces_and_origins; | 112 std::map<std::string, std::vector<GURL> > namespaces_and_origins; |
113 session_storage_database_->ReadNamespacesAndOrigins( | 113 session_storage_database_->ReadNamespacesAndOrigins( |
114 &namespaces_and_origins); | 114 &namespaces_and_origins); |
115 for (std::map<std::string, std::vector<GURL> >::const_iterator it = | 115 for (std::map<std::string, std::vector<GURL> >::const_iterator it = |
116 namespaces_and_origins.begin(); | 116 namespaces_and_origins.begin(); |
117 it != namespaces_and_origins.end(); ++it) { | 117 it != namespaces_and_origins.end(); ++it) { |
118 for (std::vector<GURL>::const_iterator origin_it = it->second.begin(); | 118 for (std::vector<GURL>::const_iterator origin_it = it->second.begin(); |
119 origin_it != it->second.end(); ++origin_it) { | 119 origin_it != it->second.end(); ++origin_it) { |
120 SessionStorageUsageInfo info; | 120 SessionStorageUsageInfo info; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 if (found != namespaces_.end()) | 169 if (found != namespaces_.end()) |
170 found->second->PurgeMemory(DomStorageNamespace::PURGE_AGGRESSIVE); | 170 found->second->PurgeMemory(DomStorageNamespace::PURGE_AGGRESSIVE); |
171 } | 171 } |
172 | 172 |
173 void DomStorageContext::Shutdown() { | 173 void DomStorageContext::Shutdown() { |
174 is_shutdown_ = true; | 174 is_shutdown_ = true; |
175 StorageNamespaceMap::const_iterator it = namespaces_.begin(); | 175 StorageNamespaceMap::const_iterator it = namespaces_.begin(); |
176 for (; it != namespaces_.end(); ++it) | 176 for (; it != namespaces_.end(); ++it) |
177 it->second->Shutdown(); | 177 it->second->Shutdown(); |
178 | 178 |
179 if (localstorage_directory_.empty() && !session_storage_database_) | 179 if (localstorage_directory_.empty() && !session_storage_database_.get()) |
180 return; | 180 return; |
181 | 181 |
182 // Respect the content policy settings about what to | 182 // Respect the content policy settings about what to |
183 // keep and what to discard. | 183 // keep and what to discard. |
184 if (force_keep_session_state_) | 184 if (force_keep_session_state_) |
185 return; // Keep everything. | 185 return; // Keep everything. |
186 | 186 |
187 bool has_session_only_origins = | 187 bool has_session_only_origins = |
188 special_storage_policy_.get() && | 188 special_storage_policy_.get() && |
189 special_storage_policy_->HasSessionOnlyOrigins(); | 189 special_storage_policy_->HasSessionOnlyOrigins(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 return guid; | 243 return guid; |
244 } | 244 } |
245 | 245 |
246 void DomStorageContext::CreateSessionNamespace( | 246 void DomStorageContext::CreateSessionNamespace( |
247 int64 namespace_id, | 247 int64 namespace_id, |
248 const std::string& persistent_namespace_id) { | 248 const std::string& persistent_namespace_id) { |
249 if (is_shutdown_) | 249 if (is_shutdown_) |
250 return; | 250 return; |
251 DCHECK(namespace_id != kLocalStorageNamespaceId); | 251 DCHECK(namespace_id != kLocalStorageNamespaceId); |
252 DCHECK(namespaces_.find(namespace_id) == namespaces_.end()); | 252 DCHECK(namespaces_.find(namespace_id) == namespaces_.end()); |
253 namespaces_[namespace_id] = new DomStorageNamespace( | 253 namespaces_[namespace_id] = |
254 namespace_id, persistent_namespace_id, session_storage_database_.get(), | 254 new DomStorageNamespace(namespace_id, |
255 task_runner_); | 255 persistent_namespace_id, |
| 256 session_storage_database_.get(), |
| 257 task_runner_.get()); |
256 persistent_namespace_id_to_namespace_id_[persistent_namespace_id] = | 258 persistent_namespace_id_to_namespace_id_[persistent_namespace_id] = |
257 namespace_id; | 259 namespace_id; |
258 } | 260 } |
259 | 261 |
260 void DomStorageContext::DeleteSessionNamespace( | 262 void DomStorageContext::DeleteSessionNamespace( |
261 int64 namespace_id, bool should_persist_data) { | 263 int64 namespace_id, bool should_persist_data) { |
262 DCHECK_NE(kLocalStorageNamespaceId, namespace_id); | 264 DCHECK_NE(kLocalStorageNamespaceId, namespace_id); |
263 StorageNamespaceMap::const_iterator it = namespaces_.find(namespace_id); | 265 StorageNamespaceMap::const_iterator it = namespaces_.find(namespace_id); |
264 if (it == namespaces_.end()) | 266 if (it == namespaces_.end()) |
265 return; | 267 return; |
266 std::string persistent_namespace_id = it->second->persistent_namespace_id(); | 268 std::string persistent_namespace_id = it->second->persistent_namespace_id(); |
267 if (session_storage_database_) { | 269 if (session_storage_database_.get()) { |
268 if (!should_persist_data) { | 270 if (!should_persist_data) { |
269 task_runner_->PostShutdownBlockingTask( | 271 task_runner_->PostShutdownBlockingTask( |
270 FROM_HERE, | 272 FROM_HERE, |
271 DomStorageTaskRunner::COMMIT_SEQUENCE, | 273 DomStorageTaskRunner::COMMIT_SEQUENCE, |
272 base::Bind( | 274 base::Bind( |
273 base::IgnoreResult(&SessionStorageDatabase::DeleteNamespace), | 275 base::IgnoreResult(&SessionStorageDatabase::DeleteNamespace), |
274 session_storage_database_, | 276 session_storage_database_, |
275 persistent_namespace_id)); | 277 persistent_namespace_id)); |
276 } else { | 278 } else { |
277 // Ensure that the data gets committed before we shut down. | 279 // Ensure that the data gets committed before we shut down. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 | 316 |
315 const bool kNotRecursive = false; | 317 const bool kNotRecursive = false; |
316 base::FilePath database_file_path = localstorage_directory_.Append( | 318 base::FilePath database_file_path = localstorage_directory_.Append( |
317 DomStorageArea::DatabaseFileNameFromOrigin(origin)); | 319 DomStorageArea::DatabaseFileNameFromOrigin(origin)); |
318 file_util::Delete(database_file_path, kNotRecursive); | 320 file_util::Delete(database_file_path, kNotRecursive); |
319 file_util::Delete( | 321 file_util::Delete( |
320 DomStorageDatabase::GetJournalFilePath(database_file_path), | 322 DomStorageDatabase::GetJournalFilePath(database_file_path), |
321 kNotRecursive); | 323 kNotRecursive); |
322 } | 324 } |
323 } | 325 } |
324 if (session_storage_database_) { | 326 if (session_storage_database_.get()) { |
325 std::vector<SessionStorageUsageInfo> infos; | 327 std::vector<SessionStorageUsageInfo> infos; |
326 GetSessionStorageUsage(&infos); | 328 GetSessionStorageUsage(&infos); |
327 for (size_t i = 0; i < infos.size(); ++i) { | 329 for (size_t i = 0; i < infos.size(); ++i) { |
328 const GURL& origin = infos[i].origin; | 330 const GURL& origin = infos[i].origin; |
329 if (special_storage_policy_->IsStorageProtected(origin)) | 331 if (special_storage_policy_->IsStorageProtected(origin)) |
330 continue; | 332 continue; |
331 if (!special_storage_policy_->IsStorageSessionOnly(origin)) | 333 if (!special_storage_policy_->IsStorageSessionOnly(origin)) |
332 continue; | 334 continue; |
333 session_storage_database_->DeleteArea(infos[i].persistent_namespace_id, | 335 session_storage_database_->DeleteArea(infos[i].persistent_namespace_id, |
334 origin); | 336 origin); |
335 } | 337 } |
336 } | 338 } |
337 } | 339 } |
338 | 340 |
339 void DomStorageContext::SetSaveSessionStorageOnDisk() { | 341 void DomStorageContext::SetSaveSessionStorageOnDisk() { |
340 DCHECK(namespaces_.empty()); | 342 DCHECK(namespaces_.empty()); |
341 if (!sessionstorage_directory_.empty()) { | 343 if (!sessionstorage_directory_.empty()) { |
342 session_storage_database_ = new SessionStorageDatabase( | 344 session_storage_database_ = new SessionStorageDatabase( |
343 sessionstorage_directory_); | 345 sessionstorage_directory_); |
344 } | 346 } |
345 } | 347 } |
346 | 348 |
347 void DomStorageContext::StartScavengingUnusedSessionStorage() { | 349 void DomStorageContext::StartScavengingUnusedSessionStorage() { |
348 if (session_storage_database_) { | 350 if (session_storage_database_.get()) { |
349 task_runner_->PostDelayedTask( | 351 task_runner_->PostDelayedTask( |
350 FROM_HERE, base::Bind(&DomStorageContext::FindUnusedNamespaces, this), | 352 FROM_HERE, |
| 353 base::Bind(&DomStorageContext::FindUnusedNamespaces, this), |
351 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); | 354 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
352 } | 355 } |
353 } | 356 } |
354 | 357 |
355 void DomStorageContext::FindUnusedNamespaces() { | 358 void DomStorageContext::FindUnusedNamespaces() { |
356 DCHECK(session_storage_database_.get()); | 359 DCHECK(session_storage_database_.get()); |
357 if (scavenging_started_) | 360 if (scavenging_started_) |
358 return; | 361 return; |
359 scavenging_started_ = true; | 362 scavenging_started_ = true; |
360 std::set<std::string> namespace_ids_in_use; | 363 std::set<std::string> namespace_ids_in_use; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 if (!deletable_persistent_namespace_ids_.empty()) { | 418 if (!deletable_persistent_namespace_ids_.empty()) { |
416 task_runner_->PostDelayedTask( | 419 task_runner_->PostDelayedTask( |
417 FROM_HERE, base::Bind( | 420 FROM_HERE, base::Bind( |
418 &DomStorageContext::DeleteNextUnusedNamespace, | 421 &DomStorageContext::DeleteNextUnusedNamespace, |
419 this), | 422 this), |
420 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); | 423 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
421 } | 424 } |
422 } | 425 } |
423 | 426 |
424 } // namespace dom_storage | 427 } // namespace dom_storage |
OLD | NEW |