| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 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 "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h" | 5 #include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h" |
| 6 | 6 |
| 7 #include "base/nullable_string16.h" | 7 #include "base/nullable_string16.h" |
| 8 #include "chrome/browser/chrome_thread.h" | 8 #include "chrome/browser/chrome_thread.h" |
| 9 #include "chrome/browser/in_process_webkit/dom_storage_context.h" | 9 #include "chrome/browser/in_process_webkit/dom_storage_context.h" |
| 10 #include "chrome/browser/in_process_webkit/storage_area.h" | 10 #include "chrome/browser/in_process_webkit/storage_area.h" |
| 11 #include "chrome/browser/in_process_webkit/storage_namespace.h" | 11 #include "chrome/browser/in_process_webkit/storage_namespace.h" |
| 12 #include "chrome/browser/in_process_webkit/webkit_thread.h" | 12 #include "chrome/browser/in_process_webkit/webkit_thread.h" |
| 13 #include "chrome/browser/renderer_host/browser_render_process_host.h" | 13 #include "chrome/browser/renderer_host/browser_render_process_host.h" |
| 14 #include "chrome/common/render_messages.h" | 14 #include "chrome/common/render_messages.h" |
| 15 | 15 |
| 16 DOMStorageDispatcherHost* DOMStorageDispatcherHost::current_ = NULL; |
| 17 |
| 18 DOMStorageDispatcherHost:: |
| 19 AutoSetCurrentDispatcherHost::AutoSetCurrentDispatcherHost( |
| 20 DOMStorageDispatcherHost* dispatcher_host) { |
| 21 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 22 DCHECK(!current_); |
| 23 current_ = dispatcher_host; |
| 24 } |
| 25 |
| 26 DOMStorageDispatcherHost:: |
| 27 AutoSetCurrentDispatcherHost::~AutoSetCurrentDispatcherHost() { |
| 28 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 29 DCHECK(current_); |
| 30 current_ = NULL; |
| 31 } |
| 32 |
| 16 DOMStorageDispatcherHost::DOMStorageDispatcherHost( | 33 DOMStorageDispatcherHost::DOMStorageDispatcherHost( |
| 17 IPC::Message::Sender* message_sender, WebKitContext* webkit_context, | 34 IPC::Message::Sender* message_sender, WebKitContext* webkit_context, |
| 18 WebKitThread* webkit_thread) | 35 WebKitThread* webkit_thread) |
| 19 : webkit_context_(webkit_context), | 36 : webkit_context_(webkit_context), |
| 20 webkit_thread_(webkit_thread), | 37 webkit_thread_(webkit_thread), |
| 21 message_sender_(message_sender), | 38 message_sender_(message_sender), |
| 22 process_handle_(0), | 39 process_handle_(0), |
| 23 ever_used_(false), | 40 ever_used_(false), |
| 24 shutdown_(false) { | 41 shutdown_(false) { |
| 25 DCHECK(webkit_context_.get()); | 42 DCHECK(webkit_context_.get()); |
| 26 DCHECK(webkit_thread_); | 43 DCHECK(webkit_thread_); |
| 27 DCHECK(message_sender_); | 44 DCHECK(message_sender_); |
| 28 } | 45 } |
| 29 | 46 |
| 30 DOMStorageDispatcherHost::~DOMStorageDispatcherHost() { | 47 DOMStorageDispatcherHost::~DOMStorageDispatcherHost() { |
| 31 DCHECK(shutdown_); | 48 DCHECK(shutdown_); |
| 32 } | 49 } |
| 33 | 50 |
| 34 void DOMStorageDispatcherHost::Init(base::ProcessHandle process_handle) { | 51 void DOMStorageDispatcherHost::Init(base::ProcessHandle process_handle) { |
| 35 DCHECK(!process_handle_); | 52 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 53 DCHECK(message_sender_); // Make sure Shutdown() has not yet been called. |
| 54 DCHECK(!process_handle_); // Make sure Init() has not yet been called. |
| 55 DCHECK(process_handle); |
| 56 Context()->RegisterDispatcherHost(this); |
| 36 process_handle_ = process_handle; | 57 process_handle_ = process_handle; |
| 37 DCHECK(process_handle_); | |
| 38 } | 58 } |
| 39 | 59 |
| 40 void DOMStorageDispatcherHost::Shutdown() { | 60 void DOMStorageDispatcherHost::Shutdown() { |
| 41 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { | 61 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 62 if (process_handle_) // Init() was called |
| 63 Context()->UnregisterDispatcherHost(this); |
| 42 message_sender_ = NULL; | 64 message_sender_ = NULL; |
| 43 if (!ever_used_) { | 65 if (!ever_used_) { |
| 44 // No need to (possibly) spin up the WebKit thread for a no-op. | 66 // No need to (possibly) spin up the WebKit thread for a no-op. |
| 45 shutdown_ = true; | 67 shutdown_ = true; |
| 46 return; | 68 return; |
| 47 } | 69 } |
| 48 | 70 |
| 49 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); | 71 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); |
| 50 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, | 72 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 51 &DOMStorageDispatcherHost::Shutdown)); | 73 &DOMStorageDispatcherHost::Shutdown)); |
| 52 return; | 74 return; |
| 53 } | 75 } |
| 54 | 76 |
| 55 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); | 77 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 56 DCHECK(ever_used_); | 78 DCHECK(ever_used_); |
| 57 DCHECK(!message_sender_); | 79 DCHECK(!message_sender_); |
| 58 DCHECK(!shutdown_); | 80 DCHECK(!shutdown_); |
| 59 shutdown_ = true; | 81 shutdown_ = true; |
| 60 | 82 |
| 61 // TODO(jorlow): If we have any locks or are tracking resources that need to | 83 // TODO(jorlow): Do stuff that needs to be run on the WebKit thread. Locks |
| 62 // be released on the WebKit thread, do it here. | 84 // and others will likely need this, so let's not delete this |
| 85 // code even though it doesn't do anyting yet. |
| 63 } | 86 } |
| 64 | 87 |
| 65 bool DOMStorageDispatcherHost::OnMessageReceived( | 88 /* static */ |
| 66 const IPC::Message& message, bool *msg_is_ok) { | 89 void DOMStorageDispatcherHost::DispatchStorageEvent(const string16& key, |
| 90 const NullableString16& old_value, const NullableString16& new_value, |
| 91 const string16& origin, bool is_local_storage) { |
| 92 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 93 DCHECK(current_); |
| 94 current_->webkit_thread_->PostIOThreadTask(FROM_HERE, NewRunnableMethod( |
| 95 current_, &DOMStorageDispatcherHost::OnStorageEvent, key, old_value, |
| 96 new_value, origin, is_local_storage)); |
| 97 } |
| 98 |
| 99 bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& message, |
| 100 bool *msg_is_ok) { |
| 67 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 101 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 68 DCHECK(!shutdown_); | 102 DCHECK(!shutdown_); |
| 69 DCHECK(process_handle_); | 103 DCHECK(process_handle_); |
| 70 | 104 |
| 71 bool handled = true; | 105 bool handled = true; |
| 72 IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageDispatcherHost, message, *msg_is_ok) | 106 IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageDispatcherHost, message, *msg_is_ok) |
| 73 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageNamespaceId, | 107 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageNamespaceId, |
| 74 OnNamespaceId) | 108 OnNamespaceId) |
| 75 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageCloneNamespaceId, | 109 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageCloneNamespaceId, |
| 76 OnCloneNamespaceId) | 110 OnCloneNamespaceId) |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 299 } |
| 266 | 300 |
| 267 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); | 301 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 268 bool quota_exception = false; | 302 bool quota_exception = false; |
| 269 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); | 303 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); |
| 270 if (!storage_area) { | 304 if (!storage_area) { |
| 271 BrowserRenderProcessHost::BadMessageTerminateProcess( | 305 BrowserRenderProcessHost::BadMessageTerminateProcess( |
| 272 ViewHostMsg_DOMStorageSetItem::ID, process_handle_); | 306 ViewHostMsg_DOMStorageSetItem::ID, process_handle_); |
| 273 return; | 307 return; |
| 274 } | 308 } |
| 309 |
| 310 AutoSetCurrentDispatcherHost auto_set(this); |
| 275 storage_area->SetItem(key, value, "a_exception); | 311 storage_area->SetItem(key, value, "a_exception); |
| 276 DCHECK(!quota_exception); // This is tracked by the renderer. | 312 DCHECK(!quota_exception); // This is tracked by the renderer. |
| 277 } | 313 } |
| 278 | 314 |
| 279 void DOMStorageDispatcherHost::OnRemoveItem(int64 storage_area_id, | 315 void DOMStorageDispatcherHost::OnRemoveItem(int64 storage_area_id, |
| 280 const string16& key) { | 316 const string16& key) { |
| 281 DCHECK(!shutdown_); | 317 DCHECK(!shutdown_); |
| 282 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { | 318 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 283 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); | 319 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); |
| 284 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, | 320 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 285 &DOMStorageDispatcherHost::OnRemoveItem, storage_area_id, key)); | 321 &DOMStorageDispatcherHost::OnRemoveItem, storage_area_id, key)); |
| 286 return; | 322 return; |
| 287 } | 323 } |
| 288 | 324 |
| 289 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); | 325 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 290 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); | 326 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); |
| 291 if (!storage_area) { | 327 if (!storage_area) { |
| 292 BrowserRenderProcessHost::BadMessageTerminateProcess( | 328 BrowserRenderProcessHost::BadMessageTerminateProcess( |
| 293 ViewHostMsg_DOMStorageRemoveItem::ID, process_handle_); | 329 ViewHostMsg_DOMStorageRemoveItem::ID, process_handle_); |
| 294 return; | 330 return; |
| 295 } | 331 } |
| 332 |
| 333 AutoSetCurrentDispatcherHost auto_set(this); |
| 296 storage_area->RemoveItem(key); | 334 storage_area->RemoveItem(key); |
| 297 } | 335 } |
| 298 | 336 |
| 299 void DOMStorageDispatcherHost::OnClear(int64 storage_area_id) { | 337 void DOMStorageDispatcherHost::OnClear(int64 storage_area_id) { |
| 300 DCHECK(!shutdown_); | 338 DCHECK(!shutdown_); |
| 301 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { | 339 if (ChromeThread::CurrentlyOn(ChromeThread::IO)) { |
| 302 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); | 340 MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop(); |
| 303 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, | 341 webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 304 &DOMStorageDispatcherHost::OnClear, storage_area_id)); | 342 &DOMStorageDispatcherHost::OnClear, storage_area_id)); |
| 305 return; | 343 return; |
| 306 } | 344 } |
| 307 | 345 |
| 308 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); | 346 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); |
| 309 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); | 347 StorageArea* storage_area = Context()->GetStorageArea(storage_area_id); |
| 310 if (!storage_area) { | 348 if (!storage_area) { |
| 311 BrowserRenderProcessHost::BadMessageTerminateProcess( | 349 BrowserRenderProcessHost::BadMessageTerminateProcess( |
| 312 ViewHostMsg_DOMStorageClear::ID, process_handle_); | 350 ViewHostMsg_DOMStorageClear::ID, process_handle_); |
| 313 return; | 351 return; |
| 314 } | 352 } |
| 353 |
| 354 AutoSetCurrentDispatcherHost auto_set(this); |
| 315 storage_area->Clear(); | 355 storage_area->Clear(); |
| 316 } | 356 } |
| 357 |
| 358 void DOMStorageDispatcherHost::OnStorageEvent(const string16& key, |
| 359 const NullableString16& old_value, const NullableString16& new_value, |
| 360 const string16& origin, bool is_local_storage) { |
| 361 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 362 DCHECK(is_local_storage); // Only LocalStorage is implemented right now. |
| 363 DOMStorageType dom_storage_type = is_local_storage ? DOM_STORAGE_LOCAL |
| 364 : DOM_STORAGE_SESSION; |
| 365 const DOMStorageContext::DispatcherHostSet* set = |
| 366 Context()->GetDispatcherHostSet(); |
| 367 DOMStorageContext::DispatcherHostSet::const_iterator cur = set->begin(); |
| 368 while (cur != set->end()) { |
| 369 (*cur)->Send(new ViewMsg_DOMStorageEvent(key, old_value, new_value, origin, |
| 370 dom_storage_type)); |
| 371 ++cur; |
| 372 } |
| 373 } |
| OLD | NEW |