Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_uploader.cc

Issue 10540132: gdata: Convert GDataFileSystem::AddUploadFile() to asynchronous. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add comments to explain why Patch Set #11 is necesary. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/chromeos/gdata/gdata_uploader.h" 5 #include "chrome/browser/chromeos/gdata/gdata_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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // Create buffer to hold upload data. 66 // Create buffer to hold upload data.
67 info->buf_len = std::min(info->file_size, kUploadChunkSize); 67 info->buf_len = std::min(info->file_size, kUploadChunkSize);
68 info->buf = new net::IOBuffer(info->buf_len); 68 info->buf = new net::IOBuffer(info->buf_len);
69 69
70 OpenFile(info); 70 OpenFile(info);
71 return upload_id; 71 return upload_id;
72 } 72 }
73 73
74 void GDataUploader::UpdateUpload(int upload_id, 74 void GDataUploader::UpdateUpload(int upload_id,
75 content::DownloadItem* download) { 75 content::DownloadItem* download) {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77
76 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); 78 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id);
77 if (!upload_file_info) 79 if (!upload_file_info)
78 return; 80 return;
79 81
80 const int64 file_size = download->GetReceivedBytes(); 82 const int64 file_size = download->GetReceivedBytes();
81 83
82 // Update file_size and all_bytes_present. 84 // Update file_size and all_bytes_present.
83 DVLOG(1) << "Updating file size from " << upload_file_info->file_size 85 DVLOG(1) << "Updating file size from " << upload_file_info->file_size
84 << " to " << file_size 86 << " to " << file_size
85 << (download->AllDataSaved() ? " (AllDataSaved)" : " (In-progress)"); 87 << (download->AllDataSaved() ? " (AllDataSaved)" : " (In-progress)");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 173
172 DVLOG(1) << "Error opening \"" << upload_file_info->file_path.value() 174 DVLOG(1) << "Error opening \"" << upload_file_info->file_path.value()
173 << "\" for reading: " << net::ErrorToString(result) 175 << "\" for reading: " << net::ErrorToString(result)
174 << ", tries=" << upload_file_info->num_file_open_tries; 176 << ", tries=" << upload_file_info->num_file_open_tries;
175 177
176 // Stop trying to open this file if we exceed kMaxFileOpenTries. 178 // Stop trying to open this file if we exceed kMaxFileOpenTries.
177 const bool exceeded_max_attempts = 179 const bool exceeded_max_attempts =
178 upload_file_info->num_file_open_tries >= kMaxFileOpenTries; 180 upload_file_info->num_file_open_tries >= kMaxFileOpenTries;
179 upload_file_info->should_retry_file_open = !exceeded_max_attempts; 181 upload_file_info->should_retry_file_open = !exceeded_max_attempts;
180 if (exceeded_max_attempts) 182 if (exceeded_max_attempts)
181 UploadFailed(upload_file_info, base::PLATFORM_FILE_ERROR_NOT_FOUND); 183 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
184 base::PLATFORM_FILE_ERROR_NOT_FOUND);
182 185
183 return; 186 return;
184 } 187 }
185 188
186 // Open succeeded, initiate the upload. 189 // Open succeeded, initiate the upload.
187 upload_file_info->should_retry_file_open = false; 190 upload_file_info->should_retry_file_open = false;
188 const GURL destination_directory_url = file_system_->GetUploadUrlForDirectory( 191 const GURL destination_directory_url = file_system_->GetUploadUrlForDirectory(
189 upload_file_info->gdata_path.DirName()); 192 upload_file_info->gdata_path.DirName());
190 if (destination_directory_url.is_empty()) { 193 if (destination_directory_url.is_empty()) {
191 UploadFailed(upload_file_info, base::PLATFORM_FILE_ERROR_ABORT); 194 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
195 base::PLATFORM_FILE_ERROR_ABORT);
192 return; 196 return;
193 } 197 }
194 198
195 documents_service_->InitiateUpload( 199 documents_service_->InitiateUpload(
196 InitiateUploadParams(upload_file_info->title, 200 InitiateUploadParams(upload_file_info->title,
197 upload_file_info->content_type, 201 upload_file_info->content_type,
198 upload_file_info->content_length, 202 upload_file_info->content_length,
199 destination_directory_url, 203 destination_directory_url,
200 upload_file_info->gdata_path), 204 upload_file_info->gdata_path),
201 base::Bind(&GDataUploader::OnUploadLocationReceived, 205 base::Bind(&GDataUploader::OnUploadLocationReceived,
202 uploader_factory_.GetWeakPtr(), 206 uploader_factory_.GetWeakPtr(),
203 upload_file_info->upload_id)); 207 upload_file_info->upload_id));
204 } 208 }
205 209
206 void GDataUploader::OnUploadLocationReceived( 210 void GDataUploader::OnUploadLocationReceived(
207 int upload_id, 211 int upload_id,
208 GDataErrorCode code, 212 GDataErrorCode code,
209 const GURL& upload_location) { 213 const GURL& upload_location) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 215
212 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); 216 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id);
213 if (!upload_file_info) 217 if (!upload_file_info)
214 return; 218 return;
215 219
216 DVLOG(1) << "Got upload location [" << upload_location.spec() 220 DVLOG(1) << "Got upload location [" << upload_location.spec()
217 << "] for [" << upload_file_info->title << "]"; 221 << "] for [" << upload_file_info->title << "]";
218 222
219 if (code != HTTP_SUCCESS) { 223 if (code != HTTP_SUCCESS) {
220 // TODO(achuith): Handle error codes from Google Docs server. 224 // TODO(achuith): Handle error codes from Google Docs server.
221 UploadFailed(upload_file_info, base::PLATFORM_FILE_ERROR_ABORT); 225 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info),
226 base::PLATFORM_FILE_ERROR_ABORT);
222 return; 227 return;
223 } 228 }
224 229
225 upload_file_info->upload_location = upload_location; 230 upload_file_info->upload_location = upload_location;
226 231
227 // Start the upload from the beginning of the file. 232 // Start the upload from the beginning of the file.
228 UploadNextChunk(upload_file_info); 233 UploadNextChunk(upload_file_info);
229 } 234 }
230 235
231 void GDataUploader::UploadNextChunk(UploadFileInfo* upload_file_info) { 236 void GDataUploader::UploadNextChunk(UploadFileInfo* upload_file_info) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
307 312
308 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); 313 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id);
309 if (!upload_file_info) 314 if (!upload_file_info)
310 return; 315 return;
311 316
312 if (response.code == HTTP_CREATED) { 317 if (response.code == HTTP_CREATED) {
313 DVLOG(1) << "Successfully created uploaded file=[" 318 DVLOG(1) << "Successfully created uploaded file=["
314 << upload_file_info->title; 319 << upload_file_info->title;
315 320
321 // Remove |upload_id| from the UploadFileInfoMap. The UploadFileInfo object
322 // will be deleted upon completion of completion_callback.
323 RemoveUpload(upload_id);
324
316 // Done uploading. 325 // Done uploading.
317 upload_file_info->entry = entry.Pass(); 326 upload_file_info->entry = entry.Pass();
318 if (!upload_file_info->completion_callback.is_null()) { 327 if (!upload_file_info->completion_callback.is_null()) {
319 upload_file_info->completion_callback.Run(base::PLATFORM_FILE_OK, 328 upload_file_info->completion_callback.Run(
320 upload_file_info); 329 base::PLATFORM_FILE_OK,
330 scoped_ptr<UploadFileInfo>(upload_file_info));
321 } 331 }
322 // TODO(achuith): DeleteUpload() here and let clients call
323 // GDataFileSystem::AddUploadedFile.
324 return; 332 return;
325 } 333 }
326 334
327 // If code is 308 (RESUME_INCOMPLETE) and range_received is what has been 335 // If code is 308 (RESUME_INCOMPLETE) and range_received is what has been
328 // previously uploaded (i.e. = upload_file_info->end_range), proceed to 336 // previously uploaded (i.e. = upload_file_info->end_range), proceed to
329 // upload the next chunk. 337 // upload the next chunk.
330 if (response.code != HTTP_RESUME_INCOMPLETE || 338 if (response.code != HTTP_RESUME_INCOMPLETE ||
331 response.start_range_received != 0 || 339 response.start_range_received != 0 ||
332 response.end_range_received != upload_file_info->end_range) { 340 response.end_range_received != upload_file_info->end_range) {
333 // TODO(achuith): Handle error cases, e.g. 341 // TODO(achuith): Handle error cases, e.g.
334 // - when previously uploaded data wasn't received by Google Docs server, 342 // - when previously uploaded data wasn't received by Google Docs server,
335 // i.e. when end_range_received < upload_file_info->end_range 343 // i.e. when end_range_received < upload_file_info->end_range
336 LOG(ERROR) << "UploadNextChunk http code=" << response.code 344 LOG(ERROR) << "UploadNextChunk http code=" << response.code
337 << ", start_range_received=" << response.start_range_received 345 << ", start_range_received=" << response.start_range_received
338 << ", end_range_received=" << response.end_range_received 346 << ", end_range_received=" << response.end_range_received
339 << ", expected end range=" << upload_file_info->end_range; 347 << ", expected end range=" << upload_file_info->end_range;
340 UploadFailed(upload_file_info, 348 UploadFailed(
349 scoped_ptr<UploadFileInfo>(upload_file_info),
341 response.code == HTTP_FORBIDDEN ? 350 response.code == HTTP_FORBIDDEN ?
342 base::PLATFORM_FILE_ERROR_NO_SPACE : 351 base::PLATFORM_FILE_ERROR_NO_SPACE :
343 base::PLATFORM_FILE_ERROR_ABORT); 352 base::PLATFORM_FILE_ERROR_ABORT);
344 return; 353 return;
345 } 354 }
346 355
347 DVLOG(1) << "Received range " << response.start_range_received 356 DVLOG(1) << "Received range " << response.start_range_received
348 << "-" << response.end_range_received 357 << "-" << response.end_range_received
349 << " for [" << upload_file_info->title << "]"; 358 << " for [" << upload_file_info->title << "]";
350 359
351 // Continue uploading. 360 // Continue uploading.
352 UploadNextChunk(upload_file_info); 361 UploadNextChunk(upload_file_info);
353 } 362 }
354 363
355 void GDataUploader::MoveFileToCache(UploadFileInfo* upload_file_info) { 364 void GDataUploader::MoveFileToCache(UploadFileInfo* upload_file_info) {
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
357 if (upload_file_info->entry == NULL) 366 if (upload_file_info->entry == NULL)
358 return; 367 return;
359 368
369 // Remove |upload_id| from the UploadFileInfoMap. The UploadFileInfo object
370 // will be deleted upon completion of AddUploadedFile.
371 RemoveUpload(upload_file_info->upload_id);
372
360 DVLOG(1) << "MoveFileToCache " << upload_file_info->file_path.value(); 373 DVLOG(1) << "MoveFileToCache " << upload_file_info->file_path.value();
361 file_system_->AddUploadedFile( 374 file_system_->AddUploadedFile(
362 upload_file_info->gdata_path.DirName(), 375 upload_file_info->gdata_path.DirName(),
363 upload_file_info->entry.get(), 376 upload_file_info->entry.get(),
364 upload_file_info->file_path, 377 upload_file_info->file_path,
365 GDataCache::FILE_OPERATION_MOVE); 378 GDataCache::FILE_OPERATION_MOVE,
366 DeleteUpload(upload_file_info); 379 base::Bind(&base::DeletePointer<UploadFileInfo>,
380 upload_file_info));
367 } 381 }
368 382
369 void GDataUploader::UploadFailed(UploadFileInfo* upload_file_info, 383 void GDataUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
370 base::PlatformFileError error) { 384 base::PlatformFileError error) {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
386
387 RemoveUpload(upload_file_info->upload_id);
388
372 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString(); 389 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString();
373 if (!upload_file_info->completion_callback.is_null()) { 390 if (!upload_file_info->completion_callback.is_null()) {
374 upload_file_info->completion_callback.Run(error, 391 upload_file_info->completion_callback.Run(error,
375 upload_file_info); 392 upload_file_info.Pass());
376 } 393 }
377 DeleteUpload(upload_file_info);
378 } 394 }
379 395
380 void GDataUploader::DeleteUpload(UploadFileInfo* upload_file_info) { 396 void GDataUploader::RemoveUpload(int upload_id) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382 398 pending_uploads_.erase(upload_id);
383 DVLOG(1) << "Deleting upload " << upload_file_info->gdata_path.value();
384 pending_uploads_.erase(upload_file_info->upload_id);
385
386 // The file stream is closed by the destructor asynchronously.
387 delete upload_file_info->file_stream;
388 delete upload_file_info;
389 } 399 }
390 400
391 } // namespace gdata 401 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_uploader.h ('k') | chrome/browser/chromeos/gdata/mock_gdata_file_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698