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

Side by Side Diff: chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc

Issue 5722003: Make DOMStorageDispatcherHost be a message filter (and rename it accordingly)... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: get rid of _DELAY_HANDLE macro Created 10 years 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
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
6
7 #include "base/nullable_string16.h"
8 #include "chrome/browser/browser_thread.h"
9 #include "chrome/browser/in_process_webkit/dom_storage_area.h"
10 #include "chrome/browser/in_process_webkit/dom_storage_context.h"
11 #include "chrome/browser/in_process_webkit/dom_storage_namespace.h"
12 #include "chrome/browser/net/chrome_url_request_context.h"
13 #include "chrome/browser/renderer_host/browser_render_process_host.h"
14 #include "chrome/browser/renderer_host/render_view_host_notification_task.h"
15 #include "chrome/browser/renderer_host/resource_message_filter.h"
16 #include "chrome/common/render_messages.h"
17 #include "chrome/common/render_messages_params.h"
18 #include "googleurl/src/gurl.h"
19
20 using WebKit::WebStorageArea;
21
22 DOMStorageDispatcherHost* DOMStorageDispatcherHost::storage_event_host_ = NULL;
23 const GURL* DOMStorageDispatcherHost::storage_event_url_ = NULL;
24
25 DOMStorageDispatcherHost::
26 ScopedStorageEventContext::ScopedStorageEventContext(
27 DOMStorageDispatcherHost* dispatcher_host, const GURL* url) {
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
29 DCHECK(!storage_event_host_);
30 DCHECK(!storage_event_url_);
31 storage_event_host_ = dispatcher_host;
32 storage_event_url_ = url;
33 DCHECK(storage_event_host_);
34 DCHECK(storage_event_url_);
35 }
36
37 DOMStorageDispatcherHost::
38 ScopedStorageEventContext::~ScopedStorageEventContext() {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
40 DCHECK(storage_event_host_);
41 DCHECK(storage_event_url_);
42 storage_event_host_ = NULL;
43 storage_event_url_ = NULL;
44 }
45
46 DOMStorageDispatcherHost::DOMStorageDispatcherHost(
47 ResourceMessageFilter* resource_message_filter,
48 WebKitContext* webkit_context)
49 : webkit_context_(webkit_context),
50 resource_message_filter_(resource_message_filter),
51 process_handle_(0),
52 process_id_(0) {
53 DCHECK(webkit_context_.get());
54 DCHECK(resource_message_filter_);
55 }
56
57 DOMStorageDispatcherHost::~DOMStorageDispatcherHost() {
58 }
59
60 void DOMStorageDispatcherHost::Init(int process_id,
61 base::ProcessHandle process_handle) {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
63 DCHECK(resource_message_filter_); // Ensure Shutdown() has not been called.
64 DCHECK(!process_handle_); // Make sure Init() has not yet been called.
65 DCHECK(process_handle);
66 Context()->RegisterDispatcherHost(this);
67 process_id_ = process_id;
68 process_handle_ = process_handle;
69 }
70
71 void DOMStorageDispatcherHost::Shutdown() {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
73 // This is not always true during testing.
74 if (process_handle_)
75 Context()->UnregisterDispatcherHost(this);
76 resource_message_filter_ = NULL;
77 }
78
79 /* static */
80 void DOMStorageDispatcherHost::DispatchStorageEvent(const NullableString16& key,
81 const NullableString16& old_value, const NullableString16& new_value,
82 const string16& origin, const GURL& url, bool is_local_storage) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
84 DCHECK(is_local_storage); // Only LocalStorage is implemented right now.
85 DCHECK(storage_event_host_);
86 ViewMsg_DOMStorageEvent_Params params;
87 params.key_ = key;
88 params.old_value_ = old_value;
89 params.new_value_ = new_value;
90 params.origin_ = origin;
91 params.url_ = *storage_event_url_; // The url passed in is junk.
92 params.storage_type_ = is_local_storage ? DOM_STORAGE_LOCAL
93 : DOM_STORAGE_SESSION;
94 // The storage_event_host_ is the DOMStorageDispatcherHost that is up in the
95 // current call stack since it caused the storage event to fire.
96 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
97 NewRunnableMethod(storage_event_host_,
98 &DOMStorageDispatcherHost::OnStorageEvent, params));
99 }
100
101 bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& message,
102 bool* msg_is_ok) {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
104 DCHECK(process_handle_);
105
106 bool handled = true;
107 IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageDispatcherHost, message, *msg_is_ok)
108 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageStorageAreaId,
109 OnStorageAreaId)
110 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageLength, OnLength)
111 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageKey, OnKey)
112 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageGetItem, OnGetItem)
113 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageSetItem, OnSetItem)
114 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageRemoveItem,
115 OnRemoveItem)
116 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageClear, OnClear)
117 IPC_MESSAGE_UNHANDLED(handled = false)
118 IPC_END_MESSAGE_MAP()
119 return handled;
120 }
121
122 int64 DOMStorageDispatcherHost::CloneSessionStorage(int64 original_id) {
123 return Context()->CloneSessionStorage(original_id);
124 }
125
126 void DOMStorageDispatcherHost::Send(IPC::Message* message) {
127 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
128 // TODO(jorlow): Even if we successfully post, I believe it's possible for
129 // the task to never run (if the IO thread is already shutting
130 // down). We may want to handle this case, though
131 // realistically it probably doesn't matter.
132 if (!BrowserThread::PostTask(
133 BrowserThread::IO, FROM_HERE, NewRunnableMethod(
134 this, &DOMStorageDispatcherHost::Send, message))) {
135 // The IO thread is dead.
136 delete message;
137 }
138 return;
139 }
140
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
142 if (!resource_message_filter_)
143 delete message;
144 else
145 resource_message_filter_->Send(message);
146 }
147
148 void DOMStorageDispatcherHost::OnStorageAreaId(int64 namespace_id,
149 const string16& origin,
150 IPC::Message* reply_msg) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
152 ChromeURLRequestContext* url_request_context =
153 resource_message_filter_->GetRequestContextForURL(GURL(origin));
154 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
155 this, &DOMStorageDispatcherHost::OnStorageAreaIdWebKit, namespace_id,
156 origin, reply_msg,
157 make_scoped_refptr(url_request_context->host_content_settings_map())));
158 }
159
160 void DOMStorageDispatcherHost::OnStorageAreaIdWebKit(
161 int64 namespace_id, const string16& origin, IPC::Message* reply_msg,
162 HostContentSettingsMap* host_content_settings_map) {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
164 DOMStorageNamespace* storage_namespace =
165 Context()->GetStorageNamespace(namespace_id, true);
166 if (!storage_namespace) {
167 BrowserRenderProcessHost::BadMessageTerminateProcess(
168 ViewHostMsg_DOMStorageStorageAreaId::ID, process_handle_);
169 delete reply_msg;
170 return;
171 }
172 DOMStorageArea* storage_area = storage_namespace->GetStorageArea(
173 origin, host_content_settings_map);
174 ViewHostMsg_DOMStorageStorageAreaId::WriteReplyParams(reply_msg,
175 storage_area->id());
176 Send(reply_msg);
177 }
178
179 void DOMStorageDispatcherHost::OnLength(int64 storage_area_id,
180 IPC::Message* reply_msg) {
181 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
182 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
183 this, &DOMStorageDispatcherHost::OnLength, storage_area_id, reply_msg));
184 return;
185 }
186
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
188 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
189 if (!storage_area) {
190 BrowserRenderProcessHost::BadMessageTerminateProcess(
191 ViewHostMsg_DOMStorageLength::ID, process_handle_);
192 delete reply_msg;
193 return;
194 }
195 unsigned length = storage_area->Length();
196 ViewHostMsg_DOMStorageLength::WriteReplyParams(reply_msg, length);
197 Send(reply_msg);
198 }
199
200 void DOMStorageDispatcherHost::OnKey(int64 storage_area_id, unsigned index,
201 IPC::Message* reply_msg) {
202 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
203 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
204 this, &DOMStorageDispatcherHost::OnKey, storage_area_id, index,
205 reply_msg));
206 return;
207 }
208
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
210 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
211 if (!storage_area) {
212 BrowserRenderProcessHost::BadMessageTerminateProcess(
213 ViewHostMsg_DOMStorageKey::ID, process_handle_);
214 delete reply_msg;
215 return;
216 }
217 const NullableString16& key = storage_area->Key(index);
218 ViewHostMsg_DOMStorageKey::WriteReplyParams(reply_msg, key);
219 Send(reply_msg);
220 }
221
222 void DOMStorageDispatcherHost::OnGetItem(int64 storage_area_id,
223 const string16& key,
224 IPC::Message* reply_msg) {
225 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
226 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
227 this, &DOMStorageDispatcherHost::OnGetItem, storage_area_id, key,
228 reply_msg));
229 return;
230 }
231
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
233 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
234 if (!storage_area) {
235 BrowserRenderProcessHost::BadMessageTerminateProcess(
236 ViewHostMsg_DOMStorageGetItem::ID, process_handle_);
237 delete reply_msg;
238 return;
239 }
240 const NullableString16& value = storage_area->GetItem(key);
241 ViewHostMsg_DOMStorageGetItem::WriteReplyParams(reply_msg, value);
242 Send(reply_msg);
243 }
244
245 void DOMStorageDispatcherHost::OnSetItem(
246 int64 storage_area_id, const string16& key, const string16& value,
247 const GURL& url, IPC::Message* reply_msg) {
248 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
249 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
250 this, &DOMStorageDispatcherHost::OnSetItem, storage_area_id, key, value,
251 url, reply_msg));
252 return;
253 }
254
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
256 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
257 if (!storage_area) {
258 BrowserRenderProcessHost::BadMessageTerminateProcess(
259 ViewHostMsg_DOMStorageSetItem::ID, process_handle_);
260 return;
261 }
262
263 ScopedStorageEventContext scope(this, &url);
264 WebStorageArea::Result result;
265 NullableString16 old_value = storage_area->SetItem(key, value, &result, this);
266
267 // If content was blocked, tell the UI to display the blocked content icon.
268 if (reply_msg->routing_id() == MSG_ROUTING_CONTROL) {
269 DLOG(WARNING) << "setItem was not given a proper routing id";
270 } else {
271 CallRenderViewHostContentSettingsDelegate(
272 process_id_, reply_msg->routing_id(),
273 &RenderViewHostDelegate::ContentSettings::OnLocalStorageAccessed,
274 url, storage_area->owner()->dom_storage_type(),
275 result == WebStorageArea::ResultBlockedByPolicy);
276 }
277
278 ViewHostMsg_DOMStorageSetItem::WriteReplyParams(reply_msg, result, old_value);
279 Send(reply_msg);
280 }
281
282 void DOMStorageDispatcherHost::OnRemoveItem(
283 int64 storage_area_id, const string16& key, const GURL& url,
284 IPC::Message* reply_msg) {
285 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
286 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
287 this, &DOMStorageDispatcherHost::OnRemoveItem, storage_area_id, key,
288 url, reply_msg));
289 return;
290 }
291
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
293 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
294 if (!storage_area) {
295 BrowserRenderProcessHost::BadMessageTerminateProcess(
296 ViewHostMsg_DOMStorageRemoveItem::ID, process_handle_);
297 return;
298 }
299
300 ScopedStorageEventContext scope(this, &url);
301 NullableString16 old_value = storage_area->RemoveItem(key);
302 ViewHostMsg_DOMStorageRemoveItem::WriteReplyParams(reply_msg, old_value);
303 Send(reply_msg);
304 }
305
306 void DOMStorageDispatcherHost::OnClear(int64 storage_area_id, const GURL& url,
307 IPC::Message* reply_msg) {
308 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
309 BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, NewRunnableMethod(
310 this, &DOMStorageDispatcherHost::OnClear, storage_area_id, url,
311 reply_msg));
312 return;
313 }
314
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
316 DOMStorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
317 if (!storage_area) {
318 BrowserRenderProcessHost::BadMessageTerminateProcess(
319 ViewHostMsg_DOMStorageClear::ID, process_handle_);
320 return;
321 }
322
323 ScopedStorageEventContext scope(this, &url);
324 bool something_cleared = storage_area->Clear();
325 ViewHostMsg_DOMStorageClear::WriteReplyParams(reply_msg, something_cleared);
326 Send(reply_msg);
327 }
328
329 void DOMStorageDispatcherHost::OnStorageEvent(
330 const ViewMsg_DOMStorageEvent_Params& params) {
331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
332 const DOMStorageContext::DispatcherHostSet* set =
333 Context()->GetDispatcherHostSet();
334 DOMStorageContext::DispatcherHostSet::const_iterator cur = set->begin();
335 while (cur != set->end()) {
336 // The renderer that generates the event handles it itself.
337 if (*cur != this)
338 (*cur)->Send(new ViewMsg_DOMStorageEvent(params));
339 ++cur;
340 }
341 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698