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

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate.cc

Issue 10704052: Download filename determination refactor (3/3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use a callback with DetermineDownloadTarget(). 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 "chrome/browser/download/chrome_download_manager_delegate.h" 5 #include "chrome/browser/download/chrome_download_manager_delegate.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 128 }
129 129
130 DownloadId ChromeDownloadManagerDelegate::GetNextId() { 130 DownloadId ChromeDownloadManagerDelegate::GetNextId() {
131 if (!profile_->IsOffTheRecord()) 131 if (!profile_->IsOffTheRecord())
132 return DownloadId(this, next_download_id_++); 132 return DownloadId(this, next_download_id_++);
133 133
134 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> 134 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())->
135 GetDelegate()->GetNextId(); 135 GetDelegate()->GetNextId();
136 } 136 }
137 137
138 bool ChromeDownloadManagerDelegate::ShouldStartDownload(int32 download_id) { 138 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
139 DownloadItem* download,
140 const content::DownloadTargetCallback& callback) {
139 // We create a download item and store it in our download map, and inform the 141 // We create a download item and store it in our download map, and inform the
140 // history system of a new download. Since this method can be called while the 142 // history system of a new download. Since this method can be called while the
141 // history service thread is still reading the persistent state, we do not 143 // history service thread is still reading the persistent state, we do not
142 // insert the new DownloadItem into 'history_downloads_' or inform our 144 // insert the new DownloadItem into 'history_downloads_' or inform our
143 // observers at this point. OnCreateDownloadEntryComplete() handles that 145 // observers at this point. OnCreateDownloadEntryComplete() handles that
144 // finalization of the the download creation as a callback from the history 146 // finalization of the the download creation as a callback from the history
145 // thread. 147 // thread.
Randy Smith (Not in Mondays) 2012/07/10 18:33:09 This comment seems very strange; can you clean it
asanka 2012/07/11 20:03:32 Removed.
146 DownloadItem* download =
147 download_manager_->GetActiveDownloadItem(download_id);
148 if (!download)
149 return false;
150
151 #if defined(ENABLE_SAFE_BROWSING) 148 #if defined(ENABLE_SAFE_BROWSING)
152 DownloadProtectionService* service = GetDownloadProtectionService(); 149 DownloadProtectionService* service = GetDownloadProtectionService();
153 if (service) { 150 if (service) {
154 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " 151 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = "
155 << download->DebugString(false); 152 << download->DebugString(false);
156 service->CheckDownloadUrl( 153 service->CheckDownloadUrl(
157 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), 154 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download),
158 base::Bind( 155 base::Bind(
159 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, 156 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone,
160 this, 157 this,
161 download->GetId())); 158 download->GetId(),
162 return false; 159 callback));
160 return true;
163 } 161 }
164 #endif 162 #endif
165 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); 163 CheckDownloadUrlDone(download->GetId(), callback,
166 return false; 164 DownloadProtectionService::SAFE);
165 return true;
167 } 166 }
168 167
169 void ChromeDownloadManagerDelegate::ChooseDownloadPath(DownloadItem* item) { 168 void ChromeDownloadManagerDelegate::ChooseDownloadPath(
169 DownloadItem* item,
170 const FilePath& suggested_path,
171 const base::Callback<void(const FilePath&)>& file_selected_callback) {
170 // Deletes itself. 172 // Deletes itself.
171 DownloadFilePicker* file_picker = 173 DownloadFilePicker* file_picker =
172 #if defined(OS_CHROMEOS) 174 #if defined(OS_CHROMEOS)
173 new DownloadFilePickerChromeOS(); 175 new DownloadFilePickerChromeOS();
174 #else 176 #else
175 new DownloadFilePicker(); 177 new DownloadFilePicker();
176 #endif 178 #endif
177 file_picker->Init(download_manager_, item); 179 file_picker->Init(download_manager_, item, suggested_path,
180 file_selected_callback);
178 } 181 }
179 182
180 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( 183 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath(
181 const DownloadItem& download) { 184 const FilePath& target_path,
185 content::DownloadDangerType danger_type) {
182 // If the download is not dangerous, just append .crdownload to the target 186 // If the download is not dangerous, just append .crdownload to the target
183 // path. 187 // path.
184 if (download.GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) 188 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)
185 return download_util::GetCrDownloadPath(download.GetTargetFilePath()); 189 return download_util::GetCrDownloadPath(target_path);
186 190
187 // If the download is potentially dangerous we create a filename of the form 191 // If the download is potentially dangerous we create a filename of the form
188 // 'Unconfirmed <random>.crdownload'. 192 // 'Unconfirmed <random>.crdownload'.
189 FilePath::StringType file_name; 193 FilePath::StringType file_name;
190 FilePath dir = download.GetTargetFilePath().DirName(); 194 FilePath dir = target_path.DirName();
191 #if defined(OS_WIN) 195 #if defined(OS_WIN)
192 string16 unconfirmed_prefix = 196 string16 unconfirmed_prefix =
193 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 197 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
194 #else 198 #else
195 std::string unconfirmed_prefix = 199 std::string unconfirmed_prefix =
196 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 200 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
197 #endif 201 #endif
198 base::SStringPrintf( 202 base::SStringPrintf(
199 &file_name, 203 &file_name,
200 unconfirmed_prefix.append( 204 unconfirmed_prefix.append(
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 return !download.HasUserGesture() || !visited_referrer_before; 529 return !download.HasUserGesture() || !visited_referrer_before;
526 530
527 return danger_level == download_util::Dangerous; 531 return danger_level == download_util::Dangerous;
528 } 532 }
529 533
530 void ChromeDownloadManagerDelegate::GetReservedPath( 534 void ChromeDownloadManagerDelegate::GetReservedPath(
531 DownloadItem& download, 535 DownloadItem& download,
532 const FilePath& target_path, 536 const FilePath& target_path,
533 const FilePath& default_download_path, 537 const FilePath& default_download_path,
534 bool should_uniquify_path, 538 bool should_uniquify_path,
535 const DownloadPathReservationTracker::ReservedPathCallback callback) { 539 const DownloadPathReservationTracker::ReservedPathCallback& callback) {
536 DownloadPathReservationTracker::GetReservedPath( 540 DownloadPathReservationTracker::GetReservedPath(
537 download, target_path, default_download_path, should_uniquify_path, 541 download, target_path, default_download_path, should_uniquify_path,
538 callback); 542 callback);
539 } 543 }
540 544
541 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( 545 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone(
542 int32 download_id, 546 int32 download_id,
547 const content::DownloadTargetCallback& callback,
543 DownloadProtectionService::DownloadCheckResult result) { 548 DownloadProtectionService::DownloadCheckResult result) {
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 DownloadItem* download = 550 DownloadItem* download =
546 download_manager_->GetActiveDownloadItem(download_id); 551 download_manager_->GetActiveDownloadItem(download_id);
547 if (!download) 552 if (!download)
548 return; 553 return;
549 554
550 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) 555 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false)
551 << " verdict = " << result; 556 << " verdict = " << result;
552 content::DownloadDangerType danger_type = download->GetDangerType(); 557 content::DownloadDangerType danger_type = download->GetDangerType();
553 if (result != DownloadProtectionService::SAFE) 558 if (result != DownloadProtectionService::SAFE)
554 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL; 559 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
555 560
556 download_history_->CheckVisitedReferrerBefore( 561 download_history_->CheckVisitedReferrerBefore(
557 download_id, download->GetReferrerUrl(), 562 download_id, download->GetReferrerUrl(),
558 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone, 563 base::Bind(&ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone,
559 base::Unretained(this), download_id, danger_type)); 564 base::Unretained(this), download_id, callback, danger_type));
560 } 565 }
561 566
562 void ChromeDownloadManagerDelegate::CheckClientDownloadDone( 567 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
563 int32 download_id, 568 int32 download_id,
564 DownloadProtectionService::DownloadCheckResult result) { 569 DownloadProtectionService::DownloadCheckResult result) {
565 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); 570 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id);
566 if (!item) 571 if (!item)
567 return; 572 return;
568 573
569 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) 574 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 int download_id = crx_installers_[installer]; 612 int download_id = crx_installers_[installer];
608 crx_installers_.erase(installer.get()); 613 crx_installers_.erase(installer.get());
609 614
610 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); 615 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id);
611 if (item) 616 if (item)
612 item->DelayedDownloadOpened(installer->did_handle_successfully()); 617 item->DelayedDownloadOpened(installer->did_handle_successfully());
613 } 618 }
614 619
615 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( 620 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
616 int32 download_id, 621 int32 download_id,
622 const content::DownloadTargetCallback& callback,
617 content::DownloadDangerType danger_type, 623 content::DownloadDangerType danger_type,
618 bool visited_referrer_before) { 624 bool visited_referrer_before) {
619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
620 626
621 DownloadItem* download = 627 DownloadItem* download =
622 download_manager_->GetActiveDownloadItem(download_id); 628 download_manager_->GetActiveDownloadItem(download_id);
623 if (!download) 629 if (!download)
624 return; 630 return;
625 631
626 bool should_prompt = (download->GetTargetDisposition() == 632 bool should_prompt = (download->GetTargetDisposition() ==
(...skipping 21 matching lines...) Expand all
648 !ShouldOpenFileBasedOnExtension(generated_name)) 654 !ShouldOpenFileBasedOnExtension(generated_name))
649 should_prompt = true; 655 should_prompt = true;
650 } 656 }
651 if (download_prefs_->IsDownloadPathManaged()) 657 if (download_prefs_->IsDownloadPathManaged())
652 should_prompt = false; 658 should_prompt = false;
653 659
654 // Determine the proper path for a download, by either one of the following: 660 // Determine the proper path for a download, by either one of the following:
655 // 1) using the default download directory. 661 // 1) using the default download directory.
656 // 2) prompting the user. 662 // 2) prompting the user.
657 FilePath target_directory; 663 FilePath target_directory;
658 if (should_prompt && !download_manager_->LastDownloadPath().empty()) 664 if (should_prompt && !last_download_path_.empty())
659 target_directory = download_manager_->LastDownloadPath(); 665 target_directory = last_download_path_;
660 else 666 else
661 target_directory = download_prefs_->download_path(); 667 target_directory = download_prefs_->download_path();
662 suggested_path = target_directory.Append(generated_name); 668 suggested_path = target_directory.Append(generated_name);
663 } else { 669 } else {
664 DCHECK(!should_prompt); 670 DCHECK(!should_prompt);
665 suggested_path = download->GetForcedFilePath(); 671 suggested_path = download->GetForcedFilePath();
666 } 672 }
667 673
668 // If the download hasn't already been marked dangerous (could be 674 // If the download hasn't already been marked dangerous (could be
669 // DANGEROUS_URL), check if it is a dangerous file. 675 // DANGEROUS_URL), check if it is a dangerous file.
(...skipping 22 matching lines...) Expand all
692 } else { 698 } else {
693 // Currently we only expect this case. 699 // Currently we only expect this case.
694 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type); 700 DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type);
695 } 701 }
696 702
697 #if defined (OS_CHROMEOS) 703 #if defined (OS_CHROMEOS)
698 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath( 704 gdata::GDataDownloadObserver::SubstituteGDataDownloadPath(
699 profile_, suggested_path, download, 705 profile_, suggested_path, download,
700 base::Bind( 706 base::Bind(
701 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback, 707 &ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback,
702 this, download->GetId(), should_prompt, is_forced_path, danger_type)); 708 this, download->GetId(), callback, should_prompt, is_forced_path,
709 danger_type));
703 #else 710 #else
704 GetReservedPath( 711 GetReservedPath(
705 *download, suggested_path, download_prefs_->download_path(), 712 *download, suggested_path, download_prefs_->download_path(),
706 !is_forced_path, 713 !is_forced_path,
707 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, 714 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable,
708 this, download->GetId(), should_prompt, danger_type)); 715 this, download->GetId(), callback, should_prompt,
716 danger_type));
709 #endif 717 #endif
710 } 718 }
711 719
712 #if defined (OS_CHROMEOS) 720 #if defined (OS_CHROMEOS)
721 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS.
713 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( 722 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback(
714 int32 download_id, 723 int32 download_id,
724 const content::DownloadTargetCallback& callback,
715 bool should_prompt, 725 bool should_prompt,
716 bool is_forced_path, 726 bool is_forced_path,
717 content::DownloadDangerType danger_type, 727 content::DownloadDangerType danger_type,
718 const FilePath& suggested_path) { 728 const FilePath& suggested_path) {
719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
720 DownloadItem* download = 730 DownloadItem* download =
721 download_manager_->GetActiveDownloadItem(download_id); 731 download_manager_->GetActiveDownloadItem(download_id);
722 if (!download) 732 if (!download)
723 return; 733 return;
724 734
725 GetReservedPath( 735 GetReservedPath(
726 *download, suggested_path, download_prefs_->download_path(), 736 *download, suggested_path, download_prefs_->download_path(),
727 !is_forced_path, 737 !is_forced_path,
728 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, 738 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable,
729 this, download->GetId(), should_prompt, danger_type)); 739 this, download->GetId(), callback, should_prompt,
740 danger_type));
730 } 741 }
731 #endif 742 #endif
732 743
733 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( 744 void ChromeDownloadManagerDelegate::OnPathReservationAvailable(
734 int32 download_id, 745 int32 download_id,
746 const content::DownloadTargetCallback& callback,
735 bool should_prompt, 747 bool should_prompt,
736 content::DownloadDangerType danger_type, 748 content::DownloadDangerType danger_type,
737 const FilePath& target_path, 749 const FilePath& reserved_path,
738 bool target_path_verified) { 750 bool reserved_path_verified) {
739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 751 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
740 DownloadItem* download = 752 DownloadItem* download =
741 download_manager_->GetActiveDownloadItem(download_id); 753 download_manager_->GetActiveDownloadItem(download_id);
742 if (!download) 754 if (!download)
743 return; 755 return;
744 DownloadItem::TargetDisposition disposition; 756 if (should_prompt || !reserved_path_verified) {
745 // If the target path could not be verified then the path was non-existant, 757 // If the target path could not be verified then the path was non-existant,
746 // non writeable or could not be uniquified. Prompt the user. 758 // non writeable or could not be uniquified. Prompt the user.
747 if (should_prompt || !target_path_verified) 759 ChooseDownloadPath(
748 disposition = DownloadItem::TARGET_DISPOSITION_PROMPT; 760 download, reserved_path,
749 else 761 base::Bind(&ChromeDownloadManagerDelegate::OnTargetPathDetermined,
750 disposition = DownloadItem::TARGET_DISPOSITION_OVERWRITE; 762 this, download_id, callback,
751 download->OnTargetPathDetermined(target_path, disposition, danger_type); 763 DownloadItem::TARGET_DISPOSITION_PROMPT, danger_type));
752 download_manager_->RestartDownload(download_id); 764 } else {
765 OnTargetPathDetermined(download_id, callback,
766 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
767 danger_type, reserved_path);
768 }
769 }
770
771 void ChromeDownloadManagerDelegate::OnTargetPathDetermined(
772 int32 download_id,
773 const content::DownloadTargetCallback& callback,
774 DownloadItem::TargetDisposition disposition,
775 content::DownloadDangerType danger_type,
776 const FilePath& target_path) {
777 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
778 DownloadItem* download =
779 download_manager_->GetActiveDownloadItem(download_id);
780 if (!download)
781 return;
782
783 // If |target_path| is empty, then that means that the user wants to cancel
784 // the download.
785 if (target_path.empty()) {
786 DCHECK_EQ(DownloadItem::TARGET_DISPOSITION_PROMPT, disposition);
787 download->Cancel(true);
788 return;
789 }
790
791 // Retain the last directory. Exclude temporary downloads since the path
792 // likely points at the location of a temporary file.
793 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
794 // directory to persist. Or perhaps, if the GData path
795 // substitution logic is moved here, then we would have a
796 // persistable path after the DownloadFilePicker is done.
797 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
798 !download->IsTemporary())
799 last_download_path_ = target_path.DirName();
800
801 FilePath intermediate_path = GetIntermediatePath(target_path, danger_type);
802 callback.Run(target_path, disposition, danger_type, intermediate_path);
753 } 803 }
754 804
755 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( 805 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore(
756 int32 download_id, int64 db_handle) { 806 int32 download_id, int64 db_handle) {
757 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 807 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
758 // call this function with an invalid |db_handle|. For instance, this can 808 // call this function with an invalid |db_handle|. For instance, this can
759 // happen when the history database is offline. We cannot have multiple 809 // happen when the history database is offline. We cannot have multiple
760 // DownloadItems with the same invalid db_handle, so we need to assign a 810 // DownloadItems with the same invalid db_handle, so we need to assign a
761 // unique |db_handle| here. 811 // unique |db_handle| here.
762 if (db_handle == DownloadItem::kUninitializedHandle) 812 if (db_handle == DownloadItem::kUninitializedHandle)
763 db_handle = download_history_->GetNextFakeDbHandle(); 813 db_handle = download_history_->GetNextFakeDbHandle();
764 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); 814 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle);
765 } 815 }
816
817 void ChromeDownloadManagerDelegate::ClearTransientState() {
818 last_download_path_.clear();
819 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698