Commit c059c102 authored by satorux@chromium.org's avatar satorux@chromium.org

gdata:: Add GDataFileSystem::GetFile().

This function is used to get files from the file system.
For now, it always download files from the cloud.
We should have the caching layer in-pace here.

Along the way, a mssing 'return' to Remove().
Change GetDocumentUrlFromPath() to GetGDataFileInfoFromPath,
and wrote a test for it.

BUG=chromium-os:27174
TEST=unit_tests


Review URL: http://codereview.chromium.org/9583031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124857 0039d316-1c4b-4281-b951-d872f2087c98
parent bd058d1c
...@@ -401,13 +401,14 @@ void GDataFileSystem::StartDirectoryRefresh( ...@@ -401,13 +401,14 @@ void GDataFileSystem::StartDirectoryRefresh(
void GDataFileSystem::Remove(const FilePath& file_path, void GDataFileSystem::Remove(const FilePath& file_path,
bool is_recursive, bool is_recursive,
const FileOperationCallback& callback) { const FileOperationCallback& callback) {
GURL document_url = GetDocumentUrlFromPath(file_path); GDataFileBase* file_info = GetGDataFileInfoFromPath(file_path);
if (document_url.is_empty()) { if (!file_info) {
if (!callback.is_null()) { if (!callback.is_null()) {
MessageLoop::current()->PostTask( MessageLoop::current()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND)); base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
} }
return;
} }
BrowserThread::PostTask( BrowserThread::PostTask(
...@@ -415,13 +416,13 @@ void GDataFileSystem::Remove(const FilePath& file_path, ...@@ -415,13 +416,13 @@ void GDataFileSystem::Remove(const FilePath& file_path,
base::Bind( base::Bind(
&DocumentsService::DeleteDocument, &DocumentsService::DeleteDocument,
documents_service_bound_to_ui_thread_, documents_service_bound_to_ui_thread_,
document_url, file_info->self_url(),
base::Bind(&GDataFileSystem::OnRemovedDocument, base::Bind(&GDataFileSystem::OnRemovedDocument,
file_system_bound_to_ui_thread_, file_system_bound_to_ui_thread_,
callback, callback,
file_path, file_path,
// MessageLoopProxy is used to run |callback| on the // MessageLoopProxy is used to run |callback| on the
// thread where Remove() was called. // thread where this function was called.
base::MessageLoopProxy::current()))); base::MessageLoopProxy::current())));
} }
...@@ -504,6 +505,37 @@ void GDataFileSystem::CreateDirectoryInternal( ...@@ -504,6 +505,37 @@ void GDataFileSystem::CreateDirectoryInternal(
reply_proxy)))); reply_proxy))));
} }
void GDataFileSystem::GetFile(const FilePath& file_path,
const GetFileCallback& callback) {
GDataFileBase* file_info = GetGDataFileInfoFromPath(file_path);
if (!file_info) {
if (!callback.is_null()) {
MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback,
base::PLATFORM_FILE_ERROR_NOT_FOUND,
FilePath()));
}
return;
}
// TODO(satorux): We should get a file from the cache if it's present, but
// the caching layer is not implemented yet. For now, always download from
// the cloud.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
&DocumentsService::DownloadFile,
documents_service_bound_to_ui_thread_,
file_info->content_url(),
base::Bind(&GDataFileSystem::OnFileDownloaded,
file_system_bound_to_ui_thread_,
callback,
// MessageLoopProxy is used to run |callback| on the
// thread where this function was called.
base::MessageLoopProxy::current())));
}
void GDataFileSystem::UnsafeFindFileByPath( void GDataFileSystem::UnsafeFindFileByPath(
const FilePath& file_path, scoped_refptr<FindFileDelegate> delegate) { const FilePath& file_path, scoped_refptr<FindFileDelegate> delegate) {
lock_.AssertAcquired(); lock_.AssertAcquired();
...@@ -555,16 +587,17 @@ void GDataFileSystem::UnsafeFindFileByPath( ...@@ -555,16 +587,17 @@ void GDataFileSystem::UnsafeFindFileByPath(
delegate->OnError(base::PLATFORM_FILE_ERROR_NOT_FOUND); delegate->OnError(base::PLATFORM_FILE_ERROR_NOT_FOUND);
} }
GURL GDataFileSystem::GetDocumentUrlFromPath(const FilePath& file_path) { GDataFileBase* GDataFileSystem::GetGDataFileInfoFromPath(
const FilePath& file_path) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
// Find directory element within the cached file system snapshot. // Find directory element within the cached file system snapshot.
scoped_refptr<ReadOnlyFindFileDelegate> find_delegate( scoped_refptr<ReadOnlyFindFileDelegate> find_delegate(
new ReadOnlyFindFileDelegate()); new ReadOnlyFindFileDelegate());
UnsafeFindFileByPath(file_path, find_delegate); UnsafeFindFileByPath(file_path, find_delegate);
if (!find_delegate->file()) if (!find_delegate->file())
return GURL(); return NULL;
return find_delegate->file()->self_url(); return find_delegate->file();
} }
void GDataFileSystem::OnCreateDirectoryCompleted( void GDataFileSystem::OnCreateDirectoryCompleted(
...@@ -669,6 +702,22 @@ void GDataFileSystem::OnRemovedDocument( ...@@ -669,6 +702,22 @@ void GDataFileSystem::OnRemovedDocument(
} }
} }
void GDataFileSystem::OnFileDownloaded(
const GetFileCallback& callback,
scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
GDataErrorCode status,
const GURL& content_url,
const FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::PlatformFileError error = GDataToPlatformError(status);
if (!callback.is_null()) {
message_loop_proxy->PostTask(FROM_HERE,
base::Bind(callback, error, file_path));
}
}
base::PlatformFileError GDataFileSystem::RemoveFileFromFileSystem( base::PlatformFileError GDataFileSystem::RemoveFileFromFileSystem(
const FilePath& file_path) { const FilePath& file_path) {
// We need to lock here as well (despite FindFileByPath lock) since directory // We need to lock here as well (despite FindFileByPath lock) since directory
......
...@@ -37,14 +37,19 @@ class GDataFileBase { ...@@ -37,14 +37,19 @@ class GDataFileBase {
virtual GDataFile* AsGDataFile(); virtual GDataFile* AsGDataFile();
virtual GDataDirectory* AsGDataDirectory(); virtual GDataDirectory* AsGDataDirectory();
GDataDirectory* parent() { return parent_; } GDataDirectory* parent() { return parent_; }
const GURL& content_url() const { return content_url_; }
const base::PlatformFileInfo& file_info() const { return file_info_; } const base::PlatformFileInfo& file_info() const { return file_info_; }
const FilePath::StringType& file_name() const { return file_name_; } const FilePath::StringType& file_name() const { return file_name_; }
const FilePath::StringType& original_file_name() const { const FilePath::StringType& original_file_name() const {
return original_file_name_; return original_file_name_;
} }
void set_file_name(const FilePath::StringType& name) { file_name_ = name; } void set_file_name(const FilePath::StringType& name) { file_name_ = name; }
// The content URL is used for downloading regular files as is.
const GURL& content_url() const { return content_url_; }
// The self URL is used for removing files and hosted documents.
const GURL& self_url() const { return self_url_; } const GURL& self_url() const { return self_url_; }
// Returns virtual file path representing this file system entry. This path // Returns virtual file path representing this file system entry. This path
// corresponds to file path expected by public methods of GDataFileSyste // corresponds to file path expected by public methods of GDataFileSyste
// class. // class.
...@@ -237,9 +242,15 @@ class GDataFileSystem : public ProfileKeyedService { ...@@ -237,9 +242,15 @@ class GDataFileSystem : public ProfileKeyedService {
const scoped_refptr<FindFileDelegate> delegate; const scoped_refptr<FindFileDelegate> delegate;
}; };
// Used for file operations like removing files.
typedef base::Callback<void(base::PlatformFileError error)> typedef base::Callback<void(base::PlatformFileError error)>
FileOperationCallback; FileOperationCallback;
// Used to get files from the file system.
typedef base::Callback<void(base::PlatformFileError error,
const FilePath& file_path)>
GetFileCallback;
// ProfileKeyedService override: // ProfileKeyedService override:
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
...@@ -284,7 +295,14 @@ class GDataFileSystem : public ProfileKeyedService { ...@@ -284,7 +295,14 @@ class GDataFileSystem : public ProfileKeyedService {
bool is_recursive, bool is_recursive,
const FileOperationCallback& callback); const FileOperationCallback& callback);
// Initiates directory feed fetching operation and continues previously // Gets |file_path| from the file system. The file entry represented by
// |file_path| needs to be present in in-memory representation of the file
// system in order to be retrieved. If the file is not cached, the file
// will be downloaded through gdata api.
//
// Can be called from any thread. |callback| is run on the calling thread.
void GetFile(const FilePath& file_path, const GetFileCallback& callback);
// initiated FindFileByPath() attempt upon its completion. Safe to be called // initiated FindFileByPath() attempt upon its completion. Safe to be called
// from any thread. Internally, it will route content refresh request to // from any thread. Internally, it will route content refresh request to
// DocumentsService::GetDocuments() which will initiated content // DocumentsService::GetDocuments() which will initiated content
...@@ -293,6 +311,10 @@ class GDataFileSystem : public ProfileKeyedService { ...@@ -293,6 +311,10 @@ class GDataFileSystem : public ProfileKeyedService {
// Can be called from any thread. // Can be called from any thread.
void StartDirectoryRefresh(const FindFileParams& params); void StartDirectoryRefresh(const FindFileParams& params);
// Finds file object by |file_path| and returns the file info.
// Returns NULL if it does not find the file.
GDataFileBase* GetGDataFileInfoFromPath(const FilePath& file_path);
private: private:
friend class GDataFileSystemFactory; friend class GDataFileSystemFactory;
friend class GDataFileSystemTest; friend class GDataFileSystemTest;
...@@ -335,10 +357,6 @@ class GDataFileSystem : public ProfileKeyedService { ...@@ -335,10 +357,6 @@ class GDataFileSystem : public ProfileKeyedService {
void UnsafeFindFileByPath(const FilePath& file_path, void UnsafeFindFileByPath(const FilePath& file_path,
scoped_refptr<FindFileDelegate> delegate); scoped_refptr<FindFileDelegate> delegate);
// Finds file object by |file_path| and returns its gdata self-url.
// Returns empty GURL if it does not find the file.
GURL GetDocumentUrlFromPath(const FilePath& file_path);
// Converts document feed from gdata service into DirectoryInfo. On failure, // Converts document feed from gdata service into DirectoryInfo. On failure,
// returns NULL and fills in |error| with an appropriate value. // returns NULL and fills in |error| with an appropriate value.
GDataDirectory* ParseGDataFeed(GDataErrorCode status, GDataDirectory* ParseGDataFeed(GDataErrorCode status,
...@@ -369,6 +387,14 @@ class GDataFileSystem : public ProfileKeyedService { ...@@ -369,6 +387,14 @@ class GDataFileSystem : public ProfileKeyedService {
GDataErrorCode status, GDataErrorCode status,
base::Value* created_entry); base::Value* created_entry);
// Callback for handling file downloading requests.
void OnFileDownloaded(
const GetFileCallback& callback,
scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
GDataErrorCode status,
const GURL& content_url,
const FilePath& temp_file);
// Removes file under |file_path| from in-memory snapshot of the file system. // Removes file under |file_path| from in-memory snapshot of the file system.
// Return PLATFORM_FILE_OK if successful. // Return PLATFORM_FILE_OK if successful.
base::PlatformFileError RemoveFileFromFileSystem(const FilePath& file_path); base::PlatformFileError RemoveFileFromFileSystem(const FilePath& file_path);
......
...@@ -453,4 +453,21 @@ TEST_F(GDataFileSystemTest, FindFirstMissingParentDirectory) { ...@@ -453,4 +453,21 @@ TEST_F(GDataFileSystemTest, FindFirstMissingParentDirectory) {
&first_missing_parent_path)); &first_missing_parent_path));
} }
// TODO(satorux): Write a test for GetFile() once DocumentsService is
// mockable.
TEST_F(GDataFileSystemTest, GetGDataFileInfoFromPath) {
LoadRootFeedDocument("root_feed.json");
GDataFileBase* file_info = file_system_->GetGDataFileInfoFromPath(
FilePath(FILE_PATH_LITERAL("gdata/File 1.txt")));
ASSERT_TRUE(file_info != NULL);
EXPECT_EQ("https://file_link_self/", file_info->self_url().spec());
EXPECT_EQ("https://file_content_url/", file_info->content_url().spec());
GDataFileBase* non_existent = file_system_->GetGDataFileInfoFromPath(
FilePath(FILE_PATH_LITERAL("gdata/Nonexistent.txt")));
ASSERT_TRUE(non_existent == NULL);
}
} // namespace gdata } // namespace gdata
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment