blob: 123eb7932e7549f3b884aab0ff78924f55fa43e5 [file] [log] [blame]
// Copyright 2013 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 "webkit/browser/fileapi/file_system_operation_runner.h"
#include "base/bind.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/local_file_system_operation.h"
#include "webkit/common/blob/shareable_file_reference.h"
namespace fileapi {
typedef FileSystemOperationRunner::OperationID OperationID;
const OperationID FileSystemOperationRunner::kErrorOperationID = -1;
FileSystemOperationRunner::~FileSystemOperationRunner() {
}
OperationID FileSystemOperationRunner::CreateFile(
const FileSystemURL& url,
bool exclusive,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->CreateFile(
url, exclusive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::CreateDirectory(
const FileSystemURL& url,
bool exclusive,
bool recursive,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->CreateDirectory(
url, exclusive, recursive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::Copy(
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(dest_url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->Copy(
src_url, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::Move(
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(dest_url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->Move(
src_url, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::DirectoryExists(
const FileSystemURL& url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->DirectoryExists(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::FileExists(
const FileSystemURL& url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->FileExists(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::GetMetadata(
const FileSystemURL& url,
const GetMetadataCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error, base::PlatformFileInfo(), base::FilePath());
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->GetMetadata(
url,
base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::ReadDirectory(
const FileSystemURL& url,
const ReadDirectoryCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error, std::vector<DirectoryEntry>(), false);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->ReadDirectory(
url,
base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::Remove(
const FileSystemURL& url, bool recursive,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->Remove(
url, recursive,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::Write(
const net::URLRequestContext* url_request_context,
const FileSystemURL& url,
const GURL& blob_url,
int64 offset,
const WriteCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error, 0, true);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->Write(
url_request_context, url, blob_url, offset,
base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::Truncate(
const FileSystemURL& url, int64 length,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->Truncate(
url, length,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
void FileSystemOperationRunner::Cancel(
OperationID id,
const StatusCallback& callback) {
FileSystemOperation* operation = operations_.Lookup(id);
if (!operation) {
// The operation is already finished; report that we failed to stop it.
callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
return;
}
operation->Cancel(callback);
}
OperationID FileSystemOperationRunner::TouchFile(
const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->TouchFile(
url, last_access_time, last_modified_time,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::OpenFile(
const FileSystemURL& url,
int file_flags,
base::ProcessHandle peer_handle,
const OpenFileCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error, base::kInvalidPlatformFileValue,
base::Closure(), base::ProcessHandle());
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->OpenFile(
url, file_flags, peer_handle,
base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::CreateSnapshotFile(
const FileSystemURL& url,
const SnapshotFileCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error, base::PlatformFileInfo(), base::FilePath(), NULL);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->CreateSnapshotFile(
url,
base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::CopyInForeignFile(
const base::FilePath& src_local_disk_path,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(
dest_url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->AsLocalFileSystemOperation()->CopyInForeignFile(
src_local_disk_path, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::RemoveFile(
const FileSystemURL& url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->AsLocalFileSystemOperation()->RemoveFile(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::RemoveDirectory(
const FileSystemURL& url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->AsLocalFileSystemOperation()->RemoveDirectory(
url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::CopyFileLocal(
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(
src_url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->AsLocalFileSystemOperation()->CopyFileLocal(
src_url, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
OperationID FileSystemOperationRunner::MoveFileLocal(
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(
src_url, &error);
if (!operation) {
callback.Run(error);
return kErrorOperationID;
}
OperationID id = operations_.Add(operation);
operation->AsLocalFileSystemOperation()->MoveFileLocal(
src_url, dest_url,
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
id, callback));
return id;
}
base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath(
const FileSystemURL& url,
base::FilePath* platform_path) {
base::PlatformFileError error = base::PLATFORM_FILE_OK;
FileSystemOperation* operation = CreateLocalFileSystemOperation(url, &error);
if (!operation)
return error;
operation->AsLocalFileSystemOperation()->SyncGetPlatformPath(
url, platform_path);
return base::PLATFORM_FILE_OK;
}
FileSystemOperationRunner::FileSystemOperationRunner(
FileSystemContext* file_system_context)
: file_system_context_(file_system_context) {}
void FileSystemOperationRunner::DidFinish(
OperationID id,
const StatusCallback& callback,
base::PlatformFileError rv) {
callback.Run(rv);
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
void FileSystemOperationRunner::DidGetMetadata(
OperationID id,
const GetMetadataCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const base::FilePath& platform_path) {
callback.Run(rv, file_info, platform_path);
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
void FileSystemOperationRunner::DidReadDirectory(
OperationID id,
const ReadDirectoryCallback& callback,
base::PlatformFileError rv,
const std::vector<DirectoryEntry>& entries,
bool has_more) {
callback.Run(rv, entries, has_more);
if (rv != base::PLATFORM_FILE_OK || !has_more) {
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
}
void FileSystemOperationRunner::DidWrite(
OperationID id,
const WriteCallback& callback,
base::PlatformFileError rv,
int64 bytes,
bool complete) {
callback.Run(rv, bytes, complete);
if (rv != base::PLATFORM_FILE_OK || complete) {
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
}
void FileSystemOperationRunner::DidOpenFile(
OperationID id,
const OpenFileCallback& callback,
base::PlatformFileError rv,
base::PlatformFile file,
const base::Closure& on_close_callback,
base::ProcessHandle peer_handle) {
callback.Run(rv, file, on_close_callback, peer_handle);
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
void FileSystemOperationRunner::DidCreateSnapshot(
OperationID id,
const SnapshotFileCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const base::FilePath& platform_path,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
callback.Run(rv, file_info, platform_path, file_ref);
DCHECK(operations_.Lookup(id));
operations_.Remove(id);
}
FileSystemOperation*
FileSystemOperationRunner::CreateLocalFileSystemOperation(
const FileSystemURL& url, base::PlatformFileError* error) {
FileSystemOperation* operation =
file_system_context_->CreateFileSystemOperation(url, error);
if (!operation)
return NULL;
if (!operation->AsLocalFileSystemOperation()) {
*error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
delete operation;
return NULL;
}
return operation;
}
} // namespace fileapi