1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_DRIVE_DRIVE_UPLOADER_H_ 6 #define CHROME_BROWSER_DRIVE_DRIVE_UPLOADER_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback_forward.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/weak_ptr.h" 14 #include "chrome/browser/drive/drive_service_interface.h" 15 #include "google_apis/drive/gdata_errorcode.h" 16 #include "google_apis/drive/gdata_wapi_parser.h" 17 18 class GURL; 19 20 namespace base { 21 class FilePath; 22 class TaskRunner; 23 } 24 25 namespace google_apis { 26 struct UploadRangeResponse; 27 } 28 29 namespace drive { 30 class DriveServiceInterface; 31 32 // Callback to be invoked once the upload has completed. 33 // |upload_location| will be returned when the uploading process is started but 34 // terminated before the completion due to some errors. It can be used to 35 // resume it. 36 typedef base::Callback<void( 37 google_apis::GDataErrorCode error, 38 const GURL& upload_location, 39 scoped_ptr<google_apis::ResourceEntry> resource_entry)> 40 UploadCompletionCallback; 41 42 class DriveUploaderInterface { 43 public: ~DriveUploaderInterface()44 virtual ~DriveUploaderInterface() {} 45 46 // Uploads a new file to a directory specified by |upload_location|. 47 // Returns a callback for cancelling the uploading job. 48 // 49 // parent_resource_id: 50 // resource id of the destination directory. 51 // 52 // local_file_path: 53 // The path to the local file to be uploaded. 54 // 55 // title: 56 // The title (file name) of the file to be uploaded. 57 // 58 // content_type: 59 // The content type of the file to be uploaded. 60 // 61 // callback: 62 // Called when an upload is done regardless of it was successful or not. 63 // Must not be null. 64 // 65 // progress_callback: 66 // Periodically called back with the total number of bytes sent so far. 67 // May be null if the information is not needed. 68 virtual google_apis::CancelCallback UploadNewFile( 69 const std::string& parent_resource_id, 70 const base::FilePath& local_file_path, 71 const std::string& title, 72 const std::string& content_type, 73 const UploadCompletionCallback& callback, 74 const google_apis::ProgressCallback& progress_callback) = 0; 75 76 // Uploads an existing file (a file that already exists on Drive). 77 // 78 // See comments at UploadNewFile about common parameters and the return value. 79 // 80 // resource_id: 81 // resource id of the existing file to be overwritten. 82 // 83 // etag: 84 // Expected ETag for the destination file. If it does not match, the upload 85 // fails with UPLOAD_ERROR_CONFLICT. 86 // If |etag| is empty, the test is skipped. 87 virtual google_apis::CancelCallback UploadExistingFile( 88 const std::string& resource_id, 89 const base::FilePath& local_file_path, 90 const std::string& content_type, 91 const std::string& etag, 92 const UploadCompletionCallback& callback, 93 const google_apis::ProgressCallback& progress_callback) = 0; 94 95 // Resumes the uploading process terminated before the completion. 96 // |upload_location| should be the one returned via UploadCompletionCallback 97 // for previous invocation. |drive_file_path|, |local_file_path| and 98 // |content_type| must be set to the same ones for previous invocation. 99 // 100 // See comments at UploadNewFile about common parameters and the return value. 101 virtual google_apis::CancelCallback ResumeUploadFile( 102 const GURL& upload_location, 103 const base::FilePath& local_file_path, 104 const std::string& content_type, 105 const UploadCompletionCallback& callback, 106 const google_apis::ProgressCallback& progress_callback) = 0; 107 }; 108 109 class DriveUploader : public DriveUploaderInterface { 110 public: 111 DriveUploader(DriveServiceInterface* drive_service, 112 base::TaskRunner* blocking_task_runner); 113 virtual ~DriveUploader(); 114 115 // DriveUploaderInterface overrides. 116 virtual google_apis::CancelCallback UploadNewFile( 117 const std::string& parent_resource_id, 118 const base::FilePath& local_file_path, 119 const std::string& title, 120 const std::string& content_type, 121 const UploadCompletionCallback& callback, 122 const google_apis::ProgressCallback& progress_callback) OVERRIDE; 123 virtual google_apis::CancelCallback UploadExistingFile( 124 const std::string& resource_id, 125 const base::FilePath& local_file_path, 126 const std::string& content_type, 127 const std::string& etag, 128 const UploadCompletionCallback& callback, 129 const google_apis::ProgressCallback& progress_callback) OVERRIDE; 130 virtual google_apis::CancelCallback ResumeUploadFile( 131 const GURL& upload_location, 132 const base::FilePath& local_file_path, 133 const std::string& content_type, 134 const UploadCompletionCallback& callback, 135 const google_apis::ProgressCallback& progress_callback) OVERRIDE; 136 137 private: 138 struct UploadFileInfo; 139 typedef base::Callback<void(scoped_ptr<UploadFileInfo> upload_file_info)> 140 StartInitiateUploadCallback; 141 142 // Starts uploading a file with |upload_file_info|. 143 google_apis::CancelCallback StartUploadFile( 144 scoped_ptr<UploadFileInfo> upload_file_info, 145 const StartInitiateUploadCallback& start_initiate_upload_callback); 146 void StartUploadFileAfterGetFileSize( 147 scoped_ptr<UploadFileInfo> upload_file_info, 148 const StartInitiateUploadCallback& start_initiate_upload_callback, 149 bool get_file_size_result); 150 151 // Starts to initiate the new file uploading. 152 // Upon completion, OnUploadLocationReceived should be called. 153 void StartInitiateUploadNewFile( 154 const std::string& parent_resource_id, 155 const std::string& title, 156 scoped_ptr<UploadFileInfo> upload_file_info); 157 158 // Starts to initiate the existing file uploading. 159 // Upon completion, OnUploadLocationReceived should be called. 160 void StartInitiateUploadExistingFile( 161 const std::string& resource_id, 162 const std::string& etag, 163 scoped_ptr<UploadFileInfo> upload_file_info); 164 165 // DriveService callback for InitiateUpload. 166 void OnUploadLocationReceived(scoped_ptr<UploadFileInfo> upload_file_info, 167 google_apis::GDataErrorCode code, 168 const GURL& upload_location); 169 170 // Starts to get the current upload status for the file uploading. 171 // Upon completion, OnUploadRangeResponseReceived should be called. 172 void StartGetUploadStatus(scoped_ptr<UploadFileInfo> upload_file_info); 173 174 // Uploads the next chunk of data from the file. 175 void UploadNextChunk(scoped_ptr<UploadFileInfo> upload_file_info); 176 177 // DriveService callback for ResumeUpload. 178 void OnUploadRangeResponseReceived( 179 scoped_ptr<UploadFileInfo> upload_file_info, 180 const google_apis::UploadRangeResponse& response, 181 scoped_ptr<google_apis::ResourceEntry> entry); 182 void OnUploadProgress(const google_apis::ProgressCallback& callback, 183 int64 start_position, 184 int64 total_size, 185 int64 progress_of_chunk, 186 int64 total_of_chunk); 187 188 // Handle failed uploads. 189 void UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, 190 google_apis::GDataErrorCode error); 191 192 // The lifetime of this object should be guaranteed to exceed that of the 193 // DriveUploader instance. 194 DriveServiceInterface* drive_service_; // Not owned by this class. 195 196 scoped_refptr<base::TaskRunner> blocking_task_runner_; 197 198 // Note: This should remain the last member so it'll be destroyed and 199 // invalidate its weak pointers before any other members are destroyed. 200 base::WeakPtrFactory<DriveUploader> weak_ptr_factory_; 201 DISALLOW_COPY_AND_ASSIGN(DriveUploader); 202 }; 203 204 } // namespace drive 205 206 #endif // CHROME_BROWSER_DRIVE_DRIVE_UPLOADER_H_ 207