diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-15 01:38:10 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-15 01:38:10 +0000 |
commit | 7d1f3348c26eda2d1656860c821d335bf94d4cda (patch) | |
tree | cf910edd254fb577e5e47513797fc9969341a884 | |
parent | 24f4babaca825d5eb07e5ad09830b77b3cd6326f (diff) | |
download | chromium_src-7d1f3348c26eda2d1656860c821d335bf94d4cda.zip chromium_src-7d1f3348c26eda2d1656860c821d335bf94d4cda.tar.gz chromium_src-7d1f3348c26eda2d1656860c821d335bf94d4cda.tar.bz2 |
Support file utilities and mime-related methods on workers.
They are necessary to support File::create and File.size() on workers.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3660003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62692 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/file_utilities_dispatcher_host.cc | 201 | ||||
-rw-r--r-- | chrome/browser/renderer_host/file_utilities_dispatcher_host.h | 63 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 151 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 15 | ||||
-rw-r--r-- | chrome/browser/worker_host/worker_process_host.cc | 32 | ||||
-rw-r--r-- | chrome/browser/worker_host/worker_process_host.h | 10 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/renderer/renderer_webkitclient_impl.cc | 6 | ||||
-rw-r--r-- | chrome/worker/worker_webkitclient_impl.cc | 97 | ||||
-rw-r--r-- | chrome/worker/worker_webkitclient_impl.h | 10 |
10 files changed, 411 insertions, 176 deletions
diff --git a/chrome/browser/renderer_host/file_utilities_dispatcher_host.cc b/chrome/browser/renderer_host/file_utilities_dispatcher_host.cc new file mode 100644 index 0000000..ffbbc19 --- /dev/null +++ b/chrome/browser/renderer_host/file_utilities_dispatcher_host.cc @@ -0,0 +1,201 @@ +// 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/file_utilities_dispatcher_host.h" + +#include "base/file_util.h" +#include "base/platform_file.h" +#include "chrome/browser/child_process_security_policy.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/render_messages_params.h" + +namespace { + +void WriteFileSize(IPC::Message* reply_msg, + const base::PlatformFileInfo& file_info) { + ViewHostMsg_GetFileSize::WriteReplyParams(reply_msg, file_info.size); +} + +void WriteFileModificationTime(IPC::Message* reply_msg, + const base::PlatformFileInfo& file_info) { + ViewHostMsg_GetFileModificationTime::WriteReplyParams( + reply_msg, file_info.last_modified); +} + +} // namespace + +FileUtilitiesDispatcherHost::FileUtilitiesDispatcherHost( + IPC::Message::Sender* sender, int process_id) + : message_sender_(sender), + process_id_(process_id), + process_handle_(0), + shutdown_(false) { + DCHECK(message_sender_); +} + +FileUtilitiesDispatcherHost::~FileUtilitiesDispatcherHost() { +} + +void FileUtilitiesDispatcherHost::Init(base::ProcessHandle process_handle) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(!shutdown_); + DCHECK(!process_handle_); + DCHECK(process_handle); + process_handle_ = process_handle; +} + +void FileUtilitiesDispatcherHost::Shutdown() { + message_sender_ = NULL; + shutdown_ = true; +} + +bool FileUtilitiesDispatcherHost::OnMessageReceived( + const IPC::Message& message, bool* message_was_ok) { + DCHECK(!shutdown_); + *message_was_ok = true; + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(FileUtilitiesDispatcherHost, + message, *message_was_ok) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileSize, OnGetFileSize) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileModificationTime, + OnGetFileModificationTime) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenFile, OnOpenFile) + IPC_MESSAGE_UNHANDLED((handled = false, msg_is_ok__ = true)) + IPC_END_MESSAGE_MAP_EX() + return handled; +} + +void FileUtilitiesDispatcherHost::OnGetFileSize( + const FilePath& path, IPC::Message* reply_msg) { + // Get file size only when the child process has been granted permission to + // upload the file. + if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile( + process_id_, path)) { + ViewHostMsg_GetFileSize::WriteReplyParams( + reply_msg, static_cast<int64>(-1)); + Send(reply_msg); + return; + } + + // Getting file size could take long time if it lives on a network share, + // so run it on FILE thread. + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod( + this, &FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread, path, + reply_msg, &WriteFileSize)); +} + +void FileUtilitiesDispatcherHost::OnGetFileModificationTime( + const FilePath& path, IPC::Message* reply_msg) { + // Get file modification time only when the child process has been granted + // permission to upload the file. + if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile( + process_id_, path)) { + ViewHostMsg_GetFileModificationTime::WriteReplyParams(reply_msg, + base::Time()); + Send(reply_msg); + return; + } + + // Getting file modification time could take a long time if it lives on a + // network share, so run it on the FILE thread. + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod( + this, &FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread, + path, reply_msg, &WriteFileModificationTime)); +} + +void FileUtilitiesDispatcherHost::OnGetFileInfoOnFileThread( + const FilePath& path, + IPC::Message* reply_msg, + FileInfoWriteFunc write_func) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + base::PlatformFileInfo file_info; + file_info.size = 0; + file_util::GetFileInfo(path, &file_info); + + (*write_func)(reply_msg, file_info); + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(this, &FileUtilitiesDispatcherHost::Send, reply_msg)); +} + +void FileUtilitiesDispatcherHost::OnOpenFile( + const FilePath& path, int mode, IPC::Message* reply_msg) { + // Open the file only when the child process has been granted permission to + // upload the file. + // TODO(jianli): Do we need separate permission to control opening the file? + if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile( + process_id_, path)) { + ViewHostMsg_OpenFile::WriteReplyParams( + reply_msg, +#if defined(OS_WIN) + base::kInvalidPlatformFileValue +#elif defined(OS_POSIX) + base::FileDescriptor(base::kInvalidPlatformFileValue, true) +#endif + ); + Send(reply_msg); + return; + } + + // Opening the file could take a long time if it lives on a network share, + // so run it on the FILE thread. + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod( + this, &FileUtilitiesDispatcherHost::OnOpenFileOnFileThread, + path, mode, reply_msg)); +} + +void FileUtilitiesDispatcherHost::OnOpenFileOnFileThread( + const FilePath& path, int mode, IPC::Message* reply_msg) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + base::PlatformFile file_handle = base::CreatePlatformFile( + path, + (mode == 0) ? (base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ) + : (base::PLATFORM_FILE_CREATE_ALWAYS | + base::PLATFORM_FILE_WRITE), + NULL, NULL); + + base::PlatformFile target_file_handle; +#if defined(OS_WIN) + // Duplicate the file handle so that the renderer process can access the file. + if (!DuplicateHandle(GetCurrentProcess(), file_handle, + process_handle_, &target_file_handle, 0, false, + DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { + // file_handle is closed whether or not DuplicateHandle succeeds. + target_file_handle = INVALID_HANDLE_VALUE; + } +#else + target_file_handle = file_handle; +#endif + + ViewHostMsg_OpenFile::WriteReplyParams( + reply_msg, +#if defined(OS_WIN) + target_file_handle +#elif defined(OS_POSIX) + base::FileDescriptor(target_file_handle, true) +#endif + ); + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(this, &FileUtilitiesDispatcherHost::Send, reply_msg)); +} + +void FileUtilitiesDispatcherHost::Send(IPC::Message* message) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!shutdown_ && message_sender_) + message_sender_->Send(message); + else + delete message; +} diff --git a/chrome/browser/renderer_host/file_utilities_dispatcher_host.h b/chrome/browser/renderer_host/file_utilities_dispatcher_host.h new file mode 100644 index 0000000..4e8972a --- /dev/null +++ b/chrome/browser/renderer_host/file_utilities_dispatcher_host.h @@ -0,0 +1,63 @@ +// 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. + +#ifndef CHROME_BROWSER_RENDERER_HOST_FILE_UTILITIES_DISPATCHER_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_FILE_UTILITIES_DISPATCHER_HOST_H_ + +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/process.h" +#include "base/ref_counted.h" +#include "ipc/ipc_message.h" + +namespace base { +struct PlatformFileInfo; +} + +namespace IPC { +class Message; +} + +class FileUtilitiesDispatcherHost + : public base::RefCountedThreadSafe<FileUtilitiesDispatcherHost> { + public: + FileUtilitiesDispatcherHost(IPC::Message::Sender* sender, int process_id); + void Init(base::ProcessHandle process_handle); + void Shutdown(); + bool OnMessageReceived(const IPC::Message& message, bool* msg_is_ok); + + void Send(IPC::Message* message); + + private: + friend class base::RefCountedThreadSafe<FileUtilitiesDispatcherHost>; + ~FileUtilitiesDispatcherHost(); + + typedef void (*FileInfoWriteFunc)(IPC::Message* reply_msg, + const base::PlatformFileInfo& file_info); + + void OnGetFileSize(const FilePath& path, IPC::Message* reply_msg); + void OnGetFileModificationTime(const FilePath& path, IPC::Message* reply_msg); + void OnGetFileInfoOnFileThread(const FilePath& path, + IPC::Message* reply_msg, + FileInfoWriteFunc write_func); + void OnOpenFile(const FilePath& path, int mode,IPC::Message* reply_msg); + void OnOpenFileOnFileThread(const FilePath& path, + int mode, + IPC::Message* reply_msg); + + // The sender to be used for sending out IPC messages. + IPC::Message::Sender* message_sender_; + + // The ID of this process. + int process_id_; + + // The handle of this process. + base::ProcessHandle process_handle_; + + bool shutdown_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(FileUtilitiesDispatcherHost); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_FILE_UTILITIES_DISPATCHER_HOST_H_ diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index cc4e662..3f19e58 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -57,6 +57,7 @@ #include "chrome/browser/renderer_host/blob_dispatcher_host.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/file_utilities_dispatcher_host.h" #include "chrome/browser/renderer_host/render_view_host_notification_task.h" #include "chrome/browser/renderer_host/render_widget_helper.h" #include "chrome/browser/search_engines/search_provider_install_state_dispatcher_host.h" @@ -199,17 +200,6 @@ class ClearCacheCompletion : public net::CompletionCallback { scoped_refptr<ResourceMessageFilter> filter_; }; -void WriteFileSize(IPC::Message* reply_msg, - const base::PlatformFileInfo& file_info) { - ViewHostMsg_GetFileSize::WriteReplyParams(reply_msg, file_info.size); -} - -void WriteFileModificationTime(IPC::Message* reply_msg, - const base::PlatformFileInfo& file_info) { - ViewHostMsg_GetFileModificationTime::WriteReplyParams( - reply_msg, file_info.last_modified); -} - } // namespace ResourceMessageFilter::ResourceMessageFilter( @@ -261,7 +251,9 @@ ResourceMessageFilter::ResourceMessageFilter( new FileSystemDispatcherHost(this, profile))), ALLOW_THIS_IN_INITIALIZER_LIST(blob_dispatcher_host_( new BlobDispatcherHost( - this->id(), profile->GetBlobStorageContext()))) { + this->id(), profile->GetBlobStorageContext()))), + ALLOW_THIS_IN_INITIALIZER_LIST(file_utilities_dispatcher_host_( + new FileUtilitiesDispatcherHost(this, this->id()))) { request_context_ = profile_->GetRequestContext(); DCHECK(request_context_); DCHECK(media_request_context_); @@ -297,6 +289,9 @@ ResourceMessageFilter::~ResourceMessageFilter() { // Shut down the blob dispatcher host. blob_dispatcher_host_->Shutdown(); + // Shut down the async file_utilities dispatcher host. + file_utilities_dispatcher_host_->Shutdown(); + // Let interested observers know we are being deleted. NotificationService::current()->Notify( NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN, @@ -333,6 +328,7 @@ void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) { indexed_db_dispatcher_host_->Init(id(), handle()); db_dispatcher_host_->Init(handle()); file_system_dispatcher_host_->Init(handle()); + file_utilities_dispatcher_host_->Init(handle()); } void ResourceMessageFilter::OnChannelError() { @@ -373,7 +369,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { msg, &msg_is_ok) || device_orientation_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) || file_system_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) || - blob_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok); + blob_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) || + file_utilities_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok); if (!handled) { DCHECK(msg_is_ok); // It should have been marked handled if it wasn't OK. @@ -513,10 +510,6 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata, OnCacheableMetadataAvailable) IPC_MESSAGE_HANDLER(ViewHostMsg_EnableSpdy, OnEnableSpdy) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileSize, OnGetFileSize) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetFileModificationTime, - OnGetFileModificationTime) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenFile, OnOpenFile) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetExtensionMessageBundle, OnGetExtensionMessageBundle) @@ -1486,130 +1479,6 @@ void ResourceMessageFilter::OnEnableSpdy(bool enable) { } } -void ResourceMessageFilter::OnGetFileSize(const FilePath& path, - IPC::Message* reply_msg) { - // Get file size only when the child process has been granted permission to - // upload the file. - if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(id(), path)) { - ViewHostMsg_GetFileSize::WriteReplyParams( - reply_msg, static_cast<int64>(-1)); - Send(reply_msg); - return; - } - - // Getting file size could take long time if it lives on a network share, - // so run it on FILE thread. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod( - this, &ResourceMessageFilter::OnGetFileInfoOnFileThread, path, - reply_msg, &WriteFileSize)); -} - -void ResourceMessageFilter::OnGetFileModificationTime(const FilePath& path, - IPC::Message* reply_msg) { - // Get file modification time only when the child process has been granted - // permission to upload the file. - if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(id(), path)) { - ViewHostMsg_GetFileModificationTime::WriteReplyParams(reply_msg, - base::Time()); - Send(reply_msg); - return; - } - - // Getting file modification time could take a long time if it lives on a - // network share, so run it on the FILE thread. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod( - this, &ResourceMessageFilter::OnGetFileInfoOnFileThread, - path, reply_msg, &WriteFileModificationTime)); -} - -void ResourceMessageFilter::OnGetFileInfoOnFileThread( - const FilePath& path, - IPC::Message* reply_msg, - FileInfoWriteFunc write_func) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - - base::PlatformFileInfo file_info; - file_info.size = 0; - file_util::GetFileInfo(path, &file_info); - - (*write_func)(reply_msg, file_info); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, &ResourceMessageFilter::Send, reply_msg)); -} - -void ResourceMessageFilter::OnOpenFile(const FilePath& path, - int mode, - IPC::Message* reply_msg) { - // Open the file only when the child process has been granted permission to - // upload the file. - // TODO(jianli): Do we need separate permission to control opening the file? - if (!ChildProcessSecurityPolicy::GetInstance()->CanReadFile(id(), path)) { - ViewHostMsg_OpenFile::WriteReplyParams( - reply_msg, -#if defined(OS_WIN) - base::kInvalidPlatformFileValue -#elif defined(OS_POSIX) - base::FileDescriptor(base::kInvalidPlatformFileValue, true) -#endif - ); - Send(reply_msg); - return; - } - - // Opening the file could take a long time if it lives on a network share, - // so run it on the FILE thread. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod( - this, &ResourceMessageFilter::OnOpenFileOnFileThread, - path, mode, reply_msg)); -} - -void ResourceMessageFilter::OnOpenFileOnFileThread(const FilePath& path, - int mode, - IPC::Message* reply_msg) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - - base::PlatformFile file_handle = base::CreatePlatformFile( - path, - (mode == 0) ? (base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ) - : (base::PLATFORM_FILE_CREATE_ALWAYS | - base::PLATFORM_FILE_WRITE), - NULL, NULL); - - base::PlatformFile target_file_handle; -#if defined(OS_WIN) - // Duplicate the file handle so that the renderer process can access the file. - if (!DuplicateHandle(GetCurrentProcess(), file_handle, - handle(), &target_file_handle, 0, false, - DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { - // file_handle is closed whether or not DuplicateHandle succeeds. - target_file_handle = INVALID_HANDLE_VALUE; - } -#else - target_file_handle = file_handle; -#endif - - ViewHostMsg_OpenFile::WriteReplyParams( - reply_msg, -#if defined(OS_WIN) - target_file_handle -#elif defined(OS_POSIX) - base::FileDescriptor(target_file_handle, true) -#endif - ); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, &ResourceMessageFilter::Send, reply_msg)); -} - void ResourceMessageFilter::OnKeygen(uint32 key_size_index, const std::string& challenge_string, const GURL& url, diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index ca4b920..7c46541 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -37,6 +37,7 @@ class ChromeURLRequestContext; class DatabaseDispatcherHost; class DOMStorageDispatcherHost; class FileSystemDispatcherHost; +class FileUtilitiesDispatcherHost; struct FontDescriptor; class GeolocationDispatcherHost; class HostZoomMap; @@ -130,8 +131,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, private: friend class BrowserThread; friend class DeleteTask<ResourceMessageFilter>; - typedef void (*FileInfoWriteFunc)(IPC::Message* reply_msg, - const base::PlatformFileInfo& file_info); virtual ~ResourceMessageFilter(); @@ -357,15 +356,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, double expected_response_time, const std::vector<char>& data); void OnEnableSpdy(bool enable); - void OnGetFileSize(const FilePath& path, IPC::Message* reply_msg); - void OnGetFileModificationTime(const FilePath& path, IPC::Message* reply_msg); - void OnGetFileInfoOnFileThread(const FilePath& path, - IPC::Message* reply_msg, - FileInfoWriteFunc write_func); - void OnOpenFile(const FilePath& path, int mode,IPC::Message* reply_msg); - void OnOpenFileOnFileThread(const FilePath& path, - int mode, - IPC::Message* reply_msg); void OnKeygen(uint32 key_size_index, const std::string& challenge_string, const GURL& url, IPC::Message* reply_msg); void OnKeygenOnWorkerThread( @@ -505,6 +495,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // Handles blob related messages. scoped_ptr<BlobDispatcherHost> blob_dispatcher_host_; + // Handles file utilities messages. + scoped_refptr<FileUtilitiesDispatcherHost> file_utilities_dispatcher_host_; + DISALLOW_COPY_AND_ASSIGN(ResourceMessageFilter); }; diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index 35ffd74..7fe1c53 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -21,6 +21,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/blob_dispatcher_host.h" #include "chrome/browser/renderer_host/database_dispatcher_host.h" +#include "chrome/browser/renderer_host/file_utilities_dispatcher_host.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/resource_message_filter.h" @@ -33,6 +34,7 @@ #include "chrome/common/render_messages_params.h" #include "chrome/common/result_codes.h" #include "chrome/common/worker_messages.h" +#include "net/base/mime_util.h" #include "ipc/ipc_switches.h" #include "net/base/registry_controlled_domain.h" @@ -70,7 +72,9 @@ WorkerProcessHost::WorkerProcessHost( new BlobDispatcherHost( this->id(), request_context->blob_storage_context()))), ALLOW_THIS_IN_INITIALIZER_LIST(file_system_dispatcher_host_( - new FileSystemDispatcherHost(this, request_context))) { + new FileSystemDispatcherHost(this, request_context))), + ALLOW_THIS_IN_INITIALIZER_LIST(file_utilities_dispatcher_host_( + new FileUtilitiesDispatcherHost(this, this->id()))) { next_route_id_callback_.reset(NewCallbackWithReturnValue( WorkerService::GetInstance(), &WorkerService::next_worker_route_id)); db_dispatcher_host_ = new DatabaseDispatcherHost( @@ -89,6 +93,9 @@ WorkerProcessHost::~WorkerProcessHost() { // Shut down the file system dispatcher host. file_system_dispatcher_host_->Shutdown(); + // Shut down the file utilities dispatcher host. + file_utilities_dispatcher_host_->Shutdown(); + // Let interested observers know we are being deleted. NotificationService::current()->Notify( NotificationType::WORKER_PROCESS_HOST_SHUTDOWN, @@ -249,6 +256,7 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { db_dispatcher_host_->OnMessageReceived(message, &msg_is_ok) || blob_dispatcher_host_->OnMessageReceived(message, &msg_is_ok) || file_system_dispatcher_host_->OnMessageReceived(message, &msg_is_ok) || + file_utilities_dispatcher_host_->OnMessageReceived(message, &msg_is_ok) || MessagePortDispatcher::GetInstance()->OnMessageReceived( message, this, next_route_id_callback_.get(), &msg_is_ok); @@ -263,6 +271,12 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { OnWorkerContextClosed); IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, OnForwardToWorker) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromExtension, + OnGetMimeTypeFromExtension) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromFile, + OnGetMimeTypeFromFile) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetPreferredExtensionForMimeType, + OnGetPreferredExtensionForMimeType) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() } @@ -298,6 +312,7 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { void WorkerProcessHost::OnProcessLaunched() { db_dispatcher_host_->Init(handle()); file_system_dispatcher_host_->Init(handle()); + file_utilities_dispatcher_host_->Init(handle()); } CallbackWithReturnValue<int>::Type* WorkerProcessHost::GetNextRouteIdCallback( @@ -487,6 +502,21 @@ void WorkerProcessHost::OnForwardToWorker(const IPC::Message& message) { WorkerService::GetInstance()->ForwardMessage(message, this); } +void WorkerProcessHost::OnGetMimeTypeFromExtension( + const FilePath::StringType& ext, std::string* mime_type) { + net::GetMimeTypeFromExtension(ext, mime_type); +} + +void WorkerProcessHost::OnGetMimeTypeFromFile( + const FilePath& file_path, std::string* mime_type) { + net::GetMimeTypeFromFile(file_path, mime_type); +} + +void WorkerProcessHost::OnGetPreferredExtensionForMimeType( + const std::string& mime_type, FilePath::StringType* ext) { + net::GetPreferredExtensionForMimeType(mime_type, ext); +} + void WorkerProcessHost::DocumentDetached(IPC::Message::Sender* parent, unsigned long long document_id) { // Walk all instances and remove the document from their document set. diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h index 0bdc4ef..3331586 100644 --- a/chrome/browser/worker_host/worker_process_host.h +++ b/chrome/browser/worker_host/worker_process_host.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/callback.h" +#include "base/file_path.h" #include "base/ref_counted.h" #include "chrome/browser/browser_child_process_host.h" #include "chrome/browser/net/chrome_url_request_context.h" @@ -23,6 +24,7 @@ class ChromeURLRequestContext; class ChromeURLRequestContextGetter; class DatabaseDispatcherHost; class FileSystemDispatcherHost; +class FileUtilitiesDispatcherHost; namespace webkit_database { class DatabaseTracker; } // namespace webkit_database @@ -192,6 +194,13 @@ class WorkerProcessHost : public BrowserChildProcessHost { void OnCancelCreateDedicatedWorker(int route_id); void OnForwardToWorker(const IPC::Message& message); + void OnGetMimeTypeFromExtension( + const FilePath::StringType& ext, std::string* mime_type); + void OnGetMimeTypeFromFile( + const FilePath& file_path, std::string* mime_type); + void OnGetPreferredExtensionForMimeType( + const std::string& mime_type, FilePath::StringType* ext); + Instances instances_; scoped_refptr<ChromeURLRequestContext> request_context_; @@ -199,6 +208,7 @@ class WorkerProcessHost : public BrowserChildProcessHost { scoped_refptr<DatabaseDispatcherHost> db_dispatcher_host_; scoped_ptr<BlobDispatcherHost> blob_dispatcher_host_; scoped_refptr<FileSystemDispatcherHost> file_system_dispatcher_host_; + scoped_refptr<FileUtilitiesDispatcherHost> file_utilities_dispatcher_host_; // A callback to create a routing id for the associated worker process. scoped_ptr<CallbackWithReturnValue<int>::Type> next_route_id_callback_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 3064c27..29ea45f 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2467,6 +2467,8 @@ 'browser/renderer_host/download_resource_handler.h', 'browser/renderer_host/download_throttling_resource_handler.cc', 'browser/renderer_host/download_throttling_resource_handler.h', + 'browser/renderer_host/file_utilities_dispatcher_host.cc', + 'browser/renderer_host/file_utilities_dispatcher_host.h', 'browser/renderer_host/global_request_id.h', 'browser/renderer_host/gpu_view_host.cc', 'browser/renderer_host/gpu_view_host.h', diff --git a/chrome/renderer/renderer_webkitclient_impl.cc b/chrome/renderer/renderer_webkitclient_impl.cc index 8909582..c681bc2 100644 --- a/chrome/renderer/renderer_webkitclient_impl.cc +++ b/chrome/renderer/renderer_webkitclient_impl.cc @@ -127,12 +127,10 @@ class RendererWebKitClientImpl::SandboxSupport RendererWebKitClientImpl::RendererWebKitClientImpl() : clipboard_(new webkit_glue::WebClipboardImpl), - file_utilities_(new RendererWebKitClientImpl::FileUtilities), mime_registry_(new RendererWebKitClientImpl::MimeRegistry), sandbox_support_(new RendererWebKitClientImpl::SandboxSupport), sudden_termination_disables_(0), shared_worker_repository_(new WebSharedWorkerRepositoryImpl) { - file_utilities_->set_sandbox_enabled(sandboxEnabled()); } RendererWebKitClientImpl::~RendererWebKitClientImpl() { @@ -149,6 +147,10 @@ WebKit::WebMimeRegistry* RendererWebKitClientImpl::mimeRegistry() { } WebKit::WebFileUtilities* RendererWebKitClientImpl::fileUtilities() { + if (!file_utilities_.get()) { + file_utilities_.reset(new FileUtilities); + file_utilities_->set_sandbox_enabled(sandboxEnabled()); + } return file_utilities_.get(); } diff --git a/chrome/worker/worker_webkitclient_impl.cc b/chrome/worker/worker_webkitclient_impl.cc index 1645fa8..1f74232 100644 --- a/chrome/worker/worker_webkitclient_impl.cc +++ b/chrome/worker/worker_webkitclient_impl.cc @@ -5,6 +5,7 @@ #include "chrome/worker/worker_webkitclient_impl.h" #include "base/logging.h" +#include "base/utf_string_conversions.h" #include "chrome/common/database_util.h" #include "chrome/common/file_system/webfilesystem_impl.h" #include "chrome/common/render_messages.h" @@ -12,13 +13,17 @@ #include "chrome/common/webblobregistry_impl.h" #include "chrome/common/webmessageportchannel_impl.h" #include "chrome/worker/worker_thread.h" +#include "ipc/ipc_sync_message_filter.h" #include "third_party/WebKit/WebKit/chromium/public/WebBlobRegistry.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" +#include "webkit/glue/webfileutilities_impl.h" +#include "webkit/glue/webkit_glue.h" using WebKit::WebBlobRegistry; using WebKit::WebClipboard; using WebKit::WebFileSystem; +using WebKit::WebFileUtilities; using WebKit::WebKitClient; using WebKit::WebMessagePortChannel; using WebKit::WebMimeRegistry; @@ -28,6 +33,54 @@ using WebKit::WebStorageNamespace; using WebKit::WebString; using WebKit::WebURL; +// TODO(kinuko): Probably this could be consolidated into +// RendererWebKitClientImpl::FileUtilities. +class WorkerWebKitClientImpl::FileUtilities + : public webkit_glue::WebFileUtilitiesImpl { + public: + virtual bool getFileSize(const WebKit::WebString& path, long long& result); + virtual bool getFileModificationTime(const WebKit::WebString& path, + double& result); +}; + +static bool SendSyncMessageFromAnyThread(IPC::SyncMessage* msg) { + WorkerThread* worker_thread = WorkerThread::current(); + if (worker_thread) + return worker_thread->Send(msg); + + scoped_refptr<IPC::SyncMessageFilter> sync_msg_filter = + ChildThread::current()->sync_message_filter(); + return sync_msg_filter->Send(msg); +} + +bool WorkerWebKitClientImpl::FileUtilities::getFileSize(const WebString& path, + long long& result) { + if (SendSyncMessageFromAnyThread(new ViewHostMsg_GetFileSize( + webkit_glue::WebStringToFilePath(path), + reinterpret_cast<int64*>(&result)))) { + return result >= 0; + } + + result = -1; + return false; +} + +bool WorkerWebKitClientImpl::FileUtilities::getFileModificationTime( + const WebString& path, + double& result) { + base::Time time; + if (SendSyncMessageFromAnyThread(new ViewHostMsg_GetFileModificationTime( + webkit_glue::WebStringToFilePath(path), &time))) { + result = time.ToDoubleT(); + return !time.is_null(); + } + + result = 0; + return false; +} + +//------------------------------------------------------------------------------ + WorkerWebKitClientImpl::WorkerWebKitClientImpl() { } @@ -43,14 +96,18 @@ WebMimeRegistry* WorkerWebKitClientImpl::mimeRegistry() { return this; } -WebKit::WebFileSystem* WorkerWebKitClientImpl::fileSystem() { +WebFileSystem* WorkerWebKitClientImpl::fileSystem() { if (!web_file_system_.get()) web_file_system_.reset(new WebFileSystemImpl()); return web_file_system_.get(); } -WebKit::WebFileUtilities* WorkerWebKitClientImpl::fileUtilities() { - return &file_utilities_; +WebFileUtilities* WorkerWebKitClientImpl::fileUtilities() { + if (!file_utilities_.get()) { + file_utilities_.reset(new FileUtilities); + file_utilities_->set_sandbox_enabled(sandboxEnabled()); + } + return file_utilities_.get(); } WebSandboxSupport* WorkerWebKitClientImpl::sandboxSupport() { @@ -97,12 +154,6 @@ void WorkerWebKitClientImpl::prefetchHostName(const WebString&) { NOTREACHED(); } -bool WorkerWebKitClientImpl::getFileSize(const WebString& path, - long long& result) { - NOTREACHED(); - return false; -} - WebString WorkerWebKitClientImpl::defaultLocale() { NOTREACHED(); return WebString(); @@ -174,20 +225,30 @@ WebMimeRegistry::SupportsType WorkerWebKitClientImpl::supportsNonImageMIMEType( return WebMimeRegistry::IsSupported; } -WebString WorkerWebKitClientImpl::mimeTypeForExtension(const WebString&) { - NOTREACHED(); - return WebString(); +WebString WorkerWebKitClientImpl::mimeTypeForExtension( + const WebString& file_extension) { + std::string mime_type; + WorkerThread::current()->Send(new ViewHostMsg_GetMimeTypeFromExtension( + webkit_glue::WebStringToFilePathString(file_extension), &mime_type)); + return ASCIIToUTF16(mime_type); } -WebString WorkerWebKitClientImpl::mimeTypeFromFile(const WebString&) { - NOTREACHED(); - return WebString(); +WebString WorkerWebKitClientImpl::mimeTypeFromFile( + const WebString& file_path) { + std::string mime_type; + WorkerThread::current()->Send(new ViewHostMsg_GetMimeTypeFromFile( + FilePath(webkit_glue::WebStringToFilePathString(file_path)), + &mime_type)); + return ASCIIToUTF16(mime_type); } WebString WorkerWebKitClientImpl::preferredExtensionForMIMEType( - const WebString&) { - NOTREACHED(); - return WebString(); + const WebString& mime_type) { + FilePath::StringType file_extension; + WorkerThread::current()->Send( + new ViewHostMsg_GetPreferredExtensionForMimeType(UTF16ToASCII(mime_type), + &file_extension)); + return webkit_glue::FilePathStringToWebString(file_extension); } WebBlobRegistry* WorkerWebKitClientImpl::blobRegistry() { diff --git a/chrome/worker/worker_webkitclient_impl.h b/chrome/worker/worker_webkitclient_impl.h index e5b3ec6..df98e7d 100644 --- a/chrome/worker/worker_webkitclient_impl.h +++ b/chrome/worker/worker_webkitclient_impl.h @@ -8,11 +8,14 @@ #include "base/scoped_ptr.h" #include "third_party/WebKit/WebKit/chromium/public/WebMimeRegistry.h" -#include "webkit/glue/webfileutilities_impl.h" #include "webkit/glue/webkitclient_impl.h" class WebFileSystemImpl; +namespace WebKit { +class WebFileUtilities; +} + class WorkerWebKitClientImpl : public webkit_glue::WebKitClientImpl, public WebKit::WebMimeRegistry { public: @@ -37,7 +40,6 @@ class WorkerWebKitClientImpl : public webkit_glue::WebKitClientImpl, const WebKit::WebURL& url, const WebKit::WebURL& first_party_for_cookies); virtual void prefetchHostName(const WebKit::WebString&); - virtual bool getFileSize(const WebKit::WebString& path, long long& result); virtual WebKit::WebString defaultLocale(); virtual WebKit::WebStorageNamespace* createLocalStorageNamespace( const WebKit::WebString& path, unsigned quota); @@ -75,7 +77,9 @@ class WorkerWebKitClientImpl : public webkit_glue::WebKitClientImpl, const WebKit::WebString&); private: - webkit_glue::WebFileUtilitiesImpl file_utilities_; + + class FileUtilities; + scoped_ptr<FileUtilities> file_utilities_; scoped_ptr<WebKit::WebBlobRegistry> blob_registry_; |