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

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

Issue 7480041: Adding session-only localStorage. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Un-blocking the WebKit thread, delayed answering to the DOMStorageHostMsg_StorageAreaId. Created 9 years, 4 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) 2010 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "content/browser/in_process_webkit/dom_storage_namespace.h" 5 #include "content/browser/in_process_webkit/dom_storage_namespace.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "content/browser/content_browser_client.h"
8 #include "content/browser/in_process_webkit/dom_storage_area.h" 9 #include "content/browser/in_process_webkit/dom_storage_area.h"
9 #include "content/browser/in_process_webkit/dom_storage_context.h" 10 #include "content/browser/in_process_webkit/dom_storage_context.h"
10 #include "content/browser/in_process_webkit/dom_storage_message_filter.h" 11 #include "content/browser/in_process_webkit/dom_storage_message_filter.h"
12 #include "content/common/content_client.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h" 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageArea.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h " 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h "
13 #include "webkit/glue/webkit_glue.h" 15 #include "webkit/glue/webkit_glue.h"
14 16
15 using WebKit::WebStorageArea; 17 using WebKit::WebStorageArea;
16 using WebKit::WebStorageNamespace; 18 using WebKit::WebStorageNamespace;
17 using WebKit::WebString; 19 using WebKit::WebString;
18 20
21 namespace {
jochen (gone - plz use gerrit) 2011/07/29 08:01:06 why not make these two functions method of DOMStor
marja 2011/08/01 08:36:32 Done.
22
23 void CreateStorageAreaInWebKitThread(DOMStorageNamespace* dom_storage_namespace,
24 const string16& origin,
25 bool allow_permanent_storage,
26 DOMStorageNamespace::Delegate* delegate,
27 IPC::Message* reply_msg) {
28 // It's possible that the same origin has been requested by multiple
29 // renderers. There can be multiple CreateStorageAreaInWebKitThread tasks in
30 // the event queue and the WebKit thread will process them sequentally. Each
31 // task needs to check if the storage area got created by a previous task.
32 DOMStorageArea* storage_area =
33 dom_storage_namespace->GetExistingStorageArea(origin);
34 if (storage_area) {
35 if (delegate)
36 delegate->OnGotStorageArea(storage_area, reply_msg);
37 return;
38 }
39 dom_storage_namespace->CreateStorageAreaInWebKitThread(
40 origin,
41 allow_permanent_storage,
42 delegate,
43 reply_msg);
44 }
45
46 void ReadContentSettingsOnIOThread(
47 DOMStorageContext* dom_storage_context,
48 const string16& origin,
49 const string16& first_party_origin,
50 DOMStorageNamespace* dom_storage_namespace,
51 DOMStorageNamespace::Delegate* delegate,
52 IPC::Message* reply_msg) {
53 content::ContentBrowserClient* content_browser_client =
54 content::GetContentClient()->browser();
55 bool allow_permanent_storage =
56 content_browser_client->AllowPermanentStorage(
57 GURL(origin),
58 GURL(first_party_origin),
59 dom_storage_context->GetResourceContext());
60 BrowserThread::PostTask(BrowserThread::WEBKIT,
61 FROM_HERE,
62 NewRunnableFunction(
63 CreateStorageAreaInWebKitThread,
64 dom_storage_namespace,
65 origin,
66 allow_permanent_storage,
67 delegate,
68 reply_msg));
69 }
70
71 } // namespace
72
19 /* static */ 73 /* static */
20 DOMStorageNamespace* DOMStorageNamespace::CreateLocalStorageNamespace( 74 DOMStorageNamespace* DOMStorageNamespace::CreateLocalStorageNamespace(
21 DOMStorageContext* dom_storage_context, const FilePath& data_dir_path) { 75 DOMStorageContext* dom_storage_context, const FilePath& data_dir_path) {
22 int64 id = kLocalStorageNamespaceId; 76 int64 id = kLocalStorageNamespaceId;
23 DCHECK(!dom_storage_context->GetStorageNamespace(id, false)); 77 DCHECK(!dom_storage_context->GetStorageNamespace(id, false));
24 return new DOMStorageNamespace(dom_storage_context, id, 78 return new DOMStorageNamespace(dom_storage_context, id,
25 webkit_glue::FilePathToWebString(data_dir_path), DOM_STORAGE_LOCAL); 79 webkit_glue::FilePathToWebString(data_dir_path), DOM_STORAGE_LOCAL);
26 } 80 }
27 81
28 /* static */ 82 /* static */
29 DOMStorageNamespace* DOMStorageNamespace::CreateSessionStorageNamespace( 83 DOMStorageNamespace* DOMStorageNamespace::CreateSessionStorageNamespace(
30 DOMStorageContext* dom_storage_context, int64 id) { 84 DOMStorageContext* dom_storage_context, int64 id) {
31 DCHECK(!dom_storage_context->GetStorageNamespace(id, false)); 85 DCHECK(!dom_storage_context->GetStorageNamespace(id, false));
32 return new DOMStorageNamespace(dom_storage_context, id, WebString(), 86 return new DOMStorageNamespace(dom_storage_context, id, WebString(),
33 DOM_STORAGE_SESSION); 87 DOM_STORAGE_SESSION);
34 } 88 }
35 89
36 DOMStorageNamespace::DOMStorageNamespace(DOMStorageContext* dom_storage_context, 90 DOMStorageNamespace::DOMStorageNamespace(DOMStorageContext* dom_storage_context,
37 int64 id, 91 int64 id,
38 const WebString& data_dir_path, 92 const WebString& data_dir_path,
39 DOMStorageType dom_storage_type) 93 DOMStorageType dom_storage_type)
40 : dom_storage_context_(dom_storage_context), 94 : dom_storage_context_(dom_storage_context),
41 id_(id), 95 id_(id),
42 data_dir_path_(data_dir_path), 96 data_dir_path_(data_dir_path),
43 dom_storage_type_(dom_storage_type) { 97 dom_storage_type_(dom_storage_type) {
98 if (dom_storage_type == DOM_STORAGE_LOCAL && !data_dir_path.isEmpty()) {
99 // This DOMStorageNamespace represents permanent storage; create a sibling
100 // namespace that represents the corresponding session-only storage.
101 session_only_local_storage_.reset(
102 new DOMStorageNamespace(dom_storage_context,
103 id,
104 WebString(),
105 dom_storage_type));
106 }
44 DCHECK(dom_storage_context_); 107 DCHECK(dom_storage_context_);
45 } 108 }
46 109
47 DOMStorageNamespace::~DOMStorageNamespace() { 110 DOMStorageNamespace::~DOMStorageNamespace() {
48 // TODO(jorlow): If the DOMStorageContext is being destructed, there's no need 111 // TODO(jorlow): If the DOMStorageContext is being destructed, there's no need
49 // to do these calls. Maybe we should add a fast path? 112 // to do these calls. Maybe we should add a fast path?
50 for (OriginToStorageAreaMap::iterator iter(origin_to_storage_area_.begin()); 113 for (OriginToStorageAreaMap::iterator iter(origin_to_storage_area_.begin());
51 iter != origin_to_storage_area_.end(); ++iter) { 114 iter != origin_to_storage_area_.end(); ++iter) {
52 dom_storage_context_->UnregisterStorageArea(iter->second); 115 dom_storage_context_->UnregisterStorageArea(iter->second);
53 delete iter->second; 116 delete iter->second;
54 } 117 }
55 } 118 }
56 119
57 DOMStorageArea* DOMStorageNamespace::GetStorageArea(const string16& origin) { 120 DOMStorageArea* DOMStorageNamespace::GetStorageArea(const string16& origin,
121 Delegate* delegate,
122 IPC::Message* reply_msg) {
58 // We may have already created it for another dispatcher host. 123 // We may have already created it for another dispatcher host.
59 OriginToStorageAreaMap::iterator iter = origin_to_storage_area_.find(origin); 124 DOMStorageArea* storage_area = GetExistingStorageArea(origin);
60 if (iter != origin_to_storage_area_.end()) 125 if (storage_area)
61 return iter->second; 126 return storage_area;
127 // Else, we need to create a new DOMStorageArea.
62 128
63 // We need to create a new one. 129 if (session_only_local_storage_.get()) {
64 int64 id = dom_storage_context_->AllocateStorageAreaId(); 130 // We have a session-only sibling DOMStorageNamespace, so we need to check
65 DCHECK(!dom_storage_context_->GetStorageArea(id)); 131 // whether to create it in this or in the sibling. We're now in the WebKit
66 DOMStorageArea* storage_area = new DOMStorageArea(origin, id, this); 132 // thread, but the content settings need to be accessed in the IO thread.
67 origin_to_storage_area_[origin] = storage_area; 133 BrowserThread::PostTask(BrowserThread::IO,
68 dom_storage_context_->RegisterStorageArea(storage_area); 134 FROM_HERE,
69 return storage_area; 135 NewRunnableFunction(
136 ReadContentSettingsOnIOThread,
137 dom_storage_context_,
138 origin,
139 // FIXME(marja): get the first-party url
140 origin,
141 this,
142 delegate,
143 reply_msg));
144 return NULL;
145 }
146 else {
147 // No sibling; handle creation here.
148 return CreateStorageAreaInWebKitThread(origin, true, NULL, NULL);
149 }
70 } 150 }
71 151
72 DOMStorageNamespace* DOMStorageNamespace::Copy(int64 id) { 152 DOMStorageNamespace* DOMStorageNamespace::Copy(int64 id) {
73 DCHECK(dom_storage_type_ == DOM_STORAGE_SESSION); 153 DCHECK(dom_storage_type_ == DOM_STORAGE_SESSION);
74 DCHECK(!dom_storage_context_->GetStorageNamespace(id, false)); 154 DCHECK(!dom_storage_context_->GetStorageNamespace(id, false));
75 DOMStorageNamespace* new_storage_namespace = new DOMStorageNamespace( 155 DOMStorageNamespace* new_storage_namespace = new DOMStorageNamespace(
76 dom_storage_context_, id, data_dir_path_, dom_storage_type_); 156 dom_storage_context_, id, data_dir_path_, dom_storage_type_);
77 // If we haven't used the namespace yet, there's nothing to copy. 157 // If we haven't used the namespace yet, there's nothing to copy.
78 if (storage_namespace_.get()) 158 if (storage_namespace_.get())
79 new_storage_namespace->storage_namespace_.reset(storage_namespace_->copy()); 159 new_storage_namespace->storage_namespace_.reset(storage_namespace_->copy());
(...skipping 20 matching lines...) Expand all
100 180
101 if (dom_storage_type_ == DOM_STORAGE_LOCAL) { 181 if (dom_storage_type_ == DOM_STORAGE_LOCAL) {
102 storage_namespace_.reset( 182 storage_namespace_.reset(
103 WebStorageNamespace::createLocalStorageNamespace(data_dir_path_, 183 WebStorageNamespace::createLocalStorageNamespace(data_dir_path_,
104 WebStorageNamespace::m_localStorageQuota)); 184 WebStorageNamespace::m_localStorageQuota));
105 } else { 185 } else {
106 storage_namespace_.reset(WebStorageNamespace::createSessionStorageNamespace( 186 storage_namespace_.reset(WebStorageNamespace::createSessionStorageNamespace(
107 WebStorageNamespace::m_sessionStorageQuota)); 187 WebStorageNamespace::m_sessionStorageQuota));
108 } 188 }
109 } 189 }
190
191 DOMStorageArea* DOMStorageNamespace::GetExistingStorageArea(
192 const string16& origin) {
193 OriginToStorageAreaMap::iterator iter = origin_to_storage_area_.find(origin);
194 if (iter != origin_to_storage_area_.end())
195 return iter->second;
196
197 // Our our session-only sibling might have it. (This is independent of what
198 // the content settings say; it might be that the settings were changed after
199 // the DOMStorageArea was created.)
200 if (session_only_local_storage_.get()) {
201 iter = session_only_local_storage_->origin_to_storage_area_.find(origin);
202 if (iter != session_only_local_storage_->origin_to_storage_area_.end())
203 return iter->second;
204 }
205 return NULL;
206 }
207
208 DOMStorageArea* DOMStorageNamespace::CreateStorageAreaInWebKitThread(
209 const string16& origin,
210 bool allow_permanent_storage,
211 Delegate* delegate,
212 IPC::Message* reply_msg) {
213 DOMStorageArea* storage_area = NULL;
214 if (session_only_local_storage_.get() &&
215 !allow_permanent_storage) {
216 // For that origin, only session-only data is allowed, and we have a
217 // sibling namespace taking care of it. This will finish immediately,
218 // since the sibling won't check again whether the permanent storage is
219 // allowed.
220 storage_area =
221 session_only_local_storage_->GetStorageArea(origin, NULL, NULL);
222 } else {
223 int64 id = dom_storage_context_->AllocateStorageAreaId();
224 DCHECK(!dom_storage_context_->GetStorageArea(id));
225 storage_area = new DOMStorageArea(origin, id, this);
226 origin_to_storage_area_[origin] = storage_area;
227 dom_storage_context_->RegisterStorageArea(storage_area);
228 }
229 if (delegate)
230 delegate->OnGotStorageArea(storage_area, reply_msg);
231 return storage_area;
232 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698