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

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

Issue 11574006: Implement chrome.downloads.onDeterminingFilename() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r176347 Created 7 years, 11 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"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/prefs/public/pref_member.h" 13 #include "base/prefs/public/pref_member.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/download/download_completion_blocker.h" 19 #include "chrome/browser/download/download_completion_blocker.h"
20 #include "chrome/browser/download/download_crx_util.h" 20 #include "chrome/browser/download/download_crx_util.h"
21 #include "chrome/browser/download/download_extensions.h" 21 #include "chrome/browser/download/download_extensions.h"
22 #include "chrome/browser/download/download_file_picker.h" 22 #include "chrome/browser/download/download_file_picker.h"
23 #include "chrome/browser/download/download_history.h" 23 #include "chrome/browser/download/download_history.h"
24 #include "chrome/browser/download/download_path_reservation_tracker.h" 24 #include "chrome/browser/download/download_path_reservation_tracker.h"
25 #include "chrome/browser/download/download_prefs.h" 25 #include "chrome/browser/download/download_prefs.h"
26 #include "chrome/browser/download/download_service.h"
27 #include "chrome/browser/download/download_service_factory.h"
26 #include "chrome/browser/download/download_status_updater.h" 28 #include "chrome/browser/download/download_status_updater.h"
27 #include "chrome/browser/download/download_util.h" 29 #include "chrome/browser/download/download_util.h"
28 #include "chrome/browser/download/save_package_file_picker.h" 30 #include "chrome/browser/download/save_package_file_picker.h"
29 #include "chrome/browser/extensions/api/downloads/downloads_api.h" 31 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
30 #include "chrome/browser/extensions/crx_installer.h" 32 #include "chrome/browser/extensions/crx_installer.h"
31 #include "chrome/browser/extensions/extension_service.h" 33 #include "chrome/browser/extensions/extension_service.h"
32 #include "chrome/browser/extensions/extension_system.h" 34 #include "chrome/browser/extensions/extension_system.h"
33 #include "chrome/browser/history/history.h" 35 #include "chrome/browser/history/history.h"
34 #include "chrome/browser/history/history_service_factory.h" 36 #include "chrome/browser/history/history_service_factory.h"
35 #include "chrome/browser/intents/web_intents_util.h" 37 #include "chrome/browser/intents/web_intents_util.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 : profile_(profile), 167 : profile_(profile),
166 next_download_id_(0), 168 next_download_id_(0),
167 download_prefs_(new DownloadPrefs(profile)) { 169 download_prefs_(new DownloadPrefs(profile)) {
168 } 170 }
169 171
170 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { 172 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
171 } 173 }
172 174
173 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) { 175 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
174 download_manager_ = dm; 176 download_manager_ = dm;
175 #if !defined(OS_ANDROID)
176 extension_event_router_.reset(new ExtensionDownloadsEventRouter(
177 profile_, download_manager_));
178 #endif
179 } 177 }
180 178
181 void ChromeDownloadManagerDelegate::Shutdown() { 179 void ChromeDownloadManagerDelegate::Shutdown() {
182 download_prefs_.reset(); 180 download_prefs_.reset();
183 #if !defined(OS_ANDROID)
184 extension_event_router_.reset();
185 #endif
186 } 181 }
187 182
188 DownloadId ChromeDownloadManagerDelegate::GetNextId() { 183 DownloadId ChromeDownloadManagerDelegate::GetNextId() {
189 if (!profile_->IsOffTheRecord()) 184 if (!profile_->IsOffTheRecord())
190 return DownloadId(this, next_download_id_++); 185 return DownloadId(this, next_download_id_++);
191 186
192 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> 187 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())->
193 GetDelegate()->GetNextId(); 188 GetDelegate()->GetNextId();
194 } 189 }
195 190
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 656 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
662 source); 657 source);
663 658
664 scoped_refptr<extensions::CrxInstaller> installer = 659 scoped_refptr<extensions::CrxInstaller> installer =
665 content::Source<extensions::CrxInstaller>(source).ptr(); 660 content::Source<extensions::CrxInstaller>(source).ptr();
666 content::DownloadOpenDelayedCallback callback = crx_installers_[installer]; 661 content::DownloadOpenDelayedCallback callback = crx_installers_[installer];
667 crx_installers_.erase(installer.get()); 662 crx_installers_.erase(installer.get());
668 callback.Run(installer->did_handle_successfully()); 663 callback.Run(installer->did_handle_successfully());
669 } 664 }
670 665
666 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
667 ContinueFilenameDeterminationInfo() {}
668 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
669 ~ContinueFilenameDeterminationInfo() {}
670
671 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( 671 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
672 int32 download_id, 672 int32 download_id,
673 const content::DownloadTargetCallback& callback, 673 const content::DownloadTargetCallback& callback,
674 content::DownloadDangerType danger_type, 674 content::DownloadDangerType danger_type,
675 bool visited_referrer_before) { 675 bool visited_referrer_before) {
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
677 677
678 DownloadItem* download = 678 DownloadItem* download =
679 download_manager_->GetDownload(download_id); 679 download_manager_->GetDownload(download_id);
680 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 680 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
681 return; 681 return;
682 682
683 bool should_prompt = (download->GetTargetDisposition() == 683 bool should_prompt = (download->GetTargetDisposition() ==
684 DownloadItem::TARGET_DISPOSITION_PROMPT); 684 DownloadItem::TARGET_DISPOSITION_PROMPT);
685 bool is_forced_path = !download->GetForcedFilePath().empty(); 685 bool is_forced_path = !download->GetForcedFilePath().empty();
686 FilePath generated_name;
686 FilePath suggested_path; 687 FilePath suggested_path;
687 688
688 // Check whether this download is for an extension install or not. 689 // Check whether this download is for an extension install or not.
689 // Allow extensions to be explicitly saved. 690 // Allow extensions to be explicitly saved.
690 if (!is_forced_path) { 691 if (!is_forced_path) {
691 FilePath generated_name;
692 GenerateFileNameFromRequest( 692 GenerateFileNameFromRequest(
693 *download, 693 *download,
694 &generated_name, 694 &generated_name,
695 profile_->GetPrefs()->GetString(prefs::kDefaultCharset)); 695 profile_->GetPrefs()->GetString(prefs::kDefaultCharset));
696 696
697 // Freeze the user's preference for showing a Save As dialog. We're going 697 // Freeze the user's preference for showing a Save As dialog. We're going
698 // to bounce around a bunch of threads and we don't want to worry about race 698 // to bounce around a bunch of threads and we don't want to worry about race
699 // conditions where the user changes this pref out from under us. 699 // conditions where the user changes this pref out from under us.
700 if (download_prefs_->PromptForDownload()) { 700 if (download_prefs_->PromptForDownload()) {
701 // But ignore the user's preference for the following scenarios: 701 // But ignore the user's preference for the following scenarios:
(...skipping 10 matching lines...) Expand all
712 should_prompt = false; 712 should_prompt = false;
713 713
714 // Determine the proper path for a download, by either one of the following: 714 // Determine the proper path for a download, by either one of the following:
715 // 1) using the default download directory. 715 // 1) using the default download directory.
716 // 2) prompting the user. 716 // 2) prompting the user.
717 FilePath target_directory; 717 FilePath target_directory;
718 if (should_prompt && !last_download_path_.empty()) 718 if (should_prompt && !last_download_path_.empty())
719 target_directory = last_download_path_; 719 target_directory = last_download_path_;
720 else 720 else
721 target_directory = download_prefs_->DownloadPath(); 721 target_directory = download_prefs_->DownloadPath();
722 // If an extension overrides the filename, then the target directory will be
723 // forced to download_prefs_->DownloadPath() since extensions cannot place
724 // downloaded files anywhere except there. This prevents subdirectories from
725 // accumulating: if an extension is allowed to say that a file should go in
726 // last_download_path/music/foo.mp3, then last_download_path will accumulate
727 // the subdirectory /music/ so that the next download may end up in
728 // last_download_path/music/music/bar.mp3.
asanka 2013/01/11 21:56:54 I understand why this comment is here, but I think
benjhayden 2013/01/11 22:04:52 Done.
722 suggested_path = target_directory.Append(generated_name); 729 suggested_path = target_directory.Append(generated_name);
723 } else { 730 } else {
724 DCHECK(!should_prompt); 731 DCHECK(!should_prompt);
725 suggested_path = download->GetForcedFilePath(); 732 suggested_path = download->GetForcedFilePath();
726 } 733 }
727 734
728 // If we will open the file with a web intents dispatch, 735 // If we will open the file with a web intents dispatch,
729 // give it a name that will not allow the OS to open it using usual 736 // give it a name that will not allow the OS to open it using usual
730 // associated apps. 737 // associated apps.
731 if (ShouldOpenWithWebIntents(download)) { 738 if (ShouldOpenWithWebIntents(download)) {
732 download->SetDisplayName(suggested_path.BaseName()); 739 download->SetDisplayName(suggested_path.BaseName());
733 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension); 740 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension);
734 } 741 }
735 742
743 ContinueFilenameDeterminationInfo continue_info;
744 continue_info.download_id = download_id;
745 continue_info.callback = callback;
746 continue_info.danger_type = danger_type;
747 continue_info.visited_referrer_before = visited_referrer_before;
748 continue_info.should_prompt = should_prompt;
749
750 base::Closure filename_determined = base::Bind(
751 &ChromeDownloadManagerDelegate::OnExtensionsDeterminedFilename,
752 this,
753 continue_info,
754 suggested_path,
755 is_forced_path);
756 #if !defined(OS_ANDROID)
757 if (is_forced_path ||
758 ShouldOpenWithWebIntents(download) ||
759 !DownloadServiceFactory::GetForProfile(profile_)
760 ->GetExtensionEventRouter()) {
761 filename_determined.Run();
762 } else {
763 DownloadServiceFactory::GetForProfile(profile_)->GetExtensionEventRouter()
764 ->OnDownloadFilenameDetermined(
765 download,
766 generated_name,
767 filename_determined,
768 base::Bind(&ChromeDownloadManagerDelegate::OnExtensionsChangingFilename,
769 this, continue_info));
770 }
771 #else
772 filename_determined.Run();
asanka 2013/01/11 21:56:54 Why not just call OnExtensionsDeterminedFilename()
benjhayden 2013/01/11 22:04:52 If OnExtensionsDeterminedFilename's signature chan
773 #endif
774 }
775
776 void ChromeDownloadManagerDelegate::OnExtensionsChangingFilename(
777 const ContinueFilenameDeterminationInfo& continue_info,
778 const FilePath& changed_filename,
779 bool overwrite) {
780 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
781 CHECK(!changed_filename.empty());
782 CHECK(!changed_filename.IsAbsolute());
783 DownloadItem* download =
784 download_manager_->GetDownload(continue_info.download_id);
785 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
asanka 2013/01/11 21:56:54 We need to invoke the DownloadTargetCallback regar
benjhayden 2013/01/11 22:04:52 Why? That's not what SubstituteDriveDownloadPathCa
786 return;
787 FilePath temp_filename(download_prefs_->DownloadPath().Append(
788 changed_filename));
789 net::GenerateSafeFileName(download->GetMimeType(), false, &temp_filename);
790 // If |is_forced_path| were true, then extensions would not have been
791 // consulted, so use |overwrite| instead of |is_forced_path|. This does NOT
792 // set DownloadItem::GetForcedFilePath()!
793 OnExtensionsDeterminedFilename(continue_info, temp_filename, overwrite);
794 }
795
796 void ChromeDownloadManagerDelegate::OnExtensionsDeterminedFilename(
797 const ContinueFilenameDeterminationInfo& continue_info,
798 const FilePath& suggested_path,
799 bool is_forced_path) {
800 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
801 int32 download_id = continue_info.download_id;
802 const content::DownloadTargetCallback& callback = continue_info.callback;
803 content::DownloadDangerType danger_type = continue_info.danger_type;
804 bool visited_referrer_before = continue_info.visited_referrer_before;
805 bool should_prompt = continue_info.should_prompt;
806 DownloadItem* download =
807 download_manager_->GetDownload(download_id);
808 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
asanka 2013/01/11 21:56:54 As above.
benjhayden 2013/01/11 22:04:52 ditto.
809 return;
810
736 // If the download hasn't already been marked dangerous (could be 811 // If the download hasn't already been marked dangerous (could be
737 // DANGEROUS_URL), check if it is a dangerous file. 812 // DANGEROUS_URL), check if it is a dangerous file.
738 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 813 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
739 if (!should_prompt && !is_forced_path && 814 if (!should_prompt && !is_forced_path &&
740 IsDangerousFile(*download, suggested_path, visited_referrer_before)) { 815 IsDangerousFile(*download, suggested_path, visited_referrer_before)) {
741 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 816 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
742 } 817 }
743 818
744 #if defined(FULL_SAFE_BROWSING) 819 #if defined(FULL_SAFE_BROWSING)
745 DownloadProtectionService* service = GetDownloadProtectionService(); 820 DownloadProtectionService* service = GetDownloadProtectionService();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a 928 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
854 // directory to persist. Or perhaps, if the Drive path 929 // directory to persist. Or perhaps, if the Drive path
855 // substitution logic is moved here, then we would have a 930 // substitution logic is moved here, then we would have a
856 // persistable path after the DownloadFilePicker is done. 931 // persistable path after the DownloadFilePicker is done.
857 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && 932 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
858 !download->IsTemporary()) 933 !download->IsTemporary())
859 last_download_path_ = target_path.DirName(); 934 last_download_path_ = target_path.DirName();
860 } 935 }
861 callback.Run(target_path, disposition, danger_type, intermediate_path); 936 callback.Run(target_path, disposition, danger_type, intermediate_path);
862 } 937 }
OLDNEW
« no previous file with comments | « chrome/browser/download/chrome_download_manager_delegate.h ('k') | chrome/browser/download/download_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698