Index: chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc |
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc |
index b8d0880e5a7cc1cea7e8402ed83f53def37757b1..9fbf55c7e693bb0724e8a6f0d5989ba4e03a6db8 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc |
@@ -34,7 +34,7 @@ const char kGDataRootDirectory[] = "drive"; |
const char kFeedField[] = "feed"; |
// Helper function that creates platform file on bocking IO thread pool. |
-void CreatePlatformFileOnIOPool(const FilePath& local_path, |
+void OpenPlatformFileOnIOPool(const FilePath& local_path, |
int file_flags, |
base::PlatformFile* platform_file, |
base::PlatformFileError* open_error) { |
@@ -45,9 +45,9 @@ void CreatePlatformFileOnIOPool(const FilePath& local_path, |
open_error); |
} |
-// Helper function to run reply on results of CreatePlatformFileOnIOPool() on |
+// Helper function to run reply on results of OpenPlatformFileOnIOPool() on |
// IO thread. |
-void OnPlatformFileCreated( |
+void OnPlatformFileOpened( |
const FileSystemOperationInterface::OpenFileCallback& callback, |
base::ProcessHandle peer_handle, |
base::PlatformFile* platform_file, |
@@ -77,12 +77,12 @@ void OnGetFileByPathForOpen( |
base::PlatformFileError* open_error = |
new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED); |
BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, |
- base::Bind(&CreatePlatformFileOnIOPool, |
+ base::Bind(&OpenPlatformFileOnIOPool, |
local_path, |
file_flags, |
platform_file, |
open_error), |
- base::Bind(&OnPlatformFileCreated, |
+ base::Bind(&OnPlatformFileOpened, |
callback, |
peer_handle, |
base::Owned(platform_file), |
@@ -148,7 +148,7 @@ void DoTruncateOnFileThread( |
} |
void DidCloseFileForTruncate( |
- const fileapi::FileSystemOperationInterface::StatusCallback& callback, |
+ const FileSystemOperationInterface::StatusCallback& callback, |
base::PlatformFileError truncate_result, |
gdata::GDataFileError close_result) { |
// Reports the first error. |
@@ -187,15 +187,13 @@ GDataFileSystemProxy::GDataFileSystemProxy( |
void GDataFileSystemProxy::GetFileInfo(const FileSystemURL& file_url, |
const FileSystemOperationInterface::GetMetadataCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
FilePath file_path; |
if (!ValidateUrl(file_url, &file_path)) { |
- base::MessageLoopProxy::current()->PostTask( |
- FROM_HERE, |
- base::Bind(callback, |
- base::PLATFORM_FILE_ERROR_NOT_FOUND, |
- base::PlatformFileInfo(), |
- FilePath())); |
+ MessageLoopProxy::current()->PostTask(FROM_HERE, |
+ base::Bind(callback, |
+ base::PLATFORM_FILE_ERROR_NOT_FOUND, |
+ base::PlatformFileInfo(), |
+ FilePath())); |
return; |
} |
@@ -326,7 +324,7 @@ void GDataFileSystemProxy::CreateFile( |
void GDataFileSystemProxy::Truncate( |
const FileSystemURL& file_url, int64 length, |
- const fileapi::FileSystemOperationInterface::StatusCallback& callback) { |
+ const FileSystemOperationInterface::StatusCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
if (length < 0) { |
@@ -354,6 +352,75 @@ void GDataFileSystemProxy::Truncate( |
callback)); |
} |
+void GDataFileSystemProxy::OnOpenFileForWriting( |
+ int file_flags, |
+ base::ProcessHandle peer_handle, |
+ const FileSystemOperationInterface::OpenFileCallback& callback, |
+ GDataFileError gdata_error, |
+ const FilePath& local_cache_path) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ base::PlatformFileError error = |
+ gdata::util::GDataFileErrorToPlatformError(gdata_error); |
+ |
+ if (error != base::PLATFORM_FILE_OK) { |
+ callback.Run(error, base::kInvalidPlatformFileValue, peer_handle); |
+ return; |
+ } |
+ |
+ // Cache file prepared for modification is available. Truncate it. |
+ // File operation must be done on FILE thread, so relay the operation. |
+ base::PlatformFileError* result = |
+ new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED); |
+ base::PlatformFile* platform_file = new base::PlatformFile( |
+ base::kInvalidPlatformFileValue); |
+ bool posted = BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, |
+ base::Bind(&OpenPlatformFileOnIOPool, |
+ local_cache_path, |
+ file_flags, |
+ platform_file, |
+ result), |
+ base::Bind(&OnPlatformFileOpened, |
+ callback, |
+ peer_handle, |
+ base::Owned(platform_file), |
+ base::Owned(result))); |
+ DCHECK(posted); |
+} |
+ |
+void GDataFileSystemProxy::OnCreateFileForOpen( |
+ const FilePath& file_path, |
+ int file_flags, |
+ base::ProcessHandle peer_handle, |
+ const FileSystemOperationInterface::OpenFileCallback& callback, |
+ GDataFileError gdata_error) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ base::PlatformFileError create_result = |
+ gdata::util::GDataFileErrorToPlatformError(gdata_error); |
+ |
+ if ((create_result == base::PLATFORM_FILE_OK) || |
+ ((create_result == base::PLATFORM_FILE_ERROR_EXISTS) && |
+ (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS))) { |
+ // If we are trying to always create an existing file, then |
+ // if it really exists open it as truncated. |
+ file_flags &= ~base::PLATFORM_FILE_CREATE; |
+ file_flags &= ~base::PLATFORM_FILE_CREATE_ALWAYS; |
+ file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED; |
+ } else { |
+ callback.Run(create_result, base::kInvalidPlatformFileValue, peer_handle); |
+ return; |
+ } |
+ |
+ // Open created (or existing) file for writing. |
+ file_system_->OpenFile( |
+ file_path, |
+ base::Bind(&GDataFileSystemProxy::OnOpenFileForWriting, |
+ this, |
+ file_flags, |
+ peer_handle, |
+ callback)); |
+} |
+ |
void GDataFileSystemProxy::OnFileOpenedForTruncate( |
const FilePath& virtual_path, |
int64 length, |
@@ -388,7 +455,7 @@ void GDataFileSystemProxy::OnFileOpenedForTruncate( |
void GDataFileSystemProxy::DidTruncate( |
const FilePath& virtual_path, |
- const fileapi::FileSystemOperationInterface::StatusCallback& callback, |
+ const FileSystemOperationInterface::StatusCallback& callback, |
base::PlatformFileError* truncate_result) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
@@ -418,18 +485,70 @@ void GDataFileSystemProxy::OpenFile( |
return; |
} |
- file_system_->GetFileByPath(file_path, |
- base::Bind(&OnGetFileByPathForOpen, |
- callback, |
- file_flags, |
- peer_handle), |
- GetDownloadDataCallback()); |
+ // TODO(zelidrag): Wire all other file open operations. |
+ if ((file_flags & base::PLATFORM_FILE_DELETE_ON_CLOSE)) { |
+ NOTIMPLEMENTED() << "File create/write operations not yet supported " |
+ << file_path.value(); |
+ MessageLoopProxy::current()->PostTask(FROM_HERE, |
+ base::Bind(callback, |
+ base::PLATFORM_FILE_ERROR_FAILED, |
+ base::kInvalidPlatformFileValue, |
+ peer_handle)); |
+ return; |
+ } |
+ |
+ if ((file_flags & base::PLATFORM_FILE_OPEN) || |
+ (file_flags & base::PLATFORM_FILE_OPEN_ALWAYS) || |
+ (file_flags & base::PLATFORM_FILE_OPEN_TRUNCATED)) { |
+ if ((file_flags & base::PLATFORM_FILE_OPEN_TRUNCATED) || |
+ (file_flags & base::PLATFORM_FILE_OPEN_ALWAYS) || |
+ (file_flags & base::PLATFORM_FILE_WRITE) || |
+ (file_flags & base::PLATFORM_FILE_EXCLUSIVE_WRITE)) { |
+ // Open existing file for writing. |
+ file_system_->OpenFile( |
+ file_path, |
+ base::Bind(&GDataFileSystemProxy::OnOpenFileForWriting, |
+ this, |
+ file_flags, |
+ peer_handle, |
+ callback)); |
+ } else { |
+ // Read-only file open. |
+ file_system_->GetFileByPath(file_path, |
+ base::Bind(&OnGetFileByPathForOpen, |
+ callback, |
+ file_flags, |
+ peer_handle), |
+ GetDownloadDataCallback()); |
+ } |
+ } else if ((file_flags & base::PLATFORM_FILE_CREATE) || |
+ (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS)) { |
+ // Open existing file for writing. |
+ file_system_->CreateFile( |
+ file_path, |
+ file_flags & base::PLATFORM_FILE_EXCLUSIVE_WRITE, |
+ base::Bind(&GDataFileSystemProxy::OnCreateFileForOpen, |
+ this, |
+ file_path, |
+ file_flags, |
+ peer_handle, |
+ callback)); |
+ } else { |
+ NOTREACHED() << "Unhandled file flags combination " << file_flags; |
+ MessageLoopProxy::current()->PostTask(FROM_HERE, |
+ base::Bind(callback, |
+ base::PLATFORM_FILE_ERROR_FAILED, |
+ base::kInvalidPlatformFileValue, |
+ peer_handle)); |
+ } |
} |
void GDataFileSystemProxy::NotifyCloseFile(const FileSystemURL& url) { |
- // TODO(kinaba,zelidrag): crbug.com/132236. |
- // Once OpenFile() for writing is implemented, we also need to implement the |
- // corresponding NotifyCloseFile for committing dirty cache. |
+ FilePath file_path; |
+ if (!ValidateUrl(url, &file_path)) |
+ return; |
+ |
+ file_system_->CloseFile(file_path, FileOperationCallback()); |
} |
void GDataFileSystemProxy::CreateSnapshotFile( |