Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/drive/drive_uploader.h" | 5 #include "chrome/browser/drive/drive_uploader.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 // bytes (except the request for uploading the last chunk of data). | 37 // bytes (except the request for uploading the last chunk of data). |
| 38 // The value must be a multiple of 512KB according to the spec of GData WAPI and | 38 // The value must be a multiple of 512KB according to the spec of GData WAPI and |
| 39 // Drive API v2. It is set to a smaller value than 2^31 for working around | 39 // Drive API v2. It is set to a smaller value than 2^31 for working around |
| 40 // server side error (crbug.com/264089). | 40 // server side error (crbug.com/264089). |
| 41 const int64 kUploadChunkSize = (1LL << 30); // 1GB | 41 const int64 kUploadChunkSize = (1LL << 30); // 1GB |
| 42 // Maximum file size to be uploaded by multipart requests. The file that is | 42 // Maximum file size to be uploaded by multipart requests. The file that is |
| 43 // larger than the size is processed by resumable upload. | 43 // larger than the size is processed by resumable upload. |
| 44 const int64 kMaxMultipartUploadSize = (1LL << 20); // 1MB | 44 const int64 kMaxMultipartUploadSize = (1LL << 20); // 1MB |
| 45 } // namespace | 45 } // namespace |
| 46 | 46 |
| 47 // Refcounted helper class to manage batch request. DriveUploader uses the class | |
| 48 // for keeping the BatchRequestConfigurator instance while it prepares upload | |
| 49 // file information asynchronously. DriveUploader discard the reference after | |
| 50 // getting file information and the instance will be destroyed after all | |
| 51 // preparations complete. At that time, the helper instance commits owned batch | |
| 52 // request at the destrutor. | |
| 53 class DriveUploader::RefCountedBatchRequest | |
| 54 : public base::RefCounted<RefCountedBatchRequest> { | |
| 55 public: | |
| 56 RefCountedBatchRequest( | |
| 57 scoped_ptr<BatchRequestConfiguratorInterface> configurator) | |
| 58 : configurator_(configurator.Pass()) {} | |
| 59 | |
| 60 // Gets pointer of BatchRequestConfiguratorInterface owned by the instance. | |
| 61 BatchRequestConfiguratorInterface* get() const { return configurator_.get(); } | |
| 62 | |
| 63 private: | |
| 64 friend class base::RefCounted<RefCountedBatchRequest>; | |
| 65 ~RefCountedBatchRequest() { configurator_->Commit(); } | |
| 66 scoped_ptr<BatchRequestConfiguratorInterface> configurator_; | |
| 67 }; | |
| 68 | |
| 47 // Structure containing current upload information of file, passed between | 69 // Structure containing current upload information of file, passed between |
| 48 // DriveServiceInterface methods and callbacks. | 70 // DriveServiceInterface methods and callbacks. |
| 49 struct DriveUploader::UploadFileInfo { | 71 struct DriveUploader::UploadFileInfo { |
| 50 UploadFileInfo(const base::FilePath& local_path, | 72 UploadFileInfo(const base::FilePath& local_path, |
| 51 const std::string& content_type, | 73 const std::string& content_type, |
| 52 const UploadCompletionCallback& callback, | 74 const UploadCompletionCallback& callback, |
| 53 const ProgressCallback& progress_callback) | 75 const ProgressCallback& progress_callback) |
| 54 : file_path(local_path), | 76 : file_path(local_path), |
| 55 content_type(content_type), | 77 content_type(content_type), |
| 56 completion_callback(callback), | 78 completion_callback(callback), |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 DCHECK(!local_file_path.empty()); | 170 DCHECK(!local_file_path.empty()); |
| 149 DCHECK(!title.empty()); | 171 DCHECK(!title.empty()); |
| 150 DCHECK(!content_type.empty()); | 172 DCHECK(!content_type.empty()); |
| 151 DCHECK(!callback.is_null()); | 173 DCHECK(!callback.is_null()); |
| 152 | 174 |
| 153 return StartUploadFile( | 175 return StartUploadFile( |
| 154 scoped_ptr<UploadFileInfo>(new UploadFileInfo( | 176 scoped_ptr<UploadFileInfo>(new UploadFileInfo( |
| 155 local_file_path, content_type, callback, progress_callback)), | 177 local_file_path, content_type, callback, progress_callback)), |
| 156 base::Bind(&DriveUploader::CallUploadServiceAPINewFile, | 178 base::Bind(&DriveUploader::CallUploadServiceAPINewFile, |
| 157 weak_ptr_factory_.GetWeakPtr(), parent_resource_id, title, | 179 weak_ptr_factory_.GetWeakPtr(), parent_resource_id, title, |
| 158 options)); | 180 options, current_batch_request_)); |
| 181 } | |
| 182 | |
| 183 void DriveUploader::StartBatchProcessing() { | |
| 184 DCHECK(current_batch_request_ == nullptr); | |
| 185 current_batch_request_ = | |
| 186 new RefCountedBatchRequest(drive_service_->StartBatchRequest().Pass()); | |
| 187 } | |
| 188 | |
| 189 void DriveUploader::StopBatchProcessing() { | |
| 190 current_batch_request_ = nullptr; | |
| 159 } | 191 } |
| 160 | 192 |
| 161 CancelCallback DriveUploader::UploadExistingFile( | 193 CancelCallback DriveUploader::UploadExistingFile( |
| 162 const std::string& resource_id, | 194 const std::string& resource_id, |
| 163 const base::FilePath& local_file_path, | 195 const base::FilePath& local_file_path, |
| 164 const std::string& content_type, | 196 const std::string& content_type, |
| 165 const UploadExistingFileOptions& options, | 197 const UploadExistingFileOptions& options, |
| 166 const UploadCompletionCallback& callback, | 198 const UploadCompletionCallback& callback, |
| 167 const ProgressCallback& progress_callback) { | 199 const ProgressCallback& progress_callback) { |
| 168 DCHECK(thread_checker_.CalledOnValidThread()); | 200 DCHECK(thread_checker_.CalledOnValidThread()); |
| 169 DCHECK(!resource_id.empty()); | 201 DCHECK(!resource_id.empty()); |
| 170 DCHECK(!local_file_path.empty()); | 202 DCHECK(!local_file_path.empty()); |
| 171 DCHECK(!content_type.empty()); | 203 DCHECK(!content_type.empty()); |
| 172 DCHECK(!callback.is_null()); | 204 DCHECK(!callback.is_null()); |
| 173 | 205 |
| 174 return StartUploadFile( | 206 return StartUploadFile( |
| 175 scoped_ptr<UploadFileInfo>(new UploadFileInfo( | 207 scoped_ptr<UploadFileInfo>(new UploadFileInfo( |
| 176 local_file_path, content_type, callback, progress_callback)), | 208 local_file_path, content_type, callback, progress_callback)), |
| 177 base::Bind(&DriveUploader::CallUploadServiceAPIExistingFile, | 209 base::Bind(&DriveUploader::CallUploadServiceAPIExistingFile, |
| 178 weak_ptr_factory_.GetWeakPtr(), resource_id, options)); | 210 weak_ptr_factory_.GetWeakPtr(), resource_id, options, |
| 211 current_batch_request_)); | |
| 179 } | 212 } |
| 180 | 213 |
| 181 CancelCallback DriveUploader::ResumeUploadFile( | 214 CancelCallback DriveUploader::ResumeUploadFile( |
| 182 const GURL& upload_location, | 215 const GURL& upload_location, |
| 183 const base::FilePath& local_file_path, | 216 const base::FilePath& local_file_path, |
| 184 const std::string& content_type, | 217 const std::string& content_type, |
| 185 const UploadCompletionCallback& callback, | 218 const UploadCompletionCallback& callback, |
| 186 const ProgressCallback& progress_callback) { | 219 const ProgressCallback& progress_callback) { |
| 187 DCHECK(thread_checker_.CalledOnValidThread()); | 220 DCHECK(thread_checker_.CalledOnValidThread()); |
| 188 DCHECK(!local_file_path.empty()); | 221 DCHECK(!local_file_path.empty()); |
| 189 DCHECK(!content_type.empty()); | 222 DCHECK(!content_type.empty()); |
| 190 DCHECK(!callback.is_null()); | 223 DCHECK(!callback.is_null()); |
| 191 | 224 |
| 192 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( | 225 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( |
| 193 local_file_path, content_type, | 226 local_file_path, content_type, callback, progress_callback)); |
| 194 callback, progress_callback)); | |
| 195 upload_file_info->upload_location = upload_location; | 227 upload_file_info->upload_location = upload_location; |
| 196 | 228 |
| 197 return StartUploadFile( | 229 return StartUploadFile( |
| 198 upload_file_info.Pass(), | 230 upload_file_info.Pass(), |
| 199 base::Bind(&DriveUploader::StartGetUploadStatus, | 231 base::Bind(&DriveUploader::StartGetUploadStatus, |
| 200 weak_ptr_factory_.GetWeakPtr())); | 232 weak_ptr_factory_.GetWeakPtr())); |
| 201 } | 233 } |
| 202 | 234 |
| 203 CancelCallback DriveUploader::StartUploadFile( | 235 CancelCallback DriveUploader::StartUploadFile( |
| 204 scoped_ptr<UploadFileInfo> upload_file_info, | 236 scoped_ptr<UploadFileInfo> upload_file_info, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 UploadFailed(upload_file_info.Pass(), DRIVE_CANCELLED); | 268 UploadFailed(upload_file_info.Pass(), DRIVE_CANCELLED); |
| 237 return; | 269 return; |
| 238 } | 270 } |
| 239 start_initiate_upload_callback.Run(upload_file_info.Pass()); | 271 start_initiate_upload_callback.Run(upload_file_info.Pass()); |
| 240 } | 272 } |
| 241 | 273 |
| 242 void DriveUploader::CallUploadServiceAPINewFile( | 274 void DriveUploader::CallUploadServiceAPINewFile( |
| 243 const std::string& parent_resource_id, | 275 const std::string& parent_resource_id, |
| 244 const std::string& title, | 276 const std::string& title, |
| 245 const UploadNewFileOptions& options, | 277 const UploadNewFileOptions& options, |
| 278 const scoped_refptr<RefCountedBatchRequest>& batch_request, | |
| 246 scoped_ptr<UploadFileInfo> upload_file_info) { | 279 scoped_ptr<UploadFileInfo> upload_file_info) { |
| 247 DCHECK(thread_checker_.CalledOnValidThread()); | 280 DCHECK(thread_checker_.CalledOnValidThread()); |
| 248 | 281 |
| 249 UploadFileInfo* const info_ptr = upload_file_info.get(); | 282 UploadFileInfo* const info_ptr = upload_file_info.get(); |
| 250 if (info_ptr->content_length <= kMaxMultipartUploadSize) { | 283 if (info_ptr->content_length <= kMaxMultipartUploadSize) { |
| 251 info_ptr->cancel_callback = drive_service_->MultipartUploadNewFile( | 284 DriveServiceBatchOperationsInterface* service = drive_service_; |
| 285 // If this is a batched request, calls the API on the request instead. | |
| 286 if (batch_request.get()) | |
| 287 service = batch_request->get(); | |
| 288 info_ptr->cancel_callback = service->MultipartUploadNewFile( | |
| 252 info_ptr->content_type, info_ptr->content_length, parent_resource_id, | 289 info_ptr->content_type, info_ptr->content_length, parent_resource_id, |
| 253 title, info_ptr->file_path, options, | 290 title, info_ptr->file_path, options, |
| 254 base::Bind(&DriveUploader::OnMultipartUploadComplete, | 291 base::Bind(&DriveUploader::OnMultipartUploadComplete, |
| 255 weak_ptr_factory_.GetWeakPtr(), | 292 weak_ptr_factory_.GetWeakPtr(), |
| 256 base::Passed(&upload_file_info)), | 293 base::Passed(&upload_file_info)), |
| 257 info_ptr->progress_callback); | 294 info_ptr->progress_callback); |
| 258 } else { | 295 } else { |
| 259 info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( | 296 info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( |
| 260 info_ptr->content_type, info_ptr->content_length, parent_resource_id, | 297 info_ptr->content_type, info_ptr->content_length, parent_resource_id, |
| 261 title, options, base::Bind(&DriveUploader::OnUploadLocationReceived, | 298 title, options, base::Bind(&DriveUploader::OnUploadLocationReceived, |
| 262 weak_ptr_factory_.GetWeakPtr(), | 299 weak_ptr_factory_.GetWeakPtr(), |
| 263 base::Passed(&upload_file_info))); | 300 base::Passed(&upload_file_info))); |
| 264 } | 301 } |
| 265 } | 302 } |
| 266 | 303 |
| 267 void DriveUploader::CallUploadServiceAPIExistingFile( | 304 void DriveUploader::CallUploadServiceAPIExistingFile( |
| 268 const std::string& resource_id, | 305 const std::string& resource_id, |
| 269 const UploadExistingFileOptions& options, | 306 const UploadExistingFileOptions& options, |
| 307 const scoped_refptr<RefCountedBatchRequest>& batch_request, | |
| 270 scoped_ptr<UploadFileInfo> upload_file_info) { | 308 scoped_ptr<UploadFileInfo> upload_file_info) { |
| 271 DCHECK(thread_checker_.CalledOnValidThread()); | 309 DCHECK(thread_checker_.CalledOnValidThread()); |
| 272 | 310 |
| 273 UploadFileInfo* const info_ptr = upload_file_info.get(); | 311 UploadFileInfo* const info_ptr = upload_file_info.get(); |
| 274 if (info_ptr->content_length <= kMaxMultipartUploadSize) { | 312 if (info_ptr->content_length <= kMaxMultipartUploadSize) { |
| 275 info_ptr->cancel_callback = drive_service_->MultipartUploadExistingFile( | 313 DriveServiceBatchOperationsInterface* service = drive_service_; |
| 314 // If this is a batched request, calls the API on the request instead. | |
| 315 if (batch_request.get()) | |
| 316 service = batch_request->get(); | |
|
kinaba
2015/05/11 05:33:14
Let's rename RefCountedBatchRequest::get to someth
hirono
2015/05/11 05:53:30
Yes totally agree with you. Done.
| |
| 317 info_ptr->cancel_callback = service->MultipartUploadExistingFile( | |
| 276 info_ptr->content_type, info_ptr->content_length, resource_id, | 318 info_ptr->content_type, info_ptr->content_length, resource_id, |
| 277 info_ptr->file_path, options, | 319 info_ptr->file_path, options, |
| 278 base::Bind(&DriveUploader::OnMultipartUploadComplete, | 320 base::Bind(&DriveUploader::OnMultipartUploadComplete, |
| 279 weak_ptr_factory_.GetWeakPtr(), | 321 weak_ptr_factory_.GetWeakPtr(), |
| 280 base::Passed(&upload_file_info)), | 322 base::Passed(&upload_file_info)), |
| 281 info_ptr->progress_callback); | 323 info_ptr->progress_callback); |
| 282 } else { | 324 } else { |
| 283 info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( | 325 info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( |
| 284 info_ptr->content_type, info_ptr->content_length, resource_id, options, | 326 info_ptr->content_type, info_ptr->content_length, resource_id, options, |
| 285 base::Bind(&DriveUploader::OnUploadLocationReceived, | 327 base::Bind(&DriveUploader::OnUploadLocationReceived, |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 } else { | 495 } else { |
| 454 DVLOG(1) << "Upload failed " << upload_file_info->DebugString(); | 496 DVLOG(1) << "Upload failed " << upload_file_info->DebugString(); |
| 455 if (error == HTTP_PRECONDITION) | 497 if (error == HTTP_PRECONDITION) |
| 456 error = HTTP_CONFLICT; // ETag mismatch. | 498 error = HTTP_CONFLICT; // ETag mismatch. |
| 457 upload_file_info->completion_callback.Run( | 499 upload_file_info->completion_callback.Run( |
| 458 error, upload_file_info->upload_location, scoped_ptr<FileResource>()); | 500 error, upload_file_info->upload_location, scoped_ptr<FileResource>()); |
| 459 } | 501 } |
| 460 } | 502 } |
| 461 | 503 |
| 462 } // namespace drive | 504 } // namespace drive |
| OLD | NEW |