summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/gdata
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 21:09:43 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 21:09:43 +0000
commit71f2be8ac4c9024f9a7286545d06c921f50f18f3 (patch)
tree77d45637476f804235d948d53d2920eba27a7d71 /chrome/browser/chromeos/gdata
parentf3dc6fbc4d1ae9591fb59bdcba591fec5a2e7187 (diff)
downloadchromium_src-71f2be8ac4c9024f9a7286545d06c921f50f18f3.zip
chromium_src-71f2be8ac4c9024f9a7286545d06c921f50f18f3.tar.gz
chromium_src-71f2be8ac4c9024f9a7286545d06c921f50f18f3.tar.bz2
Implemented GDataFileSystem::TransferFile() method. It uploads file from the local path directly to gdata server.
BUG=chromium-os:28331 TEST=none Review URL: https://chromiumcodereview.appspot.com/9850001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128775 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/gdata')
-rw-r--r--chrome/browser/chromeos/gdata/gdata_download_observer.cc4
-rw-r--r--chrome/browser/chromeos/gdata/gdata_download_observer.h10
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.cc137
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.h53
-rw-r--r--chrome/browser/chromeos/gdata/gdata_operations.cc4
-rw-r--r--chrome/browser/chromeos/gdata/gdata_parser.cc4
-rw-r--r--chrome/browser/chromeos/gdata/gdata_system_service.h3
-rw-r--r--chrome/browser/chromeos/gdata/gdata_upload_file_info.h9
-rw-r--r--chrome/browser/chromeos/gdata/gdata_uploader.cc19
-rw-r--r--chrome/browser/chromeos/gdata/mock_gdata_file_system.h10
10 files changed, 209 insertions, 44 deletions
diff --git a/chrome/browser/chromeos/gdata/gdata_download_observer.cc b/chrome/browser/chromeos/gdata/gdata_download_observer.cc
index 15b8d7e..f5cc19c 100644
--- a/chrome/browser/chromeos/gdata/gdata_download_observer.cc
+++ b/chrome/browser/chromeos/gdata/gdata_download_observer.cc
@@ -300,7 +300,9 @@ UploadFileInfo* GDataDownloadObserver::CreateUploadFileInfo(
return upload_file_info;
}
-void GDataDownloadObserver::OnUploadComplete(int32 download_id) {
+void GDataDownloadObserver::OnUploadComplete(int32 download_id,
+ base::PlatformFileError error,
+ DocumentEntry* unused_entry) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadMap::iterator iter = pending_downloads_.find(download_id);
if (iter == pending_downloads_.end())
diff --git a/chrome/browser/chromeos/gdata/gdata_download_observer.h b/chrome/browser/chromeos/gdata/gdata_download_observer.h
index b3e9d6b..ef67487 100644
--- a/chrome/browser/chromeos/gdata/gdata_download_observer.h
+++ b/chrome/browser/chromeos/gdata/gdata_download_observer.h
@@ -10,11 +10,13 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
+#include "base/platform_file.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
namespace gdata {
+class DocumentEntry;
class GDataUploader;
struct UploadFileInfo;
@@ -88,9 +90,11 @@ class GDataDownloadObserver : public content::DownloadManager::Observer,
UploadFileInfo* CreateUploadFileInfo(content::DownloadItem* download);
// Callback invoked by GDataUploader when the upload associated with
- // |download_id| has completed. This function invokes the
- // MaybeCompleteDownload() method on the DownloadItem to allow it to complete.
- void OnUploadComplete(int32 download_id);
+ // |download_id| has completed. |error| indicated whether the
+ // call was successful. This function invokes the MaybeCompleteDownload()
+ // method on the DownloadItem to allow it to complete.
+ void OnUploadComplete(int32 download_id, base::PlatformFileError error,
+ DocumentEntry* unused_entry);
// Private data.
// Use GDataUploader to trigger file uploads.
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.cc b/chrome/browser/chromeos/gdata/gdata_file_system.cc
index 117cf5a..75f1ffd 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.cc
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.cc
@@ -22,10 +22,13 @@
#include "chrome/browser/chromeos/gdata/gdata_documents_service.h"
#include "chrome/browser/chromeos/gdata/gdata_download_observer.h"
#include "chrome/browser/chromeos/gdata/gdata_sync_client.h"
+#include "chrome/browser/chromeos/gdata/gdata_system_service.h"
+#include "chrome/browser/chromeos/gdata/gdata_upload_file_info.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "content/public/browser/browser_thread.h"
+#include "net/base/mime_util.h"
#include "webkit/fileapi/file_system_file_util_proxy.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_util.h"
@@ -34,6 +37,7 @@ using content::BrowserThread;
namespace {
+const char kApplicationOctetStream[] = "application/octet-stream";
const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("gdata");
const char kFeedField[] = "feed";
const char kWildCard[] = "*";
@@ -551,14 +555,117 @@ void GDataFileSystem::LoadFeedFromServer(
void GDataFileSystem::TransferFile(const FilePath& local_file_path,
const FilePath& remote_dest_file_path,
const FileOperationCallback& callback) {
- // TODO(zelidrag): Wire this with GDataUploader stack.
- if (!callback.is_null()) {
- MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_EMPTY));
+ base::AutoLock lock(lock_);
+ // Make sure the destination directory exists
+ GDataFileBase* dest_dir = GetGDataFileInfoFromPath(
+ remote_dest_file_path.DirName());
+ if (!dest_dir || !dest_dir->AsGDataDirectory()) {
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
+ return;
}
- return;
+
+ BrowserThread::PostBlockingPoolTask(FROM_HERE,
+ base::Bind(&GDataFileSystem::CreateUploadFileInfoOnIOThreadPool,
+ local_file_path,
+ remote_dest_file_path,
+ base::Bind(&GDataFileSystem::StartFileUploadOnUIThread,
+ ui_weak_ptr_factory_->GetWeakPtr(),
+ base::MessageLoopProxy::current(),
+ callback)));
}
+void GDataFileSystem::StartFileUploadOnUIThread(
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ const FileOperationCallback& callback,
+ base::PlatformFileError error,
+ scoped_ptr<UploadFileInfo> upload_file_info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ GDataSystemService* service =
+ GDataSystemServiceFactory::GetForProfile(profile_);
+
+ if (error == base::PLATFORM_FILE_OK) {
+ if (!service || !upload_file_info.get())
+ error = base::PLATFORM_FILE_ERROR_FAILED;
+ }
+
+ if (error != base::PLATFORM_FILE_OK) {
+ if (!callback.is_null())
+ proxy->PostTask(FROM_HERE, base::Bind(callback, error));
+
+ return;
+ }
+
+ upload_file_info->completion_callback =
+ base::Bind(&GDataFileSystem::OnTransferCompleted,
+ GetWeakPtrForCurrentThread(),
+ upload_file_info->file_path,
+ upload_file_info->gdata_path,
+ proxy,
+ callback);
+
+ service->uploader()->UploadFile(upload_file_info.release());
+}
+
+void GDataFileSystem::OnTransferCompleted(
+ const FilePath& local_file_path,
+ const FilePath& remote_dest_file_path,
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ const FileOperationCallback& callback,
+ base::PlatformFileError error,
+ DocumentEntry* entry) {
+ if (error == base::PLATFORM_FILE_OK && entry) {
+ AddUploadedFile(remote_dest_file_path.DirName(),
+ entry,
+ local_file_path,
+ FILE_OPERATION_COPY);
+ }
+ proxy->PostTask(FROM_HERE, base::Bind(callback, error));
+}
+
+// static.
+void GDataFileSystem::CreateUploadFileInfoOnIOThreadPool(
+ const FilePath& local_file,
+ const FilePath& remote_dest_file,
+ const CreateUploadFileInfoCallback& callback) {
+ scoped_ptr<UploadFileInfo> upload_file_info;
+
+ int64 file_size;
+ if (!file_util::GetFileSize(local_file, &file_size)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback,
+ base::PLATFORM_FILE_ERROR_NOT_FOUND,
+ base::Passed(&upload_file_info)));
+
+ return;
+ }
+
+ upload_file_info.reset(new UploadFileInfo());
+ upload_file_info->file_path = local_file;
+ upload_file_info->file_size = file_size;
+ // Extract the final path from DownloadItem.
+ upload_file_info->gdata_path = remote_dest_file;
+ // Use the file name as the title.
+ upload_file_info->title = remote_dest_file.BaseName().value();
+ upload_file_info->content_length = file_size;
+ upload_file_info->all_bytes_present = true;
+ std::string mime_type;
+ if (!net::GetMimeTypeFromExtension(local_file.Extension(),
+ &upload_file_info->content_type)) {
+ upload_file_info->content_type= kApplicationOctetStream;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback,
+ base::PLATFORM_FILE_OK,
+ base::Passed(&upload_file_info)));
+}
+
+
void GDataFileSystem::Copy(const FilePath& src_file_path,
const FilePath& dest_file_path,
const FileOperationCallback& callback) {
@@ -1623,7 +1730,13 @@ void GDataFileSystem::SaveFeedOnIOThreadPool(
FilePath file_name = meta_cache_path.Append(name);
std::string json;
+#ifndef NDEBUG
+ base::JSONWriter::WriteWithOptions(feed.get(),
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &json);
+#else
base::JSONWriter::Write(feed.get(), &json);
+#endif
int file_size = static_cast<int>(json.length());
if (file_util::WriteFile(file_name, json.data(), file_size) != file_size) {
@@ -2077,12 +2190,13 @@ base::PlatformFileError GDataFileSystem::RemoveFileFromGData(
return base::PLATFORM_FILE_OK;
}
-void GDataFileSystem::AddDownloadedFile(const FilePath& virtual_dir_path,
- scoped_ptr<gdata::DocumentEntry> entry,
- const FilePath& file_content_path) {
+void GDataFileSystem::AddUploadedFile(const FilePath& virtual_dir_path,
+ gdata::DocumentEntry* entry,
+ const FilePath& file_content_path,
+ FileOperationType cache_operation) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!entry.get()) {
+ if (!entry) {
NOTREACHED();
return;
}
@@ -2100,7 +2214,7 @@ void GDataFileSystem::AddDownloadedFile(const FilePath& virtual_dir_path,
return;
scoped_ptr<GDataFileBase> new_file(
- GDataFileBase::FromDocumentEntry(parent_dir, entry.get(), root_.get()));
+ GDataFileBase::FromDocumentEntry(parent_dir, entry, root_.get()));
if (!new_file.get())
return;
@@ -2111,7 +2225,8 @@ void GDataFileSystem::AddDownloadedFile(const FilePath& virtual_dir_path,
parent_dir->AddFile(new_file.release());
}
NotifyDirectoryChanged(virtual_dir_path);
- StoreToCache(resource_id, md5, file_content_path, FILE_OPERATION_MOVE,
+
+ StoreToCache(resource_id, md5, file_content_path, cache_operation,
CacheOperationCallback());
}
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.h b/chrome/browser/chromeos/gdata/gdata_file_system.h
index e3965ca..d7a8716 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.h
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.h
@@ -33,6 +33,11 @@ class WaitableEvent;
namespace gdata {
class DocumentsServiceInterface;
+struct UploadFileInfo;
+
+// Used for file operations like removing files.
+typedef base::Callback<void(base::PlatformFileError error)>
+ FileOperationCallback;
// Callback for completion of cache operation.
typedef base::Callback<void(base::PlatformFileError error,
@@ -56,10 +61,6 @@ typedef base::Callback<void(base::PlatformFileError error,
GDataFileBase* file)>
FindFileCallback;
-// Used for file operations like removing files.
-typedef base::Callback<void(base::PlatformFileError error)>
- FileOperationCallback;
-
// Used to get files from the file system.
typedef base::Callback<void(base::PlatformFileError error,
const FilePath& file_path,
@@ -361,9 +362,10 @@ class GDataFileSystemInterface {
// Creates a new file from |entry| under |virtual_dir_path|. Stored its
// content from |file_content_path| into the cache.
- virtual void AddDownloadedFile(const FilePath& virtual_dir_path,
- scoped_ptr<DocumentEntry> entry,
- const FilePath& file_content_path) = 0;
+ virtual void AddUploadedFile(const FilePath& virtual_dir_path,
+ DocumentEntry* entry,
+ const FilePath& file_content_path,
+ FileOperationType cache_operation) = 0;
};
// The production implementation of GDataFileSystemInterface.
@@ -431,9 +433,10 @@ class GDataFileSystem : public GDataFileSystemInterface {
CachedFileOrigin file_orign) const OVERRIDE;
virtual void GetAvailableSpace(
const GetAvailableSpaceCallback& callback) OVERRIDE;
- virtual void AddDownloadedFile(const FilePath& virtual_dir_path,
- scoped_ptr<DocumentEntry> entry,
- const FilePath& file_content_path) OVERRIDE;
+ virtual void AddUploadedFile(const FilePath& virtual_dir_path,
+ DocumentEntry* entry,
+ const FilePath& file_content_path,
+ FileOperationType cache_operation) OVERRIDE;
private:
friend class GDataUploader;
@@ -490,6 +493,12 @@ class GDataFileSystem : public GDataFileSystemInterface {
const CacheOperationCallback& callback)>
CacheOperationIntermediateCallback;
+ // Internal intermediate callback for dealing with results of
+ // CreateUploadFileInfoOnIOThreadPool() method.
+ typedef base::Callback<void(base::PlatformFileError error,
+ scoped_ptr<UploadFileInfo> upload_file_info)>
+ CreateUploadFileInfoCallback;
+
// Parameters to pass from calling thread to all cache file operations tasks
// on IO thread pool.
struct ModifyCacheStateParams {
@@ -801,6 +810,30 @@ class GDataFileSystem : public GDataFileSystemInterface {
const std::string& md5);
void NotifyDirectoryChanged(const FilePath& directory_path);
+ // Helper function that completes bookkeeping tasks related to
+ // completed file transfer.
+ void OnTransferCompleted(
+ const FilePath& local_file_path,
+ const FilePath& remote_dest_file_path,
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ const FileOperationCallback& callback,
+ base::PlatformFileError error,
+ DocumentEntry* entry);
+
+ // Kicks off file upload once it receives |upload_file_info|.
+ void StartFileUploadOnUIThread(
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ const FileOperationCallback& callback,
+ base::PlatformFileError error,
+ scoped_ptr<UploadFileInfo> upload_file_info);
+
+ // Reads properties of |local_file| and fills in values of UploadFileInfo
+ // which are returned through |callback| on UI thread.
+ static void CreateUploadFileInfoOnIOThreadPool(
+ const FilePath& local_file,
+ const FilePath& remote_dest_file,
+ const CreateUploadFileInfoCallback& callback);
+
// Cache entry points from within GDataFileSystem.
// The functionalities of GData blob cache include:
// - stores downloaded gdata files on disk, indexed by the resource_id and md5
diff --git a/chrome/browser/chromeos/gdata/gdata_operations.cc b/chrome/browser/chromeos/gdata/gdata_operations.cc
index 6b5ebec..ac37665 100644
--- a/chrome/browser/chromeos/gdata/gdata_operations.cc
+++ b/chrome/browser/chromeos/gdata/gdata_operations.cc
@@ -790,7 +790,9 @@ URLFetcher::RequestType InitiateUploadOperation::GetRequestType() const {
std::vector<std::string>
InitiateUploadOperation::GetExtraRequestHeaders() const {
std::vector<std::string> headers;
- headers.push_back(kUploadContentType + params_.content_type);
+ if (!params_.content_type.empty())
+ headers.push_back(kUploadContentType + params_.content_type);
+
headers.push_back(
kUploadContentLength + base::Int64ToString(params_.content_length));
return headers;
diff --git a/chrome/browser/chromeos/gdata/gdata_parser.cc b/chrome/browser/chromeos/gdata/gdata_parser.cc
index 4cfd3c3..a7fb3a0 100644
--- a/chrome/browser/chromeos/gdata/gdata_parser.cc
+++ b/chrome/browser/chromeos/gdata/gdata_parser.cc
@@ -73,9 +73,9 @@ const LinkTypeMap kLinkTypeMap[] = {
{ Link::EDIT_MEDIA,
"edit-media" },
{ Link::ALT_EDIT_MEDIA,
- "alt-edit-media" },
+ "http://schemas.google.com/docs/2007#alt-edit-media" },
{ Link::ALT_POST,
- "alt-post" },
+ "http://schemas.google.com/docs/2007#alt-post" },
{ Link::FEED,
"http://schemas.google.com/g/2005#feed"},
{ Link::POST,
diff --git a/chrome/browser/chromeos/gdata/gdata_system_service.h b/chrome/browser/chromeos/gdata/gdata_system_service.h
index 86754bb..befe0b5 100644
--- a/chrome/browser/chromeos/gdata/gdata_system_service.h
+++ b/chrome/browser/chromeos/gdata/gdata_system_service.h
@@ -29,6 +29,9 @@ class GDataSystemService : public ProfileKeyedService {
// Returns the file system instance.
GDataFileSystem* file_system() { return file_system_.get(); }
+ // Returns the uploader instance.
+ GDataUploader* uploader() { return uploader_.get(); }
+
// ProfileKeyedService override:
virtual void Shutdown() OVERRIDE;
diff --git a/chrome/browser/chromeos/gdata/gdata_upload_file_info.h b/chrome/browser/chromeos/gdata/gdata_upload_file_info.h
index 1d5e2b7..42b2772 100644
--- a/chrome/browser/chromeos/gdata/gdata_upload_file_info.h
+++ b/chrome/browser/chromeos/gdata/gdata_upload_file_info.h
@@ -26,11 +26,14 @@ namespace gdata {
class DocumentEntry;
+// Used for file operations like removing files.
+typedef base::Callback<void(base::PlatformFileError error,
+ DocumentEntry* entry)>
+ UploadCompletionCallback;
+
// Structure containing current upload information of file, passed between
// DocumentsService methods and callbacks.
struct UploadFileInfo {
- typedef base::Closure UploadFileCallback;
-
UploadFileInfo();
~UploadFileInfo();
@@ -79,7 +82,7 @@ struct UploadFileInfo {
scoped_ptr<DocumentEntry> entry;
// Callback to be invoked once the upload has completed.
- UploadFileCallback completion_callback;
+ UploadCompletionCallback completion_callback;
};
} // namespace gdata
diff --git a/chrome/browser/chromeos/gdata/gdata_uploader.cc b/chrome/browser/chromeos/gdata/gdata_uploader.cc
index d8d866b..256502d 100644
--- a/chrome/browser/chromeos/gdata/gdata_uploader.cc
+++ b/chrome/browser/chromeos/gdata/gdata_uploader.cc
@@ -125,8 +125,10 @@ UploadFileInfo* GDataUploader::GetUploadFileInfo(int upload_id) const {
void GDataUploader::RemovePendingUpload(UploadFileInfo* upload_file_info) {
pending_uploads_.erase(upload_file_info->upload_id);
- if (!upload_file_info->completion_callback.is_null())
- upload_file_info->completion_callback.Run();
+ if (!upload_file_info->completion_callback.is_null()) {
+ upload_file_info->completion_callback.Run(
+ base::PLATFORM_FILE_ERROR_ABORT, NULL);
+ }
// The file stream is closed by the destructor asynchronously.
delete upload_file_info->file_stream;
delete upload_file_info;
@@ -301,7 +303,9 @@ void GDataUploader::OnResumeUploadResponseReceived(
// Done uploading.
upload_file_info->entry = entry.Pass();
if (!upload_file_info->completion_callback.is_null()) {
- upload_file_info->completion_callback.Run();
+ upload_file_info->completion_callback.Run(
+ base::PLATFORM_FILE_OK,
+ upload_file_info->entry.get());
upload_file_info->completion_callback.Reset();
}
return;
@@ -341,10 +345,11 @@ void GDataUploader::OnResumeUploadResponseReceived(
}
void GDataUploader::UploadComplete(UploadFileInfo* upload_file_info) {
- DVLOG(1) << "UploadComplete " << upload_file_info->entry.get();
- file_system_->AddDownloadedFile(upload_file_info->gdata_path.DirName(),
- upload_file_info->entry.Pass(),
- upload_file_info->file_path);
+ DVLOG(1) << "UploadComplete " << upload_file_info->file_path.value();
+ file_system_->AddUploadedFile(upload_file_info->gdata_path.DirName(),
+ upload_file_info->entry.get(),
+ upload_file_info->file_path,
+ GDataFileSystemInterface::FILE_OPERATION_MOVE);
RemovePendingUpload(upload_file_info);
}
diff --git a/chrome/browser/chromeos/gdata/mock_gdata_file_system.h b/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
index fabc2f2..9a5b9d8 100644
--- a/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
+++ b/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
@@ -72,12 +72,10 @@ class MockGDataFileSystem : public GDataFileSystemInterface {
CachedFileOrigin));
MOCK_METHOD1(GetAvailableSpace,
void(const GetAvailableSpaceCallback& callback));
-
- // scoped_ptr can't be copied.
- // TODO(achuith): Figure out how to mock this.
- virtual void AddDownloadedFile(const FilePath&,
- scoped_ptr<DocumentEntry> entry,
- const FilePath& file_content_path) OVERRIDE {}
+ MOCK_METHOD4(AddUploadedFile, void(const FilePath& file,
+ DocumentEntry* entry,
+ const FilePath& file_content_path,
+ FileOperationType cache_operation));
};
} // namespace gdata