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

Side by Side Diff: content/browser/download/download_manager.cc

Issue 7646025: Detect file system errors during downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk. Created 9 years, 3 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/download/download_manager.h" 5 #include "content/browser/download/download_manager.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 if (download->IsInProgress()) { 343 if (download->IsInProgress()) {
344 download->Update(size); 344 download->Update(size);
345 UpdateDownloadProgress(); // Reflect size updates. 345 UpdateDownloadProgress(); // Reflect size updates.
346 delegate_->UpdateItemInPersistentStore(download); 346 delegate_->UpdateItemInPersistentStore(download);
347 } 347 }
348 } 348 }
349 } 349 }
350 350
351 void DownloadManager::OnResponseCompleted(int32 download_id, 351 void DownloadManager::OnResponseCompleted(int32 download_id,
352 int64 size, 352 int64 size,
353 int os_error,
354 const std::string& hash) { 353 const std::string& hash) {
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
356 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
357 // advertise a larger Content-Length than the amount of bytes in the message
358 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
359 // and Safari 5.0.4 - treat the download as complete in this case, so we
360 // follow their lead.
361 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) {
362 OnAllDataSaved(download_id, size, hash);
363 } else {
364 OnDownloadError(download_id, size, os_error);
365 }
366 }
367
368 void DownloadManager::OnAllDataSaved(int32 download_id,
369 int64 size,
370 const std::string& hash) {
371 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 354 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
372 << " size = " << size; 355 << " size = " << size;
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
374 357
375 // If it's not in active_downloads_, that means it was cancelled; just 358 // If it's not in active_downloads_, that means it was cancelled; just
376 // ignore the notification. 359 // ignore the notification.
377 if (active_downloads_.count(download_id) == 0) 360 if (active_downloads_.count(download_id) == 0)
378 return; 361 return;
379 362
380 DownloadItem* download = active_downloads_[download_id]; 363 DownloadItem* download = active_downloads_[download_id];
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); 486 file_manager_, &DownloadFileManager::CompleteDownload, download_id));
504 487
505 if (uniquifier) 488 if (uniquifier)
506 item->set_path_uniquifier(uniquifier); 489 item->set_path_uniquifier(uniquifier);
507 490
508 item->OnDownloadRenamedToFinalName(full_path); 491 item->OnDownloadRenamedToFinalName(full_path);
509 delegate_->UpdatePathForItemInPersistentStore(item, full_path); 492 delegate_->UpdatePathForItemInPersistentStore(item, full_path);
510 } 493 }
511 494
512 void DownloadManager::CancelDownload(int32 download_id) { 495 void DownloadManager::CancelDownload(int32 download_id) {
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 496 DownloadItem* download = GetActiveDownload(download_id);
Randy Smith (Not in Mondays) 2011/08/28 22:14:03 Why remove the DCHECK?
ahendrickson 2011/08/29 16:30:53 I removed it because GetActiveDownload() has it.
514 DownloadItem* download = GetDownloadItem(download_id); 497 // A cancel at the right time could remove the download from the
498 // |active_downloads_| map before we get here.
515 if (!download) 499 if (!download)
516 return; 500 return;
517 501
518 download->Cancel(true); 502 download->Cancel(true);
519 } 503 }
520 504
521 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { 505 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) {
522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
523 int download_id = download->id();
524 507
525 VLOG(20) << __FUNCTION__ << "()" 508 VLOG(20) << __FUNCTION__ << "()"
526 << " download = " << download->DebugString(true); 509 << " download = " << download->DebugString(true);
527 510
528 // Clean up will happen when the history system create callback runs if we 511 RemoveFromActiveList(download);
529 // don't have a valid db_handle yet. 512 // This function is called from the DownloadItem, so DI state
530 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 513 // should already have been updated.
531 in_progress_.erase(download_id); 514 AssertQueueStateConsistent(download);
532 active_downloads_.erase(download_id);
533 UpdateDownloadProgress(); // Reflect removal from in_progress_.
534 delegate_->UpdateItemInPersistentStore(download);
535
536 // This function is called from the DownloadItem, so DI state
537 // should already have been updated.
538 AssertQueueStateConsistent(download);
539 }
540 515
541 download->OffThreadCancel(file_manager_); 516 download->OffThreadCancel(file_manager_);
542 } 517 }
543 518
544 void DownloadManager::OnDownloadError(int32 download_id, 519 void DownloadManager::OnDownloadError(int32 download_id,
545 int64 size, 520 int64 size,
546 int os_error) { 521 int error) {
522 DownloadItem* download = GetActiveDownload(download_id);
523 if (!download)
524 return;
525
526 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
527 << " at offset " << download->received_bytes()
528 << " size = " << size
529 << " download = " << download->DebugString(true);
530
531 RemoveFromActiveList(download);
532 download->Interrupted(size, error);
533 download->OffThreadCancel(file_manager_);
534 }
535
536 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
548 DownloadMap::iterator it = active_downloads_.find(download_id); 538 DownloadMap::iterator it = active_downloads_.find(download_id);
549 // A cancel at the right time could remove the download from the
550 // |active_downloads_| map before we get here.
551 if (it == active_downloads_.end()) 539 if (it == active_downloads_.end())
552 return; 540 return NULL;
553 541
554 DownloadItem* download = it->second; 542 DownloadItem* download = it->second;
555 543
556 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 544 DCHECK(download);
557 << " at offset " << download->received_bytes() 545 DCHECK_EQ(download_id, download->id());
558 << " for download = " << download->DebugString(true);
559 546
560 download->Interrupted(size, os_error); 547 return download;
548 }
561 549
562 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 550 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
563 // downloads, as we will keep the download item around in that case. 551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
564 // 552 DCHECK(download);
553
565 // Clean up will happen when the history system create callback runs if we 554 // Clean up will happen when the history system create callback runs if we
566 // don't have a valid db_handle yet. 555 // don't have a valid db_handle yet.
567 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 556 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
568 in_progress_.erase(download_id); 557 in_progress_.erase(download->id());
569 active_downloads_.erase(download_id); 558 active_downloads_.erase(download->id());
570 UpdateDownloadProgress(); // Reflect removal from in_progress_. 559 UpdateDownloadProgress(); // Reflect removal from in_progress_.
571 delegate_->UpdateItemInPersistentStore(download); 560 delegate_->UpdateItemInPersistentStore(download);
572 } 561 }
573
574 BrowserThread::PostTask(
575 BrowserThread::FILE, FROM_HERE,
576 NewRunnableMethod(
577 file_manager_, &DownloadFileManager::CancelDownload, download_id));
578 } 562 }
579 563
580 void DownloadManager::UpdateDownloadProgress() { 564 void DownloadManager::UpdateDownloadProgress() {
581 delegate_->DownloadProgressUpdated(); 565 delegate_->DownloadProgressUpdated();
582 } 566 }
583 567
584 int DownloadManager::RemoveDownloadItems( 568 int DownloadManager::RemoveDownloadItems(
585 const DownloadVector& pending_deletes) { 569 const DownloadVector& pending_deletes) {
586 if (pending_deletes.empty()) 570 if (pending_deletes.empty())
587 return 0; 571 return 0;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 int32 download_id = *id_ptr; 740 int32 download_id = *id_ptr;
757 delete id_ptr; 741 delete id_ptr;
758 742
759 DownloadItem* download = GetActiveDownloadItem(download_id); 743 DownloadItem* download = GetActiveDownloadItem(download_id);
760 if (!download) 744 if (!download)
761 return; 745 return;
762 746
763 VLOG(20) << __FUNCTION__ << "()" 747 VLOG(20) << __FUNCTION__ << "()"
764 << " download = " << download->DebugString(true); 748 << " download = " << download->DebugString(true);
765 749
750 // TODO(ahendrickson) -- This currently has no effect, as the download is
751 // not put on the active list until the file selection is complete. Need
752 // to put it on the active list earlier in the process.
753 RemoveFromActiveList(download);
754
766 download->OffThreadCancel(file_manager_); 755 download->OffThreadCancel(file_manager_);
767 } 756 }
768 757
769 // Operations posted to us from the history service ---------------------------- 758 // Operations posted to us from the history service ----------------------------
770 759
771 // The history service has retrieved all download entries. 'entries' contains 760 // The history service has retrieved all download entries. 'entries' contains
772 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 761 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
773 void DownloadManager::OnPersistentStoreQueryComplete( 762 void DownloadManager::OnPersistentStoreQueryComplete(
774 std::vector<DownloadPersistentStoreInfo>* entries) { 763 std::vector<DownloadPersistentStoreInfo>* entries) {
775 // TODO(rdsmith): Remove this and related logic when 764 // TODO(rdsmith): Remove this and related logic when
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 DCHECK(ContainsKey(save_page_downloads_, download->id())); 1004 DCHECK(ContainsKey(save_page_downloads_, download->id()));
1016 save_page_downloads_.erase(download->id()); 1005 save_page_downloads_.erase(download->id());
1017 1006
1018 if (download->IsComplete()) 1007 if (download->IsComplete())
1019 NotificationService::current()->Notify( 1008 NotificationService::current()->Notify(
1020 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 1009 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1021 Source<DownloadManager>(this), 1010 Source<DownloadManager>(this),
1022 Details<DownloadItem>(download)); 1011 Details<DownloadItem>(download));
1023 } 1012 }
1024 } 1013 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698