From 2aba99da8333d9fe2df2b1bea3bbd0cef5ed5079 Mon Sep 17 00:00:00 2001 From: "tzik@chromium.org" Date: Wed, 29 Feb 2012 08:13:32 +0000 Subject: Merge BlobMessageFilter and FileSystemDispatcherHost into FileAndBlobMessageFilter. So that we can handle files and blobs in a unified way. BUG=115603 TEST="existing tests should pass" Review URL: http://codereview.chromium.org/9514010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124152 0039d316-1c4b-4281-b951-d872f2087c98 --- .../file_system/file_and_blob_message_filter.cc | 525 +++++++++++++++++++++ .../file_system/file_and_blob_message_filter.h | 177 +++++++ .../file_system/file_system_dispatcher_host.cc | 454 ------------------ .../file_system/file_system_dispatcher_host.h | 164 ------- .../browser/renderer_host/blob_message_filter.cc | 111 ----- .../browser/renderer_host/blob_message_filter.h | 51 -- .../renderer_host/render_process_host_impl.cc | 8 +- content/browser/worker_host/worker_process_host.cc | 10 +- 8 files changed, 708 insertions(+), 792 deletions(-) create mode 100644 content/browser/file_system/file_and_blob_message_filter.cc create mode 100644 content/browser/file_system/file_and_blob_message_filter.h delete mode 100644 content/browser/file_system/file_system_dispatcher_host.cc delete mode 100644 content/browser/file_system/file_system_dispatcher_host.h delete mode 100644 content/browser/renderer_host/blob_message_filter.cc delete mode 100644 content/browser/renderer_host/blob_message_filter.h (limited to 'content/browser') diff --git a/content/browser/file_system/file_and_blob_message_filter.cc b/content/browser/file_system/file_and_blob_message_filter.cc new file mode 100644 index 0000000..c05f645 --- /dev/null +++ b/content/browser/file_system/file_and_blob_message_filter.cc @@ -0,0 +1,525 @@ +// Copyright (c) 2012 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 "content/browser/file_system/file_and_blob_message_filter.h" + +#include +#include + +#include "base/bind.h" +#include "base/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/platform_file.h" +#include "base/threading/thread.h" +#include "base/time.h" +#include "content/browser/child_process_security_policy_impl.h" +#include "content/browser/chrome_blob_storage_context.h" +#include "content/common/file_system_messages.h" +#include "content/common/webblob_messages.h" +#include "content/public/browser/user_metrics.h" +#include "googleurl/src/gurl.h" +#include "ipc/ipc_platform_file.h" +#include "net/base/mime_util.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" +#include "webkit/blob/blob_data.h" +#include "webkit/blob/blob_storage_controller.h" +#include "webkit/blob/deletable_file_reference.h" +#include "webkit/fileapi/file_system_context.h" +#include "webkit/fileapi/file_system_operation.h" +#include "webkit/fileapi/file_system_quota_util.h" +#include "webkit/fileapi/file_system_util.h" +#include "webkit/fileapi/sandbox_mount_point_provider.h" + +using content::BrowserMessageFilter; +using content::BrowserThread; +using content::UserMetricsAction; +using fileapi::FileSystemFileUtil; +using fileapi::FileSystemOperation; +using fileapi::FileSystemOperationInterface; +using webkit_blob::BlobData; +using webkit_blob::BlobStorageController; + +FileAndBlobMessageFilter::FileAndBlobMessageFilter( + int process_id, + net::URLRequestContextGetter* request_context_getter, + fileapi::FileSystemContext* file_system_context, + ChromeBlobStorageContext* blob_storage_context) + : process_id_(process_id), + context_(file_system_context), + request_context_getter_(request_context_getter), + request_context_(NULL), + blob_storage_context_(blob_storage_context) { + DCHECK(context_); + DCHECK(request_context_getter_); + DCHECK(blob_storage_context); +} + +FileAndBlobMessageFilter::FileAndBlobMessageFilter( + int process_id, + net::URLRequestContext* request_context, + fileapi::FileSystemContext* file_system_context, + ChromeBlobStorageContext* blob_storage_context) + : process_id_(process_id), + context_(file_system_context), + request_context_(request_context), + blob_storage_context_(blob_storage_context) { + DCHECK(context_); + DCHECK(request_context_); + DCHECK(blob_storage_context); +} + +FileAndBlobMessageFilter::~FileAndBlobMessageFilter() { +} + +void FileAndBlobMessageFilter::OnChannelConnected(int32 peer_pid) { + BrowserMessageFilter::OnChannelConnected(peer_pid); + + if (request_context_getter_.get()) { + DCHECK(!request_context_); + request_context_ = request_context_getter_->GetURLRequestContext(); + request_context_getter_ = NULL; + DCHECK(request_context_); + } +} + +void FileAndBlobMessageFilter::OnChannelClosing() { + BrowserMessageFilter::OnChannelClosing(); + + // Unregister all the blob URLs that are previously registered in this + // process. + for (base::hash_set::const_iterator iter = blob_urls_.begin(); + iter != blob_urls_.end(); ++iter) { + blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); + } +} + +void FileAndBlobMessageFilter::OverrideThreadForMessage( + const IPC::Message& message, + BrowserThread::ID* thread) { + if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID) + *thread = BrowserThread::FILE; +} + +bool FileAndBlobMessageFilter::OnMessageReceived( + const IPC::Message& message, bool* message_was_ok) { + *message_was_ok = true; + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(FileAndBlobMessageFilter, message, *message_was_ok) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Open, OnOpen) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Move, OnMove) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Copy, OnCopy) + IPC_MESSAGE_HANDLER(FileSystemMsg_Remove, OnRemove) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadMetadata, OnReadMetadata) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Create, OnCreate) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, + OnCreateSnapshotFile) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) + IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, + OnSyncGetPlatformPath) + IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) + IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) + IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, + OnAppendSharedMemory) + IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) + IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) + IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP_EX() + return handled; +} + +void FileAndBlobMessageFilter::OnOpen( + int request_id, const GURL& origin_url, fileapi::FileSystemType type, + int64 requested_size, bool create) { + if (type == fileapi::kFileSystemTypeTemporary) { + content::RecordAction(UserMetricsAction("OpenFileSystemTemporary")); + } else if (type == fileapi::kFileSystemTypePersistent) { + content::RecordAction(UserMetricsAction("OpenFileSystemPersistent")); + } + context_->OpenFileSystem(origin_url, type, create, base::Bind( + &FileAndBlobMessageFilter::DidOpenFileSystem, this, request_id)); +} + +void FileAndBlobMessageFilter::OnMove( + int request_id, const GURL& src_path, const GURL& dest_path) { + GetNewOperation(src_path, request_id)->Move( + src_path, dest_path, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); +} + +void FileAndBlobMessageFilter::OnCopy( + int request_id, const GURL& src_path, const GURL& dest_path) { + GetNewOperation(src_path, request_id)->Copy( + src_path, dest_path, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); +} + +void FileAndBlobMessageFilter::OnRemove( + int request_id, const GURL& path, bool recursive) { + GetNewOperation(path, request_id)->Remove( + path, recursive, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); +} + +void FileAndBlobMessageFilter::OnReadMetadata( + int request_id, const GURL& path) { + GetNewOperation(path, request_id)->GetMetadata( + path, + base::Bind(&FileAndBlobMessageFilter::DidGetMetadata, this, request_id)); +} + +void FileAndBlobMessageFilter::OnCreate( + int request_id, const GURL& path, bool exclusive, + bool is_directory, bool recursive) { + if (is_directory) { + GetNewOperation(path, request_id)->CreateDirectory( + path, exclusive, recursive, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); + } else { + GetNewOperation(path, request_id)->CreateFile( + path, exclusive, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); + } +} + +void FileAndBlobMessageFilter::OnExists( + int request_id, const GURL& path, bool is_directory) { + if (is_directory) { + GetNewOperation(path, request_id)->DirectoryExists( + path, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); + } else { + GetNewOperation(path, request_id)->FileExists( + path, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); + } +} + +void FileAndBlobMessageFilter::OnReadDirectory( + int request_id, const GURL& path) { + GetNewOperation(path, request_id)->ReadDirectory( + path, base::Bind(&FileAndBlobMessageFilter::DidReadDirectory, + this, request_id)); +} + +void FileAndBlobMessageFilter::OnWrite( + int request_id, + const GURL& path, + const GURL& blob_url, + int64 offset) { + if (!request_context_) { + // We can't write w/o a request context, trying to do so will crash. + NOTREACHED(); + return; + } + GetNewOperation(path, request_id)->Write( + request_context_, path, blob_url, offset, + base::Bind(&FileAndBlobMessageFilter::DidWrite, this, request_id)); +} + +void FileAndBlobMessageFilter::OnTruncate( + int request_id, + const GURL& path, + int64 length) { + GetNewOperation(path, request_id)->Truncate( + path, length, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); +} + +void FileAndBlobMessageFilter::OnTouchFile( + int request_id, + const GURL& path, + const base::Time& last_access_time, + const base::Time& last_modified_time) { + GetNewOperation(path, request_id)->TouchFile( + path, last_access_time, last_modified_time, + base::Bind(&FileAndBlobMessageFilter::DidFinish, this, request_id)); +} + +void FileAndBlobMessageFilter::OnCancel( + int request_id, + int request_id_to_cancel) { + FileSystemOperationInterface* write = operations_.Lookup( + request_id_to_cancel); + if (write) { + // The cancel will eventually send both the write failure and the cancel + // success. + write->Cancel( + base::Bind(&FileAndBlobMessageFilter::DidCancel, this, request_id)); + } else { + // The write already finished; report that we failed to stop it. + Send(new FileSystemMsg_DidFail( + request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); + } +} + +void FileAndBlobMessageFilter::OnOpenFile( + int request_id, const GURL& path, int file_flags) { + GetNewOperation(path, request_id)->OpenFile( + path, file_flags, peer_handle(), + base::Bind(&FileAndBlobMessageFilter::DidOpenFile, this, request_id)); +} + +void FileAndBlobMessageFilter::OnWillUpdate(const GURL& path) { + GURL origin_url; + fileapi::FileSystemType type; + if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) + return; + fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); + if (!quota_util) + return; + quota_util->proxy()->StartUpdateOrigin(origin_url, type); +} + +void FileAndBlobMessageFilter::OnDidUpdate(const GURL& path, int64 delta) { + GURL origin_url; + fileapi::FileSystemType type; + if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) + return; + fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); + if (!quota_util) + return; + quota_util->proxy()->UpdateOriginUsage( + context_->quota_manager_proxy(), origin_url, type, delta); + quota_util->proxy()->EndUpdateOrigin(origin_url, type); +} + +void FileAndBlobMessageFilter::OnSyncGetPlatformPath( + const GURL& path, FilePath* platform_path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(platform_path); + *platform_path = FilePath(); + + GURL origin_url; + fileapi::FileSystemType file_system_type = fileapi::kFileSystemTypeUnknown; + FilePath file_path; + if (!fileapi::CrackFileSystemURL( + path, &origin_url, &file_system_type, &file_path)) { + return; + } + + // This is called only by pepper plugin as of writing to get the + // underlying platform path to upload a file in the sandboxed filesystem + // (e.g. TEMPORARY or PERSISTENT). + // TODO(kinuko): this hack should go away once appropriate upload-stream + // handling based on element types is supported. + FileSystemOperation* operation = + context_->CreateFileSystemOperation( + path, + BrowserThread::GetMessageLoopProxyForThread( + BrowserThread::FILE))->AsFileSystemOperation(); + DCHECK(operation); + operation->SyncGetPlatformPath(path, platform_path); +} + +void FileAndBlobMessageFilter::OnCreateSnapshotFile( + int request_id, const GURL& blob_url, const GURL& path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + GetNewOperation(path, request_id)->CreateSnapshotFile( + path, + base::Bind(&FileAndBlobMessageFilter::DidCreateSnapshot, + this, request_id, blob_url)); +} + +void FileAndBlobMessageFilter::OnStartBuildingBlob(const GURL& url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + blob_storage_context_->controller()->StartBuildingBlob(url); + blob_urls_.insert(url.spec()); +} + +void FileAndBlobMessageFilter::OnAppendBlobDataItem( + const GURL& url, const BlobData::Item& item) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (item.type == BlobData::TYPE_FILE && + !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( + process_id_, item.file_path)) { + OnRemoveBlob(url); + return; + } + blob_storage_context_->controller()->AppendBlobDataItem(url, item); +} + +void FileAndBlobMessageFilter::OnAppendSharedMemory( + const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { + DCHECK(base::SharedMemory::IsHandleValid(handle)); +#if defined(OS_WIN) + base::SharedMemory shared_memory(handle, true, peer_handle()); +#else + base::SharedMemory shared_memory(handle, true); +#endif + if (!shared_memory.Map(buffer_size)) { + OnRemoveBlob(url); + return; + } + + BlobData::Item item; + item.SetToDataExternal(static_cast(shared_memory.memory()), + buffer_size); + blob_storage_context_->controller()->AppendBlobDataItem(url, item); +} + +void FileAndBlobMessageFilter::OnFinishBuildingBlob( + const GURL& url, const std::string& content_type) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); +} + +void FileAndBlobMessageFilter::OnCloneBlob( + const GURL& url, const GURL& src_url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + blob_storage_context_->controller()->CloneBlob(url, src_url); + blob_urls_.insert(url.spec()); +} + +void FileAndBlobMessageFilter::OnRemoveBlob(const GURL& url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + blob_storage_context_->controller()->RemoveBlob(url); + blob_urls_.erase(url.spec()); +} + +void FileAndBlobMessageFilter::DidFinish(int request_id, + base::PlatformFileError result) { + if (result == base::PLATFORM_FILE_OK) + Send(new FileSystemMsg_DidSucceed(request_id)); + else + Send(new FileSystemMsg_DidFail(request_id, result)); + UnregisterOperation(request_id); +} + +void FileAndBlobMessageFilter::DidCancel(int request_id, + base::PlatformFileError result) { + if (result == base::PLATFORM_FILE_OK) + Send(new FileSystemMsg_DidSucceed(request_id)); + else + Send(new FileSystemMsg_DidFail(request_id, result)); + // For Cancel we do not create a new operation, so no unregister here. +} + +void FileAndBlobMessageFilter::DidGetMetadata( + int request_id, + base::PlatformFileError result, + const base::PlatformFileInfo& info, + const FilePath& platform_path) { + if (result == base::PLATFORM_FILE_OK) + Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); + else + Send(new FileSystemMsg_DidFail(request_id, result)); + UnregisterOperation(request_id); +} + +void FileAndBlobMessageFilter::DidReadDirectory( + int request_id, + base::PlatformFileError result, + const std::vector& entries, + bool has_more) { + if (result == base::PLATFORM_FILE_OK) + Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more)); + else + Send(new FileSystemMsg_DidFail(request_id, result)); + UnregisterOperation(request_id); +} + +void FileAndBlobMessageFilter::DidOpenFile(int request_id, + base::PlatformFileError result, + base::PlatformFile file, + base::ProcessHandle peer_handle) { + if (result == base::PLATFORM_FILE_OK) { + IPC::PlatformFileForTransit file_for_transit = + file != base::kInvalidPlatformFileValue ? + IPC::GetFileHandleForProcess(file, peer_handle, true) : + IPC::InvalidPlatformFileForTransit(); + Send(new FileSystemMsg_DidOpenFile(request_id, file_for_transit)); + } else { + Send(new FileSystemMsg_DidFail(request_id, result)); + } + UnregisterOperation(request_id); +} + +void FileAndBlobMessageFilter::DidWrite(int request_id, + base::PlatformFileError result, + int64 bytes, + bool complete) { + if (result == base::PLATFORM_FILE_OK) { + Send(new FileSystemMsg_DidWrite(request_id, bytes, complete)); + if (complete) + UnregisterOperation(request_id); + } else { + Send(new FileSystemMsg_DidFail(request_id, result)); + UnregisterOperation(request_id); + } +} + +void FileAndBlobMessageFilter::DidOpenFileSystem(int request_id, + base::PlatformFileError result, + const std::string& name, + const GURL& root) { + if (result == base::PLATFORM_FILE_OK) { + DCHECK(root.is_valid()); + Send(new FileSystemMsg_DidOpenFileSystem(request_id, name, root)); + } else { + Send(new FileSystemMsg_DidFail(request_id, result)); + } + // For OpenFileSystem we do not create a new operation, so no unregister here. +} + +void FileAndBlobMessageFilter::DidCreateSnapshot( + int request_id, + const GURL& blob_url, + base::PlatformFileError result, + const base::PlatformFileInfo& info, + const FilePath& platform_path, + const scoped_refptr& unused) { + if (result != base::PLATFORM_FILE_OK) { + Send(new FileSystemMsg_DidFail(request_id, result)); + return; + } + + FilePath::StringType extension = platform_path.Extension(); + if (!extension.empty()) + extension = extension.substr(1); // Strip leading ".". + + // This may fail, but then we'll be just setting the empty mime type. + std::string mime_type; + net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); + + // Register the created file to the blob registry. + // Blob storage automatically finds and refs deletable files, so we don't + // need to do anything for the returned file reference (|unused|) here. + BlobData::Item item; + item.SetToFile(platform_path, 0, -1, base::Time()); + BlobStorageController* controller = blob_storage_context_->controller(); + controller->StartBuildingBlob(blob_url); + controller->AppendBlobDataItem(blob_url, item); + controller->FinishBuildingBlob(blob_url, mime_type); + blob_urls_.insert(blob_url.spec()); + + // Return the file info and platform_path. + Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); +} + +FileSystemOperationInterface* FileAndBlobMessageFilter::GetNewOperation( + const GURL& target_path, + int request_id) { + FileSystemOperationInterface* operation = + context_->CreateFileSystemOperation( + target_path, + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); + DCHECK(operation); + operations_.AddWithID(operation, request_id); + return operation; +} + +void FileAndBlobMessageFilter::UnregisterOperation(int request_id) { + DCHECK(operations_.Lookup(request_id)); + operations_.Remove(request_id); +} diff --git a/content/browser/file_system/file_and_blob_message_filter.h b/content/browser/file_system/file_and_blob_message_filter.h new file mode 100644 index 0000000..fb347ac --- /dev/null +++ b/content/browser/file_system/file_and_blob_message_filter.h @@ -0,0 +1,177 @@ +// Copyright (c) 2012 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 CONTENT_BROWSER_FILE_SYSTEM_FILE_AND_BLOB_MESSAGE_FILTER_H_ +#define CONTENT_BROWSER_FILE_SYSTEM_FILE_AND_BLOB_MESSAGE_FILTER_H_ + +#include + +#include "base/basictypes.h" +#include "base/file_util_proxy.h" +#include "base/hash_tables.h" +#include "base/id_map.h" +#include "base/platform_file.h" +#include "base/shared_memory.h" +#include "content/public/browser/browser_message_filter.h" +#include "webkit/blob/blob_data.h" +#include "webkit/fileapi/file_system_types.h" + +class ChromeBlobStorageContext; +class FilePath; +class GURL; + +namespace base { +class Time; +} + +namespace fileapi { +class FileSystemContext; +class FileSystemOperationInterface; +} + +namespace net { +class URLRequestContext; +class URLRequestContextGetter; +} // namespace net + +namespace webkit_blob { +class DeletableFileReference; +} + +class FileAndBlobMessageFilter : public content::BrowserMessageFilter { + public: + // Used by the renderer process host on the UI thread. + FileAndBlobMessageFilter( + int process_id, + net::URLRequestContextGetter* request_context_getter, + fileapi::FileSystemContext* file_system_context, + ChromeBlobStorageContext* blob_storage_context); + // Used by the worker process host on the IO thread. + FileAndBlobMessageFilter( + int process_id, + net::URLRequestContext* request_context, + fileapi::FileSystemContext* file_system_context, + ChromeBlobStorageContext* blob_storage_context); + virtual ~FileAndBlobMessageFilter(); + + // content::BrowserMessageFilter implementation. + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnChannelClosing() OVERRIDE; + virtual void OverrideThreadForMessage( + const IPC::Message& message, + content::BrowserThread::ID* thread) OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) OVERRIDE; + + void UnregisterOperation(int request_id); + + private: + void OnOpen(int request_id, + const GURL& origin_url, + fileapi::FileSystemType type, + int64 requested_size, + bool create); + void OnMove(int request_id, + const GURL& src_path, + const GURL& dest_path); + void OnCopy(int request_id, + const GURL& src_path, + const GURL& dest_path); + void OnRemove(int request_id, const GURL& path, bool recursive); + void OnReadMetadata(int request_id, const GURL& path); + void OnCreate(int request_id, + const GURL& path, + bool exclusive, + bool is_directory, + bool recursive); + void OnExists(int request_id, const GURL& path, bool is_directory); + void OnReadDirectory(int request_id, const GURL& path); + void OnWrite(int request_id, + const GURL& path, + const GURL& blob_url, + int64 offset); + void OnTruncate(int request_id, const GURL& path, int64 length); + void OnTouchFile(int request_id, + const GURL& path, + const base::Time& last_access_time, + const base::Time& last_modified_time); + void OnCancel(int request_id, int request_to_cancel); + void OnOpenFile(int request_id, const GURL& path, int file_flags); + void OnWillUpdate(const GURL& path); + void OnDidUpdate(const GURL& path, int64 delta); + void OnSyncGetPlatformPath(const GURL& path, + FilePath* platform_path); + void OnCreateSnapshotFile(int request_id, + const GURL& blob_url, + const GURL& path); + + void OnStartBuildingBlob(const GURL& url); + void OnAppendBlobDataItem(const GURL& url, + const webkit_blob::BlobData::Item& item); + void OnAppendSharedMemory(const GURL& url, base::SharedMemoryHandle handle, + size_t buffer_size); + void OnFinishBuildingBlob(const GURL& url, const std::string& content_type); + void OnCloneBlob(const GURL& url, const GURL& src_url); + void OnRemoveBlob(const GURL& url); + + // Callback functions to be used when each file operation is finished. + void DidFinish(int request_id, base::PlatformFileError result); + void DidCancel(int request_id, base::PlatformFileError result); + void DidGetMetadata(int request_id, + base::PlatformFileError result, + const base::PlatformFileInfo& info, + const FilePath& platform_path); + void DidReadDirectory(int request_id, + base::PlatformFileError result, + const std::vector& entries, + bool has_more); + void DidOpenFile(int request_id, + base::PlatformFileError result, + base::PlatformFile file, + base::ProcessHandle peer_handle); + void DidWrite(int request_id, + base::PlatformFileError result, + int64 bytes, + bool complete); + void DidOpenFileSystem(int request_id, + base::PlatformFileError result, + const std::string& name, + const GURL& root); + void DidCreateSnapshot( + int request_id, + const GURL& blob_url, + base::PlatformFileError result, + const base::PlatformFileInfo& info, + const FilePath& platform_path, + const scoped_refptr& + deletable_ref); + + // Creates a new FileSystemOperationInterface based on |target_path|. + fileapi::FileSystemOperationInterface* GetNewOperation( + const GURL& target_path, + int request_id); + + int process_id_; + + fileapi::FileSystemContext* context_; + + // Keeps ongoing file system operations. + typedef IDMap OperationsMap; + OperationsMap operations_; + + // The getter holds the context until Init() can be called from the + // IO thread, which will extract the net::URLRequestContext from it. + scoped_refptr request_context_getter_; + net::URLRequestContext* request_context_; + + scoped_refptr blob_storage_context_; + + // Keep track of blob URLs registered in this process. Need to unregister + // all of them when the renderer process dies. + base::hash_set blob_urls_; + + DISALLOW_COPY_AND_ASSIGN(FileAndBlobMessageFilter); +}; + +#endif // CONTENT_BROWSER_FILE_SYSTEM_FILE_AND_BLOB_MESSAGE_FILTER_H_ diff --git a/content/browser/file_system/file_system_dispatcher_host.cc b/content/browser/file_system/file_system_dispatcher_host.cc deleted file mode 100644 index d1f3119..0000000 --- a/content/browser/file_system/file_system_dispatcher_host.cc +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright (c) 2012 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 "content/browser/file_system/file_system_dispatcher_host.h" - -#include -#include - -#include "base/bind.h" -#include "base/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/platform_file.h" -#include "base/threading/thread.h" -#include "base/time.h" -#include "content/browser/chrome_blob_storage_context.h" -#include "content/common/file_system_messages.h" -#include "content/public/browser/user_metrics.h" -#include "googleurl/src/gurl.h" -#include "ipc/ipc_platform_file.h" -#include "net/base/mime_util.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" -#include "webkit/blob/blob_data.h" -#include "webkit/blob/blob_storage_controller.h" -#include "webkit/blob/deletable_file_reference.h" -#include "webkit/fileapi/file_system_context.h" -#include "webkit/fileapi/file_system_operation.h" -#include "webkit/fileapi/file_system_quota_util.h" -#include "webkit/fileapi/file_system_util.h" -#include "webkit/fileapi/sandbox_mount_point_provider.h" - -using content::BrowserMessageFilter; -using content::BrowserThread; -using content::UserMetricsAction; -using fileapi::FileSystemFileUtil; -using fileapi::FileSystemOperation; -using fileapi::FileSystemOperationInterface; -using webkit_blob::BlobData; -using webkit_blob::BlobStorageController; - -FileSystemDispatcherHost::FileSystemDispatcherHost( - net::URLRequestContextGetter* request_context_getter, - fileapi::FileSystemContext* file_system_context, - ChromeBlobStorageContext* blob_storage_context) - : context_(file_system_context), - request_context_getter_(request_context_getter), - request_context_(NULL), - blob_storage_context_(blob_storage_context) { - DCHECK(context_); - DCHECK(request_context_getter_); -} - -FileSystemDispatcherHost::FileSystemDispatcherHost( - net::URLRequestContext* request_context, - fileapi::FileSystemContext* file_system_context, - ChromeBlobStorageContext* blob_storage_context) - : context_(file_system_context), - request_context_(request_context), - blob_storage_context_(blob_storage_context) { - DCHECK(context_); - DCHECK(request_context_); -} - -FileSystemDispatcherHost::~FileSystemDispatcherHost() { -} - -void FileSystemDispatcherHost::OnChannelClosing() { - BrowserMessageFilter::OnChannelClosing(); - - // Unregister all the blob URLs that are previously registered in this - // process. - for (base::hash_set::const_iterator iter = blob_urls_.begin(); - iter != blob_urls_.end(); ++iter) { - blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); - } -} - -void FileSystemDispatcherHost::OnChannelConnected(int32 peer_pid) { - BrowserMessageFilter::OnChannelConnected(peer_pid); - - if (request_context_getter_.get()) { - DCHECK(!request_context_); - request_context_ = request_context_getter_->GetURLRequestContext(); - request_context_getter_ = NULL; - DCHECK(request_context_); - } -} - -void FileSystemDispatcherHost::OverrideThreadForMessage( - const IPC::Message& message, - BrowserThread::ID* thread) { - if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID) - *thread = BrowserThread::FILE; -} - -bool FileSystemDispatcherHost::OnMessageReceived( - const IPC::Message& message, bool* message_was_ok) { - *message_was_ok = true; - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_EX(FileSystemDispatcherHost, message, *message_was_ok) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Open, OnOpen) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Move, OnMove) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Copy, OnCopy) - IPC_MESSAGE_HANDLER(FileSystemMsg_Remove, OnRemove) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadMetadata, OnReadMetadata) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Create, OnCreate) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, - OnCreateSnapshotFile) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) - IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, - OnSyncGetPlatformPath) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP_EX() - return handled; -} - -void FileSystemDispatcherHost::OnOpen( - int request_id, const GURL& origin_url, fileapi::FileSystemType type, - int64 requested_size, bool create) { - if (type == fileapi::kFileSystemTypeTemporary) { - content::RecordAction(UserMetricsAction("OpenFileSystemTemporary")); - } else if (type == fileapi::kFileSystemTypePersistent) { - content::RecordAction(UserMetricsAction("OpenFileSystemPersistent")); - } - context_->OpenFileSystem(origin_url, type, create, base::Bind( - &FileSystemDispatcherHost::DidOpenFileSystem, this, request_id)); -} - -void FileSystemDispatcherHost::OnMove( - int request_id, const GURL& src_path, const GURL& dest_path) { - GetNewOperation(src_path, request_id)->Move( - src_path, dest_path, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); -} - -void FileSystemDispatcherHost::OnCopy( - int request_id, const GURL& src_path, const GURL& dest_path) { - GetNewOperation(src_path, request_id)->Copy( - src_path, dest_path, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); -} - -void FileSystemDispatcherHost::OnRemove( - int request_id, const GURL& path, bool recursive) { - GetNewOperation(path, request_id)->Remove( - path, recursive, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); -} - -void FileSystemDispatcherHost::OnReadMetadata( - int request_id, const GURL& path) { - GetNewOperation(path, request_id)->GetMetadata( - path, - base::Bind(&FileSystemDispatcherHost::DidGetMetadata, this, request_id)); -} - -void FileSystemDispatcherHost::OnCreate( - int request_id, const GURL& path, bool exclusive, - bool is_directory, bool recursive) { - if (is_directory) { - GetNewOperation(path, request_id)->CreateDirectory( - path, exclusive, recursive, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); - } else { - GetNewOperation(path, request_id)->CreateFile( - path, exclusive, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); - } -} - -void FileSystemDispatcherHost::OnExists( - int request_id, const GURL& path, bool is_directory) { - if (is_directory) { - GetNewOperation(path, request_id)->DirectoryExists( - path, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); - } else { - GetNewOperation(path, request_id)->FileExists( - path, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); - } -} - -void FileSystemDispatcherHost::OnReadDirectory( - int request_id, const GURL& path) { - GetNewOperation(path, request_id)->ReadDirectory( - path, base::Bind(&FileSystemDispatcherHost::DidReadDirectory, - this, request_id)); -} - -void FileSystemDispatcherHost::OnWrite( - int request_id, - const GURL& path, - const GURL& blob_url, - int64 offset) { - if (!request_context_) { - // We can't write w/o a request context, trying to do so will crash. - NOTREACHED(); - return; - } - GetNewOperation(path, request_id)->Write( - request_context_, path, blob_url, offset, - base::Bind(&FileSystemDispatcherHost::DidWrite, this, request_id)); -} - -void FileSystemDispatcherHost::OnTruncate( - int request_id, - const GURL& path, - int64 length) { - GetNewOperation(path, request_id)->Truncate( - path, length, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); -} - -void FileSystemDispatcherHost::OnTouchFile( - int request_id, - const GURL& path, - const base::Time& last_access_time, - const base::Time& last_modified_time) { - GetNewOperation(path, request_id)->TouchFile( - path, last_access_time, last_modified_time, - base::Bind(&FileSystemDispatcherHost::DidFinish, this, request_id)); -} - -void FileSystemDispatcherHost::OnCancel( - int request_id, - int request_id_to_cancel) { - FileSystemOperationInterface* write = operations_.Lookup( - request_id_to_cancel); - if (write) { - // The cancel will eventually send both the write failure and the cancel - // success. - write->Cancel( - base::Bind(&FileSystemDispatcherHost::DidCancel, this, request_id)); - } else { - // The write already finished; report that we failed to stop it. - Send(new FileSystemMsg_DidFail( - request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); - } -} - -void FileSystemDispatcherHost::OnOpenFile( - int request_id, const GURL& path, int file_flags) { - GetNewOperation(path, request_id)->OpenFile( - path, file_flags, peer_handle(), - base::Bind(&FileSystemDispatcherHost::DidOpenFile, this, request_id)); -} - -void FileSystemDispatcherHost::OnWillUpdate(const GURL& path) { - GURL origin_url; - fileapi::FileSystemType type; - if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) - return; - fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); - if (!quota_util) - return; - quota_util->proxy()->StartUpdateOrigin(origin_url, type); -} - -void FileSystemDispatcherHost::OnDidUpdate(const GURL& path, int64 delta) { - GURL origin_url; - fileapi::FileSystemType type; - if (!CrackFileSystemURL(path, &origin_url, &type, NULL)) - return; - fileapi::FileSystemQuotaUtil* quota_util = context_->GetQuotaUtil(type); - if (!quota_util) - return; - quota_util->proxy()->UpdateOriginUsage( - context_->quota_manager_proxy(), origin_url, type, delta); - quota_util->proxy()->EndUpdateOrigin(origin_url, type); -} - -void FileSystemDispatcherHost::OnSyncGetPlatformPath( - const GURL& path, FilePath* platform_path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - DCHECK(platform_path); - *platform_path = FilePath(); - - GURL origin_url; - fileapi::FileSystemType file_system_type = fileapi::kFileSystemTypeUnknown; - FilePath file_path; - if (!fileapi::CrackFileSystemURL( - path, &origin_url, &file_system_type, &file_path)) { - return; - } - - // This is called only by pepper plugin as of writing to get the - // underlying platform path to upload a file in the sandboxed filesystem - // (e.g. TEMPORARY or PERSISTENT). - // TODO(kinuko): this hack should go away once appropriate upload-stream - // handling based on element types is supported. - FileSystemOperation* operation = - context_->CreateFileSystemOperation( - path, - BrowserThread::GetMessageLoopProxyForThread( - BrowserThread::FILE))->AsFileSystemOperation(); - DCHECK(operation); - operation->SyncGetPlatformPath(path, platform_path); -} - -void FileSystemDispatcherHost::OnCreateSnapshotFile( - int request_id, const GURL& blob_url, const GURL& path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - GetNewOperation(path, request_id)->CreateSnapshotFile( - path, - base::Bind(&FileSystemDispatcherHost::DidCreateSnapshot, - this, request_id, blob_url)); -} - -void FileSystemDispatcherHost::DidFinish(int request_id, - base::PlatformFileError result) { - if (result == base::PLATFORM_FILE_OK) - Send(new FileSystemMsg_DidSucceed(request_id)); - else - Send(new FileSystemMsg_DidFail(request_id, result)); - UnregisterOperation(request_id); -} - -void FileSystemDispatcherHost::DidCancel(int request_id, - base::PlatformFileError result) { - if (result == base::PLATFORM_FILE_OK) - Send(new FileSystemMsg_DidSucceed(request_id)); - else - Send(new FileSystemMsg_DidFail(request_id, result)); - // For Cancel we do not create a new operation, so no unregister here. -} - -void FileSystemDispatcherHost::DidGetMetadata( - int request_id, - base::PlatformFileError result, - const base::PlatformFileInfo& info, - const FilePath& platform_path) { - if (result == base::PLATFORM_FILE_OK) - Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); - else - Send(new FileSystemMsg_DidFail(request_id, result)); - UnregisterOperation(request_id); -} - -void FileSystemDispatcherHost::DidReadDirectory( - int request_id, - base::PlatformFileError result, - const std::vector& entries, - bool has_more) { - if (result == base::PLATFORM_FILE_OK) - Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more)); - else - Send(new FileSystemMsg_DidFail(request_id, result)); - UnregisterOperation(request_id); -} - -void FileSystemDispatcherHost::DidOpenFile(int request_id, - base::PlatformFileError result, - base::PlatformFile file, - base::ProcessHandle peer_handle) { - if (result == base::PLATFORM_FILE_OK) { - IPC::PlatformFileForTransit file_for_transit = - file != base::kInvalidPlatformFileValue ? - IPC::GetFileHandleForProcess(file, peer_handle, true) : - IPC::InvalidPlatformFileForTransit(); - Send(new FileSystemMsg_DidOpenFile(request_id, file_for_transit)); - } else { - Send(new FileSystemMsg_DidFail(request_id, result)); - } - UnregisterOperation(request_id); -} - -void FileSystemDispatcherHost::DidWrite(int request_id, - base::PlatformFileError result, - int64 bytes, - bool complete) { - if (result == base::PLATFORM_FILE_OK) { - Send(new FileSystemMsg_DidWrite(request_id, bytes, complete)); - if (complete) - UnregisterOperation(request_id); - } else { - Send(new FileSystemMsg_DidFail(request_id, result)); - UnregisterOperation(request_id); - } -} - -void FileSystemDispatcherHost::DidOpenFileSystem(int request_id, - base::PlatformFileError result, - const std::string& name, - const GURL& root) { - if (result == base::PLATFORM_FILE_OK) { - DCHECK(root.is_valid()); - Send(new FileSystemMsg_DidOpenFileSystem(request_id, name, root)); - } else { - Send(new FileSystemMsg_DidFail(request_id, result)); - } - // For OpenFileSystem we do not create a new operation, so no unregister here. -} - -void FileSystemDispatcherHost::DidCreateSnapshot( - int request_id, - const GURL& blob_url, - base::PlatformFileError result, - const base::PlatformFileInfo& info, - const FilePath& platform_path, - const scoped_refptr& unused) { - if (result != base::PLATFORM_FILE_OK) { - Send(new FileSystemMsg_DidFail(request_id, result)); - return; - } - - FilePath::StringType extension = platform_path.Extension(); - if (!extension.empty()) - extension = extension.substr(1); // Strip leading ".". - - // This may fail, but then we'll be just setting the empty mime type. - std::string mime_type; - net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); - - // Register the created file to the blob registry. - // Blob storage automatically finds and refs deletable files, so we don't - // need to do anything for the returned file reference (|unused|) here. - BlobData::Item item; - item.SetToFile(platform_path, 0, -1, base::Time()); - BlobStorageController* controller = blob_storage_context_->controller(); - controller->StartBuildingBlob(blob_url); - controller->AppendBlobDataItem(blob_url, item); - controller->FinishBuildingBlob(blob_url, mime_type); - blob_urls_.insert(blob_url.spec()); - - // Return the file info and platform_path. - Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); -} - -FileSystemOperationInterface* FileSystemDispatcherHost::GetNewOperation( - const GURL& target_path, - int request_id) { - FileSystemOperationInterface* operation = - context_->CreateFileSystemOperation( - target_path, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); - DCHECK(operation); - operations_.AddWithID(operation, request_id); - return operation; -} - -void FileSystemDispatcherHost::UnregisterOperation(int request_id) { - DCHECK(operations_.Lookup(request_id)); - operations_.Remove(request_id); -} diff --git a/content/browser/file_system/file_system_dispatcher_host.h b/content/browser/file_system/file_system_dispatcher_host.h deleted file mode 100644 index 040a10a..0000000 --- a/content/browser/file_system/file_system_dispatcher_host.h +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2012 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 CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_DISPATCHER_HOST_H_ -#define CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_DISPATCHER_HOST_H_ - -#include - -#include "base/basictypes.h" -#include "base/file_util_proxy.h" -#include "base/id_map.h" -#include "base/platform_file.h" -#include "content/public/browser/browser_message_filter.h" -#include "webkit/fileapi/file_system_types.h" - -class ChromeBlobStorageContext; -class FilePath; -class GURL; - -namespace base { -class Time; -} - -namespace fileapi { -class FileSystemContext; -class FileSystemOperationInterface; -} - -namespace net { -class URLRequestContext; -class URLRequestContextGetter; -} // namespace net - -namespace webkit_blob { -class DeletableFileReference; -} - -class FileSystemDispatcherHost : public content::BrowserMessageFilter { - public: - // Used by the renderer process host on the UI thread. - FileSystemDispatcherHost( - net::URLRequestContextGetter* request_context_getter, - fileapi::FileSystemContext* file_system_context, - ChromeBlobStorageContext* blob_storage_context); - // Used by the worker process host on the IO thread. - FileSystemDispatcherHost( - net::URLRequestContext* request_context, - fileapi::FileSystemContext* file_system_context, - ChromeBlobStorageContext* blob_storage_context); - virtual ~FileSystemDispatcherHost(); - - // content::BrowserMessageFilter implementation. - virtual void OnChannelClosing() OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - virtual void OverrideThreadForMessage( - const IPC::Message& message, - content::BrowserThread::ID* thread) OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) OVERRIDE; - - void UnregisterOperation(int request_id); - - private: - void OnOpen(int request_id, - const GURL& origin_url, - fileapi::FileSystemType type, - int64 requested_size, - bool create); - void OnMove(int request_id, - const GURL& src_path, - const GURL& dest_path); - void OnCopy(int request_id, - const GURL& src_path, - const GURL& dest_path); - void OnRemove(int request_id, const GURL& path, bool recursive); - void OnReadMetadata(int request_id, const GURL& path); - void OnCreate(int request_id, - const GURL& path, - bool exclusive, - bool is_directory, - bool recursive); - void OnExists(int request_id, const GURL& path, bool is_directory); - void OnReadDirectory(int request_id, const GURL& path); - void OnWrite(int request_id, - const GURL& path, - const GURL& blob_url, - int64 offset); - void OnTruncate(int request_id, const GURL& path, int64 length); - void OnTouchFile(int request_id, - const GURL& path, - const base::Time& last_access_time, - const base::Time& last_modified_time); - void OnCancel(int request_id, int request_to_cancel); - void OnOpenFile(int request_id, const GURL& path, int file_flags); - void OnWillUpdate(const GURL& path); - void OnDidUpdate(const GURL& path, int64 delta); - void OnSyncGetPlatformPath(const GURL& path, - FilePath* platform_path); - void OnCreateSnapshotFile(int request_id, - const GURL& blob_url, - const GURL& path); - - // Callback functions to be used when each file operation is finished. - void DidFinish(int request_id, base::PlatformFileError result); - void DidCancel(int request_id, base::PlatformFileError result); - void DidGetMetadata(int request_id, - base::PlatformFileError result, - const base::PlatformFileInfo& info, - const FilePath& platform_path); - void DidReadDirectory(int request_id, - base::PlatformFileError result, - const std::vector& entries, - bool has_more); - void DidOpenFile(int request_id, - base::PlatformFileError result, - base::PlatformFile file, - base::ProcessHandle peer_handle); - void DidWrite(int request_id, - base::PlatformFileError result, - int64 bytes, - bool complete); - void DidOpenFileSystem(int request_id, - base::PlatformFileError result, - const std::string& name, - const GURL& root); - void DidCreateSnapshot( - int request_id, - const GURL& blob_url, - base::PlatformFileError result, - const base::PlatformFileInfo& info, - const FilePath& platform_path, - const scoped_refptr& - deletable_ref); - - // Creates a new FileSystemOperationInterface based on |target_path|. - fileapi::FileSystemOperationInterface* GetNewOperation( - const GURL& target_path, - int request_id); - - fileapi::FileSystemContext* context_; - - // Keeps ongoing file system operations. - typedef IDMap OperationsMap; - OperationsMap operations_; - - // The getter holds the context until Init() can be called from the - // IO thread, which will extract the net::URLRequestContext from it. - scoped_refptr request_context_getter_; - net::URLRequestContext* request_context_; - - // We access BlobStorageContext to construct an internal blob for - // snapshot files. - scoped_refptr blob_storage_context_; - - // Keeps track of internal blob URLs for temporary snapshot files. - // (As we do for regular blobs in BlobMessageFilter.) - // TODO(kinuko,tzik): merge this with the one in BlobMessageFilter. - base::hash_set blob_urls_; - - DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcherHost); -}; - -#endif // CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_DISPATCHER_HOST_H_ diff --git a/content/browser/renderer_host/blob_message_filter.cc b/content/browser/renderer_host/blob_message_filter.cc deleted file mode 100644 index e227c50..0000000 --- a/content/browser/renderer_host/blob_message_filter.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2012 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 "content/browser/renderer_host/blob_message_filter.h" - -#include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/chrome_blob_storage_context.h" -#include "content/common/webblob_messages.h" -#include "googleurl/src/gurl.h" -#include "webkit/blob/blob_data.h" -#include "webkit/blob/blob_storage_controller.h" - -using content::BrowserMessageFilter; -using content::BrowserThread; -using webkit_blob::BlobData; - -BlobMessageFilter::BlobMessageFilter( - int process_id, - ChromeBlobStorageContext* blob_storage_context) - : process_id_(process_id), - blob_storage_context_(blob_storage_context) { -} - -BlobMessageFilter::~BlobMessageFilter() { -} - -void BlobMessageFilter::OnChannelClosing() { - BrowserMessageFilter::OnChannelClosing(); - - // Unregister all the blob URLs that are previously registered in this - // process. - for (base::hash_set::const_iterator iter = blob_urls_.begin(); - iter != blob_urls_.end(); ++iter) { - blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); - } -} - -bool BlobMessageFilter::OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_EX(BlobMessageFilter, message, *message_was_ok) - IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) - IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) - IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, - OnAppendSharedMemory) - IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) - IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) - IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void BlobMessageFilter::OnStartBuildingBlob(const GURL& url) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - blob_storage_context_->controller()->StartBuildingBlob(url); - blob_urls_.insert(url.spec()); -} - -void BlobMessageFilter::OnAppendBlobDataItem( - const GURL& url, const BlobData::Item& item) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (item.type == BlobData::TYPE_FILE && - !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( - process_id_, item.file_path)) { - OnRemoveBlob(url); - return; - } - blob_storage_context_->controller()->AppendBlobDataItem(url, item); -} - -void BlobMessageFilter::OnAppendSharedMemory( - const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { - DCHECK(base::SharedMemory::IsHandleValid(handle)); -#if defined(OS_WIN) - base::SharedMemory shared_memory(handle, true, peer_handle()); -#else - base::SharedMemory shared_memory(handle, true); -#endif - if (!shared_memory.Map(buffer_size)) { - OnRemoveBlob(url); - return; - } - - BlobData::Item item; - item.SetToDataExternal(static_cast(shared_memory.memory()), - buffer_size); - blob_storage_context_->controller()->AppendBlobDataItem(url, item); -} - -void BlobMessageFilter::OnFinishBuildingBlob( - const GURL& url, const std::string& content_type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); -} - -void BlobMessageFilter::OnCloneBlob( - const GURL& url, const GURL& src_url) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - blob_storage_context_->controller()->CloneBlob(url, src_url); - blob_urls_.insert(url.spec()); -} - -void BlobMessageFilter::OnRemoveBlob(const GURL& url) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - blob_storage_context_->controller()->RemoveBlob(url); - blob_urls_.erase(url.spec()); -} diff --git a/content/browser/renderer_host/blob_message_filter.h b/content/browser/renderer_host/blob_message_filter.h deleted file mode 100644 index d8ddf07..0000000 --- a/content/browser/renderer_host/blob_message_filter.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011 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 CONTENT_BROWSER_RENDERER_HOST_BLOB_MESSAGE_FILTER_H_ -#define CONTENT_BROWSER_RENDERER_HOST_BLOB_MESSAGE_FILTER_H_ - -#include "base/hash_tables.h" -#include "base/shared_memory.h" -#include "content/public/browser/browser_message_filter.h" -#include "webkit/blob/blob_data.h" - -class ChromeBlobStorageContext; -class GURL; - -namespace IPC { -class Message; -} - -class BlobMessageFilter : public content::BrowserMessageFilter { - public: - BlobMessageFilter(int process_id, - ChromeBlobStorageContext* blob_storage_context); - virtual ~BlobMessageFilter(); - - // content::BrowserMessageFilter implementation. - virtual void OnChannelClosing() OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) OVERRIDE; - - private: - void OnStartBuildingBlob(const GURL& url); - void OnAppendBlobDataItem(const GURL& url, - const webkit_blob::BlobData::Item& item); - void OnAppendSharedMemory(const GURL& url, base::SharedMemoryHandle handle, - size_t buffer_size); - void OnFinishBuildingBlob(const GURL& url, const std::string& content_type); - void OnCloneBlob(const GURL& url, const GURL& src_url); - void OnRemoveBlob(const GURL& url); - - int process_id_; - scoped_refptr blob_storage_context_; - - // Keep track of blob URLs registered in this process. Need to unregister - // all of them when the renderer process dies. - base::hash_set blob_urls_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(BlobMessageFilter); -}; - -#endif // CONTENT_BROWSER_RENDERER_HOST_BLOB_MESSAGE_FILTER_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 90dc78d..2717a4e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -46,7 +46,7 @@ #include "content/browser/chrome_blob_storage_context.h" #include "content/browser/device_orientation/message_filter.h" #include "content/browser/download/mhtml_generation_manager.h" -#include "content/browser/file_system/file_system_dispatcher_host.h" +#include "content/browser/file_system/file_and_blob_message_filter.h" #include "content/browser/geolocation/geolocation_dispatcher_host.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host.h" @@ -57,7 +57,6 @@ #include "content/browser/mime_registry_message_filter.h" #include "content/browser/plugin_service_impl.h" #include "content/browser/profiler_message_filter.h" -#include "content/browser/renderer_host/blob_message_filter.h" #include "content/browser/renderer_host/clipboard_message_filter.h" #include "content/browser/renderer_host/database_message_filter.h" #include "content/browser/renderer_host/file_utilities_message_filter.h" @@ -500,13 +499,12 @@ void RenderProcessHostImpl::CreateMessageFilters() { browser_context->GetSpeechInputPreferences(), content::BrowserMainLoop::GetAudioManager())); #endif - channel_->AddFilter(new FileSystemDispatcherHost( + channel_->AddFilter(new FileAndBlobMessageFilter( + GetID(), browser_context->GetRequestContext(), BrowserContext::GetFileSystemContext(browser_context), ChromeBlobStorageContext::GetFor(browser_context))); channel_->AddFilter(new device_orientation::MessageFilter()); - channel_->AddFilter(new BlobMessageFilter(GetID(), - ChromeBlobStorageContext::GetFor(browser_context))); channel_->AddFilter(new FileUtilitiesMessageFilter(GetID())); channel_->AddFilter(new MimeRegistryMessageFilter()); channel_->AddFilter(new DatabaseMessageFilter( diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index 39e1a8e..647ee82 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -22,10 +22,9 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/debugger/worker_devtools_manager.h" #include "content/browser/debugger/worker_devtools_message_filter.h" -#include "content/browser/file_system/file_system_dispatcher_host.h" +#include "content/browser/file_system/file_and_blob_message_filter.h" #include "content/browser/in_process_webkit/indexed_db_dispatcher_host.h" #include "content/browser/mime_registry_message_filter.h" -#include "content/browser/renderer_host/blob_message_filter.h" #include "content/browser/renderer_host/database_message_filter.h" #include "content/browser/renderer_host/file_utilities_message_filter.h" #include "content/browser/renderer_host/render_view_host.h" @@ -263,17 +262,14 @@ void WorkerProcessHost::CreateMessageFilters(int render_process_id) { static_cast( ResourceContext::GetAppCacheService(resource_context_)), process_->GetData().id)); - process_->GetHost()->AddFilter(new FileSystemDispatcherHost( + process_->GetHost()->AddFilter(new FileAndBlobMessageFilter( + process_->GetData().id, request_context, ResourceContext::GetFileSystemContext(resource_context_), content::GetChromeBlobStorageContextForResourceContext( resource_context_))); process_->GetHost()->AddFilter(new FileUtilitiesMessageFilter( process_->GetData().id)); - process_->GetHost()->AddFilter(new BlobMessageFilter( - process_->GetData().id, - content::GetChromeBlobStorageContextForResourceContext( - resource_context_))); process_->GetHost()->AddFilter(new MimeRegistryMessageFilter()); process_->GetHost()->AddFilter(new DatabaseMessageFilter( content::GetDatabaseTrackerForResourceContext(resource_context_))); -- cgit v1.1