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

Side by Side Diff: content/browser/in_process_webkit/dom_storage_context.cc

Issue 8929007: Restore sessionStorage when chrome restarts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review. Created 8 years, 11 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.h" 5 #include "content/browser/in_process_webkit/dom_storage_context.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 file_util::Delete(file_path, false); 45 file_util::Delete(file_path, false);
46 } 46 }
47 } 47 }
48 } 48 }
49 49
50 } // namespace 50 } // namespace
51 51
52 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] = 52 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
53 FILE_PATH_LITERAL("Local Storage"); 53 FILE_PATH_LITERAL("Local Storage");
54 54
55 const FilePath::CharType DOMStorageContext::kSessionStorageDirectory[] =
56 FILE_PATH_LITERAL("Session Storage");
57
55 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] = 58 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
56 FILE_PATH_LITERAL(".localstorage"); 59 FILE_PATH_LITERAL(".localstorage");
57 60
58 DOMStorageContext::DOMStorageContext( 61 DOMStorageContext::DOMStorageContext(
59 WebKitContext* webkit_context, 62 WebKitContext* webkit_context,
60 quota::SpecialStoragePolicy* special_storage_policy) 63 quota::SpecialStoragePolicy* special_storage_policy)
61 : last_storage_area_id_(0), 64 : last_storage_area_id_(0),
62 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), 65 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
63 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), 66 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId),
64 clear_local_state_on_exit_(false), 67 clear_local_state_on_exit_(false),
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 return ++last_session_storage_namespace_id_on_ui_thread_; 110 return ++last_session_storage_namespace_id_on_ui_thread_;
108 return --last_session_storage_namespace_id_on_io_thread_; 111 return --last_session_storage_namespace_id_on_io_thread_;
109 } 112 }
110 113
111 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) { 114 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
112 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 115 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
113 int64 clone_id = AllocateSessionStorageNamespaceId(); 116 int64 clone_id = AllocateSessionStorageNamespaceId();
114 BrowserThread::PostTask( 117 BrowserThread::PostTask(
115 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, 118 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
116 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this, 119 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this,
117 original_id, clone_id)); 120 original_id, clone_id, data_path_));
118 return clone_id; 121 return clone_id;
119 } 122 }
120 123
121 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { 124 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
123 int64 id = storage_area->id(); 126 int64 id = storage_area->id();
124 DCHECK(!GetStorageArea(id)); 127 DCHECK(!GetStorageArea(id));
125 storage_area_map_[id] = storage_area; 128 storage_area_map_[id] = storage_area;
126 } 129 }
127 130
(...skipping 12 matching lines...) Expand all
140 return iter->second; 143 return iter->second;
141 } 144 }
142 145
143 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) { 146 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) {
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
145 StorageNamespaceMap::iterator iter = 148 StorageNamespaceMap::iterator iter =
146 storage_namespace_map_.find(namespace_id); 149 storage_namespace_map_.find(namespace_id);
147 if (iter == storage_namespace_map_.end()) 150 if (iter == storage_namespace_map_.end())
148 return; 151 return;
149 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION); 152 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
153 FilePath session_storage_directory =
154 iter->second->session_storage_directory();
150 delete iter->second; 155 delete iter->second;
151 storage_namespace_map_.erase(iter); 156 storage_namespace_map_.erase(iter);
157
158 if (!save_session_state_ &&
159 !session_storage_directory.empty() &&
160 !data_path_.empty()) {
161 FilePath to_delete = data_path_.Append(kSessionStorageDirectory)
162 .Append(session_storage_directory);
163 }
152 } 164 }
153 165
154 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace( 166 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
155 int64 id, bool allocation_allowed) { 167 int64 id, bool allocation_allowed) {
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
157 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); 169 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
158 if (iter != storage_namespace_map_.end()) 170 if (iter != storage_namespace_map_.end())
159 return iter->second; 171 return iter->second;
160 if (!allocation_allowed) 172 if (!allocation_allowed)
161 return NULL; 173 return NULL;
162 if (id == kLocalStorageNamespaceId) 174 if (id == kLocalStorageNamespaceId)
163 return CreateLocalStorage(); 175 return CreateLocalStorage();
164 return CreateSessionStorage(id); 176 return CreateSessionStorage(id);
165 } 177 }
166 178
179 DOMStorageNamespace* DOMStorageContext::RecreateSessionStorageNamespace(
180 int64 id,
181 const FilePath& session_storage_directory) {
182 FilePath dir_path;
183 if (!data_path_.empty()) {
184 dir_path = data_path_.Append(kSessionStorageDirectory)
185 .Append(session_storage_directory);
186 }
187 DOMStorageNamespace* new_namespace =
188 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path, id);
189 RegisterStorageNamespace(new_namespace);
190 return new_namespace;
191 }
192
167 void DOMStorageContext::RegisterMessageFilter( 193 void DOMStorageContext::RegisterMessageFilter(
168 DOMStorageMessageFilter* message_filter) { 194 DOMStorageMessageFilter* message_filter) {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
170 DCHECK(message_filter_set_.find(message_filter) == 196 DCHECK(message_filter_set_.find(message_filter) ==
171 message_filter_set_.end()); 197 message_filter_set_.end());
172 message_filter_set_.insert(message_filter); 198 message_filter_set_.insert(message_filter);
173 } 199 }
174 200
175 void DOMStorageContext::UnregisterMessageFilter( 201 void DOMStorageContext::UnregisterMessageFilter(
176 DOMStorageMessageFilter* message_filter) { 202 DOMStorageMessageFilter* message_filter) {
(...skipping 11 matching lines...) Expand all
188 214
189 void DOMStorageContext::PurgeMemory() { 215 void DOMStorageContext::PurgeMemory() {
190 // It is only safe to purge the memory from the LocalStorage namespace, 216 // It is only safe to purge the memory from the LocalStorage namespace,
191 // because it is backed by disk and can be reloaded later. If we purge a 217 // because it is backed by disk and can be reloaded later. If we purge a
192 // SessionStorage namespace, its data will be gone forever, because it isn't 218 // SessionStorage namespace, its data will be gone forever, because it isn't
193 // currently backed by disk. 219 // currently backed by disk.
194 DOMStorageNamespace* local_storage = 220 DOMStorageNamespace* local_storage =
195 GetStorageNamespace(kLocalStorageNamespaceId, false); 221 GetStorageNamespace(kLocalStorageNamespaceId, false);
196 if (local_storage) 222 if (local_storage)
197 local_storage->PurgeMemory(); 223 local_storage->PurgeMemory();
224 // In non-incognito profiles, the sessionStorage is backed up on the disk, and
225 // can be purged.
226 if (!data_path_.empty()) {
227 for (StorageNamespaceMap::iterator it = storage_namespace_map_.begin();
228 it != storage_namespace_map_.end(); ++it) {
229 }
230 }
198 } 231 }
199 232
200 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { 233 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
201 // Make sure that we don't delete a database that's currently being accessed 234 // Make sure that we don't delete a database that's currently being accessed
202 // by unloading all of the databases temporarily. 235 // by unloading all of the databases temporarily.
203 PurgeMemory(); 236 PurgeMemory();
204 237
205 file_util::FileEnumerator file_enumerator( 238 file_util::FileEnumerator file_enumerator(
206 data_path_.Append(kLocalStorageDirectory), false, 239 data_path_.Append(kLocalStorageDirectory), false,
207 file_util::FileEnumerator::FILES); 240 file_util::FileEnumerator::FILES);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 if (!data_path_.empty()) 291 if (!data_path_.empty())
259 dir_path = data_path_.Append(kLocalStorageDirectory); 292 dir_path = data_path_.Append(kLocalStorageDirectory);
260 DOMStorageNamespace* new_namespace = 293 DOMStorageNamespace* new_namespace =
261 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path); 294 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
262 RegisterStorageNamespace(new_namespace); 295 RegisterStorageNamespace(new_namespace);
263 return new_namespace; 296 return new_namespace;
264 } 297 }
265 298
266 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage( 299 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage(
267 int64 namespace_id) { 300 int64 namespace_id) {
301 FilePath dir_path;
302 if (!data_path_.empty()) {
303 // We cannot derive the directory name for the sessionStorage databases
304 // directly from |namespace_id|. There is no guarantee that the same
305 // namespace ID won't be reused before we restore the session.
306 file_util::CreateDirectory(data_path_.Append(kSessionStorageDirectory));
307 file_util::CreateTemporaryDirInDir(
308 data_path_.Append(kSessionStorageDirectory), "", &dir_path);
309 }
268 DOMStorageNamespace* new_namespace = 310 DOMStorageNamespace* new_namespace =
269 DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id); 311 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path,
312 namespace_id);
270 RegisterStorageNamespace(new_namespace); 313 RegisterStorageNamespace(new_namespace);
271 return new_namespace; 314 return new_namespace;
272 } 315 }
273 316
274 void DOMStorageContext::RegisterStorageNamespace( 317 void DOMStorageContext::RegisterStorageNamespace(
275 DOMStorageNamespace* storage_namespace) { 318 DOMStorageNamespace* storage_namespace) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
277 int64 id = storage_namespace->id(); 320 int64 id = storage_namespace->id();
278 DCHECK(!GetStorageNamespace(id, false)); 321 DCHECK(!GetStorageNamespace(id, false));
279 storage_namespace_map_[id] = storage_namespace; 322 storage_namespace_map_[id] = storage_namespace;
280 } 323 }
281 324
282 /* static */ 325 /* static */
283 void DOMStorageContext::CompleteCloningSessionStorage( 326 void DOMStorageContext::CompleteCloningSessionStorage(
284 DOMStorageContext* context, int64 existing_id, int64 clone_id) { 327 DOMStorageContext* context, int64 existing_id, int64 clone_id,
328 const FilePath& data_path) {
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
286 DOMStorageNamespace* existing_namespace = 330 DOMStorageNamespace* existing_namespace =
287 context->GetStorageNamespace(existing_id, false); 331 context->GetStorageNamespace(existing_id, false);
288 // If nothing exists, then there's nothing to clone. 332 // If nothing exists, then there's nothing to clone.
289 if (existing_namespace) 333 if (existing_namespace) {
290 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id)); 334 if (data_path.empty()) {
335 // Incognito session storage.
336 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id));
337 } else {
338 FilePath from_path;
339 FilePath to_path;
340 if (!data_path.empty()) {
341 from_path = data_path.Append(kSessionStorageDirectory).Append(
342 existing_namespace->session_storage_directory());
343 if (!file_util::CreateTemporaryDirInDir(
344 data_path.Append(kSessionStorageDirectory), "", &to_path)) {
345 LOG(WARNING) << "Failed to create directory for sessionStorage in " <<
346 data_path.Append(kSessionStorageDirectory).value();
347 return;
348 }
349 // Copy the files from from_path to to_path. file_util doesn't seem to
350 // have a simple function for doing this.
michaeln 2012/01/17 21:25:13 Not sure this approach to cloning session storage
marja 2012/01/19 12:43:43 Ah, true, this was broken, thanks for pointing it
351 file_util::FileEnumerator file_enumerator(
352 from_path, false, file_util::FileEnumerator::FILES);
353 for (FilePath path = file_enumerator.Next(); !path.value().empty();
354 path = file_enumerator.Next()) {
355 if (!file_util::CopyFile(path, to_path.Append(path.BaseName()))) {
356 LOG(WARNING) << "Failed to copy sessionStorage file from " <<
357 path.value() << " to " << to_path.value();
358 return;
359 }
360 }
361 }
362 context->RecreateSessionStorageNamespace(clone_id, to_path.BaseName());
363 }
364 }
291 } 365 }
292 366
293 FilePath DOMStorageContext::GetLocalStorageFilePath( 367 FilePath DOMStorageContext::GetLocalStorageFilePath(
294 const string16& origin_id) const { 368 const string16& origin_id) const {
295 FilePath storageDir = data_path_.Append( 369 FilePath storageDir = data_path_.Append(
296 DOMStorageContext::kLocalStorageDirectory); 370 DOMStorageContext::kLocalStorageDirectory);
297 FilePath::StringType id = 371 FilePath::StringType id =
298 webkit_glue::WebStringToFilePathString(origin_id); 372 webkit_glue::WebStringToFilePathString(origin_id);
299 return storageDir.Append(id.append(kLocalStorageExtension)); 373 return storageDir.Append(id.append(kLocalStorageExtension));
300 } 374 }
375
376 void DOMStorageContext::DeleteUnneededSessionStorages(
377 const std::set<std::string>& needed_session_storages) {
378 file_util::FileEnumerator file_enumerator(
379 data_path_.Append(kSessionStorageDirectory),
380 false, file_util::FileEnumerator::DIRECTORIES);
381 for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
382 file_path = file_enumerator.Next()) {
383 if (needed_session_storages.find(file_path.BaseName().value()) ==
384 needed_session_storages.end())
385 file_util::Delete(file_path, true);
386 }
387 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698