Chromium Code Reviews| Index: content/browser/fileapi/fileapi_message_filter.cc |
| =================================================================== |
| --- content/browser/fileapi/fileapi_message_filter.cc (revision 171309) |
| +++ content/browser/fileapi/fileapi_message_filter.cc (working copy) |
| @@ -24,7 +24,7 @@ |
| #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/blob_storage_context.h" |
| #include "webkit/blob/shareable_file_reference.h" |
| #include "webkit/fileapi/file_observers.h" |
| #include "webkit/fileapi/file_system_context.h" |
| @@ -42,7 +42,8 @@ |
| using fileapi::LocalFileSystemOperation; |
| using fileapi::UpdateObserverList; |
| using webkit_blob::BlobData; |
| -using webkit_blob::BlobStorageController; |
| +using webkit_blob::BlobStorageContext; |
| +using webkit_blob::BlobStorageConsumer; |
| namespace content { |
| namespace { |
| @@ -114,17 +115,16 @@ |
| request_context_getter_ = NULL; |
| DCHECK(request_context_); |
| } |
| + |
| + blob_storage_consumer_.reset( |
| + new webkit_blob::BlobStorageConsumer(blob_storage_context_->context())); |
| } |
| void FileAPIMessageFilter::OnChannelClosing() { |
| BrowserMessageFilter::OnChannelClosing(); |
| - // Unregister all the blob URLs that are previously registered in this |
| - // process. |
| - for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); |
| - iter != blob_urls_.end(); ++iter) { |
| - blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); |
| - } |
| + blob_storage_consumer_.reset(); |
| + in_transit_snapshot_files_.clear(); |
| // Close all files that are previously OpenFile()'ed in this process. |
| if (!open_filesystem_urls_.empty()) { |
| @@ -172,17 +172,24 @@ |
| IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) |
| IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
| OnCreateSnapshotFile) |
| + IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, |
| + OnDidReceiveSnapshotFile) |
| 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_HANDLER(BlobHostMsg_StartBuildingBlob2, OnStartBuildingBlob2) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem2, OnAppendBlobDataItem2) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_AppendSharedMemory2, |
| + OnAppendSharedMemory2) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob2, OnFinishBuildingBlob2) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementBlobRefCount, |
| + OnIncrementBlobRefCount) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementBlobRefCount, |
| + OnDecrementBlobRefCount) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicBlobURL, |
| + OnRegisterPublicBlobURL) |
| + IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicBlobURL, OnRevokePublicBlobURL) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP_EX() |
| return handled; |
| @@ -236,7 +243,7 @@ |
| return; |
| } |
| - FileSystemOperation* operation = GetNewOperation(dest_url, request_id); |
| + FileSystemOperation* operation = GetNewOperation(src_url, request_id); |
|
kinuko
2013/01/07 08:52:01
note: in the current code this needs to take dest_
michaeln
2013/01/25 21:19:44
Done.
|
| if (!operation) |
| return; |
| operation->Move( |
| @@ -256,7 +263,7 @@ |
| return; |
| } |
| - FileSystemOperation* operation = GetNewOperation(dest_url, request_id); |
| + FileSystemOperation* operation = GetNewOperation(src_url, request_id); |
|
kinuko
2013/01/07 08:52:01
ditto
michaeln
2013/01/25 21:19:44
Done.
|
| if (!operation) |
| return; |
| operation->Copy( |
| @@ -370,7 +377,7 @@ |
| void FileAPIMessageFilter::OnWrite( |
| int request_id, |
| const GURL& path, |
| - const GURL& blob_url, |
| + const std::string& blob_uuid, |
| int64 offset) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| if (!request_context_) { |
| @@ -389,8 +396,10 @@ |
| FileSystemOperation* operation = GetNewOperation(url, request_id); |
| if (!operation) |
| return; |
| + scoped_ptr<webkit_blob::BlobDataHandle> blob = |
| + blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid); |
| operation->Write( |
| - request_context_, url, blob_url, offset, |
| + request_context_, url, blob.Pass(), offset, |
| base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); |
| } |
| @@ -543,7 +552,7 @@ |
| if (!operation) |
| return; |
| - operation->SyncGetPlatformPath(url, platform_path); |
| + operation->SyncGetPlatformPath(url, platform_path); |
|
kinuko
2013/01/07 08:52:01
nit: indent is off
michaeln
2013/01/25 21:19:44
Done.
|
| // The path is to be attached to URLLoader so we grant read permission |
| // for the file. (We first need to check if it can already be read not to |
| @@ -556,12 +565,9 @@ |
| } |
| void FileAPIMessageFilter::OnCreateSnapshotFile( |
| - int request_id, const GURL& blob_url, const GURL& path) { |
| + int request_id, const GURL& path) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| FileSystemURL url(path); |
| - base::Callback<void(const FilePath&)> register_file_callback = |
| - base::Bind(&FileAPIMessageFilter::RegisterFileAsBlob, |
| - this, blob_url, url); |
| // Make sure if this file can be read by the renderer as this is |
| // called when the renderer is about to create a new File object |
| @@ -578,35 +584,41 @@ |
| operation->CreateSnapshotFile( |
| url, |
| base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, |
| - this, request_id, register_file_callback)); |
| + this, url, request_id)); |
| } |
| -void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { |
| +void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - blob_storage_context_->controller()->StartBuildingBlob(url); |
| - blob_urls_.insert(url.spec()); |
| + in_transit_snapshot_files_.erase(request_id); |
| } |
| -void FileAPIMessageFilter::OnAppendBlobDataItem( |
| - const GURL& url, const BlobData::Item& item) { |
| +void FileAPIMessageFilter::OnStartBuildingBlob2(const std::string& uuid) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + blob_storage_consumer_->StartBuildingBlob(uuid); |
| +} |
| + |
| +void FileAPIMessageFilter::OnAppendBlobDataItem2( |
| + const std::string& uuid, const webkit_blob::BlobData::Item& item) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| // TODO(kinuko): We must check permission in TYPE_FILE_FILESYSTEM cases too. |
| // http://crbug.com/141827 |
| if (item.type() == BlobData::Item::TYPE_FILE && |
| !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
| process_id_, item.path())) { |
| - OnRemoveBlob(url); |
| + blob_storage_consumer_->CancelBuildingBlob(uuid); |
| return; |
| } |
| if (item.length() == 0) { |
| BadMessageReceived(); |
| return; |
| } |
| - blob_storage_context_->controller()->AppendBlobDataItem(url, item); |
| + blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
| } |
| -void FileAPIMessageFilter::OnAppendSharedMemory( |
| - const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { |
| +void FileAPIMessageFilter::OnAppendSharedMemory2( |
| + const std::string& uuid, |
| + base::SharedMemoryHandle handle, |
| + size_t buffer_size) { |
| DCHECK(base::SharedMemory::IsHandleValid(handle)); |
| if (!buffer_size) { |
| BadMessageReceived(); |
| @@ -618,35 +630,43 @@ |
| base::SharedMemory shared_memory(handle, true); |
| #endif |
| if (!shared_memory.Map(buffer_size)) { |
| - OnRemoveBlob(url); |
| + blob_storage_consumer_->CancelBuildingBlob(uuid); |
| return; |
| } |
| BlobData::Item item; |
| item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), |
| buffer_size); |
| - blob_storage_context_->controller()->AppendBlobDataItem(url, item); |
| + blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
| } |
| -void FileAPIMessageFilter::OnFinishBuildingBlob( |
| - const GURL& url, const std::string& content_type) { |
| +void FileAPIMessageFilter::OnFinishBuildingBlob2(const std::string& uuid, |
| + const std::string& content_type) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); |
| + blob_storage_consumer_->FinishBuildingBlob(uuid, content_type); |
| } |
| -void FileAPIMessageFilter::OnCloneBlob( |
| - const GURL& url, const GURL& src_url) { |
| +void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - blob_storage_context_->controller()->CloneBlob(url, src_url); |
| - blob_urls_.insert(url.spec()); |
| + blob_storage_consumer_->IncrementBlobRefCount(uuid); |
| } |
| -void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { |
| +void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - blob_storage_context_->controller()->RemoveBlob(url); |
| - blob_urls_.erase(url.spec()); |
| + blob_storage_consumer_->DecrementBlobRefCount(uuid); |
| } |
| +void FileAPIMessageFilter::OnRegisterPublicBlobURL( |
| + const GURL& public_url, const std::string& uuid) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + blob_storage_consumer_->RegisterPublicBlobURL(public_url, uuid); |
| +} |
| + |
| +void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + blob_storage_consumer_->RevokePublicBlobURL(public_url); |
| +} |
| + |
| void FileAPIMessageFilter::DidFinish(int request_id, |
| base::PlatformFileError result) { |
| if (result == base::PLATFORM_FILE_OK) |
| @@ -748,38 +768,18 @@ |
| } |
| void FileAPIMessageFilter::DidCreateSnapshot( |
| + const FileSystemURL& url, |
| int request_id, |
| - const base::Callback<void(const FilePath&)>& register_file_callback, |
| base::PlatformFileError result, |
| const base::PlatformFileInfo& info, |
| const FilePath& platform_path, |
| - const scoped_refptr<webkit_blob::ShareableFileReference>& unused) { |
| + const scoped_refptr<webkit_blob::ShareableFileReference>& snaphot_file) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| if (result != base::PLATFORM_FILE_OK) { |
| Send(new FileSystemMsg_DidFail(request_id, result)); |
| return; |
| } |
| - // Register the created file to the blob registry by calling |
| - // RegisterFileAsBlob. |
| - // Blob storage automatically finds and refs the file_ref, so we don't |
| - // need to do anything for the returned file reference (|unused|) here. |
| - register_file_callback.Run(platform_path); |
| - |
| - // Return the file info and platform_path. |
| - Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); |
| -} |
| - |
| -void FileAPIMessageFilter::RegisterFileAsBlob(const GURL& blob_url, |
| - const FileSystemURL& url, |
| - const FilePath& platform_path) { |
| - // Use the virtual path's extension to determine MIME type. |
| - FilePath::StringType extension = url.path().Extension(); |
| - if (!extension.empty()) |
| - extension = extension.substr(1); // Strip leading ".". |
| - |
| - scoped_refptr<webkit_blob::ShareableFileReference> shareable_file = |
| - webkit_blob::ShareableFileReference::Get(platform_path); |
| if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
| process_id_, platform_path)) { |
| // If the underlying file system implementation is returning a new |
| @@ -787,28 +787,29 @@ |
| // filesystems it's ok to grant permission here. |
| // (Note that we have also already checked if the renderer has the |
| // read permission for this file in OnCreateSnapshotFile.) |
| - DCHECK(shareable_file || |
| + DCHECK(snaphot_file || |
| fileapi::SandboxMountPointProvider::CanHandleType(url.type())); |
| ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
| process_id_, platform_path); |
| - if (shareable_file) { |
| + if (snaphot_file) { |
| // This will revoke all permissions for the file when the last ref |
| // of the file is dropped (assuming it's ok). |
| - shareable_file->AddFinalReleaseCallback( |
| + snaphot_file->AddFinalReleaseCallback( |
| base::Bind(&RevokeFilePermission, process_id_)); |
| } |
| } |
| - // This may fail, but then we'll be just setting the empty mime type. |
| - std::string mime_type; |
| - net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); |
| - BlobData::Item item; |
| - item.SetToFilePathRange(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()); |
| + if (snaphot_file) { |
| + // This ref is held until OnDidReceiveSnapshotFile is called. By holding |
| + // this ref we ensure that the file is not deleted prior to the renderer |
| + // having created a webcore blob data handle that refers to this file |
| + // and takes a ref of its own. |
|
kinuko
2013/01/07 08:52:01
nit: extra space before 'a ref'
michaeln
2013/01/25 21:19:44
Done.
|
| + in_transit_snapshot_files_[request_id] = snaphot_file; |
| + } |
| + |
| + // Return the file info and platform_path. |
| + Send(new FileSystemMsg_DidCreateSnapshotFile( |
| + request_id, info, platform_path)); |
| } |
| bool FileAPIMessageFilter::HasPermissionsForFile( |