This source file includes following definitions.
- GetOpenMode
- RunStatusCallbackByFileError
- RunGetFileInfoCallback
- RunReadDirectoryCallback
- RunCreateSnapshotFileCallback
- RunCreateWritableSnapshotFileCallback
- RunOpenFileCallback
- OpenFileAfterFileSystemOpenFile
- GetFileSystemFromUrl
- RunFileSystemCallback
- GetFileInfo
- Copy
- Move
- CopyInForeignFile
- ReadDirectory
- Remove
- CreateDirectory
- CreateFile
- Truncate
- CreateSnapshotFile
- CreateWritableSnapshotFile
- OpenFile
- TouchFile
#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/chromeos/drive/drive.pb.h"
#include "chrome/browser/chromeos/drive/file_errors.h"
#include "chrome/browser/chromeos/drive/file_system_interface.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/directory_entry.h"
using content::BrowserThread;
namespace drive {
namespace fileapi_internal {
namespace {
OpenMode GetOpenMode(int file_flag) {
if (file_flag & (base::PLATFORM_FILE_OPEN |
base::PLATFORM_FILE_OPEN_TRUNCATED))
return OPEN_FILE;
if (file_flag & base::PLATFORM_FILE_CREATE)
return CREATE_FILE;
DCHECK(file_flag & (base::PLATFORM_FILE_OPEN_ALWAYS |
base::PLATFORM_FILE_CREATE_ALWAYS));
return OPEN_OR_CREATE_FILE;
}
void RunStatusCallbackByFileError(const StatusCallback& callback,
FileError error) {
callback.Run(FileErrorToBaseFileError(error));
}
void RunGetFileInfoCallback(const GetFileInfoCallback& callback,
FileError error,
scoped_ptr<ResourceEntry> entry) {
if (error != FILE_ERROR_OK) {
callback.Run(FileErrorToBaseFileError(error), base::File::Info());
return;
}
DCHECK(entry);
base::File::Info file_info;
ConvertResourceEntryToFileInfo(*entry, &file_info);
callback.Run(base::File::FILE_OK, file_info);
}
void RunReadDirectoryCallback(
const ReadDirectoryCallback& callback,
FileError error,
scoped_ptr<ResourceEntryVector> resource_entries,
bool has_more) {
if (error != FILE_ERROR_OK) {
DCHECK(!has_more);
callback.Run(FileErrorToBaseFileError(error),
std::vector<fileapi::DirectoryEntry>(), has_more);
return;
}
DCHECK(resource_entries);
std::vector<fileapi::DirectoryEntry> entries;
entries.reserve(resource_entries->size());
for (size_t i = 0; i < resource_entries->size(); ++i) {
const ResourceEntry& resource_entry = (*resource_entries)[i];
fileapi::DirectoryEntry entry;
entry.name = resource_entry.base_name();
const PlatformFileInfoProto& file_info = resource_entry.file_info();
entry.is_directory = file_info.is_directory();
entry.size = file_info.size();
entry.last_modified_time =
base::Time::FromInternalValue(file_info.last_modified());
entries.push_back(entry);
}
callback.Run(base::File::FILE_OK, entries, has_more);
}
void RunCreateSnapshotFileCallback(const CreateSnapshotFileCallback& callback,
FileError error,
const base::FilePath& local_path,
scoped_ptr<ResourceEntry> entry) {
if (error != FILE_ERROR_OK) {
callback.Run(
FileErrorToBaseFileError(error),
base::File::Info(), base::FilePath(),
webkit_blob::ScopedFile::ScopeOutPolicy());
return;
}
DCHECK(entry);
base::File::Info file_info;
ConvertResourceEntryToFileInfo(*entry, &file_info);
file_info.last_modified = base::Time();
webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy =
entry->file_specific_info().is_hosted_document() ?
webkit_blob::ScopedFile::DELETE_ON_SCOPE_OUT :
webkit_blob::ScopedFile::DONT_DELETE_ON_SCOPE_OUT;
callback.Run(base::File::FILE_OK, file_info, local_path, scope_out_policy);
}
void RunCreateWritableSnapshotFileCallback(
const CreateWritableSnapshotFileCallback& callback,
FileError error,
const base::FilePath& local_path,
const base::Closure& close_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
callback.Run(FileErrorToBaseFileError(error), local_path, close_callback);
}
void RunOpenFileCallback(const OpenFileCallback& callback,
const base::Closure& close_callback,
base::File::Error* error,
base::PlatformFile platform_file) {
callback.Run(*error, platform_file, close_callback);
}
void OpenFileAfterFileSystemOpenFile(int file_flags,
const OpenFileCallback& callback,
FileError error,
const base::FilePath& local_path,
const base::Closure& close_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (error != FILE_ERROR_OK) {
callback.Run(FileErrorToBaseFileError(error),
base::kInvalidPlatformFileValue,
base::Closure());
return;
}
if (file_flags & (base::PLATFORM_FILE_CREATE |
base::PLATFORM_FILE_OPEN_ALWAYS)) {
file_flags &= ~(base::PLATFORM_FILE_CREATE |
base::PLATFORM_FILE_OPEN_ALWAYS);
file_flags |= base::PLATFORM_FILE_OPEN;
} else if (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS) {
file_flags &= ~base::PLATFORM_FILE_CREATE_ALWAYS;
file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
}
base::File::Error* result =
new base::File::Error(base::File::FILE_ERROR_FAILED);
bool posted = base::PostTaskAndReplyWithResult(
BrowserThread::GetBlockingPool(), FROM_HERE,
base::Bind(&base::CreatePlatformFile,
local_path, file_flags, static_cast<bool*>(NULL),
reinterpret_cast<base::PlatformFileError*>(result)),
base::Bind(&RunOpenFileCallback,
callback, close_callback, base::Owned(result)));
DCHECK(posted);
}
}
FileSystemInterface* GetFileSystemFromUrl(const fileapi::FileSystemURL& url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
Profile* profile = util::ExtractProfileFromPath(url.path());
return profile ? util::GetFileSystemByProfile(profile) : NULL;
}
void RunFileSystemCallback(
const FileSystemGetter& file_system_getter,
const base::Callback<void(FileSystemInterface*)>& callback,
const base::Closure& on_error_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FileSystemInterface* file_system = file_system_getter.Run();
if (!file_system) {
if (!on_error_callback.is_null())
on_error_callback.Run();
return;
}
callback.Run(file_system);
}
void GetFileInfo(const base::FilePath& file_path,
const GetFileInfoCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->GetResourceEntry(
file_path,
base::Bind(&RunGetFileInfoCallback, callback));
}
void Copy(const base::FilePath& src_file_path,
const base::FilePath& dest_file_path,
bool preserve_last_modified,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->Copy(src_file_path, dest_file_path, preserve_last_modified,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void Move(const base::FilePath& src_file_path,
const base::FilePath& dest_file_path,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->Move(src_file_path, dest_file_path,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void CopyInForeignFile(const base::FilePath& src_foreign_file_path,
const base::FilePath& dest_file_path,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->TransferFileFromLocalToRemote(
src_foreign_file_path, dest_file_path,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void ReadDirectory(const base::FilePath& file_path,
const ReadDirectoryCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->ReadDirectory(file_path,
base::Bind(&RunReadDirectoryCallback, callback));
}
void Remove(const base::FilePath& file_path,
bool is_recursive,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->Remove(file_path, is_recursive,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void CreateDirectory(const base::FilePath& file_path,
bool is_exclusive,
bool is_recursive,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->CreateDirectory(
file_path, is_exclusive, is_recursive,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void CreateFile(const base::FilePath& file_path,
bool is_exclusive,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->CreateFile(file_path, is_exclusive,
std::string(),
base::Bind(&RunStatusCallbackByFileError, callback));
}
void Truncate(const base::FilePath& file_path,
int64 length,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->TruncateFile(
file_path, length,
base::Bind(&RunStatusCallbackByFileError, callback));
}
void CreateSnapshotFile(const base::FilePath& file_path,
const CreateSnapshotFileCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->GetFile(file_path,
base::Bind(&RunCreateSnapshotFileCallback, callback));
}
void CreateWritableSnapshotFile(
const base::FilePath& file_path,
const CreateWritableSnapshotFileCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->OpenFile(
file_path,
OPEN_FILE,
std::string(),
base::Bind(&RunCreateWritableSnapshotFileCallback, callback));
}
void OpenFile(const base::FilePath& file_path,
int file_flags,
const OpenFileCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (file_flags & ~(base::PLATFORM_FILE_OPEN |
base::PLATFORM_FILE_CREATE |
base::PLATFORM_FILE_OPEN_ALWAYS |
base::PLATFORM_FILE_CREATE_ALWAYS |
base::PLATFORM_FILE_OPEN_TRUNCATED |
base::PLATFORM_FILE_READ |
base::PLATFORM_FILE_WRITE |
base::PLATFORM_FILE_WRITE_ATTRIBUTES |
base::PLATFORM_FILE_APPEND)) {
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
base::Bind(callback,
base::File::FILE_ERROR_FAILED,
base::kInvalidPlatformFileValue,
base::Closure()));
return;
}
file_system->OpenFile(
file_path, GetOpenMode(file_flags),
std::string(),
base::Bind(&OpenFileAfterFileSystemOpenFile, file_flags, callback));
}
void TouchFile(const base::FilePath& file_path,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback,
FileSystemInterface* file_system) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
file_system->TouchFile(file_path, last_access_time, last_modified_time,
base::Bind(&RunStatusCallbackByFileError, callback));
}
}
}