summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-13 19:35:05 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-13 19:35:05 +0000
commit26a9acf48d0c411045030f3e6bd70dca6ab90d83 (patch)
tree38eb22a1960cd4e05249975129dc94c9b56b7c52 /chrome/browser/renderer_host
parent081b094efb32b0921e949655dfca9e92933a9d66 (diff)
downloadchromium_src-26a9acf48d0c411045030f3e6bd70dca6ab90d83.zip
chromium_src-26a9acf48d0c411045030f3e6bd70dca6ab90d83.tar.gz
chromium_src-26a9acf48d0c411045030f3e6bd70dca6ab90d83.tar.bz2
Make DatabaseDispatcherHost be a message filter so that ResourceMessageFilter doesn't have to know about it.
Review URL: http://codereview.chromium.org/5757002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69031 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc3
-rw-r--r--chrome/browser/renderer_host/database_dispatcher_host.cc438
-rw-r--r--chrome/browser/renderer_host/database_message_filter.cc319
-rw-r--r--chrome/browser/renderer_host/database_message_filter.h (renamed from chrome/browser/renderer_host/database_dispatcher_host.h)94
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc9
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h4
6 files changed, 351 insertions, 516 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 3a46d65..aff7ee6 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -46,6 +46,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/audio_renderer_host.h"
#include "chrome/browser/renderer_host/blob_message_filter.h"
+#include "chrome/browser/renderer_host/database_message_filter.h"
#include "chrome/browser/renderer_host/file_utilities_message_filter.h"
#include "chrome/browser/renderer_host/pepper_file_message_filter.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -405,6 +406,8 @@ void BrowserRenderProcessHost::CreateMessageFilters() {
new BlobMessageFilter(id(), profile()->GetBlobStorageContext()));
channel_->AddFilter(new FileUtilitiesMessageFilter(id()));
channel_->AddFilter(new MimeRegistryMessageFilter());
+ channel_->AddFilter(new DatabaseMessageFilter(
+ profile()->GetDatabaseTracker(), profile()->GetHostContentSettingsMap()));
}
int BrowserRenderProcessHost::GetNextRoutingID() {
diff --git a/chrome/browser/renderer_host/database_dispatcher_host.cc b/chrome/browser/renderer_host/database_dispatcher_host.cc
deleted file mode 100644
index c755bf0..0000000
--- a/chrome/browser/renderer_host/database_dispatcher_host.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/renderer_host/database_dispatcher_host.h"
-
-#include <string>
-
-#include "base/string_util.h"
-#include "base/thread.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
-#include "chrome/browser/net/chrome_url_request_context.h"
-#include "chrome/browser/renderer_host/browser_render_process_host.h"
-#include "chrome/common/render_messages.h"
-#include "googleurl/src/gurl.h"
-#include "third_party/sqlite/sqlite3.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
-#include "webkit/database/database_util.h"
-#include "webkit/database/vfs_backend.h"
-
-#if defined(OS_POSIX)
-#include "base/file_descriptor_posix.h"
-#endif
-
-using WebKit::WebSecurityOrigin;
-using webkit_database::DatabaseTracker;
-using webkit_database::DatabaseUtil;
-using webkit_database::VfsBackend;
-
-const int kNumDeleteRetries = 2;
-const int kDelayDeleteRetryMs = 100;
-
-DatabaseDispatcherHost::DatabaseDispatcherHost(
- DatabaseTracker* db_tracker,
- IPC::Message::Sender* sender,
- HostContentSettingsMap *host_content_settings_map)
- : db_tracker_(db_tracker),
- message_sender_(sender),
- process_handle_(0),
- observer_added_(false),
- shutdown_(false),
- host_content_settings_map_(host_content_settings_map) {
- DCHECK(db_tracker_);
- DCHECK(message_sender_);
-}
-
-void DatabaseDispatcherHost::Init(base::ProcessHandle process_handle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(!shutdown_);
- DCHECK(!process_handle_);
- DCHECK(process_handle);
- process_handle_ = process_handle;
-}
-
-void DatabaseDispatcherHost::Shutdown() {
- shutdown_ = true;
- message_sender_ = NULL;
- if (observer_added_) {
- observer_added_ = false;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &DatabaseDispatcherHost::RemoveObserver));
- }
-}
-
-void DatabaseDispatcherHost::AddObserver() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- db_tracker_->AddObserver(this);
-}
-
-void DatabaseDispatcherHost::RemoveObserver() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- // If the renderer process died without closing all databases,
- // then we need to manually close those connections
- db_tracker_->CloseDatabases(database_connections_);
- database_connections_.RemoveAllConnections();
-
- db_tracker_->RemoveObserver(this);
-}
-
-bool DatabaseDispatcherHost::OnMessageReceived(
- const IPC::Message& message, bool* message_was_ok) {
- DCHECK(!shutdown_);
- *message_was_ok = true;
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(DatabaseDispatcherHost, message, *message_was_ok)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DatabaseOpenFile,
- OnDatabaseOpenFile)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DatabaseDeleteFile,
- OnDatabaseDeleteFile)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DatabaseGetFileAttributes,
- OnDatabaseGetFileAttributes)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DatabaseGetFileSize,
- OnDatabaseGetFileSize)
- IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseOpened, OnDatabaseOpened)
- IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseModified, OnDatabaseModified)
- IPC_MESSAGE_HANDLER(ViewHostMsg_DatabaseClosed, OnDatabaseClosed)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_AllowDatabase, OnAllowDatabase)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
- return handled;
-}
-
-void DatabaseDispatcherHost::ReceivedBadMessage(uint32 msg_type) {
- BrowserRenderProcessHost::BadMessageTerminateProcess(
- msg_type, process_handle_);
-}
-
-void DatabaseDispatcherHost::Send(IPC::Message* message) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- if (!BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::Send,
- message)))
- delete message;
- return;
- }
-
- if (!shutdown_ && message_sender_)
- message_sender_->Send(message);
- else
- delete message;
-}
-
-DatabaseDispatcherHost::~DatabaseDispatcherHost() {}
-
-void DatabaseDispatcherHost::OnDatabaseOpenFile(const string16& vfs_file_name,
- int desired_flags,
- IPC::Message* reply_msg) {
- if (!observer_added_) {
- observer_added_ = true;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &DatabaseDispatcherHost::AddObserver));
- }
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseOpenFile,
- vfs_file_name,
- desired_flags,
- reply_msg));
-}
-
-// Scheduled by the IO thread on the file thread.
-// Opens the given database file, then schedules
-// a task on the IO thread's message loop to send an IPC back to
-// corresponding renderer process with the file handle.
-void DatabaseDispatcherHost::DatabaseOpenFile(const string16& vfs_file_name,
- int desired_flags,
- IPC::Message* reply_msg) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
- base::PlatformFile target_handle = base::kInvalidPlatformFileValue;
- string16 origin_identifier;
- string16 database_name;
-
- // When in incognito mode, we want to make sure that all DB files are
- // removed when the incognito profile goes away, so we add the
- // SQLITE_OPEN_DELETEONCLOSE flag when opening all files, and keep
- // open handles to them in the database tracker to make sure they're
- // around for as long as needed.
- if (vfs_file_name.empty()) {
- VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(),
- desired_flags, &file_handle);
- } else if (DatabaseUtil::CrackVfsFileName(vfs_file_name, &origin_identifier,
- &database_name, NULL) &&
- !db_tracker_->IsDatabaseScheduledForDeletion(origin_identifier,
- database_name)) {
- FilePath db_file =
- DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
- if (!db_file.empty()) {
- if (db_tracker_->IsIncognitoProfile()) {
- db_tracker_->GetIncognitoFileHandle(vfs_file_name, &file_handle);
- if (file_handle == base::kInvalidPlatformFileValue) {
- VfsBackend::OpenFile(db_file,
- desired_flags | SQLITE_OPEN_DELETEONCLOSE,
- &file_handle);
- if (VfsBackend::FileTypeIsMainDB(desired_flags) ||
- VfsBackend::FileTypeIsJournal(desired_flags))
- db_tracker_->SaveIncognitoFileHandle(vfs_file_name, file_handle);
- }
- } else {
- VfsBackend::OpenFile(db_file, desired_flags, &file_handle);
- }
- }
- }
-
- // Then we duplicate the file handle to make it useable in the renderer
- // process. The original handle is closed, unless we saved it in the
- // database tracker.
- bool auto_close = !db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name);
- VfsBackend::GetFileHandleForProcess(process_handle_, file_handle,
- &target_handle, auto_close);
-
- ViewHostMsg_DatabaseOpenFile::WriteReplyParams(
- reply_msg,
-#if defined(OS_WIN)
- target_handle
-#elif defined(OS_POSIX)
- base::FileDescriptor(target_handle, auto_close)
-#endif
- );
- Send(reply_msg);
-}
-
-void DatabaseDispatcherHost::OnDatabaseDeleteFile(const string16& vfs_file_name,
- const bool& sync_dir,
- IPC::Message* reply_msg) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseDeleteFile,
- vfs_file_name,
- sync_dir,
- reply_msg,
- kNumDeleteRetries));
-}
-
-// Scheduled by the IO thread on the file thread.
-// Deletes the given database file, then schedules
-// a task on the IO thread's message loop to send an IPC back to
-// corresponding renderer process with the error code.
-void DatabaseDispatcherHost::DatabaseDeleteFile(const string16& vfs_file_name,
- bool sync_dir,
- IPC::Message* reply_msg,
- int reschedule_count) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- // Return an error if the file name is invalid or if the file could not
- // be deleted after kNumDeleteRetries attempts.
- int error_code = SQLITE_IOERR_DELETE;
- FilePath db_file =
- DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
- if (!db_file.empty()) {
- // In order to delete a journal file in incognito mode, we only need to
- // close the open handle to it that's stored in the database tracker.
- if (db_tracker_->IsIncognitoProfile()) {
- if (db_tracker_->CloseIncognitoFileHandle(vfs_file_name))
- error_code = SQLITE_OK;
- } else {
- error_code = VfsBackend::DeleteFile(db_file, sync_dir);
- }
-
- if ((error_code == SQLITE_IOERR_DELETE) && reschedule_count) {
- // If the file could not be deleted, try again.
- BrowserThread::PostDelayedTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseDeleteFile,
- vfs_file_name,
- sync_dir,
- reply_msg,
- reschedule_count - 1),
- kDelayDeleteRetryMs);
- return;
- }
- }
-
- ViewHostMsg_DatabaseDeleteFile::WriteReplyParams(reply_msg, error_code);
- Send(reply_msg);
-}
-
-void DatabaseDispatcherHost::OnDatabaseGetFileAttributes(
- const string16& vfs_file_name,
- IPC::Message* reply_msg) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseGetFileAttributes,
- vfs_file_name,
- reply_msg));
-}
-
-// Scheduled by the IO thread on the file thread.
-// Gets the attributes of the given database file, then schedules
-// a task on the IO thread's message loop to send an IPC back to
-// corresponding renderer process.
-void DatabaseDispatcherHost::DatabaseGetFileAttributes(
- const string16& vfs_file_name,
- IPC::Message* reply_msg) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- int32 attributes = -1;
- FilePath db_file =
- DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
- if (!db_file.empty())
- attributes = VfsBackend::GetFileAttributes(db_file);
-
- ViewHostMsg_DatabaseGetFileAttributes::WriteReplyParams(
- reply_msg, attributes);
- Send(reply_msg);
-}
-
-void DatabaseDispatcherHost::OnDatabaseGetFileSize(
- const string16& vfs_file_name, IPC::Message* reply_msg) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseGetFileSize,
- vfs_file_name,
- reply_msg));
-}
-
-// Scheduled by the IO thread on the file thread.
-// Gets the size of the given file, then schedules a task
-// on the IO thread's message loop to send an IPC back to
-// the corresponding renderer process.
-void DatabaseDispatcherHost::DatabaseGetFileSize(const string16& vfs_file_name,
- IPC::Message* reply_msg) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- int64 size = 0;
- FilePath db_file =
- DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
- if (!db_file.empty())
- size = VfsBackend::GetFileSize(db_file);
-
- ViewHostMsg_DatabaseGetFileSize::WriteReplyParams(reply_msg, size);
- Send(reply_msg);
-}
-
-void DatabaseDispatcherHost::OnDatabaseOpened(const string16& origin_identifier,
- const string16& database_name,
- const string16& description,
- int64 estimated_size) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseOpened,
- origin_identifier,
- database_name,
- description,
- estimated_size));
-}
-
-void DatabaseDispatcherHost::DatabaseOpened(const string16& origin_identifier,
- const string16& database_name,
- const string16& description,
- int64 estimated_size) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- int64 database_size = 0;
- int64 space_available = 0;
- database_connections_.AddConnection(origin_identifier, database_name);
- db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
- estimated_size, &database_size, &space_available);
- Send(new ViewMsg_DatabaseUpdateSize(origin_identifier, database_name,
- database_size, space_available));
-}
-
-void DatabaseDispatcherHost::OnDatabaseModified(
- const string16& origin_identifier,
- const string16& database_name) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseModified,
- origin_identifier,
- database_name));
-}
-
-void DatabaseDispatcherHost::DatabaseModified(const string16& origin_identifier,
- const string16& database_name) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- if (!database_connections_.IsDatabaseOpened(
- origin_identifier, database_name)) {
- ReceivedBadMessage(ViewHostMsg_DatabaseModified::ID);
- return;
- }
-
- db_tracker_->DatabaseModified(origin_identifier, database_name);
-}
-
-void DatabaseDispatcherHost::OnDatabaseClosed(const string16& origin_identifier,
- const string16& database_name) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &DatabaseDispatcherHost::DatabaseClosed,
- origin_identifier,
- database_name));
-}
-
-void DatabaseDispatcherHost::OnAllowDatabase(const std::string& origin_url,
- const string16& name,
- const string16& display_name,
- unsigned long estimated_size,
- IPC::Message* reply_msg) {
- GURL url = GURL(origin_url);
- ContentSetting content_setting =
- host_content_settings_map_->GetContentSetting(
- url, CONTENT_SETTINGS_TYPE_COOKIES, "");
- AllowDatabaseResponse(reply_msg, content_setting);
-}
-
-void DatabaseDispatcherHost::AllowDatabaseResponse(
- IPC::Message* reply_msg, ContentSetting content_setting) {
- DCHECK((content_setting == CONTENT_SETTING_ALLOW) ||
- (content_setting == CONTENT_SETTING_BLOCK) ||
- (content_setting == CONTENT_SETTING_SESSION_ONLY));
- ViewHostMsg_AllowDatabase::WriteReplyParams(
- reply_msg, content_setting != CONTENT_SETTING_BLOCK);
- Send(reply_msg);
-}
-
-void DatabaseDispatcherHost::DatabaseClosed(const string16& origin_identifier,
- const string16& database_name) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- if (!database_connections_.IsDatabaseOpened(
- origin_identifier, database_name)) {
- ReceivedBadMessage(ViewHostMsg_DatabaseClosed::ID);
- return;
- }
-
- db_tracker_->DatabaseClosed(origin_identifier, database_name);
- database_connections_.RemoveConnection(origin_identifier, database_name);
-}
-
-void DatabaseDispatcherHost::OnDatabaseSizeChanged(
- const string16& origin_identifier,
- const string16& database_name,
- int64 database_size,
- int64 space_available) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- if (database_connections_.IsOriginUsed(origin_identifier)) {
- Send(new ViewMsg_DatabaseUpdateSize(origin_identifier, database_name,
- database_size, space_available));
- }
-}
-
-void DatabaseDispatcherHost::OnDatabaseScheduledForDeletion(
- const string16& origin_identifier,
- const string16& database_name) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- Send(new ViewMsg_DatabaseCloseImmediately(origin_identifier, database_name));
-}
diff --git a/chrome/browser/renderer_host/database_message_filter.cc b/chrome/browser/renderer_host/database_message_filter.cc
new file mode 100644
index 0000000..a134bb2
--- /dev/null
+++ b/chrome/browser/renderer_host/database_message_filter.cc
@@ -0,0 +1,319 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/renderer_host/database_message_filter.h"
+
+#include <string>
+
+#include "base/string_util.h"
+#include "base/thread.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/common/database_messages.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/sqlite/sqlite3.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "webkit/database/database_util.h"
+#include "webkit/database/vfs_backend.h"
+
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+
+using WebKit::WebSecurityOrigin;
+using webkit_database::DatabaseTracker;
+using webkit_database::DatabaseUtil;
+using webkit_database::VfsBackend;
+
+const int kNumDeleteRetries = 2;
+const int kDelayDeleteRetryMs = 100;
+
+DatabaseMessageFilter::DatabaseMessageFilter(
+ webkit_database::DatabaseTracker* db_tracker,
+ HostContentSettingsMap *host_content_settings_map)
+ : db_tracker_(db_tracker),
+ observer_added_(false),
+ host_content_settings_map_(host_content_settings_map) {
+ DCHECK(db_tracker_);
+}
+
+void DatabaseMessageFilter::OnChannelClosing() {
+ BrowserMessageFilter::OnChannelClosing();
+ if (observer_added_) {
+ observer_added_ = false;
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &DatabaseMessageFilter::RemoveObserver));
+ }
+}
+
+void DatabaseMessageFilter::AddObserver() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ db_tracker_->AddObserver(this);
+}
+
+void DatabaseMessageFilter::RemoveObserver() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // If the renderer process died without closing all databases,
+ // then we need to manually close those connections
+ db_tracker_->CloseDatabases(database_connections_);
+ database_connections_.RemoveAllConnections();
+
+ db_tracker_->RemoveObserver(this);
+}
+
+void DatabaseMessageFilter::OverrideThreadForMessage(
+ const IPC::Message& message,
+ BrowserThread::ID* thread) {
+ if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart &&
+ message.type() != DatabaseHostMsg_Allow::ID) {
+ *thread = BrowserThread::FILE;
+ }
+
+ if (message.type() == DatabaseHostMsg_OpenFile::ID && !observer_added_) {
+ observer_added_ = true;
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver));
+ }
+}
+
+bool DatabaseMessageFilter::OnMessageReceived(
+ const IPC::Message& message,
+ bool* message_was_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile,
+ OnDatabaseOpenFile)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile,
+ OnDatabaseDeleteFile)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes,
+ OnDatabaseGetFileAttributes)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize,
+ OnDatabaseGetFileSize)
+ IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened)
+ IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified)
+ IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_Allow, OnAllowDatabase)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+ return handled;
+}
+
+DatabaseMessageFilter::~DatabaseMessageFilter() {
+}
+
+void DatabaseMessageFilter::OnDatabaseOpenFile(const string16& vfs_file_name,
+ int desired_flags,
+ IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
+ base::PlatformFile target_handle = base::kInvalidPlatformFileValue;
+ string16 origin_identifier;
+ string16 database_name;
+
+ // When in incognito mode, we want to make sure that all DB files are
+ // removed when the incognito profile goes away, so we add the
+ // SQLITE_OPEN_DELETEONCLOSE flag when opening all files, and keep
+ // open handles to them in the database tracker to make sure they're
+ // around for as long as needed.
+ if (vfs_file_name.empty()) {
+ VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(),
+ desired_flags, &file_handle);
+ } else if (DatabaseUtil::CrackVfsFileName(vfs_file_name, &origin_identifier,
+ &database_name, NULL) &&
+ !db_tracker_->IsDatabaseScheduledForDeletion(origin_identifier,
+ database_name)) {
+ FilePath db_file =
+ DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
+ if (!db_file.empty()) {
+ if (db_tracker_->IsIncognitoProfile()) {
+ db_tracker_->GetIncognitoFileHandle(vfs_file_name, &file_handle);
+ if (file_handle == base::kInvalidPlatformFileValue) {
+ VfsBackend::OpenFile(db_file,
+ desired_flags | SQLITE_OPEN_DELETEONCLOSE,
+ &file_handle);
+ if (VfsBackend::FileTypeIsMainDB(desired_flags) ||
+ VfsBackend::FileTypeIsJournal(desired_flags))
+ db_tracker_->SaveIncognitoFileHandle(vfs_file_name, file_handle);
+ }
+ } else {
+ VfsBackend::OpenFile(db_file, desired_flags, &file_handle);
+ }
+ }
+ }
+
+ // Then we duplicate the file handle to make it useable in the renderer
+ // process. The original handle is closed, unless we saved it in the
+ // database tracker.
+ bool auto_close = !db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name);
+ VfsBackend::GetFileHandleForProcess(peer_handle(), file_handle,
+ &target_handle, auto_close);
+
+ DatabaseHostMsg_OpenFile::WriteReplyParams(
+ reply_msg,
+#if defined(OS_WIN)
+ target_handle
+#elif defined(OS_POSIX)
+ base::FileDescriptor(target_handle, auto_close)
+#endif
+ );
+ Send(reply_msg);
+}
+
+void DatabaseMessageFilter::OnDatabaseDeleteFile(const string16& vfs_file_name,
+ const bool& sync_dir,
+ IPC::Message* reply_msg) {
+ DatabaseDeleteFile(vfs_file_name, sync_dir, reply_msg, kNumDeleteRetries);
+}
+
+void DatabaseMessageFilter::DatabaseDeleteFile(const string16& vfs_file_name,
+ bool sync_dir,
+ IPC::Message* reply_msg,
+ int reschedule_count) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // Return an error if the file name is invalid or if the file could not
+ // be deleted after kNumDeleteRetries attempts.
+ int error_code = SQLITE_IOERR_DELETE;
+ FilePath db_file =
+ DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
+ if (!db_file.empty()) {
+ // In order to delete a journal file in incognito mode, we only need to
+ // close the open handle to it that's stored in the database tracker.
+ if (db_tracker_->IsIncognitoProfile()) {
+ if (db_tracker_->CloseIncognitoFileHandle(vfs_file_name))
+ error_code = SQLITE_OK;
+ } else {
+ error_code = VfsBackend::DeleteFile(db_file, sync_dir);
+ }
+
+ if ((error_code == SQLITE_IOERR_DELETE) && reschedule_count) {
+ // If the file could not be deleted, try again.
+ BrowserThread::PostDelayedTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this,
+ &DatabaseMessageFilter::DatabaseDeleteFile,
+ vfs_file_name,
+ sync_dir,
+ reply_msg,
+ reschedule_count - 1),
+ kDelayDeleteRetryMs);
+ return;
+ }
+ }
+
+ DatabaseHostMsg_DeleteFile::WriteReplyParams(reply_msg, error_code);
+ Send(reply_msg);
+}
+
+void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
+ const string16& vfs_file_name,
+ IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ int32 attributes = -1;
+ FilePath db_file =
+ DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
+ if (!db_file.empty())
+ attributes = VfsBackend::GetFileAttributes(db_file);
+
+ DatabaseHostMsg_GetFileAttributes::WriteReplyParams(
+ reply_msg, attributes);
+ Send(reply_msg);
+}
+
+void DatabaseMessageFilter::OnDatabaseGetFileSize(
+ const string16& vfs_file_name, IPC::Message* reply_msg) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ int64 size = 0;
+ FilePath db_file =
+ DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
+ if (!db_file.empty())
+ size = VfsBackend::GetFileSize(db_file);
+
+ DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size);
+ Send(reply_msg);
+}
+
+void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier,
+ const string16& database_name,
+ const string16& description,
+ int64 estimated_size) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ int64 database_size = 0;
+ int64 space_available = 0;
+ database_connections_.AddConnection(origin_identifier, database_name);
+ db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
+ estimated_size, &database_size, &space_available);
+ Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
+ database_size, space_available));
+}
+
+void DatabaseMessageFilter::OnDatabaseModified(
+ const string16& origin_identifier,
+ const string16& database_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ if (!database_connections_.IsDatabaseOpened(
+ origin_identifier, database_name)) {
+ BadMessageReceived(DatabaseHostMsg_Modified::ID);
+ return;
+ }
+
+ db_tracker_->DatabaseModified(origin_identifier, database_name);
+}
+
+void DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier,
+ const string16& database_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ if (!database_connections_.IsDatabaseOpened(
+ origin_identifier, database_name)) {
+ BadMessageReceived(DatabaseHostMsg_Closed::ID);
+ return;
+ }
+
+ db_tracker_->DatabaseClosed(origin_identifier, database_name);
+ database_connections_.RemoveConnection(origin_identifier, database_name);
+}
+
+void DatabaseMessageFilter::OnAllowDatabase(const std::string& origin_url,
+ const string16& name,
+ const string16& display_name,
+ unsigned long estimated_size,
+ IPC::Message* reply_msg) {
+ GURL url = GURL(origin_url);
+ ContentSetting content_setting =
+ host_content_settings_map_->GetContentSetting(
+ url, CONTENT_SETTINGS_TYPE_COOKIES, "");
+ AllowDatabaseResponse(reply_msg, content_setting);
+}
+
+void DatabaseMessageFilter::AllowDatabaseResponse(
+ IPC::Message* reply_msg, ContentSetting content_setting) {
+ DCHECK((content_setting == CONTENT_SETTING_ALLOW) ||
+ (content_setting == CONTENT_SETTING_BLOCK) ||
+ (content_setting == CONTENT_SETTING_SESSION_ONLY));
+ DatabaseHostMsg_Allow::WriteReplyParams(
+ reply_msg, content_setting != CONTENT_SETTING_BLOCK);
+ Send(reply_msg);
+}
+
+void DatabaseMessageFilter::OnDatabaseSizeChanged(
+ const string16& origin_identifier,
+ const string16& database_name,
+ int64 database_size,
+ int64 space_available) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ if (database_connections_.IsOriginUsed(origin_identifier)) {
+ Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
+ database_size, space_available));
+ }
+}
+
+void DatabaseMessageFilter::OnDatabaseScheduledForDeletion(
+ const string16& origin_identifier,
+ const string16& database_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name));
+}
diff --git a/chrome/browser/renderer_host/database_dispatcher_host.h b/chrome/browser/renderer_host/database_message_filter.h
index 000c0632..4bd9994 100644
--- a/chrome/browser/renderer_host/database_dispatcher_host.h
+++ b/chrome/browser/renderer_host/database_message_filter.h
@@ -2,37 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_RENDERER_HOST_DATABASE_DISPATCHER_HOST_H_
-#define CHROME_BROWSER_RENDERER_HOST_DATABASE_DISPATCHER_HOST_H_
+#ifndef CHROME_BROWSER_RENDERER_HOST_DATABASE_MESSAGE_FILTER_H_
+#define CHROME_BROWSER_RENDERER_HOST_DATABASE_MESSAGE_FILTER_H_
#pragma once
#include "base/hash_tables.h"
-#include "base/process.h"
-#include "base/ref_counted.h"
#include "base/string16.h"
+#include "chrome/browser/browser_message_filter.h"
#include "chrome/common/content_settings.h"
-#include "ipc/ipc_message.h"
#include "webkit/database/database_connections.h"
#include "webkit/database/database_tracker.h"
-class GURL;
class HostContentSettingsMap;
-class Receiver;
-class ResourceMessageFilter;
-class DatabaseDispatcherHost
- : public base::RefCountedThreadSafe<DatabaseDispatcherHost>,
+class DatabaseMessageFilter
+ : public BrowserMessageFilter,
public webkit_database::DatabaseTracker::Observer {
public:
- DatabaseDispatcherHost(webkit_database::DatabaseTracker* db_tracker,
- IPC::Message::Sender* sender,
- HostContentSettingsMap *host_content_settings_map);
- void Init(base::ProcessHandle process_handle);
- void Shutdown();
+ DatabaseMessageFilter(
+ webkit_database::DatabaseTracker* db_tracker,
+ HostContentSettingsMap *host_content_settings_map);
- bool OnMessageReceived(const IPC::Message& message, bool* message_was_ok);
+ // BrowserMessageFilter implementation.
+ virtual void OnChannelClosing();
+ virtual void OverrideThreadForMessage(const IPC::Message& message,
+ BrowserThread::ID* thread);
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok);
- // VFS message handlers (IO thread)
+ webkit_database::DatabaseTracker* database_tracker() const {
+ return db_tracker_.get();
+ }
+
+ private:
+ virtual ~DatabaseMessageFilter();
+
+ class PromptDelegate;
+
+ void AddObserver();
+ void RemoveObserver();
+
+ // VFS message handlers (file thread)
void OnDatabaseOpenFile(const string16& vfs_file_name,
int desired_flags,
IPC::Message* reply_msg);
@@ -44,7 +54,7 @@ class DatabaseDispatcherHost
void OnDatabaseGetFileSize(const string16& vfs_file_name,
IPC::Message* reply_msg);
- // Database tracker message handlers (IO thread)
+ // Database tracker message handlers (file thread)
void OnDatabaseOpened(const string16& origin_identifier,
const string16& database_name,
const string16& description,
@@ -67,45 +77,10 @@ class DatabaseDispatcherHost
virtual void OnDatabaseScheduledForDeletion(const string16& origin_identifier,
const string16& database_name);
- webkit_database::DatabaseTracker* database_tracker() const {
- return db_tracker_.get();
- }
-
- void Send(IPC::Message* message);
-
- private:
- friend class base::RefCountedThreadSafe<DatabaseDispatcherHost>;
- virtual ~DatabaseDispatcherHost();
-
- class PromptDelegate;
-
- void AddObserver();
- void RemoveObserver();
-
- void ReceivedBadMessage(uint32 msg_type);
-
- // VFS message handlers (file thread)
- void DatabaseOpenFile(const string16& vfs_file_name,
- int desired_flags,
- IPC::Message* reply_msg);
void DatabaseDeleteFile(const string16& vfs_file_name,
bool sync_dir,
IPC::Message* reply_msg,
int reschedule_count);
- void DatabaseGetFileAttributes(const string16& vfs_file_name,
- IPC::Message* reply_msg);
- void DatabaseGetFileSize(const string16& vfs_file_name,
- IPC::Message* reply_msg);
-
- // Database tracker message handlers (file thread)
- void DatabaseOpened(const string16& origin_identifier,
- const string16& database_name,
- const string16& description,
- int64 estimated_size);
- void DatabaseModified(const string16& origin_identifier,
- const string16& database_name);
- void DatabaseClosed(const string16& origin_identifier,
- const string16& database_name);
// CookiePromptModalDialog response handler (io thread)
void AllowDatabaseResponse(IPC::Message* reply_msg,
@@ -114,21 +89,10 @@ class DatabaseDispatcherHost
// The database tracker for the current profile.
scoped_refptr<webkit_database::DatabaseTracker> db_tracker_;
- // The sender to be used for sending out IPC messages.
- IPC::Message::Sender* message_sender_;
-
- // The handle of this process.
- base::ProcessHandle process_handle_;
-
// True if and only if this instance was added as an observer
// to DatabaseTracker.
bool observer_added_;
- // If true, all messages that are normally processed by this class
- // will be silently discarded. This field should be set to true
- // only when the corresponding renderer process is about to go away.
- bool shutdown_;
-
// Keeps track of all DB connections opened by this renderer
webkit_database::DatabaseConnections database_connections_;
@@ -136,4 +100,4 @@ class DatabaseDispatcherHost
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
};
-#endif // CHROME_BROWSER_RENDERER_HOST_DATABASE_DISPATCHER_HOST_H_
+#endif // CHROME_BROWSER_RENDERER_HOST_DATABASE_MESSAGE_FILTER_H_
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index d762bfb..fe88078 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -41,7 +41,6 @@
#include "chrome/browser/printing/printer_query.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
-#include "chrome/browser/renderer_host/database_dispatcher_host.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/render_view_host_notification_task.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
@@ -252,9 +251,6 @@ ResourceMessageFilter::ResourceMessageFilter(
new DOMStorageDispatcherHost(this, profile->GetWebKitContext()))),
ALLOW_THIS_IN_INITIALIZER_LIST(indexed_db_dispatcher_host_(
new IndexedDBDispatcherHost(this, profile))),
- ALLOW_THIS_IN_INITIALIZER_LIST(db_dispatcher_host_(
- new DatabaseDispatcherHost(profile->GetDatabaseTracker(), this,
- profile->GetHostContentSettingsMap()))),
notification_prefs_(
profile->GetDesktopNotificationService()->prefs_cache()),
host_zoom_map_(profile->GetHostZoomMap()),
@@ -288,9 +284,6 @@ ResourceMessageFilter::~ResourceMessageFilter() {
// Tell the Indexed DB dispatcher host to stop sending messages via us.
indexed_db_dispatcher_host_->Shutdown();
- // Shut down the database dispatcher host.
- db_dispatcher_host_->Shutdown();
-
// Let interested observers know we are being deleted.
NotificationService::current()->Notify(
NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN,
@@ -320,7 +313,6 @@ void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
WorkerService::GetInstance()->Initialize(resource_dispatcher_host_);
dom_storage_dispatcher_host_->Init(id(), handle());
indexed_db_dispatcher_host_->Init(id(), handle());
- db_dispatcher_host_->Init(handle());
}
void ResourceMessageFilter::OnChannelError() {
@@ -347,7 +339,6 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
resource_dispatcher_host_->OnMessageReceived(msg, this, &msg_is_ok) ||
dom_storage_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) ||
indexed_db_dispatcher_host_->OnMessageReceived(msg) ||
- db_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) ||
mp_dispatcher->OnMessageReceived(
msg, this, next_route_id_callback(), &msg_is_ok) ||
geolocation_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) ;
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 9986262..5d30051 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -32,7 +32,6 @@
#include "third_party/WebKit/WebKit/chromium/public/WebPopupType.h"
class ChromeURLRequestContext;
-class DatabaseDispatcherHost;
class DOMStorageDispatcherHost;
struct FontDescriptor;
class GeolocationDispatcherHostOld;
@@ -437,9 +436,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
// Handles Indexed Database related messages.
scoped_refptr<IndexedDBDispatcherHost> indexed_db_dispatcher_host_;
- // Handles HTML5 DB related messages
- scoped_refptr<DatabaseDispatcherHost> db_dispatcher_host_;
-
// A cache of notifications preferences which is used to handle
// Desktop Notifications permission messages.
scoped_refptr<NotificationsPrefsCache> notification_prefs_;