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

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: Changed namespace for MockFileStream. 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
« no previous file with comments | « content/browser/download/download_manager.h ('k') | net/base/file_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
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 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
523
524 DownloadItem* download = GetActiveDownload(download_id);
525 if (!download)
526 return;
527
528 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
529 << " at offset " << download->received_bytes()
530 << " size = " << size
531 << " download = " << download->DebugString(true);
532
533 RemoveFromActiveList(download);
534 download->Interrupted(size, error);
535 download->OffThreadCancel(file_manager_);
536 }
537
538 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
548 DownloadMap::iterator it = active_downloads_.find(download_id); 540 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()) 541 if (it == active_downloads_.end())
552 return; 542 return NULL;
553 543
554 DownloadItem* download = it->second; 544 DownloadItem* download = it->second;
555 545
556 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 546 DCHECK(download);
557 << " at offset " << download->received_bytes() 547 DCHECK_EQ(download_id, download->id());
558 << " for download = " << download->DebugString(true);
559 548
560 download->Interrupted(size, os_error); 549 return download;
550 }
561 551
562 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 552 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
563 // downloads, as we will keep the download item around in that case. 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
564 // 554 DCHECK(download);
555
565 // Clean up will happen when the history system create callback runs if we 556 // Clean up will happen when the history system create callback runs if we
566 // don't have a valid db_handle yet. 557 // don't have a valid db_handle yet.
567 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 558 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
568 in_progress_.erase(download_id); 559 in_progress_.erase(download->id());
569 active_downloads_.erase(download_id); 560 active_downloads_.erase(download->id());
570 UpdateDownloadProgress(); // Reflect removal from in_progress_. 561 UpdateDownloadProgress(); // Reflect removal from in_progress_.
571 delegate_->UpdateItemInPersistentStore(download); 562 delegate_->UpdateItemInPersistentStore(download);
572 } 563 }
573
574 BrowserThread::PostTask(
575 BrowserThread::FILE, FROM_HERE,
576 NewRunnableMethod(
577 file_manager_, &DownloadFileManager::CancelDownload, download_id));
578 } 564 }
579 565
580 void DownloadManager::UpdateDownloadProgress() { 566 void DownloadManager::UpdateDownloadProgress() {
581 delegate_->DownloadProgressUpdated(); 567 delegate_->DownloadProgressUpdated();
582 } 568 }
583 569
584 int DownloadManager::RemoveDownloadItems( 570 int DownloadManager::RemoveDownloadItems(
585 const DownloadVector& pending_deletes) { 571 const DownloadVector& pending_deletes) {
586 if (pending_deletes.empty()) 572 if (pending_deletes.empty())
587 return 0; 573 return 0;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 int32 download_id = *id_ptr; 742 int32 download_id = *id_ptr;
757 delete id_ptr; 743 delete id_ptr;
758 744
759 DownloadItem* download = GetActiveDownloadItem(download_id); 745 DownloadItem* download = GetActiveDownloadItem(download_id);
760 if (!download) 746 if (!download)
761 return; 747 return;
762 748
763 VLOG(20) << __FUNCTION__ << "()" 749 VLOG(20) << __FUNCTION__ << "()"
764 << " download = " << download->DebugString(true); 750 << " download = " << download->DebugString(true);
765 751
752 // TODO(ahendrickson) -- This currently has no effect, as the download is
753 // not put on the active list until the file selection is complete. Need
754 // to put it on the active list earlier in the process.
755 RemoveFromActiveList(download);
756
766 download->OffThreadCancel(file_manager_); 757 download->OffThreadCancel(file_manager_);
767 } 758 }
768 759
769 // Operations posted to us from the history service ---------------------------- 760 // Operations posted to us from the history service ----------------------------
770 761
771 // The history service has retrieved all download entries. 'entries' contains 762 // The history service has retrieved all download entries. 'entries' contains
772 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 763 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
773 void DownloadManager::OnPersistentStoreQueryComplete( 764 void DownloadManager::OnPersistentStoreQueryComplete(
774 std::vector<DownloadPersistentStoreInfo>* entries) { 765 std::vector<DownloadPersistentStoreInfo>* entries) {
775 // TODO(rdsmith): Remove this and related logic when 766 // 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())); 1006 DCHECK(ContainsKey(save_page_downloads_, download->id()));
1016 save_page_downloads_.erase(download->id()); 1007 save_page_downloads_.erase(download->id());
1017 1008
1018 if (download->IsComplete()) 1009 if (download->IsComplete())
1019 NotificationService::current()->Notify( 1010 NotificationService::current()->Notify(
1020 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 1011 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1021 Source<DownloadManager>(this), 1012 Source<DownloadManager>(this),
1022 Details<DownloadItem>(download)); 1013 Details<DownloadItem>(download));
1023 } 1014 }
1024 } 1015 }
OLDNEW
« no previous file with comments | « content/browser/download/download_manager.h ('k') | net/base/file_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698