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

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: Removed illegal include from content. 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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 if (download->IsInProgress()) { 340 if (download->IsInProgress()) {
341 download->Update(size); 341 download->Update(size);
342 UpdateDownloadProgress(); // Reflect size updates. 342 UpdateDownloadProgress(); // Reflect size updates.
343 delegate_->UpdateItemInPersistentStore(download); 343 delegate_->UpdateItemInPersistentStore(download);
344 } 344 }
345 } 345 }
346 } 346 }
347 347
348 void DownloadManager::OnResponseCompleted(int32 download_id, 348 void DownloadManager::OnResponseCompleted(int32 download_id,
349 int64 size, 349 int64 size,
350 int os_error,
351 const std::string& hash) { 350 const std::string& hash) {
352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
353 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
354 // advertise a larger Content-Length than the amount of bytes in the message
355 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
356 // and Safari 5.0.4 - treat the download as complete in this case, so we
357 // follow their lead.
358 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) {
359 OnAllDataSaved(download_id, size, hash);
360 } else {
361 OnDownloadError(download_id, size, os_error);
362 }
363 }
364
365 void DownloadManager::OnAllDataSaved(int32 download_id,
366 int64 size,
367 const std::string& hash) {
368 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 351 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
369 << " size = " << size; 352 << " size = " << size;
370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
371 354
372 // If it's not in active_downloads_, that means it was cancelled; just 355 // If it's not in active_downloads_, that means it was cancelled; just
373 // ignore the notification. 356 // ignore the notification.
374 if (active_downloads_.count(download_id) == 0) 357 if (active_downloads_.count(download_id) == 0)
375 return; 358 return;
376 359
377 DownloadItem* download = active_downloads_[download_id]; 360 DownloadItem* download = active_downloads_[download_id];
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); 483 file_manager_, &DownloadFileManager::CompleteDownload, download_id));
501 484
502 if (uniquifier) 485 if (uniquifier)
503 item->set_path_uniquifier(uniquifier); 486 item->set_path_uniquifier(uniquifier);
504 487
505 item->OnDownloadRenamedToFinalName(full_path); 488 item->OnDownloadRenamedToFinalName(full_path);
506 delegate_->UpdatePathForItemInPersistentStore(item, full_path); 489 delegate_->UpdatePathForItemInPersistentStore(item, full_path);
507 } 490 }
508 491
509 void DownloadManager::DownloadCancelled(int32 download_id) { 492 void DownloadManager::DownloadCancelled(int32 download_id) {
510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 493 DownloadItem* download = GetActiveDownload(download_id);
511 DownloadMap::iterator it = in_progress_.find(download_id); 494
512 if (it == in_progress_.end()) 495 // A cancel at the right time could remove the download from the
496 // |active_downloads_| map before we get here.
497 if (!download)
513 return; 498 return;
514 DownloadItem* download = it->second;
515 499
516 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 500 VLOG(20) << __FUNCTION__ << "()"
517 << " download = " << download->DebugString(true); 501 << " download = " << download->DebugString(true);
518 502
519 // Clean up will happen when the history system create callback runs if we 503 RemoveFromActiveList(download);
520 // don't have a valid db_handle yet.
521 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
522 in_progress_.erase(it);
523 active_downloads_.erase(download_id);
524 UpdateDownloadProgress(); // Reflect removal from in_progress_.
525 delegate_->UpdateItemInPersistentStore(download);
526 AssertQueueStateConsistent(download);
527 }
528 504
529 DownloadCancelledInternal(download_id, download->request_handle()); 505 DownloadCancelledInternal(download_id, download->request_handle());
530 } 506 }
531 507
508 void DownloadManager::OnDownloadError(int32 download_id,
509 int64 size,
510 int error) {
511 DownloadItem* download = GetActiveDownload(download_id);
512 if (!download)
513 return;
514
515 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
516 << " at offset " << download->received_bytes()
517 << " size = " << size
518 << " download = " << download->DebugString(true);
519
520 RemoveFromActiveList(download);
521 download->Interrupted(size, error);
522 DownloadCancelledInternal(download_id, download->request_handle());
523 }
524
532 void DownloadManager::DownloadCancelledInternal( 525 void DownloadManager::DownloadCancelledInternal(
533 int download_id, const DownloadRequestHandle& request_handle) { 526 int download_id, const DownloadRequestHandle& request_handle) {
534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 527 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
535 request_handle.CancelRequest(); 528 request_handle.CancelRequest();
536 529
537 BrowserThread::PostTask( 530 BrowserThread::PostTask(
538 BrowserThread::FILE, FROM_HERE, 531 BrowserThread::FILE, FROM_HERE,
539 NewRunnableMethod( 532 NewRunnableMethod(
540 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 533 file_manager_, &DownloadFileManager::CancelDownload, download_id));
541 } 534 }
542 535
543 void DownloadManager::OnDownloadError(int32 download_id, 536 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
544 int64 size,
545 int os_error) {
546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
547 DownloadMap::iterator it = active_downloads_.find(download_id); 538 DownloadMap::iterator it = active_downloads_.find(download_id);
548 // A cancel at the right time could remove the download from the
549 // |active_downloads_| map before we get here.
550 if (it == active_downloads_.end()) 539 if (it == active_downloads_.end())
551 return; 540 return NULL;
552 541
553 DownloadItem* download = it->second; 542 DownloadItem* download = it->second;
554 543
555 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 544 DCHECK(download);
556 << " at offset " << download->received_bytes() 545 DCHECK_EQ(download_id, download->id());
557 << " for download = " << download->DebugString(true);
558 546
559 download->Interrupted(size, os_error); 547 return download;
548 }
560 549
561 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 550 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
562 // downloads, as we will keep the download item around in that case. 551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
563 // 552 DCHECK(download);
553
564 // 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
565 // don't have a valid db_handle yet. 555 // don't have a valid db_handle yet.
566 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 556 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
567 in_progress_.erase(download_id); 557 in_progress_.erase(download->id());
568 active_downloads_.erase(download_id); 558 active_downloads_.erase(download->id());
569 UpdateDownloadProgress(); // Reflect removal from in_progress_. 559 UpdateDownloadProgress(); // Reflect removal from in_progress_.
570 delegate_->UpdateItemInPersistentStore(download); 560 delegate_->UpdateItemInPersistentStore(download);
571 } 561 }
572
573 BrowserThread::PostTask(
574 BrowserThread::FILE, FROM_HERE,
575 NewRunnableMethod(
576 file_manager_, &DownloadFileManager::CancelDownload, download_id));
577 } 562 }
578 563
579 void DownloadManager::UpdateDownloadProgress() { 564 void DownloadManager::UpdateDownloadProgress() {
580 delegate_->DownloadProgressUpdated(); 565 delegate_->DownloadProgressUpdated();
581 } 566 }
582 567
583 int DownloadManager::RemoveDownloadItems( 568 int DownloadManager::RemoveDownloadItems(
584 const DownloadVector& pending_deletes) { 569 const DownloadVector& pending_deletes) {
585 if (pending_deletes.empty()) 570 if (pending_deletes.empty())
586 return 0; 571 return 0;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 int32 download_id = *id_ptr; 740 int32 download_id = *id_ptr;
756 delete id_ptr; 741 delete id_ptr;
757 742
758 DownloadItem* download = GetActiveDownloadItem(download_id); 743 DownloadItem* download = GetActiveDownloadItem(download_id);
759 if (!download) 744 if (!download)
760 return; 745 return;
761 746
762 VLOG(20) << __FUNCTION__ << "()" 747 VLOG(20) << __FUNCTION__ << "()"
763 << " download = " << download->DebugString(true); 748 << " download = " << download->DebugString(true);
764 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
765 DownloadCancelledInternal(download_id, download->request_handle()); 755 DownloadCancelledInternal(download_id, download->request_handle());
766 } 756 }
767 757
768 // Operations posted to us from the history service ---------------------------- 758 // Operations posted to us from the history service ----------------------------
769 759
770 // The history service has retrieved all download entries. 'entries' contains 760 // The history service has retrieved all download entries. 'entries' contains
771 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 761 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
772 void DownloadManager::OnPersistentStoreQueryComplete( 762 void DownloadManager::OnPersistentStoreQueryComplete(
773 std::vector<DownloadPersistentStoreInfo>* entries) { 763 std::vector<DownloadPersistentStoreInfo>* entries) {
774 for (size_t i = 0; i < entries->size(); ++i) { 764 for (size_t i = 0; i < entries->size(); ++i) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 DCHECK(ContainsKey(save_page_downloads_, download->id())); 982 DCHECK(ContainsKey(save_page_downloads_, download->id()));
993 save_page_downloads_.erase(download->id()); 983 save_page_downloads_.erase(download->id());
994 984
995 if (download->IsComplete()) 985 if (download->IsComplete())
996 NotificationService::current()->Notify( 986 NotificationService::current()->Notify(
997 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 987 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
998 Source<DownloadManager>(this), 988 Source<DownloadManager>(this),
999 Details<DownloadItem>(download)); 989 Details<DownloadItem>(download));
1000 } 990 }
1001 } 991 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698