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. When the instance is | |
48 // destroyed, it commits owned batch request. | |
kinaba
2015/05/08 06:58:12
Please add some comment on why refcounted control
hirono
2015/05/11 05:22:05
Done.
| |
49 class DriveUploader::RefCountedBatchRequest | |
50 : public base::RefCounted<RefCountedBatchRequest> { | |
51 public: | |
52 RefCountedBatchRequest( | |
53 scoped_ptr<BatchRequestConfiguratorInterface> configurator) | |
54 : configurator_(configurator.Pass()) {} | |
55 | |
56 // Gets pointer of BatchRequestConfiguratorInterface owned by the instance. | |
57 BatchRequestConfiguratorInterface* get() const { return configurator_.get(); } | |
58 | |
59 private: | |
60 friend class base::RefCounted<RefCountedBatchRequest>; | |
61 ~RefCountedBatchRequest() { configurator_->Commit(); } | |
62 scoped_ptr<BatchRequestConfiguratorInterface> configurator_; | |
63 }; | |
64 | |
47 // Structure containing current upload information of file, passed between | 65 // Structure containing current upload information of file, passed between |
48 // DriveServiceInterface methods and callbacks. | 66 // DriveServiceInterface methods and callbacks. |
49 struct DriveUploader::UploadFileInfo { | 67 struct DriveUploader::UploadFileInfo { |
50 UploadFileInfo(const base::FilePath& local_path, | 68 UploadFileInfo(const base::FilePath& local_path, |
51 const std::string& content_type, | 69 const std::string& content_type, |
52 const UploadCompletionCallback& callback, | 70 const UploadCompletionCallback& callback, |
53 const ProgressCallback& progress_callback) | 71 const ProgressCallback& progress_callback) |
54 : file_path(local_path), | 72 : file_path(local_path), |
55 content_type(content_type), | 73 content_type(content_type), |
56 completion_callback(callback), | 74 completion_callback(callback), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 DCHECK(!local_file_path.empty()); | 166 DCHECK(!local_file_path.empty()); |
149 DCHECK(!title.empty()); | 167 DCHECK(!title.empty()); |
150 DCHECK(!content_type.empty()); | 168 DCHECK(!content_type.empty()); |
151 DCHECK(!callback.is_null()); | 169 DCHECK(!callback.is_null()); |
152 | 170 |
153 return StartUploadFile( | 171 return StartUploadFile( |
154 scoped_ptr<UploadFileInfo>(new UploadFileInfo( | 172 scoped_ptr<UploadFileInfo>(new UploadFileInfo( |
155 local_file_path, content_type, callback, progress_callback)), | 173 local_file_path, content_type, callback, progress_callback)), |
156 base::Bind(&DriveUploader::CallUploadServiceAPINewFile, | 174 base::Bind(&DriveUploader::CallUploadServiceAPINewFile, |
157 weak_ptr_factory_.GetWeakPtr(), parent_resource_id, title, | 175 weak_ptr_factory_.GetWeakPtr(), parent_resource_id, title, |
158 options)); | 176 options, current_batch_request_)); |
177 } | |
178 | |
179 void DriveUploader::StartBatchProcessing() { | |
kinaba
2015/05/08 06:58:12
DCHECK(current_batch_request_ == null)?
hirono
2015/05/11 05:22:06
Done.
| |
180 current_batch_request_ = | |
181 new RefCountedBatchRequest(drive_service_->StartBatchRequest().Pass()); | |
182 } | |
183 | |
184 void DriveUploader::StopBatchProcessing() { | |
185 current_batch_request_ = nullptr; | |
159 } | 186 } |
160 | 187 |
161 CancelCallback DriveUploader::UploadExistingFile( | 188 CancelCallback DriveUploader::UploadExistingFile( |
162 const std::string& resource_id, | 189 const std::string& resource_id, |
163 const base::FilePath& local_file_path, | 190 const base::FilePath& local_file_path, |
164 const std::string& content_type, | 191 const std::string& content_type, |
165 const UploadExistingFileOptions& options, | 192 const UploadExistingFileOptions& options, |
166 const UploadCompletionCallback& callback, | 193 const UploadCompletionCallback& callback, |
167 const ProgressCallback& progress_callback) { | 194 const ProgressCallback& progress_callback) { |
168 DCHECK(thread_checker_.CalledOnValidThread()); | 195 DCHECK(thread_checker_.CalledOnValidThread()); |
169 DCHECK(!resource_id.empty()); | 196 DCHECK(!resource_id.empty()); |
170 DCHECK(!local_file_path.empty()); | 197 DCHECK(!local_file_path.empty()); |
171 DCHECK(!content_type.empty()); | 198 DCHECK(!content_type.empty()); |
172 DCHECK(!callback.is_null()); | 199 DCHECK(!callback.is_null()); |
173 | 200 |
174 return StartUploadFile( | 201 return StartUploadFile( |
175 scoped_ptr<UploadFileInfo>(new UploadFileInfo( | 202 scoped_ptr<UploadFileInfo>(new UploadFileInfo( |
176 local_file_path, content_type, callback, progress_callback)), | 203 local_file_path, content_type, callback, progress_callback)), |
177 base::Bind(&DriveUploader::CallUploadServiceAPIExistingFile, | 204 base::Bind(&DriveUploader::CallUploadServiceAPIExistingFile, |
178 weak_ptr_factory_.GetWeakPtr(), resource_id, options)); | 205 weak_ptr_factory_.GetWeakPtr(), resource_id, options, |
206 current_batch_request_)); | |
179 } | 207 } |
180 | 208 |
181 CancelCallback DriveUploader::ResumeUploadFile( | 209 CancelCallback DriveUploader::ResumeUploadFile( |
182 const GURL& upload_location, | 210 const GURL& upload_location, |
183 const base::FilePath& local_file_path, | 211 const base::FilePath& local_file_path, |
184 const std::string& content_type, | 212 const std::string& content_type, |
185 const UploadCompletionCallback& callback, | 213 const UploadCompletionCallback& callback, |
186 const ProgressCallback& progress_callback) { | 214 const ProgressCallback& progress_callback) { |
187 DCHECK(thread_checker_.CalledOnValidThread()); | 215 DCHECK(thread_checker_.CalledOnValidThread()); |
188 DCHECK(!local_file_path.empty()); | 216 DCHECK(!local_file_path.empty()); |
189 DCHECK(!content_type.empty()); | 217 DCHECK(!content_type.empty()); |
190 DCHECK(!callback.is_null()); | 218 DCHECK(!callback.is_null()); |
191 | 219 |
192 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( | 220 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( |
193 local_file_path, content_type, | 221 local_file_path, content_type, callback, progress_callback)); |
194 callback, progress_callback)); | |
195 upload_file_info->upload_location = upload_location; | 222 upload_file_info->upload_location = upload_location; |
196 | 223 |
197 return StartUploadFile( | 224 return StartUploadFile( |
198 upload_file_info.Pass(), | 225 upload_file_info.Pass(), |
199 base::Bind(&DriveUploader::StartGetUploadStatus, | 226 base::Bind(&DriveUploader::StartGetUploadStatus, |
200 weak_ptr_factory_.GetWeakPtr())); | 227 weak_ptr_factory_.GetWeakPtr())); |
201 } | 228 } |
202 | 229 |
203 CancelCallback DriveUploader::StartUploadFile( | 230 CancelCallback DriveUploader::StartUploadFile( |
204 scoped_ptr<UploadFileInfo> upload_file_info, | 231 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); | 263 UploadFailed(upload_file_info.Pass(), DRIVE_CANCELLED); |
237 return; | 264 return; |
238 } | 265 } |
239 start_initiate_upload_callback.Run(upload_file_info.Pass()); | 266 start_initiate_upload_callback.Run(upload_file_info.Pass()); |
240 } | 267 } |
241 | 268 |
242 void DriveUploader::CallUploadServiceAPINewFile( | 269 void DriveUploader::CallUploadServiceAPINewFile( |
243 const std::string& parent_resource_id, | 270 const std::string& parent_resource_id, |
244 const std::string& title, | 271 const std::string& title, |
245 const UploadNewFileOptions& options, | 272 const UploadNewFileOptions& options, |
273 const scoped_refptr<RefCountedBatchRequest>& batch_request, | |
246 scoped_ptr<UploadFileInfo> upload_file_info) { | 274 scoped_ptr<UploadFileInfo> upload_file_info) { |
247 DCHECK(thread_checker_.CalledOnValidThread()); | 275 DCHECK(thread_checker_.CalledOnValidThread()); |
248 | 276 |
249 UploadFileInfo* const info_ptr = upload_file_info.get(); | 277 UploadFileInfo* const info_ptr = upload_file_info.get(); |
250 if (info_ptr->content_length <= kMaxMultipartUploadSize) { | 278 if (info_ptr->content_length <= kMaxMultipartUploadSize) { |
251 info_ptr->cancel_callback = drive_service_->MultipartUploadNewFile( | 279 DriveServiceBatchOperationsInterface* const service = |
280 batch_request.get() | |
281 ? static_cast<DriveServiceBatchOperationsInterface*>( | |
282 batch_request.get()->get()) | |
283 : static_cast<DriveServiceBatchOperationsInterface*>( | |
284 drive_service_); | |
kinaba
2015/05/08 06:58:12
I can understand the preference to constness, but
hirono
2015/05/11 05:22:06
Done.
| |
285 info_ptr->cancel_callback = service->MultipartUploadNewFile( | |
252 info_ptr->content_type, info_ptr->content_length, parent_resource_id, | 286 info_ptr->content_type, info_ptr->content_length, parent_resource_id, |
253 title, info_ptr->file_path, options, | 287 title, info_ptr->file_path, options, |
254 base::Bind(&DriveUploader::OnMultipartUploadComplete, | 288 base::Bind(&DriveUploader::OnMultipartUploadComplete, |
255 weak_ptr_factory_.GetWeakPtr(), | 289 weak_ptr_factory_.GetWeakPtr(), |
256 base::Passed(&upload_file_info)), | 290 base::Passed(&upload_file_info)), |
257 info_ptr->progress_callback); | 291 info_ptr->progress_callback); |
258 } else { | 292 } else { |
259 info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( | 293 info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( |
260 info_ptr->content_type, info_ptr->content_length, parent_resource_id, | 294 info_ptr->content_type, info_ptr->content_length, parent_resource_id, |
261 title, options, base::Bind(&DriveUploader::OnUploadLocationReceived, | 295 title, options, base::Bind(&DriveUploader::OnUploadLocationReceived, |
262 weak_ptr_factory_.GetWeakPtr(), | 296 weak_ptr_factory_.GetWeakPtr(), |
263 base::Passed(&upload_file_info))); | 297 base::Passed(&upload_file_info))); |
264 } | 298 } |
265 } | 299 } |
266 | 300 |
267 void DriveUploader::CallUploadServiceAPIExistingFile( | 301 void DriveUploader::CallUploadServiceAPIExistingFile( |
268 const std::string& resource_id, | 302 const std::string& resource_id, |
269 const UploadExistingFileOptions& options, | 303 const UploadExistingFileOptions& options, |
304 const scoped_refptr<RefCountedBatchRequest>& batch_request, | |
270 scoped_ptr<UploadFileInfo> upload_file_info) { | 305 scoped_ptr<UploadFileInfo> upload_file_info) { |
271 DCHECK(thread_checker_.CalledOnValidThread()); | 306 DCHECK(thread_checker_.CalledOnValidThread()); |
272 | 307 |
273 UploadFileInfo* const info_ptr = upload_file_info.get(); | 308 UploadFileInfo* const info_ptr = upload_file_info.get(); |
274 if (info_ptr->content_length <= kMaxMultipartUploadSize) { | 309 if (info_ptr->content_length <= kMaxMultipartUploadSize) { |
275 info_ptr->cancel_callback = drive_service_->MultipartUploadExistingFile( | 310 DriveServiceBatchOperationsInterface* const service = |
311 batch_request.get() | |
312 ? static_cast<DriveServiceBatchOperationsInterface*>( | |
313 batch_request.get()->get()) | |
314 : static_cast<DriveServiceBatchOperationsInterface*>( | |
315 drive_service_); | |
kinaba
2015/05/08 06:58:12
ditto.
hirono
2015/05/11 05:22:06
Done.
| |
316 info_ptr->cancel_callback = service->MultipartUploadExistingFile( | |
276 info_ptr->content_type, info_ptr->content_length, resource_id, | 317 info_ptr->content_type, info_ptr->content_length, resource_id, |
277 info_ptr->file_path, options, | 318 info_ptr->file_path, options, |
278 base::Bind(&DriveUploader::OnMultipartUploadComplete, | 319 base::Bind(&DriveUploader::OnMultipartUploadComplete, |
279 weak_ptr_factory_.GetWeakPtr(), | 320 weak_ptr_factory_.GetWeakPtr(), |
280 base::Passed(&upload_file_info)), | 321 base::Passed(&upload_file_info)), |
281 info_ptr->progress_callback); | 322 info_ptr->progress_callback); |
282 } else { | 323 } else { |
283 info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( | 324 info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( |
284 info_ptr->content_type, info_ptr->content_length, resource_id, options, | 325 info_ptr->content_type, info_ptr->content_length, resource_id, options, |
285 base::Bind(&DriveUploader::OnUploadLocationReceived, | 326 base::Bind(&DriveUploader::OnUploadLocationReceived, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 } else { | 494 } else { |
454 DVLOG(1) << "Upload failed " << upload_file_info->DebugString(); | 495 DVLOG(1) << "Upload failed " << upload_file_info->DebugString(); |
455 if (error == HTTP_PRECONDITION) | 496 if (error == HTTP_PRECONDITION) |
456 error = HTTP_CONFLICT; // ETag mismatch. | 497 error = HTTP_CONFLICT; // ETag mismatch. |
457 upload_file_info->completion_callback.Run( | 498 upload_file_info->completion_callback.Run( |
458 error, upload_file_info->upload_location, scoped_ptr<FileResource>()); | 499 error, upload_file_info->upload_location, scoped_ptr<FileResource>()); |
459 } | 500 } |
460 } | 501 } |
461 | 502 |
462 } // namespace drive | 503 } // namespace drive |
OLD | NEW |