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

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

Issue 10704052: Download filename determination refactor (3/3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 "content/browser/download/download_manager_impl.h" 5 #include "content/browser/download/download_manager_impl.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 if (delegate_) 214 if (delegate_)
215 id = delegate_->GetNextId(); 215 id = delegate_->GetNextId();
216 if (!id.IsValid()) { 216 if (!id.IsValid()) {
217 static int next_id; 217 static int next_id;
218 id = DownloadId(browser_context_, ++next_id); 218 id = DownloadId(browser_context_, ++next_id);
219 } 219 }
220 220
221 return id; 221 return id;
222 } 222 }
223 223
224 DownloadFileManager* DownloadManagerImpl::GetDownloadFileManager() {
225 return file_manager_;
226 }
227
224 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItem* item) { 228 bool DownloadManagerImpl::ShouldOpenDownload(DownloadItem* item) {
225 if (!delegate_) 229 if (!delegate_)
226 return true; 230 return true;
227 231
228 return delegate_->ShouldOpenDownload(item); 232 return delegate_->ShouldOpenDownload(item);
229 } 233 }
230 234
231 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) { 235 bool DownloadManagerImpl::ShouldOpenFileBasedOnExtension(const FilePath& path) {
232 if (!delegate_) 236 if (!delegate_)
233 return false; 237 return false;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 OnDownloadInterrupted(download_id, 0, "", reason); 414 OnDownloadInterrupted(download_id, 0, "", reason);
411 // TODO(rdsmith): It makes no sense to continue along the 415 // TODO(rdsmith): It makes no sense to continue along the
412 // regular download path after we've gotten an error. But it's 416 // regular download path after we've gotten an error. But it's
413 // the way the code has historically worked, and this allows us 417 // the way the code has historically worked, and this allows us
414 // to get the download persisted and observers of the download manager 418 // to get the download persisted and observers of the download manager
415 // notified, so tests work. When we execute all side effects of cancel 419 // notified, so tests work. When we execute all side effects of cancel
416 // (including queue removal) immedately rather than waiting for 420 // (including queue removal) immedately rather than waiting for
417 // persistence we should replace this comment with a "return;". 421 // persistence we should replace this comment with a "return;".
418 } 422 }
419 423
420 if (!delegate_ || delegate_->ShouldStartDownload(download_id)) 424 DownloadItem* download = GetActiveDownloadItem(download_id);
421 RestartDownload(download_id); 425 if (!download)
426 return;
427
428 if (!delegate_ || !delegate_->DetermineDownloadTarget(download)) {
429 FilePath target_path = download->GetForcedFilePath();
430 // TODO(asanka): Determine a useful path if |target_path| is empty.
431 download->OnDownloadTargetDetermined(
432 target_path,
433 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
434 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
435 target_path);
436 }
437 // Once DownloadItem::OnDownloadTargetDetermined() is called, we expect a
438 // DownloadRenamedToIntermediateName() callback. This is necessary for the
439 // download to proceed.
422 } 440 }
423 441
424 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { 442 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
426 for (DownloadMap::iterator it = downloads_.begin(); 444 for (DownloadMap::iterator it = downloads_.begin();
427 it != downloads_.end(); ++it) { 445 it != downloads_.end(); ++it) {
428 DownloadItem* item = it->second; 446 DownloadItem* item = it->second;
429 if (item->IsPersisted()) 447 if (item->IsPersisted())
430 CheckForFileRemoval(item); 448 CheckForFileRemoval(item);
431 } 449 }
(...skipping 23 matching lines...) Expand all
455 } 473 }
456 } 474 }
457 475
458 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { 476 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) {
459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
460 DownloadItem* download = GetDownload(download_id); 478 DownloadItem* download = GetDownload(download_id);
461 if (download) 479 if (download)
462 download->OnDownloadedFileRemoved(); 480 download->OnDownloadedFileRemoved();
463 } 481 }
464 482
465 void DownloadManagerImpl::RestartDownload(int32 download_id) {
466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
467
468 DownloadItem* download = GetActiveDownloadItem(download_id);
469 if (!download)
470 return;
471
472 VLOG(20) << __FUNCTION__ << "()"
473 << " download = " << download->DebugString(true);
474
475 if (download->GetTargetDisposition() ==
476 DownloadItem::TARGET_DISPOSITION_PROMPT) {
477 // We must ask the user for the place to put the download.
478 if (delegate_) {
479 delegate_->ChooseDownloadPath(download);
480 FOR_EACH_OBSERVER(Observer, observers_,
481 SelectFileDialogDisplayed(this, download_id));
482 } else {
483 FileSelectionCanceled(download_id);
484 }
485 } else {
486 // No prompting for download, just continue with the current target path.
487 OnTargetPathAvailable(download);
488 }
489 }
490
491 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { 483 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const {
492 return browser_context_; 484 return browser_context_;
493 } 485 }
494 486
495 FilePath DownloadManagerImpl::LastDownloadPath() {
496 return last_download_path_;
497 }
498
499 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( 487 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem(
500 DownloadCreateInfo* info) { 488 DownloadCreateInfo* info) {
501 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
502 490
503 net::BoundNetLog bound_net_log = 491 net::BoundNetLog bound_net_log =
504 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 492 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
505 if (!info->download_id.IsValid()) 493 if (!info->download_id.IsValid())
506 info->download_id = GetNextId(); 494 info->download_id = GetNextId();
507 DownloadItem* download = factory_->CreateActiveItem( 495 DownloadItem* download = factory_->CreateActiveItem(
508 this, *info, 496 this, *info,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 DCHECK(!ContainsKey(save_page_downloads_, download->GetId())); 530 DCHECK(!ContainsKey(save_page_downloads_, download->GetId()));
543 save_page_downloads_[download->GetId()] = download; 531 save_page_downloads_[download->GetId()] = download;
544 532
545 // Will notify the observer in the callback. 533 // Will notify the observer in the callback.
546 if (delegate_) 534 if (delegate_)
547 delegate_->AddItemToPersistentStore(download); 535 delegate_->AddItemToPersistentStore(download);
548 536
549 return download; 537 return download;
550 } 538 }
551 539
552 // The target path for the download item is now valid. We proceed with the
553 // determination of an intermediate path.
554 void DownloadManagerImpl::OnTargetPathAvailable(DownloadItem* download) {
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
556 DCHECK(download);
557 DCHECK(ContainsKey(downloads_, download->GetId()));
558 DCHECK(ContainsKey(active_downloads_, download->GetId()));
559
560 VLOG(20) << __FUNCTION__ << "()"
561 << " download = " << download->DebugString(true);
562
563 // Rename to intermediate name.
564 // TODO(asanka): Skip this rename if download->AllDataSaved() is true. This
565 // avoids a spurious rename when we can just rename to the final
566 // filename. Unnecessary renames may cause bugs like
567 // http://crbug.com/74187.
568 FilePath intermediate_path;
569 if (delegate_)
570 intermediate_path = delegate_->GetIntermediatePath(*download);
571 else
572 intermediate_path = download->GetTargetFilePath();
573
574 // We want the intermediate and target paths to refer to the same directory so
575 // that they are both on the same device and subject to same
576 // space/permission/availability constraints.
577 DCHECK(intermediate_path.DirName() ==
578 download->GetTargetFilePath().DirName());
579 download->OnIntermediatePathDetermined(file_manager_, intermediate_path);
580 }
581
582 void DownloadManagerImpl::UpdateDownload(int32 download_id, 540 void DownloadManagerImpl::UpdateDownload(int32 download_id,
583 int64 bytes_so_far, 541 int64 bytes_so_far,
584 int64 bytes_per_sec, 542 int64 bytes_per_sec,
585 const std::string& hash_state) { 543 const std::string& hash_state) {
586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
587 DownloadMap::iterator it = active_downloads_.find(download_id); 545 DownloadMap::iterator it = active_downloads_.find(download_id);
588 if (it != active_downloads_.end()) { 546 if (it != active_downloads_.end()) {
589 DownloadItem* download = it->second; 547 DownloadItem* download = it->second;
590 if (download->IsInProgress()) { 548 if (download->IsInProgress()) {
591 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state); 549 download->UpdateProgress(bytes_so_far, bytes_per_sec, hash_state);
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 // TODO: It is the responsibility of the observers to query the 842 // TODO: It is the responsibility of the observers to query the
885 // DownloadManager. Remove the following call from here and update all 843 // DownloadManager. Remove the following call from here and update all
886 // observers. 844 // observers.
887 observer->ModelChanged(this); 845 observer->ModelChanged(this);
888 } 846 }
889 847
890 void DownloadManagerImpl::RemoveObserver(Observer* observer) { 848 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
891 observers_.RemoveObserver(observer); 849 observers_.RemoveObserver(observer);
892 } 850 }
893 851
894 void DownloadManagerImpl::FileSelected(const FilePath& path,
895 int32 download_id) {
896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
897 DCHECK(!path.empty());
898
899 DownloadItem* download = GetActiveDownloadItem(download_id);
900 if (!download)
901 return;
902 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\""
903 << " download = " << download->DebugString(true);
904
905 // Retain the last directory. Exclude temporary downloads since the path
906 // likely points at the location of a temporary file.
907 if (!download->IsTemporary())
908 last_download_path_ = path.DirName();
909
910 // Make sure the initial file name is set only once.
911 download->OnTargetPathSelected(path);
912 OnTargetPathAvailable(download);
913 }
914
915 void DownloadManagerImpl::FileSelectionCanceled(int32 download_id) {
916 // The user didn't pick a place to save the file, so need to cancel the
917 // download that's already in progress to the temporary location.
918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
919
920 DownloadItem* download = GetActiveDownloadItem(download_id);
921 if (!download)
922 return;
923
924 VLOG(20) << __FUNCTION__ << "()"
925 << " download = " << download->DebugString(true);
926
927 download->Cancel(true);
928 }
929
930 // Operations posted to us from the history service ---------------------------- 852 // Operations posted to us from the history service ----------------------------
931 853
932 // The history service has retrieved all download entries. 'entries' contains 854 // The history service has retrieved all download entries. 'entries' contains
933 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 855 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
934 void DownloadManagerImpl::OnPersistentStoreQueryComplete( 856 void DownloadManagerImpl::OnPersistentStoreQueryComplete(
935 std::vector<DownloadPersistentStoreInfo>* entries) { 857 std::vector<DownloadPersistentStoreInfo>* entries) {
936 history_size_ = entries->size(); 858 history_size_ = entries->size();
937 for (size_t i = 0; i < entries->size(); ++i) { 859 for (size_t i = 0; i < entries->size(); ++i) {
938 int64 db_handle = entries->at(i).db_handle; 860 int64 db_handle = entries->at(i).db_handle;
939 base::debug::Alias(&db_handle); 861 base::debug::Alias(&db_handle);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 for (DownloadMap::const_iterator it = active_downloads_.begin(); 963 for (DownloadMap::const_iterator it = active_downloads_.begin();
1042 it != active_downloads_.end(); ++it) { 964 it != active_downloads_.end(); ++it) {
1043 DownloadItem* item = it->second; 965 DownloadItem* item = it->second;
1044 if (item->IsInProgress()) 966 if (item->IsInProgress())
1045 ++count; 967 ++count;
1046 } 968 }
1047 return count; 969 return count;
1048 } 970 }
1049 971
1050 // Clears the last download path, used to initialize "save as" dialogs. 972 // Clears the last download path, used to initialize "save as" dialogs.
1051 void DownloadManagerImpl::ClearLastDownloadPath() { 973 void DownloadManagerImpl::ClearTransientState() {
1052 last_download_path_ = FilePath(); 974 if (delegate_)
975 delegate_->ClearTransientState();
1053 } 976 }
1054 977
1055 void DownloadManagerImpl::NotifyModelChanged() { 978 void DownloadManagerImpl::NotifyModelChanged() {
1056 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this)); 979 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged(this));
1057 } 980 }
1058 981
1059 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) { 982 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) {
1060 DownloadItem* download = GetDownload(download_id); 983 DownloadItem* download = GetDownload(download_id);
1061 return (download && download->IsPersisted()) ? download : NULL; 984 return (download && download->IsPersisted()) ? download : NULL;
1062 } 985 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 if (item->IsComplete() && 1091 if (item->IsComplete() &&
1169 !item->GetOpened()) 1092 !item->GetOpened())
1170 ++num_unopened; 1093 ++num_unopened;
1171 } 1094 }
1172 download_stats::RecordOpensOutstanding(num_unopened); 1095 download_stats::RecordOpensOutstanding(num_unopened);
1173 } 1096 }
1174 1097
1175 void DownloadManagerImpl::DownloadRenamedToIntermediateName( 1098 void DownloadManagerImpl::DownloadRenamedToIntermediateName(
1176 DownloadItem* download) { 1099 DownloadItem* download) {
1177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1178 // If the rename failed, we receive an OnDownloadInterrupted() call before we 1101 // download->GetFullPath() is only expected to be meaningful after this
1179 // receive the DownloadRenamedToIntermediateName() call. 1102 // callback is received. Therefore we can now add the download to a persistent
1180 if (delegate_) 1103 // store. If the rename failed, we receive an OnDownloadInterrupted() call
1104 // before we receive the DownloadRenamedToIntermediateName() call.
1105 if (delegate_) {
1181 delegate_->AddItemToPersistentStore(download); 1106 delegate_->AddItemToPersistentStore(download);
1107 } else {
1108 OnItemAddedToPersistentStore(download->GetId(),
1109 DownloadItem::kUninitializedHandle);
1110 }
1182 } 1111 }
1183 1112
1184 void DownloadManagerImpl::DownloadRenamedToFinalName( 1113 void DownloadManagerImpl::DownloadRenamedToFinalName(
1185 DownloadItem* download) { 1114 DownloadItem* download) {
1186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1187 // If the rename failed, we receive an OnDownloadInterrupted() call before we 1116 // If the rename failed, we receive an OnDownloadInterrupted() call before we
1188 // receive the DownloadRenamedToFinalName() call. 1117 // receive the DownloadRenamedToFinalName() call.
1189 if (delegate_) { 1118 if (delegate_) {
1190 delegate_->UpdatePathForItemInPersistentStore( 1119 delegate_->UpdatePathForItemInPersistentStore(
1191 download, download->GetFullPath()); 1120 download, download->GetFullPath());
1192 } 1121 }
1193 } 1122 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698