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

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: @r180415 Created 7 years, 10 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_service.h" 35 #include "chrome/browser/history/history_service.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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 : profile_(profile), 169 : profile_(profile),
168 next_download_id_(0), 170 next_download_id_(0),
169 download_prefs_(new DownloadPrefs(profile)) { 171 download_prefs_(new DownloadPrefs(profile)) {
170 } 172 }
171 173
172 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { 174 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
173 } 175 }
174 176
175 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) { 177 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
176 download_manager_ = dm; 178 download_manager_ = dm;
177 #if !defined(OS_ANDROID)
178 extension_event_router_.reset(new ExtensionDownloadsEventRouter(
179 profile_, download_manager_));
180 #endif
181 } 179 }
182 180
183 void ChromeDownloadManagerDelegate::Shutdown() { 181 void ChromeDownloadManagerDelegate::Shutdown() {
184 download_prefs_.reset(); 182 download_prefs_.reset();
185 #if !defined(OS_ANDROID)
186 extension_event_router_.reset();
187 #endif
188 } 183 }
189 184
190 DownloadId ChromeDownloadManagerDelegate::GetNextId() { 185 DownloadId ChromeDownloadManagerDelegate::GetNextId() {
191 if (!profile_->IsOffTheRecord()) 186 if (!profile_->IsOffTheRecord())
192 return DownloadId(this, next_download_id_++); 187 return DownloadId(this, next_download_id_++);
193 188
194 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> 189 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())->
195 GetDelegate()->GetNextId(); 190 GetDelegate()->GetNextId();
196 } 191 }
197 192
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 688 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
694 source); 689 source);
695 690
696 scoped_refptr<extensions::CrxInstaller> installer = 691 scoped_refptr<extensions::CrxInstaller> installer =
697 content::Source<extensions::CrxInstaller>(source).ptr(); 692 content::Source<extensions::CrxInstaller>(source).ptr();
698 content::DownloadOpenDelayedCallback callback = crx_installers_[installer]; 693 content::DownloadOpenDelayedCallback callback = crx_installers_[installer];
699 crx_installers_.erase(installer.get()); 694 crx_installers_.erase(installer.get());
700 callback.Run(installer->did_handle_successfully()); 695 callback.Run(installer->did_handle_successfully());
701 } 696 }
702 697
698 struct ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo {
699 ContinueFilenameDeterminationInfo();
700 ~ContinueFilenameDeterminationInfo();
701
702 int32 download_id;
703 content::DownloadTargetCallback callback;
704 content::DownloadDangerType danger_type;
705 bool visited_referrer_before;
706 bool should_prompt;
707 };
708
709 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
710 ContinueFilenameDeterminationInfo() {}
711 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
712 ~ContinueFilenameDeterminationInfo() {}
713
703 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( 714 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
704 int32 download_id, 715 int32 download_id,
705 const content::DownloadTargetCallback& callback, 716 const content::DownloadTargetCallback& callback,
706 content::DownloadDangerType danger_type, 717 content::DownloadDangerType danger_type,
707 bool visited_referrer_before) { 718 bool visited_referrer_before) {
708 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
709 720
710 DownloadItem* download = 721 DownloadItem* download =
711 download_manager_->GetDownload(download_id); 722 download_manager_->GetDownload(download_id);
712 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 723 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
713 return; 724 return;
714 725
715 bool should_prompt = (download->GetTargetDisposition() == 726 bool should_prompt = (download->GetTargetDisposition() ==
716 DownloadItem::TARGET_DISPOSITION_PROMPT); 727 DownloadItem::TARGET_DISPOSITION_PROMPT);
717 bool is_forced_path = !download->GetForcedFilePath().empty(); 728 bool is_forced_path = !download->GetForcedFilePath().empty();
729 FilePath generated_name;
718 FilePath suggested_path; 730 FilePath suggested_path;
719 731
720 // Check whether this download is for an extension install or not. 732 // Check whether this download is for an extension install or not.
721 // Allow extensions to be explicitly saved. 733 // Allow extensions to be explicitly saved.
722 if (!is_forced_path) { 734 if (!is_forced_path) {
723 FilePath generated_name;
724 GenerateFileNameFromRequest( 735 GenerateFileNameFromRequest(
725 *download, 736 *download,
726 &generated_name, 737 &generated_name,
727 profile_->GetPrefs()->GetString(prefs::kDefaultCharset)); 738 profile_->GetPrefs()->GetString(prefs::kDefaultCharset));
728 739
729 // Freeze the user's preference for showing a Save As dialog. We're going 740 // Freeze the user's preference for showing a Save As dialog. We're going
730 // to bounce around a bunch of threads and we don't want to worry about race 741 // to bounce around a bunch of threads and we don't want to worry about race
731 // conditions where the user changes this pref out from under us. 742 // conditions where the user changes this pref out from under us.
732 if (download_prefs_->PromptForDownload()) { 743 if (download_prefs_->PromptForDownload()) {
733 // But ignore the user's preference for the following scenarios: 744 // But ignore the user's preference for the following scenarios:
(...skipping 26 matching lines...) Expand all
760 #if defined(ENABLE_WEB_INTENTS) 771 #if defined(ENABLE_WEB_INTENTS)
761 // If we will open the file with a web intents dispatch, 772 // If we will open the file with a web intents dispatch,
762 // give it a name that will not allow the OS to open it using usual 773 // give it a name that will not allow the OS to open it using usual
763 // associated apps. 774 // associated apps.
764 if (ShouldOpenWithWebIntents(download)) { 775 if (ShouldOpenWithWebIntents(download)) {
765 download->SetDisplayName(suggested_path.BaseName()); 776 download->SetDisplayName(suggested_path.BaseName());
766 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension); 777 suggested_path = suggested_path.AddExtension(kWebIntentsFileExtension);
767 } 778 }
768 #endif 779 #endif
769 780
781 ContinueFilenameDeterminationInfo continue_info;
782 continue_info.download_id = download_id;
783 continue_info.callback = callback;
784 continue_info.danger_type = danger_type;
785 continue_info.visited_referrer_before = visited_referrer_before;
786 continue_info.should_prompt = should_prompt;
787
788 base::Closure filename_determined = base::Bind(
789 &ChromeDownloadManagerDelegate::ContinueDeterminingFilename,
790 this,
791 continue_info,
792 suggested_path,
793 is_forced_path);
794 #if !defined(OS_ANDROID)
795 if (is_forced_path ||
796 ShouldOpenWithWebIntents(download) ||
797 !DownloadServiceFactory::GetForProfile(profile_)
798 ->GetExtensionEventRouter()) {
799 filename_determined.Run();
800 } else {
801 DownloadService* service = DownloadServiceFactory::GetForProfile(profile_);
802 ExtensionDownloadsEventRouter* router = service->GetExtensionEventRouter();
803 ExtensionDownloadsEventRouter::FilenameChangedCallback overriding =
804 base::Bind(&ChromeDownloadManagerDelegate::OnExtensionOverridingFilename,
805 this, continue_info);
806 router->OnDeterminingFilename(
807 download, generated_name, filename_determined, overriding);
808 }
809 #else
810 filename_determined.Run();
811 #endif
812 }
813
814 void ChromeDownloadManagerDelegate::OnExtensionOverridingFilename(
815 const ContinueFilenameDeterminationInfo& continue_info,
816 const FilePath& changed_filename,
817 bool overwrite) {
818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
819 DownloadItem* download =
820 download_manager_->GetDownload(continue_info.download_id);
821 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
822 return;
823 // If an extension overrides the filename, then the target directory will be
824 // forced to download_prefs_->DownloadPath() since extensions cannot place
825 // downloaded files anywhere except there. This prevents subdirectories from
826 // accumulating: if an extension is allowed to say that a file should go in
827 // last_download_path/music/foo.mp3, then last_download_path will accumulate
828 // the subdirectory /music/ so that the next download may end up in
829 // last_download_path/music/music/bar.mp3.
830 FilePath temp_filename(download_prefs_->DownloadPath().Append(
831 changed_filename));
832 net::GenerateSafeFileName(download->GetMimeType(), false, &temp_filename);
833 // If |is_forced_path| were true, then extensions would not have been
834 // consulted, so use |overwrite| instead of |is_forced_path|. This does NOT
835 // set DownloadItem::GetForcedFilePath()!
836 ContinueDeterminingFilename(continue_info, temp_filename, overwrite);
837 }
838
839 void ChromeDownloadManagerDelegate::ContinueDeterminingFilename(
840 const ContinueFilenameDeterminationInfo& continue_info,
841 const FilePath& suggested_path,
842 bool is_forced_path) {
843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
844 int32 download_id = continue_info.download_id;
845 const content::DownloadTargetCallback& callback = continue_info.callback;
846 content::DownloadDangerType danger_type = continue_info.danger_type;
847 bool visited_referrer_before = continue_info.visited_referrer_before;
848 bool should_prompt = continue_info.should_prompt;
849 DownloadItem* download =
850 download_manager_->GetDownload(download_id);
851 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
852 return;
853
770 // If the download hasn't already been marked dangerous (could be 854 // If the download hasn't already been marked dangerous (could be
771 // DANGEROUS_URL), check if it is a dangerous file. 855 // DANGEROUS_URL), check if it is a dangerous file.
772 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 856 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
773 if (!should_prompt && !is_forced_path && 857 if (!should_prompt && !is_forced_path &&
774 IsDangerousFile(*download, suggested_path, visited_referrer_before)) { 858 IsDangerousFile(*download, suggested_path, visited_referrer_before)) {
775 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 859 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
776 } 860 }
777 861
778 #if defined(FULL_SAFE_BROWSING) 862 #if defined(FULL_SAFE_BROWSING)
779 DownloadProtectionService* service = GetDownloadProtectionService(); 863 DownloadProtectionService* service = GetDownloadProtectionService();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a 984 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
901 // directory to persist. Or perhaps, if the Drive path 985 // directory to persist. Or perhaps, if the Drive path
902 // substitution logic is moved here, then we would have a 986 // substitution logic is moved here, then we would have a
903 // persistable path after the DownloadFilePicker is done. 987 // persistable path after the DownloadFilePicker is done.
904 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && 988 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
905 !download->IsTemporary()) 989 !download->IsTemporary())
906 last_download_path_ = target_path.DirName(); 990 last_download_path_ = target_path.DirName();
907 } 991 }
908 callback.Run(target_path, disposition, danger_type, intermediate_path); 992 callback.Run(target_path, disposition, danger_type, intermediate_path);
909 } 993 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698